#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 | CONTAINER_UNLINK(container, obj, tag) |
Unlink the given object from the container and return TRUE if it was in the container. | |
#define | DATA_EXPORT_SIP_PEER(MEMBER) |
#define | FORMAT "%-15.15s %-15.15s %-15.15s %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s %-10.10s\n" |
#define | FORMAT "%-30.30s %-12.12s %-10.10s %-10.10s\n" |
#define | FORMAT "%-15.15s %-11.11s %-8.8s %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf\n" |
#define | FORMAT "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n" |
#define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define | FORMAT "%-25.25s %-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 } |
enum | peer_unlink_flag_t { SIP_PEERS_MARKED, SIP_PEERS_ALL } |
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 fatal, int sipmethod) |
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) |
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 void | add_realm_authentication (struct sip_auth_container **credentials, const char *configuration, int lineno) |
static void | add_route (struct sip_request *req, struct sip_route *route) |
Add route header into request per learned route. | |
static int | add_rpid (struct sip_request *req, struct sip_pvt *p) |
Add Remote-Party-ID header to SIP message. | |
static enum sip_result | add_sdp (struct sip_request *resp, struct sip_pvt *p, int oldsdp, int add_audio, int add_t38) |
Add Session Description Protocol message. | |
static int | add_sip_domain (const char *domain, const enum domain_mode mode, const char *context) |
Add SIP domain to list of domains we are responsible for. | |
static int | add_supported_header (struct sip_pvt *pvt, struct sip_request *req) |
Add "Supported" header to sip message. Since some options may be disabled in the config, the sip_pvt must be inspected to determine what is supported for this dialog. | |
static void | add_tcodec_to_sdp (const struct sip_pvt *p, int codec, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size) |
Add text codec offer to SDP offer/answer body in INVITE or 200 OK. | |
static int | add_text (struct sip_request *req, const char *text) |
Add text body to SIP message. | |
static struct ast_variable * | add_var (const char *buf, struct ast_variable *list) |
implement the setvar config line | |
static void | add_vcodec_to_sdp (const struct sip_pvt *p, format_t codec, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size) |
Add video codec offer to SDP offer/answer body in INVITE or 200 OK. | |
static int | add_vidupdate (struct sip_request *req) |
add XML encoded media control with update | |
static int | addr_is_multicast (const struct ast_sockaddr *addr) |
Check if an ip is an multicast IP. addr the address to check. | |
static const char * | allowoverlap2str (int mode) |
Convert AllowOverlap setting to printable string. | |
static void | append_date (struct sip_request *req) |
Append date to SIP message. | |
static void | append_history_full (struct sip_pvt *p, const char *fmt,...) |
Append to SIP dialog history with arg list. | |
static void | append_history_va (struct sip_pvt *p, const char *fmt, va_list ap) |
Append to SIP dialog history with arg list. | |
static int | apply_directmedia_ha (struct sip_pvt *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 header for a 401 or 407 code | |
static int | auto_congest (const void *arg) |
Scheduled congestion on a call. Only called by the scheduler, must return the reference when done. | |
static void | build_callid_pvt (struct sip_pvt *pvt) |
Build SIP Call-ID value for a non-REGISTER transaction. | |
static void | build_callid_registry (struct sip_registry *reg, const struct ast_sockaddr *ourip, const char *fromdomain) |
Build SIP Call-ID value for a REGISTER transaction. | |
static void | build_contact (struct sip_pvt *p) |
Build contact header - the contact header we send out. | |
static struct sip_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only) |
Build peer from configuration (file or realtime static/dynamic). | |
static int | build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len) |
Build reply digest. | |
static void | build_route (struct sip_pvt *p, struct sip_request *req, int backwards, int resp) |
Build route list from Record-Route header. | |
static void | build_via (struct sip_pvt *p) |
Build a Via header for a request. | |
static int | cb_extensionstate (char *context, char *exten, int state, void *data) |
Callback for the devicestate notification (SUBSCRIBE) support subsystem. | |
static void | cb_extensionstate_destroy (int id, void *data) |
static void | cc_epa_destructor (void *data) |
static int | cc_esc_publish_handler (struct sip_pvt *pvt, struct sip_request *req, struct event_state_compositor *esc, struct sip_esc_entry *esc_entry) |
static void | cc_handle_publish_error (struct sip_pvt *pvt, const int resp, struct sip_request *req, struct sip_epa_entry *epa_entry) |
static void | change_callid_pvt (struct sip_pvt *pvt, const char *callid) |
static void | change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly) |
Change hold state for a call. | |
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_all_regs (void) |
static void | cleanup_stale_contexts (char *new, char *old) |
Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly. | |
static void | clear_peer_mailboxes (struct sip_peer *peer) |
static void | clear_sip_domains (void) |
Clear our domain list (at reload). | |
static char * | complete_sip_peer (const char *word, int state, int flags2) |
Do completion on peer name. | |
static char * | complete_sip_registered_peer (const char *word, int state, int flags2) |
Do completion on registered peer name. | |
static char * | complete_sip_show_history (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show history' CLI. | |
static char * | complete_sip_show_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show peer' CLI. | |
static char * | complete_sip_show_user (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show user' CLI. | |
static char * | complete_sip_unregister (const char *line, const char *word, int pos, int state) |
Support routine for 'sip unregister' CLI. | |
static char * | complete_sip_user (const char *word, int state) |
Do completion on user name. | |
static char * | complete_sipch (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show channel' and 'sip show history' CLI This is in charge of generating all strings that match a prefix in the given position. As many functions of this kind, each invokation has O(state) time complexity so be careful in using it. | |
static char * | complete_sipnotify (const char *line, const char *word, int pos, int state) |
Support routine for 'sip notify' CLI. | |
static int | construct_pidf_body (enum sip_cc_publish_state state, char *pidf_body, size_t size, const char *presentity) |
static int | copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy all headers from one request to another. | |
static int | copy_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy one header field from one request to another. | |
static void | copy_request (struct sip_request *dst, const struct sip_request *src) |
copy SIP request (mostly used to save request for responses) | |
static void | copy_socket_data (struct sip_socket *to_sock, const struct sip_socket *from_sock) |
static struct ast_variable * | copy_vars (struct ast_variable *src) |
duplicate a list of channel variables, | |
static int | copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy SIP VIA Headers from the request to the response. | |
static int | create_addr (struct sip_pvt *dialog, const char *opeer, struct ast_sockaddr *addr, int newdialog, 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 int | default_sip_port (enum sip_transport type) |
The default sip port for the given transport. | |
static void | deinit_req (struct sip_request *req) |
Deinitialize SIP response/request. | |
static void | destroy_association (struct sip_peer *peer) |
Remove registration data from realtime database or AST/DB when registration expires. | |
static void | destroy_escs (void) |
static void | destroy_mailbox (struct sip_mailbox *mailbox) |
static void | destroy_realm_authentication (void *obj) |
static int | determine_firstline_parts (struct sip_request *req) |
Parse first line of incoming SIP request. | |
static enum sip_publish_type | determine_sip_publish_type (struct sip_request *req, const char *const event, const char *const etag, const char *const expires, int *expires_int) |
static int | dialog_cmp_cb (void *obj, void *arg, int flags) |
static int | dialog_dump_func (void *userobj, void *arg, int flags) |
static int | dialog_find_multiple (void *obj, void *arg, int flags) |
static int | dialog_hash_cb (const void *obj, const int flags) |
static int | dialog_initialize_rtp (struct sip_pvt *dialog) |
Initialize RTP portion of a dialog. | |
static int | dialog_needdestroy (void *dialogobj, void *arg, int flags) |
Match dialogs that need to be destroyed. | |
sip_pvt * | dialog_ref_debug (struct sip_pvt *p, char *tag, char *file, int line, const char *func) |
void | dialog_unlink_all (struct sip_pvt *dialog) |
Unlink a dialog from the dialogs container, as well as any other places that it may be currently stored. | |
static int | dialog_unlink_callback (void *obj, void *arg, int flags) |
sip_pvt * | dialog_unref_debug (struct sip_pvt *p, char *tag, char *file, int line, const char *func) |
static void | disable_dsp_detect (struct sip_pvt *p) |
static void | display_nat_warning (const char *cat, int reason, struct ast_flags *flags) |
static int | do_magic_pickup (struct ast_channel *channel, const char *extension, const char *context) |
static void * | do_monitor (void *data) |
The SIP monitoring thread. | |
static int | do_proxy_auth (struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code, int sipmethod, int init) |
Add authentication on outbound SIP packet. | |
static int | do_register_auth (struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code) |
Authenticate for outbound registration. | |
static void | do_setnat (struct sip_pvt *p) |
Set nat mode on the various data sockets. | |
static const char * | domain_mode_to_text (const enum domain_mode mode) |
Print domain mode to cli. | |
static const char * | dtmfmode2str (int mode) |
Convert DTMF mode to printable string. | |
static void | enable_dsp_detect (struct sip_pvt *p) |
static int | esc_cmp_fn (void *obj, void *arg, int flags) |
static void | esc_entry_destructor (void *obj) |
static int | esc_hash_fn (const void *obj, const int flags) |
static int | expire_register (const void *data) |
Expire registration of SIP peer. | |
static void | extract_host_from_hostport (char **hostport) |
Terminate a host:port at the ':'. | |
static void | extract_uri (struct sip_pvt *p, struct sip_request *req) |
Check Contact: URI of SIP message. | |
static const char * | faxec2str (int faxec) |
static int | finalize_content (struct sip_request *req) |
Add 'Content-Length' header and content to SIP message. | |
static const char * | find_alias (const char *name, const char *_default) |
Find compressed SIP alias. | |
static int | find_by_callid_helper (void *obj, void *arg, int flags) |
static int | find_by_name (void *obj, void *arg, void *data, int flags) |
static int | find_by_notify_uri_helper (void *obj, void *arg, int flags) |
static int | find_by_subscribe_uri_helper (void *obj, void *arg, int flags) |
static struct sip_pvt * | find_call (struct sip_request *req, struct ast_sockaddr *addr, const int intended_method) |
find or create a dialog structure for an incoming SIP message. Connect incoming SIP message to current dialog or create new dialog structure Returns a reference to the sip_pvt object, remember to give it back once done. Called by handle_request_do | |
static int | find_calling_channel (void *obj, void *arg, void *data, int flags) |
Find the channel that is causing the RINGING update. | |
const char * | find_closing_quote (const char *start, const char *lim) |
Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote. | |
static struct sip_peer * | find_peer (const char *peer, struct ast_sockaddr *addr, int realtime, int which_objects, int devstate_only, int transport) |
Locate device by name or ip address. | |
static struct sip_auth * | find_realm_authentication (struct sip_auth_container *credentials, const char *realm) |
static int | find_sdp (struct sip_request *req) |
Determine whether a SIP message contains an SDP in its body. | |
static struct ast_cc_agent * | find_sip_cc_agent_by_notify_uri (const char *const uri) |
static struct ast_cc_agent * | find_sip_cc_agent_by_original_callid (struct sip_pvt *pvt) |
static struct ast_cc_agent * | find_sip_cc_agent_by_subscribe_uri (const char *const uri) |
static int | find_sip_method (const char *msg) |
find_sip_method: Find SIP method from header | |
static int | find_sip_monitor_instance_by_subscription_pvt (void *obj, void *arg, int flags) |
static int | find_sip_monitor_instance_by_suspension_entry (void *obj, void *arg, int flags) |
static struct epa_static_data * | find_static_data (const char *const event_package) |
static struct cfsubscription_types * | find_subscription_type (enum subscriptiontype subtype) |
Find subscription type in array. | |
static void | free_old_route (struct sip_route *route) |
Remove route from route list. | |
static int | func_check_sipdomain (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
Dial plan function to check if domain is local. | |
static int | func_header_read (struct ast_channel *chan, const char *function, char *data, char *buf, size_t len) |
Read SIP header (dialplan function). | |
static int | function_sipchaninfo_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
${SIPCHANINFO()} Dialplan function - reads sip channel data | |
static int | function_sippeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
${SIPPEER()} Dialplan function - reads peer data | |
static char * | generate_random_string (char *buf, size_t size) |
Generate 32 byte random string for callid's etc. | |
static char * | generate_uri (struct sip_pvt *pvt, char *buf, size_t size) |
static int | get_address_family_filter (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. | |
static int | get_domain (const char *str, char *domain, int len) |
Extract domain from SIP To/From header. | |
static struct event_state_compositor * | get_esc (const char *const event_package) |
static struct sip_esc_entry * | get_esc_entry (const char *entity_tag, struct event_state_compositor *esc) |
static const char * | get_header (const struct sip_request *req, const char *name) |
Get header from SIP request. | |
static struct ast_variable * | get_insecure_variable_from_config (struct ast_config *config) |
static struct ast_variable * | get_insecure_variable_from_sippeers (const char *column, const char *value) |
static struct ast_variable * | get_insecure_variable_from_sipregs (const char *column, const char *value, struct ast_variable **var) |
static int | get_ip_and_port_from_sdp (struct sip_request *req, const enum media_type media, struct ast_sockaddr *addr) |
static int | get_msg_text (char *buf, int len, struct sip_request *req) |
Get message body from a SIP request. | |
static const char * | get_name_from_variable (const struct ast_variable *var) |
static void | get_our_media_address (struct sip_pvt *p, int needvideo, int needtext, struct ast_sockaddr *addr, struct ast_sockaddr *vaddr, struct ast_sockaddr *taddr, struct ast_sockaddr *dest, struct ast_sockaddr *vdest, struct ast_sockaddr *tdest) |
Set all IP media addresses for this call. | |
static int | get_pai (struct sip_pvt *p, struct sip_request *req) |
Parse the parts of the P-Asserted-Identity header on an incoming packet. Returns 1 if a valid header is found and it is different from the current caller id. | |
static 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_info (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno) |
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_message (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno) |
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 int | initialize_udptl (struct sip_pvt *p) |
static void | initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, const char *const explicit_uri) |
Initiate new SIP request to peer/user. | |
static const char * | insecure2str (int mode) |
Convert Insecure setting to printable string. | |
static int | interpret_t38_parameters (struct sip_pvt *p, const struct ast_control_t38_parameters *parameters) |
Helper function which updates T.38 capability information and triggers a reinvite. | |
static int | is_method_allowed (unsigned int *allowed_methods, enum sipmethod method) |
Check if method is allowed for a device or a dialog. | |
static void | list_route (struct sip_route *route) |
List all routes - mostly for debugging. | |
static int | load_module (void) |
PBX load module - initialization. | |
static int | local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno, int *nounlock) |
Find all call legs and bridge transferee with target called from handle_request_refer. | |
static void | lws2sws (struct ast_str *data) |
Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled. | |
static void | make_our_tag (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 int | match_and_cleanup_peer_sched (void *peerobj, void *arg, int flags) |
static enum match_req_res | match_req_to_dialog (struct sip_pvt *sip_pvt_ptr, struct match_req_args *arg) |
static int | method_match (enum sipmethod id, const char *name) |
returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send | |
static void | mwi_event_cb (const struct ast_event *event, void *userdata) |
Receive MWI events that we have subscribed to. | |
static void | network_change_event_cb (const struct ast_event *, void *) |
static int | network_change_event_sched_cb (const void *data) |
static void | network_change_event_subscribe (void) |
static void | network_change_event_unsubscribe (void) |
static struct sip_proxy * | obproxy_get (struct sip_pvt *dialog, struct sip_peer *peer) |
Get default outbound proxy or global proxy. | |
static void | on_dns_update_mwi (struct ast_sockaddr *old, struct ast_sockaddr *new, void *data) |
static void | on_dns_update_peer (struct ast_sockaddr *old, struct ast_sockaddr *new, void *data) |
static void | on_dns_update_registry (struct ast_sockaddr *old, struct ast_sockaddr *new, void *data) |
static unsigned int | parse_allowed_methods (struct sip_request *req) |
parse the Allow header to see what methods the endpoint we are communicating with allows. | |
static void | parse_copy (struct sip_request *dst, const struct sip_request *src) |
Copy SIP request, parse it. | |
static int | parse_minse (const char *p_hdrval, int *const p_interval) |
Session-Timers: Function for parsing Min-SE header. | |
static void | parse_moved_contact (struct sip_pvt *p, struct sip_request *req, char **name, char **number, int set_call_forward) |
Parse 302 Moved temporalily response. | |
static int | parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req) |
Save contact header for 200 OK on INVITE. | |
static enum parse_register_result | parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req) |
Parse contact header and save registration (peer registration). | |
static int | parse_request (struct sip_request *req) |
Parse a SIP message. | |
static int | parse_session_expires (const char *p_hdrval, int *const p_interval, enum st_refresher *const p_ref) |
Session-Timers: Function for parsing Session-Expires header. | |
static int | parse_uri_legacy_check (char *uri, const char *scheme, char **user, char **pass, char **hostport, char **transport) |
parse uri in a way that allows semicolon stripping if legacy mode is enabled | |
static int | peer_cmp_cb (void *obj, void *arg, int flags) |
static int | peer_dump_func (void *userobj, void *arg, int flags) |
static int | peer_hash_cb (const void *obj, const int flags) |
static int | peer_ipcmp_cb (void *obj, void *arg, int flags) |
static int | peer_iphash_cb (const void *obj, const int flags) |
static void | peer_mailboxes_to_str (struct ast_str **mailbox_str, struct sip_peer *peer) |
list peer mailboxes to CLI | |
static int | peer_markall_func (void *device, void *arg, int flags) |
static void | peer_sched_cleanup (struct sip_peer *peer) |
static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
int | peercomparefunc (const void *a, const void *b) |
static int | peers_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
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 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 struct sip_peer * | realtime_peer (const char *newpeername, struct ast_sockaddr *addr, int devstate_only, int which_objects) |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf Checks the "sipregs" realtime family from extconfig.conf if it's configured. This returns a pointer to a peer and because we use build_peer, we can rest assured that the refcount is bumped. | |
static int | realtime_peer_by_addr (const char **name, struct ast_sockaddr *addr, const char *ipaddr, struct ast_variable **var, struct ast_variable **varregs) |
static int | realtime_peer_by_name (const char *const *name, struct ast_sockaddr *addr, const char *ipaddr, struct ast_variable **var, struct ast_variable **varregs) |
static struct ast_variable * | realtime_peer_get_sippeer_helper (const char **name, struct ast_variable **varregs) |
static void | realtime_update_peer (const char *peername, struct ast_sockaddr *addr, const char *defaultuser, const char *fullcontact, const char *useragent, int expirey, unsigned short deprecated_username, int lastms) |
Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups. | |
static void | receive_message (struct sip_pvt *p, struct sip_request *req) |
Receive SIP MESSAGE method messages. | |
static struct sip_peer * | ref_peer (struct sip_peer *peer, char *tag) |
static void | ref_proxy (struct sip_pvt *pvt, struct sip_proxy *proxy) |
maintain proper refcounts for a sip_pvt's outboundproxy | |
static const char * | referstatus2str (enum referstatus rstatus) |
Convert transfer status to string. | |
static void | reg_source_db (struct sip_peer *peer) |
Get registration details from Asterisk DB. | |
static void | register_peer_exten (struct sip_peer *peer, int onoff) |
Automatically add peer extension to dial plan. | |
static enum check_auth_result | register_verify (struct sip_pvt *p, struct ast_sockaddr *addr, struct sip_request *req, const char *uri) |
Verify registration of user
| |
static struct sip_registry * | registry_addref (struct sip_registry *reg, char *tag) |
Add object reference to SIP registry. | |
static void * | registry_unref (struct sip_registry *reg, char *tag) |
static const char * | regstate2str (enum sipregistrystate regstate) |
Convert registration state status to string. | |
static int | 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 | 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) |
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 void | sip_epa_unregister_all (void) |
static int | sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links | |
static const char * | sip_get_callid (struct ast_channel *chan) |
Deliver SIP call ID for the call. | |
static int | sip_get_cc_information (struct sip_request *req, char *subscribe_uri, size_t size, enum ast_cc_service_type *service) |
static format_t | sip_get_codec (struct ast_channel *chan) |
static enum ast_rtp_glue_result | sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance) |
static enum ast_rtp_glue_result | sip_get_trtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance) |
static struct ast_udptl * | sip_get_udptl_peer (struct ast_channel *chan) |
static enum ast_rtp_glue_result | sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance) |
static void | sip_handle_cc (struct sip_pvt *pvt, struct sip_request *req, enum ast_cc_service_type service) |
static int | sip_hangup (struct ast_channel *ast) |
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup | |
static int | sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen) |
Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc. | |
static int | sip_is_xml_parsable (void) |
static int | sip_monitor_instance_cmp_fn (void *obj, void *arg, int flags) |
static void | sip_monitor_instance_destructor (void *data) |
static int | sip_monitor_instance_hash_fn (const void *obj, const int flags) |
static struct sip_monitor_instance * | sip_monitor_instance_init (int core_id, const char *const subscribe_uri, const char *const peername, const char *const device_name) |
static const char * | sip_nat_mode (const struct sip_pvt *p) |
Display SIP nat mode. | |
static struct ast_channel * | sip_new (struct sip_pvt *i, int state, const char *title, const char *linkedid) |
Initiate a call in the SIP channel. | |
static int | sip_notify_allocate (struct sip_pvt *p) |
Allocate SIP refer structure. | |
static int | sip_offer_timer_expire (const void *data) |
static int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno, const char *park_exten, const char *park_context) |
static void * | sip_park_thread (void *stuff) |
Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup. | |
static void | sip_peer_hold (struct sip_pvt *p, int hold) |
Change onhold state of a peer using a pvt structure. | |
static int | sip_pickup (struct ast_channel *chan) |
Pickup a call using the subsystem in features.c This is executed in a separate thread. | |
static void * | sip_pickup_thread (void *stuff) |
SIP pickup support function Starts in a new thread, then pickup the call. | |
static 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 struct ast_channel * | sip_pvt_lock_full (struct sip_pvt *pvt) |
static char * | sip_qualify_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Send an OPTIONS packet to a SIP peer. | |
static int | sip_queryoption (struct ast_channel *chan, int option, void *data, int *datalen) |
Query an option on a SIP dialog. | |
static struct ast_frame * | sip_read (struct ast_channel *ast) |
Read SIP RTP from channel. | |
static struct ast_sockaddr * | sip_real_dst (const struct sip_pvt *p) |
The real destination address for a write. | |
static const char * | sip_reason_code_to_str (enum AST_REDIRECTING_REASON code) |
static enum AST_REDIRECTING_REASON | sip_reason_str_to_code (const char *text) |
static int | sip_refer_allocate (struct sip_pvt *p) |
Allocate SIP refer structure. | |
static int | sip_reg_timeout (const void *data) |
Registration timeout, register again Registered as a timeout handler during transmit_register(), to retransmit the packet if a reply does not come back. This is called by the scheduler so the event is not pending anymore when we are called. | |
static int | sip_register (const char *value, int lineno) |
create sip_registry object from register=> line in sip.conf and link into reg container | |
static void | sip_register_tests (void) |
SIP test registration. | |
static void | sip_registry_destroy (struct sip_registry *reg) |
Destroy registry object Objects created with the register= statement in static configuration. | |
static int | sip_reinvite_retry (const void *data) |
Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler. | |
static char * | sip_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Force reload of module from cli. | |
static int | sip_removeheader (struct ast_channel *chan, const char *data) |
Remove SIP headers added previously with SipAddHeader application. | |
static struct ast_channel * | sip_request_call (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause) |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here. | |
static int | sip_reregister (const void *data) |
Update registration with SIP Proxy. Called from the scheduler when the previous registration expires, so we don't have to cancel the pending event. We assume the reference so the sip_registry is valid, since it is stored in the scheduled event anyways. | |
static struct ast_frame * | sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect) |
Read RTP from network. | |
static const char * | sip_sanitized_host (const char *host) |
void | sip_scheddestroy (struct sip_pvt *p, int ms) |
Schedule destruction of SIP dialog. | |
void | sip_scheddestroy_final (struct sip_pvt *p, int ms) |
Schedule final destruction of SIP dialog. This can not be canceled. This function is used to keep a dialog around for a period of time in order to properly respond to any retransmits. | |
static void | sip_send_all_mwi_subscriptions (void) |
Send all MWI subscriptions. | |
static void | sip_send_all_registers (void) |
Send all known registrations. | |
static int | sip_send_mwi_to_peer (struct sip_peer *peer, int cache_only) |
Send message waiting indication to alert peer that they've got voicemail. | |
static int | sip_senddigit_begin (struct ast_channel *ast, char digit) |
static int | sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration) |
Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously. | |
static int | sip_sendhtml (struct ast_channel *chan, int subclass, const char *data, int datalen) |
Send message with Access-URL header, if this is an HTML URL only! | |
static int | sip_sendtext (struct ast_channel *ast, const char *text) |
static char * | sip_set_history (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Enable/Disable SIP History logging (CLI). | |
static void | sip_set_redirstr (struct sip_pvt *p, char *reason) |
Translate referring cause. | |
static int | sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, format_t codecs, int nat_active) |
static int | sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl) |
static int | sip_setoption (struct ast_channel *chan, int option, void *data, int datalen) |
Set an option on a SIP dialog. | |
static char * | sip_show_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show details of one active dialog. | |
static char * | sip_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
CLI for show channels or subscriptions. This is a new-style CLI handler so a single function contains the prototype for the function, the 'generator' to produce multiple entries in case it is required, and the actual handler for the command. | |
static char * | sip_show_channelstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
SIP show channelstats CLI (main function). | |
static char * | sip_show_domains (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
CLI command to list local domains. | |
static char * | sip_show_history (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show history details of one dialog. | |
static char * | sip_show_inuse (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
CLI Command to show calls within limits set by call_limit. | |
static char * | sip_show_mwi (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | sip_show_objects (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
List all allocated SIP Objects (realtime or static). | |
static char * | sip_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show one peer in detail. | |
static char * | sip_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
CLI Show Peers command. | |
static char * | sip_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show SIP Registry (registrations with other SIP proxies. | |
static char * | sip_show_sched (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | sip_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
List global settings for the SIP channel. | |
static char * | sip_show_tcp (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show active TCP connections. | |
static char * | sip_show_user (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show one user in detail. | |
static char * | sip_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
CLI Command 'SIP Show Users'. | |
static int | sip_sipredirect (struct sip_pvt *p, const char *dest) |
Transfer call before connect with a 302 redirect. | |
static struct sip_st_dlg * | sip_st_alloc (struct sip_pvt *const p) |
Allocate Session-Timers struct w/in dialog. | |
static int | sip_standard_port (enum sip_transport type, int port) |
Returns the port to use for this socket. | |
static int | sip_subscribe_mwi (const char *value, int lineno) |
Parse mwi=> line in sip.conf and add to list. | |
static void | sip_subscribe_mwi_destroy (struct sip_subscription_mwi *mwi) |
Destroy MWI subscription object. | |
static int | sip_subscribe_mwi_do (const void *data) |
Send a subscription or resubscription for MWI. | |
static int | sip_t38_abort (const void *data) |
Called to deny a T38 reinvite if the core does not respond to our request. | |
static struct ast_tcptls_session_instance * | sip_tcp_locate (struct ast_sockaddr *s) |
Find thread for TCP/TLS session (based on IP/Port. | |
static void * | sip_tcp_worker_fn (void *data) |
SIP TCP connection handler. | |
static void | sip_tcptls_client_args_destructor (void *obj) |
static int | sip_tcptls_write (struct ast_tcptls_session_instance *tcptls_session, const void *buf, size_t len) |
used to indicate to a tcptls thread that data is ready to be written | |
static struct sip_threadinfo * | sip_threadinfo_create (struct ast_tcptls_session_instance *tcptls_session, int transport) |
creates a sip_threadinfo object and links it into the threadt table. | |
static void | sip_threadinfo_destructor (void *obj) |
static int | sip_transfer (struct ast_channel *ast, const char *dest) |
Transfer SIP call. | |
static char * | sip_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Unregister (force expiration) a SIP peer in the registry via CLI. | |
static void | sip_unregister_tests (void) |
SIP test registration. | |
static int | sip_write (struct ast_channel *ast, struct ast_frame *frame) |
Send frame to media channel (rtp). | |
static int | sipsock_read (int *id, int fd, short events, void *ignore) |
Read data from SIP UDP socket. | |
static int | sockaddr_is_null_or_any (const struct ast_sockaddr *addr) |
static enum st_mode | st_get_mode (struct sip_pvt *p, int no_cached) |
Get the session-timer mode. | |
static enum st_refresher | st_get_refresher (struct sip_pvt *p) |
Get the entity (UAC or UAS) that's acting as the session-timer refresher. | |
static int | st_get_se (struct sip_pvt *p, int max) |
Get Max or Min SE (session timer expiry). | |
static void | start_session_timer (struct sip_pvt *p) |
Session-Timers: Start session timer. | |
static void | state_notify_build_xml (int state, int full, const char *exten, const char *context, struct ast_str **tmp, struct sip_pvt *p, int subscribed, const char *mfrom, const char *mto) |
Builds XML portion of NOTIFY messages for presence or dialog updates. | |
static const char * | stmode2str (enum st_mode m) |
static void | stop_media_flows (struct sip_pvt *p) |
Immediately stop RTP, VRTP and UDPTL as applicable. | |
static void | stop_session_timer (struct sip_pvt *p) |
Session-Timers: Stop session timer. | |
static int | str2dtmfmode (const char *str) |
maps a string to dtmfmode, returns -1 on error | |
static enum st_mode | str2stmode (const char *s) |
static enum st_refresher | 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_all_peers_from_tables (void) |
static void | unlink_marked_peers_from_tables (void) |
static void | unlink_peer_from_tables (struct sip_peer *peer) |
static void | unlink_peers_from_tables (peer_unlink_flag_t flag) |
static int | unload_module (void) |
PBX unload module API. | |
static void * | unref_peer (struct sip_peer *peer, char *tag) |
static int | update_call_counter (struct sip_pvt *fup, int event) |
update_call_counter: Handle call_limit for SIP devices Setting a call-limit will cause calls above the limit not to be accepted. | |
static void | update_connectedline (struct sip_pvt *p, const void *data, size_t datalen) |
Notify peer that the connected line has changed. | |
static void | update_peer (struct sip_peer *p, int expire) |
Update peer data in database (if used). | |
static void | update_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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto,chan_local", } |
static struct _map_x_s | allowoverlapstr [] |
static int | apeerobjs = 0 |
static char * | app_dtmfmode = "SIPDtmfMode" |
static char * | app_sipaddheader = "SIPAddHeader" |
static char * | app_sipremoveheader = "SIPRemoveHeader" |
static struct ast_module_info * | ast_module_info = &__mod_info |
static struct sip_auth_container * | authl = NULL |
Authentication container for realm authentication. | |
static ast_mutex_t | authl_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
Global authentication container protection while adjusting the references. | |
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. | |
ao2_container * | dialogs_to_destroy |
static struct _map_x_s | dtmfstr [] |
mapping between dtmf flags and strings | |
static int | esc_etag_counter |
static const int | ESC_MAX_BUCKETS = 37 |
static struct event_state_compositor | event_state_compositors [] |
The Event State Compositors. | |
static struct ast_sockaddr | externaddr |
our external IP address/port for SIP sessions. externaddr.sin_addr is only set when we know we might be behind a NAT, and this is done using a variety of (mutually exclusive) ways from the config file: | |
static time_t | externexpire |
static char | externhost [MAXHOSTNAMELEN] |
static int | externrefresh = 10 |
static uint16_t | externtcpport |
static uint16_t | externtlsport |
static struct _map_x_s | faxecmodes [] |
static struct ast_flags | global_flags [3] = {{0}} |
static int | global_t38_maxdatagram |
static const int | HASH_DIALOG_SIZE = 563 |
static const int | HASH_PEER_SIZE = 563 |
static struct _map_x_s | insecurestr [] |
static struct ast_sockaddr | internip |
our (internal) default address/port to put in SIP/SDP messages internip is initialized picking a suitable address from one of the interfaces, and the same port number we bind to. It is used as the default address/port in SIP messages, and as the default address (but not port) in SDP messages. | |
static struct io_context * | io |
static struct ast_ha * | localaddr |
List of local networks We store "localnet" addresses from the config file into an access list, marked as 'DENY', so the call to ast_apply_ha() will return AST_SENSE_DENY for 'local' addresses, and AST_SENSE_ALLOW for 'non local' (i.e. presumably public) addresses. | |
static struct ast_sockaddr | media_address |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
static 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_store_sip_cause |
static int | global_t1 |
static int | global_t1min |
static int | global_timer_b |
static unsigned int | global_tos_audio |
static unsigned int | global_tos_sip |
static unsigned int | global_tos_text |
static unsigned int | global_tos_video |
static char | global_useragent [AST_MAX_EXTENSION] |
static struct invstate2stringtable | invitestate2string [] |
Readable descriptions of device states. | |
static int | max_expiry = DEFAULT_MAX_EXPIRY |
static int | min_expiry = DEFAULT_MIN_EXPIRY |
static int | mwi_expiry = DEFAULT_MWI_EXPIRY |
static const char | notify_config [] = "sip_notify.conf" |
static unsigned int | recordhistory |
static struct sip_settings | sip_cfg |
static struct cfsip_methods | sip_methods [] |
The core structure to setup dialogs. We parse incoming messages by using structure and then route the messages according to the type. | |
static struct sip_reasons | sip_reason_table [] |
Diversion header reasons. | |
static struct cfsubscription_types | subscription_types [] |
Subscription types that we support. We support
| |
static int | unauth_sessions = 0 |
********** 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 2219 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 14285 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
#define check_request_transport | ( | peer, | |||
tmpl | ) |
generic function for determining if a correct transport is being used to contact a peer
this is done as a macro so that the "tmpl" var can be passed either a sip_request or a sip_peer
Definition at line 2302 of file chan_sip.c.
Referenced by create_addr_from_peer(), and register_verify().
#define CONTAINER_UNLINK | ( | container, | |||
obj, | |||||
tag | ) |
Unlink the given object from the container and return TRUE if it was in the container.
Definition at line 7559 of file chan_sip.c.
Referenced by change_callid_pvt().
#define DATA_EXPORT_SIP_PEER | ( | MEMBER | ) |
Definition at line 30039 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 18272 of file chan_sip.c.
#define FORMAT "%-30.30s %-12.12s %-10.10s %-10.10s\n" |
Definition at line 18272 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 18272 of file chan_sip.c.
#define FORMAT "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n" |
Definition at line 18272 of file chan_sip.c.
#define FORMAT "%-40.40s %-20.20s %-16.16s\n" |
Definition at line 18272 of file chan_sip.c.
#define FORMAT "%-25.25s %-39.39s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n" |
Definition at line 18272 of file chan_sip.c.
#define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
Definition at line 18272 of file chan_sip.c.
#define FORMAT "%-47.47s %-9.9s %-6.6s\n" |
Definition at line 18272 of file chan_sip.c.
#define FORMAT "%-25.25s %-15.15s %-15.15s \n" |
Definition at line 18272 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 18271 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 18271 of file chan_sip.c.
#define FORMAT2 "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n" |
Definition at line 18271 of file chan_sip.c.
#define FORMAT2 "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n" |
Definition at line 18271 of file chan_sip.c.
#define FORMAT2 "%-47.47s %9.9s %6.6s\n" |
Definition at line 18271 of file chan_sip.c.
#define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
Definition at line 18271 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 702 of file chan_sip.c.
Referenced by check_user_full(), get_also_info(), get_destination(), get_refer_info(), and register_verify().
#define sip_pvt_lock | ( | x | ) | ao2_lock(x) |
Definition at line 1102 of file chan_sip.c.
Referenced by __sip_ack(), __sip_autodestruct(), auto_congest(), cb_extensionstate(), complete_sipch(), 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(), sip_answer(), sip_call(), sip_cc_agent_destructor(), sip_cc_agent_init(), sip_cc_agent_recall(), sip_cc_agent_respond(), sip_cc_monitor_request_cc(), sip_dtmfmode(), sip_fixup(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), sip_hangup(), sip_indicate(), sip_monitor_instance_destructor(), sip_new(), sip_pvt_lock_full(), sip_queryoption(), sip_read(), sip_reg_timeout(), sip_reinvite_retry(), sip_request_call(), sip_send_mwi_to_peer(), sip_senddigit_begin(), sip_senddigit_end(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_setoption(), sip_show_channel(), sip_show_history(), sip_t38_abort(), sip_transfer(), sip_write(), transmit_publish(), and update_call_counter().
#define sip_pvt_trylock | ( | x | ) | ao2_trylock(x) |
#define sip_pvt_unlock | ( | x | ) | ao2_unlock(x) |
Definition at line 1104 of file chan_sip.c.
Referenced by __sip_ack(), __sip_autodestruct(), auto_congest(), cb_extensionstate(), complete_sipch(), dialog_needdestroy(), dialog_unlink_all(), 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(), send_provisional_keepalive_full(), sip_answer(), sip_call(), sip_cc_agent_destructor(), sip_cc_agent_init(), sip_cc_agent_recall(), sip_cc_agent_respond(), sip_cc_monitor_request_cc(), sip_dtmfmode(), sip_fixup(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), sip_hangup(), sip_indicate(), sip_monitor_instance_destructor(), sip_new(), sip_pvt_lock_full(), sip_queryoption(), sip_read(), sip_reg_timeout(), sip_reinvite_retry(), sip_request_call(), sip_send_mwi_to_peer(), sip_senddigit_begin(), sip_senddigit_end(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_setoption(), sip_show_channel(), sip_show_history(), sip_t38_abort(), sip_transfer(), sip_write(), transmit_publish(), and update_call_counter().
#define UNLINK | ( | element, | |||
head, | |||||
prev | ) |
some list management macros.
Definition at line 1202 of file chan_sip.c.
Referenced by __sip_ack(), handle_request_cancel(), and retrans_pkt().
enum match_req_res |
Definition at line 7844 of file chan_sip.c.
07844 { 07845 SIP_REQ_MATCH, 07846 SIP_REQ_NOT_MATCH, 07847 SIP_REQ_LOOP_DETECTED, 07848 };
enum peer_unlink_flag_t |
Definition at line 2866 of file chan_sip.c.
02866 { 02867 SIP_PEERS_MARKED, 02868 SIP_PEERS_ALL, 02869 } peer_unlink_flag_t;
static const char * __get_header | ( | const struct sip_request * | req, | |
const char * | name, | |||
int * | start | |||
) | [static] |
Definition at line 7332 of file chan_sip.c.
References ast_skip_blanks(), find_alias(), len(), pass, and sip_cfg.
07333 { 07334 int pass; 07335 07336 /* 07337 * Technically you can place arbitrary whitespace both before and after the ':' in 07338 * a header, although RFC3261 clearly says you shouldn't before, and place just 07339 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 07340 * a good idea to say you can do it, and if you can do it, why in the hell would. 07341 * you say you shouldn't. 07342 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 07343 * and we always allow spaces after that for compatibility. 07344 */ 07345 for (pass = 0; name && pass < 2;pass++) { 07346 int x, len = strlen(name); 07347 for (x = *start; x < req->headers; x++) { 07348 const char *header = REQ_OFFSET_TO_STR(req, header[x]); 07349 if (!strncasecmp(header, name, len)) { 07350 const char *r = header + len; /* skip name */ 07351 if (sip_cfg.pedanticsipchecking) 07352 r = ast_skip_blanks(r); 07353 07354 if (*r == ':') { 07355 *start = x+1; 07356 return ast_skip_blanks(r+1); 07357 } 07358 } 07359 } 07360 if (pass == 0) /* Try aliases */ 07361 name = find_alias(name, NULL); 07362 } 07363 07364 /* Don't return NULL, so get_header is always a valid pointer */ 07365 return ""; 07366 }
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 30514 of file chan_sip.c.
static int __set_address_from_contact | ( | const char * | fullcontact, | |
struct ast_sockaddr * | addr, | |||
int | tcp | |||
) | [static] |
Definition at line 13861 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_strlen_zero(), get_transport_str2enum(), LOG_WARNING, and parse_uri_legacy_check().
Referenced by build_peer(), and set_address_from_contact().
13862 { 13863 char *hostport, *transport; 13864 char contact_buf[256]; 13865 char *contact; 13866 13867 /* Work on a copy */ 13868 ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf)); 13869 contact = contact_buf; 13870 13871 /* 13872 * We have only the part in <brackets> here so we just need to parse a SIP URI. 13873 * 13874 * Note: The outbound proxy could be using UDP between the proxy and Asterisk. 13875 * We still need to be able to send to the remote agent through the proxy. 13876 */ 13877 13878 if (parse_uri_legacy_check(contact, "sip:,sips:", &contact, NULL, &hostport, 13879 &transport)) { 13880 ast_log(LOG_WARNING, "Invalid contact uri %s (missing sip: or sips:), attempting to use anyway\n", fullcontact); 13881 } 13882 13883 /* XXX This could block for a long time XXX */ 13884 /* We should only do this if it's a name, not an IP */ 13885 /* \todo - if there's no PORT number in contact - we are required to check NAPTR/SRV records 13886 to find transport, port address and hostname. If there's a port number, we have to 13887 assume that the hostport part is a host name and only look for an A/AAAA record in DNS. 13888 */ 13889 13890 /* If we took in an invalid URI, hostport may not have been initialized */ 13891 /* ast_sockaddr_resolve requires an initialized hostport string. */ 13892 if (ast_strlen_zero(hostport)) { 13893 ast_log(LOG_WARNING, "Invalid URI: parse_uri failed to acquire hostport\n"); 13894 return -1; 13895 } 13896 13897 if (ast_sockaddr_resolve_first(addr, hostport, 0)) { 13898 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't " 13899 "resolve in DNS) : '%s'\n", hostport); 13900 return -1; 13901 } 13902 13903 /* set port */ 13904 if (!ast_sockaddr_port(addr)) { 13905 ast_sockaddr_set_port(addr, 13906 (get_transport_str2enum(transport) == 13907 SIP_TRANSPORT_TLS || 13908 !strncasecmp(fullcontact, "sips", 4)) ? 13909 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 13910 } 13911 13912 return 0; 13913 }
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 3968 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().
03969 { 03970 struct sip_pkt *cur, *prev = NULL; 03971 const char *msg = "Not Found"; /* used only for debugging */ 03972 int res = FALSE; 03973 03974 /* If we have an outbound proxy for this dialog, then delete it now since 03975 the rest of the requests in this dialog needs to follow the routing. 03976 If obforcing is set, we will keep the outbound proxy during the whole 03977 dialog, regardless of what the SIP rfc says 03978 */ 03979 if (p->outboundproxy && !p->outboundproxy->force){ 03980 ref_proxy(p, NULL); 03981 } 03982 03983 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 03984 if (cur->seqno != seqno || cur->is_resp != resp) { 03985 continue; 03986 } 03987 if (cur->is_resp || cur->method == sipmethod) { 03988 res = TRUE; 03989 msg = "Found"; 03990 if (!resp && (seqno == p->pendinginvite)) { 03991 ast_debug(1, "Acked pending invite %d\n", p->pendinginvite); 03992 p->pendinginvite = 0; 03993 } 03994 if (cur->retransid > -1) { 03995 if (sipdebug) 03996 ast_debug(4, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 03997 } 03998 /* This odd section is designed to thwart a 03999 * race condition in the packet scheduler. There are 04000 * two conditions under which deleting the packet from the 04001 * scheduler can fail. 04002 * 04003 * 1. The packet has been removed from the scheduler because retransmission 04004 * is being attempted. The problem is that if the packet is currently attempting 04005 * retransmission and we are at this point in the code, then that MUST mean 04006 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 04007 * lock temporarily to allow retransmission. 04008 * 04009 * 2. The packet has reached its maximum number of retransmissions and has 04010 * been permanently removed from the packet scheduler. If this is the case, then 04011 * the packet's retransid will be set to -1. The atomicity of the setting and checking 04012 * of the retransid to -1 is ensured since in both cases p's lock is held. 04013 */ 04014 while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) { 04015 sip_pvt_unlock(p); 04016 usleep(1); 04017 sip_pvt_lock(p); 04018 } 04019 UNLINK(cur, p->packets, prev); 04020 dialog_unref(cur->owner, "unref pkt cur->owner dialog from sip ack before freeing pkt"); 04021 if (cur->data) { 04022 ast_free(cur->data); 04023 } 04024 ast_free(cur); 04025 break; 04026 } 04027 } 04028 ast_debug(1, "Stopping retransmission on '%s' of %s %d: Match %s\n", 04029 p->callid, resp ? "Response" : "Request", seqno, msg); 04030 return res; 04031 }
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 3832 of file chan_sip.c.
References __sip_pretend_ack(), append_history, AST_CAUSE_PROTOCOL_ERROR, ast_channel_unlock, ast_channel_unref, ast_debug, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup_with_cause(), dialog_unlink_all(), LOG_WARNING, method_match(), NONE, pvt_set_needdestroy(), sip_methods, sip_pvt_lock, sip_pvt_lock_full(), sip_pvt_unlock, sip_scheddestroy(), stop_media_flows(), cfsip_methods::text, transmit_request_with_auth(), transmit_state_notify(), and TRUE.
Referenced by sip_scheddestroy(), and sip_show_sched().
03833 { 03834 struct sip_pvt *p = (struct sip_pvt *)data; 03835 struct ast_channel *owner; 03836 03837 /* If this is a subscription, tell the phone that we got a timeout */ 03838 if (p->subscribed && p->subscribed != MWI_NOTIFICATION && p->subscribed != CALL_COMPLETION) { 03839 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 03840 p->subscribed = NONE; 03841 append_history(p, "Subscribestatus", "timeout"); 03842 ast_debug(3, "Re-scheduled destruction of SIP subscription %s\n", p->callid ? p->callid : "<unknown>"); 03843 return 10000; /* Reschedule this destruction so that we know that it's gone */ 03844 } 03845 03846 /* If there are packets still waiting for delivery, delay the destruction */ 03847 if (p->packets) { 03848 if (!p->needdestroy) { 03849 char method_str[31]; 03850 ast_debug(3, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 03851 append_history(p, "ReliableXmit", "timeout"); 03852 if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) { 03853 if (method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) { 03854 pvt_set_needdestroy(p, "autodestruct"); 03855 } 03856 } 03857 return 10000; 03858 } else { 03859 /* They've had their chance to respond. Time to bail */ 03860 __sip_pretend_ack(p); 03861 } 03862 } 03863 03864 /* Reset schedule ID */ 03865 p->autokillid = -1; 03866 03867 03868 /* 03869 * Lock both the pvt and the channel safely so that we can queue up a frame. 03870 */ 03871 owner = sip_pvt_lock_full(p); 03872 if (owner) { 03873 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 03874 ast_queue_hangup_with_cause(owner, AST_CAUSE_PROTOCOL_ERROR); 03875 ast_channel_unlock(owner); 03876 ast_channel_unref(owner); 03877 } else if (p->refer && !p->alreadygone) { 03878 ast_debug(3, "Finally hanging up channel after transfer: %s\n", p->callid); 03879 stop_media_flows(p); 03880 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03881 append_history(p, "ReferBYE", "Sending BYE on transferer call leg %s", p->callid); 03882 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03883 } else { 03884 append_history(p, "AutoDestroy", "%s", p->callid); 03885 ast_debug(3, "Auto destroying SIP dialog '%s'\n", p->callid); 03886 sip_pvt_unlock(p); 03887 dialog_unlink_all(p); /* once it's unlinked and unrefd everywhere, it'll be freed automagically */ 03888 sip_pvt_lock(p); 03889 /* dialog_unref(p, "unref dialog-- no other matching conditions"); -- unlink all now should finish off the dialog's references and free it. */ 03890 /* sip_destroy(p); */ /* Go ahead and destroy dialog. All attempts to recover is done */ 03891 /* sip_destroy also absorbs the reference */ 03892 } 03893 03894 sip_pvt_unlock(p); 03895 03896 dialog_unref(p, "The ref to a dialog passed to this sched callback is going out of scope; unref it."); 03897 03898 return 0; 03899 }
void __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner, | |||
int | lockdialoglist | |||
) |
Execute destruction of SIP dialog structure, release memory.
Definition at line 5736 of file chan_sip.c.
References ao2_ref, ao2_t_ref, ast_cc_config_params_destroy(), ast_channel_lock, ast_channel_unlock, ast_debug, ast_free, ast_free_ha(), AST_LIST_REMOVE_HEAD, ast_rtp_instance_destroy(), AST_SOFTHANGUP_DEV, ast_string_field_free_memory, ast_test_flag, ast_udptl_destroy(), ast_variables_destroy(), ast_verbose, deinit_req(), dumphistory, free_old_route(), registry_unref(), sip_debug_test_pvt(), sip_dump_history(), sip_methods, sip_srtp_destroy(), stop_session_timer(), cfsip_methods::text, unref_peer(), and update_call_counter().
Referenced by sip_destroy().
05737 { 05738 struct sip_request *req; 05739 05740 /* Destroy Session-Timers if allocated */ 05741 if (p->stimer) { 05742 p->stimer->quit_flag = 1; 05743 stop_session_timer(p); 05744 ast_free(p->stimer); 05745 p->stimer = NULL; 05746 } 05747 05748 if (sip_debug_test_pvt(p)) 05749 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 05750 05751 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 05752 update_call_counter(p, DEC_CALL_LIMIT); 05753 ast_debug(2, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 05754 } 05755 05756 /* Unlink us from the owner if we have one */ 05757 if (p->owner) { 05758 if (lockowner) 05759 ast_channel_lock(p->owner); 05760 ast_debug(1, "Detaching from %s\n", p->owner->name); 05761 p->owner->tech_pvt = NULL; 05762 /* Make sure that the channel knows its backend is going away */ 05763 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 05764 if (lockowner) 05765 ast_channel_unlock(p->owner); 05766 /* Give the channel a chance to react before deallocation */ 05767 usleep(1); 05768 } 05769 05770 /* Remove link from peer to subscription of MWI */ 05771 if (p->relatedpeer && p->relatedpeer->mwipvt) 05772 p->relatedpeer->mwipvt = dialog_unref(p->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt"); 05773 if (p->relatedpeer && p->relatedpeer->call == p) 05774 p->relatedpeer->call = dialog_unref(p->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself"); 05775 05776 if (p->relatedpeer) 05777 p->relatedpeer = unref_peer(p->relatedpeer,"unsetting a dialog relatedpeer field in sip_destroy"); 05778 05779 if (p->registry) { 05780 if (p->registry->call == p) 05781 p->registry->call = dialog_unref(p->registry->call, "nulling out the registry's call dialog field in unlink_all"); 05782 p->registry = registry_unref(p->registry, "delete p->registry"); 05783 } 05784 05785 if (p->mwi) { 05786 p->mwi->call = NULL; 05787 } 05788 05789 if (dumphistory) 05790 sip_dump_history(p); 05791 05792 if (p->options) 05793 ast_free(p->options); 05794 05795 if (p->notify) { 05796 ast_variables_destroy(p->notify->headers); 05797 ast_free(p->notify->content); 05798 ast_free(p->notify); 05799 } 05800 if (p->rtp) { 05801 ast_rtp_instance_destroy(p->rtp); 05802 } 05803 if (p->vrtp) { 05804 ast_rtp_instance_destroy(p->vrtp); 05805 } 05806 if (p->trtp) { 05807 ast_rtp_instance_destroy(p->trtp); 05808 } 05809 if (p->udptl) 05810 ast_udptl_destroy(p->udptl); 05811 if (p->refer) 05812 ast_free(p->refer); 05813 if (p->route) { 05814 free_old_route(p->route); 05815 p->route = NULL; 05816 } 05817 deinit_req(&p->initreq); 05818 05819 /* Clear history */ 05820 if (p->history) { 05821 struct sip_history *hist; 05822 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 05823 ast_free(hist); 05824 p->history_entries--; 05825 } 05826 ast_free(p->history); 05827 p->history = NULL; 05828 } 05829 05830 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 05831 ast_free(req); 05832 } 05833 05834 if (p->chanvars) { 05835 ast_variables_destroy(p->chanvars); 05836 p->chanvars = NULL; 05837 } 05838 05839 if (p->srtp) { 05840 sip_srtp_destroy(p->srtp); 05841 p->srtp = NULL; 05842 } 05843 05844 if (p->vsrtp) { 05845 sip_srtp_destroy(p->vsrtp); 05846 p->vsrtp = NULL; 05847 } 05848 05849 if (p->tsrtp) { 05850 sip_srtp_destroy(p->tsrtp); 05851 p->tsrtp = NULL; 05852 } 05853 05854 if (p->directmediaha) { 05855 ast_free_ha(p->directmediaha); 05856 p->directmediaha = NULL; 05857 } 05858 05859 ast_string_field_free_memory(p); 05860 05861 ast_cc_config_params_destroy(p->cc_params); 05862 05863 if (p->epa_entry) { 05864 ao2_ref(p->epa_entry, -1); 05865 p->epa_entry = NULL; 05866 } 05867 05868 if (p->socket.tcptls_session) { 05869 ao2_ref(p->socket.tcptls_session, -1); 05870 p->socket.tcptls_session = NULL; 05871 } 05872 05873 if (p->peerauth) { 05874 ao2_t_ref(p->peerauth, -1, "Removing active peer authentication"); 05875 p->peerauth = NULL; 05876 } 05877 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 13071 of file chan_sip.c.
References transmit_register().
Referenced by sip_reregister().
13072 { 13073 int res; 13074 13075 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 13076 return res; 13077 }
void __sip_pretend_ack | ( | struct sip_pvt * | p | ) |
Pretend to ack all packets called with p locked.
Definition at line 4035 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().
04036 { 04037 struct sip_pkt *cur = NULL; 04038 04039 while (p->packets) { 04040 int method; 04041 if (cur == p->packets) { 04042 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 04043 return; 04044 } 04045 cur = p->packets; 04046 method = (cur->method) ? cur->method : find_sip_method(cur->data->str); 04047 __sip_ack(p, cur->seqno, cur->is_resp, method); 04048 } 04049 }
static enum sip_result __sip_reliable_xmit | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
struct ast_str * | data, | |||
int | fatal, | |||
int | sipmethod | |||
) | [static] |
Definition at line 3741 of file chan_sip.c.
References __sip_xmit(), append_history, ast_calloc, ast_debug, ast_free, ast_log(), AST_PTHREADT_NULL, AST_SCHED_DEL, AST_SCHED_REPLACE_VARIABLE, ast_str_buffer(), ast_str_create(), ast_str_set(), ast_str_strlen(), ast_tvnow(), DEFAULT_RETRANS, LOG_ERROR, monitor_thread, retrans_pkt(), and sipdebug.
Referenced by send_request(), and send_response().
03742 { 03743 struct sip_pkt *pkt = NULL; 03744 int siptimer_a = DEFAULT_RETRANS; 03745 int xmitres = 0; 03746 int respid; 03747 03748 if (sipmethod == SIP_INVITE) { 03749 /* Note this is a pending invite */ 03750 p->pendinginvite = seqno; 03751 } 03752 03753 /* If the transport is something reliable (TCP or TLS) then don't really send this reliably */ 03754 /* I removed the code from retrans_pkt that does the same thing so it doesn't get loaded into the scheduler */ 03755 /*! \todo According to the RFC some packets need to be retransmitted even if its TCP, so this needs to get revisited */ 03756 if (!(p->socket.type & SIP_TRANSPORT_UDP)) { 03757 xmitres = __sip_xmit(p, data); /* Send packet */ 03758 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 03759 append_history(p, "XmitErr", "%s", fatal ? "(Critical)" : "(Non-critical)"); 03760 return AST_FAILURE; 03761 } else { 03762 return AST_SUCCESS; 03763 } 03764 } 03765 03766 if (!(pkt = ast_calloc(1, sizeof(*pkt)))) { 03767 return AST_FAILURE; 03768 } 03769 /* copy data, add a terminator and save length */ 03770 if (!(pkt->data = ast_str_create(ast_str_strlen(data)))) { 03771 ast_free(pkt); 03772 return AST_FAILURE; 03773 } 03774 ast_str_set(&pkt->data, 0, "%s%s", data->str, "\0"); 03775 /* copy other parameters from the caller */ 03776 pkt->method = sipmethod; 03777 pkt->seqno = seqno; 03778 pkt->is_resp = resp; 03779 pkt->is_fatal = fatal; 03780 pkt->owner = dialog_ref(p, "__sip_reliable_xmit: setting pkt->owner"); 03781 pkt->next = p->packets; 03782 p->packets = pkt; /* Add it to the queue */ 03783 if (resp) { 03784 /* Parse out the response code */ 03785 if (sscanf(ast_str_buffer(pkt->data), "SIP/2.0 %30u", &respid) == 1) { 03786 pkt->response_code = respid; 03787 } 03788 } 03789 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 03790 pkt->retransid = -1; 03791 if (pkt->timer_t1) { 03792 siptimer_a = pkt->timer_t1; 03793 } 03794 03795 pkt->time_sent = ast_tvnow(); /* time packet was sent */ 03796 pkt->retrans_stop_time = 64 * (pkt->timer_t1 ? pkt->timer_t1 : DEFAULT_TIMER_T1); /* time in ms after pkt->time_sent to stop retransmission */ 03797 03798 /* Schedule retransmission */ 03799 AST_SCHED_REPLACE_VARIABLE(pkt->retransid, sched, siptimer_a, retrans_pkt, pkt, 1); 03800 if (sipdebug) { 03801 ast_debug(4, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 03802 } 03803 03804 xmitres = __sip_xmit(pkt->owner, pkt->data); /* Send packet */ 03805 03806 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 03807 append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 03808 ast_log(LOG_ERROR, "Serious Network Trouble; __sip_xmit returns error for pkt data\n"); 03809 AST_SCHED_DEL(sched, pkt->retransid); 03810 p->packets = pkt->next; 03811 pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now"); 03812 ast_free(pkt->data); 03813 ast_free(pkt); 03814 return AST_FAILURE; 03815 } else { 03816 /* This is odd, but since the retrans timer starts at 500ms and the do_monitor thread 03817 * only wakes up every 1000ms by default, we have to poke the thread here to make 03818 * sure it successfully detects this must be retransmitted in less time than 03819 * it usually sleeps for. Otherwise it might not retransmit this packet for 1000ms. */ 03820 if (monitor_thread != AST_PTHREADT_NULL) { 03821 pthread_kill(monitor_thread, SIGURG); 03822 } 03823 return AST_SUCCESS; 03824 } 03825 }
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 4052 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().
04053 { 04054 struct sip_pkt *cur; 04055 int res = FALSE; 04056 04057 for (cur = p->packets; cur; cur = cur->next) { 04058 if (cur->seqno == seqno && cur->is_resp == resp && 04059 (cur->is_resp || method_match(sipmethod, cur->data->str))) { 04060 /* this is our baby */ 04061 if (cur->retransid > -1) { 04062 if (sipdebug) 04063 ast_debug(4, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 04064 } 04065 AST_SCHED_DEL(sched, cur->retransid); 04066 res = TRUE; 04067 break; 04068 } 04069 } 04070 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"); 04071 return res; 04072 }
static int __sip_subscribe_mwi_do | ( | struct sip_subscription_mwi * | mwi | ) | [static] |
Actually setup an MWI subscription or resubscribe.
Definition at line 12405 of file chan_sip.c.
References ast_dnsmgr_lookup_cb(), ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_port, ast_sockaddr_set_port, ast_string_field_set, ast_strlen_zero(), ASTOBJ_REF, ASTOBJ_UNREF, bindaddr, build_contact(), build_via(), change_callid_pvt(), create_addr(), dialog_unlink_all(), get_address_family_filter(), get_srv_protocol(), get_srv_service(), MAXHOSTNAMELEN, mwi_expiry, obproxy_get(), on_dns_update_mwi(), ref_proxy(), set_socket_transport(), sip_alloc(), sip_cfg, sip_subscribe_mwi_destroy(), and transmit_invite().
Referenced by sip_subscribe_mwi_do().
12406 { 12407 /* If we have no DNS manager let's do a lookup */ 12408 if (!mwi->dnsmgr) { 12409 char transport[MAXHOSTNAMELEN]; 12410 snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(mwi->transport), get_srv_protocol(mwi->transport)); 12411 12412 mwi->us.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */ 12413 ASTOBJ_REF(mwi); /* Add a ref for storing the mwi on the dnsmgr for updates */ 12414 ast_dnsmgr_lookup_cb(mwi->hostname, &mwi->us, &mwi->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_mwi, mwi); 12415 if (!mwi->dnsmgr) { 12416 ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy); /* dnsmgr disabled, remove reference */ 12417 } 12418 } 12419 12420 /* If we already have a subscription up simply send a resubscription */ 12421 if (mwi->call) { 12422 transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 0, NULL); 12423 return 0; 12424 } 12425 12426 /* Create a dialog that we will use for the subscription */ 12427 if (!(mwi->call = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL))) { 12428 return -1; 12429 } 12430 12431 ref_proxy(mwi->call, obproxy_get(mwi->call, NULL)); 12432 12433 if (!ast_sockaddr_port(&mwi->us) && mwi->portno) { 12434 ast_sockaddr_set_port(&mwi->us, mwi->portno); 12435 } 12436 12437 /* Setup the destination of our subscription */ 12438 if (create_addr(mwi->call, mwi->hostname, &mwi->us, 0, NULL)) { 12439 dialog_unlink_all(mwi->call); 12440 mwi->call = dialog_unref(mwi->call, "unref dialog after unlink_all"); 12441 return 0; 12442 } 12443 12444 mwi->call->expiry = mwi_expiry; 12445 12446 if (!mwi->dnsmgr && mwi->portno) { 12447 ast_sockaddr_set_port(&mwi->call->sa, mwi->portno); 12448 ast_sockaddr_set_port(&mwi->call->recv, mwi->portno); 12449 } else { 12450 mwi->portno = ast_sockaddr_port(&mwi->call->sa); 12451 } 12452 12453 /* Set various other information */ 12454 if (!ast_strlen_zero(mwi->authuser)) { 12455 ast_string_field_set(mwi->call, peername, mwi->authuser); 12456 ast_string_field_set(mwi->call, authname, mwi->authuser); 12457 ast_string_field_set(mwi->call, fromuser, mwi->authuser); 12458 } else { 12459 ast_string_field_set(mwi->call, peername, mwi->username); 12460 ast_string_field_set(mwi->call, authname, mwi->username); 12461 ast_string_field_set(mwi->call, fromuser, mwi->username); 12462 } 12463 ast_string_field_set(mwi->call, username, mwi->username); 12464 if (!ast_strlen_zero(mwi->secret)) { 12465 ast_string_field_set(mwi->call, peersecret, mwi->secret); 12466 } 12467 set_socket_transport(&mwi->call->socket, mwi->transport); 12468 mwi->call->socket.port = htons(mwi->portno); 12469 ast_sip_ouraddrfor(&mwi->call->sa, &mwi->call->ourip, mwi->call); 12470 build_contact(mwi->call); 12471 build_via(mwi->call); 12472 12473 /* Change the dialog callid. */ 12474 change_callid_pvt(mwi->call, NULL); 12475 12476 ast_set_flag(&mwi->call->flags[0], SIP_OUTGOING); 12477 12478 /* Associate the call with us */ 12479 mwi->call->mwi = ASTOBJ_REF(mwi); 12480 12481 mwi->call->subscribed = MWI_NOTIFICATION; 12482 12483 /* Actually send the packet */ 12484 transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 2, NULL); 12485 12486 return 0; 12487 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
struct ast_str * | data | |||
) | [static] |
Definition at line 3339 of file chan_sip.c.
References ast_debug, ast_log(), ast_sendto(), ast_sockaddr_stringify(), ast_str_strlen(), errno, get_transport_pvt(), LOG_WARNING, sip_prepare_socket(), sip_real_dst(), and sip_tcptls_write().
Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().
03340 { 03341 int res = 0; 03342 const struct ast_sockaddr *dst = sip_real_dst(p); 03343 03344 ast_debug(2, "Trying to put '%.11s' onto %s socket destined for %s\n", data->str, get_transport_pvt(p), ast_sockaddr_stringify(dst)); 03345 03346 if (sip_prepare_socket(p) < 0) { 03347 return XMIT_ERROR; 03348 } 03349 03350 if (p->socket.type == SIP_TRANSPORT_UDP) { 03351 res = ast_sendto(p->socket.fd, data->str, ast_str_strlen(data), 0, dst); 03352 } else if (p->socket.tcptls_session) { 03353 res = sip_tcptls_write(p->socket.tcptls_session, data->str, ast_str_strlen(data)); 03354 } else { 03355 ast_debug(2, "Socket type is TCP but no tcptls_session is present to write to\n"); 03356 return XMIT_ERROR; 03357 } 03358 03359 if (res == -1) { 03360 switch (errno) { 03361 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 03362 case EHOSTUNREACH: /* Host can't be reached */ 03363 case ENETDOWN: /* Interface down */ 03364 case ENETUNREACH: /* Network failure */ 03365 case ECONNREFUSED: /* ICMP port unreachable */ 03366 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 03367 } 03368 } 03369 if (res != ast_str_strlen(data)) { 03370 ast_log(LOG_WARNING, "sip_xmit of %p (len %zu) to %s returned %d: %s\n", data, ast_str_strlen(data), ast_sockaddr_stringify(dst), res, strerror(errno)); 03371 } 03372 03373 return res; 03374 }
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 10429 of file chan_sip.c.
References add_cc_call_info_to_response(), add_diversion_header(), add_header(), add_rpid(), ast_cause2str(), ast_clear_flag, ast_log(), ast_test_flag, get_header(), hangup_sip2cause(), LOG_WARNING, respprep(), and send_response().
Referenced by transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().
10430 { 10431 struct sip_request resp; 10432 int seqno = 0; 10433 10434 if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) { 10435 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 10436 return -1; 10437 } 10438 respprep(&resp, p, msg, req); 10439 10440 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) 10441 && ast_test_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND) 10442 && (!strncmp(msg, "180", 3) || !strncmp(msg, "183", 3))) { 10443 ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 10444 add_rpid(&resp, p); 10445 } 10446 if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) { 10447 add_cc_call_info_to_response(p, &resp); 10448 } 10449 10450 /* If we are sending a 302 Redirect we can add a diversion header if the redirect information is set */ 10451 if (!strncmp(msg, "302", 3)) { 10452 add_diversion_header(&resp, p); 10453 } 10454 10455 /* If we are cancelling an incoming invite for some reason, add information 10456 about the reason why we are doing this in clear text */ 10457 if (p->method == SIP_INVITE && msg[0] != '1') { 10458 char buf[20]; 10459 10460 if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON)) { 10461 int hangupcause = 0; 10462 10463 if (p->owner && p->owner->hangupcause) { 10464 hangupcause = p->owner->hangupcause; 10465 } else if (p->hangupcause) { 10466 hangupcause = p->hangupcause; 10467 } else { 10468 int respcode; 10469 if (sscanf(msg, "%30d ", &respcode)) 10470 hangupcause = hangup_sip2cause(respcode); 10471 } 10472 10473 if (hangupcause) { 10474 sprintf(buf, "Q.850;cause=%i", hangupcause & 0x7f); 10475 add_header(&resp, "Reason", buf); 10476 } 10477 } 10478 10479 if (p->owner && p->owner->hangupcause) { 10480 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 10481 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 10482 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 10483 } 10484 } 10485 return send_response(p, &resp, reliable, seqno); 10486 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 30514 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 17281 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().
17282 { 17283 struct sip_peer *peer; 17284 int load_realtime; 17285 17286 if (argc < 4) 17287 return CLI_SHOWUSAGE; 17288 17289 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 17290 if ((peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0))) { 17291 sip_poke_peer(peer, 1); 17292 unref_peer(peer, "qualify: done with peer"); 17293 } else if (type == 0) { 17294 ast_cli(fd, "Peer '%s' not found\n", argv[3]); 17295 } else { 17296 astman_send_error(s, m, "Peer not found"); 17297 } 17298 return CLI_SUCCESS; 17299 }
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 17366 of file chan_sip.c.
References allowoverlap2str(), ao2_lock, ao2_t_ref, ao2_unlock, ARRAY_LEN, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), AST_CLI_YESNO, ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), AST_LIST_TRAVERSE, ast_print_group(), ast_sched_when(), ast_sockaddr_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_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().
17367 { 17368 char status[30] = ""; 17369 char cbuf[256]; 17370 struct sip_peer *peer; 17371 char codec_buf[512]; 17372 struct ast_codec_pref *pref; 17373 struct ast_variable *v; 17374 int x = 0, load_realtime; 17375 format_t codec = 0; 17376 int realtimepeers; 17377 17378 realtimepeers = ast_check_realtime("sippeers"); 17379 17380 if (argc < 4) 17381 return CLI_SHOWUSAGE; 17382 17383 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 17384 peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0); 17385 17386 if (s) { /* Manager */ 17387 if (peer) { 17388 const char *id = astman_get_header(m, "ActionID"); 17389 17390 astman_append(s, "Response: Success\r\n"); 17391 if (!ast_strlen_zero(id)) 17392 astman_append(s, "ActionID: %s\r\n", id); 17393 } else { 17394 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]); 17395 astman_send_error(s, m, cbuf); 17396 return CLI_SUCCESS; 17397 } 17398 } 17399 if (peer && type==0 ) { /* Normal listing */ 17400 struct ast_str *mailbox_str = ast_str_alloca(512); 17401 struct sip_auth_container *credentials; 17402 17403 ao2_lock(peer); 17404 credentials = peer->auth; 17405 if (credentials) { 17406 ao2_t_ref(credentials, +1, "Ref peer auth for show"); 17407 } 17408 ao2_unlock(peer); 17409 17410 ast_cli(fd, "\n\n"); 17411 ast_cli(fd, " * Name : %s\n", peer->name); 17412 if (realtimepeers) { /* Realtime is enabled */ 17413 ast_cli(fd, " Realtime peer: %s\n", peer->is_realtime ? "Yes, cached" : "No"); 17414 } 17415 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 17416 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 17417 ast_cli(fd, " Remote Secret: %s\n", ast_strlen_zero(peer->remotesecret)?"<Not set>":"<Set>"); 17418 if (credentials) { 17419 struct sip_auth *auth; 17420 17421 AST_LIST_TRAVERSE(&credentials->list, auth, node) { 17422 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s %s\n", 17423 auth->realm, 17424 auth->username, 17425 !ast_strlen_zero(auth->secret) 17426 ? "<Secret set>" 17427 : (!ast_strlen_zero(auth->md5secret) 17428 ? "<MD5secret set>" : "<Not set>")); 17429 } 17430 ao2_t_ref(credentials, -1, "Unref peer auth for show"); 17431 } 17432 ast_cli(fd, " Context : %s\n", peer->context); 17433 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 17434 ast_cli(fd, " Language : %s\n", peer->language); 17435 if (!ast_strlen_zero(peer->accountcode)) 17436 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 17437 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 17438 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 17439 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 17440 if (!ast_strlen_zero(peer->fromuser)) 17441 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 17442 if (!ast_strlen_zero(peer->fromdomain)) 17443 ast_cli(fd, " FromDomain : %s Port %d\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT); 17444 ast_cli(fd, " Callgroup : "); 17445 print_group(fd, peer->callgroup, 0); 17446 ast_cli(fd, " Pickupgroup : "); 17447 print_group(fd, peer->pickupgroup, 0); 17448 peer_mailboxes_to_str(&mailbox_str, peer); 17449 ast_cli(fd, " MOH Suggest : %s\n", peer->mohsuggest); 17450 ast_cli(fd, " Mailbox : %s\n", mailbox_str->str); 17451 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 17452 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 17453 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 17454 ast_cli(fd, " Max forwards : %d\n", peer->maxforwards); 17455 if (peer->busy_level) 17456 ast_cli(fd, " Busy level : %d\n", peer->busy_level); 17457 ast_cli(fd, " Dynamic : %s\n", AST_CLI_YESNO(peer->host_dynamic)); 17458 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 17459 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 17460 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 17461 ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE))); 17462 ast_cli(fd, " Force rport : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT))); 17463 ast_cli(fd, " ACL : %s\n", AST_CLI_YESNO(peer->ha != NULL)); 17464 ast_cli(fd, " DirectMedACL : %s\n", AST_CLI_YESNO(peer->directmediaha != NULL)); 17465 ast_cli(fd, " T.38 support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT))); 17466 ast_cli(fd, " T.38 EC mode : %s\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT))); 17467 ast_cli(fd, " T.38 MaxDtgrm: %d\n", peer->t38_maxdatagram); 17468 ast_cli(fd, " DirectMedia : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA))); 17469 ast_cli(fd, " PromiscRedir : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR))); 17470 ast_cli(fd, " User=Phone : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_USEREQPHONE))); 17471 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))); 17472 ast_cli(fd, " Text Support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT))); 17473 ast_cli(fd, " Ign SDP ver : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_IGNORESDPVERSION))); 17474 ast_cli(fd, " Trust RPID : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_TRUSTRPID))); 17475 ast_cli(fd, " Send RPID : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_SENDRPID))); 17476 ast_cli(fd, " Subscriptions: %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))); 17477 ast_cli(fd, " Overlap dial : %s\n", allowoverlap2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP))); 17478 if (peer->outboundproxy) 17479 ast_cli(fd, " Outb. proxy : %s %s\n", ast_strlen_zero(peer->outboundproxy->name) ? "<not set>" : peer->outboundproxy->name, 17480 peer->outboundproxy->force ? "(forced)" : ""); 17481 17482 /* - is enumerated */ 17483 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 17484 ast_cli(fd, " Timer T1 : %d\n", peer->timer_t1); 17485 ast_cli(fd, " Timer B : %d\n", peer->timer_b); 17486 ast_cli(fd, " ToHost : %s\n", peer->tohost); 17487 ast_cli(fd, " Addr->IP : %s\n", ast_sockaddr_stringify(&peer->addr)); 17488 ast_cli(fd, " Defaddr->IP : %s\n", ast_sockaddr_stringify(&peer->defaddr)); 17489 ast_cli(fd, " Prim.Transp. : %s\n", get_transport(peer->socket.type)); 17490 ast_cli(fd, " Allowed.Trsp : %s\n", get_transport_list(peer->transports)); 17491 if (!ast_strlen_zero(sip_cfg.regcontext)) 17492 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 17493 ast_cli(fd, " Def. Username: %s\n", peer->username); 17494 ast_cli(fd, " SIP Options : "); 17495 if (peer->sipoptions) { 17496 int lastoption = -1; 17497 for (x = 0 ; x < ARRAY_LEN(sip_options); x++) { 17498 if (sip_options[x].id != lastoption) { 17499 if (peer->sipoptions & sip_options[x].id) 17500 ast_cli(fd, "%s ", sip_options[x].text); 17501 lastoption = x; 17502 } 17503 } 17504 } else 17505 ast_cli(fd, "(none)"); 17506 17507 ast_cli(fd, "\n"); 17508 ast_cli(fd, " Codecs : "); 17509 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 17510 ast_cli(fd, "%s\n", codec_buf); 17511 ast_cli(fd, " Codec Order : ("); 17512 print_codec_to_cli(fd, &peer->prefs); 17513 ast_cli(fd, ")\n"); 17514 17515 ast_cli(fd, " Auto-Framing : %s \n", AST_CLI_YESNO(peer->autoframing)); 17516 ast_cli(fd, " Status : "); 17517 peer_status(peer, status, sizeof(status)); 17518 ast_cli(fd, "%s\n", status); 17519 ast_cli(fd, " Useragent : %s\n", peer->useragent); 17520 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 17521 ast_cli(fd, " Qualify Freq : %d ms\n", peer->qualifyfreq); 17522 if (peer->chanvars) { 17523 ast_cli(fd, " Variables :\n"); 17524 for (v = peer->chanvars ; v ; v = v->next) 17525 ast_cli(fd, " %s = %s\n", v->name, v->value); 17526 } 17527 17528 ast_cli(fd, " Sess-Timers : %s\n", stmode2str(peer->stimer.st_mode_oper)); 17529 ast_cli(fd, " Sess-Refresh : %s\n", strefresher2str(peer->stimer.st_ref)); 17530 ast_cli(fd, " Sess-Expires : %d secs\n", peer->stimer.st_max_se); 17531 ast_cli(fd, " Min-Sess : %d secs\n", peer->stimer.st_min_se); 17532 ast_cli(fd, " RTP Engine : %s\n", peer->engine); 17533 ast_cli(fd, " Parkinglot : %s\n", peer->parkinglot); 17534 ast_cli(fd, " Use Reason : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON))); 17535 ast_cli(fd, " Encryption : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP))); 17536 ast_cli(fd, "\n"); 17537 peer = unref_peer(peer, "sip_show_peer: unref_peer: done with peer ptr"); 17538 } else if (peer && type == 1) { /* manager listing */ 17539 char buffer[256]; 17540 struct ast_str *mailbox_str = ast_str_alloca(512); 17541 astman_append(s, "Channeltype: SIP\r\n"); 17542 astman_append(s, "ObjectName: %s\r\n", peer->name); 17543 astman_append(s, "ChanObjectType: peer\r\n"); 17544 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 17545 astman_append(s, "RemoteSecretExist: %s\r\n", ast_strlen_zero(peer->remotesecret)?"N":"Y"); 17546 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 17547 astman_append(s, "Context: %s\r\n", peer->context); 17548 astman_append(s, "Language: %s\r\n", peer->language); 17549 if (!ast_strlen_zero(peer->accountcode)) 17550 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 17551 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 17552 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 17553 if (!ast_strlen_zero(peer->fromuser)) 17554 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 17555 if (!ast_strlen_zero(peer->fromdomain)) 17556 astman_append(s, "SIP-FromDomain: %s\r\nSip-FromDomain-Port: %d\r\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT); 17557 astman_append(s, "Callgroup: "); 17558 astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->callgroup)); 17559 astman_append(s, "Pickupgroup: "); 17560 astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->pickupgroup)); 17561 astman_append(s, "MOHSuggest: %s\r\n", peer->mohsuggest); 17562 peer_mailboxes_to_str(&mailbox_str, peer); 17563 astman_append(s, "VoiceMailbox: %s\r\n", mailbox_str->str); 17564 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 17565 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 17566 astman_append(s, "Maxforwards: %d\r\n", peer->maxforwards); 17567 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 17568 astman_append(s, "Busy-level: %d\r\n", peer->busy_level); 17569 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 17570 astman_append(s, "Dynamic: %s\r\n", peer->host_dynamic?"Y":"N"); 17571 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 17572 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched, peer->expire)); 17573 astman_append(s, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE))); 17574 astman_append(s, "SIP-Forcerport: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT)?"Y":"N")); 17575 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 17576 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N")); 17577 astman_append(s, "SIP-DirectMedia: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N")); 17578 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 17579 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 17580 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 17581 astman_append(s, "SIP-TextSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT)?"Y":"N")); 17582 astman_append(s, "SIP-T.38Support: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)?"Y":"N")); 17583 astman_append(s, "SIP-T.38EC: %s\r\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT))); 17584 astman_append(s, "SIP-T.38MaxDtgrm: %d\r\n", peer->t38_maxdatagram); 17585 astman_append(s, "SIP-Sess-Timers: %s\r\n", stmode2str(peer->stimer.st_mode_oper)); 17586 astman_append(s, "SIP-Sess-Refresh: %s\r\n", strefresher2str(peer->stimer.st_ref)); 17587 astman_append(s, "SIP-Sess-Expires: %d\r\n", peer->stimer.st_max_se); 17588 astman_append(s, "SIP-Sess-Min: %d\r\n", peer->stimer.st_min_se); 17589 astman_append(s, "SIP-RTP-Engine: %s\r\n", peer->engine); 17590 astman_append(s, "SIP-Encryption: %s\r\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP) ? "Y" : "N"); 17591 17592 /* - is enumerated */ 17593 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 17594 astman_append(s, "ToHost: %s\r\n", peer->tohost); 17595 astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n", ast_sockaddr_stringify_addr(&peer->addr), ast_sockaddr_port(&peer->addr)); 17596 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)); 17597 astman_append(s, "Default-Username: %s\r\n", peer->username); 17598 if (!ast_strlen_zero(sip_cfg.regcontext)) 17599 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 17600 astman_append(s, "Codecs: "); 17601 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 17602 astman_append(s, "%s\r\n", codec_buf); 17603 astman_append(s, "CodecOrder: "); 17604 pref = &peer->prefs; 17605 for(x = 0; x < 64 ; x++) { 17606 codec = ast_codec_pref_index(pref, x); 17607 if (!codec) 17608 break; 17609 astman_append(s, "%s", ast_getformatname(codec)); 17610 if (x < 63 && ast_codec_pref_index(pref, x+1)) 17611 astman_append(s, ","); 17612 } 17613 17614 astman_append(s, "\r\n"); 17615 astman_append(s, "Status: "); 17616 peer_status(peer, status, sizeof(status)); 17617 astman_append(s, "%s\r\n", status); 17618 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 17619 astman_append(s, "Reg-Contact: %s\r\n", peer->fullcontact); 17620 astman_append(s, "QualifyFreq: %d ms\r\n", peer->qualifyfreq); 17621 astman_append(s, "Parkinglot: %s\r\n", peer->parkinglot); 17622 if (peer->chanvars) { 17623 for (v = peer->chanvars ; v ; v = v->next) { 17624 astman_append(s, "ChanVariable: %s=%s\r\n", v->name, v->value); 17625 } 17626 } 17627 astman_append(s, "SIP-Use-Reason-Header: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON)) ? "Y" : "N"); 17628 17629 peer = unref_peer(peer, "sip_show_peer: unref_peer: done with peer"); 17630 17631 } else { 17632 ast_cli(fd, "Peer %s not found.\n", argv[3]); 17633 ast_cli(fd, "\n"); 17634 } 17635 17636 return CLI_SUCCESS; 17637 }
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 16645 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().
16646 { 16647 regex_t regexbuf; 16648 int havepattern = FALSE; 16649 struct sip_peer *peer; 16650 struct ao2_iterator i; 16651 16652 /* the last argument is left-aligned, so we don't need a size anyways */ 16653 #define FORMAT2 "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n" 16654 #define FORMAT "%-25.25s %-39.39s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n" 16655 16656 char name[256]; 16657 int total_peers = 0; 16658 int peers_mon_online = 0; 16659 int peers_mon_offline = 0; 16660 int peers_unmon_offline = 0; 16661 int peers_unmon_online = 0; 16662 const char *id; 16663 char idtext[256] = ""; 16664 int realtimepeers; 16665 int objcount = ao2_container_count(peers); 16666 struct sip_peer **peerarray; 16667 int k; 16668 16669 16670 realtimepeers = ast_check_realtime("sippeers"); 16671 peerarray = ast_calloc(sizeof(struct sip_peer *), objcount); 16672 16673 if (s) { /* Manager - get ActionID */ 16674 id = astman_get_header(m, "ActionID"); 16675 if (!ast_strlen_zero(id)) 16676 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 16677 } 16678 16679 switch (argc) { 16680 case 5: 16681 if (!strcasecmp(argv[3], "like")) { 16682 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 16683 return CLI_SHOWUSAGE; 16684 havepattern = TRUE; 16685 } else 16686 return CLI_SHOWUSAGE; 16687 case 3: 16688 break; 16689 default: 16690 return CLI_SHOWUSAGE; 16691 } 16692 16693 if (!s) /* Normal list */ 16694 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Forcerport", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 16695 16696 16697 i = ao2_iterator_init(peers, 0); 16698 while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 16699 ao2_lock(peer); 16700 16701 if (!(peer->type & SIP_TYPE_PEER)) { 16702 ao2_unlock(peer); 16703 unref_peer(peer, "unref peer because it's actually a user"); 16704 continue; 16705 } 16706 16707 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) { 16708 objcount--; 16709 ao2_unlock(peer); 16710 unref_peer(peer, "toss iterator peer ptr before continue"); 16711 continue; 16712 } 16713 16714 peerarray[total_peers++] = peer; 16715 ao2_unlock(peer); 16716 } 16717 ao2_iterator_destroy(&i); 16718 16719 qsort(peerarray, total_peers, sizeof(struct sip_peer *), peercomparefunc); 16720 16721 for(k=0; k < total_peers; k++) { 16722 char status[20] = ""; 16723 char srch[2000]; 16724 char pstatus; 16725 peer = peerarray[k]; 16726 16727 ao2_lock(peer); 16728 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) { 16729 ao2_unlock(peer); 16730 peer = peerarray[k] = unref_peer(peer, "toss iterator peer ptr before continue"); 16731 continue; 16732 } 16733 16734 if (!ast_strlen_zero(peer->username) && !s) 16735 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 16736 else 16737 ast_copy_string(name, peer->name, sizeof(name)); 16738 16739 pstatus = peer_status(peer, status, sizeof(status)); 16740 if (pstatus == 1) 16741 peers_mon_online++; 16742 else if (pstatus == 0) 16743 peers_mon_offline++; 16744 else { 16745 if (ast_sockaddr_isnull(&peer->addr) || 16746 !ast_sockaddr_port(&peer->addr)) { 16747 peers_unmon_offline++; 16748 } else { 16749 peers_unmon_online++; 16750 } 16751 } 16752 16753 snprintf(srch, sizeof(srch), FORMAT, name, 16754 ast_sockaddr_isnull(&peer->addr) ? "(Unspecified)" : ast_sockaddr_stringify_addr(&peer->addr), 16755 peer->host_dynamic ? " D " : " ", /* Dynamic or not? */ 16756 ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : " ", /* NAT=yes? */ 16757 peer->ha ? " A " : " ", /* permit/deny */ 16758 ast_sockaddr_isnull(&peer->addr) ? 0 : ast_sockaddr_port(&peer->addr), status, 16759 realtimepeers ? (peer->is_realtime ? "Cached RT":"") : ""); 16760 16761 if (!s) {/* Normal CLI list */ 16762 ast_cli(fd, FORMAT, name, 16763 ast_sockaddr_isnull(&peer->addr) ? "(Unspecified)" : ast_sockaddr_stringify_addr(&peer->addr), 16764 peer->host_dynamic ? " D " : " ", /* Dynamic or not? */ 16765 ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : " ", /* NAT=yes? */ 16766 peer->ha ? " A " : " ", /* permit/deny */ 16767 ast_sockaddr_isnull(&peer->addr) ? 0 : ast_sockaddr_port(&peer->addr), status, 16768 realtimepeers ? (peer->is_realtime ? "Cached RT":"") : ""); 16769 } else { /* Manager format */ 16770 /* The names here need to be the same as other channels */ 16771 astman_append(s, 16772 "Event: PeerEntry\r\n%s" 16773 "Channeltype: SIP\r\n" 16774 "ObjectName: %s\r\n" 16775 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 16776 "IPaddress: %s\r\n" 16777 "IPport: %d\r\n" 16778 "Dynamic: %s\r\n" 16779 "Forcerport: %s\r\n" 16780 "VideoSupport: %s\r\n" 16781 "TextSupport: %s\r\n" 16782 "ACL: %s\r\n" 16783 "Status: %s\r\n" 16784 "RealtimeDevice: %s\r\n\r\n", 16785 idtext, 16786 peer->name, 16787 ast_sockaddr_isnull(&peer->addr) ? "-none-" : ast_sockaddr_stringify_fmt(&peer->addr, AST_SOCKADDR_STR_HOST), 16788 ast_sockaddr_isnull(&peer->addr) ? 0 : ast_sockaddr_port(&peer->addr), 16789 peer->host_dynamic ? "yes" : "no", /* Dynamic or not? */ 16790 ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? "yes" : "no", /* NAT=yes? */ 16791 ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 16792 ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "yes" : "no", /* TEXTSUPPORT=yes? */ 16793 peer->ha ? "yes" : "no", /* permit/deny */ 16794 status, 16795 realtimepeers ? (peer->is_realtime ? "yes":"no") : "no"); 16796 } 16797 ao2_unlock(peer); 16798 peer = peerarray[k] = unref_peer(peer, "toss iterator peer ptr"); 16799 } 16800 16801 if (!s) 16802 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 16803 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 16804 16805 if (havepattern) 16806 regfree(®exbuf); 16807 16808 if (total) 16809 *total = total_peers; 16810 16811 ast_free(peerarray); 16812 16813 return CLI_SUCCESS; 16814 #undef FORMAT 16815 #undef FORMAT2 16816 }
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 2502 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().
02503 { 02504 int res, cl, timeout = -1, authenticated = 0, flags, after_poll = 0, need_poll = 1; 02505 time_t start; 02506 struct sip_request req = { 0, } , reqcpy = { 0, }; 02507 struct sip_threadinfo *me = NULL; 02508 char buf[1024] = ""; 02509 struct pollfd fds[2] = { { 0 }, { 0 }, }; 02510 struct ast_tcptls_session_args *ca = NULL; 02511 02512 /* If this is a server session, then the connection has already been 02513 * setup. Check if the authlimit has been reached and if not create the 02514 * threadinfo object so we can access this thread for writing. 02515 * 02516 * if this is a client connection more work must be done. 02517 * 1. We own the parent session args for a client connection. This pointer needs 02518 * to be held on to so we can decrement it's ref count on thread destruction. 02519 * 2. The threadinfo object was created before this thread was launched, however 02520 * it must be found within the threadt table. 02521 * 3. Last, the tcptls_session must be started. 02522 */ 02523 if (!tcptls_session->client) { 02524 if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) { 02525 /* unauth_sessions is decremented in the cleanup code */ 02526 goto cleanup; 02527 } 02528 02529 if ((flags = fcntl(tcptls_session->fd, F_GETFL)) == -1) { 02530 ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno)); 02531 goto cleanup; 02532 } 02533 02534 flags |= O_NONBLOCK; 02535 if (fcntl(tcptls_session->fd, F_SETFL, flags) == -1) { 02536 ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno)); 02537 goto cleanup; 02538 } 02539 02540 if (!(me = sip_threadinfo_create(tcptls_session, tcptls_session->ssl ? SIP_TRANSPORT_TLS : SIP_TRANSPORT_TCP))) { 02541 goto cleanup; 02542 } 02543 ao2_t_ref(me, +1, "Adding threadinfo ref for tcp_helper_thread"); 02544 } else { 02545 struct sip_threadinfo tmp = { 02546 .tcptls_session = tcptls_session, 02547 }; 02548 02549 if ((!(ca = tcptls_session->parent)) || 02550 (!(me = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread"))) || 02551 (!(tcptls_session = ast_tcptls_client_start(tcptls_session)))) { 02552 goto cleanup; 02553 } 02554 } 02555 02556 flags = 1; 02557 if (setsockopt(tcptls_session->fd, SOL_SOCKET, SO_KEEPALIVE, &flags, sizeof(flags))) { 02558 ast_log(LOG_ERROR, "error enabling TCP keep-alives on sip socket: %s\n", strerror(errno)); 02559 goto cleanup; 02560 } 02561 02562 me->threadid = pthread_self(); 02563 ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP"); 02564 02565 /* set up pollfd to watch for reads on both the socket and the alert_pipe */ 02566 fds[0].fd = tcptls_session->fd; 02567 fds[1].fd = me->alert_pipe[0]; 02568 fds[0].events = fds[1].events = POLLIN | POLLPRI; 02569 02570 if (!(req.data = ast_str_create(SIP_MIN_PACKET))) { 02571 goto cleanup; 02572 } 02573 if (!(reqcpy.data = ast_str_create(SIP_MIN_PACKET))) { 02574 goto cleanup; 02575 } 02576 02577 if(time(&start) == -1) { 02578 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno)); 02579 goto cleanup; 02580 } 02581 02582 for (;;) { 02583 struct ast_str *str_save; 02584 02585 if (!tcptls_session->client && req.authenticated && !authenticated) { 02586 authenticated = 1; 02587 ast_atomic_fetchadd_int(&unauth_sessions, -1); 02588 } 02589 02590 /* calculate the timeout for unauthenticated server sessions */ 02591 if (!tcptls_session->client && !authenticated ) { 02592 if ((timeout = sip_check_authtimeout(start)) < 0) { 02593 goto cleanup; 02594 } 02595 02596 if (timeout == 0) { 02597 ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP"); 02598 goto cleanup; 02599 } 02600 } else { 02601 timeout = -1; 02602 } 02603 02604 res = ast_poll(fds, 2, timeout); /* polls for both socket and alert_pipe */ 02605 if (res < 0) { 02606 ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res); 02607 goto cleanup; 02608 } else if (res == 0) { 02609 /* timeout */ 02610 ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP"); 02611 goto cleanup; 02612 } 02613 02614 /* handle the socket event, check for both reads from the socket fd, 02615 * and writes from alert_pipe fd */ 02616 if (fds[0].revents) { /* there is data on the socket to be read */ 02617 after_poll = 1; 02618 02619 fds[0].revents = 0; 02620 02621 /* clear request structure */ 02622 str_save = req.data; 02623 memset(&req, 0, sizeof(req)); 02624 req.data = str_save; 02625 ast_str_reset(req.data); 02626 02627 str_save = reqcpy.data; 02628 memset(&reqcpy, 0, sizeof(reqcpy)); 02629 reqcpy.data = str_save; 02630 ast_str_reset(reqcpy.data); 02631 02632 memset(buf, 0, sizeof(buf)); 02633 02634 if (tcptls_session->ssl) { 02635 set_socket_transport(&req.socket, SIP_TRANSPORT_TLS); 02636 req.socket.port = htons(ourport_tls); 02637 } else { 02638 set_socket_transport(&req.socket, SIP_TRANSPORT_TCP); 02639 req.socket.port = htons(ourport_tcp); 02640 } 02641 req.socket.fd = tcptls_session->fd; 02642 02643 /* Read in headers one line at a time */ 02644 while (ast_str_strlen(req.data) < 4 || strncmp(REQ_OFFSET_TO_STR(&req, data->used - 4), "\r\n\r\n", 4)) { 02645 if (!tcptls_session->client && !authenticated ) { 02646 if ((timeout = sip_check_authtimeout(start)) < 0) { 02647 goto cleanup; 02648 } 02649 02650 if (timeout == 0) { 02651 ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP"); 02652 goto cleanup; 02653 } 02654 } else { 02655 timeout = -1; 02656 } 02657 02658 /* special polling behavior is required for TLS 02659 * sockets because of the buffering done in the 02660 * TLS layer */ 02661 if (!tcptls_session->ssl || need_poll) { 02662 need_poll = 0; 02663 after_poll = 1; 02664 res = ast_wait_for_input(tcptls_session->fd, timeout); 02665 if (res < 0) { 02666 ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res); 02667 goto cleanup; 02668 } else if (res == 0) { 02669 /* timeout */ 02670 ast_debug(2, "SIP TCP server timed out\n"); 02671 goto cleanup; 02672 } 02673 } 02674 02675 ast_mutex_lock(&tcptls_session->lock); 02676 if (!fgets(buf, sizeof(buf), tcptls_session->f)) { 02677 ast_mutex_unlock(&tcptls_session->lock); 02678 if (after_poll) { 02679 goto cleanup; 02680 } else { 02681 need_poll = 1; 02682 continue; 02683 } 02684 } 02685 ast_mutex_unlock(&tcptls_session->lock); 02686 after_poll = 0; 02687 if (me->stop) { 02688 goto cleanup; 02689 } 02690 ast_str_append(&req.data, 0, "%s", buf); 02691 } 02692 copy_request(&reqcpy, &req); 02693 parse_request(&reqcpy); 02694 /* In order to know how much to read, we need the content-length header */ 02695 if (sscanf(get_header(&reqcpy, "Content-Length"), "%30d", &cl)) { 02696 while (cl > 0) { 02697 size_t bytes_read; 02698 if (!tcptls_session->client && !authenticated ) { 02699 if ((timeout = sip_check_authtimeout(start)) < 0) { 02700 goto cleanup; 02701 } 02702 02703 if (timeout == 0) { 02704 ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP"); 02705 goto cleanup; 02706 } 02707 } else { 02708 timeout = -1; 02709 } 02710 02711 if (!tcptls_session->ssl || need_poll) { 02712 need_poll = 0; 02713 after_poll = 1; 02714 res = ast_wait_for_input(tcptls_session->fd, timeout); 02715 if (res < 0) { 02716 ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res); 02717 goto cleanup; 02718 } else if (res == 0) { 02719 /* timeout */ 02720 ast_debug(2, "SIP TCP server timed out\n"); 02721 goto cleanup; 02722 } 02723 } 02724 02725 ast_mutex_lock(&tcptls_session->lock); 02726 if (!(bytes_read = fread(buf, 1, MIN(sizeof(buf) - 1, cl), tcptls_session->f))) { 02727 ast_mutex_unlock(&tcptls_session->lock); 02728 if (after_poll) { 02729 goto cleanup; 02730 } else { 02731 need_poll = 1; 02732 continue; 02733 } 02734 } 02735 buf[bytes_read] = '\0'; 02736 ast_mutex_unlock(&tcptls_session->lock); 02737 after_poll = 0; 02738 if (me->stop) { 02739 goto cleanup; 02740 } 02741 cl -= strlen(buf); 02742 ast_str_append(&req.data, 0, "%s", buf); 02743 } 02744 } 02745 /*! \todo XXX If there's no Content-Length or if the content-length and what 02746 we receive is not the same - we should generate an error */ 02747 02748 req.socket.tcptls_session = tcptls_session; 02749 handle_request_do(&req, &tcptls_session->remote_address); 02750 } 02751 02752 if (fds[1].revents) { /* alert_pipe indicates there is data in the send queue to be sent */ 02753 enum sip_tcptls_alert alert; 02754 struct tcptls_packet *packet; 02755 02756 fds[1].revents = 0; 02757 02758 if (read(me->alert_pipe[0], &alert, sizeof(alert)) == -1) { 02759 ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno)); 02760 continue; 02761 } 02762 02763 switch (alert) { 02764 case TCPTLS_ALERT_STOP: 02765 goto cleanup; 02766 case TCPTLS_ALERT_DATA: 02767 ao2_lock(me); 02768 if (!(packet = AST_LIST_REMOVE_HEAD(&me->packet_q, entry))) { 02769 ast_log(LOG_WARNING, "TCPTLS thread alert_pipe indicated packet should be sent, but frame_q is empty"); 02770 } 02771 ao2_unlock(me); 02772 02773 if (packet) { 02774 if (ast_tcptls_server_write(tcptls_session, ast_str_buffer(packet->data), packet->len) == -1) { 02775 ast_log(LOG_WARNING, "Failure to write to tcp/tls socket\n"); 02776 } 02777 ao2_t_ref(packet, -1, "tcptls packet sent, this is no longer needed"); 02778 } 02779 break; 02780 default: 02781 ast_log(LOG_ERROR, "Unknown tcptls thread alert '%d'\n", alert); 02782 } 02783 } 02784 } 02785 02786 ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP"); 02787 02788 cleanup: 02789 if (tcptls_session && !tcptls_session->client && !authenticated) { 02790 ast_atomic_fetchadd_int(&unauth_sessions, -1); 02791 } 02792 02793 if (me) { 02794 ao2_t_unlink(threadt, me, "Removing tcptls helper thread, thread is closing"); 02795 ao2_t_ref(me, -1, "Removing tcp_helper_threads threadinfo ref"); 02796 } 02797 deinit_req(&reqcpy); 02798 deinit_req(&req); 02799 02800 /* if client, we own the parent session arguments and must decrement ref */ 02801 if (ca) { 02802 ao2_t_ref(ca, -1, "closing tcptls thread, getting rid of client tcptls_session arguments"); 02803 } 02804 02805 if (tcptls_session) { 02806 ast_mutex_lock(&tcptls_session->lock); 02807 ast_tcptls_close_session_file(tcptls_session); 02808 tcptls_session->parent = NULL; 02809 ast_mutex_unlock(&tcptls_session->lock); 02810 02811 ao2_ref(tcptls_session, -1); 02812 tcptls_session = NULL; 02813 } 02814 return NULL; 02815 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 4083 of file chan_sip.c.
References ast_str_append().
Referenced by send_request(), and send_response().
04084 { 04085 if (!req->lines) { 04086 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 04087 ast_str_append(&req->data, 0, "\r\n"); 04088 } 04089 }
static void add_cc_call_info_to_response | ( | struct sip_pvt * | p, | |
struct sip_request * | resp | |||
) | [static] |
Definition at line 11692 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().
11693 { 11694 char uri[SIPBUFSIZE]; 11695 struct ast_str *header = ast_str_alloca(SIPBUFSIZE); 11696 struct ast_cc_agent *agent = find_sip_cc_agent_by_original_callid(p); 11697 struct sip_cc_agent_pvt *agent_pvt; 11698 11699 if (!agent) { 11700 /* Um, what? How could the SIP_OFFER_CC flag be set but there not be an 11701 * agent? Oh well, we'll just warn and return without adding the header. 11702 */ 11703 ast_log(LOG_WARNING, "Can't find SIP CC agent for call '%s' even though OFFER_CC flag was set?\n", p->callid); 11704 return; 11705 } 11706 11707 agent_pvt = agent->private_data; 11708 11709 if (!ast_strlen_zero(agent_pvt->subscribe_uri)) { 11710 ast_copy_string(uri, agent_pvt->subscribe_uri, sizeof(uri)); 11711 } else { 11712 generate_uri(p, uri, sizeof(uri)); 11713 ast_copy_string(agent_pvt->subscribe_uri, uri, sizeof(agent_pvt->subscribe_uri)); 11714 } 11715 /* XXX Hardcode "NR" as the m reason for now. This should perhaps be changed 11716 * to be more accurate. This parameter has no bearing on the actual operation 11717 * of the feature; it's just there for informational purposes. 11718 */ 11719 ast_str_set(&header, 0, "<%s>;purpose=call-completion;m=%s", uri, "NR"); 11720 add_header(resp, "Call-Info", ast_str_buffer(header)); 11721 ao2_ref(agent, -1); 11722 }
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 10942 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().
10945 { 10946 int rtp_code; 10947 struct ast_format_list fmt; 10948 10949 10950 if (debug) 10951 ast_verbose("Adding codec 0x%" PRIx64 " (%s) to SDP\n", codec, ast_getformatname(codec)); 10952 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 1, codec)) == -1) 10953 return; 10954 10955 if (p->rtp) { 10956 struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref; 10957 fmt = ast_codec_pref_getsize(pref, codec); 10958 } 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 */ 10959 return; 10960 ast_str_append(m_buf, 0, " %d", rtp_code); 10961 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code, 10962 ast_rtp_lookup_mime_subtype2(1, codec, 10963 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 10964 ast_rtp_lookup_sample_rate2(1, codec)); 10965 10966 switch (codec) { 10967 case AST_FORMAT_G729A: 10968 /* Indicate that we don't support VAD (G.729 annex B) */ 10969 ast_str_append(a_buf, 0, "a=fmtp:%d annexb=no\r\n", rtp_code); 10970 break; 10971 case AST_FORMAT_G723_1: 10972 /* Indicate that we don't support VAD (G.723.1 annex A) */ 10973 ast_str_append(a_buf, 0, "a=fmtp:%d annexa=no\r\n", rtp_code); 10974 break; 10975 case AST_FORMAT_ILBC: 10976 /* Add information about us using only 20/30 ms packetization */ 10977 ast_str_append(a_buf, 0, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 10978 break; 10979 case AST_FORMAT_SIREN7: 10980 /* Indicate that we only expect 32Kbps */ 10981 ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=32000\r\n", rtp_code); 10982 break; 10983 case AST_FORMAT_SIREN14: 10984 /* Indicate that we only expect 48Kbps */ 10985 ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=48000\r\n", rtp_code); 10986 break; 10987 case AST_FORMAT_G719: 10988 /* Indicate that we only expect 64Kbps */ 10989 ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=64000\r\n", rtp_code); 10990 break; 10991 } 10992 10993 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 10994 *min_packet_size = fmt.cur_ms; 10995 10996 /* Our first codec packetization processed cannot be zero */ 10997 if ((*min_packet_size)==0 && fmt.cur_ms) 10998 *min_packet_size = fmt.cur_ms; 10999 }
static int add_content | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 9874 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().
09875 { 09876 if (req->lines) { 09877 ast_log(LOG_WARNING, "Can't add more content when the content has been finalized\n"); 09878 return -1; 09879 } 09880 09881 ast_str_append(&req->content, 0, "%s", line); 09882 return 0; 09883 }
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 10800 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_info_with_digit().
10801 { 10802 char tmp[256]; 10803 int event; 10804 if (mode) { 10805 /* Application/dtmf short version used by some implementations */ 10806 if ('0' <= digit && digit <= '9') { 10807 event = digit - '0'; 10808 } else if (digit == '*') { 10809 event = 10; 10810 } else if (digit == '#') { 10811 event = 11; 10812 } else if ('A' <= digit && digit <= 'D') { 10813 event = 12 + digit - 'A'; 10814 } else if ('a' <= digit && digit <= 'd') { 10815 event = 12 + digit - 'a'; 10816 } else { 10817 /* Unknown digit */ 10818 event = 0; 10819 } 10820 snprintf(tmp, sizeof(tmp), "%d\r\n", event); 10821 add_header(req, "Content-Type", "application/dtmf"); 10822 add_content(req, tmp); 10823 } else { 10824 /* Application/dtmf-relay as documented by Cisco */ 10825 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 10826 add_header(req, "Content-Type", "application/dtmf-relay"); 10827 add_content(req, tmp); 10828 } 10829 return 0; 10830 }
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 12078 of file chan_sip.c.
References add_header(), ast_sockaddr_stringify_host_remote(), ast_strlen_zero(), and sip_reason_code_to_str().
Referenced by __transmit_response(), transmit_invite(), and update_redirecting().
12079 { 12080 const char *diverting_number; 12081 const char *diverting_name; 12082 const char *reason; 12083 char header_text[256]; 12084 12085 if (!pvt->owner) { 12086 return; 12087 } 12088 12089 diverting_number = pvt->owner->redirecting.from.number.str; 12090 if (!pvt->owner->redirecting.from.number.valid 12091 || ast_strlen_zero(diverting_number)) { 12092 return; 12093 } 12094 12095 reason = sip_reason_code_to_str(pvt->owner->redirecting.reason); 12096 12097 /* We at least have a number to place in the Diversion header, which is enough */ 12098 diverting_name = pvt->owner->redirecting.from.name.str; 12099 if (!pvt->owner->redirecting.from.name.valid 12100 || ast_strlen_zero(diverting_name)) { 12101 snprintf(header_text, sizeof(header_text), "<sip:%s@%s>;reason=%s", diverting_number, 12102 ast_sockaddr_stringify_host_remote(&pvt->ourip), reason); 12103 } else { 12104 snprintf(header_text, sizeof(header_text), "\"%s\" <sip:%s@%s>;reason=%s", 12105 diverting_name, diverting_number, 12106 ast_sockaddr_stringify_host_remote(&pvt->ourip), reason); 12107 } 12108 12109 add_header(req, "Diversion", header_text); 12110 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 9816 of file chan_sip.c.
References ast_log(), ast_str_append(), ast_str_strlen(), find_alias(), LOG_WARNING, and sip_cfg.
09817 { 09818 if (req->headers == SIP_MAX_HEADERS) { 09819 ast_log(LOG_WARNING, "Out of SIP header space\n"); 09820 return -1; 09821 } 09822 09823 if (req->lines) { 09824 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 09825 return -1; 09826 } 09827 09828 if (sip_cfg.compactheaders) { 09829 var = find_alias(var, var); 09830 } 09831 09832 ast_str_append(&req->data, 0, "%s: %s\r\n", var, value); 09833 req->header[req->headers] = ast_str_strlen(req->data); 09834 09835 req->headers++; 09836 09837 return 0; 09838 }
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 9844 of file chan_sip.c.
References add_header().
Referenced by initreqprep(), reqprep(), and transmit_register().
09845 { 09846 char clen[10]; 09847 09848 snprintf(clen, sizeof(clen), "%d", dialog->maxforwards); 09849 09850 return add_header(req, "Max-Forwards", clen); 09851 }
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 11080 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().
11083 { 11084 int rtp_code; 11085 11086 if (debug) 11087 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype2(0, format, 0)); 11088 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 0, format)) == -1) 11089 return; 11090 11091 ast_str_append(m_buf, 0, " %d", rtp_code); 11092 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code, 11093 ast_rtp_lookup_mime_subtype2(0, format, 0), 11094 ast_rtp_lookup_sample_rate2(0, format)); 11095 if (format == AST_RTP_DTMF) /* Indicate we support DTMF and FLASH... */ 11096 ast_str_append(a_buf, 0, "a=fmtp:%d 0-16\r\n", rtp_code); 11097 }
static void add_peer_mailboxes | ( | struct sip_peer * | peer, | |
const char * | value | |||
) | [static] |
Definition at line 27091 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_strdupa, ast_strip(), ast_strlen_zero(), context, mailbox, mbox(), S_OR, and strsep().
Referenced by build_peer().
27092 { 27093 char *next, *mbox, *context; 27094 27095 next = ast_strdupa(value); 27096 27097 while ((mbox = context = strsep(&next, ","))) { 27098 struct sip_mailbox *mailbox; 27099 int duplicate = 0; 27100 /* remove leading/trailing whitespace from mailbox string */ 27101 mbox = ast_strip(mbox); 27102 strsep(&context, "@"); 27103 27104 if (ast_strlen_zero(mbox)) { 27105 continue; 27106 } 27107 27108 /* Check whether the mailbox is already in the list */ 27109 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 27110 if (!strcmp(mailbox->mailbox, mbox) && !strcmp(S_OR(mailbox->context, ""), S_OR(context, ""))) { 27111 duplicate = 1; 27112 break; 27113 } 27114 } 27115 if (duplicate) { 27116 continue; 27117 } 27118 27119 if (!(mailbox = ast_calloc(1, sizeof(*mailbox) + strlen(mbox) + strlen(S_OR(context, ""))))) { 27120 continue; 27121 } 27122 27123 if (!ast_strlen_zero(context)) { 27124 mailbox->context = mailbox->mailbox + strlen(mbox) + 1; 27125 strcpy(mailbox->context, context); /* SAFE */ 27126 } 27127 strcpy(mailbox->mailbox, mbox); /* SAFE */ 27128 27129 AST_LIST_INSERT_TAIL(&peer->mailboxes, mailbox, entry); 27130 } 27131 }
static void add_peer_mwi_subs | ( | struct sip_peer * | peer | ) | [static] |
Definition at line 24401 of file chan_sip.c.
References AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_event_unsubscribe(), AST_LIST_TRAVERSE, mailbox, mwi_event_cb(), and S_OR.
Referenced by build_peer(), and handle_request_subscribe().
24402 { 24403 struct sip_mailbox *mailbox; 24404 24405 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 24406 if (mailbox->event_sub) { 24407 ast_event_unsubscribe(mailbox->event_sub); 24408 } 24409 24410 mailbox->event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "SIP mbox event", peer, 24411 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox, 24412 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"), 24413 AST_EVENT_IE_END); 24414 } 24415 }
static void add_realm_authentication | ( | struct sip_auth_container ** | credentials, | |
const char * | configuration, | |||
int | lineno | |||
) | [static] |
Definition at line 26895 of file chan_sip.c.
References ao2_t_alloc, ast_calloc, ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, ast_log(), ast_strdupa, ast_strlen_zero(), ast_verb, destroy_realm_authentication(), LOG_WARNING, and secret.
Referenced by build_peer().
26896 { 26897 char *authcopy; 26898 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 26899 struct sip_auth *auth; 26900 26901 if (ast_strlen_zero(configuration)) { 26902 /* Nothing to add */ 26903 return; 26904 } 26905 26906 ast_debug(1, "Auth config :: %s\n", configuration); 26907 26908 authcopy = ast_strdupa(configuration); 26909 username = authcopy; 26910 26911 /* split user[:secret] and relm */ 26912 realm = strrchr(username, '@'); 26913 if (realm) 26914 *realm++ = '\0'; 26915 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 26916 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 26917 return; 26918 } 26919 26920 /* parse username at ':' for secret, or '#" for md5secret */ 26921 if ((secret = strchr(username, ':'))) { 26922 *secret++ = '\0'; 26923 } else if ((md5secret = strchr(username, '#'))) { 26924 *md5secret++ = '\0'; 26925 } 26926 26927 /* Create the continer if needed. */ 26928 if (!*credentials) { 26929 *credentials = ao2_t_alloc(sizeof(**credentials), destroy_realm_authentication, 26930 "Create realm auth container."); 26931 if (!*credentials) { 26932 /* Failed to create the credentials container. */ 26933 return; 26934 } 26935 } 26936 26937 /* Create the authentication credential entry. */ 26938 auth = ast_calloc(1, sizeof(*auth)); 26939 if (!auth) { 26940 return; 26941 } 26942 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 26943 ast_copy_string(auth->username, username, sizeof(auth->username)); 26944 if (secret) 26945 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 26946 if (md5secret) 26947 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 26948 26949 /* Add credential to container list. */ 26950 AST_LIST_INSERT_TAIL(&(*credentials)->list, auth, node); 26951 26952 ast_verb(3, "Added authentication for realm %s\n", realm); 26953 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 9985 of file chan_sip.c.
References add_header(), and ast_copy_string().
Referenced by initreqprep(), and reqprep().
09986 { 09987 char r[SIPBUFSIZE*2], *p; 09988 int n, rem = sizeof(r); 09989 09990 if (!route) 09991 return; 09992 09993 p = r; 09994 for (;route ; route = route->next) { 09995 n = strlen(route->hop); 09996 if (rem < n+3) /* we need room for ",<route>" */ 09997 break; 09998 if (p != r) { /* add a separator after fist route */ 09999 *p++ = ','; 10000 --rem; 10001 } 10002 *p++ = '<'; 10003 ast_copy_string(p, route->hop, rem); /* cannot fail */ 10004 p += n; 10005 *p++ = '>'; 10006 rem -= (n+2); 10007 } 10008 *p = '\0'; 10009 add_header(req, "Route", r); 10010 }
static int add_rpid | ( | struct sip_request * | req, | |
struct sip_pvt * | p | |||
) | [static] |
Add Remote-Party-ID header to SIP message.
Definition at line 10836 of file chan_sip.c.
References add_header(), ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_sockaddr_stringify_host_remote(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_strlen_zero(), ast_test_flag, ast_uri_encode(), and S_OR.
Referenced by __transmit_response(), transmit_invite(), transmit_reinvite_with_sdp(), transmit_response_with_sdp(), and update_connectedline().
10837 { 10838 struct ast_str *tmp = ast_str_alloca(256); 10839 char tmp2[256]; 10840 char *lid_num = NULL; 10841 char *lid_name = NULL; 10842 int lid_pres; 10843 const char *fromdomain; 10844 const char *privacy = NULL; 10845 const char *screen = NULL; 10846 const char *anonymous_string = "\"Anonymous\" <sip:anonymous@anonymous.invalid>"; 10847 10848 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) { 10849 return 0; 10850 } 10851 10852 if (p->owner && p->owner->connected.id.number.valid 10853 && p->owner->connected.id.number.str) { 10854 lid_num = p->owner->connected.id.number.str; 10855 } 10856 if (p->owner && p->owner->connected.id.name.valid 10857 && p->owner->connected.id.name.str) { 10858 lid_name = p->owner->connected.id.name.str; 10859 } 10860 lid_pres = (p->owner) ? ast_party_id_presentation(&p->owner->connected.id) : AST_PRES_NUMBER_NOT_AVAILABLE; 10861 10862 if (ast_strlen_zero(lid_num)) 10863 return 0; 10864 if (ast_strlen_zero(lid_name)) 10865 lid_name = lid_num; 10866 fromdomain = S_OR(p->fromdomain, ast_sockaddr_stringify_host_remote(&p->ourip)); 10867 10868 lid_num = ast_uri_encode(lid_num, tmp2, sizeof(tmp2), 0); 10869 10870 if (ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI)) { 10871 if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 10872 ast_str_set(&tmp, -1, "%s", anonymous_string); 10873 } else { 10874 ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>", lid_name, lid_num, fromdomain); 10875 } 10876 add_header(req, "P-Asserted-Identity", ast_str_buffer(tmp)); 10877 } else { 10878 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"); 10879 10880 switch (lid_pres) { 10881 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 10882 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 10883 privacy = "off"; 10884 screen = "no"; 10885 break; 10886 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 10887 case AST_PRES_ALLOWED_NETWORK_NUMBER: 10888 privacy = "off"; 10889 screen = "yes"; 10890 break; 10891 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 10892 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 10893 privacy = "full"; 10894 screen = "no"; 10895 break; 10896 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 10897 case AST_PRES_PROHIB_NETWORK_NUMBER: 10898 privacy = "full"; 10899 screen = "yes"; 10900 break; 10901 case AST_PRES_NUMBER_NOT_AVAILABLE: 10902 break; 10903 default: 10904 if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 10905 privacy = "full"; 10906 } 10907 else 10908 privacy = "off"; 10909 screen = "no"; 10910 break; 10911 } 10912 10913 if (!ast_strlen_zero(privacy) && !ast_strlen_zero(screen)) { 10914 ast_str_append(&tmp, -1, ";privacy=%s;screen=%s", privacy, screen); 10915 } 10916 10917 add_header(req, "Remote-Party-ID", ast_str_buffer(tmp)); 10918 } 10919 return 0; 10920 }
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 11218 of file chan_sip.c.
References add_codec_to_sdp(), add_content(), add_header(), add_noncodec_to_sdp(), add_tcodec_to_sdp(), add_vcodec_to_sdp(), ast_codec_pref_index(), ast_debug, AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_internal_timing_enabled(), ast_log(), ast_random(), AST_RTP_MAX, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_is_ipv4_mapped(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_addr_remote(), ast_sockaddr_stringify_port(), ast_str_alloca, ast_str_append(), ast_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.
11219 { 11220 format_t alreadysent = 0; 11221 int doing_directmedia = FALSE; 11222 11223 struct ast_sockaddr addr = { {0,} }; 11224 struct ast_sockaddr vaddr = { {0,} }; 11225 struct ast_sockaddr taddr = { {0,} }; 11226 struct ast_sockaddr udptladdr = { {0,} }; 11227 struct ast_sockaddr dest = { {0,} }; 11228 struct ast_sockaddr vdest = { {0,} }; 11229 struct ast_sockaddr tdest = { {0,} }; 11230 struct ast_sockaddr udptldest = { {0,} }; 11231 11232 /* SDP fields */ 11233 char *version = "v=0\r\n"; /* Protocol version */ 11234 char subject[256]; /* Subject of the session */ 11235 char owner[256]; /* Session owner/creator */ 11236 char connection[256]; /* Connection data */ 11237 char *session_time = "t=0 0\r\n"; /* Time the session is active */ 11238 char bandwidth[256] = ""; /* Max bitrate */ 11239 char *hold = ""; 11240 struct ast_str *m_audio = ast_str_alloca(256); /* Media declaration line for audio */ 11241 struct ast_str *m_video = ast_str_alloca(256); /* Media declaration line for video */ 11242 struct ast_str *m_text = ast_str_alloca(256); /* Media declaration line for text */ 11243 struct ast_str *m_modem = ast_str_alloca(256); /* Media declaration line for modem */ 11244 struct ast_str *a_audio = ast_str_alloca(1024); /* Attributes for audio */ 11245 struct ast_str *a_video = ast_str_alloca(1024); /* Attributes for video */ 11246 struct ast_str *a_text = ast_str_alloca(1024); /* Attributes for text */ 11247 struct ast_str *a_modem = ast_str_alloca(1024); /* Attributes for modem */ 11248 const char *a_crypto = NULL; 11249 const char *v_a_crypto = NULL; 11250 const char *t_a_crypto = NULL; 11251 11252 format_t x; 11253 format_t capability = 0; 11254 int needaudio = FALSE; 11255 int needvideo = FALSE; 11256 int needtext = FALSE; 11257 int debug = sip_debug_test_pvt(p); 11258 int min_audio_packet_size = 0; 11259 int min_video_packet_size = 0; 11260 int min_text_packet_size = 0; 11261 11262 char codecbuf[SIPBUFSIZE]; 11263 char buf[SIPBUFSIZE]; 11264 char dummy_answer[256]; 11265 11266 /* Set the SDP session name */ 11267 snprintf(subject, sizeof(subject), "s=%s\r\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession); 11268 11269 if (!p->rtp) { 11270 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 11271 return AST_FAILURE; 11272 } 11273 /* XXX We should not change properties in the SIP dialog until 11274 we have acceptance of the offer if this is a re-invite */ 11275 11276 /* Set RTP Session ID and version */ 11277 if (!p->sessionid) { 11278 p->sessionid = (int)ast_random(); 11279 p->sessionversion = p->sessionid; 11280 } else { 11281 if (oldsdp == FALSE) 11282 p->sessionversion++; 11283 } 11284 11285 if (add_audio) { 11286 doing_directmedia = (!ast_sockaddr_isnull(&p->redirip) && p->redircodecs) ? TRUE : FALSE; 11287 /* Check if we need video in this call */ 11288 if ((p->jointcapability & AST_FORMAT_VIDEO_MASK) && !p->novideo) { 11289 if (doing_directmedia && !(p->jointcapability & AST_FORMAT_VIDEO_MASK & p->redircodecs)) { 11290 ast_debug(2, "This call needs video offers, but caller probably did not offer it!\n"); 11291 } else if (p->vrtp) { 11292 needvideo = TRUE; 11293 ast_debug(2, "This call needs video offers!\n"); 11294 } else { 11295 ast_debug(2, "This call needs video offers, but there's no video support enabled!\n"); 11296 } 11297 } 11298 /* Check if we need text in this call */ 11299 if ((p->jointcapability & AST_FORMAT_TEXT_MASK) && !p->notext) { 11300 if (sipdebug_text) 11301 ast_verbose("We think we can do text\n"); 11302 if (p->trtp) { 11303 if (sipdebug_text) { 11304 ast_verbose("And we have a text rtp object\n"); 11305 } 11306 needtext = TRUE; 11307 ast_debug(2, "This call needs text offers! \n"); 11308 } else { 11309 ast_debug(2, "This call needs text offers, but there's no text support enabled ! \n"); 11310 } 11311 } 11312 } 11313 11314 get_our_media_address(p, needvideo, needtext, &addr, &vaddr, &taddr, &dest, &vdest, &tdest); 11315 11316 snprintf(owner, sizeof(owner), "o=%s %d %d IN %s %s\r\n", 11317 ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner, 11318 p->sessionid, p->sessionversion, 11319 (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ? 11320 "IP6" : "IP4", 11321 ast_sockaddr_stringify_addr_remote(&dest)); 11322 11323 snprintf(connection, sizeof(connection), "c=IN %s %s\r\n", 11324 (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ? 11325 "IP6" : "IP4", 11326 ast_sockaddr_stringify_addr_remote(&dest)); 11327 11328 if (add_audio) { 11329 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) { 11330 hold = "a=recvonly\r\n"; 11331 doing_directmedia = FALSE; 11332 } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) { 11333 hold = "a=inactive\r\n"; 11334 doing_directmedia = FALSE; 11335 } else { 11336 hold = "a=sendrecv\r\n"; 11337 } 11338 11339 capability = p->jointcapability; 11340 11341 /* XXX note, Video and Text are negated - 'true' means 'no' */ 11342 ast_debug(1, "** Our capability: %s Video flag: %s Text flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability), 11343 p->novideo ? "True" : "False", p->notext ? "True" : "False"); 11344 ast_debug(1, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 11345 11346 if (doing_directmedia) { 11347 capability &= p->redircodecs; 11348 ast_debug(1, "** Our native-bridge filtered capablity: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability)); 11349 } 11350 11351 /* Check if we need audio */ 11352 if (capability & AST_FORMAT_AUDIO_MASK) 11353 needaudio = TRUE; 11354 11355 if (debug) { 11356 ast_verbose("Audio is at %s\n", ast_sockaddr_stringify_port(&addr)); 11357 } 11358 11359 /* Ok, we need video. Let's add what we need for video and set codecs. 11360 Video is handled differently than audio since we can not transcode. */ 11361 if (needvideo) { 11362 get_crypto_attrib(p->vsrtp, &v_a_crypto); 11363 ast_str_append(&m_video, 0, "m=video %d RTP/%s", ast_sockaddr_port(&vdest), 11364 v_a_crypto ? "SAVP" : "AVP"); 11365 11366 /* Build max bitrate string */ 11367 if (p->maxcallbitrate) 11368 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 11369 if (debug) { 11370 ast_verbose("Video is at %s\n", ast_sockaddr_stringify(&vdest)); 11371 } 11372 } 11373 11374 /* Ok, we need text. Let's add what we need for text and set codecs. 11375 Text is handled differently than audio since we can not transcode. */ 11376 if (needtext) { 11377 if (sipdebug_text) 11378 ast_verbose("Lets set up the text sdp\n"); 11379 get_crypto_attrib(p->tsrtp, &t_a_crypto); 11380 ast_str_append(&m_text, 0, "m=text %d RTP/%s", ast_sockaddr_port(&tdest), 11381 t_a_crypto ? "SAVP" : "AVP"); 11382 if (debug) { /* XXX should I use tdest below ? */ 11383 ast_verbose("Text is at %s\n", ast_sockaddr_stringify(&taddr)); 11384 } 11385 } 11386 11387 /* Start building generic SDP headers */ 11388 11389 /* We break with the "recommendation" and send our IP, in order that our 11390 peer doesn't have to ast_gethostbyname() us */ 11391 11392 get_crypto_attrib(p->srtp, &a_crypto); 11393 ast_str_append(&m_audio, 0, "m=audio %d RTP/%s", ast_sockaddr_port(&dest), 11394 a_crypto ? "SAVP" : "AVP"); 11395 11396 /* Now, start adding audio codecs. These are added in this order: 11397 - First what was requested by the calling channel 11398 - Then preferences in order from sip.conf device config for this peer/user 11399 - Then other codecs in capabilities, including video 11400 */ 11401 11402 /* Prefer the audio codec we were requested to use, first, no matter what 11403 Note that p->prefcodec can include video codecs, so mask them out 11404 */ 11405 if (capability & p->prefcodec) { 11406 format_t codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 11407 11408 add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size); 11409 alreadysent |= codec; 11410 } 11411 11412 /* Start by sending our preferred audio/video codecs */ 11413 for (x = 0; x < 64; x++) { 11414 format_t codec; 11415 11416 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 11417 break; 11418 11419 if (!(capability & codec)) 11420 continue; 11421 11422 if (alreadysent & codec) 11423 continue; 11424 11425 add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size); 11426 alreadysent |= codec; 11427 } 11428 11429 /* Now send any other common audio and video codecs, and non-codec formats: */ 11430 for (x = 1ULL; x <= (needtext ? AST_FORMAT_TEXT_MASK : (needvideo ? AST_FORMAT_VIDEO_MASK : AST_FORMAT_AUDIO_MASK)); x <<= 1) { 11431 if (!(capability & x)) /* Codec not requested */ 11432 continue; 11433 11434 if (alreadysent & x) /* Already added to SDP */ 11435 continue; 11436 11437 if (x & AST_FORMAT_AUDIO_MASK) 11438 add_codec_to_sdp(p, x, &m_audio, &a_audio, debug, &min_audio_packet_size); 11439 else if (x & AST_FORMAT_VIDEO_MASK) 11440 add_vcodec_to_sdp(p, x, &m_video, &a_video, debug, &min_video_packet_size); 11441 else if (x & AST_FORMAT_TEXT_MASK) 11442 add_tcodec_to_sdp(p, x, &m_text, &a_text, debug, &min_text_packet_size); 11443 } 11444 11445 /* Now add DTMF RFC2833 telephony-event as a codec */ 11446 for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) { 11447 if (!(p->jointnoncodeccapability & x)) 11448 continue; 11449 11450 add_noncodec_to_sdp(p, x, &m_audio, &a_audio, debug); 11451 } 11452 11453 ast_debug(3, "-- Done with adding codecs to SDP\n"); 11454 11455 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 11456 ast_str_append(&a_audio, 0, "a=silenceSupp:off - - - -\r\n"); 11457 11458 if (min_audio_packet_size) 11459 ast_str_append(&a_audio, 0, "a=ptime:%d\r\n", min_audio_packet_size); 11460 11461 /* XXX don't think you can have ptime for video */ 11462 if (min_video_packet_size) 11463 ast_str_append(&a_video, 0, "a=ptime:%d\r\n", min_video_packet_size); 11464 11465 /* XXX don't think you can have ptime for text */ 11466 if (min_text_packet_size) 11467 ast_str_append(&a_text, 0, "a=ptime:%d\r\n", min_text_packet_size); 11468 11469 if (m_audio->len - m_audio->used < 2 || m_video->len - m_video->used < 2 || 11470 m_text->len - m_text->used < 2 || a_text->len - a_text->used < 2 || 11471 a_audio->len - a_audio->used < 2 || a_video->len - a_video->used < 2) 11472 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 11473 } 11474 11475 if (add_t38) { 11476 /* Our T.38 end is */ 11477 ast_udptl_get_us(p->udptl, &udptladdr); 11478 11479 /* Determine T.38 UDPTL destination */ 11480 if (!ast_sockaddr_isnull(&p->udptlredirip)) { 11481 ast_sockaddr_copy(&udptldest, &p->udptlredirip); 11482 } else { 11483 ast_sockaddr_copy(&udptldest, &p->ourip); 11484 ast_sockaddr_set_port(&udptldest, ast_sockaddr_port(&udptladdr)); 11485 } 11486 11487 if (debug) { 11488 ast_debug(1, "T.38 UDPTL is at %s port %d\n", ast_sockaddr_stringify_addr(&p->ourip), ast_sockaddr_port(&udptladdr)); 11489 } 11490 11491 /* We break with the "recommendation" and send our IP, in order that our 11492 peer doesn't have to ast_gethostbyname() us */ 11493 11494 ast_str_append(&m_modem, 0, "m=image %d udptl t38\r\n", ast_sockaddr_port(&udptldest)); 11495 11496 if (!ast_sockaddr_cmp(&udptldest, &dest)) { 11497 ast_str_append(&m_modem, 0, "c=IN %s %s\r\n", 11498 (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ? 11499 "IP6" : "IP4", ast_sockaddr_stringify_addr_remote(&udptldest)); 11500 } 11501 11502 ast_str_append(&a_modem, 0, "a=T38FaxVersion:%d\r\n", p->t38.our_parms.version); 11503 ast_str_append(&a_modem, 0, "a=T38MaxBitRate:%d\r\n", t38_get_rate(p->t38.our_parms.rate)); 11504 if (p->t38.our_parms.fill_bit_removal) { 11505 ast_str_append(&a_modem, 0, "a=T38FaxFillBitRemoval\r\n"); 11506 } 11507 if (p->t38.our_parms.transcoding_mmr) { 11508 ast_str_append(&a_modem, 0, "a=T38FaxTranscodingMMR\r\n"); 11509 } 11510 if (p->t38.our_parms.transcoding_jbig) { 11511 ast_str_append(&a_modem, 0, "a=T38FaxTranscodingJBIG\r\n"); 11512 } 11513 switch (p->t38.our_parms.rate_management) { 11514 case AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF: 11515 ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:transferredTCF\r\n"); 11516 break; 11517 case AST_T38_RATE_MANAGEMENT_LOCAL_TCF: 11518 ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:localTCF\r\n"); 11519 break; 11520 } 11521 ast_str_append(&a_modem, 0, "a=T38FaxMaxDatagram:%u\r\n", ast_udptl_get_local_max_datagram(p->udptl)); 11522 switch (ast_udptl_get_error_correction_scheme(p->udptl)) { 11523 case UDPTL_ERROR_CORRECTION_NONE: 11524 break; 11525 case UDPTL_ERROR_CORRECTION_FEC: 11526 ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPFEC\r\n"); 11527 break; 11528 case UDPTL_ERROR_CORRECTION_REDUNDANCY: 11529 ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPRedundancy\r\n"); 11530 break; 11531 } 11532 } 11533 11534 if (needaudio) 11535 ast_str_append(&m_audio, 0, "\r\n"); 11536 if (needvideo) 11537 ast_str_append(&m_video, 0, "\r\n"); 11538 if (needtext) 11539 ast_str_append(&m_text, 0, "\r\n"); 11540 11541 add_header(resp, "Content-Type", "application/sdp"); 11542 add_content(resp, version); 11543 add_content(resp, owner); 11544 add_content(resp, subject); 11545 add_content(resp, connection); 11546 /* only if video response is appropriate */ 11547 if (needvideo) { 11548 add_content(resp, bandwidth); 11549 } 11550 add_content(resp, session_time); 11551 /* if this is a response to an invite, order our offers properly */ 11552 if (p->offered_media[SDP_AUDIO].order_offered || 11553 p->offered_media[SDP_VIDEO].order_offered || 11554 p->offered_media[SDP_TEXT].order_offered || 11555 p->offered_media[SDP_IMAGE].order_offered) { 11556 int i; 11557 /* we have up to 3 streams as limited by process_sdp */ 11558 for (i = 1; i <= 3; i++) { 11559 if (p->offered_media[SDP_AUDIO].order_offered == i) { 11560 if (needaudio) { 11561 add_content(resp, m_audio->str); 11562 add_content(resp, a_audio->str); 11563 add_content(resp, hold); 11564 if (a_crypto) { 11565 add_content(resp, a_crypto); 11566 } 11567 } else { 11568 snprintf(dummy_answer, sizeof(dummy_answer), "m=audio 0 RTP/AVP %s\r\n", p->offered_media[SDP_AUDIO].codecs); 11569 add_content(resp, dummy_answer); 11570 } 11571 } else if (p->offered_media[SDP_VIDEO].order_offered == i) { 11572 if (needvideo) { /* only if video response is appropriate */ 11573 add_content(resp, m_video->str); 11574 add_content(resp, a_video->str); 11575 add_content(resp, hold); /* Repeat hold for the video stream */ 11576 if (v_a_crypto) { 11577 add_content(resp, v_a_crypto); 11578 } 11579 } else { 11580 snprintf(dummy_answer, sizeof(dummy_answer), "m=video 0 RTP/AVP %s\r\n", p->offered_media[SDP_VIDEO].codecs); 11581 add_content(resp, dummy_answer); 11582 } 11583 } else if (p->offered_media[SDP_TEXT].order_offered == i) { 11584 if (needtext) { /* only if text response is appropriate */ 11585 add_content(resp, m_text->str); 11586 add_content(resp, a_text->str); 11587 add_content(resp, hold); /* Repeat hold for the text stream */ 11588 if (t_a_crypto) { 11589 add_content(resp, t_a_crypto); 11590 } 11591 } else { 11592 snprintf(dummy_answer, sizeof(dummy_answer), "m=text 0 RTP/AVP %s\r\n", p->offered_media[SDP_TEXT].codecs); 11593 add_content(resp, dummy_answer); 11594 } 11595 } else if (p->offered_media[SDP_IMAGE].order_offered == i) { 11596 if (add_t38) { 11597 add_content(resp, m_modem->str); 11598 add_content(resp, a_modem->str); 11599 } else { 11600 add_content(resp, "m=image 0 udptl t38\r\n"); 11601 } 11602 } 11603 } 11604 } else { 11605 /* generate new SDP from scratch, no offers */ 11606 if (needaudio) { 11607 add_content(resp, m_audio->str); 11608 add_content(resp, a_audio->str); 11609 add_content(resp, hold); 11610 if (a_crypto) { 11611 add_content(resp, a_crypto); 11612 } 11613 } 11614 if (needvideo) { /* only if video response is appropriate */ 11615 add_content(resp, m_video->str); 11616 add_content(resp, a_video->str); 11617 add_content(resp, hold); /* Repeat hold for the video stream */ 11618 if (v_a_crypto) { 11619 add_content(resp, v_a_crypto); 11620 } 11621 } 11622 if (needtext) { /* only if text response is appropriate */ 11623 add_content(resp, m_text->str); 11624 add_content(resp, a_text->str); 11625 add_content(resp, hold); /* Repeat hold for the text stream */ 11626 if (t_a_crypto) { 11627 add_content(resp, t_a_crypto); 11628 } 11629 } 11630 if (add_t38) { 11631 add_content(resp, m_modem->str); 11632 add_content(resp, a_modem->str); 11633 } 11634 } 11635 11636 /* Update lastrtprx when we send our SDP */ 11637 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 11638 11639 ast_debug(3, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 11640 11641 return AST_SUCCESS; 11642 }
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 26804 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.
26805 { 26806 struct domain *d; 26807 26808 if (ast_strlen_zero(domain)) { 26809 ast_log(LOG_WARNING, "Zero length domain.\n"); 26810 return 1; 26811 } 26812 26813 if (!(d = ast_calloc(1, sizeof(*d)))) 26814 return 0; 26815 26816 ast_copy_string(d->domain, domain, sizeof(d->domain)); 26817 26818 if (!ast_strlen_zero(context)) 26819 ast_copy_string(d->context, context, sizeof(d->context)); 26820 26821 d->mode = mode; 26822 26823 AST_LIST_LOCK(&domain_list); 26824 AST_LIST_INSERT_TAIL(&domain_list, d, list); 26825 AST_LIST_UNLOCK(&domain_list); 26826 26827 if (sipdebug) 26828 ast_debug(1, "Added local SIP domain '%s'\n", domain); 26829 26830 return 1; 26831 }
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 9804 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().
09805 { 09806 int res; 09807 if (st_get_mode(pvt, 0) != SESSION_TIMER_MODE_REFUSE) { 09808 res = add_header(req, "Supported", "replaces, timer"); 09809 } else { 09810 res = add_header(req, "Supported", "replaces"); 09811 } 09812 return res; 09813 }
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 11026 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().
11029 { 11030 int rtp_code; 11031 11032 if (!p->trtp) 11033 return; 11034 11035 if (debug) 11036 ast_verbose("Adding text codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 11037 11038 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, codec)) == -1) 11039 return; 11040 11041 ast_str_append(m_buf, 0, " %d", rtp_code); 11042 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code, 11043 ast_rtp_lookup_mime_subtype2(1, codec, 0), 11044 ast_rtp_lookup_sample_rate2(1, codec)); 11045 /* Add fmtp code here */ 11046 11047 if (codec == AST_FORMAT_T140RED) { 11048 int t140code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, AST_FORMAT_T140); 11049 ast_str_append(a_buf, 0, "a=fmtp:%d %d/%d/%d\r\n", rtp_code, 11050 t140code, 11051 t140code, 11052 t140code); 11053 11054 } 11055 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 10788 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_message_with_text().
10789 { 10790 /* XXX Convert \n's to \r\n's XXX */ 10791 add_header(req, "Content-Type", "text/plain;charset=UTF-8"); 10792 add_content(req, text); 10793 return 0; 10794 }
static struct ast_variable* add_var | ( | const char * | buf, | |
struct ast_variable * | list | |||
) | [static] |
implement the setvar config line
Definition at line 26984 of file chan_sip.c.
References ast_strdupa, ast_variable_new(), and ast_variable::next.
26985 { 26986 struct ast_variable *tmpvar = NULL; 26987 char *varname = ast_strdupa(buf), *varval = NULL; 26988 26989 if ((varval = strchr(varname, '='))) { 26990 *varval++ = '\0'; 26991 if ((tmpvar = ast_variable_new(varname, varval, ""))) { 26992 tmpvar->next = list; 26993 list = tmpvar; 26994 } 26995 } 26996 return list; 26997 }
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 11003 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().
11006 { 11007 int rtp_code; 11008 11009 if (!p->vrtp) 11010 return; 11011 11012 if (debug) 11013 ast_verbose("Adding video codec 0x%" PRIx64 " (%s) to SDP\n", codec, ast_getformatname(codec)); 11014 11015 if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->vrtp), 1, codec)) == -1) 11016 return; 11017 11018 ast_str_append(m_buf, 0, " %d", rtp_code); 11019 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code, 11020 ast_rtp_lookup_mime_subtype2(1, codec, 0), 11021 ast_rtp_lookup_sample_rate2(1, codec)); 11022 /* Add fmtp code here */ 11023 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 10924 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_info_with_vidupdate().
10925 { 10926 const char *xml_is_a_huge_waste_of_space = 10927 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 10928 " <media_control>\r\n" 10929 " <vc_primitive>\r\n" 10930 " <to_encoder>\r\n" 10931 " <picture_fast_update>\r\n" 10932 " </picture_fast_update>\r\n" 10933 " </to_encoder>\r\n" 10934 " </vc_primitive>\r\n" 10935 " </media_control>\r\n"; 10936 add_header(req, "Content-Type", "application/media_control+xml"); 10937 add_content(req, xml_is_a_huge_waste_of_space); 10938 return 0; 10939 }
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 7779 of file chan_sip.c.
References ast_sockaddr_ipv4().
Referenced by process_via().
07780 { 07781 return ((ast_sockaddr_ipv4(addr) & 0xf0000000) == 0xe0000000); 07782 }
static const char * allowoverlap2str | ( | int | mode | ) | const [static] |
Convert AllowOverlap setting to printable string.
Definition at line 16920 of file chan_sip.c.
References allowoverlapstr, and map_x_s().
Referenced by _sip_show_peer(), and sip_show_settings().
16921 { 16922 return map_x_s(allowoverlapstr, mode, "<error>"); 16923 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 10611 of file chan_sip.c.
References add_header().
10612 { 10613 char tmpdat[256]; 10614 struct tm tm; 10615 time_t t = time(NULL); 10616 10617 gmtime_r(&t, &tm); 10618 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 10619 add_header(req, "Date", tmpdat); 10620 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 3530 of file chan_sip.c.
References append_history_va(), dumphistory, and recordhistory.
03531 { 03532 va_list ap; 03533 03534 if (!p) { 03535 return; 03536 } 03537 03538 if (!p->do_history && !recordhistory && !dumphistory) { 03539 return; 03540 } 03541 03542 va_start(ap, fmt); 03543 append_history_va(p, fmt, ap); 03544 va_end(ap); 03545 03546 return; 03547 }
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 3502 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().
03503 { 03504 char buf[80], *c = buf; /* max history length */ 03505 struct sip_history *hist; 03506 int l; 03507 03508 vsnprintf(buf, sizeof(buf), fmt, ap); 03509 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 03510 l = strlen(buf) + 1; 03511 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) { 03512 return; 03513 } 03514 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 03515 ast_free(hist); 03516 return; 03517 } 03518 memcpy(hist->event, buf, l); 03519 if (p->history_entries == MAX_HISTORY_ENTRIES) { 03520 struct sip_history *oldest; 03521 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 03522 p->history_entries--; 03523 ast_free(oldest); 03524 } 03525 AST_LIST_INSERT_TAIL(p->history, hist, list); 03526 p->history_entries++; 03527 }
static int apply_directmedia_ha | ( | struct sip_pvt * | p, | |
const char * | op | |||
) | [static] |
Definition at line 28935 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().
28936 { 28937 struct ast_sockaddr us = { { 0, }, }, them = { { 0, }, }; 28938 int res = AST_SENSE_ALLOW; 28939 28940 ast_rtp_instance_get_remote_address(p->rtp, &them); 28941 ast_rtp_instance_get_local_address(p->rtp, &us); 28942 28943 if ((res = ast_apply_ha(p->directmediaha, &them)) == AST_SENSE_DENY) { 28944 const char *us_addr = ast_strdupa(ast_sockaddr_stringify(&us)); 28945 const char *them_addr = ast_strdupa(ast_sockaddr_stringify(&them)); 28946 28947 ast_debug(3, "Reinvite %s to %s denied by directmedia ACL on %s\n", 28948 op, them_addr, us_addr); 28949 } 28950 28951 return res; 28952 }
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 21501 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().
21502 { 21503 if (chan && chan->_state == AST_STATE_UP) { 21504 if (ast_test_flag(chan, AST_FLAG_MOH)) 21505 ast_moh_stop(chan); 21506 else if (chan->generatordata) 21507 ast_deactivate_generator(chan); 21508 } 21509 }
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 3396 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().
03397 { 03398 struct ast_sockaddr theirs; 03399 03400 /* Set want_remap to non-zero if we want to remap 'us' to an externally 03401 * reachable IP address and port. This is done if: 03402 * 1. we have a localaddr list (containing 'internal' addresses marked 03403 * as 'deny', so ast_apply_ha() will return AST_SENSE_DENY on them, 03404 * and AST_SENSE_ALLOW on 'external' ones); 03405 * 2. externaddr is set, so we know what to use as the 03406 * externally visible address; 03407 * 3. the remote address, 'them', is external; 03408 * 4. the address returned by ast_ouraddrfor() is 'internal' (AST_SENSE_DENY 03409 * when passed to ast_apply_ha() so it does need to be remapped. 03410 * This fourth condition is checked later. 03411 */ 03412 int want_remap = 0; 03413 03414 ast_sockaddr_copy(us, &internip); /* starting guess for the internal address */ 03415 /* now ask the system what would it use to talk to 'them' */ 03416 ast_ouraddrfor(them, us); 03417 ast_sockaddr_copy(&theirs, them); 03418 03419 if (ast_sockaddr_is_ipv6(&theirs)) { 03420 if (localaddr && !ast_sockaddr_isnull(&externaddr)) { 03421 ast_log(LOG_WARNING, "Address remapping activated in sip.conf " 03422 "but we're using IPv6, which doesn't need it. Please " 03423 "remove \"localnet\" and/or \"externaddr\" settings.\n"); 03424 } 03425 } else { 03426 want_remap = localaddr && 03427 !ast_sockaddr_isnull(&externaddr) && 03428 ast_apply_ha(localaddr, &theirs) == AST_SENSE_ALLOW ; 03429 } 03430 03431 if (want_remap && 03432 (!sip_cfg.matchexternaddrlocally || !ast_apply_ha(localaddr, us)) ) { 03433 /* if we used externhost, see if it is time to refresh the info */ 03434 if (externexpire && time(NULL) >= externexpire) { 03435 if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) { 03436 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 03437 } 03438 externexpire = time(NULL) + externrefresh; 03439 } 03440 if (!ast_sockaddr_isnull(&externaddr)) { 03441 ast_sockaddr_copy(us, &externaddr); 03442 switch (p->socket.type) { 03443 case SIP_TRANSPORT_TCP: 03444 if (!externtcpport && ast_sockaddr_port(&externaddr)) { 03445 /* for consistency, default to the externaddr port */ 03446 externtcpport = ast_sockaddr_port(&externaddr); 03447 } 03448 ast_sockaddr_set_port(us, externtcpport); 03449 break; 03450 case SIP_TRANSPORT_TLS: 03451 ast_sockaddr_set_port(us, externtlsport); 03452 break; 03453 case SIP_TRANSPORT_UDP: 03454 if (!ast_sockaddr_port(&externaddr)) { 03455 ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr)); 03456 } 03457 break; 03458 default: 03459 break; 03460 } 03461 } 03462 ast_debug(1, "Target address %s is not local, substituting externaddr\n", 03463 ast_sockaddr_stringify(them)); 03464 } else if (p) { 03465 /* no remapping, but we bind to a specific address, so use it. */ 03466 switch (p->socket.type) { 03467 case SIP_TRANSPORT_TCP: 03468 if (!ast_sockaddr_is_any(&sip_tcp_desc.local_address)) { 03469 ast_sockaddr_copy(us, 03470 &sip_tcp_desc.local_address); 03471 } else { 03472 ast_sockaddr_set_port(us, 03473 ast_sockaddr_port(&sip_tcp_desc.local_address)); 03474 } 03475 break; 03476 case SIP_TRANSPORT_TLS: 03477 if (!ast_sockaddr_is_any(&sip_tls_desc.local_address)) { 03478 ast_sockaddr_copy(us, 03479 &sip_tls_desc.local_address); 03480 } else { 03481 ast_sockaddr_set_port(us, 03482 ast_sockaddr_port(&sip_tls_desc.local_address)); 03483 } 03484 break; 03485 case SIP_TRANSPORT_UDP: 03486 /* fall through on purpose */ 03487 default: 03488 if (!ast_sockaddr_is_any(&bindaddr)) { 03489 ast_sockaddr_copy(us, &bindaddr); 03490 } 03491 if (!ast_sockaddr_port(us)) { 03492 ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr)); 03493 } 03494 } 03495 } else if (!ast_sockaddr_is_any(&bindaddr)) { 03496 ast_sockaddr_copy(us, &bindaddr); 03497 } 03498 ast_debug(3, "Setting SIP_TRANSPORT_%s with address %s\n", get_transport(p->socket.type), ast_sockaddr_stringify(us)); 03499 }
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 29636 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().
29638 { 29639 return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(&bindaddr)); 29640 }
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 29612 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().
29614 { 29615 struct ast_sockaddr *addrs; 29616 int addrs_cnt; 29617 29618 addrs_cnt = ast_sockaddr_resolve(&addrs, name, flag, family); 29619 if (addrs_cnt <= 0) { 29620 return 1; 29621 } 29622 if (addrs_cnt > 1) { 29623 ast_debug(1, "Multiple addresses, using the first one only\n"); 29624 } 29625 29626 ast_sockaddr_copy(addr, &addrs[0]); 29627 29628 ast_free(addrs); 29629 return 0; 29630 }
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 21513 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.
21514 { 21515 int res = 0; 21516 struct ast_channel *peera = NULL, 21517 *peerb = NULL, 21518 *peerc = NULL, 21519 *peerd = NULL; 21520 21521 21522 /* We will try to connect the transferee with the target and hangup 21523 all channels to the transferer */ 21524 ast_debug(4, "Sip transfer:--------------------\n"); 21525 if (transferer->chan1) 21526 ast_debug(4, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 21527 else 21528 ast_debug(4, "-- No transferer first channel - odd??? \n"); 21529 if (target->chan1) 21530 ast_debug(4, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 21531 else 21532 ast_debug(4, "-- No target first channel ---\n"); 21533 if (transferer->chan2) 21534 ast_debug(4, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 21535 else 21536 ast_debug(4, "-- No bridged call to transferee\n"); 21537 if (target->chan2) 21538 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)"); 21539 else 21540 ast_debug(4, "-- No target second channel ---\n"); 21541 ast_debug(4, "-- END Sip transfer:--------------------\n"); 21542 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 21543 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 21544 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 21545 peerc = transferer->chan2; /* Asterisk to Transferee */ 21546 peerd = target->chan2; /* Asterisk to Target */ 21547 ast_debug(3, "SIP transfer: Four channels to handle\n"); 21548 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 21549 peera = target->chan1; /* Transferer to PBX -> target channel */ 21550 peerb = transferer->chan1; /* Transferer to IVR*/ 21551 peerc = target->chan2; /* Asterisk to Target */ 21552 peerd = transferer->chan2; /* Nothing */ 21553 ast_debug(3, "SIP transfer: Three channels to handle\n"); 21554 } 21555 21556 if (peera && peerb && peerc && (peerb != peerc)) { 21557 ast_quiet_chan(peera); /* Stop generators */ 21558 ast_quiet_chan(peerb); 21559 ast_quiet_chan(peerc); 21560 if (peerd) 21561 ast_quiet_chan(peerd); 21562 21563 ast_debug(4, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 21564 if (ast_channel_masquerade(peerb, peerc)) { 21565 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 21566 res = -1; 21567 } else 21568 ast_debug(4, "SIP transfer: Succeeded to masquerade channels.\n"); 21569 return res; 21570 } else { 21571 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 21572 if (transferer->chan1) 21573 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 21574 if (target->chan1) 21575 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 21576 return -1; 21577 } 21578 return 0; 21579 }
static void auth_headers | ( | enum sip_auth_type | code, | |
char ** | header, | |||
char ** | respheader | |||
) | [static] |
return the request and response header for a 401 or 407 code
Definition at line 13603 of file chan_sip.c.
References ast_verbose.
Referenced by check_auth(), do_proxy_auth(), do_register_auth(), and transmit_request_with_auth().
13604 { 13605 if (code == WWW_AUTH) { /* 401 */ 13606 *header = "WWW-Authenticate"; 13607 *respheader = "Authorization"; 13608 } else if (code == PROXY_AUTH) { /* 407 */ 13609 *header = "Proxy-Authenticate"; 13610 *respheader = "Proxy-Authorization"; 13611 } else { 13612 ast_verbose("-- wrong response code %d\n", code); 13613 *header = *respheader = "Invalid"; 13614 } 13615 }
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 5508 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().
05509 { 05510 struct sip_pvt *p = (struct sip_pvt *)arg; 05511 05512 sip_pvt_lock(p); 05513 p->initid = -1; /* event gone, will not be rescheduled */ 05514 if (p->owner) { 05515 /* XXX fails on possible deadlock */ 05516 if (!ast_channel_trylock(p->owner)) { 05517 append_history(p, "Cong", "Auto-congesting (timer)"); 05518 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 05519 ast_channel_unlock(p->owner); 05520 } 05521 05522 /* Give the channel a chance to act before we proceed with destruction */ 05523 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 05524 } 05525 sip_pvt_unlock(p); 05526 dialog_unref(p, "unreffing arg passed into auto_congest callback (p->initid)"); 05527 return 0; 05528 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 7550 of file chan_sip.c.
References ast_sockaddr_stringify_remote(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by change_callid_pvt(), and sip_alloc().
07551 { 07552 char buf[33]; 07553 const char *host = S_OR(pvt->fromdomain, ast_sockaddr_stringify_remote(&pvt->ourip)); 07554 07555 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 07556 }
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 7600 of file chan_sip.c.
References ast_sockaddr_stringify_host_remote(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by transmit_register().
07601 { 07602 char buf[33]; 07603 07604 const char *host = S_OR(fromdomain, ast_sockaddr_stringify_host_remote(ourip)); 07605 07606 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 07607 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 11886 of file chan_sip.c.
References ast_sockaddr_stringify_remote(), ast_string_field_build, ast_strlen_zero(), ast_uri_encode(), and get_transport().
Referenced by __sip_subscribe_mwi_do(), check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().
11887 { 11888 char tmp[SIPBUFSIZE]; 11889 char *user = ast_uri_encode(p->exten, tmp, sizeof(tmp), 0); 11890 11891 if (p->socket.type == SIP_TRANSPORT_UDP) { 11892 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", user, 11893 ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify_remote(&p->ourip)); 11894 } else { 11895 ast_string_field_build(p, our_contact, "<sip:%s%s%s;transport=%s>", user, 11896 ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify_remote(&p->ourip), 11897 get_transport(p->socket.type)); 11898 } 11899 }
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 27134 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_lock, ao2_t_alloc, ao2_t_find, ao2_t_ref, ao2_t_unlink, ao2_unlock, 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_cb(), ast_dnsmgr_refresh(), ast_free, ast_free_ha(), ast_get_cc_agent_policy(), ast_get_group(), ast_get_ip(), ast_get_time_t(), AST_LIST_EMPTY, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), AST_SCHED_DEL_UNREF, ast_set2_flag, ast_set_cc_agent_policy(), ast_set_flag, ast_skip_blanks(), ast_sockaddr_isnull(), ast_sockaddr_parse(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_setnull(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), ast_str_strlen(), ast_strdupa, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variables_destroy(), bindaddr, can_parse_xml, cid_name, cid_num, config, context, default_maxcallbitrate, DEFAULT_MAXMS, default_primary_transport, default_qualify, default_tls_cfg, default_transports, destroy_association(), destroy_mailbox(), ast_tls_config::enabled, 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, on_dns_update_peer(), parkinglot, PARSE_PORT_FORBID, peers_by_ip, port_str2int(), proxy_update(), ref_peer(), reg_source_db(), rpeerobjs, secret, set_peer_defaults(), set_socket_transport(), sip_cfg, sip_destroy_peer_fn(), sip_parse_host(), sip_poke_peer(), sip_register(), sip_send_mwi_to_peer(), speerobjs, srvlookup, str2stmode(), str2strefresher(), strsep(), TRUE, unref_peer(), and ast_variable::value.
27135 { 27136 struct sip_peer *peer = NULL; 27137 struct ast_ha *oldha = NULL; 27138 struct ast_ha *olddirectmediaha = NULL; 27139 int found = 0; 27140 int firstpass = 1; 27141 uint16_t port = 0; 27142 int format = 0; /* Ama flags */ 27143 int timerb_set = 0, timert1_set = 0; 27144 time_t regseconds = 0; 27145 struct ast_flags peerflags[3] = {{(0)}}; 27146 struct ast_flags mask[3] = {{(0)}}; 27147 char callback[256] = ""; 27148 struct sip_peer tmp_peer; 27149 const char *srvlookup = NULL; 27150 static int deprecation_warning = 1; 27151 int alt_fullcontact = alt ? 1 : 0, headercount = 0; 27152 struct ast_str *fullcontact = ast_str_alloca(512); 27153 27154 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 27155 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 27156 /* We also use a case-sensitive comparison (unlike find_peer) so 27157 that case changes made to the peer name will be properly handled 27158 during reload 27159 */ 27160 ast_copy_string(tmp_peer.name, name, sizeof(tmp_peer.name)); 27161 peer = ao2_t_find(peers, &tmp_peer, OBJ_POINTER | OBJ_UNLINK, "find and unlink peer from peers table"); 27162 } 27163 27164 if (peer) { 27165 /* Already in the list, remove it and it will be added back (or FREE'd) */ 27166 found++; 27167 /* we've unlinked the peer from the peers container but not unlinked from the peers_by_ip container yet 27168 this leads to a wrong refcounter and the peer object is never destroyed */ 27169 if (!ast_sockaddr_isnull(&peer->addr)) { 27170 ao2_t_unlink(peers_by_ip, peer, "ao2_unlink peer from peers_by_ip table"); 27171 } 27172 if (!(peer->the_mark)) 27173 firstpass = 0; 27174 } else { 27175 if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct"))) 27176 return NULL; 27177 27178 if (ast_string_field_init(peer, 512)) { 27179 ao2_t_ref(peer, -1, "failed to string_field_init, drop peer"); 27180 return NULL; 27181 } 27182 27183 if (!(peer->cc_params = ast_cc_config_params_init())) { 27184 ao2_t_ref(peer, -1, "failed to allocate cc_params for peer"); 27185 return NULL; 27186 } 27187 27188 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 27189 ast_atomic_fetchadd_int(&rpeerobjs, 1); 27190 ast_debug(3, "-REALTIME- peer built. Name: %s. Peer objects: %d\n", name, rpeerobjs); 27191 } else 27192 ast_atomic_fetchadd_int(&speerobjs, 1); 27193 } 27194 27195 /* Note that our peer HAS had its reference count increased */ 27196 if (firstpass) { 27197 peer->lastmsgssent = -1; 27198 oldha = peer->ha; 27199 peer->ha = NULL; 27200 olddirectmediaha = peer->directmediaha; 27201 peer->directmediaha = NULL; 27202 set_peer_defaults(peer); /* Set peer defaults */ 27203 peer->type = 0; 27204 } 27205 27206 /* in case the case of the peer name has changed, update the name */ 27207 ast_copy_string(peer->name, name, sizeof(peer->name)); 27208 27209 /* If we have channel variables, remove them (reload) */ 27210 if (peer->chanvars) { 27211 ast_variables_destroy(peer->chanvars); 27212 peer->chanvars = NULL; 27213 /* XXX should unregister ? */ 27214 } 27215 27216 if (found) 27217 peer->portinuri = 0; 27218 27219 /* If we have realm authentication information, remove them (reload) */ 27220 ao2_lock(peer); 27221 if (peer->auth) { 27222 ao2_t_ref(peer->auth, -1, "Removing old peer authentication"); 27223 peer->auth = NULL; 27224 } 27225 ao2_unlock(peer); 27226 27227 /* clear the transport information. We will detect if a default value is required after parsing the config */ 27228 peer->default_outbound_transport = 0; 27229 peer->transports = 0; 27230 27231 if (!devstate_only) { 27232 struct sip_mailbox *mailbox; 27233 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 27234 mailbox->delme = 1; 27235 } 27236 } 27237 27238 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 27239 if (!devstate_only) { 27240 if (handle_common_options(&peerflags[0], &mask[0], v)) { 27241 continue; 27242 } 27243 if (handle_t38_options(&peerflags[0], &mask[0], v, &peer->t38_maxdatagram)) { 27244 continue; 27245 } 27246 if (!strcasecmp(v->name, "transport") && !ast_strlen_zero(v->value)) { 27247 char *val = ast_strdupa(v->value); 27248 char *trans; 27249 27250 while ((trans = strsep(&val, ","))) { 27251 trans = ast_skip_blanks(trans); 27252 27253 if (!strncasecmp(trans, "udp", 3)) { 27254 peer->transports |= SIP_TRANSPORT_UDP; 27255 } else if (sip_cfg.tcp_enabled && !strncasecmp(trans, "tcp", 3)) { 27256 peer->transports |= SIP_TRANSPORT_TCP; 27257 } else if (default_tls_cfg.enabled && !strncasecmp(trans, "tls", 3)) { 27258 peer->transports |= SIP_TRANSPORT_TLS; 27259 } else if (!strncasecmp(trans, "tcp", 3) || !strncasecmp(trans, "tls", 3)) { 27260 ast_log(LOG_WARNING, "'%.3s' is not a valid transport type when %.3senabled=no. If no other is specified, the defaults from general will be used.\n", trans, trans); 27261 } else { 27262 ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, the defaults from general will be used.\n", trans); 27263 } 27264 27265 if (!peer->default_outbound_transport) { /*!< The first transport listed should be default outbound */ 27266 peer->default_outbound_transport = peer->transports; 27267 } 27268 } 27269 } else if (realtime && !strcasecmp(v->name, "regseconds")) { 27270 ast_get_time_t(v->value, ®seconds, 0, NULL); 27271 } else if (realtime && !strcasecmp(v->name, "name")) { 27272 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 27273 } else if (realtime && !strcasecmp(v->name, "useragent")) { 27274 ast_string_field_set(peer, useragent, v->value); 27275 } else if (!strcasecmp(v->name, "type")) { 27276 if (!strcasecmp(v->value, "peer")) { 27277 peer->type |= SIP_TYPE_PEER; 27278 } else if (!strcasecmp(v->value, "user")) { 27279 peer->type |= SIP_TYPE_USER; 27280 } else if (!strcasecmp(v->value, "friend")) { 27281 peer->type = SIP_TYPE_USER | SIP_TYPE_PEER; 27282 } 27283 } else if (!strcasecmp(v->name, "remotesecret")) { 27284 ast_string_field_set(peer, remotesecret, v->value); 27285 } else if (!strcasecmp(v->name, "secret")) { 27286 ast_string_field_set(peer, secret, v->value); 27287 } else if (!strcasecmp(v->name, "md5secret")) { 27288 ast_string_field_set(peer, md5secret, v->value); 27289 } else if (!strcasecmp(v->name, "auth")) { 27290 add_realm_authentication(&peer->auth, v->value, v->lineno); 27291 } else if (!strcasecmp(v->name, "callerid")) { 27292 char cid_name[80] = { '\0' }, cid_num[80] = { '\0' }; 27293 27294 ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num)); 27295 ast_string_field_set(peer, cid_name, cid_name); 27296 ast_string_field_set(peer, cid_num, cid_num); 27297 } else if (!strcasecmp(v->name, "mwi_from")) { 27298 ast_string_field_set(peer, mwi_from, v->value); 27299 } else if (!strcasecmp(v->name, "fullname")) { 27300 ast_string_field_set(peer, cid_name, v->value); 27301 } else if (!strcasecmp(v->name, "trunkname")) { 27302 /* This is actually for a trunk, so we don't want to override callerid */ 27303 ast_string_field_set(peer, cid_name, ""); 27304 } else if (!strcasecmp(v->name, "cid_number")) { 27305 ast_string_field_set(peer, cid_num, v->value); 27306 } else if (!strcasecmp(v->name, "cid_tag")) { 27307 ast_string_field_set(peer, cid_tag, v->value); 27308 } else if (!strcasecmp(v->name, "context")) { 27309 ast_string_field_set(peer, context, v->value); 27310 ast_set_flag(&peer->flags[1], SIP_PAGE2_HAVEPEERCONTEXT); 27311 } else if (!strcasecmp(v->name, "subscribecontext")) { 27312 ast_string_field_set(peer, subscribecontext, v->value); 27313 } else if (!strcasecmp(v->name, "fromdomain")) { 27314 char *fromdomainport; 27315 ast_string_field_set(peer, fromdomain, v->value); 27316 if ((fromdomainport = strchr(peer->fromdomain, ':'))) { 27317 *fromdomainport++ = '\0'; 27318 if (!(peer->fromdomainport = port_str2int(fromdomainport, 0))) { 27319 ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport); 27320 } 27321 } else { 27322 peer->fromdomainport = STANDARD_SIP_PORT; 27323 } 27324 } else if (!strcasecmp(v->name, "usereqphone")) { 27325 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 27326 } else if (!strcasecmp(v->name, "fromuser")) { 27327 ast_string_field_set(peer, fromuser, v->value); 27328 } else if (!strcasecmp(v->name, "outboundproxy")) { 27329 char *tok, *proxyname; 27330 27331 if (ast_strlen_zero(v->value)) { 27332 ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf.", v->lineno); 27333 continue; 27334 } 27335 27336 peer->outboundproxy = 27337 ao2_alloc(sizeof(*peer->outboundproxy), NULL); 27338 27339 tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ",")); 27340 27341 sip_parse_host(tok, v->lineno, &proxyname, 27342 &peer->outboundproxy->port, 27343 &peer->outboundproxy->transport); 27344 27345 tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ",")); 27346 27347 if ((tok = strtok(NULL, ","))) { 27348 peer->outboundproxy->force = !strncasecmp(ast_skip_blanks(tok), "force", 5); 27349 } else { 27350 peer->outboundproxy->force = FALSE; 27351 } 27352 27353 if (ast_strlen_zero(proxyname)) { 27354 ast_log(LOG_WARNING, "you must specify a name for the outboundproxy on line %d of sip.conf.", v->lineno); 27355 sip_cfg.outboundproxy.name[0] = '\0'; 27356 continue; 27357 } 27358 27359 ast_copy_string(peer->outboundproxy->name, proxyname, sizeof(peer->outboundproxy->name)); 27360 27361 proxy_update(peer->outboundproxy); 27362 } else if (!strcasecmp(v->name, "host")) { 27363 if (!strcasecmp(v->value, "dynamic")) { 27364 /* They'll register with us */ 27365 if (!found || !peer->host_dynamic) { 27366 /* Initialize stuff if this is a new peer, or if it used to 27367 * not be dynamic before the reload. */ 27368 ast_sockaddr_setnull(&peer->addr); 27369 } 27370 peer->host_dynamic = TRUE; 27371 } else { 27372 /* Non-dynamic. Make sure we become that way if we're not */ 27373 AST_SCHED_DEL_UNREF(sched, peer->expire, 27374 unref_peer(peer, "removing register expire ref")); 27375 peer->host_dynamic = FALSE; 27376 srvlookup = v->value; 27377 } 27378 } else if (!strcasecmp(v->name, "defaultip")) { 27379 if (!ast_strlen_zero(v->value) && ast_get_ip(&peer->defaddr, v->value)) { 27380 unref_peer(peer, "unref_peer: from build_peer defaultip"); 27381 return NULL; 27382 } 27383 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 27384 int ha_error = 0; 27385 if (!ast_strlen_zero(v->value)) { 27386 peer->ha = ast_append_ha(v->name, v->value, peer->ha, &ha_error); 27387 } 27388 if (ha_error) { 27389 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 27390 } 27391 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 27392 int ha_error = 0; 27393 if (!ast_strlen_zero(v->value)) { 27394 peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha, &ha_error); 27395 } 27396 if (ha_error) { 27397 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 27398 } 27399 } else if (!strcasecmp(v->name, "directmediapermit") || !strcasecmp(v->name, "directmediadeny")) { 27400 int ha_error = 0; 27401 peer->directmediaha = ast_append_ha(v->name + 11, v->value, peer->directmediaha, &ha_error); 27402 if (ha_error) { 27403 ast_log(LOG_ERROR, "Bad directmedia ACL entry in configuration line %d : %s\n", v->lineno, v->value); 27404 } 27405 } else if (!strcasecmp(v->name, "port")) { 27406 peer->portinuri = 1; 27407 if (!(port = port_str2int(v->value, 0))) { 27408 if (realtime) { 27409 /* If stored as integer, could be 0 for some DBs (notably MySQL) */ 27410 peer->portinuri = 0; 27411 } else { 27412 ast_log(LOG_WARNING, "Invalid peer port configuration at line %d : %s\n", v->lineno, v->value); 27413 } 27414 } 27415 } else if (!strcasecmp(v->name, "callingpres")) { 27416 peer->callingpres = ast_parse_caller_presentation(v->value); 27417 if (peer->callingpres == -1) { 27418 peer->callingpres = atoi(v->value); 27419 } 27420 } else if (!strcasecmp(v->name, "username") || !strcmp(v->name, "defaultuser")) { /* "username" is deprecated */ 27421 ast_string_field_set(peer, username, v->value); 27422 if (!strcasecmp(v->name, "username")) { 27423 if (deprecation_warning) { 27424 ast_log(LOG_NOTICE, "The 'username' field for sip peers has been deprecated in favor of the term 'defaultuser'\n"); 27425 deprecation_warning = 0; 27426 } 27427 peer->deprecated_username = 1; 27428 } 27429 } else if (!strcasecmp(v->name, "language")) { 27430 ast_string_field_set(peer, language, v->value); 27431 } else if (!strcasecmp(v->name, "regexten")) { 27432 ast_string_field_set(peer, regexten, v->value); 27433 } else if (!strcasecmp(v->name, "callbackextension")) { 27434 ast_copy_string(callback, v->value, sizeof(callback)); 27435 } else if (!strcasecmp(v->name, "amaflags")) { 27436 format = ast_cdr_amaflags2int(v->value); 27437 if (format < 0) { 27438 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 27439 } else { 27440 peer->amaflags = format; 27441 } 27442 } else if (!strcasecmp(v->name, "maxforwards")) { 27443 if (sscanf(v->value, "%30d", &peer->maxforwards) != 1 27444 || peer->maxforwards < 1 || 255 < peer->maxforwards) { 27445 ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d. Using default.\n", v->value, v->lineno); 27446 peer->maxforwards = sip_cfg.default_max_forwards; 27447 } 27448 } else if (!strcasecmp(v->name, "accountcode")) { 27449 ast_string_field_set(peer, accountcode, v->value); 27450 } else if (!strcasecmp(v->name, "mohinterpret")) { 27451 ast_string_field_set(peer, mohinterpret, v->value); 27452 } else if (!strcasecmp(v->name, "mohsuggest")) { 27453 ast_string_field_set(peer, mohsuggest, v->value); 27454 } else if (!strcasecmp(v->name, "parkinglot")) { 27455 ast_string_field_set(peer, parkinglot, v->value); 27456 } else if (!strcasecmp(v->name, "rtp_engine")) { 27457 ast_string_field_set(peer, engine, v->value); 27458 } else if (!strcasecmp(v->name, "mailbox")) { 27459 add_peer_mailboxes(peer, v->value); 27460 } else if (!strcasecmp(v->name, "hasvoicemail")) { 27461 /* People expect that if 'hasvoicemail' is set, that the mailbox will 27462 * be also set, even if not explicitly specified. */ 27463 if (ast_true(v->value) && AST_LIST_EMPTY(&peer->mailboxes)) { 27464 add_peer_mailboxes(peer, name); 27465 } 27466 } else if (!strcasecmp(v->name, "subscribemwi")) { 27467 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 27468 } else if (!strcasecmp(v->name, "vmexten")) { 27469 ast_string_field_set(peer, vmexten, v->value); 27470 } else if (!strcasecmp(v->name, "callgroup")) { 27471 peer->callgroup = ast_get_group(v->value); 27472 } else if (!strcasecmp(v->name, "allowtransfer")) { 27473 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 27474 } else if (!strcasecmp(v->name, "pickupgroup")) { 27475 peer->pickupgroup = ast_get_group(v->value); 27476 } else if (!strcasecmp(v->name, "allow")) { 27477 int error = ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, TRUE); 27478 if (error) { 27479 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 27480 } 27481 } else if (!strcasecmp(v->name, "disallow")) { 27482 int error = ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, FALSE); 27483 if (error) { 27484 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 27485 } 27486 } else if (!strcasecmp(v->name, "preferred_codec_only")) { 27487 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC); 27488 } else if (!strcasecmp(v->name, "autoframing")) { 27489 peer->autoframing = ast_true(v->value); 27490 } else if (!strcasecmp(v->name, "rtptimeout")) { 27491 if ((sscanf(v->value, "%30d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 27492 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 27493 peer->rtptimeout = global_rtptimeout; 27494 } 27495 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 27496 if ((sscanf(v->value, "%30d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 27497 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 27498 peer->rtpholdtimeout = global_rtpholdtimeout; 27499 } 27500 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 27501 if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 27502 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 27503 peer->rtpkeepalive = global_rtpkeepalive; 27504 } 27505 } else if (!strcasecmp(v->name, "timert1")) { 27506 if ((sscanf(v->value, "%30d", &peer->timer_t1) != 1) || (peer->timer_t1 < 200) || (peer->timer_t1 < global_t1min)) { 27507 ast_log(LOG_WARNING, "'%s' is not a valid T1 time at line %d. Using default.\n", v->value, v->lineno); 27508 peer->timer_t1 = global_t1min; 27509 } 27510 timert1_set = 1; 27511 } else if (!strcasecmp(v->name, "timerb")) { 27512 if ((sscanf(v->value, "%30d", &peer->timer_b) != 1) || (peer->timer_b < 200)) { 27513 ast_log(LOG_WARNING, "'%s' is not a valid Timer B time at line %d. Using default.\n", v->value, v->lineno); 27514 peer->timer_b = global_timer_b; 27515 } 27516 timerb_set = 1; 27517 } else if (!strcasecmp(v->name, "setvar")) { 27518 peer->chanvars = add_var(v->value, peer->chanvars); 27519 } else if (!strcasecmp(v->name, "header")) { 27520 char tmp[4096]; 27521 snprintf(tmp, sizeof(tmp), "__SIPADDHEADERpre%2d=%s", ++headercount, v->value); 27522 peer->chanvars = add_var(tmp, peer->chanvars); 27523 } else if (!strcasecmp(v->name, "qualifyfreq")) { 27524 int i; 27525 if (sscanf(v->value, "%30d", &i) == 1) { 27526 peer->qualifyfreq = i * 1000; 27527 } else { 27528 ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config); 27529 peer->qualifyfreq = global_qualifyfreq; 27530 } 27531 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 27532 peer->maxcallbitrate = atoi(v->value); 27533 if (peer->maxcallbitrate < 0) { 27534 peer->maxcallbitrate = default_maxcallbitrate; 27535 } 27536 } else if (!strcasecmp(v->name, "session-timers")) { 27537 int i = (int) str2stmode(v->value); 27538 if (i < 0) { 27539 ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config); 27540 peer->stimer.st_mode_oper = global_st_mode; 27541 } else { 27542 peer->stimer.st_mode_oper = i; 27543 } 27544 } else if (!strcasecmp(v->name, "session-expires")) { 27545 if (sscanf(v->value, "%30d", &peer->stimer.st_max_se) != 1) { 27546 ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config); 27547 peer->stimer.st_max_se = global_max_se; 27548 } 27549 } else if (!strcasecmp(v->name, "session-minse")) { 27550 if (sscanf(v->value, "%30d", &peer->stimer.st_min_se) != 1) { 27551 ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config); 27552 peer->stimer.st_min_se = global_min_se; 27553 } 27554 if (peer->stimer.st_min_se < 90) { 27555 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); 27556 peer->stimer.st_min_se = global_min_se; 27557 } 27558 } else if (!strcasecmp(v->name, "session-refresher")) { 27559 int i = (int) str2strefresher(v->value); 27560 if (i < 0) { 27561 ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config); 27562 peer->stimer.st_ref = global_st_refresher; 27563 } else { 27564 peer->stimer.st_ref = i; 27565 } 27566 } else if (!strcasecmp(v->name, "disallowed_methods")) { 27567 char *disallow = ast_strdupa(v->value); 27568 mark_parsed_methods(&peer->disallowed_methods, disallow); 27569 } else if (!strcasecmp(v->name, "unsolicited_mailbox")) { 27570 ast_string_field_set(peer, unsolicited_mailbox, v->value); 27571 } else if (!strcasecmp(v->name, "use_q850_reason")) { 27572 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON); 27573 } else if (!strcasecmp(v->name, "encryption")) { 27574 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_USE_SRTP); 27575 } else if (!strcasecmp(v->name, "snom_aoc_enabled")) { 27576 ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC); 27577 } 27578 } 27579 27580 /* These apply to devstate lookups */ 27581 if (realtime && !strcasecmp(v->name, "lastms")) { 27582 sscanf(v->value, "%30d", &peer->lastms); 27583 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 27584 ast_sockaddr_parse(&peer->addr, v->value, PARSE_PORT_FORBID); 27585 } else if (realtime && !strcasecmp(v->name, "fullcontact")) { 27586 if (alt_fullcontact && !alt) { 27587 /* Reset, because the alternate also has a fullcontact and we 27588 * do NOT want the field value to be doubled. It might be 27589 * tempting to skip this, but the first table might not have 27590 * fullcontact and since we're here, we know that the alternate 27591 * absolutely does. */ 27592 alt_fullcontact = 0; 27593 ast_str_reset(fullcontact); 27594 } 27595 /* Reconstruct field, because realtime separates our value at the ';' */ 27596 if (fullcontact->used > 0) { 27597 ast_str_append(&fullcontact, 0, ";%s", v->value); 27598 } else { 27599 ast_str_set(&fullcontact, 0, "%s", v->value); 27600 } 27601 } else if (!strcasecmp(v->name, "qualify")) { 27602 if (!strcasecmp(v->value, "no")) { 27603 peer->maxms = 0; 27604 } else if (!strcasecmp(v->value, "yes")) { 27605 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 27606 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 27607 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); 27608 peer->maxms = 0; 27609 } 27610 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) { 27611 /* This would otherwise cause a network storm, where the 27612 * qualify response refreshes the peer from the database, 27613 * which in turn causes another qualify to be sent, ad 27614 * infinitum. */ 27615 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); 27616 peer->maxms = 0; 27617 } 27618 } else if (!strcasecmp(v->name, "callcounter")) { 27619 peer->call_limit = ast_true(v->value) ? INT_MAX : 0; 27620 } else if (!strcasecmp(v->name, "call-limit")) { 27621 peer->call_limit = atoi(v->value); 27622 if (peer->call_limit < 0) { 27623 peer->call_limit = 0; 27624 } 27625 } else if (!strcasecmp(v->name, "busylevel")) { 27626 peer->busy_level = atoi(v->value); 27627 if (peer->busy_level < 0) { 27628 peer->busy_level = 0; 27629 } 27630 } else if (ast_cc_is_config_param(v->name)) { 27631 ast_cc_set_param(peer->cc_params, v->name, v->value); 27632 } 27633 } 27634 27635 if (!devstate_only) { 27636 struct sip_mailbox *mailbox; 27637 AST_LIST_TRAVERSE_SAFE_BEGIN(&peer->mailboxes, mailbox, entry) { 27638 if (mailbox->delme) { 27639 AST_LIST_REMOVE_CURRENT(entry); 27640 destroy_mailbox(mailbox); 27641 } 27642 } 27643 AST_LIST_TRAVERSE_SAFE_END; 27644 } 27645 27646 if (!can_parse_xml && (ast_get_cc_agent_policy(peer->cc_params) == AST_CC_AGENT_NATIVE)) { 27647 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); 27648 ast_set_cc_agent_policy(peer->cc_params, AST_CC_AGENT_NEVER); 27649 } 27650 27651 /* Note that Timer B is dependent upon T1 and MUST NOT be lower 27652 * than T1 * 64, according to RFC 3261, Section 17.1.1.2 */ 27653 if (peer->timer_b < peer->timer_t1 * 64) { 27654 if (timerb_set && timert1_set) { 27655 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); 27656 } else if (timerb_set) { 27657 if ((peer->timer_t1 = peer->timer_b / 64) < global_t1min) { 27658 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); 27659 peer->timer_t1 = global_t1min; 27660 peer->timer_b = peer->timer_t1 * 64; 27661 } 27662 peer->timer_t1 = peer->timer_b / 64; 27663 } else { 27664 peer->timer_b = peer->timer_t1 * 64; 27665 } 27666 } 27667 27668 if (!peer->default_outbound_transport) { 27669 /* Set default set of transports */ 27670 peer->transports = default_transports; 27671 /* Set default primary transport */ 27672 peer->default_outbound_transport = default_primary_transport; 27673 } 27674 27675 /* The default transport type set during build_peer should only replace the socket.type when... 27676 * 1. Registration is not present and the socket.type and default transport types are different. 27677 * 2. The socket.type is not an acceptable transport type after rebuilding peer. 27678 * 3. The socket.type is not set yet. */ 27679 if (((peer->socket.type != peer->default_outbound_transport) && (peer->expire == -1)) || 27680 !(peer->socket.type & peer->transports) || !(peer->socket.type)) { 27681 27682 set_socket_transport(&peer->socket, peer->default_outbound_transport); 27683 } 27684 27685 if (ast_str_strlen(fullcontact)) { 27686 ast_string_field_set(peer, fullcontact, ast_str_buffer(fullcontact)); 27687 peer->rt_fromcontact = TRUE; 27688 /* We have a hostname in the fullcontact, but if we don't have an 27689 * address listed on the entry (or if it's 'dynamic'), then we need to 27690 * parse the entry to obtain the IP address, so a dynamic host can be 27691 * contacted immediately after reload (as opposed to waiting for it to 27692 * register once again). But if we have an address for this peer and NAT was 27693 * specified, use that address instead. */ 27694 /* XXX May need to revisit the final argument; does the realtime DB store whether 27695 * the original contact was over TLS or not? XXX */ 27696 if (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) || ast_sockaddr_isnull(&peer->addr)) { 27697 __set_address_from_contact(fullcontact->str, &peer->addr, 0); 27698 } 27699 } 27700 27701 if (srvlookup && peer->dnsmgr == NULL) { 27702 char transport[MAXHOSTNAMELEN]; 27703 char _srvlookup[MAXHOSTNAMELEN]; 27704 char *params; 27705 27706 ast_copy_string(_srvlookup, srvlookup, sizeof(_srvlookup)); 27707 if ((params = strchr(_srvlookup, ';'))) { 27708 *params++ = '\0'; 27709 } 27710 27711 snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(peer->socket.type), get_srv_protocol(peer->socket.type)); 27712 27713 peer->addr.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */ 27714 if (ast_dnsmgr_lookup_cb(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup && !peer->portinuri ? transport : NULL, 27715 on_dns_update_peer, ref_peer(peer, "Store peer on dnsmgr"))) { 27716 ast_log(LOG_ERROR, "srvlookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name); 27717 unref_peer(peer, "dnsmgr lookup failed, getting rid of peer dnsmgr ref"); 27718 unref_peer(peer, "getting rid of a peer pointer"); 27719 return NULL; 27720 } 27721 if (!peer->dnsmgr) { 27722 /* dnsmgr refresh disabeld, release reference */ 27723 unref_peer(peer, "dnsmgr disabled, unref peer"); 27724 } 27725 27726 ast_string_field_set(peer, tohost, srvlookup); 27727 27728 if (global_dynamic_exclude_static) { 27729 int ha_error = 0; 27730 sip_cfg.contact_ha = ast_append_ha("deny", ast_sockaddr_stringify_addr(&peer->addr), 27731 sip_cfg.contact_ha, &ha_error); 27732 if (ha_error) { 27733 ast_log(LOG_ERROR, "Bad or unresolved host/IP entry in configuration for peer %s, cannot add to contact ACL\n", peer->name); 27734 } 27735 } 27736 } else if (peer->dnsmgr && !peer->host_dynamic) { 27737 /* force a refresh here on reload if dnsmgr already exists and host is set. */ 27738 ast_dnsmgr_refresh(peer->dnsmgr); 27739 } 27740 27741 if (port && !realtime && peer->host_dynamic) { 27742 ast_sockaddr_set_port(&peer->defaddr, port); 27743 } else if (port) { 27744 ast_sockaddr_set_port(&peer->addr, port); 27745 } 27746 27747 if (ast_sockaddr_port(&peer->addr) == 0) { 27748 ast_sockaddr_set_port(&peer->addr, 27749 (peer->socket.type & SIP_TRANSPORT_TLS) ? 27750 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 27751 } 27752 if (ast_sockaddr_port(&peer->defaddr) == 0) { 27753 ast_sockaddr_set_port(&peer->defaddr, 27754 (peer->socket.type & SIP_TRANSPORT_TLS) ? 27755 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 27756 } 27757 if (!peer->socket.port) { 27758 peer->socket.port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT)); 27759 } 27760 27761 if (!sip_cfg.ignore_regexpire && peer->host_dynamic && realtime) { 27762 time_t nowtime = time(NULL); 27763 27764 if ((nowtime - regseconds) > 0) { 27765 destroy_association(peer); 27766 memset(&peer->addr, 0, sizeof(peer->addr)); 27767 peer->lastms = -1; 27768 ast_debug(1, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 27769 } 27770 } 27771 27772 /* Startup regular pokes */ 27773 if (!devstate_only && realtime && peer->lastms > 0) { 27774 ref_peer(peer, "schedule qualify"); 27775 sip_poke_peer(peer, 0); 27776 } 27777 27778 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 27779 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 27780 ast_copy_flags(&peer->flags[2], &peerflags[2], mask[2].flags); 27781 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 27782 sip_cfg.allowsubscribe = TRUE; /* No global ban any more */ 27783 } 27784 /* If read-only RT backend, then refresh from local DB cache */ 27785 if (peer->host_dynamic && (!peer->is_realtime || !sip_cfg.peer_rtupdate)) { 27786 reg_source_db(peer); 27787 } 27788 27789 /* If they didn't request that MWI is sent *only* on subscribe, go ahead and 27790 * subscribe to it now. */ 27791 if (!devstate_only && !ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 27792 !AST_LIST_EMPTY(&peer->mailboxes)) { 27793 add_peer_mwi_subs(peer); 27794 /* Send MWI from the event cache only. This is so we can send initial 27795 * MWI if app_voicemail got loaded before chan_sip. If it is the other 27796 * way, then we will get events when app_voicemail gets loaded. */ 27797 sip_send_mwi_to_peer(peer, 1); 27798 } 27799 27800 peer->the_mark = 0; 27801 27802 ast_free_ha(oldha); 27803 ast_free_ha(olddirectmediaha); 27804 if (!ast_strlen_zero(callback)) { /* build string from peer info */ 27805 char *reg_string; 27806 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) { 27807 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 27808 } else if (reg_string) { 27809 sip_register(reg_string, 0); /* XXX TODO: count in registry_count */ 27810 ast_free(reg_string); 27811 } 27812 } 27813 return peer; 27814 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 19189 of file chan_sip.c.
References ao2_lock, ao2_t_ref, ao2_unlock, append_history, ast_copy_string(), ast_debug, ast_md5_hash(), ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_sockaddr_stringify_host_remote(), ast_strlen_zero(), authl, authl_lock, find_realm_authentication(), secret, and sip_methods.
Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().
19190 { 19191 char a1[256]; 19192 char a2[256]; 19193 char a1_hash[256]; 19194 char a2_hash[256]; 19195 char resp[256]; 19196 char resp_hash[256]; 19197 char uri[256]; 19198 char opaque[256] = ""; 19199 char cnonce[80]; 19200 const char *username; 19201 const char *secret; 19202 const char *md5secret; 19203 struct sip_auth *auth; /* Realm authentication credential */ 19204 struct sip_auth_container *credentials; 19205 19206 if (!ast_strlen_zero(p->domain)) 19207 snprintf(uri, sizeof(uri), "%s:%s", p->socket.type == SIP_TRANSPORT_TLS ? "sips" : "sip", p->domain); 19208 else if (!ast_strlen_zero(p->uri)) 19209 ast_copy_string(uri, p->uri, sizeof(uri)); 19210 else 19211 snprintf(uri, sizeof(uri), "%s:%s@%s", p->socket.type == SIP_TRANSPORT_TLS ? "sips" : "sip", p->username, ast_sockaddr_stringify_host_remote(&p->sa)); 19212 19213 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 19214 19215 /* Check if we have peer credentials */ 19216 ao2_lock(p); 19217 credentials = p->peerauth; 19218 if (credentials) { 19219 ao2_t_ref(credentials, +1, "Ref peer auth for digest"); 19220 } 19221 ao2_unlock(p); 19222 auth = find_realm_authentication(credentials, p->realm); 19223 if (!auth) { 19224 /* If not, check global credentials */ 19225 if (credentials) { 19226 ao2_t_ref(credentials, -1, "Unref peer auth for digest"); 19227 } 19228 ast_mutex_lock(&authl_lock); 19229 credentials = authl; 19230 if (credentials) { 19231 ao2_t_ref(credentials, +1, "Ref global auth for digest"); 19232 } 19233 ast_mutex_unlock(&authl_lock); 19234 auth = find_realm_authentication(credentials, p->realm); 19235 } 19236 19237 if (auth) { 19238 ast_debug(3, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username); 19239 username = auth->username; 19240 secret = auth->secret; 19241 md5secret = auth->md5secret; 19242 if (sipdebug) 19243 ast_debug(1, "Using realm %s authentication for call %s\n", p->realm, p->callid); 19244 } else { 19245 /* No authentication, use peer or register= config */ 19246 username = p->authname; 19247 secret = p->relatedpeer 19248 && !ast_strlen_zero(p->relatedpeer->remotesecret) 19249 ? p->relatedpeer->remotesecret : p->peersecret; 19250 md5secret = p->peermd5secret; 19251 } 19252 if (ast_strlen_zero(username)) { 19253 /* We have no authentication */ 19254 if (credentials) { 19255 ao2_t_ref(credentials, -1, "Unref auth for digest"); 19256 } 19257 return -1; 19258 } 19259 19260 /* Calculate SIP digest response */ 19261 snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret); 19262 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[method].text, uri); 19263 if (!ast_strlen_zero(md5secret)) 19264 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 19265 else 19266 ast_md5_hash(a1_hash, a1); 19267 ast_md5_hash(a2_hash, a2); 19268 19269 p->noncecount++; 19270 if (!ast_strlen_zero(p->qop)) 19271 snprintf(resp, sizeof(resp), "%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 19272 else 19273 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, p->nonce, a2_hash); 19274 ast_md5_hash(resp_hash, resp); 19275 19276 /* only include the opaque string if it's set */ 19277 if (!ast_strlen_zero(p->opaque)) { 19278 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 19279 } 19280 19281 /* XXX We hard code our qop to "auth" for now. XXX */ 19282 if (!ast_strlen_zero(p->qop)) 19283 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); 19284 else 19285 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); 19286 19287 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 19288 19289 if (credentials) { 19290 ao2_t_ref(credentials, -1, "Unref auth for digest"); 19291 } 19292 return 0; 19293 }
static void build_route | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | backwards, | |||
int | resp | |||
) | [static] |
Build route list from Record-Route header.
resp | the SIP response code or 0 for a request |
Definition at line 14163 of file chan_sip.c.
References __get_header(), ast_copy_string(), ast_debug, ast_malloc, ast_strdupa, ast_strlen_zero(), free_old_route(), get_header(), get_in_brackets(), len(), list_route(), sip_debug_test_pvt(), and strsep().
Referenced by build_user_routes(), handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
14164 { 14165 struct sip_route *thishop, *head, *tail; 14166 int start = 0; 14167 int len; 14168 const char *rr, *c; 14169 14170 /* Once a persistent route is set, don't fool with it */ 14171 if (p->route && p->route_persistent) { 14172 ast_debug(1, "build_route: Retaining previous route: <%s>\n", p->route->hop); 14173 return; 14174 } 14175 14176 if (p->route) { 14177 free_old_route(p->route); 14178 p->route = NULL; 14179 } 14180 14181 /* We only want to create the route set the first time this is called except 14182 it is called from a provisional response.*/ 14183 if ((resp < 100) || (resp > 199)) { 14184 p->route_persistent = 1; 14185 } 14186 14187 /* Build a tailq, then assign it to p->route when done. 14188 * If backwards, we add entries from the head so they end up 14189 * in reverse order. However, we do need to maintain a correct 14190 * tail pointer because the contact is always at the end. 14191 */ 14192 head = NULL; 14193 tail = head; 14194 /* 1st we pass through all the hops in any Record-Route headers */ 14195 for (;;) { 14196 /* Each Record-Route header */ 14197 char rr_copy[256]; 14198 char *rr_copy_ptr; 14199 char *rr_iter; 14200 rr = __get_header(req, "Record-Route", &start); 14201 if (*rr == '\0') { 14202 break; 14203 } 14204 ast_copy_string(rr_copy, rr, sizeof(rr_copy)); 14205 rr_copy_ptr = rr_copy; 14206 while ((rr_iter = strsep(&rr_copy_ptr, ","))) { /* Each route entry */ 14207 char *uri = get_in_brackets(rr_iter); 14208 len = strlen(uri) + 1; 14209 /* Make a struct route */ 14210 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 14211 /* ast_calloc is not needed because all fields are initialized in this block */ 14212 ast_copy_string(thishop->hop, uri, len); 14213 ast_debug(2, "build_route: Record-Route hop: <%s>\n", thishop->hop); 14214 /* Link in */ 14215 if (backwards) { 14216 /* Link in at head so they end up in reverse order */ 14217 thishop->next = head; 14218 head = thishop; 14219 /* If this was the first then it'll be the tail */ 14220 if (!tail) { 14221 tail = thishop; 14222 } 14223 } else { 14224 thishop->next = NULL; 14225 /* Link in at the end */ 14226 if (tail) { 14227 tail->next = thishop; 14228 } else { 14229 head = thishop; 14230 } 14231 tail = thishop; 14232 } 14233 } 14234 } 14235 } 14236 14237 /* Only append the contact if we are dealing with a strict router */ 14238 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop, ";lr") == NULL) ) { 14239 /* 2nd append the Contact: if there is one */ 14240 /* Can be multiple Contact headers, comma separated values - we just take the first */ 14241 char *contact = ast_strdupa(get_header(req, "Contact")); 14242 if (!ast_strlen_zero(contact)) { 14243 ast_debug(2, "build_route: Contact hop: %s\n", contact); 14244 /* Look for <: delimited address */ 14245 c = get_in_brackets(contact); 14246 len = strlen(c) + 1; 14247 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 14248 /* ast_calloc is not needed because all fields are initialized in this block */ 14249 ast_copy_string(thishop->hop, c, len); 14250 thishop->next = NULL; 14251 /* Goes at the end */ 14252 if (tail) { 14253 tail->next = thishop; 14254 } else { 14255 head = thishop; 14256 } 14257 } 14258 } 14259 } 14260 14261 /* Store as new route */ 14262 p->route = head; 14263 14264 /* For debugging dump what we ended up with */ 14265 if (sip_debug_test_pvt(p)) { 14266 list_route(p->route); 14267 } 14268 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 3377 of file chan_sip.c.
References ast_sockaddr_stringify_remote(), ast_test_flag, and get_transport_pvt().
Referenced by __sip_subscribe_mwi_do(), reqprep(), sip_alloc(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), transmit_register(), and transmit_response_using_temp().
03378 { 03379 /* Work around buggy UNIDEN UIP200 firmware */ 03380 const char *rport = (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)) ? ";rport" : ""; 03381 03382 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 03383 snprintf(p->via, sizeof(p->via), "SIP/2.0/%s %s;branch=z9hG4bK%08x%s", 03384 get_transport_pvt(p), 03385 ast_sockaddr_stringify_remote(&p->ourip), 03386 (int) p->branch, rport); 03387 }
static int cb_extensionstate | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 14541 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_set_flag, ast_test_flag, ast_verb, FALSE, NONE, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), and transmit_state_notify().
Referenced by dialog_unlink_all(), handle_request_subscribe(), and handle_response_notify().
14542 { 14543 struct sip_pvt *p = data; 14544 14545 sip_pvt_lock(p); 14546 14547 switch(state) { 14548 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 14549 case AST_EXTENSION_REMOVED: /* Extension is gone */ 14550 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 14551 ast_verb(2, "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username); 14552 p->subscribed = NONE; 14553 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 14554 break; 14555 default: /* Tell user */ 14556 p->laststate = state; 14557 break; 14558 } 14559 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 14560 if (!p->pendinginvite) { 14561 transmit_state_notify(p, state, 1, FALSE); 14562 } else { 14563 /* We already have a NOTIFY sent that is not answered. Queue the state up. 14564 if many state changes happen meanwhile, we will only send a notification of the last one */ 14565 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 14566 } 14567 } 14568 ast_verb(2, "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username, 14569 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 14570 14571 sip_pvt_unlock(p); 14572 14573 return 0; 14574 }
static void cb_extensionstate_destroy | ( | int | id, | |
void * | data | |||
) | [static] |
Definition at line 14531 of file chan_sip.c.
Referenced by handle_request_subscribe().
14532 { 14533 struct sip_pvt *p = data; 14534 14535 dialog_unref(p, "the extensionstate containing this dialog ptr was destroyed"); 14536 }
static void cc_epa_destructor | ( | void * | data | ) | [static] |
Definition at line 891 of file chan_sip.c.
References ast_free.
00892 { 00893 struct sip_epa_entry *epa_entry = data; 00894 struct cc_epa_entry *cc_entry = epa_entry->instance_data; 00895 ast_free(cc_entry); 00896 }
static 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 24101 of file chan_sip.c.
References ao2_ref, ast_cc_agent_caller_available(), ast_cc_agent_caller_busy(), ast_log(), ast_strlen_zero(), ast_xml_close(), ast_xml_find_element(), ast_xml_free_text(), ast_xml_get_root(), ast_xml_get_text(), ast_xml_node_get_children(), ast_cc_agent::core_id, ast_cc_agent::device_name, FALSE, find_sip_cc_agent_by_notify_uri(), find_sip_cc_agent_by_subscribe_uri(), LOG_NOTICE, LOG_WARNING, ast_cc_agent::private_data, sip_pidf_validate(), transmit_response(), and TRUE.
24102 { 24103 const char *uri = REQ_OFFSET_TO_STR(req, rlPart2); 24104 struct ast_cc_agent *agent; 24105 struct sip_cc_agent_pvt *agent_pvt; 24106 struct ast_xml_doc *pidf_doc = NULL; 24107 const char *basic_status = NULL; 24108 struct ast_xml_node *presence_node; 24109 struct ast_xml_node *presence_children; 24110 struct ast_xml_node *tuple_node; 24111 struct ast_xml_node *tuple_children; 24112 struct ast_xml_node *status_node; 24113 struct ast_xml_node *status_children; 24114 struct ast_xml_node *basic_node; 24115 int res = 0; 24116 24117 if (!((agent = find_sip_cc_agent_by_notify_uri(uri)) || (agent = find_sip_cc_agent_by_subscribe_uri(uri)))) { 24118 ast_log(LOG_WARNING, "Could not find agent using uri '%s'\n", uri); 24119 transmit_response(pvt, "412 Conditional Request Failed", req); 24120 return -1; 24121 } 24122 24123 agent_pvt = agent->private_data; 24124 24125 if (sip_pidf_validate(req, &pidf_doc) == FALSE) { 24126 res = -1; 24127 goto cc_publish_cleanup; 24128 } 24129 24130 /* It's important to note that the PIDF validation routine has no knowledge 24131 * of what we specifically want in this instance. A valid PIDF document could 24132 * have no tuples, or it could have tuples whose status element has no basic 24133 * element contained within. While not violating the PIDF spec, these are 24134 * insufficient for our needs in this situation 24135 */ 24136 presence_node = ast_xml_get_root(pidf_doc); 24137 if (!(presence_children = ast_xml_node_get_children(presence_node))) { 24138 ast_log(LOG_WARNING, "No tuples within presence element.\n"); 24139 res = -1; 24140 goto cc_publish_cleanup; 24141 } 24142 24143 if (!(tuple_node = ast_xml_find_element(presence_children, "tuple", NULL, NULL))) { 24144 ast_log(LOG_NOTICE, "Couldn't find tuple node?\n"); 24145 res = -1; 24146 goto cc_publish_cleanup; 24147 } 24148 24149 /* We already made sure that the tuple has a status node when we validated the PIDF 24150 * document earlier. So there's no need to enclose this operation in an if statement. 24151 */ 24152 tuple_children = ast_xml_node_get_children(tuple_node); 24153 status_node = ast_xml_find_element(tuple_children, "status", NULL, NULL); 24154 24155 if (!(status_children = ast_xml_node_get_children(status_node))) { 24156 ast_log(LOG_WARNING, "No basic elements within status element.\n"); 24157 res = -1; 24158 goto cc_publish_cleanup; 24159 } 24160 24161 if (!(basic_node = ast_xml_find_element(status_children, "basic", NULL, NULL))) { 24162 ast_log(LOG_WARNING, "Couldn't find basic node?\n"); 24163 res = -1; 24164 goto cc_publish_cleanup; 24165 } 24166 24167 basic_status = ast_xml_get_text(basic_node); 24168 24169 if (ast_strlen_zero(basic_status)) { 24170 ast_log(LOG_NOTICE, "NOthing in basic node?\n"); 24171 res = -1; 24172 goto cc_publish_cleanup; 24173 } 24174 24175 if (!strcmp(basic_status, "open")) { 24176 agent_pvt->is_available = TRUE; 24177 ast_cc_agent_caller_available(agent->core_id, "Received PUBLISH stating SIP caller %s is available", 24178 agent->device_name); 24179 } else if (!strcmp(basic_status, "closed")) { 24180 agent_pvt->is_available = FALSE; 24181 ast_cc_agent_caller_busy(agent->core_id, "Received PUBLISH stating SIP caller %s is busy", 24182 agent->device_name); 24183 } else { 24184 ast_log(LOG_NOTICE, "Invalid content in basic element: %s\n", basic_status); 24185 } 24186 24187 cc_publish_cleanup: 24188 if (basic_status) { 24189 ast_xml_free_text(basic_status); 24190 } 24191 if (pidf_doc) { 24192 ast_xml_close(pidf_doc); 24193 } 24194 ao2_ref(agent, -1); 24195 if (res) { 24196 transmit_response(pvt, "400 Bad Request", req); 24197 } 24198 return res; 24199 }
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 19804 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().
19805 { 19806 struct cc_epa_entry *cc_entry = epa_entry->instance_data; 19807 struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0, 19808 find_sip_monitor_instance_by_suspension_entry, epa_entry); 19809 const char *min_expires; 19810 19811 if (!monitor_instance) { 19812 ast_log(LOG_WARNING, "Can't find monitor_instance corresponding to epa_entry %p.\n", epa_entry); 19813 return; 19814 } 19815 19816 if (resp != 423) { 19817 ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name, 19818 "Received error response to our PUBLISH"); 19819 ao2_ref(monitor_instance, -1); 19820 return; 19821 } 19822 19823 /* Allrighty, the other end doesn't like our Expires value. They think it's 19824 * too small, so let's see if they've provided a more sensible value. If they 19825 * haven't, then we'll just double our Expires value and see if they like that 19826 * instead. 19827 * 19828 * XXX Ideally this logic could be placed into its own function so that SUBSCRIBE, 19829 * PUBLISH, and REGISTER could all benefit from the same shared code. 19830 */ 19831 min_expires = get_header(req, "Min-Expires"); 19832 if (ast_strlen_zero(min_expires)) { 19833 pvt->expiry *= 2; 19834 if (pvt->expiry < 0) { 19835 /* You dork! You overflowed! */ 19836 ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name, 19837 "PUBLISH expiry overflowed"); 19838 ao2_ref(monitor_instance, -1); 19839 return; 19840 } 19841 } else if (sscanf(min_expires, "%d", &pvt->expiry) != 1) { 19842 ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name, 19843 "Min-Expires has non-numeric value"); 19844 ao2_ref(monitor_instance, -1); 19845 return; 19846 } 19847 /* At this point, we have most certainly changed pvt->expiry, so try transmitting 19848 * again 19849 */ 19850 transmit_invite(pvt, SIP_PUBLISH, FALSE, 0, NULL); 19851 ao2_ref(monitor_instance, -1); 19852 }
static void change_callid_pvt | ( | struct sip_pvt * | pvt, | |
const char * | callid | |||
) | [static] |
Definition at line 7581 of file chan_sip.c.
References ao2_lock, ao2_t_link, ao2_unlock, ast_string_field_set, build_callid_pvt(), CONTAINER_UNLINK, and dialogs.
Referenced by __sip_subscribe_mwi_do(), create_addr_from_peer(), sip_poke_peer(), sip_request_call(), and sip_send_mwi_to_peer().
07582 { 07583 int in_dialog_container; 07584 07585 ao2_lock(dialogs); 07586 in_dialog_container = CONTAINER_UNLINK(dialogs, pvt, 07587 "About to change the callid -- remove the old name"); 07588 if (callid) { 07589 ast_string_field_set(pvt, callid, callid); 07590 } else { 07591 build_callid_pvt(pvt); 07592 } 07593 if (in_dialog_container) { 07594 ao2_t_link(dialogs, pvt, "New dialog callid -- inserted back into table"); 07595 } 07596 ao2_unlock(dialogs); 07597 }
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 8656 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().
08657 { 08658 if (sip_cfg.notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 08659 sip_peer_hold(dialog, holdstate); 08660 if (sip_cfg.callevents) 08661 manager_event(EVENT_FLAG_CALL, "Hold", 08662 "Status: %s\r\n" 08663 "Channel: %s\r\n" 08664 "Uniqueid: %s\r\n", 08665 holdstate ? "On" : "Off", 08666 dialog->owner->name, 08667 dialog->owner->uniqueid); 08668 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data->str); 08669 if (!holdstate) { /* Put off remote hold */ 08670 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 08671 return; 08672 } 08673 /* No address for RTP, we're on hold */ 08674 08675 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 08676 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 08677 else if (sendonly == 2) /* Inactive stream */ 08678 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 08679 else 08680 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 08681 return; 08682 }
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 19541 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_name_and_number(), 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().
19544 { 19545 char *redirecting_from_name = NULL; 19546 char *redirecting_from_number = NULL; 19547 char *redirecting_to_name = NULL; 19548 char *redirecting_to_number = NULL; 19549 int reason = AST_REDIRECTING_REASON_UNCONDITIONAL; 19550 int is_response = req->method == SIP_RESPONSE; 19551 int res = 0; 19552 19553 res = get_rdnis(p, req, &redirecting_from_name, &redirecting_from_number, &reason); 19554 if (res == -1) { 19555 if (is_response) { 19556 get_name_and_number(get_header(req, "TO"), &redirecting_from_name, &redirecting_from_number); 19557 } else { 19558 return; 19559 } 19560 } 19561 19562 /* At this point, all redirecting "from" info should be filled in appropriately 19563 * on to the "to" info 19564 */ 19565 19566 if (is_response) { 19567 parse_moved_contact(p, req, &redirecting_to_name, &redirecting_to_number, set_call_forward); 19568 } else { 19569 get_name_and_number(get_header(req, "TO"), &redirecting_to_name, &redirecting_to_number); 19570 } 19571 19572 if (!ast_strlen_zero(redirecting_from_number)) { 19573 ast_debug(3, "Got redirecting from number %s\n", redirecting_from_number); 19574 update_redirecting->from.number = 1; 19575 redirecting->from.number.valid = 1; 19576 ast_free(redirecting->from.number.str); 19577 redirecting->from.number.str = redirecting_from_number; 19578 } 19579 if (!ast_strlen_zero(redirecting_from_name)) { 19580 ast_debug(3, "Got redirecting from name %s\n", redirecting_from_name); 19581 update_redirecting->from.name = 1; 19582 redirecting->from.name.valid = 1; 19583 ast_free(redirecting->from.name.str); 19584 redirecting->from.name.str = redirecting_from_name; 19585 } 19586 if (!ast_strlen_zero(p->cid_tag)) { 19587 ast_free(redirecting->from.tag); 19588 redirecting->from.tag = ast_strdup(p->cid_tag); 19589 ast_free(redirecting->to.tag); 19590 redirecting->to.tag = ast_strdup(p->cid_tag); 19591 } 19592 if (!ast_strlen_zero(redirecting_to_number)) { 19593 ast_debug(3, "Got redirecting to number %s\n", redirecting_to_number); 19594 update_redirecting->to.number = 1; 19595 redirecting->to.number.valid = 1; 19596 ast_free(redirecting->to.number.str); 19597 redirecting->to.number.str = redirecting_to_number; 19598 } 19599 if (!ast_strlen_zero(redirecting_to_name)) { 19600 ast_debug(3, "Got redirecting to name %s\n", redirecting_from_number); 19601 update_redirecting->to.name = 1; 19602 redirecting->to.name.valid = 1; 19603 ast_free(redirecting->to.name.str); 19604 redirecting->to.name.str = redirecting_to_name; 19605 } 19606 redirecting->reason = reason; 19607 }
static void change_t38_state | ( | struct sip_pvt * | p, | |
int | state | |||
) | [static] |
Change the T38 state on a SIP dialog.
Definition at line 5110 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().
05111 { 05112 int old = p->t38.state; 05113 struct ast_channel *chan = p->owner; 05114 struct ast_control_t38_parameters parameters = { .request_response = 0 }; 05115 05116 /* Don't bother changing if we are already in the state wanted */ 05117 if (old == state) 05118 return; 05119 05120 p->t38.state = state; 05121 ast_debug(2, "T38 state changed to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 05122 05123 /* If no channel was provided we can't send off a control frame */ 05124 if (!chan) 05125 return; 05126 05127 /* Given the state requested and old state determine what control frame we want to queue up */ 05128 switch (state) { 05129 case T38_PEER_REINVITE: 05130 parameters = p->t38.their_parms; 05131 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); 05132 parameters.request_response = AST_T38_REQUEST_NEGOTIATE; 05133 ast_udptl_set_tag(p->udptl, "%s", chan->name); 05134 break; 05135 case T38_ENABLED: 05136 parameters = p->t38.their_parms; 05137 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); 05138 parameters.request_response = AST_T38_NEGOTIATED; 05139 ast_udptl_set_tag(p->udptl, "%s", chan->name); 05140 break; 05141 case T38_DISABLED: 05142 if (old == T38_ENABLED) { 05143 parameters.request_response = AST_T38_TERMINATED; 05144 } else if (old == T38_LOCAL_REINVITE) { 05145 parameters.request_response = AST_T38_REFUSED; 05146 } 05147 break; 05148 case T38_LOCAL_REINVITE: 05149 /* wait until we get a peer response before responding to local reinvite */ 05150 break; 05151 } 05152 05153 /* Woot we got a message, create a control frame and send it on! */ 05154 if (parameters.request_response) 05155 ast_queue_control_data(chan, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)); 05156 }
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 14292 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().
14295 { 14296 const char *response; 14297 char *reqheader, *respheader; 14298 const char *authtoken; 14299 char a1_hash[256]; 14300 char resp_hash[256]=""; 14301 char *c; 14302 int wrongnonce = FALSE; 14303 int good_response; 14304 const char *usednonce = p->randdata; 14305 struct ast_str *buf; 14306 int res; 14307 14308 /* table of recognised keywords, and their value in the digest */ 14309 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 14310 struct x { 14311 const char *key; 14312 const char *s; 14313 } *i, keys[] = { 14314 [K_RESP] = { "response=", "" }, 14315 [K_URI] = { "uri=", "" }, 14316 [K_USER] = { "username=", "" }, 14317 [K_NONCE] = { "nonce=", "" }, 14318 [K_LAST] = { NULL, NULL} 14319 }; 14320 14321 /* Always OK if no secret */ 14322 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 14323 return AUTH_SUCCESSFUL; 14324 14325 /* Always auth with WWW-auth since we're NOT a proxy */ 14326 /* Using proxy-auth in a B2BUA may block proxy authorization in the same transaction */ 14327 response = "401 Unauthorized"; 14328 14329 /* 14330 * Note the apparent swap of arguments below, compared to other 14331 * usages of auth_headers(). 14332 */ 14333 auth_headers(WWW_AUTH, &respheader, &reqheader); 14334 14335 authtoken = get_header(req, reqheader); 14336 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 14337 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 14338 information */ 14339 if (!reliable) { 14340 /* Resend message if this was NOT a reliable delivery. Otherwise the 14341 retransmission should get it */ 14342 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 14343 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 14344 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14345 } 14346 return AUTH_CHALLENGE_SENT; 14347 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 14348 /* We have no auth, so issue challenge and request authentication */ 14349 set_nonce_randdata(p, 1); /* Create nonce for challenge */ 14350 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 14351 /* Schedule auto destroy in 32 seconds */ 14352 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14353 return AUTH_CHALLENGE_SENT; 14354 } 14355 14356 /* --- We have auth, so check it */ 14357 14358 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 14359 an example in the spec of just what it is you're doing a hash on. */ 14360 14361 if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 14362 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 14363 } 14364 14365 /* Make a copy of the response and parse it */ 14366 res = ast_str_set(&buf, 0, "%s", authtoken); 14367 14368 if (res == AST_DYNSTR_BUILD_FAILED) { 14369 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 14370 } 14371 14372 c = buf->str; 14373 14374 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 14375 for (i = keys; i->key != NULL; i++) { 14376 const char *separator = ","; /* default */ 14377 14378 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 14379 continue; 14380 } 14381 /* Found. Skip keyword, take text in quotes or up to the separator. */ 14382 c += strlen(i->key); 14383 if (*c == '"') { /* in quotes. Skip first and look for last */ 14384 c++; 14385 separator = "\""; 14386 } 14387 i->s = c; 14388 strsep(&c, separator); 14389 break; 14390 } 14391 if (i->key == NULL) { /* not found, jump after space or comma */ 14392 strsep(&c, " ,"); 14393 } 14394 } 14395 14396 /* Verify that digest username matches the username we auth as */ 14397 if (strcmp(username, keys[K_USER].s)) { 14398 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 14399 username, keys[K_USER].s); 14400 /* Oops, we're trying something here */ 14401 return AUTH_USERNAME_MISMATCH; 14402 } 14403 14404 /* Verify nonce from request matches our nonce, and the nonce has not already been responded to. 14405 * If this check fails, send 401 with new nonce */ 14406 if (strcasecmp(p->randdata, keys[K_NONCE].s) || p->stalenonce) { /* XXX it was 'n'casecmp ? */ 14407 wrongnonce = TRUE; 14408 usednonce = keys[K_NONCE].s; 14409 } else { 14410 p->stalenonce = 1; /* now, since the nonce has a response, mark it as stale so it can't be sent or responded to again */ 14411 } 14412 14413 if (!ast_strlen_zero(md5secret)) { 14414 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 14415 } else { 14416 char a1[256]; 14417 14418 snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret); 14419 ast_md5_hash(a1_hash, a1); 14420 } 14421 14422 /* compute the expected response to compare with what we received */ 14423 { 14424 char a2[256]; 14425 char a2_hash[256]; 14426 char resp[256]; 14427 14428 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 14429 S_OR(keys[K_URI].s, uri)); 14430 ast_md5_hash(a2_hash, a2); 14431 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 14432 ast_md5_hash(resp_hash, resp); 14433 } 14434 14435 good_response = keys[K_RESP].s && 14436 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 14437 if (wrongnonce) { 14438 if (good_response) { 14439 if (sipdebug) 14440 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "From")); 14441 /* We got working auth token, based on stale nonce . */ 14442 set_nonce_randdata(p, 0); 14443 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 14444 } else { 14445 /* Everything was wrong, so give the device one more try with a new challenge */ 14446 if (!req->ignore) { 14447 if (sipdebug) { 14448 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 14449 } 14450 set_nonce_randdata(p, 1); 14451 } else { 14452 if (sipdebug) { 14453 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 14454 } 14455 } 14456 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 14457 } 14458 14459 /* Schedule auto destroy in 32 seconds */ 14460 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14461 return AUTH_CHALLENGE_SENT; 14462 } 14463 if (good_response) { 14464 append_history(p, "AuthOK", "Auth challenge successful for %s", username); 14465 return AUTH_SUCCESSFUL; 14466 } 14467 14468 /* Ok, we have a bad username/secret pair */ 14469 /* Tell the UAS not to re-send this authentication data, because 14470 it will continue to fail 14471 */ 14472 14473 return AUTH_SECRET_FAILED; 14474 }
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 15894 of file chan_sip.c.
References accountcode, ao2_t_ref, ast_apply_ha(), ast_cc_copy_config_params(), ast_copy_flags, ast_debug, ast_is_shrinkable_phonenumber(), ast_rtp_codecs_packetization_set(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_set_flag, ast_shrink_phone_number(), ast_sockaddr_stringify(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_variables_destroy(), ast_verbose, check_auth(), cid_name, cid_num, context, copy_vars(), 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().
15898 { 15899 enum check_auth_result res; 15900 int debug = sip_debug_test_addr(addr); 15901 struct sip_peer *peer; 15902 15903 if (sipmethod == SIP_SUBSCRIBE) { 15904 /* For subscribes, match on device name only; for other methods, 15905 * match on IP address-port of the incoming request. 15906 */ 15907 peer = find_peer(of, NULL, TRUE, FINDALLDEVICES, FALSE, 0); 15908 } else { 15909 /* First find devices based on username (avoid all type=peer's) */ 15910 peer = find_peer(of, NULL, TRUE, FINDUSERS, FALSE, 0); 15911 15912 /* Then find devices based on IP */ 15913 if (!peer) { 15914 peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type); 15915 } 15916 } 15917 15918 if (!peer) { 15919 if (debug) { 15920 ast_verbose("No matching peer for '%s' from '%s'\n", 15921 of, ast_sockaddr_stringify(&p->recv)); 15922 } 15923 return AUTH_DONT_KNOW; 15924 } 15925 15926 if (!ast_apply_ha(peer->ha, addr)) { 15927 ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of); 15928 unref_peer(peer, "unref_peer: check_peer_ok: from find_peer call, early return of AUTH_ACL_FAILED"); 15929 return AUTH_ACL_FAILED; 15930 } 15931 if (debug) 15932 ast_verbose("Found peer '%s' for '%s' from %s\n", 15933 peer->name, of, ast_sockaddr_stringify(&p->recv)); 15934 15935 /* XXX what about p->prefs = peer->prefs; ? */ 15936 /* Set Frame packetization */ 15937 if (p->rtp) { 15938 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs); 15939 p->autoframing = peer->autoframing; 15940 } 15941 15942 /* Take the peer */ 15943 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 15944 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 15945 ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 15946 15947 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->udptl) { 15948 p->t38_maxdatagram = peer->t38_maxdatagram; 15949 set_t38_capabilities(p); 15950 } 15951 15952 /* Copy SIP extensions profile to peer */ 15953 /* XXX is this correct before a successful auth ? */ 15954 if (p->sipoptions) 15955 peer->sipoptions = p->sipoptions; 15956 15957 do_setnat(p); 15958 15959 ast_string_field_set(p, peersecret, peer->secret); 15960 ast_string_field_set(p, peermd5secret, peer->md5secret); 15961 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 15962 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 15963 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 15964 if (!ast_strlen_zero(peer->parkinglot)) { 15965 ast_string_field_set(p, parkinglot, peer->parkinglot); 15966 } 15967 ast_string_field_set(p, engine, peer->engine); 15968 p->disallowed_methods = peer->disallowed_methods; 15969 set_pvt_allowed_methods(p, req); 15970 ast_cc_copy_config_params(p->cc_params, peer->cc_params); 15971 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 15972 p->callingpres = peer->callingpres; 15973 if (peer->maxms && peer->lastms) 15974 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 15975 else 15976 p->timer_t1 = peer->timer_t1; 15977 15978 /* Set timer B to control transaction timeouts */ 15979 if (peer->timer_b) 15980 p->timer_b = peer->timer_b; 15981 else 15982 p->timer_b = 64 * p->timer_t1; 15983 15984 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 15985 /* Pretend there is no required authentication */ 15986 ast_string_field_set(p, peersecret, NULL); 15987 ast_string_field_set(p, peermd5secret, NULL); 15988 } 15989 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, req->ignore))) { 15990 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 15991 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 15992 ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 15993 /* If we have a call limit, set flag */ 15994 if (peer->call_limit) 15995 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 15996 ast_string_field_set(p, peername, peer->name); 15997 ast_string_field_set(p, authname, peer->name); 15998 15999 if (sipmethod == SIP_INVITE) { 16000 /* destroy old channel vars and copy in new ones. */ 16001 ast_variables_destroy(p->chanvars); 16002 p->chanvars = copy_vars(peer->chanvars); 16003 } 16004 16005 if (authpeer) { 16006 ao2_t_ref(peer, 1, "copy pointer into (*authpeer)"); 16007 (*authpeer) = peer; /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 16008 } 16009 16010 if (!ast_strlen_zero(peer->username)) { 16011 ast_string_field_set(p, username, peer->username); 16012 /* Use the default username for authentication on outbound calls */ 16013 /* XXX this takes the name from the caller... can we override ? */ 16014 ast_string_field_set(p, authname, peer->username); 16015 } 16016 if (!get_rpid(p, req)) { 16017 if (!ast_strlen_zero(peer->cid_num)) { 16018 char *tmp = ast_strdupa(peer->cid_num); 16019 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 16020 ast_shrink_phone_number(tmp); 16021 ast_string_field_set(p, cid_num, tmp); 16022 } 16023 if (!ast_strlen_zero(peer->cid_name)) 16024 ast_string_field_set(p, cid_name, peer->cid_name); 16025 if (!ast_strlen_zero(peer->cid_tag)) 16026 ast_string_field_set(p, cid_tag, peer->cid_tag); 16027 if (peer->callingpres) 16028 p->callingpres = peer->callingpres; 16029 } 16030 ast_string_field_set(p, fullcontact, peer->fullcontact); 16031 16032 if (!ast_strlen_zero(peer->context)) { 16033 ast_string_field_set(p, context, peer->context); 16034 } 16035 if (!ast_strlen_zero(peer->mwi_from)) { 16036 ast_string_field_set(p, mwi_from, peer->mwi_from); 16037 } 16038 16039 ast_string_field_set(p, peersecret, peer->secret); 16040 ast_string_field_set(p, peermd5secret, peer->md5secret); 16041 ast_string_field_set(p, language, peer->language); 16042 ast_string_field_set(p, accountcode, peer->accountcode); 16043 p->amaflags = peer->amaflags; 16044 p->callgroup = peer->callgroup; 16045 p->pickupgroup = peer->pickupgroup; 16046 p->capability = peer->capability; 16047 p->prefs = peer->prefs; 16048 p->jointcapability = peer->capability; 16049 if (peer->maxforwards > 0) { 16050 p->maxforwards = peer->maxforwards; 16051 } 16052 if (p->peercapability) 16053 p->jointcapability &= p->peercapability; 16054 p->maxcallbitrate = peer->maxcallbitrate; 16055 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 16056 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 16057 p->noncodeccapability |= AST_RTP_DTMF; 16058 else 16059 p->noncodeccapability &= ~AST_RTP_DTMF; 16060 p->jointnoncodeccapability = p->noncodeccapability; 16061 p->rtptimeout = peer->rtptimeout; 16062 p->rtpholdtimeout = peer->rtpholdtimeout; 16063 p->rtpkeepalive = peer->rtpkeepalive; 16064 if (!dialog_initialize_rtp(p)) { 16065 if (p->rtp) { 16066 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs); 16067 p->autoframing = peer->autoframing; 16068 } 16069 } else { 16070 res = AUTH_RTP_FAILED; 16071 } 16072 } 16073 unref_peer(peer, "check_peer_ok: unref_peer: tossing temp ptr to peer from find_peer"); 16074 return res; 16075 }
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 19727 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().
19728 { 19729 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 19730 /* if we can't BYE, then this is really a pending CANCEL */ 19731 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) { 19732 p->invitestate = INV_CANCELLED; 19733 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 19734 /* Actually don't destroy us yet, wait for the 487 on our original 19735 INVITE, but do set an autodestruct just in case we never get it. */ 19736 } else { 19737 /* We have a pending outbound invite, don't send something 19738 new in-transaction */ 19739 if (p->pendinginvite) 19740 return; 19741 19742 if (p->owner) { 19743 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 19744 } 19745 /* Perhaps there is an SD change INVITE outstanding */ 19746 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 19747 } 19748 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 19749 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 19750 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 19751 /* if we can't REINVITE, hold it for later */ 19752 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 19753 ast_debug(2, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 19754 } else { 19755 ast_debug(2, "Sending pending reinvite on '%s'\n", p->callid); 19756 /* Didn't get to reinvite yet, so do it now */ 19757 transmit_reinvite_with_sdp(p, (p->t38.state == T38_LOCAL_REINVITE ? TRUE : FALSE), FALSE); 19758 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 19759 } 19760 } 19761 }
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 25638 of file chan_sip.c.
References ast_channel_trylock, ast_channel_unlock, ast_log(), ast_rtp_instance_get_hold_timeout(), ast_rtp_instance_get_keepalive(), ast_rtp_instance_get_timeout(), ast_rtp_instance_sendcng(), ast_rtp_instance_set_hold_timeout(), ast_rtp_instance_set_timeout(), ast_sockaddr_isnull(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, and LOG_NOTICE.
Referenced by dialog_needdestroy().
25639 { 25640 /* If we have no RTP or no active owner, no need to check timers */ 25641 if (!dialog->rtp || !dialog->owner) 25642 return; 25643 /* If the call is not in UP state or redirected outside Asterisk, no need to check timers */ 25644 25645 if (dialog->owner->_state != AST_STATE_UP || !ast_sockaddr_isnull(&dialog->redirip)) 25646 return; 25647 25648 /* If the call is involved in a T38 fax session do not check RTP timeout */ 25649 if (dialog->t38.state == T38_ENABLED) 25650 return; 25651 25652 /* If we have no timers set, return now */ 25653 if (!ast_rtp_instance_get_keepalive(dialog->rtp) && !ast_rtp_instance_get_timeout(dialog->rtp) && !ast_rtp_instance_get_hold_timeout(dialog->rtp)) { 25654 return; 25655 } 25656 25657 /* Check AUDIO RTP keepalives */ 25658 if (dialog->lastrtptx && ast_rtp_instance_get_keepalive(dialog->rtp) && 25659 (t > dialog->lastrtptx + ast_rtp_instance_get_keepalive(dialog->rtp))) { 25660 /* Need to send an empty RTP packet */ 25661 dialog->lastrtptx = time(NULL); 25662 ast_rtp_instance_sendcng(dialog->rtp, 0); 25663 } 25664 25665 /*! \todo Check video RTP keepalives 25666 25667 Do we need to move the lastrtptx to the RTP structure to have one for audio and one 25668 for video? It really does belong to the RTP structure. 25669 */ 25670 25671 /* Check AUDIO RTP timers */ 25672 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))) { 25673 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)))) { 25674 /* Needs a hangup */ 25675 if (ast_rtp_instance_get_timeout(dialog->rtp)) { 25676 if (!dialog->owner || ast_channel_trylock(dialog->owner)) { 25677 /* 25678 * Don't block, just try again later. 25679 * If there was no owner, the call is dead already. 25680 */ 25681 return; 25682 } 25683 ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 25684 dialog->owner->name, (long) (t - dialog->lastrtprx)); 25685 /* Issue a softhangup */ 25686 ast_softhangup_nolock(dialog->owner, AST_SOFTHANGUP_DEV); 25687 ast_channel_unlock(dialog->owner); 25688 /* forget the timeouts for this call, since a hangup 25689 has already been requested and we don't want to 25690 repeatedly request hangups 25691 */ 25692 ast_rtp_instance_set_timeout(dialog->rtp, 0); 25693 ast_rtp_instance_set_hold_timeout(dialog->rtp, 0); 25694 if (dialog->vrtp) { 25695 ast_rtp_instance_set_timeout(dialog->vrtp, 0); 25696 ast_rtp_instance_set_hold_timeout(dialog->vrtp, 0); 25697 } 25698 } 25699 } 25700 } 25701 }
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 26834 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().
26835 { 26836 struct domain *d; 26837 int result = 0; 26838 26839 AST_LIST_LOCK(&domain_list); 26840 AST_LIST_TRAVERSE(&domain_list, d, list) { 26841 if (strcasecmp(d->domain, domain)) { 26842 continue; 26843 } 26844 26845 if (len && !ast_strlen_zero(d->context)) 26846 ast_copy_string(context, d->context, len); 26847 26848 result = 1; 26849 break; 26850 } 26851 AST_LIST_UNLOCK(&domain_list); 26852 26853 return result; 26854 }
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 16214 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_options(), and handle_request_publish().
16215 { 16216 return check_user_full(p, req, sipmethod, uri, reliable, addr, NULL); 16217 }
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 16083 of file chan_sip.c.
References ast_copy_string(), ast_is_shrinkable_phonenumber(), ast_log(), ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_contact(), check_peer_ok(), cid_name, cid_num, dialog_initialize_rtp(), exten, extract_host_from_hostport(), get_calleridname(), get_header(), get_in_brackets(), get_rpid(), global_match_auth_username, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_shrinkcallerid, LOG_ERROR, LOG_NOTICE, name, parse_uri_legacy_check(), sip_cfg, SIP_PEDANTIC_DECODE, strsep(), and terminate_uri().
Referenced by check_user(), handle_request_invite(), and handle_request_subscribe().
16086 { 16087 char from[256] = "", *of, *name, *unused_password, *domain; 16088 enum check_auth_result res = AUTH_DONT_KNOW; 16089 char calleridname[50]; 16090 char *uri2 = ast_strdupa(uri); 16091 16092 terminate_uri(uri2); /* trim extra stuff */ 16093 16094 ast_copy_string(from, get_header(req, "From"), sizeof(from)); 16095 /* XXX here tries to map the username for invite things */ 16096 16097 /* strip the display-name portion off the beginning of the FROM header. */ 16098 if (!(of = (char *) get_calleridname(from, calleridname, sizeof(calleridname)))) { 16099 ast_log(LOG_ERROR, "FROM header can not be parsed \n"); 16100 return res; 16101 } 16102 16103 if (calleridname[0]) { 16104 ast_string_field_set(p, cid_name, calleridname); 16105 } 16106 16107 if (ast_strlen_zero(p->exten)) { 16108 char *t = uri2; 16109 if (!strncasecmp(t, "sip:", 4)) 16110 t+= 4; 16111 else if (!strncasecmp(t, "sips:", 5)) 16112 t += 5; 16113 ast_string_field_set(p, exten, t); 16114 t = strchr(p->exten, '@'); 16115 if (t) 16116 *t = '\0'; 16117 16118 if (ast_strlen_zero(p->our_contact)) 16119 build_contact(p); 16120 } 16121 16122 of = get_in_brackets(of); 16123 16124 /* save the URI part of the From header */ 16125 ast_string_field_set(p, from, of); 16126 16127 if (parse_uri_legacy_check(of, "sip:,sips:", &name, &unused_password, &domain, NULL)) { 16128 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 16129 } 16130 16131 SIP_PEDANTIC_DECODE(name); 16132 SIP_PEDANTIC_DECODE(domain); 16133 16134 extract_host_from_hostport(&domain); 16135 16136 if (ast_strlen_zero(domain)) { 16137 /* <sip:name@[EMPTY]>, never good */ 16138 ast_log(LOG_ERROR, "Empty domain name in FROM header\n"); 16139 return res; 16140 } 16141 16142 if (ast_strlen_zero(name)) { 16143 /* <sip:[EMPTY][@]hostport>. Asterisk 1.4 and 1.6 have always 16144 * treated that as a username, so we continue the tradition: 16145 * uri is now <sip:host@hostport>. */ 16146 name = domain; 16147 } else { 16148 /* Non-empty name, try to get caller id from it */ 16149 char *tmp = ast_strdupa(name); 16150 /* We need to be able to handle from-headers looking like 16151 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 16152 */ 16153 tmp = strsep(&tmp, ";"); 16154 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) { 16155 ast_shrink_phone_number(tmp); 16156 } 16157 ast_string_field_set(p, cid_num, tmp); 16158 } 16159 16160 if (global_match_auth_username) { 16161 /* 16162 * XXX This is experimental code to grab the search key from the 16163 * Auth header's username instead of the 'From' name, if available. 16164 * Do not enable this block unless you understand the side effects (if any!) 16165 * Note, the search for "username" should be done in a more robust way. 16166 * Note2, at the moment we check both fields, though maybe we should 16167 * pick one or another depending on the request ? XXX 16168 */ 16169 const char *hdr = get_header(req, "Authorization"); 16170 if (ast_strlen_zero(hdr)) { 16171 hdr = get_header(req, "Proxy-Authorization"); 16172 } 16173 16174 if (!ast_strlen_zero(hdr) && (hdr = strstr(hdr, "username=\""))) { 16175 ast_copy_string(from, hdr + strlen("username=\""), sizeof(from)); 16176 name = from; 16177 name = strsep(&name, "\""); 16178 } 16179 } 16180 16181 res = check_peer_ok(p, name, req, sipmethod, addr, 16182 authpeer, reliable, calleridname, uri2); 16183 if (res != AUTH_DONT_KNOW) { 16184 return res; 16185 } 16186 16187 /* Finally, apply the guest policy */ 16188 if (sip_cfg.allowguest) { 16189 get_rpid(p, req); 16190 p->rtptimeout = global_rtptimeout; 16191 p->rtpholdtimeout = global_rtpholdtimeout; 16192 p->rtpkeepalive = global_rtpkeepalive; 16193 if (!dialog_initialize_rtp(p)) { 16194 res = AUTH_SUCCESSFUL; 16195 } else { 16196 res = AUTH_RTP_FAILED; 16197 } 16198 } else if (sip_cfg.alwaysauthreject) { 16199 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 16200 } else { 16201 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 16202 } 16203 16204 if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT)) { 16205 ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT); 16206 } 16207 16208 return res; 16209 }
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 15833 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().
15834 { 15835 char via[512]; 15836 char *c, *maddr; 15837 struct ast_sockaddr tmp = { { 0, } }; 15838 uint16_t port; 15839 15840 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 15841 15842 /* Work on the leftmost value of the topmost Via header */ 15843 c = strchr(via, ','); 15844 if (c) 15845 *c = '\0'; 15846 15847 /* Check for rport */ 15848 c = strstr(via, ";rport"); 15849 if (c && (c[6] != '=')) { /* rport query, not answer */ 15850 ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT); 15851 ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT); 15852 } 15853 15854 /* Check for maddr */ 15855 maddr = strstr(via, "maddr="); 15856 if (maddr) { 15857 maddr += 6; 15858 c = maddr + strspn(maddr, "abcdefghijklmnopqrstuvwxyz" 15859 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.:[]"); 15860 *c = '\0'; 15861 } 15862 15863 c = strchr(via, ';'); 15864 if (c) 15865 *c = '\0'; 15866 15867 c = strchr(via, ' '); 15868 if (c) { 15869 *c = '\0'; 15870 c = ast_skip_blanks(c+1); 15871 if (strcasecmp(via, "SIP/2.0/UDP") && strcasecmp(via, "SIP/2.0/TCP") && strcasecmp(via, "SIP/2.0/TLS")) { 15872 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 15873 return; 15874 } 15875 15876 if (maddr && ast_sockaddr_resolve_first(&p->sa, maddr, 0)) { 15877 p->sa = p->recv; 15878 } 15879 15880 ast_sockaddr_resolve_first(&tmp, c, 0); 15881 port = ast_sockaddr_port(&tmp); 15882 ast_sockaddr_set_port(&p->sa, 15883 port != 0 ? port : STANDARD_SIP_PORT); 15884 15885 if (sip_debug_test_pvt(p)) { 15886 ast_verbose("Sending to %s (%s)\n", 15887 ast_sockaddr_stringify(sip_real_dst(p)), 15888 sip_nat_mode(p)); 15889 } 15890 } 15891 }
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 15803 of file chan_sip.c.
References ast_copy_string(), ast_parse_arg(), ast_sockaddr_set_port, get_header(), PARSE_ADDR, and strsep().
15804 { 15805 char via[256]; 15806 char *cur, *opts; 15807 15808 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 15809 15810 /* Work on the leftmost value of the topmost Via header */ 15811 opts = strchr(via, ','); 15812 if (opts) 15813 *opts = '\0'; 15814 15815 /* parse all relevant options */ 15816 opts = strchr(via, ';'); 15817 if (!opts) 15818 return; /* no options to parse */ 15819 *opts++ = '\0'; 15820 while ( (cur = strsep(&opts, ";")) ) { 15821 if (!strncmp(cur, "rport=", 6)) { 15822 int port = strtol(cur+6, NULL, 10); 15823 /* XXX add error checking */ 15824 ast_sockaddr_set_port(&p->ourip, port); 15825 } else if (!strncmp(cur, "received=", 9)) { 15826 if (ast_parse_arg(cur + 9, PARSE_ADDR, &p->ourip)) 15827 ; /* XXX add error checking */ 15828 } 15829 } 15830 }
static void cleanup_all_regs | ( | void | ) | [static] |
Definition at line 27835 of file chan_sip.c.
References ast_debug, AST_SCHED_DEL_UNREF, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_WRLOCK, dialog_unlink_all(), registry_unref(), and regl.
Referenced by reload_config(), and unload_module().
27836 { 27837 /* First, destroy all outstanding registry calls */ 27838 /* This is needed, since otherwise active registry entries will not be destroyed */ 27839 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { /* regl is locked */ 27840 ASTOBJ_WRLOCK(iterator); /* now regl is locked, and the object is also locked */ 27841 if (iterator->call) { 27842 ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 27843 /* This will also remove references to the registry */ 27844 dialog_unlink_all(iterator->call); 27845 iterator->call = dialog_unref(iterator->call, "remove iterator->call from registry traversal"); 27846 } 27847 if (iterator->expire > -1) { 27848 AST_SCHED_DEL_UNREF(sched, iterator->expire, registry_unref(iterator, "reg ptr unref from reload config")); 27849 } 27850 if (iterator->timeout > -1) { 27851 AST_SCHED_DEL_UNREF(sched, iterator->timeout, registry_unref(iterator, "reg ptr unref from reload config")); 27852 } 27853 if (iterator->dnsmgr) { 27854 ast_dnsmgr_release(iterator->dnsmgr); 27855 iterator->dnsmgr = NULL; 27856 registry_unref(iterator, "reg ptr unref from dnsmgr"); 27857 } 27858 ASTOBJ_UNLOCK(iterator); 27859 } while(0)); 27860 }
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 16928 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().
16929 { 16930 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 16931 16932 while ((oldcontext = strsep(&old, "&"))) { 16933 stalecontext = '\0'; 16934 ast_copy_string(newlist, new, sizeof(newlist)); 16935 stringp = newlist; 16936 while ((newcontext = strsep(&stringp, "&"))) { 16937 if (!strcmp(newcontext, oldcontext)) { 16938 /* This is not the context you're looking for */ 16939 stalecontext = '\0'; 16940 break; 16941 } else if (strcmp(newcontext, oldcontext)) { 16942 stalecontext = oldcontext; 16943 } 16944 16945 } 16946 if (stalecontext) 16947 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 16948 } 16949 }
static void clear_peer_mailboxes | ( | struct sip_peer * | peer | ) | [static] |
Destroy all peer-related mailbox subscriptions
Definition at line 4595 of file chan_sip.c.
References AST_LIST_REMOVE_HEAD, destroy_mailbox(), and mailbox.
Referenced by set_peer_defaults(), and sip_destroy_peer().
04596 { 04597 struct sip_mailbox *mailbox; 04598 04599 while ((mailbox = AST_LIST_REMOVE_HEAD(&peer->mailboxes, entry))) 04600 destroy_mailbox(mailbox); 04601 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 26857 of file chan_sip.c.
References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.
Referenced by reload_config().
26858 { 26859 struct domain *d; 26860 26861 AST_LIST_LOCK(&domain_list); 26862 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 26863 ast_free(d); 26864 AST_LIST_UNLOCK(&domain_list); 26865 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 18395 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().
18396 { 18397 char *result = NULL; 18398 int wordlen = strlen(word); 18399 int which = 0; 18400 struct ao2_iterator i = ao2_iterator_init(peers, 0); 18401 struct sip_peer *peer; 18402 18403 while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 18404 /* locking of the object is not required because only the name and flags are being compared */ 18405 if (!strncasecmp(word, peer->name, wordlen) && 18406 (!flags2 || ast_test_flag(&peer->flags[1], flags2)) && 18407 ++which > state) 18408 result = ast_strdup(peer->name); 18409 unref_peer(peer, "toss iterator peer ptr before break"); 18410 if (result) { 18411 break; 18412 } 18413 } 18414 ao2_iterator_destroy(&i); 18415 return result; 18416 }
static char * complete_sip_registered_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on registered peer name.
Definition at line 18419 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().
18420 { 18421 char *result = NULL; 18422 int wordlen = strlen(word); 18423 int which = 0; 18424 struct ao2_iterator i; 18425 struct sip_peer *peer; 18426 18427 i = ao2_iterator_init(peers, 0); 18428 while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 18429 if (!strncasecmp(word, peer->name, wordlen) && 18430 (!flags2 || ast_test_flag(&peer->flags[1], flags2)) && 18431 ++which > state && peer->expire > 0) 18432 result = ast_strdup(peer->name); 18433 if (result) { 18434 unref_peer(peer, "toss iterator peer ptr before break"); 18435 break; 18436 } 18437 unref_peer(peer, "toss iterator peer ptr"); 18438 } 18439 ao2_iterator_destroy(&i); 18440 return result; 18441 }
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 18444 of file chan_sip.c.
References complete_sipch().
Referenced by sip_show_history().
18445 { 18446 if (pos == 3) 18447 return complete_sipch(line, word, pos, state); 18448 18449 return NULL; 18450 }
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 18453 of file chan_sip.c.
References complete_sip_peer().
Referenced by sip_qualify_peer(), and sip_show_peer().
18454 { 18455 if (pos == 3) { 18456 return complete_sip_peer(word, state, 0); 18457 } 18458 18459 return NULL; 18460 }
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 17670 of file chan_sip.c.
References complete_sip_user().
Referenced by sip_show_user().
17671 { 17672 if (pos == 3) 17673 return complete_sip_user(word, state); 17674 17675 return NULL; 17676 }
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 18463 of file chan_sip.c.
References complete_sip_registered_peer().
Referenced by sip_unregister().
18464 { 18465 if (pos == 2) 18466 return complete_sip_registered_peer(word, state, 0); 18467 18468 return NULL; 18469 }
static char* complete_sip_user | ( | const char * | word, | |
int | state | |||
) | [static] |
Do completion on user name.
Definition at line 17640 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_strdup, and unref_peer().
Referenced by complete_sip_show_user().
17641 { 17642 char *result = NULL; 17643 int wordlen = strlen(word); 17644 int which = 0; 17645 struct ao2_iterator user_iter; 17646 struct sip_peer *user; 17647 17648 user_iter = ao2_iterator_init(peers, 0); 17649 while ((user = ao2_t_iterator_next(&user_iter, "iterate thru peers table"))) { 17650 ao2_lock(user); 17651 if (!(user->type & SIP_TYPE_USER)) { 17652 ao2_unlock(user); 17653 unref_peer(user, "complete sip user"); 17654 continue; 17655 } 17656 /* locking of the object is not required because only the name and flags are being compared */ 17657 if (!strncasecmp(word, user->name, wordlen) && ++which > state) { 17658 result = ast_strdup(user->name); 17659 } 17660 ao2_unlock(user); 17661 unref_peer(user, "complete sip user"); 17662 if (result) { 17663 break; 17664 } 17665 } 17666 ao2_iterator_destroy(&user_iter); 17667 return result; 17668 }
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 18365 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().
18366 { 18367 int which=0; 18368 struct sip_pvt *cur; 18369 char *c = NULL; 18370 int wordlen = strlen(word); 18371 struct ao2_iterator i; 18372 18373 if (pos != 3) { 18374 return NULL; 18375 } 18376 18377 i = ao2_iterator_init(dialogs, 0); 18378 while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 18379 sip_pvt_lock(cur); 18380 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 18381 c = ast_strdup(cur->callid); 18382 sip_pvt_unlock(cur); 18383 dialog_unref(cur, "drop ref in iterator loop break"); 18384 break; 18385 } 18386 sip_pvt_unlock(cur); 18387 dialog_unref(cur, "drop ref in iterator loop"); 18388 } 18389 ao2_iterator_destroy(&i); 18390 return c; 18391 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 18472 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
Referenced by sip_cli_notify().
18473 { 18474 char *c = NULL; 18475 18476 if (pos == 2) { 18477 int which = 0; 18478 char *cat = NULL; 18479 int wordlen = strlen(word); 18480 18481 /* do completion for notify type */ 18482 18483 if (!notify_types) 18484 return NULL; 18485 18486 while ( (cat = ast_category_browse(notify_types, cat)) ) { 18487 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 18488 c = ast_strdup(cat); 18489 break; 18490 } 18491 } 18492 return c; 18493 } 18494 18495 if (pos > 2) 18496 return complete_sip_peer(word, state, 0); 18497 18498 return NULL; 18499 }
static int construct_pidf_body | ( | enum sip_cc_publish_state | state, | |
char * | pidf_body, | |||
size_t | size, | |||
const char * | presentity | |||
) | [static] |
Definition at line 1950 of file chan_sip.c.
References ast_copy_string(), ast_str_alloca, ast_str_append(), ast_str_buffer(), and generate_random_string().
Referenced by handle_cc_notify(), sip_cc_monitor_suspend(), and sip_cc_monitor_unsuspend().
01951 { 01952 struct ast_str *body = ast_str_alloca(size); 01953 char tuple_id[32]; 01954 01955 generate_random_string(tuple_id, sizeof(tuple_id)); 01956 01957 /* We'll make this a bare-bones pidf body. In state_notify_build_xml, the PIDF 01958 * body gets a lot more extra junk that isn't necessary, so we'll leave it out here. 01959 */ 01960 ast_str_append(&body, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 01961 /* XXX The entity attribute is currently set to the peer name associated with the 01962 * dialog. This is because we currently only call this function for call-completion 01963 * PUBLISH bodies. In such cases, the entity is completely disregarded. For other 01964 * event packages, it may be crucial to have a proper URI as the presentity so this 01965 * should be revisited as support is expanded. 01966 */ 01967 ast_str_append(&body, 0, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"%s\">\n", presentity); 01968 ast_str_append(&body, 0, "<tuple id=\"%s\">\n", tuple_id); 01969 ast_str_append(&body, 0, "<status><basic>%s</basic></status>\n", state == CC_OPEN ? "open" : "closed"); 01970 ast_str_append(&body, 0, "</tuple>\n"); 01971 ast_str_append(&body, 0, "</presence>\n"); 01972 ast_copy_string(pidf_body, ast_str_buffer(body), size); 01973 return 0; 01974 }
static int copy_all_header | ( | struct sip_request * | req, | |
const struct sip_request * | orig, | |||
const char * | field | |||
) | [static] |
Copy all headers from one request to another.
Definition at line 9897 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
09898 { 09899 int start = 0; 09900 int copied = 0; 09901 for (;;) { 09902 const char *tmp = __get_header(orig, field, &start); 09903 09904 if (ast_strlen_zero(tmp)) 09905 break; 09906 /* Add what we're responding to */ 09907 add_header(req, field, tmp); 09908 copied++; 09909 } 09910 return copied ? 0 : -1; 09911 }
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 9886 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
09887 { 09888 const char *tmp = get_header(orig, field); 09889 09890 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 09891 return add_header(req, field, tmp); 09892 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 09893 return -1; 09894 }
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 11665 of file chan_sip.c.
References ast_str_copy_string(), ast_str_create(), and ast_str_strlen().
Referenced by handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), parse_copy(), and sip_park().
11666 { 11667 /* XXX this function can encounter memory allocation errors, perhaps it 11668 * should return a value */ 11669 11670 struct ast_str *duplicate = dst->data; 11671 struct ast_str *duplicate_content = dst->content; 11672 11673 /* copy the entire request then restore the original data and content 11674 * members from the dst request */ 11675 memcpy(dst, src, sizeof(*dst)); 11676 dst->data = duplicate; 11677 dst->content = duplicate_content; 11678 11679 /* copy the data into the dst request */ 11680 if (!dst->data && !(dst->data = ast_str_create(ast_str_strlen(src->data) + 1))) 11681 return; 11682 ast_str_copy_string(&dst->data, src->data); 11683 11684 /* copy the content into the dst request (if it exists) */ 11685 if (src->content) { 11686 if (!dst->content && !(dst->content = ast_str_create(ast_str_strlen(src->content) + 1))) 11687 return; 11688 ast_str_copy_string(&dst->content, src->content); 11689 } 11690 }
static void copy_socket_data | ( | struct sip_socket * | to_sock, | |
const struct sip_socket * | from_sock | |||
) | [static] |
Definition at line 5172 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().
05173 { 05174 if (to_sock->tcptls_session) { 05175 ao2_ref(to_sock->tcptls_session, -1); 05176 to_sock->tcptls_session = NULL; 05177 } 05178 05179 if (from_sock->tcptls_session) { 05180 ao2_ref(from_sock->tcptls_session, +1); 05181 } 05182 05183 *to_sock = *from_sock; 05184 }
static struct ast_variable * copy_vars | ( | struct ast_variable * | src | ) | [static] |
duplicate a list of channel variables,
Definition at line 2329 of file chan_sip.c.
References ast_variable_new(), and ast_variable::next.
02330 { 02331 struct ast_variable *res = NULL, *tmp, *v = NULL; 02332 02333 for (v = src ; v ; v = v->next) { 02334 if ((tmp = ast_variable_new(v->name, v->value, v->file))) { 02335 tmp->next = res; 02336 res = tmp; 02337 } 02338 } 02339 return res; 02340 }
static int copy_via_headers | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
const struct sip_request * | orig, | |||
const char * | field | |||
) | [static] |
Copy SIP VIA Headers from the request to the response.
We always add ;received=<ip address> to the topmost via header.
Definition at line 9921 of file chan_sip.c.
References __get_header(), add_header(), ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_stringify_addr_remote(), ast_strlen_zero(), ast_test_flag, and LOG_NOTICE.
Referenced by respprep().
09922 { 09923 int copied = 0; 09924 int start = 0; 09925 09926 for (;;) { 09927 char new[512]; 09928 const char *oh = __get_header(orig, field, &start); 09929 09930 if (ast_strlen_zero(oh)) 09931 break; 09932 09933 if (!copied) { /* Only check for empty rport in topmost via header */ 09934 char leftmost[512], *others, *rport; 09935 09936 /* Only work on leftmost value */ 09937 ast_copy_string(leftmost, oh, sizeof(leftmost)); 09938 others = strchr(leftmost, ','); 09939 if (others) 09940 *others++ = '\0'; 09941 09942 /* Find ;rport; (empty request) */ 09943 rport = strstr(leftmost, ";rport"); 09944 if (rport && *(rport+6) == '=') 09945 rport = NULL; /* We already have a parameter to rport */ 09946 09947 if (((ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) || (rport && ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)))) { 09948 /* We need to add received port - rport */ 09949 char *end; 09950 09951 rport = strstr(leftmost, ";rport"); 09952 09953 if (rport) { 09954 end = strchr(rport + 1, ';'); 09955 if (end) 09956 memmove(rport, end, strlen(end) + 1); 09957 else 09958 *rport = '\0'; 09959 } 09960 09961 /* Add rport to first VIA header if requested */ 09962 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 09963 leftmost, ast_sockaddr_stringify_addr_remote(&p->recv), 09964 ast_sockaddr_port(&p->recv), 09965 others ? "," : "", others ? others : ""); 09966 } else { 09967 /* We should *always* add a received to the topmost via */ 09968 snprintf(new, sizeof(new), "%s;received=%s%s%s", 09969 leftmost, ast_sockaddr_stringify_addr_remote(&p->recv), 09970 others ? "," : "", others ? others : ""); 09971 } 09972 oh = new; /* the header to copy */ 09973 } /* else add the following via headers untouched */ 09974 add_header(req, field, oh); 09975 copied++; 09976 } 09977 if (!copied) { 09978 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 09979 return -1; 09980 } 09981 return 0; 09982 }
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 5400 of file chan_sip.c.
References AST_APP_ARG, ast_check_digits(), AST_DECLARE_APP_ARGS, ast_get_srv(), ast_log(), AST_NONSTANDARD_RAW_ARGS, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_strdupa, ast_string_field_set, bindaddr, create_addr_from_peer(), default_sip_port(), dialog_initialize_rtp(), FALSE, find_peer(), get_srv_protocol(), get_srv_service(), global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_t1, global_timer_b, LOG_WARNING, MAXHOSTNAMELEN, obproxy_get(), ref_peer(), ref_proxy(), service, set_socket_transport(), sip_cfg, TRUE, and unref_peer().
05401 { 05402 struct sip_peer *peer; 05403 char *peername, *peername2, *hostn; 05404 char host[MAXHOSTNAMELEN]; 05405 char service[MAXHOSTNAMELEN]; 05406 int srv_ret = 0; 05407 int tportno; 05408 05409 AST_DECLARE_APP_ARGS(hostport, 05410 AST_APP_ARG(host); 05411 AST_APP_ARG(port); 05412 ); 05413 05414 peername = ast_strdupa(opeer); 05415 peername2 = ast_strdupa(opeer); 05416 AST_NONSTANDARD_RAW_ARGS(hostport, peername2, ':'); 05417 05418 if (hostport.port) 05419 dialog->portinuri = 1; 05420 05421 dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */ 05422 dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */ 05423 peer = find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0); 05424 05425 if (peer) { 05426 int res; 05427 if (newdialog) { 05428 set_socket_transport(&dialog->socket, 0); 05429 } 05430 res = create_addr_from_peer(dialog, peer); 05431 if (!ast_sockaddr_isnull(remote_address)) { 05432 ast_sockaddr_copy(&dialog->sa, remote_address); 05433 } 05434 dialog->relatedpeer = ref_peer(peer, "create_addr: setting dialog's relatedpeer pointer"); 05435 unref_peer(peer, "create_addr: unref peer from find_peer hashtab lookup"); 05436 return res; 05437 } else if (ast_check_digits(peername)) { 05438 /* Although an IPv4 hostname *could* be represented as a 32-bit integer, it is uncommon and 05439 * it makes dialing SIP/${EXTEN} for a peer that isn't defined resolve to an IP that is 05440 * almost certainly not intended. It is much better to just reject purely numeric hostnames */ 05441 ast_log(LOG_WARNING, "Purely numeric hostname (%s), and not a peer--rejecting!\n", peername); 05442 return -1; 05443 } else { 05444 dialog->rtptimeout = global_rtptimeout; 05445 dialog->rtpholdtimeout = global_rtpholdtimeout; 05446 dialog->rtpkeepalive = global_rtpkeepalive; 05447 if (dialog_initialize_rtp(dialog)) { 05448 return -1; 05449 } 05450 } 05451 05452 ast_string_field_set(dialog, tohost, hostport.host); 05453 dialog->allowed_methods &= ~sip_cfg.disallowed_methods; 05454 05455 /* Get the outbound proxy information */ 05456 ref_proxy(dialog, obproxy_get(dialog, NULL)); 05457 05458 if (addr) { 05459 /* This address should be updated using dnsmgr */ 05460 ast_sockaddr_copy(&dialog->sa, addr); 05461 } else { 05462 05463 /* Let's see if we can find the host in DNS. First try DNS SRV records, 05464 then hostname lookup */ 05465 /*! \todo Fix this function. When we ask for SRV, we should check all transports 05466 In the future, we should first check NAPTR to find out transport preference 05467 */ 05468 hostn = peername; 05469 /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then 05470 * an A record lookup should be used instead of SRV. 05471 */ 05472 if (!hostport.port && sip_cfg.srvlookup) { 05473 snprintf(service, sizeof(service), "_%s._%s.%s", 05474 get_srv_service(dialog->socket.type), 05475 get_srv_protocol(dialog->socket.type), peername); 05476 if ((srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno, 05477 service)) > 0) { 05478 hostn = host; 05479 } 05480 } 05481 05482 if (ast_sockaddr_resolve_first(&dialog->sa, hostn, 0)) { 05483 ast_log(LOG_WARNING, "No such host: %s\n", peername); 05484 return -1; 05485 } 05486 05487 if (srv_ret > 0) { 05488 ast_sockaddr_set_port(&dialog->sa, tportno); 05489 } 05490 } 05491 05492 if (!dialog->socket.type) 05493 set_socket_transport(&dialog->socket, SIP_TRANSPORT_UDP); 05494 if (!dialog->socket.port) { 05495 dialog->socket.port = htons(ast_sockaddr_port(&bindaddr)); 05496 } 05497 05498 if (!ast_sockaddr_port(&dialog->sa)) { 05499 ast_sockaddr_set_port(&dialog->sa, default_sip_port(dialog->socket.type)); 05500 } 05501 ast_sockaddr_copy(&dialog->recv, &dialog->sa); 05502 return 0; 05503 }
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 5246 of file chan_sip.c.
References accountcode, ao2_lock, ao2_t_ref, ao2_unlock, ast_cc_copy_config_params(), ast_copy_flags, ast_duplicate_ha_list(), ast_rtp_codecs_packetization_set(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify_host_remote(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, change_callid_pvt(), check_request_transport, cid_name, cid_num, context, copy_socket_data(), copy_vars(), dialog_initialize_rtp(), global_t1min, language, mohinterpret, mohsuggest, obproxy_get(), parkinglot, and ref_proxy().
Referenced by create_addr(), and sip_send_mwi_to_peer().
05247 { 05248 struct sip_auth_container *credentials; 05249 05250 /* this checks that the dialog is contacting the peer on a valid 05251 * transport type based on the peers transport configuration, 05252 * otherwise, this function bails out */ 05253 if (dialog->socket.type && check_request_transport(peer, dialog)) 05254 return -1; 05255 copy_socket_data(&dialog->socket, &peer->socket); 05256 05257 if (!(ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) && 05258 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 05259 dialog->sa = ast_sockaddr_isnull(&peer->addr) ? peer->defaddr : peer->addr; 05260 dialog->recv = dialog->sa; 05261 } else 05262 return -1; 05263 05264 /* XXX TODO: get flags directly from peer only as they are needed using dialog->relatedpeer */ 05265 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 05266 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 05267 ast_copy_flags(&dialog->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 05268 dialog->capability = peer->capability; 05269 dialog->prefs = peer->prefs; 05270 dialog->amaflags = peer->amaflags; 05271 05272 ast_string_field_set(dialog, engine, peer->engine); 05273 05274 dialog->rtptimeout = peer->rtptimeout; 05275 dialog->rtpholdtimeout = peer->rtpholdtimeout; 05276 dialog->rtpkeepalive = peer->rtpkeepalive; 05277 if (dialog_initialize_rtp(dialog)) { 05278 return -1; 05279 } 05280 05281 if (dialog->rtp) { /* Audio */ 05282 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 05283 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05284 /* Set Frame packetization */ 05285 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(dialog->rtp), dialog->rtp, &dialog->prefs); 05286 dialog->autoframing = peer->autoframing; 05287 } 05288 05289 /* XXX TODO: get fields directly from peer only as they are needed using dialog->relatedpeer */ 05290 ast_string_field_set(dialog, peername, peer->name); 05291 ast_string_field_set(dialog, authname, peer->username); 05292 ast_string_field_set(dialog, username, peer->username); 05293 ast_string_field_set(dialog, peersecret, peer->secret); 05294 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 05295 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 05296 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 05297 ast_string_field_set(dialog, tohost, peer->tohost); 05298 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 05299 ast_string_field_set(dialog, accountcode, peer->accountcode); 05300 ast_string_field_set(dialog, context, peer->context); 05301 ast_string_field_set(dialog, cid_num, peer->cid_num); 05302 ast_string_field_set(dialog, cid_name, peer->cid_name); 05303 ast_string_field_set(dialog, cid_tag, peer->cid_tag); 05304 ast_string_field_set(dialog, mwi_from, peer->mwi_from); 05305 if (!ast_strlen_zero(peer->parkinglot)) { 05306 ast_string_field_set(dialog, parkinglot, peer->parkinglot); 05307 } 05308 ast_string_field_set(dialog, engine, peer->engine); 05309 ref_proxy(dialog, obproxy_get(dialog, peer)); 05310 dialog->callgroup = peer->callgroup; 05311 dialog->pickupgroup = peer->pickupgroup; 05312 dialog->allowtransfer = peer->allowtransfer; 05313 dialog->jointnoncodeccapability = dialog->noncodeccapability; 05314 05315 /* Update dialog authorization credentials */ 05316 ao2_lock(peer); 05317 credentials = peer->auth; 05318 if (credentials) { 05319 ao2_t_ref(credentials, +1, "Ref peer auth for dialog"); 05320 } 05321 ao2_unlock(peer); 05322 ao2_lock(dialog); 05323 if (dialog->peerauth) { 05324 ao2_t_ref(dialog->peerauth, -1, "Unref old dialog peer auth"); 05325 } 05326 dialog->peerauth = credentials; 05327 ao2_unlock(dialog); 05328 05329 dialog->maxcallbitrate = peer->maxcallbitrate; 05330 dialog->disallowed_methods = peer->disallowed_methods; 05331 ast_cc_copy_config_params(dialog->cc_params, peer->cc_params); 05332 if (ast_strlen_zero(dialog->tohost)) 05333 ast_string_field_set(dialog, tohost, ast_sockaddr_stringify_host_remote(&dialog->sa)); 05334 if (!ast_strlen_zero(peer->fromdomain)) { 05335 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 05336 if (!dialog->initreq.headers) { 05337 char *new_callid; 05338 char *tmpcall = ast_strdupa(dialog->callid); 05339 /* this sure looks to me like we are going to change the callid on this dialog!! */ 05340 new_callid = strchr(tmpcall, '@'); 05341 if (new_callid) { 05342 int callid_size; 05343 05344 *new_callid = '\0'; 05345 05346 /* Change the dialog callid. */ 05347 callid_size = strlen(tmpcall) + strlen(peer->fromdomain) + 2; 05348 new_callid = alloca(callid_size); 05349 snprintf(new_callid, callid_size, "%s@%s", tmpcall, peer->fromdomain); 05350 change_callid_pvt(dialog, new_callid); 05351 } 05352 } 05353 } 05354 if (!ast_strlen_zero(peer->fromuser)) 05355 ast_string_field_set(dialog, fromuser, peer->fromuser); 05356 if (!ast_strlen_zero(peer->language)) 05357 ast_string_field_set(dialog, language, peer->language); 05358 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 05359 /* Minimum is settable or default to 100 ms */ 05360 /* If there is a maxms and lastms from a qualify use that over a manual T1 05361 value. Otherwise, use the peer's T1 value. */ 05362 if (peer->maxms && peer->lastms) 05363 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 05364 else 05365 dialog->timer_t1 = peer->timer_t1; 05366 05367 /* Set timer B to control transaction timeouts, the peer setting is the default and overrides 05368 the known timer */ 05369 if (peer->timer_b) 05370 dialog->timer_b = peer->timer_b; 05371 else 05372 dialog->timer_b = 64 * dialog->timer_t1; 05373 05374 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 05375 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 05376 dialog->noncodeccapability |= AST_RTP_DTMF; 05377 else 05378 dialog->noncodeccapability &= ~AST_RTP_DTMF; 05379 dialog->directmediaha = ast_duplicate_ha_list(peer->directmediaha); 05380 if (peer->call_limit) 05381 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 05382 if (!dialog->portinuri) 05383 dialog->portinuri = peer->portinuri; 05384 dialog->chanvars = copy_vars(peer->chanvars); 05385 if (peer->fromdomainport) 05386 dialog->fromdomainport = peer->fromdomainport; 05387 05388 return 0; 05389 }
static struct sip_epa_entry* create_epa_entry | ( | const char *const | event_package, | |
const char *const | destination | |||
) | [static] |
Definition at line 919 of file chan_sip.c.
References ao2_t_alloc, ast_copy_string(), and find_static_data().
Referenced by sip_cc_monitor_suspend().
00920 { 00921 struct sip_epa_entry *epa_entry; 00922 const struct epa_static_data *static_data; 00923 00924 if (!(static_data = find_static_data(event_package))) { 00925 return NULL; 00926 } 00927 00928 if (!(epa_entry = ao2_t_alloc(sizeof(*epa_entry), static_data->destructor, "Allocate new EPA entry"))) { 00929 return NULL; 00930 } 00931 00932 epa_entry->static_data = static_data; 00933 ast_copy_string(epa_entry->destination, destination, sizeof(epa_entry->destination)); 00934 return epa_entry; 00935 }
static struct sip_esc_entry* create_esc_entry | ( | struct event_state_compositor * | esc, | |
struct sip_request * | req, | |||
const int | expires | |||
) | [static] |
Definition at line 1045 of file chan_sip.c.
References ao2_alloc, ao2_ref, ast_sched_add(), create_new_sip_etag(), esc_entry_destructor(), event_state_compositor::name, publish_expire(), and sched.
Referenced by handle_sip_publish_initial().
01046 { 01047 struct sip_esc_entry *esc_entry; 01048 int expires_ms; 01049 01050 if (!(esc_entry = ao2_alloc(sizeof(*esc_entry), esc_entry_destructor))) { 01051 return NULL; 01052 } 01053 01054 esc_entry->event = esc->name; 01055 01056 expires_ms = expires * 1000; 01057 /* Bump refcount for scheduler */ 01058 ao2_ref(esc_entry, +1); 01059 esc_entry->sched_id = ast_sched_add(sched, expires_ms, publish_expire, esc_entry); 01060 01061 /* Note: This links the esc_entry into the ESC properly */ 01062 create_new_sip_etag(esc_entry, 0); 01063 01064 return esc_entry; 01065 }
static void create_new_sip_etag | ( | struct sip_esc_entry * | esc_entry, | |
int | is_linked | |||
) | [static] |
Definition at line 1032 of file chan_sip.c.
References ao2_link, ao2_unlink, ast_assert, ast_atomic_fetchadd_int(), event_state_compositor::compositor, and get_esc().
Referenced by create_esc_entry(), and transmit_response_with_sip_etag().
01033 { 01034 int new_etag = ast_atomic_fetchadd_int(&esc_etag_counter, +1); 01035 struct event_state_compositor *esc = get_esc(esc_entry->event); 01036 01037 ast_assert(esc != NULL); 01038 if (is_linked) { 01039 ao2_unlink(esc->compositor, esc_entry); 01040 } 01041 snprintf(esc_entry->entity_tag, sizeof(esc_entry->entity_tag), "%d", new_etag); 01042 ao2_link(esc->compositor, esc_entry); 01043 }
static int default_sip_port | ( | enum sip_transport | type | ) | [inline, static] |
The default sip port for the given transport.
Definition at line 5392 of file chan_sip.c.
Referenced by create_addr(), on_dns_update_peer(), and parse_register_contact().
05393 { 05394 return type == SIP_TRANSPORT_TLS ? STANDARD_TLS_PORT : STANDARD_SIP_PORT; 05395 }
static void deinit_req | ( | struct sip_request * | req | ) | [static] |
Deinitialize SIP response/request.
Definition at line 10138 of file chan_sip.c.
References ast_free.
Referenced by __sip_destroy(), send_request(), send_response(), sip_park(), sip_park_thread(), and sipsock_read().
10139 { 10140 if (req->data) { 10141 ast_free(req->data); 10142 req->data = NULL; 10143 } 10144 if (req->content) { 10145 ast_free(req->content); 10146 req->content = NULL; 10147 } 10148 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 13655 of file chan_sip.c.
References ast_check_realtime(), ast_db_del(), ast_update_realtime(), SENTINEL, and sip_cfg.
Referenced by build_peer(), and expire_register().
13656 { 13657 int realtimeregs = ast_check_realtime("sipregs"); 13658 char *tablename = (realtimeregs) ? "sipregs" : "sippeers"; 13659 13660 if (!sip_cfg.ignore_regexpire) { 13661 if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) { 13662 ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "regserver", "", "useragent", "", "lastms", "", SENTINEL); 13663 } else { 13664 ast_db_del("SIP/Registry", peer->name); 13665 ast_db_del("SIP/PeerMethods", peer->name); 13666 } 13667 } 13668 }
static void destroy_escs | ( | void | ) | [static] |
Definition at line 1079 of file chan_sip.c.
References ao2_ref, ARRAY_LEN, and event_state_compositors.
Referenced by unload_module().
01080 { 01081 int i; 01082 for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { 01083 ao2_ref(event_state_compositors[i].compositor, -1); 01084 } 01085 }
static void destroy_mailbox | ( | struct sip_mailbox * | mailbox | ) | [static] |
Destroy mailbox subscriptions
Definition at line 4587 of file chan_sip.c.
References ast_event_unsubscribe(), and ast_free.
Referenced by build_peer(), and clear_peer_mailboxes().
04588 { 04589 if (mailbox->event_sub) 04590 ast_event_unsubscribe(mailbox->event_sub); 04591 ast_free(mailbox); 04592 }
static void destroy_realm_authentication | ( | void * | obj | ) | [static] |
Definition at line 26875 of file chan_sip.c.
References ast_free, and AST_LIST_REMOVE_HEAD.
Referenced by add_realm_authentication().
26876 { 26877 struct sip_auth_container *credentials = obj; 26878 struct sip_auth *auth; 26879 26880 while ((auth = AST_LIST_REMOVE_HEAD(&credentials->list, node))) { 26881 ast_free(auth); 26882 } 26883 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 11762 of file chan_sip.c.
References ast_debug, ast_skip_blanks(), ast_skip_nonblanks(), and ast_trim_blanks().
11763 { 11764 char *e = ast_skip_blanks(req->data->str); /* there shouldn't be any */ 11765 char *local_rlPart1; 11766 11767 if (!*e) 11768 return -1; 11769 req->rlPart1 = e - req->data->str; /* method or protocol */ 11770 local_rlPart1 = e; 11771 e = ast_skip_nonblanks(e); 11772 if (*e) 11773 *e++ = '\0'; 11774 /* Get URI or status code */ 11775 e = ast_skip_blanks(e); 11776 if ( !*e ) 11777 return -1; 11778 ast_trim_blanks(e); 11779 11780 if (!strcasecmp(local_rlPart1, "SIP/2.0") ) { /* We have a response */ 11781 if (strlen(e) < 3) /* status code is 3 digits */ 11782 return -1; 11783 req->rlPart2 = e - req->data->str; 11784 } else { /* We have a request */ 11785 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 11786 ast_debug(3, "Oops. Bogus uri in <> %s\n", e); 11787 e++; 11788 if (!*e) 11789 return -1; 11790 } 11791 req->rlPart2 = e - req->data->str; /* URI */ 11792 e = ast_skip_nonblanks(e); 11793 if (*e) 11794 *e++ = '\0'; 11795 e = ast_skip_blanks(e); 11796 if (strcasecmp(e, "SIP/2.0") ) { 11797 ast_debug(3, "Skipping packet - Bad request protocol %s\n", e); 11798 return -1; 11799 } 11800 } 11801 return 1; 11802 }
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 23889 of file chan_sip.c.
References ast_assert, ast_strlen_zero(), and DEFAULT_PUBLISH_EXPIRES.
Referenced by handle_request_publish().
23890 { 23891 int etag_present = !ast_strlen_zero(etag); 23892 int body_present = req->lines > 0; 23893 23894 ast_assert(expires_int != NULL); 23895 23896 if (ast_strlen_zero(expires)) { 23897 /* Section 6, item 4, second bullet point of RFC 3903 says to 23898 * use a locally-configured default expiration if none is provided 23899 * in the request 23900 */ 23901 *expires_int = DEFAULT_PUBLISH_EXPIRES; 23902 } else if (sscanf(expires, "%30d", expires_int) != 1) { 23903 return SIP_PUBLISH_UNKNOWN; 23904 } 23905 23906 if (*expires_int == 0) { 23907 return SIP_PUBLISH_REMOVE; 23908 } else if (!etag_present && body_present) { 23909 return SIP_PUBLISH_INITIAL; 23910 } else if (etag_present && !body_present) { 23911 return SIP_PUBLISH_REFRESH; 23912 } else if (etag_present && body_present) { 23913 return SIP_PUBLISH_MODIFY; 23914 } 23915 23916 return SIP_PUBLISH_UNKNOWN; 23917 }
static int dialog_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 29766 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_module().
29767 { 29768 struct sip_pvt *pvt = obj, *pvt2 = arg; 29769 29770 return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH | CMP_STOP : 0; 29771 }
static int dialog_dump_func | ( | void * | userobj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 16829 of file chan_sip.c.
References ao2_t_ref, ast_cli(), and ast_cli_args::fd.
Referenced by sip_show_objects().
16830 { 16831 struct sip_pvt *pvt = userobj; 16832 int refc = ao2_t_ref(userobj, 0, ""); 16833 struct ast_cli_args *a = (struct ast_cli_args *) arg; 16834 16835 ast_cli(a->fd, "name: %s\ntype: dialog\nobjflags: %d\nrefcount: %d\n\n", 16836 pvt->callid, 0, refc); 16837 return 0; 16838 }
static int dialog_find_multiple | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 29756 of file chan_sip.c.
References CMP_MATCH.
Referenced by find_call().
29757 { 29758 struct sip_pvt *pvt = obj, *pvt2 = arg; 29759 29760 return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH : 0; 29761 }
static int dialog_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 29746 of file chan_sip.c.
References ast_str_case_hash().
Referenced by load_module().
29747 { 29748 const struct sip_pvt *pvt = obj; 29749 29750 return ast_str_case_hash(pvt->callid); 29751 }
static int dialog_initialize_rtp | ( | struct sip_pvt * | dialog | ) | [static] |
Initialize RTP portion of a dialog.
Definition at line 5189 of file chan_sip.c.
References AST_FORMAT_VIDEO_MASK, ast_rtp_instance_new(), ast_rtp_instance_set_hold_timeout(), ast_rtp_instance_set_keepalive(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_qos(), ast_rtp_instance_set_timeout(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, AST_RTP_PROPERTY_RTCP, ast_sockaddr_copy(), ast_test_flag, bindaddr, do_setnat(), global_cos_audio, 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().
05190 { 05191 struct ast_sockaddr bindaddr_tmp; 05192 05193 if (!sip_methods[dialog->method].need_rtp) { 05194 return 0; 05195 } 05196 05197 ast_sockaddr_copy(&bindaddr_tmp, &bindaddr); 05198 if (!(dialog->rtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) { 05199 return -1; 05200 } 05201 05202 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) || 05203 (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (dialog->capability & AST_FORMAT_VIDEO_MASK))) { 05204 if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) { 05205 return -1; 05206 } 05207 ast_rtp_instance_set_timeout(dialog->vrtp, dialog->rtptimeout); 05208 ast_rtp_instance_set_hold_timeout(dialog->vrtp, dialog->rtpholdtimeout); 05209 ast_rtp_instance_set_keepalive(dialog->vrtp, dialog->rtpkeepalive); 05210 05211 ast_rtp_instance_set_prop(dialog->vrtp, AST_RTP_PROPERTY_RTCP, 1); 05212 } 05213 05214 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_TEXTSUPPORT)) { 05215 if (!(dialog->trtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) { 05216 return -1; 05217 } 05218 /* Do not timeout text as its not constant*/ 05219 ast_rtp_instance_set_keepalive(dialog->trtp, dialog->rtpkeepalive); 05220 05221 ast_rtp_instance_set_prop(dialog->trtp, AST_RTP_PROPERTY_RTCP, 1); 05222 } 05223 05224 ast_rtp_instance_set_timeout(dialog->rtp, dialog->rtptimeout); 05225 ast_rtp_instance_set_hold_timeout(dialog->rtp, dialog->rtpholdtimeout); 05226 ast_rtp_instance_set_keepalive(dialog->rtp, dialog->rtpkeepalive); 05227 05228 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_RTCP, 1); 05229 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 05230 ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05231 05232 ast_rtp_instance_set_qos(dialog->rtp, global_tos_audio, global_cos_audio, "SIP RTP"); 05233 05234 do_setnat(dialog); 05235 05236 return 0; 05237 }
static int dialog_needdestroy | ( | void * | dialogobj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Match dialogs that need to be destroyed.
This is used with ao2_callback to unlink/delete all dialogs that are marked needdestroy.
Definition at line 16961 of file chan_sip.c.
References ao2_t_link, ast_debug, ast_rtp_instance_get_bridged(), check_rtp_timeout(), dialogs_to_destroy, sip_methods, sip_pvt_trylock, sip_pvt_unlock, and cfsip_methods::text.
Referenced by do_monitor().
16962 { 16963 struct sip_pvt *dialog = dialogobj; 16964 time_t *t = arg; 16965 16966 if (sip_pvt_trylock(dialog)) { 16967 /* Don't block the monitor thread. This function is called often enough 16968 * that we can wait for the next time around. */ 16969 return 0; 16970 } 16971 16972 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 16973 check_rtp_timeout(dialog, *t); 16974 16975 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 16976 if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) { 16977 ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 16978 sip_pvt_unlock(dialog); 16979 return 0; 16980 } 16981 16982 if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) { 16983 ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 16984 sip_pvt_unlock(dialog); 16985 return 0; 16986 } 16987 16988 /* If we have sessions that needs to be destroyed, do it now */ 16989 /* Check if we have outstanding requests not responsed to or an active call 16990 - if that's the case, wait with destruction */ 16991 if (dialog->needdestroy && !dialog->packets && !dialog->owner) { 16992 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 16993 if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) { 16994 ast_debug(2, "Bridge still active. Delaying destruction of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 16995 sip_pvt_unlock(dialog); 16996 return 0; 16997 } 16998 16999 if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) { 17000 ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text); 17001 sip_pvt_unlock(dialog); 17002 return 0; 17003 } 17004 17005 sip_pvt_unlock(dialog); 17006 17007 /* This dialog needs to be destroyed. */ 17008 ao2_t_link(dialogs_to_destroy, dialog, "Link dialog for destruction"); 17009 return 0; 17010 } 17011 17012 sip_pvt_unlock(dialog); 17013 17014 return 0; 17015 }
struct sip_pvt* dialog_ref_debug | ( | struct sip_pvt * | p, | |
char * | tag, | |||
char * | file, | |||
int | line, | |||
const char * | func | |||
) |
Definition at line 2221 of file chan_sip.c.
References __ao2_ref_debug(), ao2_ref, ast_log(), and LOG_ERROR.
02222 { 02223 if (p) 02224 #ifdef REF_DEBUG 02225 __ao2_ref_debug(p, 1, tag, file, line, func); 02226 #else 02227 ao2_ref(p, 1); 02228 #endif 02229 else 02230 ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n"); 02231 return p; 02232 }
void dialog_unlink_all | ( | struct sip_pvt * | dialog | ) |
Unlink a dialog from the dialogs container, as well as any other places that it may be currently stored.
Definition at line 2951 of file chan_sip.c.
References ao2_t_unlink, ast_channel_unlock, ast_channel_unref, ast_debug, ast_extension_state_del(), ast_free, AST_SCHED_DEL, AST_SCHED_DEL_UNREF, cb_extensionstate(), dialogs, ast_channel::name, registry_unref(), sip_pvt_lock_full(), sip_pvt_unlock, stop_session_timer(), and ast_channel::tech_pvt.
Referenced by __sip_autodestruct(), __sip_subscribe_mwi_do(), cleanup_all_regs(), dialog_unlink_callback(), handle_request_subscribe(), manager_sipnotify(), sip_cli_notify(), sip_destroy_peer(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), transmit_register(), and unload_module().
02952 { 02953 struct sip_pkt *cp; 02954 struct ast_channel *owner; 02955 02956 dialog_ref(dialog, "Let's bump the count in the unlink so it doesn't accidentally become dead before we are done"); 02957 02958 ao2_t_unlink(dialogs, dialog, "unlinking dialog via ao2_unlink"); 02959 02960 /* Unlink us from the owner (channel) if we have one */ 02961 owner = sip_pvt_lock_full(dialog); 02962 if (owner) { 02963 ast_debug(1, "Detaching from channel %s\n", owner->name); 02964 owner->tech_pvt = dialog_unref(owner->tech_pvt, "resetting channel dialog ptr in unlink_all"); 02965 ast_channel_unlock(owner); 02966 ast_channel_unref(owner); 02967 dialog->owner = NULL; 02968 } 02969 sip_pvt_unlock(dialog); 02970 02971 if (dialog->registry) { 02972 if (dialog->registry->call == dialog) { 02973 dialog->registry->call = dialog_unref(dialog->registry->call, "nulling out the registry's call dialog field in unlink_all"); 02974 } 02975 dialog->registry = registry_unref(dialog->registry, "delete dialog->registry"); 02976 } 02977 if (dialog->stateid != -1) { 02978 ast_extension_state_del(dialog->stateid, cb_extensionstate); 02979 dialog->stateid = -1; 02980 } 02981 /* Remove link from peer to subscription of MWI */ 02982 if (dialog->relatedpeer && dialog->relatedpeer->mwipvt == dialog) { 02983 dialog->relatedpeer->mwipvt = dialog_unref(dialog->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt"); 02984 } 02985 if (dialog->relatedpeer && dialog->relatedpeer->call == dialog) { 02986 dialog->relatedpeer->call = dialog_unref(dialog->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself"); 02987 } 02988 02989 /* remove all current packets in this dialog */ 02990 while((cp = dialog->packets)) { 02991 dialog->packets = dialog->packets->next; 02992 AST_SCHED_DEL(sched, cp->retransid); 02993 dialog_unref(cp->owner, "remove all current packets in this dialog, and the pointer to the dialog too as part of __sip_destroy"); 02994 if (cp->data) { 02995 ast_free(cp->data); 02996 } 02997 ast_free(cp); 02998 } 02999 03000 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")); 03001 03002 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")); 03003 03004 if (dialog->autokillid > -1) { 03005 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")); 03006 } 03007 03008 if (dialog->request_queue_sched_id > -1) { 03009 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")); 03010 } 03011 03012 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")); 03013 03014 if (dialog->t38id > -1) { 03015 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")); 03016 } 03017 03018 if (dialog->stimer) { 03019 stop_session_timer(dialog); 03020 } 03021 03022 dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time"); 03023 }
static int dialog_unlink_callback | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 17027 of file chan_sip.c.
References CMP_MATCH, and dialog_unlink_all().
Referenced by do_monitor().
17028 { 17029 struct sip_pvt *dialog = obj; 17030 17031 dialog_unlink_all(dialog); 17032 17033 return CMP_MATCH; 17034 }
struct sip_pvt* dialog_unref_debug | ( | struct sip_pvt * | p, | |
char * | tag, | |||
char * | file, | |||
int | line, | |||
const char * | func | |||
) |
Definition at line 2234 of file chan_sip.c.
References __ao2_ref_debug(), and ao2_ref.
02235 { 02236 if (p) 02237 #ifdef REF_DEBUG 02238 __ao2_ref_debug(p, -1, tag, file, line, func); 02239 #else 02240 ao2_ref(p, -1); 02241 #endif 02242 return NULL; 02243 }
static void disable_dsp_detect | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 4270 of file chan_sip.c.
References ast_dsp_free().
Referenced by sip_dtmfmode(), sip_hangup(), and sip_setoption().
04271 { 04272 if (p->dsp) { 04273 ast_dsp_free(p->dsp); 04274 p->dsp = NULL; 04275 } 04276 }
static void display_nat_warning | ( | const char * | cat, | |
int | reason, | |||
struct ast_flags * | flags | |||
) | [static] |
Definition at line 27823 of file chan_sip.c.
References AST_CLI_YESNO, ast_log(), ast_test_flag, CHANNEL_MODULE_LOAD, global_flags, and LOG_WARNING.
27823 { 27824 int global_nat, specific_nat; 27825 27826 if (reason == CHANNEL_MODULE_LOAD && (specific_nat = ast_test_flag(&flags[0], SIP_NAT_FORCE_RPORT)) != (global_nat = ast_test_flag(&global_flags[0], SIP_NAT_FORCE_RPORT))) { 27827 ast_log(LOG_WARNING, "!!! PLEASE NOTE: Setting 'nat' for a peer/user that differs from the global setting can make\n"); 27828 ast_log(LOG_WARNING, "!!! the name of that peer/user discoverable by an attacker. Replies for non-existent peers/users\n"); 27829 ast_log(LOG_WARNING, "!!! will be sent to a different port than replies for an existing peer/user. If at all possible,\n"); 27830 ast_log(LOG_WARNING, "!!! use the global 'nat' setting and do not set 'nat' per peer/user.\n"); 27831 ast_log(LOG_WARNING, "!!! (config category='%s' global force_rport='%s' peer/user force_rport='%s')\n", cat, AST_CLI_YESNO(global_nat), AST_CLI_YESNO(specific_nat)); 27832 } 27833 }
static int do_magic_pickup | ( | struct ast_channel * | channel, | |
const char * | extension, | |||
const char * | context | |||
) | [static] |
Definition at line 22045 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().
22046 { 22047 struct ast_str *str = ast_str_alloca(AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2); 22048 struct ast_app *pickup = pbx_findapp("Pickup"); 22049 22050 if (!pickup) { 22051 ast_log(LOG_ERROR, "Unable to perform pickup: Application 'Pickup' not loaded (app_directed_pickup.so).\n"); 22052 return -1; 22053 } 22054 22055 ast_str_set(&str, 0, "%s@%s", extension, sip_cfg.notifycid == IGNORE_CONTEXT ? "PICKUPMARK" : context); 22056 22057 ast_debug(2, "About to call Pickup(%s)\n", str->str); 22058 22059 /* There is no point in capturing the return value since pickup_exec 22060 doesn't return anything meaningful unless the passed data is an empty 22061 string (which in our case it will not be) */ 22062 pbx_exec(channel, pickup, str->str); 22063 22064 return 0; 22065 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 25707 of file chan_sip.c.
References ao2_container_count(), ao2_t_callback, ast_debug, ast_io_add(), ast_io_change(), AST_IO_IN, ast_io_remove(), ast_io_wait(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_runq(), ast_sched_wait(), ast_verb, config, dialog_needdestroy(), dialog_unlink_callback(), dialogs, dialogs_to_destroy, FALSE, global_store_sip_cause, io, LOG_WARNING, monlock, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, sip_do_reload(), sip_reload_lock, sip_reloading, sip_reloadreason, sipsock, sipsock_read(), and sipsock_read_id.
25708 { 25709 int res; 25710 time_t t; 25711 int reloading; 25712 25713 /* Add an I/O event to our SIP UDP socket */ 25714 if (sipsock > -1) 25715 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 25716 25717 /* From here on out, we die whenever asked */ 25718 for(;;) { 25719 /* Check for a reload request */ 25720 ast_mutex_lock(&sip_reload_lock); 25721 reloading = sip_reloading; 25722 sip_reloading = FALSE; 25723 ast_mutex_unlock(&sip_reload_lock); 25724 if (reloading) { 25725 ast_verb(1, "Reloading SIP\n"); 25726 sip_do_reload(sip_reloadreason); 25727 25728 /* Change the I/O fd of our UDP socket */ 25729 if (sipsock > -1) { 25730 if (sipsock_read_id) 25731 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 25732 else 25733 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 25734 } else if (sipsock_read_id) { 25735 ast_io_remove(io, sipsock_read_id); 25736 sipsock_read_id = NULL; 25737 } 25738 } 25739 25740 /* Check for dialogs needing to be killed */ 25741 t = time(NULL); 25742 /* don't scan the dialogs list if it hasn't been a reasonable period 25743 of time since the last time we did it (when MWI is being sent, we can 25744 get back to this point every millisecond or less) 25745 */ 25746 /* 25747 * We cannot hold the dialogs container lock when we destroy a 25748 * dialog because of potential deadlocks. Instead we link the 25749 * doomed dialog into dialogs_to_destroy and then iterate over 25750 * that container destroying the dialogs. 25751 */ 25752 ao2_t_callback(dialogs, OBJ_NODATA | OBJ_MULTIPLE, dialog_needdestroy, &t, 25753 "callback to monitor dialog status"); 25754 if (ao2_container_count(dialogs_to_destroy)) { 25755 /* Now destroy the found dialogs that need to be destroyed. */ 25756 ao2_t_callback(dialogs_to_destroy, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, 25757 dialog_unlink_callback, NULL, "callback to dialog_unlink_all"); 25758 } 25759 25760 /* XXX TODO The scheduler usage in this module does not have sufficient 25761 * synchronization being done between running the scheduler and places 25762 * scheduling tasks. As it is written, any scheduled item may not run 25763 * any sooner than about 1 second, regardless of whether a sooner time 25764 * was asked for. */ 25765 25766 pthread_testcancel(); 25767 /* Wait for sched or io */ 25768 res = ast_sched_wait(sched); 25769 if ((res < 0) || (res > 1000)) 25770 res = 1000; 25771 res = ast_io_wait(io, res); 25772 if (res > 20) 25773 ast_debug(1, "chan_sip: ast_io_wait ran %d all at once\n", res); 25774 ast_mutex_lock(&monlock); 25775 res = ast_sched_runq(sched); 25776 if (res >= 20) 25777 ast_debug(1, "chan_sip: ast_sched_runq ran %d all at once\n", res); 25778 if (global_store_sip_cause && res >= 100) 25779 ast_log(LOG_WARNING, "scheduler delays detected, setting 'storesipcause' to 'no' in %s will improve performance\n", config); 25780 ast_mutex_unlock(&monlock); 25781 } 25782 25783 /* Never reached */ 25784 return NULL; 25785 }
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 19089 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().
19090 { 19091 char *header, *respheader; 19092 char digest[1024]; 19093 19094 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 19095 return -2; 19096 19097 p->authtries++; 19098 auth_headers(code, &header, &respheader); 19099 ast_debug(2, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 19100 memset(digest, 0, sizeof(digest)); 19101 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 19102 /* No way to authenticate */ 19103 return -1; 19104 } 19105 /* Now we have a reply digest */ 19106 p->options->auth = digest; 19107 p->options->authheader = respheader; 19108 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init, NULL); 19109 }
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 19065 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().
19066 { 19067 char *header, *respheader; 19068 char digest[1024]; 19069 19070 p->authtries++; 19071 auth_headers(code, &header, &respheader); 19072 memset(digest, 0, sizeof(digest)); 19073 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 19074 /* There's nothing to use for authentication */ 19075 /* No digest challenge in request */ 19076 if (sip_debug_test_pvt(p) && p->registry) 19077 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 19078 /* No old challenge */ 19079 return -1; 19080 } 19081 if (p->do_history) 19082 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 19083 if (sip_debug_test_pvt(p) && p->registry) 19084 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 19085 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 19086 }
static void do_setnat | ( | struct sip_pvt * | p | ) | [static] |
Set nat mode on the various data sockets.
Definition at line 5083 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().
05084 { 05085 const char *mode; 05086 int natflags; 05087 05088 natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP); 05089 mode = natflags ? "On" : "Off"; 05090 05091 if (p->rtp) { 05092 ast_debug(1, "Setting NAT on RTP to %s\n", mode); 05093 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_NAT, natflags); 05094 } 05095 if (p->vrtp) { 05096 ast_debug(1, "Setting NAT on VRTP to %s\n", mode); 05097 ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_NAT, natflags); 05098 } 05099 if (p->udptl) { 05100 ast_debug(1, "Setting NAT on UDPTL to %s\n", mode); 05101 ast_udptl_setnat(p->udptl, natflags); 05102 } 05103 if (p->trtp) { 05104 ast_debug(1, "Setting NAT on TRTP to %s\n", mode); 05105 ast_rtp_instance_set_prop(p->trtp, AST_RTP_PROPERTY_NAT, natflags); 05106 } 05107 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 17196 of file chan_sip.c.
Referenced by sip_show_domains().
17197 { 17198 switch (mode) { 17199 case SIP_DOMAIN_AUTO: 17200 return "[Automatic]"; 17201 case SIP_DOMAIN_CONFIG: 17202 return "[Configured]"; 17203 } 17204 17205 return ""; 17206 }
static const char * dtmfmode2str | ( | int | mode | ) | const [static] |
Convert DTMF mode to printable string.
Definition at line 16887 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 4236 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().
04237 { 04238 int features = 0; 04239 04240 if (p->dsp) { 04241 return; 04242 } 04243 04244 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 04245 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 04246 if (p->rtp) { 04247 ast_rtp_instance_dtmf_mode_set(p->rtp, AST_RTP_DTMF_MODE_INBAND); 04248 } 04249 features |= DSP_FEATURE_DIGIT_DETECT; 04250 } 04251 04252 if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) { 04253 features |= DSP_FEATURE_FAX_DETECT; 04254 } 04255 04256 if (!features) { 04257 return; 04258 } 04259 04260 if (!(p->dsp = ast_dsp_new())) { 04261 return; 04262 } 04263 04264 ast_dsp_set_features(p->dsp, features); 04265 if (global_relaxdtmf) { 04266 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04267 } 04268 }
static int esc_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 991 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by initialize_escs().
00992 { 00993 struct sip_esc_entry *entry1 = obj; 00994 struct sip_esc_entry *entry2 = arg; 00995 00996 return (!strcmp(entry1->entity_tag, entry2->entity_tag)) ? (CMP_MATCH | CMP_STOP) : 0; 00997 }
static void esc_entry_destructor | ( | void * | obj | ) | [static] |
Definition at line 977 of file chan_sip.c.
References AST_SCHED_DEL, and sched.
Referenced by create_esc_entry().
00978 { 00979 struct sip_esc_entry *esc_entry = obj; 00980 if (esc_entry->sched_id > -1) { 00981 AST_SCHED_DEL(sched, esc_entry->sched_id); 00982 } 00983 }
static int esc_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 985 of file chan_sip.c.
References ast_str_hash().
Referenced by initialize_escs().
00986 { 00987 const struct sip_esc_entry *entry = obj; 00988 return ast_str_hash(entry->entity_tag); 00989 }
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 13684 of file chan_sip.c.
References ao2_ref, ao2_t_unlink, ast_debug, AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_sockaddr_isnull(), ast_test_flag, destroy_association(), EVENT_FLAG_SYSTEM, FALSE, manager_event, peers_by_ip, 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().
13685 { 13686 struct sip_peer *peer = (struct sip_peer *)data; 13687 13688 if (!peer) { /* Hmmm. We have no peer. Weird. */ 13689 return 0; 13690 } 13691 13692 peer->expire = -1; 13693 peer->portinuri = 0; 13694 13695 destroy_association(peer); /* remove registration data from storage */ 13696 set_socket_transport(&peer->socket, peer->default_outbound_transport); 13697 13698 if (peer->socket.tcptls_session) { 13699 ao2_ref(peer->socket.tcptls_session, -1); 13700 peer->socket.tcptls_session = NULL; 13701 } 13702 13703 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 13704 register_peer_exten(peer, FALSE); /* Remove regexten */ 13705 ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name); 13706 13707 /* Do we need to release this peer from memory? 13708 Only for realtime peers and autocreated peers 13709 */ 13710 if (peer->is_realtime) { 13711 ast_debug(3, "-REALTIME- peer expired registration. Name: %s. Realtime peer objects now %d\n", peer->name, rpeerobjs); 13712 } 13713 13714 if (peer->selfdestruct || 13715 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 13716 unlink_peer_from_tables(peer); 13717 } else if (!ast_sockaddr_isnull(&peer->addr)) { 13718 /* If we aren't self-destructing a temp_peer, we still need to unlink the peer 13719 * from the peers_by_ip table, otherwise we end up with multiple copies hanging 13720 * around each time a registration expires and the peer re-registers. */ 13721 ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); 13722 } 13723 13724 /* Only clear the addr after we check for destruction. The addr must remain 13725 * in order to unlink from the peers_by_ip container correctly */ 13726 memset(&peer->addr, 0, sizeof(peer->addr)); 13727 13728 unref_peer(peer, "removing peer ref for expire_register"); 13729 13730 return 0; 13731 }
static void extract_host_from_hostport | ( | char ** | hostport | ) | [static] |
Terminate a host:port at the ':'.
hostport | The address of the hostport string |
Definition at line 14696 of file chan_sip.c.
References ast_sockaddr_split_hostport(), and PARSE_PORT_IGNORE.
Referenced by check_user_full(), get_destination(), and register_verify().
14697 { 14698 char *dont_care; 14699 ast_sockaddr_split_hostport(*hostport, hostport, &dont_care, PARSE_PORT_IGNORE); 14700 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 11870 of file chan_sip.c.
References ast_copy_string(), ast_string_field_set, ast_strlen_zero(), get_header(), get_in_brackets(), and remove_uri_parameters().
Referenced by handle_incoming(), and handle_request_invite().
11871 { 11872 char stripped[SIPBUFSIZE]; 11873 char *c; 11874 11875 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 11876 c = get_in_brackets(stripped); 11877 /* Cut the URI at the at sign after the @, not in the username part */ 11878 c = remove_uri_parameters(c); 11879 if (!ast_strlen_zero(c)) { 11880 ast_string_field_set(p, uri, c); 11881 } 11882 11883 }
static const char* faxec2str | ( | int | faxec | ) | [static] |
Definition at line 17360 of file chan_sip.c.
References faxecmodes, and map_x_s().
Referenced by _sip_show_peer(), and sip_show_settings().
17361 { 17362 return map_x_s(faxecmodes, faxec, "Unknown"); 17363 }
static int finalize_content | ( | struct sip_request * | req | ) | [static] |
Add 'Content-Length' header and content to SIP message.
Definition at line 9854 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().
09855 { 09856 char clen[10]; 09857 09858 if (req->lines) { 09859 ast_log(LOG_WARNING, "finalize_content() called on a message that has already been finalized\n"); 09860 return -1; 09861 } 09862 09863 snprintf(clen, sizeof(clen), "%zd", ast_str_strlen(req->content)); 09864 add_header(req, "Content-Length", clen); 09865 09866 if (ast_str_strlen(req->content)) { 09867 ast_str_append(&req->data, 0, "\r\n%s", ast_str_buffer(req->content)); 09868 } 09869 req->lines = ast_str_strlen(req->content) ? 1 : 0; 09870 return 0; 09871 }
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 7294 of file chan_sip.c.
References aliases, and ARRAY_LEN.
07295 { 07296 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 07297 static const struct cfalias { 07298 char * const fullname; 07299 char * const shortname; 07300 } aliases[] = { 07301 { "Content-Type", "c" }, 07302 { "Content-Encoding", "e" }, 07303 { "From", "f" }, 07304 { "Call-ID", "i" }, 07305 { "Contact", "m" }, 07306 { "Content-Length", "l" }, 07307 { "Subject", "s" }, 07308 { "To", "t" }, 07309 { "Supported", "k" }, 07310 { "Refer-To", "r" }, 07311 { "Referred-By", "b" }, 07312 { "Allow-Events", "u" }, 07313 { "Event", "o" }, 07314 { "Via", "v" }, 07315 { "Accept-Contact", "a" }, 07316 { "Reject-Contact", "j" }, 07317 { "Request-Disposition", "d" }, 07318 { "Session-Expires", "x" }, 07319 { "Identity", "y" }, 07320 { "Identity-Info", "n" }, 07321 }; 07322 int x; 07323 07324 for (x = 0; x < ARRAY_LEN(aliases); x++) { 07325 if (!strcasecmp(aliases[x].fullname, name)) 07326 return aliases[x].shortname; 07327 } 07328 07329 return _default; 07330 }
static int find_by_callid_helper | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1684 of file chan_sip.c.
References CMP_MATCH, CMP_STOP, and ast_cc_agent::private_data.
Referenced by find_sip_cc_agent_by_original_callid().
01685 { 01686 struct ast_cc_agent *agent = obj; 01687 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01688 struct sip_pvt *call_pvt = arg; 01689 01690 return !strcmp(agent_pvt->original_callid, call_pvt->callid) ? CMP_MATCH | CMP_STOP : 0; 01691 }
static int find_by_name | ( | void * | obj, | |
void * | arg, | |||
void * | data, | |||
int | flags | |||
) | [static] |
Definition at line 4994 of file chan_sip.c.
References CMP_MATCH, CMP_STOP, and match().
Referenced by ast_setlocale(), find_peer(), and store_by_locale().
04995 { 04996 struct sip_peer *search = obj, *match = arg; 04997 int *which_objects = data; 04998 04999 /* Usernames in SIP uri's are case sensitive. Domains are not */ 05000 if (strcmp(search->name, match->name)) { 05001 return 0; 05002 } 05003 05004 switch (*which_objects) { 05005 case FINDUSERS: 05006 if (!(search->type & SIP_TYPE_USER)) { 05007 return 0; 05008 } 05009 break; 05010 case FINDPEERS: 05011 if (!(search->type & SIP_TYPE_PEER)) { 05012 return 0; 05013 } 05014 break; 05015 case FINDALLDEVICES: 05016 break; 05017 } 05018 05019 return CMP_MATCH | CMP_STOP; 05020 }
static int find_by_notify_uri_helper | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1654 of file chan_sip.c.
References CMP_MATCH, CMP_STOP, ast_cc_agent::private_data, and sip_uri_cmp().
Referenced by find_sip_cc_agent_by_notify_uri().
01655 { 01656 struct ast_cc_agent *agent = obj; 01657 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01658 const char *uri = arg; 01659 01660 return !sip_uri_cmp(agent_pvt->notify_uri, uri) ? CMP_MATCH | CMP_STOP : 0; 01661 }
static int find_by_subscribe_uri_helper | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1669 of file chan_sip.c.
References CMP_MATCH, CMP_STOP, ast_cc_agent::private_data, and sip_uri_cmp().
Referenced by find_sip_cc_agent_by_subscribe_uri().
01670 { 01671 struct ast_cc_agent *agent = obj; 01672 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01673 const char *uri = arg; 01674 01675 return !sip_uri_cmp(agent_pvt->subscribe_uri, uri) ? CMP_MATCH | CMP_STOP : 0; 01676 }
static struct sip_pvt * find_call | ( | struct sip_request * | req, | |
struct ast_sockaddr * | addr, | |||
const int | intended_method | |||
) | [static] |
find or create a dialog structure for an incoming SIP message. Connect incoming SIP message to current dialog or create new dialog structure Returns a reference to the sip_pvt object, remember to give it back once done. Called by handle_request_do
Definition at line 8053 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, free_via(), get_header(), gettag(), match_req_to_dialog(), OBJ_MULTIPLE, OBJ_POINTER, parse_via(), sip_alloc(), sip_cfg, sip_methods, SIP_REQ_LOOP_DETECTED, SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, cfsip_methods::text, and transmit_response_using_temp().
Referenced by handle_request_do().
08054 { 08055 char totag[128]; 08056 char fromtag[128]; 08057 const char *callid = get_header(req, "Call-ID"); 08058 const char *from = get_header(req, "From"); 08059 const char *to = get_header(req, "To"); 08060 const char *cseq = get_header(req, "Cseq"); 08061 struct sip_pvt *sip_pvt_ptr; 08062 unsigned int seqno; 08063 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 08064 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 08065 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 08066 ast_strlen_zero(from) || ast_strlen_zero(cseq) || 08067 (sscanf(cseq, "%30u", &seqno) != 1)) { 08068 08069 /* RFC 3261 section 24.4.1. Send a 400 Bad Request if the request is malformed. */ 08070 if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 08071 transmit_response_using_temp(callid, addr, 1, intended_method, 08072 req, "400 Bad Request"); 08073 } 08074 return NULL; /* Invalid packet */ 08075 } 08076 08077 if (sip_cfg.pedanticsipchecking) { 08078 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 08079 we need more to identify a branch - so we have to check branch, from 08080 and to tags to identify a call leg. 08081 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 08082 in sip.conf 08083 */ 08084 if (gettag(req, "To", totag, sizeof(totag))) 08085 req->has_to_tag = 1; /* Used in handle_request/response */ 08086 gettag(req, "From", fromtag, sizeof(fromtag)); 08087 08088 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); 08089 08090 /* All messages must always have From: tag */ 08091 if (ast_strlen_zero(fromtag)) { 08092 ast_debug(5, "%s request has no from tag, dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from ); 08093 return NULL; 08094 } 08095 /* reject requests that must always have a To: tag */ 08096 if (ast_strlen_zero(totag) && (req->method == SIP_ACK || req->method == SIP_BYE || req->method == SIP_INFO )) { 08097 ast_debug(5, "%s must have a to tag. dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from ); 08098 return NULL; 08099 } 08100 } 08101 08102 if (!sip_cfg.pedanticsipchecking) { 08103 struct sip_pvt tmp_dialog = { 08104 .callid = callid, 08105 }; 08106 sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find in dialogs"); 08107 if (sip_pvt_ptr) { /* well, if we don't find it-- what IS in there? */ 08108 /* Found the call */ 08109 return sip_pvt_ptr; 08110 } 08111 } else { /* in pedantic mode! -- do the fancy search */ 08112 struct sip_pvt tmp_dialog = { 08113 .callid = callid, 08114 }; 08115 struct match_req_args args = { 0, }; 08116 int found; 08117 struct ao2_iterator *iterator = ao2_t_callback(dialogs, 08118 OBJ_POINTER | OBJ_MULTIPLE, 08119 dialog_find_multiple, 08120 &tmp_dialog, 08121 "pedantic ao2_find in dialogs"); 08122 struct sip_via *via = NULL; 08123 08124 args.method = req->method; 08125 args.callid = NULL; /* we already matched this. */ 08126 args.totag = totag; 08127 args.fromtag = fromtag; 08128 args.seqno = seqno; 08129 08130 /* If this is a Request, set the Via and Authorization header arguments */ 08131 if (req->method != SIP_RESPONSE) { 08132 args.ruri = REQ_OFFSET_TO_STR(req, rlPart2); 08133 via = parse_via(get_header(req, "Via")); 08134 if (via) { 08135 args.viasentby = via->sent_by; 08136 args.viabranch = via->branch; 08137 } 08138 if (!ast_strlen_zero(get_header(req, "Authorization")) || 08139 !ast_strlen_zero(get_header(req, "Proxy-Authorization"))) { 08140 args.authentication_present = 1; 08141 } 08142 } 08143 08144 /* Iterate a list of dialogs already matched by Call-id */ 08145 while (iterator && (sip_pvt_ptr = ao2_iterator_next(iterator))) { 08146 found = match_req_to_dialog(sip_pvt_ptr, &args); 08147 08148 switch (found) { 08149 case SIP_REQ_MATCH: 08150 ao2_iterator_destroy(iterator); 08151 free_via(via); 08152 return sip_pvt_ptr; /* return pvt with ref */ 08153 case SIP_REQ_LOOP_DETECTED: 08154 /* This is likely a forked Request that somehow resulted in us receiving multiple parts of the fork. 08155 * RFC 3261 section 8.2.2.2, Indicate that we want to merge requests by sending a 482 response. */ 08156 transmit_response_using_temp(callid, addr, 1, intended_method, req, "482 (Loop Detected)"); 08157 dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search."); 08158 ao2_iterator_destroy(iterator); 08159 free_via(via); 08160 return NULL; 08161 case SIP_REQ_NOT_MATCH: 08162 default: 08163 dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search"); 08164 } 08165 } 08166 if (iterator) { 08167 ao2_iterator_destroy(iterator); 08168 } 08169 08170 free_via(via); 08171 } /* end of pedantic mode Request/Reponse to Dialog matching */ 08172 08173 /* See if the method is capable of creating a dialog */ 08174 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 08175 struct sip_pvt *p = NULL; 08176 08177 if (intended_method == SIP_REFER) { 08178 /* We do support REFER, but not outside of a dialog yet */ 08179 transmit_response_using_temp(callid, addr, 1, intended_method, req, "603 Declined (no dialog)"); 08180 08181 /* Ok, time to create a new SIP dialog object, a pvt */ 08182 } else if (!(p = sip_alloc(callid, addr, 1, intended_method, req))) { 08183 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 08184 getting a dialog from sip_alloc. 08185 08186 Without a dialog we can't retransmit and handle ACKs and all that, but at least 08187 send an error message. 08188 08189 Sorry, we apologize for the inconvienience 08190 */ 08191 transmit_response_using_temp(callid, addr, 1, intended_method, req, "500 Server internal error"); 08192 ast_debug(4, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 08193 } 08194 return p; /* can be NULL */ 08195 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 08196 /* A method we do not support, let's take it on the volley */ 08197 transmit_response_using_temp(callid, addr, 1, intended_method, req, "501 Method Not Implemented"); 08198 ast_debug(2, "Got a request with unsupported SIP method.\n"); 08199 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 08200 /* This is a request outside of a dialog that we don't know about */ 08201 transmit_response_using_temp(callid, addr, 1, intended_method, req, "481 Call leg/transaction does not exist"); 08202 ast_debug(2, "That's odd... Got a request in unknown dialog. Callid %s\n", callid ? callid : "<unknown>"); 08203 } 08204 /* We do not respond to responses for dialogs that we don't know about, we just drop 08205 the session quickly */ 08206 if (intended_method == SIP_RESPONSE) 08207 ast_debug(2, "That's odd... Got a response on a call we don't know about. Callid %s\n", callid ? callid : "<unknown>"); 08208 08209 return NULL; 08210 }
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 12490 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().
12491 { 12492 struct ast_channel *c = obj; 12493 struct sip_pvt *p = data; 12494 int res; 12495 12496 ast_channel_lock(c); 12497 12498 res = (c->pbx && 12499 (!strcasecmp(c->macroexten, p->exten) || !strcasecmp(c->exten, p->exten)) && 12500 (sip_cfg.notifycid == IGNORE_CONTEXT || !strcasecmp(c->context, p->context))); 12501 12502 ast_channel_unlock(c); 12503 12504 return res ? CMP_MATCH | CMP_STOP : 0; 12505 }
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 4411 of file chan_sip.c.
Referenced by get_comma(), get_in_brackets_full(), and parse_moved_contact().
04412 { 04413 char last_char = '\0'; 04414 const char *s; 04415 for (s = start; *s && s != lim; last_char = *s++) { 04416 if (*s == '"' && last_char != '\\') 04417 break; 04418 } 04419 return s; 04420 }
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 5035 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().
05036 { 05037 struct sip_peer *p = NULL; 05038 struct sip_peer tmp_peer; 05039 05040 if (peer) { 05041 ast_copy_string(tmp_peer.name, peer, sizeof(tmp_peer.name)); 05042 p = ao2_t_callback_data(peers, OBJ_POINTER, find_by_name, &tmp_peer, &which_objects, "ao2_find in peers table"); 05043 } else if (addr) { /* search by addr? */ 05044 ast_sockaddr_copy(&tmp_peer.addr, addr); 05045 tmp_peer.flags[0].flags = 0; 05046 tmp_peer.transports = transport; 05047 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); */ 05048 if (!p) { 05049 ast_set_flag(&tmp_peer.flags[0], SIP_INSECURE_PORT); 05050 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); */ 05051 if (p) { 05052 return p; 05053 } 05054 } 05055 } 05056 05057 if (!p && (realtime || devstate_only)) { 05058 p = realtime_peer(peer, addr, devstate_only, which_objects); 05059 if (p) { 05060 switch (which_objects) { 05061 case FINDUSERS: 05062 if (!(p->type & SIP_TYPE_USER)) { 05063 unref_peer(p, "Wrong type of realtime SIP endpoint"); 05064 return NULL; 05065 } 05066 break; 05067 case FINDPEERS: 05068 if (!(p->type & SIP_TYPE_PEER)) { 05069 unref_peer(p, "Wrong type of realtime SIP endpoint"); 05070 return NULL; 05071 } 05072 break; 05073 case FINDALLDEVICES: 05074 break; 05075 } 05076 } 05077 } 05078 05079 return p; 05080 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth_container * | credentials, | |
const char * | realm | |||
) | [static] |
Definition at line 26964 of file chan_sip.c.
References AST_LIST_TRAVERSE.
Referenced by build_reply_digest().
26965 { 26966 struct sip_auth *auth; 26967 26968 if (credentials) { 26969 AST_LIST_TRAVERSE(&credentials->list, auth, node) { 26970 if (!strcasecmp(auth->realm, realm)) { 26971 break; 26972 } 26973 } 26974 } else { 26975 auth = NULL; 26976 } 26977 26978 return auth; 26979 }
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 8563 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().
08564 { 08565 const char *content_type; 08566 const char *content_length; 08567 const char *search; 08568 char *boundary; 08569 unsigned int x; 08570 int boundaryisquoted = FALSE; 08571 int found_application_sdp = FALSE; 08572 int found_end_of_headers = FALSE; 08573 08574 content_length = get_header(req, "Content-Length"); 08575 08576 if (!ast_strlen_zero(content_length)) { 08577 if (sscanf(content_length, "%30u", &x) != 1) { 08578 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 08579 return 0; 08580 } 08581 08582 /* Content-Length of zero means there can't possibly be an 08583 SDP here, even if the Content-Type says there is */ 08584 if (x == 0) 08585 return 0; 08586 } 08587 08588 content_type = get_header(req, "Content-Type"); 08589 08590 /* if the body contains only SDP, this is easy */ 08591 if (!strncasecmp(content_type, "application/sdp", 15)) { 08592 req->sdp_start = 0; 08593 req->sdp_count = req->lines; 08594 return req->lines ? 1 : 0; 08595 } 08596 08597 /* if it's not multipart/mixed, there cannot be an SDP */ 08598 if (strncasecmp(content_type, "multipart/mixed", 15)) 08599 return 0; 08600 08601 /* if there is no boundary marker, it's invalid */ 08602 if ((search = strcasestr(content_type, ";boundary="))) 08603 search += 10; 08604 else if ((search = strcasestr(content_type, "; boundary="))) 08605 search += 11; 08606 else 08607 return 0; 08608 08609 if (ast_strlen_zero(search)) 08610 return 0; 08611 08612 /* If the boundary is quoted with ", remove quote */ 08613 if (*search == '\"') { 08614 search++; 08615 boundaryisquoted = TRUE; 08616 } 08617 08618 /* make a duplicate of the string, with two extra characters 08619 at the beginning */ 08620 boundary = ast_strdupa(search - 2); 08621 boundary[0] = boundary[1] = '-'; 08622 /* Remove final quote */ 08623 if (boundaryisquoted) 08624 boundary[strlen(boundary) - 1] = '\0'; 08625 08626 /* search for the boundary marker, the empty line delimiting headers from 08627 sdp part and the end boundry if it exists */ 08628 08629 for (x = 0; x < (req->lines); x++) { 08630 const char *line = REQ_OFFSET_TO_STR(req, line[x]); 08631 if (!strncasecmp(line, boundary, strlen(boundary))){ 08632 if (found_application_sdp && found_end_of_headers) { 08633 req->sdp_count = (x - 1) - req->sdp_start; 08634 return 1; 08635 } 08636 found_application_sdp = FALSE; 08637 } 08638 if (!strcasecmp(line, "Content-Type: application/sdp")) 08639 found_application_sdp = TRUE; 08640 08641 if (ast_strlen_zero(line)) { 08642 if (found_application_sdp && !found_end_of_headers){ 08643 req->sdp_start = x; 08644 found_end_of_headers = TRUE; 08645 } 08646 } 08647 } 08648 if (found_application_sdp && found_end_of_headers) { 08649 req->sdp_count = x - req->sdp_start; 08650 return TRUE; 08651 } 08652 return FALSE; 08653 }
static struct ast_cc_agent* find_sip_cc_agent_by_notify_uri | ( | const char *const | uri | ) | [static] |
Definition at line 1663 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().
01664 { 01665 struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_notify_uri_helper, (char *)uri, "SIP"); 01666 return agent; 01667 }
static struct ast_cc_agent* find_sip_cc_agent_by_original_callid | ( | struct sip_pvt * | pvt | ) | [static] |
Definition at line 1693 of file chan_sip.c.
References ast_cc_agent_callback(), and find_by_callid_helper().
Referenced by add_cc_call_info_to_response().
01694 { 01695 struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_callid_helper, pvt, "SIP"); 01696 return agent; 01697 }
static struct ast_cc_agent* find_sip_cc_agent_by_subscribe_uri | ( | const char *const | uri | ) | [static] |
Definition at line 1678 of file chan_sip.c.
References ast_cc_agent_callback(), and find_by_subscribe_uri_helper().
Referenced by cc_esc_publish_handler(), and handle_cc_subscribe().
01679 { 01680 struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_subscribe_uri_helper, (char *)uri, "SIP"); 01681 return agent; 01682 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 3165 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().
03166 { 03167 int i, res = 0; 03168 03169 if (ast_strlen_zero(msg)) { 03170 return 0; 03171 } 03172 for (i = 1; i < ARRAY_LEN(sip_methods) && !res; i++) { 03173 if (method_match(i, msg)) { 03174 res = sip_methods[i].id; 03175 } 03176 } 03177 return res; 03178 }
static int find_sip_monitor_instance_by_subscription_pvt | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1891 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by handle_cc_notify(), and handle_response_subscribe().
01892 { 01893 struct sip_monitor_instance *monitor_instance = obj; 01894 return monitor_instance->subscription_pvt == arg ? CMP_MATCH | CMP_STOP : 0; 01895 }
static int find_sip_monitor_instance_by_suspension_entry | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1897 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by cc_handle_publish_error().
01898 { 01899 struct sip_monitor_instance *monitor_instance = obj; 01900 return monitor_instance->suspension_entry == arg ? CMP_MATCH | CMP_STOP : 0; 01901 }
static struct epa_static_data* find_static_data | ( | const char *const | event_package | ) | [static] |
Definition at line 905 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.
Referenced by create_epa_entry().
00906 { 00907 const struct epa_backend *backend = NULL; 00908 00909 AST_LIST_LOCK(&epa_static_data_list); 00910 AST_LIST_TRAVERSE(&epa_static_data_list, backend, next) { 00911 if (!strcmp(backend->static_data->name, event_package)) { 00912 break; 00913 } 00914 } 00915 AST_LIST_UNLOCK(&epa_static_data_list); 00916 return backend ? backend->static_data : NULL; 00917 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static] |
Find subscription type in array.
Definition at line 18250 of file chan_sip.c.
References ARRAY_LEN, subscription_types, and type.
Referenced by transmit_state_notify().
18251 { 18252 int i; 18253 18254 for (i = 1; i < ARRAY_LEN(subscription_types); i++) { 18255 if (subscription_types[i].type == subtype) { 18256 return &subscription_types[i]; 18257 } 18258 } 18259 return &subscription_types[0]; 18260 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 14139 of file chan_sip.c.
References ast_free.
Referenced by __sip_destroy(), and build_route().
14140 { 14141 struct sip_route *next; 14142 14143 while (route) { 14144 next = route->next; 14145 ast_free(route); 14146 route = next; 14147 } 14148 }
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 19355 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.
19356 { 19357 if (ast_strlen_zero(data)) { 19358 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 19359 return -1; 19360 } 19361 if (check_sip_domain(data, NULL, 0)) 19362 ast_copy_string(buf, data, len); 19363 else 19364 buf[0] = '\0'; 19365 return 0; 19366 }
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 19296 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.
19297 { 19298 struct sip_pvt *p; 19299 const char *content = NULL; 19300 AST_DECLARE_APP_ARGS(args, 19301 AST_APP_ARG(header); 19302 AST_APP_ARG(number); 19303 ); 19304 int i, number, start = 0; 19305 19306 if (ast_strlen_zero(data)) { 19307 ast_log(LOG_WARNING, "This function requires a header name.\n"); 19308 return -1; 19309 } 19310 19311 ast_channel_lock(chan); 19312 if (!IS_SIP_TECH(chan->tech)) { 19313 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 19314 ast_channel_unlock(chan); 19315 return -1; 19316 } 19317 19318 AST_STANDARD_APP_ARGS(args, data); 19319 if (!args.number) { 19320 number = 1; 19321 } else { 19322 sscanf(args.number, "%30d", &number); 19323 if (number < 1) 19324 number = 1; 19325 } 19326 19327 p = chan->tech_pvt; 19328 19329 /* If there is no private structure, this channel is no longer alive */ 19330 if (!p) { 19331 ast_channel_unlock(chan); 19332 return -1; 19333 } 19334 19335 for (i = 0; i < number; i++) 19336 content = __get_header(&p->initreq, args.header, &start); 19337 19338 if (ast_strlen_zero(content)) { 19339 ast_channel_unlock(chan); 19340 return -1; 19341 } 19342 19343 ast_copy_string(buf, content, len); 19344 ast_channel_unlock(chan); 19345 19346 return 0; 19347 }
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 19473 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.
19474 { 19475 struct sip_pvt *p; 19476 static int deprecated = 0; 19477 19478 *buf = 0; 19479 19480 if (!data) { 19481 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 19482 return -1; 19483 } 19484 19485 ast_channel_lock(chan); 19486 if (!IS_SIP_TECH(chan->tech)) { 19487 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 19488 ast_channel_unlock(chan); 19489 return -1; 19490 } 19491 19492 if (deprecated++ % 20 == 0) { 19493 /* Deprecated in 1.6.1 */ 19494 ast_log(LOG_WARNING, "SIPCHANINFO() is deprecated. Please transition to using CHANNEL().\n"); 19495 } 19496 19497 p = chan->tech_pvt; 19498 19499 /* If there is no private structure, this channel is no longer alive */ 19500 if (!p) { 19501 ast_channel_unlock(chan); 19502 return -1; 19503 } 19504 19505 if (!strcasecmp(data, "peerip")) { 19506 ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->sa), len); 19507 } else if (!strcasecmp(data, "recvip")) { 19508 ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->recv), len); 19509 } else if (!strcasecmp(data, "from")) { 19510 ast_copy_string(buf, p->from, len); 19511 } else if (!strcasecmp(data, "uri")) { 19512 ast_copy_string(buf, p->uri, len); 19513 } else if (!strcasecmp(data, "useragent")) { 19514 ast_copy_string(buf, p->useragent, len); 19515 } else if (!strcasecmp(data, "peername")) { 19516 ast_copy_string(buf, p->peername, len); 19517 } else if (!strcasecmp(data, "t38passthrough")) { 19518 if (p->t38.state == T38_DISABLED) { 19519 ast_copy_string(buf, "0", len); 19520 } else { /* T38 is offered or enabled in this call */ 19521 ast_copy_string(buf, "1", len); 19522 } 19523 } else { 19524 ast_channel_unlock(chan); 19525 return -1; 19526 } 19527 ast_channel_unlock(chan); 19528 19529 return 0; 19530 }
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 19374 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.
19375 { 19376 struct sip_peer *peer; 19377 char *colname; 19378 19379 if ((colname = strchr(data, ':'))) { /*! \todo Will be deprecated after 1.4 */ 19380 static int deprecation_warning = 0; 19381 *colname++ = '\0'; 19382 if (deprecation_warning++ % 10 == 0) 19383 ast_log(LOG_WARNING, "SIPPEER(): usage of ':' to separate arguments is deprecated. Please use ',' instead.\n"); 19384 } else if ((colname = strchr(data, ','))) 19385 *colname++ = '\0'; 19386 else 19387 colname = "ip"; 19388 19389 if (!(peer = find_peer(data, NULL, TRUE, FINDPEERS, FALSE, 0))) 19390 return -1; 19391 19392 if (!strcasecmp(colname, "ip")) { 19393 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len); 19394 } else if (!strcasecmp(colname, "port")) { 19395 snprintf(buf, len, "%d", ast_sockaddr_port(&peer->addr)); 19396 } else if (!strcasecmp(colname, "status")) { 19397 peer_status(peer, buf, len); 19398 } else if (!strcasecmp(colname, "language")) { 19399 ast_copy_string(buf, peer->language, len); 19400 } else if (!strcasecmp(colname, "regexten")) { 19401 ast_copy_string(buf, peer->regexten, len); 19402 } else if (!strcasecmp(colname, "limit")) { 19403 snprintf(buf, len, "%d", peer->call_limit); 19404 } else if (!strcasecmp(colname, "busylevel")) { 19405 snprintf(buf, len, "%d", peer->busy_level); 19406 } else if (!strcasecmp(colname, "curcalls")) { 19407 snprintf(buf, len, "%d", peer->inUse); 19408 } else if (!strcasecmp(colname, "maxforwards")) { 19409 snprintf(buf, len, "%d", peer->maxforwards); 19410 } else if (!strcasecmp(colname, "accountcode")) { 19411 ast_copy_string(buf, peer->accountcode, len); 19412 } else if (!strcasecmp(colname, "callgroup")) { 19413 ast_print_group(buf, len, peer->callgroup); 19414 } else if (!strcasecmp(colname, "pickupgroup")) { 19415 ast_print_group(buf, len, peer->pickupgroup); 19416 } else if (!strcasecmp(colname, "useragent")) { 19417 ast_copy_string(buf, peer->useragent, len); 19418 } else if (!strcasecmp(colname, "mailbox")) { 19419 struct ast_str *mailbox_str = ast_str_alloca(512); 19420 peer_mailboxes_to_str(&mailbox_str, peer); 19421 ast_copy_string(buf, mailbox_str->str, len); 19422 } else if (!strcasecmp(colname, "context")) { 19423 ast_copy_string(buf, peer->context, len); 19424 } else if (!strcasecmp(colname, "expire")) { 19425 snprintf(buf, len, "%d", peer->expire); 19426 } else if (!strcasecmp(colname, "dynamic")) { 19427 ast_copy_string(buf, peer->host_dynamic ? "yes" : "no", len); 19428 } else if (!strcasecmp(colname, "callerid_name")) { 19429 ast_copy_string(buf, peer->cid_name, len); 19430 } else if (!strcasecmp(colname, "callerid_num")) { 19431 ast_copy_string(buf, peer->cid_num, len); 19432 } else if (!strcasecmp(colname, "codecs")) { 19433 ast_getformatname_multiple(buf, len -1, peer->capability); 19434 } else if (!strcasecmp(colname, "encryption")) { 19435 snprintf(buf, len, "%d", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP)); 19436 } else if (!strncasecmp(colname, "chanvar[", 8)) { 19437 char *chanvar=colname + 8; 19438 struct ast_variable *v; 19439 19440 chanvar = strsep(&chanvar, "]"); 19441 for (v = peer->chanvars ; v ; v = v->next) { 19442 if (!strcasecmp(v->name, chanvar)) { 19443 ast_copy_string(buf, v->value, len); 19444 } 19445 } 19446 } else if (!strncasecmp(colname, "codec[", 6)) { 19447 char *codecnum; 19448 format_t codec = 0; 19449 19450 codecnum = colname + 6; /* move past the '[' */ 19451 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 19452 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) { 19453 ast_copy_string(buf, ast_getformatname(codec), len); 19454 } else { 19455 buf[0] = '\0'; 19456 } 19457 } else { 19458 buf[0] = '\0'; 19459 } 19460 19461 unref_peer(peer, "unref_peer from function_sippeer, just before return"); 19462 19463 return 0; 19464 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 7518 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().
07519 { 07520 long val[4]; 07521 int x; 07522 07523 for (x=0; x<4; x++) 07524 val[x] = ast_random(); 07525 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 07526 07527 return buf; 07528 }
static char* generate_uri | ( | struct sip_pvt * | pvt, | |
char * | buf, | |||
size_t | size | |||
) | [static] |
Definition at line 7530 of file chan_sip.c.
References ast_copy_string(), ast_sockaddr_stringify_remote(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), and generate_random_string().
Referenced by add_cc_call_info_to_response(), and transmit_cc_notify().
07531 { 07532 struct ast_str *uri = ast_str_alloca(size); 07533 ast_str_set(&uri, 0, "%s", pvt->socket.type == SIP_TRANSPORT_TLS ? "sips:" : "sip:"); 07534 /* Here would be a great place to generate a UUID, but for now we'll 07535 * use the handy random string generation function we already have 07536 */ 07537 ast_str_append(&uri, 0, "%s", generate_random_string(buf, size)); 07538 ast_str_append(&uri, 0, "@%s", ast_sockaddr_stringify_remote(&pvt->ourip)); 07539 ast_copy_string(buf, ast_str_buffer(uri), size); 07540 return buf; 07541 }
int get_address_family_filter | ( | const struct ast_sockaddr * | addr | ) | [static] |
Helper for dns resolution to filter by address family.
Definition at line 25379 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_by_name(), and transmit_register().
25380 { 25381 if (ast_sockaddr_is_ipv6(addr) && ast_sockaddr_is_any(addr)) { 25382 return 0; 25383 } 25384 25385 return addr->ss.ss_family; 25386 }
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 15738 of file chan_sip.c.
References ast_canmatch_extension(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_verbose, context, get_header(), get_in_brackets(), LOG_WARNING, parse_uri_legacy_check(), pbx_builtin_getvar_helper(), S_OR, sip_cfg, sip_debug_test_pvt(), SIP_PEDANTIC_DECODE, and sip_refer_allocate().
Referenced by handle_request_bye().
15739 { 15740 char tmp[256] = "", *c, *a; 15741 struct sip_request *req = oreq ? oreq : &p->initreq; 15742 struct sip_refer *referdata = NULL; 15743 const char *transfer_context = NULL; 15744 15745 if (!p->refer && !sip_refer_allocate(p)) 15746 return -1; 15747 15748 referdata = p->refer; 15749 15750 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 15751 c = get_in_brackets(tmp); 15752 15753 if (parse_uri_legacy_check(c, "sip:,sips:", &c, NULL, &a, NULL)) { 15754 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 15755 return -1; 15756 } 15757 15758 SIP_PEDANTIC_DECODE(c); 15759 SIP_PEDANTIC_DECODE(a); 15760 15761 if (!ast_strlen_zero(a)) { 15762 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 15763 } 15764 15765 if (sip_debug_test_pvt(p)) 15766 ast_verbose("Looking for %s in %s\n", c, p->context); 15767 15768 if (p->owner) /* Mimic behaviour in res_features.c */ 15769 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 15770 15771 /* By default, use the context in the channel sending the REFER */ 15772 if (ast_strlen_zero(transfer_context)) { 15773 transfer_context = S_OR(p->owner->macrocontext, 15774 S_OR(p->context, sip_cfg.default_context)); 15775 } 15776 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 15777 /* This is a blind transfer */ 15778 ast_debug(1, "SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 15779 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 15780 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 15781 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 15782 referdata->refer_call = dialog_unref(referdata->refer_call, "unreffing referdata->refer_call"); 15783 /* Set new context */ 15784 ast_string_field_set(p, context, transfer_context); 15785 return 0; 15786 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 15787 return 1; 15788 } 15789 15790 return -1; 15791 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name, | |||
char | delimiter | |||
) | [static] |
Get a specific line from the message body.
Definition at line 7278 of file chan_sip.c.
References get_body_by_line(), and len().
Referenced by handle_cc_notify(), handle_request_info(), and handle_request_notify().
07279 { 07280 int x; 07281 int len = strlen(name); 07282 char *r; 07283 07284 for (x = 0; x < req->lines; x++) { 07285 r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[x]), name, len, delimiter); 07286 if (r[0] != '\0') 07287 return r; 07288 } 07289 07290 return ""; 07291 }
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 7223 of file chan_sip.c.
References ast_skip_blanks().
Referenced by get_body(), and get_sdp_iterate().
07224 { 07225 if (!strncasecmp(line, name, nameLen) && line[nameLen] == delimiter) 07226 return ast_skip_blanks(line + nameLen + 1); 07227 07228 return ""; 07229 }
static int get_cached_mwi | ( | struct sip_peer * | peer, | |
int * | new, | |||
int * | old | |||
) | [static] |
Get cached MWI info.
Definition at line 25521 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().
25522 { 25523 struct sip_mailbox *mailbox; 25524 int in_cache; 25525 25526 in_cache = 0; 25527 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 25528 struct ast_event *event; 25529 event = ast_event_get_cached(AST_EVENT_MWI, 25530 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox, 25531 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"), 25532 AST_EVENT_IE_END); 25533 if (!event) 25534 continue; 25535 *new += ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 25536 *old += ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 25537 ast_event_destroy(event); 25538 in_cache = 1; 25539 } 25540 25541 return in_cache; 25542 }
static void get_crypto_attrib | ( | struct sip_srtp * | srtp, | |
const char ** | a_crypto | |||
) | [static] |
Definition at line 11195 of file chan_sip.c.
References ast_log(), LOG_WARNING, sdp_crypto_attrib(), sdp_crypto_offer(), and sdp_crypto_setup().
Referenced by add_sdp().
11196 { 11197 /* Set encryption properties */ 11198 if (srtp) { 11199 if (!srtp->crypto) { 11200 srtp->crypto = sdp_crypto_setup(); 11201 } 11202 if (srtp->crypto && (sdp_crypto_offer(srtp->crypto) >= 0)) { 11203 *a_crypto = sdp_crypto_attrib(srtp->crypto); 11204 } 11205 11206 if (!*a_crypto) { 11207 ast_log(LOG_WARNING, "No SRTP key management enabled\n"); 11208 } 11209 } 11210 }
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 15288 of file chan_sip.c.
References ao2_ref, ast_canmatch_extension(), ast_cc_agent_recalling(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_get_hint(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose, check_sip_domain(), context, ast_cc_agent::core_id, ast_cc_agent::device_name, exten, extract_host_from_hostport(), find_sip_cc_agent_by_notify_uri(), get_header(), get_in_brackets(), global_flags, LOG_WARNING, parse_uri_legacy_check(), ast_cc_agent::private_data, S_OR, sip_cfg, sip_debug_test_pvt(), sip_methods, SIP_PEDANTIC_DECODE, and cfsip_methods::text.
Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().
15289 { 15290 char tmp[256] = "", *uri, *unused_password, *domain; 15291 char tmpf[256] = "", *from = NULL; 15292 struct sip_request *req; 15293 char *decoded_uri; 15294 15295 req = oreq; 15296 if (!req) { 15297 req = &p->initreq; 15298 } 15299 15300 /* Find the request URI */ 15301 if (req->rlPart2) 15302 ast_copy_string(tmp, REQ_OFFSET_TO_STR(req, rlPart2), sizeof(tmp)); 15303 15304 uri = ast_strdupa(get_in_brackets(tmp)); 15305 15306 if (parse_uri_legacy_check(uri, "sip:,sips:", &uri, &unused_password, &domain, NULL)) { 15307 ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", uri); 15308 return SIP_GET_DEST_INVALID_URI; 15309 } 15310 15311 SIP_PEDANTIC_DECODE(domain); 15312 SIP_PEDANTIC_DECODE(uri); 15313 15314 extract_host_from_hostport(&domain); 15315 15316 if (ast_strlen_zero(uri)) { 15317 /* 15318 * Either there really was no extension found or the request 15319 * URI had encoded nulls that made the string "empty". Use "s" 15320 * as the extension. 15321 */ 15322 uri = "s"; 15323 } 15324 15325 ast_string_field_set(p, domain, domain); 15326 15327 /* Now find the From: caller ID and name */ 15328 /* XXX Why is this done in get_destination? Isn't it already done? 15329 Needs to be checked 15330 */ 15331 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 15332 if (!ast_strlen_zero(tmpf)) { 15333 from = get_in_brackets(tmpf); 15334 if (parse_uri_legacy_check(from, "sip:,sips:", &from, NULL, &domain, NULL)) { 15335 ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", from); 15336 return SIP_GET_DEST_INVALID_URI; 15337 } 15338 15339 SIP_PEDANTIC_DECODE(from); 15340 SIP_PEDANTIC_DECODE(domain); 15341 15342 extract_host_from_hostport(&domain); 15343 15344 ast_string_field_set(p, fromdomain, domain); 15345 } 15346 15347 if (!AST_LIST_EMPTY(&domain_list)) { 15348 char domain_context[AST_MAX_EXTENSION]; 15349 15350 domain_context[0] = '\0'; 15351 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 15352 if (!sip_cfg.allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 15353 ast_debug(1, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 15354 return SIP_GET_DEST_REFUSED; 15355 } 15356 } 15357 /* If we don't have a peer (i.e. we're a guest call), 15358 * overwrite the original context */ 15359 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_HAVEPEERCONTEXT) && !ast_strlen_zero(domain_context)) { 15360 ast_string_field_set(p, context, domain_context); 15361 } 15362 } 15363 15364 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 15365 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) { 15366 ast_string_field_set(p, context, p->subscribecontext); 15367 } 15368 15369 if (sip_debug_test_pvt(p)) { 15370 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 15371 } 15372 15373 /* Since extensions.conf can have unescaped characters, try matching a 15374 * decoded uri in addition to the non-decoded uri. */ 15375 decoded_uri = ast_strdupa(uri); 15376 ast_uri_decode(decoded_uri); 15377 15378 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 15379 if (req->method == SIP_SUBSCRIBE) { 15380 char hint[AST_MAX_EXTENSION]; 15381 int which = 0; 15382 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, uri) || 15383 (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, decoded_uri) && (which = 1))) { 15384 if (!oreq) { 15385 ast_string_field_set(p, exten, which ? decoded_uri : uri); 15386 } 15387 return SIP_GET_DEST_EXTEN_FOUND; 15388 } else { 15389 return SIP_GET_DEST_EXTEN_NOT_FOUND; 15390 } 15391 } else { 15392 struct ast_cc_agent *agent; 15393 /* Check the dialplan for the username part of the request URI, 15394 the domain will be stored in the SIPDOMAIN variable 15395 Return 0 if we have a matching extension */ 15396 if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) { 15397 if (!oreq) { 15398 ast_string_field_set(p, exten, uri); 15399 } 15400 return SIP_GET_DEST_EXTEN_FOUND; 15401 } 15402 if (ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) 15403 || !strcmp(decoded_uri, ast_pickup_ext())) { 15404 if (!oreq) { 15405 ast_string_field_set(p, exten, decoded_uri); 15406 } 15407 return SIP_GET_DEST_EXTEN_FOUND; 15408 } 15409 if ((agent = find_sip_cc_agent_by_notify_uri(tmp))) { 15410 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 15411 /* This is a CC recall. We can set p's extension to the exten from 15412 * the original INVITE 15413 */ 15414 ast_string_field_set(p, exten, agent_pvt->original_exten); 15415 /* And we need to let the CC core know that the caller is attempting 15416 * his recall 15417 */ 15418 ast_cc_agent_recalling(agent->core_id, "SIP caller %s is attempting recall", 15419 agent->device_name); 15420 if (cc_recall_core_id) { 15421 *cc_recall_core_id = agent->core_id; 15422 } 15423 ao2_ref(agent, -1); 15424 return SIP_GET_DEST_EXTEN_FOUND; 15425 } 15426 } 15427 15428 if (ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) 15429 && (ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) 15430 || ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) 15431 || !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri)))) { 15432 /* Overlap dialing is enabled and we need more digits to match an extension. */ 15433 return SIP_GET_DEST_EXTEN_MATCHMORE; 15434 } 15435 15436 return SIP_GET_DEST_EXTEN_NOT_FOUND; 15437 }
static int get_domain | ( | const char * | str, | |
char * | domain, | |||
int | len | |||
) | [static] |
Extract domain from SIP To/From header.
Definition at line 10690 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), get_in_brackets(), and LOG_WARNING.
Referenced by get_realm().
10691 { 10692 char tmpf[256]; 10693 char *a, *from; 10694 10695 *domain = '\0'; 10696 ast_copy_string(tmpf, str, sizeof(tmpf)); 10697 from = get_in_brackets(tmpf); 10698 if (!ast_strlen_zero(from)) { 10699 if (strncasecmp(from, "sip:", 4)) { 10700 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 10701 return -1; 10702 } 10703 from += 4; 10704 } else 10705 from = NULL; 10706 10707 if (from) { 10708 int bracket = 0; 10709 10710 /* Strip any params or options from user */ 10711 if ((a = strchr(from, ';'))) 10712 *a = '\0'; 10713 /* Strip port from domain if present */ 10714 for (a = from; *a != '\0'; ++a) { 10715 if (*a == ':' && bracket == 0) { 10716 *a = '\0'; 10717 break; 10718 } else if (*a == '[') { 10719 ++bracket; 10720 } else if (*a == ']') { 10721 --bracket; 10722 } 10723 } 10724 if ((a = strchr(from, '@'))) { 10725 *a = '\0'; 10726 ast_copy_string(domain, a + 1, len); 10727 } else 10728 ast_copy_string(domain, from, len); 10729 } 10730 10731 return ast_strlen_zero(domain); 10732 }
static struct event_state_compositor* get_esc | ( | const char *const | event_package | ) | [static] |
Definition at line 999 of file chan_sip.c.
References ARRAY_LEN, event_state_compositors, and name.
Referenced by create_new_sip_etag(), handle_request_publish(), and publish_expire().
00999 { 01000 int i; 01001 for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { 01002 if (!strcasecmp(event_package, event_state_compositors[i].name)) { 01003 return &event_state_compositors[i]; 01004 } 01005 } 01006 return NULL; 01007 }
static struct sip_esc_entry* get_esc_entry | ( | const char * | entity_tag, | |
struct event_state_compositor * | esc | |||
) | [static] |
Definition at line 1009 of file chan_sip.c.
References ao2_find, ast_copy_string(), event_state_compositor::compositor, and OBJ_POINTER.
Referenced by handle_sip_publish_modify(), handle_sip_publish_refresh(), and handle_sip_publish_remove().
01009 { 01010 struct sip_esc_entry *entry; 01011 struct sip_esc_entry finder; 01012 01013 ast_copy_string(finder.entity_tag, entity_tag, sizeof(finder.entity_tag)); 01014 01015 entry = ao2_find(esc->compositor, &finder, OBJ_POINTER); 01016 01017 return entry; 01018 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 7371 of file chan_sip.c.
References __get_header().
07372 { 07373 int start = 0; 07374 return __get_header(req, name, &start); 07375 }
static struct ast_variable * get_insecure_variable_from_config | ( | struct ast_config * | config | ) | [static] |
Definition at line 4676 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.
Referenced by get_insecure_variable_from_sippeers().
04677 { 04678 struct ast_variable *var = NULL; 04679 struct ast_flags flags = {0}; 04680 char *cat = NULL; 04681 const char *insecure; 04682 while ((cat = ast_category_browse(cfg, cat))) { 04683 insecure = ast_variable_retrieve(cfg, cat, "insecure"); 04684 set_insecure_flags(&flags, insecure, -1); 04685 if (ast_test_flag(&flags, SIP_INSECURE_PORT)) { 04686 var = ast_category_root(cfg, cat); 04687 break; 04688 } 04689 } 04690 return var; 04691 }
static struct ast_variable* get_insecure_variable_from_sippeers | ( | const char * | column, | |
const char * | value | |||
) | [static] |
Definition at line 4693 of file chan_sip.c.
References ast_config_destroy(), ast_load_realtime_multientry(), ast_variables_dup(), get_insecure_variable_from_config(), SENTINEL, and var.
Referenced by realtime_peer_by_addr().
04694 { 04695 struct ast_config *peerlist; 04696 struct ast_variable *var = NULL; 04697 if ((peerlist = ast_load_realtime_multientry("sippeers", column, value, "insecure LIKE", "%port%", SENTINEL))) { 04698 if ((var = get_insecure_variable_from_config(peerlist))) { 04699 /* Must clone, because var will get freed along with 04700 * peerlist. */ 04701 var = ast_variables_dup(var); 04702 } 04703 ast_config_destroy(peerlist); 04704 } 04705 return var; 04706 }
static struct ast_variable* get_insecure_variable_from_sipregs | ( | const char * | column, | |
const char * | value, | |||
struct ast_variable ** | var | |||
) | [static] |
Definition at line 4713 of file chan_sip.c.
References ast_category_browse(), ast_category_root(), ast_config_destroy(), ast_load_realtime_multientry(), ast_test_flag, ast_variable_retrieve(), ast_variables_destroy(), ast_variables_dup(), ast_flags::flags, peers, SENTINEL, set_insecure_flags(), and var.
Referenced by realtime_peer_by_addr().
04714 { 04715 struct ast_variable *varregs = NULL; 04716 struct ast_config *regs, *peers; 04717 char *regscat; 04718 const char *regname; 04719 04720 if (!(regs = ast_load_realtime_multientry("sipregs", column, value, SENTINEL))) { 04721 return NULL; 04722 } 04723 04724 /* Load *all* peers that are probably insecure=port */ 04725 if (!(peers = ast_load_realtime_multientry("sippeers", "insecure LIKE", "%port%", SENTINEL))) { 04726 ast_config_destroy(regs); 04727 return NULL; 04728 } 04729 04730 /* Loop over the sipregs that match IP address and attempt to find an 04731 * insecure=port match to it in sippeers. */ 04732 regscat = NULL; 04733 while ((regscat = ast_category_browse(regs, regscat)) && (regname = ast_variable_retrieve(regs, regscat, "name"))) { 04734 char *peerscat; 04735 const char *peername; 04736 04737 peerscat = NULL; 04738 while ((peerscat = ast_category_browse(peers, peerscat)) && (peername = ast_variable_retrieve(peers, peerscat, "name"))) { 04739 if (!strcasecmp(regname, peername)) { 04740 /* Ensure that it really is insecure=port and 04741 * not something else. */ 04742 const char *insecure = ast_variable_retrieve(peers, peerscat, "insecure"); 04743 struct ast_flags flags = {0}; 04744 set_insecure_flags(&flags, insecure, -1); 04745 if (ast_test_flag(&flags, SIP_INSECURE_PORT)) { 04746 /* ENOMEM checks till the bitter end. */ 04747 if ((varregs = ast_variables_dup(ast_category_root(regs, regscat)))) { 04748 if (!(*var = ast_variables_dup(ast_category_root(peers, peerscat)))) { 04749 ast_variables_destroy(varregs); 04750 varregs = NULL; 04751 } 04752 } 04753 goto done; 04754 } 04755 } 04756 } 04757 } 04758 04759 done: 04760 ast_config_destroy(regs); 04761 ast_config_destroy(peers); 04762 return varregs; 04763 }
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 8685 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().
08686 { 08687 const char *m; 08688 const char *c; 08689 int miterator = req->sdp_start; 08690 int citerator = req->sdp_start; 08691 int x = 0; 08692 int numberofports; 08693 int len; 08694 int af; 08695 char proto[4], host[258] = ""; /*Initialize to empty so we will know if we have any input */ 08696 08697 c = get_sdp_iterate(&citerator, req, "c"); 08698 if (sscanf(c, "IN %3s %256s", proto, host) != 2) { 08699 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 08700 /* Continue since there may be a valid host in a c= line specific to the audio stream */ 08701 } 08702 /* We only want the m and c lines for audio */ 08703 for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) { 08704 if ((media == SDP_AUDIO && ((sscanf(m, "audio %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 08705 (sscanf(m, "audio %30u RTP/AVP %n", &x, &len) == 1 && len > 0))) || 08706 (media == SDP_VIDEO && ((sscanf(m, "video %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 08707 (sscanf(m, "video %30u RTP/AVP %n", &x, &len) == 1 && len > 0)))) { 08708 /* See if there's a c= line for this media stream. 08709 * XXX There is no guarantee that we'll be grabbing the c= line for this 08710 * particular media stream here. However, this is the same logic used in process_sdp. 08711 */ 08712 c = get_sdp_iterate(&citerator, req, "c"); 08713 if (!ast_strlen_zero(c)) { 08714 sscanf(c, "IN %3s %256s", proto, host); 08715 } 08716 break; 08717 } 08718 } 08719 08720 if (!strcmp("IP4", proto)) { 08721 af = AF_INET; 08722 } else if (!strcmp("IP6", proto)) { 08723 af = AF_INET6; 08724 } else { 08725 ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto); 08726 return -1; 08727 } 08728 08729 if (ast_strlen_zero(host) || x == 0) { 08730 ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video"); 08731 return -1; 08732 } 08733 08734 if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) { 08735 ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video"); 08736 return -1; 08737 } 08738 08739 return 0; 08740 }
static int get_msg_text | ( | char * | buf, | |
int | len, | |||
struct sip_request * | req | |||
) | [static] |
Get message body from a SIP request.
buf | Destination buffer | |
len | Destination buffer size | |
req | The SIP request |
Definition at line 16227 of file chan_sip.c.
Referenced by handle_request_info(), handle_request_notify(), and receive_message().
16228 { 16229 int x; 16230 int linelen; 16231 16232 buf[0] = '\0'; 16233 --len; /* reserve strncat null */ 16234 for (x = 0; len && x < req->lines; ++x) { 16235 const char *line = REQ_OFFSET_TO_STR(req, line[x]); 16236 strncat(buf, line, len); /* safe */ 16237 linelen = strlen(buf); 16238 buf += linelen; 16239 len -= linelen; 16240 if (len) { 16241 strcat(buf, "\n"); /* safe */ 16242 ++buf; 16243 --len; 16244 } 16245 } 16246 return 0; 16247 }
static const char * get_name_from_variable | ( | const struct ast_variable * | var | ) | [static] |
Definition at line 4765 of file chan_sip.c.
References ast_strlen_zero(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
Referenced by realtime_peer_by_addr(), and realtime_peer_get_sippeer_helper().
04766 { 04767 /* Don't expect this to return non-NULL. Both NULL and empty 04768 * values can cause the option to get removed from the variable 04769 * list. This is called on ast_variables gotten from both 04770 * ast_load_realtime and ast_load_realtime_multientry. 04771 * - ast_load_realtime removes options with empty values 04772 * - ast_load_realtime_multientry does not! 04773 * For consistent behaviour, we check for the empty name and 04774 * return NULL instead. */ 04775 const struct ast_variable *tmp; 04776 for (tmp = var; tmp; tmp = tmp->next) { 04777 if (!strcasecmp(tmp->name, "name")) { 04778 if (!ast_strlen_zero(tmp->value)) { 04779 return tmp->value; 04780 } 04781 break; 04782 } 04783 } 04784 return NULL; 04785 }
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 11102 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().
11106 { 11107 int use_externip = 0; 11108 11109 /* First, get our address */ 11110 ast_rtp_instance_get_local_address(p->rtp, addr); 11111 if (p->vrtp) { 11112 ast_rtp_instance_get_local_address(p->vrtp, vaddr); 11113 } 11114 if (p->trtp) { 11115 ast_rtp_instance_get_local_address(p->trtp, taddr); 11116 } 11117 11118 /* If our real IP differs from the local address returned by the RTP engine, use it. */ 11119 /* The premise is that if we are already using that IP to communicate with the client, */ 11120 /* we should be using it for RTP too. */ 11121 use_externip = ast_sockaddr_cmp_addr(&p->ourip, addr); 11122 11123 /* Now, try to figure out where we want them to send data */ 11124 /* Is this a re-invite to move the media out, then use the original offer from caller */ 11125 if (!ast_sockaddr_isnull(&p->redirip)) { /* If we have a redirection IP, use it */ 11126 ast_sockaddr_copy(dest, &p->redirip); 11127 } else { 11128 /* 11129 * Audio Destination IP: 11130 * 11131 * 1. Specifically configured media address. 11132 * 2. Local address as specified by the RTP engine. 11133 * 3. The local IP as defined by chan_sip. 11134 * 11135 * Audio Destination Port: 11136 * 11137 * 1. Provided by the RTP engine. 11138 */ 11139 ast_sockaddr_copy(dest, 11140 !ast_sockaddr_isnull(&media_address) ? &media_address : 11141 !ast_sockaddr_is_any(addr) && !use_externip ? addr : 11142 &p->ourip); 11143 ast_sockaddr_set_port(dest, ast_sockaddr_port(addr)); 11144 } 11145 11146 if (needvideo) { 11147 /* Determine video destination */ 11148 if (!ast_sockaddr_isnull(&p->vredirip)) { 11149 ast_sockaddr_copy(vdest, &p->vredirip); 11150 } else { 11151 /* 11152 * Video Destination IP: 11153 * 11154 * 1. Specifically configured media address. 11155 * 2. Local address as specified by the RTP engine. 11156 * 3. The local IP as defined by chan_sip. 11157 * 11158 * Video Destination Port: 11159 * 11160 * 1. Provided by the RTP engine. 11161 */ 11162 ast_sockaddr_copy(vdest, 11163 !ast_sockaddr_isnull(&media_address) ? &media_address : 11164 !ast_sockaddr_is_any(vaddr) && !use_externip ? vaddr : 11165 &p->ourip); 11166 ast_sockaddr_set_port(vdest, ast_sockaddr_port(vaddr)); 11167 } 11168 } 11169 11170 if (needtext) { 11171 /* Determine text destination */ 11172 if (!ast_sockaddr_isnull(&p->tredirip)) { 11173 ast_sockaddr_copy(tdest, &p->tredirip); 11174 } else { 11175 /* 11176 * Text Destination IP: 11177 * 11178 * 1. Specifically configured media address. 11179 * 2. Local address as specified by the RTP engine. 11180 * 3. The local IP as defined by chan_sip. 11181 * 11182 * Text Destination Port: 11183 * 11184 * 1. Provided by the RTP engine. 11185 */ 11186 ast_sockaddr_copy(tdest, 11187 !ast_sockaddr_isnull(&media_address) ? &media_address : 11188 !ast_sockaddr_is_any(taddr) && !use_externip ? taddr : 11189 &p->ourip); 11190 ast_sockaddr_set_port(tdest, ast_sockaddr_port(taddr)); 11191 } 11192 } 11193 }
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 15017 of file chan_sip.c.
References ast_copy_string(), ast_free, ast_is_shrinkable_phonenumber(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, ast_set_callerid(), ast_shrink_phone_number(), ast_string_field_set, ast_strlen_zero(), cid_name, cid_num, get_header(), get_in_brackets(), get_name_and_number(), and global_shrinkcallerid.
Referenced by get_rpid().
15018 { 15019 char pai[256]; 15020 char privacy[64]; 15021 char *cid_num = NULL; 15022 char *cid_name = NULL; 15023 char emptyname[1] = ""; 15024 int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 15025 char *uri = NULL; 15026 int is_anonymous = 0, do_update = 1, no_name = 0; 15027 15028 ast_copy_string(pai, get_header(req, "P-Asserted-Identity"), sizeof(pai)); 15029 15030 if (ast_strlen_zero(pai)) { 15031 return 0; 15032 } 15033 15034 /* use the reqresp_parser function get_name_and_number*/ 15035 if (get_name_and_number(pai, &cid_name, &cid_num)) { 15036 return 0; 15037 } 15038 15039 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num)) { 15040 ast_shrink_phone_number(cid_num); 15041 } 15042 15043 uri = get_in_brackets(pai); 15044 if (!strncasecmp(uri, "sip:anonymous@anonymous.invalid", 31)) { 15045 callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 15046 /*XXX Assume no change in cid_num. Perhaps it should be 15047 * blanked? 15048 */ 15049 ast_free(cid_num); 15050 is_anonymous = 1; 15051 cid_num = (char *)p->cid_num; 15052 } 15053 15054 ast_copy_string(privacy, get_header(req, "Privacy"), sizeof(privacy)); 15055 if (!ast_strlen_zero(privacy) && strncmp(privacy, "id", 2)) { 15056 callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 15057 } 15058 if (!cid_name) { 15059 no_name = 1; 15060 cid_name = (char *)emptyname; 15061 } 15062 /* Only return true if the supplied caller id is different */ 15063 if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres) { 15064 do_update = 0; 15065 } else { 15066 15067 ast_string_field_set(p, cid_num, cid_num); 15068 ast_string_field_set(p, cid_name, cid_name); 15069 p->callingpres = callingpres; 15070 15071 if (p->owner) { 15072 ast_set_callerid(p->owner, cid_num, cid_name, NULL); 15073 p->owner->caller.id.name.presentation = callingpres; 15074 p->owner->caller.id.number.presentation = callingpres; 15075 } 15076 } 15077 15078 /* get_name_and_number allocates memory for cid_num and cid_name so we have to free it */ 15079 if (!is_anonymous) { 15080 ast_free(cid_num); 15081 } 15082 if (!no_name) { 15083 ast_free(cid_name); 15084 } 15085 15086 return do_update; 15087 }
static void get_pidf_body | ( | struct sip_request * | req, | |
char * | pidf_body, | |||
size_t | size | |||
) | [static] |
Definition at line 23920 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().
23921 { 23922 int i; 23923 struct ast_str *str = ast_str_alloca(size); 23924 for (i = 0; i < req->lines; ++i) { 23925 ast_str_append(&str, 0, "%s", REQ_OFFSET_TO_STR(req, line[i])); 23926 } 23927 ast_copy_string(pidf_body, ast_str_buffer(str), size); 23928 }
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 15190 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strdup, ast_strip_quoted(), ast_strlen_zero(), ast_verbose, exten, get_header(), get_in_brackets(), LOG_WARNING, pbx_builtin_setvar_helper(), sip_debug_test_pvt(), sip_reason_str_to_code(), sip_set_redirstr(), strcasestr(), and strsep().
Referenced by change_redirecting_information().
15191 { 15192 char tmp[256], *exten, *rexten, *rdomain, *rname = NULL; 15193 char *params, *reason_param = NULL; 15194 struct sip_request *req; 15195 15196 req = oreq ? oreq : &p->initreq; 15197 15198 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 15199 if (ast_strlen_zero(tmp)) 15200 return -1; 15201 15202 if ((params = strchr(tmp, '>'))) { 15203 params = strchr(params, ';'); 15204 } 15205 15206 exten = get_in_brackets(tmp); 15207 if (!strncasecmp(exten, "sip:", 4)) { 15208 exten += 4; 15209 } else if (!strncasecmp(exten, "sips:", 5)) { 15210 exten += 5; 15211 } else { 15212 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", exten); 15213 return -1; 15214 } 15215 15216 /* Get diversion-reason param if present */ 15217 if (params) { 15218 *params = '\0'; /* Cut off parameters */ 15219 params++; 15220 while (*params == ';' || *params == ' ') 15221 params++; 15222 /* Check if we have a reason parameter */ 15223 if ((reason_param = strcasestr(params, "reason="))) { 15224 char *end; 15225 reason_param+=7; 15226 if ((end = strchr(reason_param, ';'))) { 15227 *end = '\0'; 15228 } 15229 /* Remove enclosing double-quotes */ 15230 if (*reason_param == '"') 15231 ast_strip_quoted(reason_param, "\"", "\""); 15232 if (!ast_strlen_zero(reason_param)) { 15233 sip_set_redirstr(p, reason_param); 15234 if (p->owner) { 15235 pbx_builtin_setvar_helper(p->owner, "__PRIREDIRECTREASON", p->redircause); 15236 pbx_builtin_setvar_helper(p->owner, "__SIPREDIRECTREASON", reason_param); 15237 } 15238 } 15239 } 15240 } 15241 15242 rdomain = exten; 15243 rexten = strsep(&rdomain, "@"); /* trim anything after @ */ 15244 if (p->owner) 15245 pbx_builtin_setvar_helper(p->owner, "__SIPRDNISDOMAIN", rdomain); 15246 15247 if (sip_debug_test_pvt(p)) 15248 ast_verbose("RDNIS for this call is %s (reason %s)\n", exten, reason ? reason_param : ""); 15249 15250 /*ast_string_field_set(p, rdnis, rexten);*/ 15251 15252 if (*tmp == '\"') { 15253 char *end_quote; 15254 rname = tmp + 1; 15255 end_quote = strchr(rname, '\"'); 15256 *end_quote = '\0'; 15257 } 15258 15259 if (number) { 15260 *number = ast_strdup(rexten); 15261 } 15262 15263 if (name && rname) { 15264 *name = ast_strdup(rname); 15265 } 15266 15267 if (reason && !ast_strlen_zero(reason_param)) { 15268 *reason = sip_reason_str_to_code(reason_param); 15269 } 15270 15271 return 0; 15272 }
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 10738 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().
10739 { 10740 char domain[MAXHOSTNAMELEN]; 10741 10742 if (!ast_strlen_zero(p->realm)) 10743 return; 10744 10745 if (sip_cfg.domainsasrealm && 10746 !AST_LIST_EMPTY(&domain_list)) 10747 { 10748 /* Check From header first */ 10749 if (!get_domain(get_header(req, "From"), domain, sizeof(domain))) { 10750 if (check_sip_domain(domain, NULL, 0)) { 10751 ast_string_field_set(p, realm, domain); 10752 return; 10753 } 10754 } 10755 /* Check To header */ 10756 if (!get_domain(get_header(req, "To"), domain, sizeof(domain))) { 10757 if (check_sip_domain(domain, NULL, 0)) { 10758 ast_string_field_set(p, realm, domain); 10759 return; 10760 } 10761 } 10762 } 10763 10764 /* Use default realm from config file */ 10765 ast_string_field_set(p, realm, sip_cfg.realm); 10766 }
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 15531 of file chan_sip.c.
References ast_bridged_channel(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose, ast_channel::context, get_header(), get_in_brackets(), LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), S_OR, sip_cfg, sip_debug_test_pvt(), SIP_PEDANTIC_DECODE, and strcasestr().
Referenced by handle_request_refer().
15532 { 15533 15534 const char *p_referred_by = NULL; 15535 char *h_refer_to = NULL; 15536 char *h_referred_by = NULL; 15537 char *refer_to; 15538 const char *p_refer_to; 15539 char *referred_by_uri = NULL; 15540 char *ptr; 15541 struct sip_request *req = NULL; 15542 const char *transfer_context = NULL; 15543 struct sip_refer *referdata; 15544 15545 15546 req = outgoing_req; 15547 referdata = transferer->refer; 15548 15549 if (!req) { 15550 req = &transferer->initreq; 15551 } 15552 15553 p_refer_to = get_header(req, "Refer-To"); 15554 if (ast_strlen_zero(p_refer_to)) { 15555 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 15556 return -2; /* Syntax error */ 15557 } 15558 h_refer_to = ast_strdupa(p_refer_to); 15559 refer_to = get_in_brackets(h_refer_to); 15560 if (!strncasecmp(refer_to, "sip:", 4)) { 15561 refer_to += 4; /* Skip sip: */ 15562 } else if (!strncasecmp(refer_to, "sips:", 5)) { 15563 refer_to += 5; 15564 } else { 15565 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 15566 return -3; 15567 } 15568 15569 /* Get referred by header if it exists */ 15570 p_referred_by = get_header(req, "Referred-By"); 15571 15572 /* Give useful transfer information to the dialplan */ 15573 if (transferer->owner) { 15574 struct ast_channel *peer = ast_bridged_channel(transferer->owner); 15575 if (peer) { 15576 pbx_builtin_setvar_helper(peer, "SIPREFERRINGCONTEXT", transferer->context); 15577 pbx_builtin_setvar_helper(peer, "SIPREFERREDBYHDR", p_referred_by); 15578 } 15579 } 15580 15581 if (!ast_strlen_zero(p_referred_by)) { 15582 char *lessthan; 15583 h_referred_by = ast_strdupa(p_referred_by); 15584 15585 /* Store referrer's caller ID name */ 15586 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 15587 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 15588 *(lessthan - 1) = '\0'; /* Space */ 15589 } 15590 15591 referred_by_uri = get_in_brackets(h_referred_by); 15592 15593 if (!strncasecmp(referred_by_uri, "sip:", 4)) { 15594 referred_by_uri += 4; /* Skip sip: */ 15595 } else if (!strncasecmp(referred_by_uri, "sips:", 5)) { 15596 referred_by_uri += 5; /* Skip sips: */ 15597 } else { 15598 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 15599 referred_by_uri = NULL; 15600 } 15601 } 15602 15603 /* Check for arguments in the refer_to header */ 15604 if ((ptr = strcasestr(refer_to, "replaces="))) { 15605 char *to = NULL, *from = NULL; 15606 15607 /* This is an attended transfer */ 15608 referdata->attendedtransfer = 1; 15609 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 15610 ast_uri_decode(referdata->replaces_callid); 15611 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 15612 *ptr++ = '\0'; 15613 } 15614 15615 if (ptr) { 15616 /* Find the different tags before we destroy the string */ 15617 to = strcasestr(ptr, "to-tag="); 15618 from = strcasestr(ptr, "from-tag="); 15619 } 15620 15621 /* Grab the to header */ 15622 if (to) { 15623 ptr = to + 7; 15624 if ((to = strchr(ptr, '&'))) { 15625 *to = '\0'; 15626 } 15627 if ((to = strchr(ptr, ';'))) { 15628 *to = '\0'; 15629 } 15630 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 15631 } 15632 15633 if (from) { 15634 ptr = from + 9; 15635 if ((to = strchr(ptr, '&'))) { 15636 *to = '\0'; 15637 } 15638 if ((to = strchr(ptr, ';'))) { 15639 *to = '\0'; 15640 } 15641 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 15642 } 15643 15644 if (!strcmp(referdata->replaces_callid, transferer->callid) && 15645 (!sip_cfg.pedanticsipchecking || 15646 (!strcmp(referdata->replaces_callid_fromtag, transferer->theirtag) && 15647 !strcmp(referdata->replaces_callid_totag, transferer->tag)))) { 15648 ast_log(LOG_WARNING, "Got an attempt to replace own Call-ID on %s\n", transferer->callid); 15649 return -4; 15650 } 15651 15652 if (!sip_cfg.pedanticsipchecking) { 15653 ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 15654 } else { 15655 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>" ); 15656 } 15657 } 15658 15659 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 15660 char *urioption = NULL, *domain; 15661 int bracket = 0; 15662 *ptr++ = '\0'; 15663 15664 if ((urioption = strchr(ptr, ';'))) { /* Separate urioptions */ 15665 *urioption++ = '\0'; 15666 } 15667 15668 domain = ptr; 15669 15670 /* Remove :port */ 15671 for (; *ptr != '\0'; ++ptr) { 15672 if (*ptr == ':' && bracket == 0) { 15673 *ptr = '\0'; 15674 break; 15675 } else if (*ptr == '[') { 15676 ++bracket; 15677 } else if (*ptr == ']') { 15678 --bracket; 15679 } 15680 } 15681 15682 SIP_PEDANTIC_DECODE(domain); 15683 SIP_PEDANTIC_DECODE(urioption); 15684 15685 /* Save the domain for the dial plan */ 15686 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 15687 if (urioption) { 15688 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 15689 } 15690 } 15691 15692 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 15693 *ptr = '\0'; 15694 15695 SIP_PEDANTIC_DECODE(refer_to); 15696 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 15697 15698 if (referred_by_uri) { 15699 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 15700 *ptr = '\0'; 15701 SIP_PEDANTIC_DECODE(referred_by_uri); 15702 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 15703 } else { 15704 referdata->referred_by[0] = '\0'; 15705 } 15706 15707 /* Determine transfer context */ 15708 if (transferer->owner) /* Mimic behaviour in res_features.c */ 15709 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 15710 15711 /* By default, use the context in the channel sending the REFER */ 15712 if (ast_strlen_zero(transfer_context)) { 15713 transfer_context = S_OR(transferer->owner->macrocontext, 15714 S_OR(transferer->context, sip_cfg.default_context)); 15715 } 15716 15717 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 15718 15719 /* Either an existing extension or the parking extension */ 15720 if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 15721 if (sip_debug_test_pvt(transferer)) { 15722 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 15723 } 15724 /* We are ready to transfer to the extension */ 15725 return 0; 15726 } 15727 if (sip_debug_test_pvt(transferer)) 15728 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 15729 15730 /* Failure, we can't find this extension */ 15731 return -1; 15732 }
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 15093 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().
15094 { 15095 char tmp[256]; 15096 struct sip_request *req; 15097 char *cid_num = ""; 15098 char *cid_name = ""; 15099 int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 15100 char *privacy = ""; 15101 char *screen = ""; 15102 char *start, *end; 15103 15104 if (!ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) 15105 return 0; 15106 req = oreq; 15107 if (!req) 15108 req = &p->initreq; 15109 ast_copy_string(tmp, get_header(req, "Remote-Party-ID"), sizeof(tmp)); 15110 if (ast_strlen_zero(tmp)) { 15111 return get_pai(p, req); 15112 } 15113 15114 start = tmp; 15115 if (*start == '"') { 15116 *start++ = '\0'; 15117 end = strchr(start, '"'); 15118 if (!end) 15119 return 0; 15120 *end++ = '\0'; 15121 cid_name = start; 15122 start = ast_skip_blanks(end); 15123 } 15124 15125 if (*start != '<') 15126 return 0; 15127 *start++ = '\0'; 15128 end = strchr(start, '@'); 15129 if (!end) 15130 return 0; 15131 *end++ = '\0'; 15132 if (strncasecmp(start, "sip:", 4)) 15133 return 0; 15134 cid_num = start + 4; 15135 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num)) 15136 ast_shrink_phone_number(cid_num); 15137 start = end; 15138 15139 end = strchr(start, '>'); 15140 if (!end) 15141 return 0; 15142 *end++ = '\0'; 15143 if (*end) { 15144 start = end; 15145 if (*start != ';') 15146 return 0; 15147 *start++ = '\0'; 15148 while (!ast_strlen_zero(start)) { 15149 end = strchr(start, ';'); 15150 if (end) 15151 *end++ = '\0'; 15152 if (!strncasecmp(start, "privacy=", 8)) 15153 privacy = start + 8; 15154 else if (!strncasecmp(start, "screen=", 7)) 15155 screen = start + 7; 15156 start = end; 15157 } 15158 15159 if (!strcasecmp(privacy, "full")) { 15160 if (!strcasecmp(screen, "yes")) 15161 callingpres = AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN; 15162 else if (!strcasecmp(screen, "no")) 15163 callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 15164 } else { 15165 if (!strcasecmp(screen, "yes")) 15166 callingpres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 15167 else if (!strcasecmp(screen, "no")) 15168 callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; 15169 } 15170 } 15171 15172 /* Only return true if the supplied caller id is different */ 15173 if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres) 15174 return 0; 15175 15176 ast_string_field_set(p, cid_num, cid_num); 15177 ast_string_field_set(p, cid_name, cid_name); 15178 p->callingpres = callingpres; 15179 15180 if (p->owner) { 15181 ast_set_callerid(p->owner, cid_num, cid_name, NULL); 15182 p->owner->caller.id.name.presentation = callingpres; 15183 p->owner->caller.id.number.presentation = callingpres; 15184 } 15185 15186 return 1; 15187 }
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 7235 of file chan_sip.c.
References get_body_by_line(), and len().
07236 { 07237 int len = strlen(name); 07238 07239 while (*start < (req->sdp_start + req->sdp_count)) { 07240 const char *r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[(*start)++]), name, len, '='); 07241 if (r[0] != '\0') 07242 return r; 07243 } 07244 07245 /* if the line was not found, ensure that *start points past the SDP */ 07246 (*start)++; 07247 07248 return ""; 07249 }
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 7256 of file chan_sip.c.
References ast_skip_blanks(), and type.
Referenced by process_sdp().
07257 { 07258 char type = '\0'; 07259 const char *line = NULL; 07260 07261 if (stop > (req->sdp_start + req->sdp_count)) { 07262 stop = req->sdp_start + req->sdp_count; 07263 } 07264 07265 while (*start < stop) { 07266 line = REQ_OFFSET_TO_STR(req, line[(*start)++]); 07267 if (line[1] == '=') { 07268 type = line[0]; 07269 *value = ast_skip_blanks(line + 2); 07270 break; 07271 } 07272 } 07273 07274 return type; 07275 }
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 15442 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().
15443 { 15444 struct sip_pvt *sip_pvt_ptr; 15445 struct sip_pvt tmp_dialog = { 15446 .callid = callid, 15447 }; 15448 15449 if (totag) { 15450 ast_debug(4, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 15451 } 15452 15453 /* Search dialogs and find the match */ 15454 15455 sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find of dialog in dialogs table"); 15456 if (sip_pvt_ptr) { 15457 /* Go ahead and lock it (and its owner) before returning */ 15458 sip_pvt_lock(sip_pvt_ptr); 15459 if (sip_cfg.pedanticsipchecking) { 15460 unsigned char frommismatch = 0, tomismatch = 0; 15461 15462 if (ast_strlen_zero(fromtag)) { 15463 sip_pvt_unlock(sip_pvt_ptr); 15464 ast_debug(4, "Matched %s call for callid=%s - no from tag specified, pedantic check fails\n", 15465 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid); 15466 return NULL; 15467 } 15468 15469 if (ast_strlen_zero(totag)) { 15470 sip_pvt_unlock(sip_pvt_ptr); 15471 ast_debug(4, "Matched %s call for callid=%s - no to tag specified, pedantic check fails\n", 15472 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid); 15473 return NULL; 15474 } 15475 /* RFC 3891 15476 * > 3. User Agent Server Behavior: Receiving a Replaces Header 15477 * > The Replaces header contains information used to match an existing 15478 * > SIP dialog (call-id, to-tag, and from-tag). Upon receiving an INVITE 15479 * > with a Replaces header, the User Agent (UA) attempts to match this 15480 * > information with a confirmed or early dialog. The User Agent Server 15481 * > (UAS) matches the to-tag and from-tag parameters as if they were tags 15482 * > present in an incoming request. In other words, the to-tag parameter 15483 * > is compared to the local tag, and the from-tag parameter is compared 15484 * > to the remote tag. 15485 * 15486 * Thus, the totag is always compared to the local tag, regardless if 15487 * this our call is an incoming or outgoing call. 15488 */ 15489 frommismatch = !!strcmp(fromtag, sip_pvt_ptr->theirtag); 15490 tomismatch = !!strcmp(totag, sip_pvt_ptr->tag); 15491 15492 if (frommismatch || tomismatch) { 15493 sip_pvt_unlock(sip_pvt_ptr); 15494 if (frommismatch) { 15495 ast_debug(4, "Matched %s call for callid=%s - pedantic from tag check fails; their tag is %s our tag is %s\n", 15496 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid, 15497 fromtag, sip_pvt_ptr->theirtag); 15498 } 15499 if (tomismatch) { 15500 ast_debug(4, "Matched %s call for callid=%s - pedantic to tag check fails; their tag is %s our tag is %s\n", 15501 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid, 15502 totag, sip_pvt_ptr->tag); 15503 } 15504 return NULL; 15505 } 15506 } 15507 15508 if (totag) 15509 ast_debug(4, "Matched %s call - their tag is %s Our tag is %s\n", 15510 sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", 15511 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 15512 15513 /* deadlock avoidance... */ 15514 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 15515 sip_pvt_unlock(sip_pvt_ptr); 15516 usleep(1); 15517 sip_pvt_lock(sip_pvt_ptr); 15518 } 15519 } 15520 15521 return sip_pvt_ptr; 15522 }
static const char* get_srv_protocol | ( | enum sip_transport | t | ) | [inline, static] |
Return protocol string for srv dns query.
Definition at line 3287 of file chan_sip.c.
Referenced by __sip_subscribe_mwi_do(), build_peer(), create_addr(), and transmit_register().
03288 { 03289 switch (t) { 03290 case SIP_TRANSPORT_UDP: 03291 return "udp"; 03292 case SIP_TRANSPORT_TLS: 03293 case SIP_TRANSPORT_TCP: 03294 return "tcp"; 03295 } 03296 03297 return "udp"; 03298 }
static const char* get_srv_service | ( | enum sip_transport | t | ) | [inline, static] |
Return service string for srv dns query.
Definition at line 3301 of file chan_sip.c.
Referenced by __sip_subscribe_mwi_do(), build_peer(), create_addr(), and transmit_register().
03302 { 03303 switch (t) { 03304 case SIP_TRANSPORT_TCP: 03305 case SIP_TRANSPORT_UDP: 03306 return "sip"; 03307 case SIP_TRANSPORT_TLS: 03308 return "sips"; 03309 } 03310 return "sip"; 03311 }
static const char* get_transport | ( | enum sip_transport | t | ) | [inline, static] |
Return transport as string.
Definition at line 3272 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().
03273 { 03274 switch (t) { 03275 case SIP_TRANSPORT_UDP: 03276 return "UDP"; 03277 case SIP_TRANSPORT_TCP: 03278 return "TCP"; 03279 case SIP_TRANSPORT_TLS: 03280 return "TLS"; 03281 } 03282 03283 return "UNKNOWN"; 03284 }
static const char* get_transport_list | ( | unsigned int | transports | ) | [inline, static] |
Return configuration of transports for a device.
Definition at line 3251 of file chan_sip.c.
Referenced by _sip_show_peer(), peers_data_provider_get(), and sip_show_settings().
03251 { 03252 switch (transports) { 03253 case SIP_TRANSPORT_UDP: 03254 return "UDP"; 03255 case SIP_TRANSPORT_TCP: 03256 return "TCP"; 03257 case SIP_TRANSPORT_TLS: 03258 return "TLS"; 03259 case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TCP: 03260 return "TCP,UDP"; 03261 case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TLS: 03262 return "TLS,UDP"; 03263 case SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS: 03264 return "TLS,TCP"; 03265 default: 03266 return transports ? 03267 "TLS,TCP,UDP" : "UNKNOWN"; 03268 } 03269 }
static const char* get_transport_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Return transport of dialog.
Definition at line 3319 of file chan_sip.c.
References get_transport(), and set_socket_transport().
Referenced by __sip_xmit(), and build_via().
03320 { 03321 if (p->outboundproxy && p->outboundproxy->transport) { 03322 set_socket_transport(&p->socket, p->outboundproxy->transport); 03323 } 03324 03325 return get_transport(p->socket.type); 03326 }
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 3229 of file chan_sip.c.
References ast_strlen_zero().
Referenced by __set_address_from_contact(), and parse_register_contact().
03230 { 03231 int res = 0; 03232 03233 if (ast_strlen_zero(transport)) { 03234 return res; 03235 } 03236 03237 if (!strcasecmp(transport, "udp")) { 03238 res |= SIP_TRANSPORT_UDP; 03239 } 03240 if (!strcasecmp(transport, "tcp")) { 03241 res |= SIP_TRANSPORT_TCP; 03242 } 03243 if (!strcasecmp(transport, "tls")) { 03244 res |= SIP_TRANSPORT_TLS; 03245 } 03246 03247 return res; 03248 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 21586 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().
21587 { 21588 const char *thetag; 21589 21590 if (!tagbuf) 21591 return NULL; 21592 tagbuf[0] = '\0'; /* reset the buffer */ 21593 thetag = get_header(req, header); 21594 thetag = strcasestr(thetag, ";tag="); 21595 if (thetag) { 21596 thetag += 5; 21597 ast_copy_string(tagbuf, thetag, tagbufsize); 21598 return strsep(&tagbuf, ";"); 21599 } 21600 return NULL; 21601 }
static int handle_cc_notify | ( | struct sip_pvt * | pvt, | |
struct sip_request * | req | |||
) | [static] |
Definition at line 21603 of file chan_sip.c.
References ao2_callback, ao2_ref, ast_cc_monitor_callee_available(), ast_cc_monitor_request_acked(), ast_string_field_set, ast_strlen_zero(), construct_pidf_body(), find_sip_monitor_instance_by_subscription_pvt(), get_body(), get_header(), get_in_brackets(), sip_monitor_instances, status, transmit_publish(), and transmit_response().
Referenced by handle_request_notify().
21604 { 21605 struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0, 21606 find_sip_monitor_instance_by_subscription_pvt, pvt); 21607 const char *status = get_body(req, "cc-state", ':'); 21608 struct cc_epa_entry *cc_entry; 21609 char *uri; 21610 21611 if (!monitor_instance) { 21612 transmit_response(pvt, "400 Bad Request", req); 21613 return -1; 21614 } 21615 21616 if (ast_strlen_zero(status)) { 21617 ao2_ref(monitor_instance, -1); 21618 transmit_response(pvt, "400 Bad Request", req); 21619 return -1; 21620 } 21621 21622 if (!strcmp(status, "queued")) { 21623 /* We've been told that we're queued. This is the endpoint's way of telling 21624 * us that it has accepted our CC request. We need to alert the core of this 21625 * development 21626 */ 21627 ast_cc_monitor_request_acked(monitor_instance->core_id, "SIP endpoint %s accepted request", monitor_instance->device_name); 21628 transmit_response(pvt, "200 OK", req); 21629 ao2_ref(monitor_instance, -1); 21630 return 0; 21631 } 21632 21633 /* It's open! Yay! */ 21634 uri = get_body(req, "cc-URI", ':'); 21635 if (ast_strlen_zero(uri)) { 21636 uri = get_in_brackets((char *)get_header(req, "From")); 21637 } 21638 21639 ast_string_field_set(monitor_instance, notify_uri, uri); 21640 if (monitor_instance->suspension_entry) { 21641 cc_entry = monitor_instance->suspension_entry->instance_data; 21642 if (cc_entry->current_state == CC_CLOSED) { 21643 /* If we've created a suspension entry and the current state is closed, then that means 21644 * we got a notice from the CC core earlier to suspend monitoring, but because this particular 21645 * call leg had not yet notified us that it was ready for recall, it meant that we 21646 * could not yet send a PUBLISH. Now, however, we can. 21647 */ 21648 construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body, 21649 sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername); 21650 transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_INITIAL, monitor_instance->notify_uri); 21651 } else { 21652 ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available"); 21653 } 21654 } else { 21655 ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available"); 21656 } 21657 ao2_ref(monitor_instance, -1); 21658 transmit_response(pvt, "200 OK", req); 21659 21660 return 0; 21661 }
static int handle_cc_subscribe | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Definition at line 24417 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().
24418 { 24419 const char *uri = REQ_OFFSET_TO_STR(req, rlPart2); 24420 char *param_separator; 24421 struct ast_cc_agent *agent; 24422 struct sip_cc_agent_pvt *agent_pvt; 24423 const char *expires_str = get_header(req, "Expires"); 24424 int expires = -1; /* Just need it to be non-zero */ 24425 24426 if (!ast_strlen_zero(expires_str)) { 24427 sscanf(expires_str, "%d", &expires); 24428 } 24429 24430 if ((param_separator = strchr(uri, ';'))) { 24431 *param_separator = '\0'; 24432 } 24433 24434 p->subscribed = CALL_COMPLETION; 24435 24436 if (!(agent = find_sip_cc_agent_by_subscribe_uri(uri))) { 24437 if (!expires) { 24438 /* Typically, if a 0 Expires reaches us and we can't find 24439 * the corresponding agent, it means that the CC transaction 24440 * has completed and so the calling side is just trying to 24441 * clean up its subscription. We'll just respond with a 24442 * 200 OK and be done with it 24443 */ 24444 transmit_response(p, "200 OK", req); 24445 return 0; 24446 } 24447 ast_log(LOG_WARNING, "Invalid URI '%s' in CC subscribe\n", uri); 24448 transmit_response(p, "404 Not Found", req); 24449 return -1; 24450 } 24451 24452 agent_pvt = agent->private_data; 24453 24454 if (!expires) { 24455 /* We got sent a SUBSCRIBE and found an agent. This means that CC 24456 * is being canceled. 24457 */ 24458 ast_cc_failed(agent->core_id, "CC is being canceled by %s", agent->device_name); 24459 transmit_response(p, "200 OK", req); 24460 ao2_ref(agent, -1); 24461 return 0; 24462 } 24463 24464 agent_pvt->subscribe_pvt = dialog_ref(p, "SIP CC agent gains reference to subscription dialog"); 24465 ast_cc_agent_accept_request(agent->core_id, "SIP caller %s has requested CC via SUBSCRIBE", 24466 agent->device_name); 24467 24468 /* We don't send a response here. That is done in the agent's ack callback or in the 24469 * agent destructor, should a failure occur before we have responded 24470 */ 24471 ao2_ref(agent, -1); 24472 return 0; 24473 }
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 26651 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(), and reload_config().
26652 { 26653 int res = 1; 26654 26655 if (!strcasecmp(v->name, "trustrpid")) { 26656 ast_set_flag(&mask[0], SIP_TRUSTRPID); 26657 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 26658 } else if (!strcasecmp(v->name, "sendrpid")) { 26659 ast_set_flag(&mask[0], SIP_SENDRPID); 26660 if (!strcasecmp(v->value, "pai")) { 26661 ast_set_flag(&flags[0], SIP_SENDRPID_PAI); 26662 } else if (!strcasecmp(v->value, "rpid")) { 26663 ast_set_flag(&flags[0], SIP_SENDRPID_RPID); 26664 } else if (ast_true(v->value)) { 26665 ast_set_flag(&flags[0], SIP_SENDRPID_RPID); 26666 } 26667 } else if (!strcasecmp(v->name, "rpid_update")) { 26668 ast_set_flag(&mask[1], SIP_PAGE2_RPID_UPDATE); 26669 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_UPDATE); 26670 } else if (!strcasecmp(v->name, "rpid_immediate")) { 26671 ast_set_flag(&mask[1], SIP_PAGE2_RPID_IMMEDIATE); 26672 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_IMMEDIATE); 26673 } else if (!strcasecmp(v->name, "g726nonstandard")) { 26674 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 26675 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 26676 } else if (!strcasecmp(v->name, "useclientcode")) { 26677 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 26678 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 26679 } else if (!strcasecmp(v->name, "dtmfmode")) { 26680 ast_set_flag(&mask[0], SIP_DTMF); 26681 ast_clear_flag(&flags[0], SIP_DTMF); 26682 if (!strcasecmp(v->value, "inband")) 26683 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 26684 else if (!strcasecmp(v->value, "rfc2833")) 26685 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 26686 else if (!strcasecmp(v->value, "info")) 26687 ast_set_flag(&flags[0], SIP_DTMF_INFO); 26688 else if (!strcasecmp(v->value, "shortinfo")) 26689 ast_set_flag(&flags[0], SIP_DTMF_SHORTINFO); 26690 else if (!strcasecmp(v->value, "auto")) 26691 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 26692 else { 26693 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 26694 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 26695 } 26696 } else if (!strcasecmp(v->name, "nat")) { 26697 ast_set_flag(&mask[0], SIP_NAT_FORCE_RPORT); 26698 ast_set_flag(&flags[0], SIP_NAT_FORCE_RPORT); /* Default to "force_rport" */ 26699 if (!strcasecmp(v->value, "no")) { 26700 ast_clear_flag(&flags[0], SIP_NAT_FORCE_RPORT); 26701 } else if (!strcasecmp(v->value, "yes")) { 26702 /* We've already defaulted to force_rport */ 26703 ast_set_flag(&mask[1], SIP_PAGE2_SYMMETRICRTP); 26704 ast_set_flag(&flags[1], SIP_PAGE2_SYMMETRICRTP); 26705 } else if (!strcasecmp(v->value, "comedia")) { 26706 ast_clear_flag(&flags[0], SIP_NAT_FORCE_RPORT); 26707 ast_set_flag(&mask[1], SIP_PAGE2_SYMMETRICRTP); 26708 ast_set_flag(&flags[1], SIP_PAGE2_SYMMETRICRTP); 26709 } 26710 } else if (!strcasecmp(v->name, "directmedia") || !strcasecmp(v->name, "canreinvite")) { 26711 ast_set_flag(&mask[0], SIP_REINVITE); 26712 ast_clear_flag(&flags[0], SIP_REINVITE); 26713 if (ast_true(v->value)) { 26714 ast_set_flag(&flags[0], SIP_DIRECT_MEDIA | SIP_DIRECT_MEDIA_NAT); 26715 } else if (!ast_false(v->value)) { 26716 char buf[64]; 26717 char *word, *next = buf; 26718 26719 ast_copy_string(buf, v->value, sizeof(buf)); 26720 while ((word = strsep(&next, ","))) { 26721 if (!strcasecmp(word, "update")) { 26722 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_DIRECT_MEDIA); 26723 } else if (!strcasecmp(word, "nonat")) { 26724 ast_set_flag(&flags[0], SIP_DIRECT_MEDIA); 26725 ast_clear_flag(&flags[0], SIP_DIRECT_MEDIA_NAT); 26726 } else { 26727 ast_log(LOG_WARNING, "Unknown directmedia mode '%s' on line %d\n", v->value, v->lineno); 26728 } 26729 } 26730 } 26731 } else if (!strcasecmp(v->name, "insecure")) { 26732 ast_set_flag(&mask[0], SIP_INSECURE); 26733 ast_clear_flag(&flags[0], SIP_INSECURE); 26734 set_insecure_flags(&flags[0], v->value, v->lineno); 26735 } else if (!strcasecmp(v->name, "progressinband")) { 26736 ast_set_flag(&mask[0], SIP_PROG_INBAND); 26737 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 26738 if (ast_true(v->value)) 26739 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 26740 else if (strcasecmp(v->value, "never")) 26741 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 26742 } else if (!strcasecmp(v->name, "promiscredir")) { 26743 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 26744 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 26745 } else if (!strcasecmp(v->name, "videosupport")) { 26746 if (!strcasecmp(v->value, "always")) { 26747 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS); 26748 ast_set_flag(&flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS); 26749 } else { 26750 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 26751 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 26752 } 26753 } else if (!strcasecmp(v->name, "textsupport")) { 26754 ast_set_flag(&mask[1], SIP_PAGE2_TEXTSUPPORT); 26755 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_TEXTSUPPORT); 26756 res = 1; 26757 } else if (!strcasecmp(v->name, "allowoverlap")) { 26758 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 26759 ast_clear_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP); 26760 if (ast_true(v->value)) { 26761 ast_set_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP_YES); 26762 } else if (!strcasecmp(v->value, "dtmf")){ 26763 ast_set_flag(&flags[1], SIP_PAGE2_ALLOWOVERLAP_DTMF); 26764 } 26765 } else if (!strcasecmp(v->name, "allowsubscribe")) { 26766 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 26767 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 26768 } else if (!strcasecmp(v->name, "ignoresdpversion")) { 26769 ast_set_flag(&mask[1], SIP_PAGE2_IGNORESDPVERSION); 26770 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_IGNORESDPVERSION); 26771 } else if (!strcasecmp(v->name, "faxdetect")) { 26772 ast_set_flag(&mask[1], SIP_PAGE2_FAX_DETECT); 26773 if (ast_true(v->value)) { 26774 ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH); 26775 } else if (ast_false(v->value)) { 26776 ast_clear_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH); 26777 } else { 26778 char *buf = ast_strdupa(v->value); 26779 char *word, *next = buf; 26780 26781 while ((word = strsep(&next, ","))) { 26782 if (!strcasecmp(word, "cng")) { 26783 ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_CNG); 26784 } else if (!strcasecmp(word, "t38")) { 26785 ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_T38); 26786 } else { 26787 ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno); 26788 } 26789 } 26790 } 26791 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 26792 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 26793 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 26794 } else if (!strcasecmp(v->name, "buggymwi")) { 26795 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 26796 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 26797 } else 26798 res = 0; 26799 26800 return res; 26801 }
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 24929 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(), global_store_sip_cause, handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_publish(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_request_update(), handle_response(), 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().
24930 { 24931 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 24932 relatively static */ 24933 const char *cmd; 24934 const char *cseq; 24935 const char *useragent; 24936 const char *via; 24937 const char *callid; 24938 int via_pos = 0; 24939 int seqno; 24940 int len; 24941 int respid; 24942 int res = 0; 24943 int debug = sip_debug_test_pvt(p); 24944 const char *e; 24945 int error = 0; 24946 int oldmethod = p->method; 24947 int acked = 0; 24948 24949 /* RFC 3261 - 8.1.1 A valid SIP request must contain To, From, CSeq, Call-ID and Via. 24950 * 8.2.6.2 Response must have To, From, Call-ID CSeq, and Via related to the request, 24951 * so we can check to make sure these fields exist for all requests and responses */ 24952 cseq = get_header(req, "Cseq"); 24953 cmd = REQ_OFFSET_TO_STR(req, header[0]); 24954 /* Save the via_pos so we can check later that responses only have 1 Via header */ 24955 via = __get_header(req, "Via", &via_pos); 24956 /* This must exist already because we've called find_call by now */ 24957 callid = get_header(req, "Call-ID"); 24958 24959 /* Must have Cseq */ 24960 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq) || ast_strlen_zero(via)) { 24961 ast_log(LOG_ERROR, "Dropping this SIP message with Call-ID '%s', it's incomplete.\n", callid); 24962 error = 1; 24963 } 24964 if (!error && sscanf(cseq, "%30d%n", &seqno, &len) != 1) { 24965 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 24966 error = 1; 24967 } 24968 if (error) { 24969 if (!p->initreq.headers) { /* New call */ 24970 pvt_set_needdestroy(p, "no headers"); 24971 } 24972 return -1; 24973 } 24974 /* Get the command XXX */ 24975 24976 cmd = REQ_OFFSET_TO_STR(req, rlPart1); 24977 e = ast_skip_blanks(REQ_OFFSET_TO_STR(req, rlPart2)); 24978 24979 /* Save useragent of the client */ 24980 useragent = get_header(req, "User-Agent"); 24981 if (!ast_strlen_zero(useragent)) 24982 ast_string_field_set(p, useragent, useragent); 24983 24984 /* Find out SIP method for incoming request */ 24985 if (req->method == SIP_RESPONSE) { /* Response to our request */ 24986 /* ignore means "don't do anything with it" but still have to 24987 * respond appropriately. 24988 * But in this case this is a response already, so we really 24989 * have nothing to do with this message, and even setting the 24990 * ignore flag is pointless. 24991 */ 24992 if (ast_strlen_zero(e)) { 24993 return 0; 24994 } 24995 if (sscanf(e, "%30d %n", &respid, &len) != 1) { 24996 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 24997 return 0; 24998 } 24999 if (respid <= 0) { 25000 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 25001 return 0; 25002 } 25003 /* RFC 3261 - 8.1.3.3 If more than one Via header field value is present in a reponse 25004 * the UAC SHOULD discard the message. This is not perfect, as it will not catch multiple 25005 * headers joined with a comma. Fixing that would pretty much involve writing a new parser */ 25006 if (!ast_strlen_zero(__get_header(req, "via", &via_pos))) { 25007 ast_log(LOG_WARNING, "Misrouted SIP response '%s' with Call-ID '%s', too many vias\n", e, callid); 25008 return 0; 25009 } 25010 if (p->ocseq && (p->ocseq < seqno)) { 25011 ast_debug(1, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 25012 return -1; 25013 } else { 25014 char causevar[256], causeval[256]; 25015 25016 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) { 25017 extract_uri(p, req); 25018 } 25019 25020 handle_response(p, respid, e + len, req, seqno); 25021 25022 if (global_store_sip_cause && p->owner) { 25023 struct ast_channel *owner = p->owner; 25024 25025 snprintf(causevar, sizeof(causevar), "MASTER_CHANNEL(HASH(SIP_CAUSE,%s))", owner->name); 25026 snprintf(causeval, sizeof(causeval), "SIP %s", REQ_OFFSET_TO_STR(req, rlPart2)); 25027 25028 ast_channel_ref(owner); 25029 sip_pvt_unlock(p); 25030 ast_channel_unlock(owner); 25031 *nounlock = 1; 25032 pbx_builtin_setvar_helper(owner, causevar, causeval); 25033 ast_channel_unref(owner); 25034 sip_pvt_lock(p); 25035 } 25036 } 25037 return 0; 25038 } 25039 25040 /* New SIP request coming in 25041 (could be new request in existing SIP dialog as well...) 25042 */ 25043 25044 p->method = req->method; /* Find out which SIP method they are using */ 25045 ast_debug(4, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 25046 25047 if (p->icseq && (p->icseq > seqno) ) { 25048 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 25049 ast_debug(2, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 25050 } else { 25051 ast_debug(1, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 25052 if (req->method == SIP_INVITE) { 25053 unsigned int ran = (ast_random() % 10) + 1; 25054 char seconds[4]; 25055 snprintf(seconds, sizeof(seconds), "%u", ran); 25056 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 */ 25057 } else if (req->method != SIP_ACK) { 25058 transmit_response(p, "500 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 25059 } 25060 return -1; 25061 } 25062 } else if (p->icseq && 25063 p->icseq == seqno && 25064 req->method != SIP_ACK && 25065 (p->method != SIP_CANCEL || p->alreadygone)) { 25066 /* ignore means "don't do anything with it" but still have to 25067 respond appropriately. We do this if we receive a repeat of 25068 the last sequence number */ 25069 req->ignore = 1; 25070 ast_debug(3, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 25071 } 25072 25073 /* RFC 3261 section 9. "CANCEL has no effect on a request to which a UAS has 25074 * already given a final response." */ 25075 if (!p->pendinginvite && (req->method == SIP_CANCEL)) { 25076 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 25077 return res; 25078 } 25079 25080 if (seqno >= p->icseq) 25081 /* Next should follow monotonically (but not necessarily 25082 incrementally -- thanks again to the genius authors of SIP -- 25083 increasing */ 25084 p->icseq = seqno; 25085 25086 /* Find their tag if we haven't got it */ 25087 if (ast_strlen_zero(p->theirtag)) { 25088 char tag[128]; 25089 25090 gettag(req, "From", tag, sizeof(tag)); 25091 ast_string_field_set(p, theirtag, tag); 25092 } 25093 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 25094 25095 if (sip_cfg.pedanticsipchecking) { 25096 /* If this is a request packet without a from tag, it's not 25097 correct according to RFC 3261 */ 25098 /* Check if this a new request in a new dialog with a totag already attached to it, 25099 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 25100 if (!p->initreq.headers && req->has_to_tag) { 25101 /* If this is a first request and it got a to-tag, it is not for us */ 25102 if (!req->ignore && req->method == SIP_INVITE) { 25103 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 25104 /* Will cease to exist after ACK */ 25105 } else if (req->method != SIP_ACK) { 25106 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 25107 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 25108 } else { 25109 ast_debug(1, "Got ACK for unknown dialog... strange.\n"); 25110 } 25111 return res; 25112 } 25113 } 25114 25115 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY || p->method == SIP_PUBLISH)) { 25116 transmit_response(p, "400 Bad request", req); 25117 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 25118 return -1; 25119 } 25120 25121 /* Handle various incoming SIP methods in requests */ 25122 switch (p->method) { 25123 case SIP_OPTIONS: 25124 res = handle_request_options(p, req, addr, e); 25125 break; 25126 case SIP_INVITE: 25127 res = handle_request_invite(p, req, debug, seqno, addr, recount, e, nounlock); 25128 break; 25129 case SIP_REFER: 25130 res = handle_request_refer(p, req, debug, seqno, nounlock); 25131 break; 25132 case SIP_CANCEL: 25133 res = handle_request_cancel(p, req); 25134 break; 25135 case SIP_BYE: 25136 res = handle_request_bye(p, req); 25137 break; 25138 case SIP_MESSAGE: 25139 res = handle_request_message(p, req); 25140 break; 25141 case SIP_PUBLISH: 25142 res = handle_request_publish(p, req, addr, seqno, e); 25143 break; 25144 case SIP_SUBSCRIBE: 25145 res = handle_request_subscribe(p, req, addr, seqno, e); 25146 break; 25147 case SIP_REGISTER: 25148 res = handle_request_register(p, req, addr, e); 25149 break; 25150 case SIP_INFO: 25151 if (req->debug) 25152 ast_verbose("Receiving INFO!\n"); 25153 if (!req->ignore) 25154 handle_request_info(p, req); 25155 else /* if ignoring, transmit response */ 25156 transmit_response(p, "200 OK", req); 25157 break; 25158 case SIP_NOTIFY: 25159 res = handle_request_notify(p, req, addr, seqno, e); 25160 break; 25161 case SIP_UPDATE: 25162 res = handle_request_update(p, req); 25163 break; 25164 case SIP_ACK: 25165 /* Make sure we don't ignore this */ 25166 if (seqno == p->pendinginvite) { 25167 p->invitestate = INV_TERMINATED; 25168 p->pendinginvite = 0; 25169 acked = __sip_ack(p, seqno, 1 /* response */, 0); 25170 if (find_sdp(req)) { 25171 if (process_sdp(p, req, SDP_T38_NONE)) 25172 return -1; 25173 } 25174 check_pendings(p); 25175 } else if (p->glareinvite == seqno) { 25176 /* handle ack for the 491 pending sent for glareinvite */ 25177 p->glareinvite = 0; 25178 acked = __sip_ack(p, seqno, 1, 0); 25179 } 25180 if (!acked) { 25181 /* Got an ACK that did not match anything. Ignore 25182 * silently and restore previous method */ 25183 p->method = oldmethod; 25184 } 25185 if (!p->lastinvite && ast_strlen_zero(p->randdata)) { 25186 pvt_set_needdestroy(p, "unmatched ACK"); 25187 } 25188 break; 25189 default: 25190 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 25191 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 25192 cmd, ast_sockaddr_stringify(&p->sa)); 25193 /* If this is some new method, and we don't have a call, destroy it now */ 25194 if (!p->initreq.headers) { 25195 pvt_set_needdestroy(p, "unimplemented method"); 25196 } 25197 break; 25198 } 25199 return res; 25200 }
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 21921 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().
21922 { 21923 int earlyreplace = 0; 21924 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 21925 struct ast_channel *c = p->owner; /* Our incoming call */ 21926 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 21927 struct ast_channel *targetcall; /* The bridge to the take-over target */ 21928 21929 /* Check if we're in ring state */ 21930 if (replacecall->_state == AST_STATE_RING) 21931 earlyreplace = 1; 21932 21933 /* Check if we have a bridge */ 21934 if (!(targetcall = ast_bridged_channel(replacecall))) { 21935 /* We have no bridge */ 21936 if (!earlyreplace) { 21937 ast_debug(2, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 21938 oneleggedreplace = 1; 21939 } 21940 } 21941 if (targetcall && targetcall->_state == AST_STATE_RINGING) 21942 ast_debug(4, "SIP transfer: Target channel is in ringing state\n"); 21943 21944 if (targetcall) 21945 ast_debug(4, "SIP transfer: Invite Replace incoming channel should bridge to channel %s while hanging up channel %s\n", targetcall->name, replacecall->name); 21946 else 21947 ast_debug(4, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 21948 21949 if (req->ignore) { 21950 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 21951 /* We should answer something here. If we are here, the 21952 call we are replacing exists, so an accepted 21953 can't harm */ 21954 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE); 21955 /* Do something more clever here */ 21956 if (c) { 21957 *nounlock = 1; 21958 ast_channel_unlock(c); 21959 } 21960 ast_channel_unlock(replacecall); 21961 sip_pvt_unlock(p->refer->refer_call); 21962 return 1; 21963 } 21964 if (!c) { 21965 /* What to do if no channel ??? */ 21966 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 21967 transmit_response_reliable(p, "503 Service Unavailable", req); 21968 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 21969 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21970 ast_channel_unlock(replacecall); 21971 sip_pvt_unlock(p->refer->refer_call); 21972 return 1; 21973 } 21974 append_history(p, "Xfer", "INVITE/Replace received"); 21975 /* We have three channels to play with 21976 channel c: New incoming call 21977 targetcall: Call from PBX to target 21978 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 21979 replacecall: The owner of the previous 21980 We need to masq C into refer_call to connect to 21981 targetcall; 21982 If we are talking to internal audio stream, target call is null. 21983 */ 21984 21985 /* Fake call progress */ 21986 transmit_response(p, "100 Trying", req); 21987 ast_setstate(c, AST_STATE_RING); 21988 21989 /* Masquerade the new call into the referred call to connect to target call 21990 Targetcall is not touched by the masq */ 21991 21992 /* Answer the incoming call and set channel to UP state */ 21993 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE); 21994 21995 ast_setstate(c, AST_STATE_UP); 21996 21997 /* Stop music on hold and other generators */ 21998 ast_quiet_chan(replacecall); 21999 ast_quiet_chan(targetcall); 22000 ast_debug(4, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 22001 22002 /* Make sure that the masq does not free our PVT for the old call */ 22003 if (! earlyreplace && ! oneleggedreplace ) 22004 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 22005 22006 /* Prepare the masquerade - if this does not happen, we will be gone */ 22007 if(ast_channel_masquerade(replacecall, c)) 22008 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 22009 else 22010 ast_debug(4, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 22011 22012 /* C should now be in place of replacecall. all channel locks and pvt locks should be removed 22013 * before issuing the masq. Since we are unlocking both the pvt (p) and its owner channel (c) 22014 * it is possible for channel c to be destroyed on us. To prevent this, we must give c a reference 22015 * before any unlocking takes place and remove it only once we are completely done with it */ 22016 ast_channel_ref(c); 22017 ast_channel_unlock(replacecall); 22018 ast_channel_unlock(c); 22019 sip_pvt_unlock(p->refer->refer_call); 22020 sip_pvt_unlock(p); 22021 if (ast_do_masquerade(replacecall)) { 22022 ast_log(LOG_WARNING, "Failed to perform masquerade with INVITE replaces\n"); 22023 } 22024 ast_channel_lock(c); 22025 if (earlyreplace || oneleggedreplace ) { 22026 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 22027 } 22028 ast_setstate(c, AST_STATE_DOWN); 22029 ast_channel_unlock(c); 22030 22031 /* The call should be down with no ast_channel, so hang it up */ 22032 c->tech_pvt = dialog_unref(c->tech_pvt, "unref dialog c->tech_pvt"); 22033 22034 /* c and c's tech pvt must be unlocked at this point for ast_hangup */ 22035 ast_hangup(c); 22036 /* this indicates to handle_request_do that the owner channel has already been unlocked */ 22037 *nounlock = 1; 22038 /* lock PVT structure again after hangup */ 22039 sip_pvt_lock(p); 22040 ast_channel_unref(c); 22041 return 0; 22042 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 23729 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, parse_sip_options(), 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().
23730 { 23731 struct ast_channel *c=NULL; 23732 int res; 23733 struct ast_channel *bridged_to; 23734 const char *required; 23735 23736 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 23737 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !req->ignore) { 23738 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 23739 } 23740 23741 __sip_pretend_ack(p); 23742 23743 p->invitestate = INV_TERMINATED; 23744 23745 copy_request(&p->initreq, req); 23746 if (sipdebug) 23747 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 23748 check_via(p, req); 23749 sip_alreadygone(p); 23750 23751 /* Get RTCP quality before end of call */ 23752 if (p->do_history || p->owner) { 23753 char quality_buf[AST_MAX_USER_FIELD], *quality; 23754 struct ast_channel *bridge = p->owner ? ast_bridged_channel(p->owner) : NULL; 23755 23756 /* We need to get the lock on bridge because ast_rtp_instance_set_stats_vars will attempt 23757 * to lock the bridge. This may get hairy... 23758 */ 23759 while (bridge && ast_channel_trylock(bridge)) { 23760 ast_channel_unlock(p->owner); 23761 do { 23762 /* Can't use DEADLOCK_AVOIDANCE since p is an ao2 object */ 23763 sip_pvt_unlock(p); 23764 usleep(1); 23765 sip_pvt_lock(p); 23766 } while (p->owner && ast_channel_trylock(p->owner)); 23767 bridge = p->owner ? ast_bridged_channel(p->owner) : NULL; 23768 } 23769 23770 23771 if (p->rtp && (quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 23772 if (p->do_history) { 23773 append_history(p, "RTCPaudio", "Quality:%s", quality); 23774 23775 if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, quality_buf, sizeof(quality_buf)))) { 23776 append_history(p, "RTCPaudioJitter", "Quality:%s", quality); 23777 } 23778 if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, quality_buf, sizeof(quality_buf)))) { 23779 append_history(p, "RTCPaudioLoss", "Quality:%s", quality); 23780 } 23781 if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, quality_buf, sizeof(quality_buf)))) { 23782 append_history(p, "RTCPaudioRTT", "Quality:%s", quality); 23783 } 23784 } 23785 23786 if (p->owner) { 23787 ast_rtp_instance_set_stats_vars(p->owner, p->rtp); 23788 } 23789 23790 } 23791 23792 if (bridge) { 23793 struct sip_pvt *q = bridge->tech_pvt; 23794 23795 if (IS_SIP_TECH(bridge->tech) && q && q->rtp) { 23796 ast_rtp_instance_set_stats_vars(bridge, q->rtp); 23797 } 23798 ast_channel_unlock(bridge); 23799 } 23800 23801 if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 23802 if (p->do_history) { 23803 append_history(p, "RTCPvideo", "Quality:%s", quality); 23804 } 23805 if (p->owner) { 23806 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", quality); 23807 } 23808 } 23809 if (p->trtp && (quality = ast_rtp_instance_get_quality(p->trtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 23810 if (p->do_history) { 23811 append_history(p, "RTCPtext", "Quality:%s", quality); 23812 } 23813 if (p->owner) { 23814 pbx_builtin_setvar_helper(p->owner, "RTPTEXTQOS", quality); 23815 } 23816 } 23817 } 23818 23819 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 23820 stop_session_timer(p); /* Stop Session-Timer */ 23821 23822 if (!ast_strlen_zero(get_header(req, "Also"))) { 23823 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 23824 ast_sockaddr_stringify(&p->recv)); 23825 if (ast_strlen_zero(p->context)) 23826 ast_string_field_set(p, context, sip_cfg.default_context); 23827 res = get_also_info(p, req); 23828 if (!res) { 23829 c = p->owner; 23830 if (c) { 23831 bridged_to = ast_bridged_channel(c); 23832 if (bridged_to) { 23833 /* Don't actually hangup here... */ 23834 ast_queue_control(c, AST_CONTROL_UNHOLD); 23835 ast_channel_unlock(c); /* async_goto can do a masquerade, no locks can be held during a masq */ 23836 ast_async_goto(bridged_to, p->context, p->refer->refer_to, 1); 23837 ast_channel_lock(c); 23838 } else 23839 ast_queue_hangup(p->owner); 23840 } 23841 } else { 23842 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_sockaddr_stringify(&p->recv)); 23843 if (p->owner) 23844 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR); 23845 } 23846 } else if (p->owner) { 23847 ast_set_hangupsource(p->owner, p->owner->name, 0); 23848 ast_queue_hangup(p->owner); 23849 sip_scheddestroy_final(p, DEFAULT_TRANS_TIMEOUT); 23850 ast_debug(3, "Received bye, issuing owner hangup\n"); 23851 } else { 23852 sip_scheddestroy_final(p, DEFAULT_TRANS_TIMEOUT); 23853 ast_debug(3, "Received bye, no owner, selfdestruct soon.\n"); 23854 } 23855 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 23856 23857 /* Find out what they require */ 23858 required = get_header(req, "Require"); 23859 if (!ast_strlen_zero(required)) { 23860 char unsupported[256] = { 0, }; 23861 parse_sip_options(required, unsupported, ARRAY_LEN(unsupported)); 23862 /* If there are any options required that we do not support, 23863 * then send a 420 with only those unsupported options listed */ 23864 if (!ast_strlen_zero(unsupported)) { 23865 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported); 23866 ast_log(LOG_WARNING, "Received SIP BYE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported); 23867 } else { 23868 transmit_response(p, "200 OK", req); 23869 } 23870 } else { 23871 transmit_response(p, "200 OK", req); 23872 } 23873 23874 return 1; 23875 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 23660 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_str_strlen(), 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().
23661 { 23662 23663 check_via(p, req); 23664 sip_alreadygone(p); 23665 23666 if (p->owner && p->owner->_state == AST_STATE_UP) { 23667 /* This call is up, cancel is ignored, we need a bye */ 23668 transmit_response(p, "200 OK", req); 23669 ast_debug(1, "Got CANCEL on an answered call. Ignoring... \n"); 23670 return 0; 23671 } 23672 23673 /* At this point, we could have cancelled the invite at the same time 23674 as the other side sends a CANCEL. Our final reply with error code 23675 might not have been received by the other side before the CANCEL 23676 was sent, so let's just give up retransmissions and waiting for 23677 ACK on our error code. The call is hanging up any way. */ 23678 if (p->invitestate == INV_TERMINATED || p->invitestate == INV_COMPLETED) { 23679 __sip_pretend_ack(p); 23680 } 23681 if (p->invitestate != INV_TERMINATED) 23682 p->invitestate = INV_CANCELLED; 23683 23684 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 23685 update_call_counter(p, DEC_CALL_LIMIT); 23686 23687 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 23688 if (p->owner) { 23689 ast_set_hangupsource(p->owner, p->owner->name, 0); 23690 ast_queue_hangup(p->owner); 23691 } 23692 else 23693 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 23694 if (ast_str_strlen(p->initreq.data) > 0) { 23695 struct sip_pkt *pkt, *prev_pkt; 23696 /* If the CANCEL we are receiving is a retransmission, and we already have scheduled 23697 * a reliable 487, then we don't want to schedule another one on top of the previous 23698 * one. 23699 * 23700 * As odd as this may sound, we can't rely on the previously-transmitted "reliable" 23701 * response in this situation. What if we've sent all of our reliable responses 23702 * already and now all of a sudden, we get this second CANCEL? 23703 * 23704 * The only way to do this correctly is to cancel our previously-scheduled reliably- 23705 * transmitted response and send a new one in its place. 23706 */ 23707 for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->next) { 23708 if (pkt->seqno == p->lastinvite && pkt->response_code == 487) { 23709 AST_SCHED_DEL(sched, pkt->retransid); 23710 UNLINK(pkt, p->packets, prev_pkt); 23711 dialog_unref(pkt->owner, "unref packet->owner from dialog"); 23712 if (pkt->data) { 23713 ast_free(pkt->data); 23714 } 23715 ast_free(pkt); 23716 break; 23717 } 23718 } 23719 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 23720 transmit_response(p, "200 OK", req); 23721 return 1; 23722 } else { 23723 transmit_response(p, "481 Call Leg Does Not Exist", req); 23724 return 0; 23725 } 23726 }
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 25252 of file chan_sip.c.
References ao2_t_ref, append_history, ast_channel_unlock, ast_channel_unref, ast_debug, ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_copy(), ast_sockaddr_stringify(), ast_str_reset(), ast_str_strlen(), ast_update_use_count(), ast_verbose, copy_socket_data(), find_call(), find_sip_method(), get_header(), get_transport(), handle_incoming(), lws2sws(), netlock, parse_request(), sip_cfg, sip_debug_test_addr(), sip_pvt_lock_full(), and sip_pvt_unlock.
Referenced by sipsock_read().
25253 { 25254 struct sip_pvt *p; 25255 struct ast_channel *owner_chan_ref = NULL; 25256 int recount = 0; 25257 int nounlock = 0; 25258 25259 if (sip_debug_test_addr(addr)) /* Set the debug flag early on packet level */ 25260 req->debug = 1; 25261 if (sip_cfg.pedanticsipchecking) 25262 lws2sws(req->data); /* Fix multiline headers */ 25263 if (req->debug) { 25264 ast_verbose("\n<--- SIP read from %s:%s --->\n%s\n<------------->\n", 25265 get_transport(req->socket.type), ast_sockaddr_stringify(addr), req->data->str); 25266 } 25267 25268 if (parse_request(req) == -1) { /* Bad packet, can't parse */ 25269 ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */ 25270 return 1; 25271 } 25272 req->method = find_sip_method(REQ_OFFSET_TO_STR(req, rlPart1)); 25273 25274 if (req->debug) 25275 ast_verbose("--- (%d headers %d lines)%s ---\n", req->headers, req->lines, (req->headers + req->lines == 0) ? " Nat keepalive" : ""); 25276 25277 if (req->headers < 2) { /* Must have at least two headers */ 25278 ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */ 25279 return 1; 25280 } 25281 25282 /* Process request, with netlock held, and with usual deadlock avoidance */ 25283 ast_mutex_lock(&netlock); 25284 25285 /* Find the active SIP dialog or create a new one */ 25286 p = find_call(req, addr, req->method); /* returns p with a reference only. _NOT_ locked*/ 25287 if (p == NULL) { 25288 ast_debug(1, "Invalid SIP message - rejected , no callid, len %zu\n", ast_str_strlen(req->data)); 25289 ast_mutex_unlock(&netlock); 25290 return 1; 25291 } 25292 25293 /* Lock both the pvt and the owner if owner is present. This will 25294 * not fail. */ 25295 owner_chan_ref = sip_pvt_lock_full(p); 25296 25297 copy_socket_data(&p->socket, &req->socket); 25298 ast_sockaddr_copy(&p->recv, addr); 25299 25300 /* if we have an owner, then this request has been authenticated */ 25301 if (p->owner) { 25302 req->authenticated = 1; 25303 } 25304 25305 if (p->do_history) /* This is a request or response, note what it was for */ 25306 append_history(p, "Rx", "%s / %s / %s", req->data->str, get_header(req, "CSeq"), REQ_OFFSET_TO_STR(req, rlPart2)); 25307 25308 if (handle_incoming(p, req, addr, &recount, &nounlock) == -1) { 25309 /* Request failed */ 25310 ast_debug(1, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 25311 } 25312 25313 if (recount) { 25314 ast_update_use_count(); 25315 } 25316 25317 if (p->owner && !nounlock) { 25318 ast_channel_unlock(p->owner); 25319 } 25320 if (owner_chan_ref) { 25321 ast_channel_unref(owner_chan_ref); 25322 } 25323 sip_pvt_unlock(p); 25324 ao2_t_ref(p, -1, "throw away dialog ptr from find_call at end of routine"); /* p is gone after the return */ 25325 ast_mutex_unlock(&netlock); 25326 25327 return 1; 25328 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 18710 of file chan_sip.c.
References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, ast_copy_string(), ast_debug, ast_find_call_feature(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), AST_LOG_WARNING, ast_queue_control(), ast_queue_frame(), ast_rdlock_call_features(), ast_strlen_zero(), ast_test_flag, ast_unlock_call_features(), ast_verbose, ast_channel::cdr, ast_call_feature::exten, f, get_body(), get_header(), get_msg_text(), LOG_WARNING, sip_scheddestroy(), and transmit_response().
Referenced by handle_incoming().
18711 { 18712 char buf[1024] = ""; 18713 unsigned int event; 18714 const char *c = get_header(req, "Content-Type"); 18715 18716 /* Need to check the media/type */ 18717 if (!strcasecmp(c, "application/dtmf-relay") || 18718 !strcasecmp(c, "application/vnd.nortelnetworks.digits") || 18719 !strcasecmp(c, "application/dtmf")) { 18720 unsigned int duration = 0; 18721 18722 if (!p->owner) { /* not a PBX call */ 18723 transmit_response(p, "481 Call leg/transaction does not exist", req); 18724 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 18725 return; 18726 } 18727 18728 /* If dtmf-relay or vnd.nortelnetworks.digits, parse the signal and duration; 18729 * otherwise use the body as the signal */ 18730 if (strcasecmp(c, "application/dtmf")) { 18731 const char *msg_body; 18732 18733 if ( ast_strlen_zero(msg_body = get_body(req, "Signal", '=')) 18734 && ast_strlen_zero(msg_body = get_body(req, "d", '='))) { 18735 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal for INFO message on " 18736 "call %s\n", p->callid); 18737 transmit_response(p, "200 OK", req); 18738 return; 18739 } 18740 ast_copy_string(buf, msg_body, sizeof(buf)); 18741 18742 if (!ast_strlen_zero((msg_body = get_body(req, "Duration", '=')))) { 18743 sscanf(msg_body, "%30u", &duration); 18744 } 18745 } else { 18746 /* Type is application/dtmf, simply use what's in the message body */ 18747 get_msg_text(buf, sizeof(buf), req); 18748 } 18749 18750 /* An empty message body requires us to send a 200 OK */ 18751 if (ast_strlen_zero(buf)) { 18752 transmit_response(p, "200 OK", req); 18753 return; 18754 } 18755 18756 if (!duration) { 18757 duration = 100; /* 100 ms */ 18758 } 18759 18760 if (buf[0] == '*') { 18761 event = 10; 18762 } else if (buf[0] == '#') { 18763 event = 11; 18764 } else if (buf[0] == '!') { 18765 event = 16; 18766 } else if ('A' <= buf[0] && buf[0] <= 'D') { 18767 event = 12 + buf[0] - 'A'; 18768 } else if ('a' <= buf[0] && buf[0] <= 'd') { 18769 event = 12 + buf[0] - 'a'; 18770 } else if ((sscanf(buf, "%30u", &event) != 1) || event > 16) { 18771 ast_log(AST_LOG_WARNING, "Unable to convert DTMF event signal code to a valid " 18772 "value for INFO message on call %s\n", p->callid); 18773 transmit_response(p, "200 OK", req); 18774 return; 18775 } 18776 18777 if (event == 16) { 18778 /* send a FLASH event */ 18779 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH, } }; 18780 ast_queue_frame(p->owner, &f); 18781 if (sipdebug) { 18782 ast_verbose("* DTMF-relay event received: FLASH\n"); 18783 } 18784 } else { 18785 /* send a DTMF event */ 18786 struct ast_frame f = { AST_FRAME_DTMF, }; 18787 if (event < 10) { 18788 f.subclass.integer = '0' + event; 18789 } else if (event == 10) { 18790 f.subclass.integer = '*'; 18791 } else if (event == 11) { 18792 f.subclass.integer = '#'; 18793 } else { 18794 f.subclass.integer = 'A' + (event - 12); 18795 } 18796 f.len = duration; 18797 ast_queue_frame(p->owner, &f); 18798 if (sipdebug) { 18799 ast_verbose("* DTMF-relay event received: %c\n", (int) f.subclass.integer); 18800 } 18801 } 18802 transmit_response(p, "200 OK", req); 18803 return; 18804 } else if (!strcasecmp(c, "application/media_control+xml")) { 18805 /* Eh, we'll just assume it's a fast picture update for now */ 18806 if (p->owner) 18807 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 18808 transmit_response(p, "200 OK", req); 18809 return; 18810 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 18811 /* Client code (from SNOM phone) */ 18812 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 18813 if (p->owner && p->owner->cdr) 18814 ast_cdr_setuserfield(p->owner, c); 18815 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 18816 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 18817 transmit_response(p, "200 OK", req); 18818 } else { 18819 transmit_response(p, "403 Forbidden", req); 18820 } 18821 return; 18822 } else if (!ast_strlen_zero(c = get_header(req, "Record"))) { 18823 /* INFO messages generated by some phones to start/stop recording 18824 on phone calls. 18825 OEJ: I think this should be something that is enabled/disabled 18826 per device. I don't want incoming callers to record calls in my 18827 pbx. 18828 */ 18829 18830 struct ast_call_feature *feat; 18831 int j; 18832 struct ast_frame f = { AST_FRAME_DTMF, }; 18833 18834 if (!p->owner) { /* not a PBX call */ 18835 transmit_response(p, "481 Call leg/transaction does not exist", req); 18836 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 18837 return; 18838 } 18839 18840 /* first, get the feature string, if it exists */ 18841 ast_rdlock_call_features(); 18842 feat = ast_find_call_feature("automon"); 18843 if (!feat || ast_strlen_zero(feat->exten)) { 18844 ast_log(LOG_WARNING, "Recording requested, but no One Touch Monitor registered. (See features.conf)\n"); 18845 /* 403 means that we don't support this feature, so don't request it again */ 18846 transmit_response(p, "403 Forbidden", req); 18847 ast_unlock_call_features(); 18848 return; 18849 } 18850 /* Send the feature code to the PBX as DTMF, just like the handset had sent it */ 18851 f.len = 100; 18852 for (j=0; j < strlen(feat->exten); j++) { 18853 f.subclass.integer = feat->exten[j]; 18854 ast_queue_frame(p->owner, &f); 18855 if (sipdebug) 18856 ast_verbose("* DTMF-relay event faked: %c\n", f.subclass.integer); 18857 } 18858 ast_unlock_call_features(); 18859 18860 ast_debug(1, "Got a Request to Record the channel, state %s\n", c); 18861 transmit_response(p, "200 OK", req); 18862 return; 18863 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 18864 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 18865 transmit_response(p, "200 OK", req); 18866 return; 18867 } 18868 18869 /* Other type of INFO message, not really understood by Asterisk */ 18870 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 18871 18872 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 18873 transmit_response(p, "415 Unsupported media type", req); 18874 return; 18875 }
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 22137 of file chan_sip.c.
References __sip_ack(), ast_channel::_state, append_history, ARRAY_LEN, AST_CAUSE_FAILURE, ast_cc_agent_set_interfaces_chanvar(), ast_channel_queue_connected_line_update(), ast_channel_set_redirecting(), ast_channel_unlock, ast_clear_flag, AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, AST_CONTROL_BUSY, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, ast_copy_string(), ast_debug, ast_hangup(), ast_log(), AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_null_frame, ast_party_connected_line_init(), ast_party_redirecting_free(), ast_party_redirecting_init(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_ext(), ast_queue_control(), ast_queue_frame(), ast_rtp_instance_set_alt_remote_address(), ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_setstate(), ast_setup_cc_recall_datastore(), ast_skip_blanks(), ast_sockaddr_stringify(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose, build_contact(), build_route(), change_hold_state(), change_redirecting_information(), check_user_full(), check_via(), connected, context, copy_request(), do_magic_pickup(), ast_channel::exten, exten, extract_uri(), FALSE, find_sdp(), get_destination(), get_header(), get_ip_and_port_from_sdp(), get_rpid(), get_sip_pvt_byid_locked(), global_max_se, handle_invite_replaces(), ast_channel::hangupcause, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_our_tag(), ast_channel::name, parse_minse(), parse_ok_contact(), parse_session_expires(), parse_sip_options(), process_sdp(), ref_peer(), restart_session_timer(), S_OR, set_pvt_allowed_methods(), sip_alreadygone(), sip_cancel_destroy(), sip_cfg, sip_methods, sip_new(), sip_pickup(), sip_pvt_lock, sip_pvt_unlock, sip_refer_allocate(), sip_scheddestroy(), sip_st_alloc(), sip_t38_abort(), sip_uri_cmp(), 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().
22138 { 22139 int res = 1; 22140 int gotdest; 22141 const char *p_replaces; 22142 char *replace_id = NULL; 22143 int refer_locked = 0; 22144 const char *required; 22145 unsigned int required_profile = 0; 22146 struct ast_channel *c = NULL; /* New channel */ 22147 struct sip_peer *authpeer = NULL; /* Matching Peer */ 22148 int reinvite = 0; 22149 int rtn; 22150 struct ast_party_redirecting redirecting; 22151 struct ast_set_party_redirecting update_redirecting; 22152 22153 const char *p_uac_se_hdr; /* UAC's Session-Expires header string */ 22154 const char *p_uac_min_se; /* UAC's requested Min-SE interval (char string) */ 22155 int uac_max_se = -1; /* UAC's Session-Expires in integer format */ 22156 int uac_min_se = -1; /* UAC's Min-SE in integer format */ 22157 int st_active = FALSE; /* Session-Timer on/off boolean */ 22158 int st_interval = 0; /* Session-Timer negotiated refresh interval */ 22159 enum st_refresher st_ref; /* Session-Timer session refresher */ 22160 int dlg_min_se = -1; 22161 struct { 22162 char exten[AST_MAX_EXTENSION]; 22163 char context[AST_MAX_CONTEXT]; 22164 } pickup = { 22165 .exten = "", 22166 }; 22167 st_ref = SESSION_TIMER_REFRESHER_AUTO; 22168 22169 /* Find out what they support */ 22170 if (!p->sipoptions) { 22171 const char *supported = get_header(req, "Supported"); 22172 if (!ast_strlen_zero(supported)) { 22173 p->sipoptions = parse_sip_options(supported, NULL, 0); 22174 } 22175 } 22176 22177 /* Find out what they require */ 22178 required = get_header(req, "Require"); 22179 if (!ast_strlen_zero(required)) { 22180 char unsupported[256] = { 0, }; 22181 required_profile = parse_sip_options(required, unsupported, ARRAY_LEN(unsupported)); 22182 22183 /* If there are any options required that we do not support, 22184 * then send a 420 with only those unsupported options listed */ 22185 if (!ast_strlen_zero(unsupported)) { 22186 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported); 22187 ast_log(LOG_WARNING, "Received SIP INVITE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported); 22188 p->invitestate = INV_COMPLETED; 22189 if (!p->lastinvite) 22190 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22191 res = -1; 22192 goto request_invite_cleanup; 22193 } 22194 } 22195 22196 /* The option tags may be present in Supported: or Require: headers. 22197 Include the Require: option tags for further processing as well */ 22198 p->sipoptions |= required_profile; 22199 p->reqsipoptions = required_profile; 22200 22201 /* Check if this is a loop */ 22202 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) { 22203 /* This is a call to ourself. Send ourselves an error code and stop 22204 processing immediately, as SIP really has no good mechanism for 22205 being able to call yourself */ 22206 /* If pedantic is on, we need to check the tags. If they're different, this is 22207 in fact a forked call through a SIP proxy somewhere. */ 22208 int different; 22209 const char *initial_rlPart2 = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); 22210 const char *this_rlPart2 = REQ_OFFSET_TO_STR(req, rlPart2); 22211 if (sip_cfg.pedanticsipchecking) 22212 different = sip_uri_cmp(initial_rlPart2, this_rlPart2); 22213 else 22214 different = strcmp(initial_rlPart2, this_rlPart2); 22215 if (!different) { 22216 transmit_response(p, "482 Loop Detected", req); 22217 p->invitestate = INV_COMPLETED; 22218 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22219 res = 0; 22220 goto request_invite_cleanup; 22221 } else { 22222 /*! This is a spiral. What we need to do is to just change the outgoing INVITE 22223 * so that it now routes to the new Request URI. Since we created the INVITE ourselves 22224 * that should be all we need to do. 22225 * 22226 * \todo XXX This needs to be reviewed. YOu don't change the request URI really, you route the packet 22227 * correctly instead... 22228 */ 22229 char *uri = ast_strdupa(this_rlPart2); 22230 char *at = strchr(uri, '@'); 22231 char *peerorhost; 22232 ast_debug(2, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", initial_rlPart2, this_rlPart2); 22233 transmit_response(p, "100 Trying", req); 22234 if (at) { 22235 *at = '\0'; 22236 } 22237 /* Parse out "sip:" */ 22238 if ((peerorhost = strchr(uri, ':'))) { 22239 *peerorhost++ = '\0'; 22240 } 22241 ast_string_field_set(p, theirtag, NULL); 22242 /* Treat this as if there were a call forward instead... 22243 */ 22244 ast_string_field_set(p->owner, call_forward, peerorhost); 22245 ast_queue_control(p->owner, AST_CONTROL_BUSY); 22246 res = 0; 22247 goto request_invite_cleanup; 22248 } 22249 } 22250 22251 if (!req->ignore && p->pendinginvite) { 22252 if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && (p->invitestate == INV_COMPLETED || p->invitestate == INV_TERMINATED)) { 22253 /* What do these circumstances mean? We have received an INVITE for an "incoming" dialog for which we 22254 * have sent a final response. We have not yet received an ACK, though (which is why p->pendinginvite is non-zero). 22255 * We also know that the INVITE is not a retransmission, because otherwise the "ignore" flag would be set. 22256 * This means that either we are receiving a reinvite for a terminated dialog, or we are receiving an INVITE with 22257 * credentials based on one we challenged earlier. 22258 * 22259 * The action to take in either case is to treat the INVITE as though it contains an implicit ACK for the previous 22260 * transaction. Calling __sip_ack will take care of this by clearing the p->pendinginvite and removing the response 22261 * from the previous transaction from the list of outstanding packets. 22262 */ 22263 __sip_ack(p, p->pendinginvite, 1, 0); 22264 } else { 22265 /* We already have a pending invite. Sorry. You are on hold. */ 22266 p->glareinvite = seqno; 22267 if (p->rtp && find_sdp(req)) { 22268 struct ast_sockaddr addr; 22269 if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &addr)) { 22270 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Audio may not work properly on this call.\n"); 22271 } else { 22272 ast_rtp_instance_set_alt_remote_address(p->rtp, &addr); 22273 } 22274 if (p->vrtp) { 22275 if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &addr)) { 22276 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Video may not work properly on this call.\n"); 22277 } else { 22278 ast_rtp_instance_set_alt_remote_address(p->vrtp, &addr); 22279 } 22280 } 22281 } 22282 transmit_response_reliable(p, "491 Request Pending", req); 22283 ast_debug(1, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 22284 /* Don't destroy dialog here */ 22285 res = 0; 22286 goto request_invite_cleanup; 22287 } 22288 } 22289 22290 p_replaces = get_header(req, "Replaces"); 22291 if (!ast_strlen_zero(p_replaces)) { 22292 /* We have a replaces header */ 22293 char *ptr; 22294 char *fromtag = NULL; 22295 char *totag = NULL; 22296 char *start, *to; 22297 int error = 0; 22298 22299 if (p->owner) { 22300 ast_debug(3, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 22301 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 22302 /* Do not destroy existing call */ 22303 res = -1; 22304 goto request_invite_cleanup; 22305 } 22306 22307 if (sipdebug) 22308 ast_debug(3, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 22309 /* Create a buffer we can manipulate */ 22310 replace_id = ast_strdupa(p_replaces); 22311 ast_uri_decode(replace_id); 22312 22313 if (!p->refer && !sip_refer_allocate(p)) { 22314 transmit_response_reliable(p, "500 Server Internal Error", req); 22315 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 22316 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22317 p->invitestate = INV_COMPLETED; 22318 res = -1; 22319 goto request_invite_cleanup; 22320 } 22321 22322 /* Todo: (When we find phones that support this) 22323 if the replaces header contains ";early-only" 22324 we can only replace the call in early 22325 stage, not after it's up. 22326 22327 If it's not in early mode, 486 Busy. 22328 */ 22329 22330 /* Skip leading whitespace */ 22331 replace_id = ast_skip_blanks(replace_id); 22332 22333 start = replace_id; 22334 while ( (ptr = strsep(&start, ";")) ) { 22335 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 22336 if ( (to = strcasestr(ptr, "to-tag=") ) ) 22337 totag = to + 7; /* skip the keyword */ 22338 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 22339 fromtag = to + 9; /* skip the keyword */ 22340 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 22341 } 22342 } 22343 22344 if (sipdebug) 22345 ast_debug(4, "Invite/replaces: Will use Replace-Call-ID : %s Fromtag: %s Totag: %s\n", 22346 replace_id, 22347 fromtag ? fromtag : "<no from tag>", 22348 totag ? totag : "<no to tag>"); 22349 22350 /* Try to find call that we are replacing. 22351 If we have a Replaces header, we need to cancel that call if we succeed with this call. 22352 First we cheat a little and look for a magic call-id from phones that support 22353 dialog-info+xml so we can do technology independent pickup... */ 22354 if (strncmp(replace_id, "pickup-", 7) == 0) { 22355 struct sip_pvt *subscription = NULL; 22356 replace_id += 7; /* Worst case we are looking at \0 */ 22357 22358 if ((subscription = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 22359 ast_log(LOG_NOTICE, "Unable to find subscription with call-id: %s\n", replace_id); 22360 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 22361 error = 1; 22362 } else { 22363 ast_log(LOG_NOTICE, "Trying to pick up %s@%s\n", subscription->exten, subscription->context); 22364 ast_copy_string(pickup.exten, subscription->exten, sizeof(pickup.exten)); 22365 ast_copy_string(pickup.context, subscription->context, sizeof(pickup.context)); 22366 sip_pvt_unlock(subscription); 22367 if (subscription->owner) { 22368 ast_channel_unlock(subscription->owner); 22369 } 22370 } 22371 } 22372 22373 /* This locks both refer_call pvt and refer_call pvt's owner!!!*/ 22374 if (!error && ast_strlen_zero(pickup.exten) && (p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 22375 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 22376 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 22377 error = 1; 22378 } else { 22379 refer_locked = 1; 22380 } 22381 22382 /* The matched call is the call from the transferer to Asterisk . 22383 We want to bridge the bridged part of the call to the 22384 incoming invite, thus taking over the refered call */ 22385 22386 if (p->refer->refer_call == p) { 22387 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 22388 p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call"); 22389 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 22390 error = 1; 22391 } 22392 22393 if (!error && ast_strlen_zero(pickup.exten) && !p->refer->refer_call->owner) { 22394 /* Oops, someting wrong anyway, no owner, no call */ 22395 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 22396 /* Check for better return code */ 22397 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req); 22398 error = 1; 22399 } 22400 22401 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) { 22402 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 22403 transmit_response_reliable(p, "603 Declined (Replaces)", req); 22404 error = 1; 22405 } 22406 22407 if (error) { /* Give up this dialog */ 22408 append_history(p, "Xfer", "INVITE/Replace Failed."); 22409 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22410 sip_pvt_unlock(p); 22411 if (p->refer->refer_call) { 22412 sip_pvt_unlock(p->refer->refer_call); 22413 if (p->refer->refer_call->owner) { 22414 ast_channel_unlock(p->refer->refer_call->owner); 22415 } 22416 } 22417 refer_locked = 0; 22418 p->invitestate = INV_COMPLETED; 22419 res = -1; 22420 goto request_invite_cleanup; 22421 } 22422 } 22423 22424 /* Check if this is an INVITE that sets up a new dialog or 22425 a re-invite in an existing dialog */ 22426 22427 if (!req->ignore) { 22428 int newcall = (p->initreq.headers ? TRUE : FALSE); 22429 22430 if (sip_cancel_destroy(p)) 22431 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 22432 /* This also counts as a pending invite */ 22433 p->pendinginvite = seqno; 22434 check_via(p, req); 22435 22436 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 22437 if (sipdebug) 22438 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 22439 if (!p->owner) { /* Not a re-invite */ 22440 if (debug) 22441 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 22442 if (newcall) 22443 append_history(p, "Invite", "New call: %s", p->callid); 22444 parse_ok_contact(p, req); 22445 } else { /* Re-invite on existing call */ 22446 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 22447 if (get_rpid(p, req)) { 22448 struct ast_party_connected_line connected; 22449 struct ast_set_party_connected_line update_connected; 22450 22451 ast_party_connected_line_init(&connected); 22452 memset(&update_connected, 0, sizeof(update_connected)); 22453 22454 update_connected.id.number = 1; 22455 connected.id.number.valid = 1; 22456 connected.id.number.str = (char *) p->cid_num; 22457 connected.id.number.presentation = p->callingpres; 22458 22459 update_connected.id.name = 1; 22460 connected.id.name.valid = 1; 22461 connected.id.name.str = (char *) p->cid_name; 22462 connected.id.name.presentation = p->callingpres; 22463 22464 connected.id.tag = (char *) p->cid_tag; 22465 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 22466 ast_channel_queue_connected_line_update(p->owner, &connected, 22467 &update_connected); 22468 } 22469 /* Handle SDP here if we already have an owner */ 22470 if (find_sdp(req)) { 22471 if (process_sdp(p, req, SDP_T38_INITIATE)) { 22472 if (!ast_strlen_zero(get_header(req, "Content-Encoding"))) { 22473 /* Asterisk does not yet support any Content-Encoding methods. Always 22474 * attempt to process the sdp, but return a 415 if a Content-Encoding header 22475 * was present after processing failed. */ 22476 transmit_response_reliable(p, "415 Unsupported Media type", req); 22477 } else { 22478 transmit_response_reliable(p, "488 Not acceptable here", req); 22479 } 22480 if (!p->lastinvite) 22481 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22482 res = -1; 22483 goto request_invite_cleanup; 22484 } 22485 ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE); 22486 } else { 22487 p->jointcapability = p->capability; 22488 ast_debug(1, "Hm.... No sdp for the moment\n"); 22489 /* Some devices signal they want to be put off hold by sending a re-invite 22490 *without* an SDP, which is supposed to mean "Go back to your state" 22491 and since they put os on remote hold, we go back to off hold */ 22492 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 22493 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 22494 /* Activate a re-invite */ 22495 ast_queue_frame(p->owner, &ast_null_frame); 22496 change_hold_state(p, req, FALSE, 0); 22497 } 22498 } 22499 if (p->do_history) /* This is a response, note what it was for */ 22500 append_history(p, "ReInv", "Re-invite received"); 22501 } 22502 } else if (debug) 22503 ast_verbose("Ignoring this INVITE request\n"); 22504 22505 if (!p->lastinvite && !req->ignore && !p->owner) { 22506 /* This is a new invite */ 22507 /* Handle authentication if this is our first invite */ 22508 int cc_recall_core_id = -1; 22509 set_pvt_allowed_methods(p, req); 22510 res = check_user_full(p, req, SIP_INVITE, e, XMIT_RELIABLE, addr, &authpeer); 22511 if (res == AUTH_CHALLENGE_SENT) { 22512 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 22513 res = 0; 22514 goto request_invite_cleanup; 22515 } 22516 if (res < 0) { /* Something failed in authentication */ 22517 if (res == AUTH_FAKE_AUTH) { 22518 ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From")); 22519 transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE); 22520 } else { 22521 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 22522 transmit_response_reliable(p, "403 Forbidden", req); 22523 } 22524 p->invitestate = INV_COMPLETED; 22525 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22526 res = 0; 22527 goto request_invite_cleanup; 22528 } 22529 22530 /* Successful authentication and peer matching so record the peer related to this pvt (for easy access to peer settings) */ 22531 if (p->relatedpeer) { 22532 p->relatedpeer = unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else."); 22533 } 22534 if (authpeer) { 22535 p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer"); 22536 } 22537 22538 req->authenticated = 1; 22539 22540 /* We have a successful authentication, process the SDP portion if there is one */ 22541 if (find_sdp(req)) { 22542 if (process_sdp(p, req, SDP_T38_INITIATE)) { 22543 /* Asterisk does not yet support any Content-Encoding methods. Always 22544 * attempt to process the sdp, but return a 415 if a Content-Encoding header 22545 * was present after processing fails. */ 22546 if (!ast_strlen_zero(get_header(req, "Content-Encoding"))) { 22547 transmit_response_reliable(p, "415 Unsupported Media type", req); 22548 } else { 22549 /* Unacceptable codecs */ 22550 transmit_response_reliable(p, "488 Not acceptable here", req); 22551 } 22552 p->invitestate = INV_COMPLETED; 22553 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22554 ast_debug(1, "No compatible codecs for this SIP call.\n"); 22555 res = -1; 22556 goto request_invite_cleanup; 22557 } 22558 } else { /* No SDP in invite, call control session */ 22559 p->jointcapability = p->capability; 22560 ast_debug(2, "No SDP in Invite, third party call control\n"); 22561 } 22562 22563 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 22564 /* This seems redundant ... see !p-owner above */ 22565 if (p->owner) 22566 ast_queue_frame(p->owner, &ast_null_frame); 22567 22568 22569 /* Initialize the context if it hasn't been already */ 22570 if (ast_strlen_zero(p->context)) 22571 ast_string_field_set(p, context, sip_cfg.default_context); 22572 22573 22574 /* Check number of concurrent calls -vs- incoming limit HERE */ 22575 ast_debug(1, "Checking SIP call limits for device %s\n", p->username); 22576 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 22577 if (res < 0) { 22578 ast_log(LOG_NOTICE, "Failed to place call for device %s, too many calls\n", p->username); 22579 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 22580 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22581 p->invitestate = INV_COMPLETED; 22582 } 22583 res = 0; 22584 goto request_invite_cleanup; 22585 } 22586 gotdest = get_destination(p, NULL, &cc_recall_core_id); /* Get destination right away */ 22587 extract_uri(p, req); /* Get the Contact URI */ 22588 build_contact(p); /* Build our contact header */ 22589 22590 if (p->rtp) { 22591 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 22592 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 22593 } 22594 22595 if (!replace_id && (gotdest != SIP_GET_DEST_EXTEN_FOUND)) { /* No matching extension found */ 22596 switch(gotdest) { 22597 case SIP_GET_DEST_INVALID_URI: 22598 transmit_response_reliable(p, "416 Unsupported URI scheme", req); 22599 break; 22600 case SIP_GET_DEST_EXTEN_MATCHMORE: 22601 if (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP) 22602 == SIP_PAGE2_ALLOWOVERLAP_YES) { 22603 transmit_response_reliable(p, "484 Address Incomplete", req); 22604 break; 22605 } 22606 /* 22607 * XXX We would have to implement collecting more digits in 22608 * chan_sip for any other schemes of overlap dialing. 22609 * 22610 * For SIP_PAGE2_ALLOWOVERLAP_DTMF it is better to do this in 22611 * the dialplan using the Incomplete application rather than 22612 * having the channel driver do it. 22613 */ 22614 /* Fall through */ 22615 case SIP_GET_DEST_EXTEN_NOT_FOUND: 22616 case SIP_GET_DEST_REFUSED: 22617 default: 22618 { 22619 char *decoded_exten = ast_strdupa(p->exten); 22620 transmit_response_reliable(p, "404 Not Found", req); 22621 ast_uri_decode(decoded_exten); 22622 ast_log(LOG_NOTICE, "Call from '%s' (%s) to extension" 22623 " '%s' rejected because extension not found in context '%s'.\n", 22624 S_OR(p->username, p->peername), ast_sockaddr_stringify(&p->recv), decoded_exten, p->context); 22625 } 22626 } /* end switch */ 22627 22628 p->invitestate = INV_COMPLETED; 22629 update_call_counter(p, DEC_CALL_LIMIT); 22630 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22631 res = 0; 22632 goto request_invite_cleanup; 22633 } else { 22634 22635 /* If no extension was specified, use the s one */ 22636 /* Basically for calling to IP/Host name only */ 22637 if (ast_strlen_zero(p->exten)) 22638 ast_string_field_set(p, exten, "s"); 22639 /* Initialize our tag */ 22640 22641 make_our_tag(p->tag, sizeof(p->tag)); 22642 /* First invitation - create the channel. Allocation 22643 * failures are handled below. */ 22644 c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL), NULL); 22645 if (cc_recall_core_id != -1) { 22646 ast_setup_cc_recall_datastore(c, cc_recall_core_id); 22647 ast_cc_agent_set_interfaces_chanvar(c); 22648 } 22649 *recount = 1; 22650 22651 /* Save Record-Route for any later requests we make on this dialogue */ 22652 build_route(p, req, 0, 0); 22653 22654 if (c) { 22655 ast_party_redirecting_init(&redirecting); 22656 memset(&update_redirecting, 0, sizeof(update_redirecting)); 22657 change_redirecting_information(p, req, &redirecting, &update_redirecting, 22658 FALSE); /*Will return immediately if no Diversion header is present */ 22659 ast_channel_set_redirecting(c, &redirecting, &update_redirecting); 22660 ast_party_redirecting_free(&redirecting); 22661 } 22662 } 22663 } else { 22664 ast_party_redirecting_init(&redirecting); 22665 memset(&update_redirecting, 0, sizeof(update_redirecting)); 22666 if (sipdebug) { 22667 if (!req->ignore) 22668 ast_debug(2, "Got a SIP re-invite for call %s\n", p->callid); 22669 else 22670 ast_debug(2, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 22671 } 22672 if (!req->ignore) 22673 reinvite = 1; 22674 c = p->owner; 22675 change_redirecting_information(p, req, &redirecting, &update_redirecting, FALSE); /*Will return immediately if no Diversion header is present */ 22676 if (c) { 22677 ast_channel_set_redirecting(c, &redirecting, &update_redirecting); 22678 } 22679 ast_party_redirecting_free(&redirecting); 22680 } 22681 22682 /* Session-Timers */ 22683 if ((p->sipoptions & SIP_OPT_TIMER) && !ast_strlen_zero(get_header(req, "Session-Expires"))) { 22684 /* The UAC has requested session-timers for this session. Negotiate 22685 the session refresh interval and who will be the refresher */ 22686 ast_debug(2, "Incoming INVITE with 'timer' option supported and \"Session-Expires\" header.\n"); 22687 22688 /* Allocate Session-Timers struct w/in the dialog */ 22689 if (!p->stimer) 22690 sip_st_alloc(p); 22691 22692 /* Parse the Session-Expires header */ 22693 p_uac_se_hdr = get_header(req, "Session-Expires"); 22694 rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref); 22695 if (rtn != 0) { 22696 transmit_response_reliable(p, "400 Session-Expires Invalid Syntax", req); 22697 p->invitestate = INV_COMPLETED; 22698 if (!p->lastinvite) { 22699 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22700 } 22701 res = -1; 22702 goto request_invite_cleanup; 22703 } 22704 22705 /* Parse the Min-SE header */ 22706 p_uac_min_se = get_header(req, "Min-SE"); 22707 if (!ast_strlen_zero(p_uac_min_se)) { 22708 rtn = parse_minse(p_uac_min_se, &uac_min_se); 22709 if (rtn != 0) { 22710 transmit_response_reliable(p, "400 Min-SE Invalid Syntax", req); 22711 p->invitestate = INV_COMPLETED; 22712 if (!p->lastinvite) { 22713 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22714 } 22715 res = -1; 22716 goto request_invite_cleanup; 22717 } 22718 } 22719 22720 dlg_min_se = st_get_se(p, FALSE); 22721 switch (st_get_mode(p, 1)) { 22722 case SESSION_TIMER_MODE_ACCEPT: 22723 case SESSION_TIMER_MODE_ORIGINATE: 22724 if (uac_max_se > 0 && uac_max_se < dlg_min_se) { 22725 transmit_response_with_minse(p, "422 Session Interval Too Small", req, dlg_min_se); 22726 p->invitestate = INV_COMPLETED; 22727 if (!p->lastinvite) { 22728 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22729 } 22730 res = -1; 22731 goto request_invite_cleanup; 22732 } 22733 22734 p->stimer->st_active_peer_ua = TRUE; 22735 st_active = TRUE; 22736 if (st_ref == SESSION_TIMER_REFRESHER_AUTO) { 22737 st_ref = st_get_refresher(p); 22738 } 22739 22740 if (uac_max_se > 0) { 22741 int dlg_max_se = st_get_se(p, TRUE); 22742 if (dlg_max_se >= uac_min_se) { 22743 st_interval = (uac_max_se < dlg_max_se) ? uac_max_se : dlg_max_se; 22744 } else { 22745 st_interval = uac_max_se; 22746 } 22747 } else { 22748 /* Set to default max value */ 22749 st_interval = global_max_se; 22750 } 22751 break; 22752 22753 case SESSION_TIMER_MODE_REFUSE: 22754 if (p->reqsipoptions & SIP_OPT_TIMER) { 22755 transmit_response_with_unsupported(p, "420 Option Disabled", req, required); 22756 ast_log(LOG_WARNING, "Received SIP INVITE with supported but disabled option: %s\n", required); 22757 p->invitestate = INV_COMPLETED; 22758 if (!p->lastinvite) { 22759 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22760 } 22761 res = -1; 22762 goto request_invite_cleanup; 22763 } 22764 break; 22765 22766 default: 22767 ast_log(LOG_ERROR, "Internal Error %d at %s:%d\n", st_get_mode(p, 1), __FILE__, __LINE__); 22768 break; 22769 } 22770 } else { 22771 /* The UAC did not request session-timers. Asterisk (UAS), will now decide 22772 (based on session-timer-mode in sip.conf) whether to run session-timers for 22773 this session or not. */ 22774 switch (st_get_mode(p, 1)) { 22775 case SESSION_TIMER_MODE_ORIGINATE: 22776 st_active = TRUE; 22777 st_interval = st_get_se(p, TRUE); 22778 st_ref = SESSION_TIMER_REFRESHER_UAS; 22779 p->stimer->st_active_peer_ua = FALSE; 22780 break; 22781 22782 default: 22783 break; 22784 } 22785 } 22786 22787 if (reinvite == 0) { 22788 /* Session-Timers: Start session refresh timer based on negotiation/config */ 22789 if (st_active == TRUE) { 22790 p->stimer->st_active = TRUE; 22791 p->stimer->st_interval = st_interval; 22792 p->stimer->st_ref = st_ref; 22793 start_session_timer(p); 22794 } 22795 } else { 22796 if (p->stimer->st_active == TRUE) { 22797 /* Session-Timers: A re-invite request sent within a dialog will serve as 22798 a refresh request, no matter whether the re-invite was sent for refreshing 22799 the session or modifying it.*/ 22800 ast_debug (2, "Restarting session-timers on a refresh - %s\n", p->callid); 22801 22802 /* The UAC may be adjusting the session-timers mid-session */ 22803 if (st_interval > 0) { 22804 p->stimer->st_interval = st_interval; 22805 p->stimer->st_ref = st_ref; 22806 } 22807 22808 restart_session_timer(p); 22809 if (p->stimer->st_expirys > 0) { 22810 p->stimer->st_expirys--; 22811 } 22812 } 22813 } 22814 22815 if (!req->ignore && p) 22816 p->lastinvite = seqno; 22817 22818 if (c && replace_id) { /* Attended transfer or call pickup - we're the target */ 22819 if (!ast_strlen_zero(pickup.exten)) { 22820 append_history(p, "Xfer", "INVITE/Replace received"); 22821 22822 /* Let the caller know we're giving it a shot */ 22823 transmit_response(p, "100 Trying", req); 22824 p->invitestate = INV_PROCEEDING; 22825 ast_setstate(c, AST_STATE_RING); 22826 22827 /* Do the pickup itself */ 22828 ast_channel_unlock(c); 22829 *nounlock = 1; 22830 22831 /* since p->owner (c) is unlocked, we need to go ahead and unlock pvt for both 22832 * magic pickup and ast_hangup. Both of these functions will attempt to lock 22833 * p->owner again, which can cause a deadlock if we already hold a lock on p. 22834 * Locking order is, channel then pvt. Dead lock avoidance must be used if 22835 * called the other way around. */ 22836 sip_pvt_unlock(p); 22837 do_magic_pickup(c, pickup.exten, pickup.context); 22838 /* Now we're either masqueraded or we failed to pickup, in either case we... */ 22839 ast_hangup(c); 22840 sip_pvt_lock(p); /* pvt is expected to remain locked on return, so re-lock it */ 22841 22842 res = 0; 22843 goto request_invite_cleanup; 22844 } else { 22845 /* Go and take over the target call */ 22846 if (sipdebug) 22847 ast_debug(4, "Sending this call to the invite/replcaes handler %s\n", p->callid); 22848 res = handle_invite_replaces(p, req, debug, seqno, addr, nounlock); 22849 refer_locked = 0; 22850 goto request_invite_cleanup; 22851 } 22852 } 22853 22854 22855 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 22856 enum ast_channel_state c_state = c->_state; 22857 22858 if (c_state != AST_STATE_UP && reinvite && 22859 (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) { 22860 /* If these conditions are true, and the channel is still in the 'ringing' 22861 * state, then this likely means that we have a situation where the initial 22862 * INVITE transaction has completed *but* the channel's state has not yet been 22863 * changed to UP. The reason this could happen is if the reinvite is received 22864 * on the SIP socket prior to an application calling ast_read on this channel 22865 * to read the answer frame we earlier queued on it. In this case, the reinvite 22866 * is completely legitimate so we need to handle this the same as if the channel 22867 * were already UP. Thus we are purposely falling through to the AST_STATE_UP case. 22868 */ 22869 c_state = AST_STATE_UP; 22870 } 22871 22872 switch(c_state) { 22873 case AST_STATE_DOWN: 22874 ast_debug(2, "%s: New call is still down.... Trying... \n", c->name); 22875 transmit_provisional_response(p, "100 Trying", req, 0); 22876 p->invitestate = INV_PROCEEDING; 22877 ast_setstate(c, AST_STATE_RING); 22878 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 22879 enum ast_pbx_result result; 22880 22881 result = ast_pbx_start(c); 22882 22883 switch(result) { 22884 case AST_PBX_FAILED: 22885 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 22886 p->invitestate = INV_COMPLETED; 22887 transmit_response_reliable(p, "503 Unavailable", req); 22888 break; 22889 case AST_PBX_CALL_LIMIT: 22890 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 22891 p->invitestate = INV_COMPLETED; 22892 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 22893 break; 22894 case AST_PBX_SUCCESS: 22895 /* nothing to do */ 22896 break; 22897 } 22898 22899 if (result) { 22900 22901 /* Unlock locks so ast_hangup can do its magic */ 22902 ast_channel_unlock(c); 22903 *nounlock = 1; 22904 sip_pvt_unlock(p); 22905 ast_hangup(c); 22906 sip_pvt_lock(p); 22907 c = NULL; 22908 } 22909 } else { /* Pickup call in call group */ 22910 if (sip_pickup(c)) { 22911 ast_log(LOG_WARNING, "Failed to start Group pickup by %s\n", c->name); 22912 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 22913 sip_alreadygone(p); 22914 c->hangupcause = AST_CAUSE_FAILURE; 22915 22916 /* Unlock locks so ast_hangup can do its magic */ 22917 ast_channel_unlock(c); 22918 *nounlock = 1; 22919 22920 p->invitestate = INV_COMPLETED; 22921 sip_pvt_unlock(p); 22922 ast_hangup(c); 22923 sip_pvt_lock(p); 22924 c = NULL; 22925 } 22926 } 22927 break; 22928 case AST_STATE_RING: 22929 transmit_provisional_response(p, "100 Trying", req, 0); 22930 p->invitestate = INV_PROCEEDING; 22931 break; 22932 case AST_STATE_RINGING: 22933 transmit_provisional_response(p, "180 Ringing", req, 0); 22934 p->invitestate = INV_PROCEEDING; 22935 break; 22936 case AST_STATE_UP: 22937 ast_debug(2, "%s: This call is UP.... \n", c->name); 22938 22939 transmit_response(p, "100 Trying", req); 22940 22941 if (p->t38.state == T38_PEER_REINVITE) { 22942 if (p->t38id > -1) { 22943 /* reset t38 abort timer */ 22944 AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "remove ref for t38id")); 22945 } 22946 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.")); 22947 } else if (p->t38.state == T38_ENABLED) { 22948 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 22949 transmit_response_with_t38_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 22950 } else if (p->t38.state == T38_DISABLED) { 22951 /* If this is not a re-invite or something to ignore - it's critical */ 22952 if (p->srtp && !ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)) { 22953 ast_log(LOG_WARNING, "Target does not support required crypto\n"); 22954 transmit_response_reliable(p, "488 Not Acceptable Here (crypto)", req); 22955 } else { 22956 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 22957 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL)), p->session_modify == TRUE ? FALSE : TRUE, FALSE); 22958 ast_queue_control(p->owner, AST_CONTROL_UPDATE_RTP_PEER); 22959 } 22960 } 22961 22962 p->invitestate = INV_TERMINATED; 22963 break; 22964 default: 22965 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 22966 transmit_response(p, "100 Trying", req); 22967 break; 22968 } 22969 } else { 22970 if (p && (p->autokillid == -1)) { 22971 const char *msg; 22972 22973 if (!p->jointcapability) 22974 msg = "488 Not Acceptable Here (codec error)"; 22975 else { 22976 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 22977 msg = "503 Unavailable"; 22978 } 22979 transmit_response_reliable(p, msg, req); 22980 p->invitestate = INV_COMPLETED; 22981 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 22982 } 22983 } 22984 22985 request_invite_cleanup: 22986 22987 if (refer_locked && p->refer && p->refer->refer_call) { 22988 sip_pvt_unlock(p->refer->refer_call); 22989 if (p->refer->refer_call->owner) { 22990 ast_channel_unlock(p->refer->refer_call->owner); 22991 } 22992 } 22993 if (authpeer) { 22994 authpeer = unref_peer(authpeer, "unref_peer, from handle_request_invite authpeer"); 22995 } 22996 22997 return res; 22998 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 23878 of file chan_sip.c.
References ast_verbose, receive_message(), and transmit_response().
Referenced by handle_incoming().
23879 { 23880 if (!req->ignore) { 23881 if (req->debug) 23882 ast_verbose("Receiving message!\n"); 23883 receive_message(p, req); 23884 } else 23885 transmit_response(p, "202 Accepted", req); 23886 return 1; 23887 }
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 21664 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().
21665 { 21666 /* This is mostly a skeleton for future improvements */ 21667 /* Mostly created to return proper answers on notifications on outbound REFER's */ 21668 int res = 0; 21669 const char *event = get_header(req, "Event"); 21670 char *sep; 21671 21672 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 21673 *sep++ = '\0'; 21674 } 21675 21676 if (sipdebug) 21677 ast_debug(2, "Got NOTIFY Event: %s\n", event); 21678 21679 if (!strcmp(event, "refer")) { 21680 /* Save nesting depth for now, since there might be other events we will 21681 support in the future */ 21682 21683 /* Handle REFER notifications */ 21684 21685 char buf[1024]; 21686 char *cmd, *code; 21687 int respcode; 21688 int success = TRUE; 21689 21690 /* EventID for each transfer... EventID is basically the REFER cseq 21691 21692 We are getting notifications on a call that we transfered 21693 We should hangup when we are getting a 200 OK in a sipfrag 21694 Check if we have an owner of this event */ 21695 21696 /* Check the content type */ 21697 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 21698 /* We need a sipfrag */ 21699 transmit_response(p, "400 Bad request", req); 21700 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21701 return -1; 21702 } 21703 21704 /* Get the text of the attachment */ 21705 if (get_msg_text(buf, sizeof(buf), req)) { 21706 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 21707 transmit_response(p, "400 Bad request", req); 21708 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21709 return -1; 21710 } 21711 21712 /* 21713 From the RFC... 21714 A minimal, but complete, implementation can respond with a single 21715 NOTIFY containing either the body: 21716 SIP/2.0 100 Trying 21717 21718 if the subscription is pending, the body: 21719 SIP/2.0 200 OK 21720 if the reference was successful, the body: 21721 SIP/2.0 503 Service Unavailable 21722 if the reference failed, or the body: 21723 SIP/2.0 603 Declined 21724 21725 if the REFER request was accepted before approval to follow the 21726 reference could be obtained and that approval was subsequently denied 21727 (see Section 2.4.7). 21728 21729 If there are several REFERs in the same dialog, we need to 21730 match the ID of the event header... 21731 */ 21732 ast_debug(3, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 21733 cmd = ast_skip_blanks(buf); 21734 code = cmd; 21735 /* We are at SIP/2.0 */ 21736 while(*code && (*code > 32)) { /* Search white space */ 21737 code++; 21738 } 21739 *code++ = '\0'; 21740 code = ast_skip_blanks(code); 21741 sep = code; 21742 sep++; 21743 while(*sep && (*sep > 32)) { /* Search white space */ 21744 sep++; 21745 } 21746 *sep++ = '\0'; /* Response string */ 21747 respcode = atoi(code); 21748 switch (respcode) { 21749 case 200: /* OK: The new call is up, hangup this call */ 21750 /* Hangup the call that we are replacing */ 21751 break; 21752 case 301: /* Moved permenantly */ 21753 case 302: /* Moved temporarily */ 21754 /* Do we get the header in the packet in this case? */ 21755 success = FALSE; 21756 break; 21757 case 503: /* Service Unavailable: The new call failed */ 21758 case 603: /* Declined: Not accepted */ 21759 /* Cancel transfer, continue the current call */ 21760 success = FALSE; 21761 break; 21762 case 0: /* Parse error */ 21763 /* Cancel transfer, continue the current call */ 21764 ast_log(LOG_NOTICE, "Error parsing sipfrag in NOTIFY in response to REFER.\n"); 21765 success = FALSE; 21766 break; 21767 default: 21768 if (respcode < 200) { 21769 /* ignore provisional responses */ 21770 success = -1; 21771 } else { 21772 ast_log(LOG_NOTICE, "Got unknown code '%d' in NOTIFY in response to REFER.\n", respcode); 21773 success = FALSE; 21774 } 21775 break; 21776 } 21777 if (success == FALSE) { 21778 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 21779 } 21780 21781 if (p->owner && success != -1) { 21782 enum ast_control_transfer message = success ? AST_TRANSFER_SUCCESS : AST_TRANSFER_FAILED; 21783 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 21784 } 21785 /* Confirm that we received this packet */ 21786 transmit_response(p, "200 OK", req); 21787 } else if (!strcmp(event, "message-summary")) { 21788 const char *mailbox = NULL; 21789 char *c = ast_strdupa(get_body(req, "Voice-Message", ':')); 21790 21791 if (!p->mwi) { 21792 struct sip_peer *peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type); 21793 21794 if (peer) { 21795 mailbox = ast_strdupa(peer->unsolicited_mailbox); 21796 unref_peer(peer, "removing unsolicited mwi ref"); 21797 } 21798 } else { 21799 mailbox = p->mwi->mailbox; 21800 } 21801 21802 if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(c)) { 21803 char *old = strsep(&c, " "); 21804 char *new = strsep(&old, "/"); 21805 struct ast_event *event; 21806 21807 if ((event = ast_event_new(AST_EVENT_MWI, 21808 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 21809 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, "SIP_Remote", 21810 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, atoi(new), 21811 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, atoi(old), 21812 AST_EVENT_IE_END))) { 21813 ast_event_queue_and_cache(event); 21814 } 21815 transmit_response(p, "200 OK", req); 21816 } else { 21817 transmit_response(p, "489 Bad event", req); 21818 res = -1; 21819 } 21820 } else if (!strcmp(event, "keep-alive")) { 21821 /* Used by Sipura/Linksys for NAT pinhole, 21822 * just confirm that we received the packet. */ 21823 transmit_response(p, "200 OK", req); 21824 } else if (!strcmp(event, "call-completion")) { 21825 res = handle_cc_notify(p, req); 21826 } else { 21827 /* We don't understand this event. */ 21828 transmit_response(p, "489 Bad event", req); 21829 res = -1; 21830 } 21831 21832 if (!p->lastinvite) 21833 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21834 21835 return res; 21836 }
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 21841 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().
21842 { 21843 const char *msg; 21844 enum sip_get_dest_result gotdest; 21845 int res; 21846 21847 if (p->lastinvite) { 21848 /* if this is a request in an active dialog, just confirm that the dialog exists. */ 21849 transmit_response_with_allow(p, "200 OK", req, 0); 21850 return 0; 21851 } 21852 21853 if (sip_cfg.auth_options_requests) { 21854 /* Do authentication if this OPTIONS request began the dialog */ 21855 copy_request(&p->initreq, req); 21856 set_pvt_allowed_methods(p, req); 21857 res = check_user(p, req, SIP_OPTIONS, e, XMIT_UNRELIABLE, addr); 21858 if (res == AUTH_CHALLENGE_SENT) { 21859 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21860 return 0; 21861 } 21862 if (res < 0) { /* Something failed in authentication */ 21863 if (res == AUTH_FAKE_AUTH) { 21864 ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From")); 21865 transmit_fake_auth_response(p, SIP_OPTIONS, req, XMIT_UNRELIABLE); 21866 } else { 21867 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 21868 transmit_response(p, "403 Forbidden", req); 21869 } 21870 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21871 return 0; 21872 } 21873 } 21874 21875 /* must go through authentication before getting here */ 21876 gotdest = get_destination(p, req, NULL); 21877 build_contact(p); 21878 21879 if (ast_strlen_zero(p->context)) 21880 ast_string_field_set(p, context, sip_cfg.default_context); 21881 21882 if (ast_shutting_down()) { 21883 msg = "503 Unavailable"; 21884 } else { 21885 msg = "404 Not Found"; 21886 switch (gotdest) { 21887 case SIP_GET_DEST_INVALID_URI: 21888 msg = "416 Unsupported URI scheme"; 21889 break; 21890 case SIP_GET_DEST_EXTEN_MATCHMORE: 21891 case SIP_GET_DEST_REFUSED: 21892 case SIP_GET_DEST_EXTEN_NOT_FOUND: 21893 //msg = "404 Not Found"; 21894 break; 21895 case SIP_GET_DEST_EXTEN_FOUND: 21896 msg = "200 OK"; 21897 break; 21898 } 21899 } 21900 transmit_response_with_allow(p, msg, req, 0); 21901 21902 /* Destroy if this OPTIONS was the opening request, but not if 21903 it's in the middle of a normal call flow. */ 21904 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 21905 21906 return 0; 21907 }
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 24309 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, max_expiry, pvt_set_needdestroy(), sip_scheddestroy(), transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), and transmit_response_with_minexpires().
Referenced by handle_incoming().
24310 { 24311 const char *etag = get_header(req, "SIP-If-Match"); 24312 const char *event = get_header(req, "Event"); 24313 struct event_state_compositor *esc; 24314 enum sip_publish_type publish_type; 24315 const char *expires_str = get_header(req, "Expires"); 24316 int expires_int; 24317 int auth_result; 24318 int handler_result = -1; 24319 24320 if (ast_strlen_zero(event)) { 24321 transmit_response(p, "489 Bad Event", req); 24322 pvt_set_needdestroy(p, "missing Event: header"); 24323 return -1; 24324 } 24325 24326 if (!(esc = get_esc(event))) { 24327 transmit_response(p, "489 Bad Event", req); 24328 pvt_set_needdestroy(p, "unknown event package in publish"); 24329 return -1; 24330 } 24331 24332 auth_result = check_user(p, req, SIP_PUBLISH, uri, XMIT_RELIABLE, addr); 24333 if (auth_result == AUTH_CHALLENGE_SENT) { 24334 p->lastinvite = seqno; 24335 return 0; 24336 } else if (auth_result < 0) { 24337 if (auth_result == AUTH_FAKE_AUTH) { 24338 ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From")); 24339 transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE); 24340 } else { 24341 ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From")); 24342 transmit_response_reliable(p, "403 Forbidden", req); 24343 } 24344 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 24345 ast_string_field_set(p, theirtag, NULL); 24346 return 0; 24347 } else if (auth_result == AUTH_SUCCESSFUL && p->lastinvite) { 24348 /* We need to stop retransmitting the 401 */ 24349 __sip_ack(p, p->lastinvite, 1, 0); 24350 } 24351 24352 publish_type = determine_sip_publish_type(req, event, etag, expires_str, &expires_int); 24353 24354 if (expires_int > max_expiry) { 24355 expires_int = max_expiry; 24356 } else if (expires_int < min_expiry && expires_int > 0) { 24357 transmit_response_with_minexpires(p, "423 Interval too small", req); 24358 pvt_set_needdestroy(p, "Expires is less that the min expires allowed."); 24359 return 0; 24360 } 24361 p->expiry = expires_int; 24362 24363 /* It is the responsibility of these handlers to formulate any response 24364 * sent for a PUBLISH 24365 */ 24366 switch (publish_type) { 24367 case SIP_PUBLISH_UNKNOWN: 24368 transmit_response(p, "400 Bad Request", req); 24369 break; 24370 case SIP_PUBLISH_INITIAL: 24371 handler_result = handle_sip_publish_initial(p, req, esc, expires_int); 24372 break; 24373 case SIP_PUBLISH_REFRESH: 24374 handler_result = handle_sip_publish_refresh(p, req, esc, etag, expires_int); 24375 break; 24376 case SIP_PUBLISH_MODIFY: 24377 handler_result = handle_sip_publish_modify(p, req, esc, etag, expires_int); 24378 break; 24379 case SIP_PUBLISH_REMOVE: 24380 handler_result = handle_sip_publish_remove(p, req, esc, etag); 24381 break; 24382 default: 24383 transmit_response(p, "400 Impossible Condition", req); 24384 break; 24385 } 24386 if (!handler_result && p->expiry > 0) { 24387 sip_scheddestroy(p, (p->expiry + 10) * 1000); 24388 } else { 24389 pvt_set_needdestroy(p, "forcing expiration"); 24390 } 24391 24392 return handler_result; 24393 }
static int handle_request_refer | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug, | |||
int | seqno, | |||
int * | nounlock | |||
) | [static] |
Definition at line 23266 of file chan_sip.c.
References append_history, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_NORMAL_CLEARING, AST_CEL_ATTENDEDTRANSFER, AST_CEL_BLINDTRANSFER, ast_cel_report_event(), ast_channel_lock, ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_clear_flag, AST_CONTROL_UNHOLD, ast_debug, ast_indicate(), AST_LIST_EMPTY, ast_manager_event_multichan, ast_parking_ext_valid(), ast_queue_control(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose, check_sip_domain(), context, EVENT_FLAG_CALL, FALSE, get_refer_info(), local_attended_transfer(), 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().
23267 { 23268 /*! 23269 * Chan1: Call between asterisk and transferer 23270 * Chan2: Call between asterisk and transferee 23271 */ 23272 struct sip_dual current = { 0, }; 23273 struct ast_channel *chans[2] = { 0, }; 23274 char *refer_to = NULL; 23275 char *refer_to_domain = NULL; 23276 char *refer_to_context = NULL; 23277 char *referred_by = NULL; 23278 char *callid = NULL; 23279 int localtransfer = 0; 23280 int attendedtransfer = 0; 23281 int res = 0; 23282 23283 if (req->debug) { 23284 ast_verbose("Call %s got a SIP call transfer from %s: (REFER)!\n", 23285 p->callid, 23286 ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "callee" : "caller"); 23287 } 23288 23289 if (!p->owner) { 23290 /* This is a REFER outside of an existing SIP dialog */ 23291 /* We can't handle that, so decline it */ 23292 ast_debug(3, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 23293 transmit_response(p, "603 Declined (No dialog)", req); 23294 if (!req->ignore) { 23295 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 23296 sip_alreadygone(p); 23297 pvt_set_needdestroy(p, "outside of dialog"); 23298 } 23299 res = 0; 23300 goto handle_refer_cleanup; 23301 } 23302 23303 /* Check if transfer is allowed from this device */ 23304 if (p->allowtransfer == TRANSFER_CLOSED ) { 23305 /* Transfer not allowed, decline */ 23306 transmit_response(p, "603 Declined (policy)", req); 23307 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 23308 /* Do not destroy SIP session */ 23309 res = 0; 23310 goto handle_refer_cleanup; 23311 } 23312 23313 if (!req->ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 23314 /* Already have a pending REFER */ 23315 transmit_response(p, "491 Request pending", req); 23316 append_history(p, "Xfer", "Refer failed. Request pending."); 23317 res = 0; 23318 goto handle_refer_cleanup; 23319 } 23320 23321 /* Allocate memory for call transfer data */ 23322 if (!p->refer && !sip_refer_allocate(p)) { 23323 transmit_response(p, "500 Internal Server Error", req); 23324 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 23325 res = -3; 23326 goto handle_refer_cleanup; 23327 } 23328 23329 res = get_refer_info(p, req); /* Extract headers */ 23330 23331 p->refer->status = REFER_SENT; 23332 23333 if (res != 0) { 23334 switch (res) { 23335 case -2: /* Syntax error */ 23336 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 23337 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 23338 if (req->debug) { 23339 ast_debug(1, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 23340 } 23341 break; 23342 case -3: 23343 transmit_response(p, "603 Declined (Non sip: uri)", req); 23344 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 23345 if (req->debug) { 23346 ast_debug(1, "SIP transfer to non-SIP uri denied\n"); 23347 } 23348 break; 23349 default: 23350 /* Refer-to extension not found, fake a failed transfer */ 23351 transmit_response(p, "202 Accepted", req); 23352 append_history(p, "Xfer", "Refer failed. Bad extension."); 23353 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 23354 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 23355 if (req->debug) { 23356 ast_debug(1, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 23357 } 23358 break; 23359 } 23360 res = 0; 23361 goto handle_refer_cleanup; 23362 } 23363 if (ast_strlen_zero(p->context)) { 23364 ast_string_field_set(p, context, sip_cfg.default_context); 23365 } 23366 23367 /* If we do not support SIP domains, all transfers are local */ 23368 if (sip_cfg.allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 23369 p->refer->localtransfer = 1; 23370 if (sipdebug) { 23371 ast_debug(3, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 23372 } 23373 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 23374 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 23375 p->refer->localtransfer = 1; 23376 } else if (sipdebug) { 23377 ast_debug(3, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 23378 } 23379 23380 /* Is this a repeat of a current request? Ignore it */ 23381 /* Don't know what else to do right now. */ 23382 if (req->ignore) { 23383 goto handle_refer_cleanup; 23384 } 23385 23386 /* If this is a blind transfer, we have the following 23387 channels to work with: 23388 - chan1, chan2: The current call between transferer and transferee (2 channels) 23389 - target_channel: A new call from the transferee to the target (1 channel) 23390 We need to stay tuned to what happens in order to be able 23391 to bring back the call to the transferer */ 23392 23393 /* If this is a attended transfer, we should have all call legs within reach: 23394 - chan1, chan2: The call between the transferer and transferee (2 channels) 23395 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 23396 We want to bridge chan2 with targetcall_pvt! 23397 23398 The replaces call id in the refer message points 23399 to the call leg between Asterisk and the transferer. 23400 So we need to connect the target and the transferee channel 23401 and hangup the two other channels silently 23402 23403 If the target is non-local, the call ID could be on a remote 23404 machine and we need to send an INVITE with replaces to the 23405 target. We basically handle this as a blind transfer 23406 and let the sip_call function catch that we need replaces 23407 header in the INVITE. 23408 */ 23409 23410 /* Get the transferer's channel */ 23411 chans[0] = current.chan1 = p->owner; 23412 23413 /* Find the other part of the bridge (2) - transferee */ 23414 chans[1] = current.chan2 = ast_bridged_channel(current.chan1); 23415 23416 ast_channel_ref(current.chan1); 23417 if (current.chan2) { 23418 ast_channel_ref(current.chan2); 23419 } 23420 23421 if (sipdebug) { 23422 ast_debug(3, "SIP %s transfer: Transferer channel %s, transferee channel %s\n", 23423 p->refer->attendedtransfer ? "attended" : "blind", 23424 current.chan1->name, 23425 current.chan2 ? current.chan2->name : "<none>"); 23426 } 23427 23428 if (!current.chan2 && !p->refer->attendedtransfer) { 23429 /* No bridged channel, propably IVR or echo or similar... */ 23430 /* Guess we should masquerade or something here */ 23431 /* Until we figure it out, refuse transfer of such calls */ 23432 if (sipdebug) { 23433 ast_debug(3, "Refused SIP transfer on non-bridged channel.\n"); 23434 } 23435 p->refer->status = REFER_FAILED; 23436 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 23437 transmit_response(p, "603 Declined", req); 23438 res = -1; 23439 goto handle_refer_cleanup; 23440 } 23441 23442 if (current.chan2) { 23443 if (sipdebug) { 23444 ast_debug(4, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 23445 } 23446 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 23447 } 23448 23449 ast_set_flag(&p->flags[0], SIP_GOTREFER); 23450 23451 /* From here on failures will be indicated with NOTIFY requests */ 23452 transmit_response(p, "202 Accepted", req); 23453 23454 /* Attended transfer: Find all call legs and bridge transferee with target*/ 23455 if (p->refer->attendedtransfer) { 23456 /* both p and p->owner _MUST_ be locked while calling local_attended_transfer */ 23457 if ((res = local_attended_transfer(p, ¤t, req, seqno, nounlock))) { 23458 goto handle_refer_cleanup; /* We're done with the transfer */ 23459 } 23460 /* Fall through for remote transfers that we did not find locally */ 23461 if (sipdebug) { 23462 ast_debug(4, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 23463 } 23464 /* Fallthrough if we can't find the call leg internally */ 23465 } 23466 23467 /* Copy data we can not safely access after letting the pvt lock go. */ 23468 refer_to = ast_strdupa(p->refer->refer_to); 23469 refer_to_domain = ast_strdupa(p->refer->refer_to_domain); 23470 refer_to_context = ast_strdupa(p->refer->refer_to_context); 23471 referred_by = ast_strdupa(p->refer->referred_by); 23472 callid = ast_strdupa(p->callid); 23473 localtransfer = p->refer->localtransfer; 23474 attendedtransfer = p->refer->attendedtransfer; 23475 23476 if (!*nounlock) { 23477 ast_channel_unlock(p->owner); 23478 *nounlock = 1; 23479 } 23480 sip_pvt_unlock(p); 23481 23482 /* Parking a call. DO NOT hold any locks while calling ast_parking_ext_valid() */ 23483 if (localtransfer && ast_parking_ext_valid(refer_to, current.chan1, current.chan1->context)) { 23484 sip_pvt_lock(p); 23485 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 23486 p->refer->status = REFER_200OK; 23487 append_history(p, "Xfer", "REFER to call parking."); 23488 sip_pvt_unlock(p); 23489 23490 ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, 23491 "TransferMethod: SIP\r\n" 23492 "TransferType: Blind\r\n" 23493 "Channel: %s\r\n" 23494 "Uniqueid: %s\r\n" 23495 "SIP-Callid: %s\r\n" 23496 "TargetChannel: %s\r\n" 23497 "TargetUniqueid: %s\r\n" 23498 "TransferExten: %s\r\n" 23499 "Transfer2Parking: Yes\r\n", 23500 current.chan1->name, 23501 current.chan1->uniqueid, 23502 callid, 23503 current.chan2->name, 23504 current.chan2->uniqueid, 23505 refer_to); 23506 23507 if (sipdebug) { 23508 ast_debug(4, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 23509 } 23510 23511 /* DO NOT hold any locks while calling sip_park */ 23512 if (sip_park(current.chan2, current.chan1, req, seqno, refer_to, current.chan1->context)) { 23513 sip_pvt_lock(p); 23514 transmit_notify_with_sipfrag(p, seqno, "500 Internal Server Error", TRUE); 23515 } else { 23516 sip_pvt_lock(p); 23517 } 23518 goto handle_refer_cleanup; 23519 } 23520 23521 /* Blind transfers and remote attended xfers. 23522 * Locks should not be held while calling pbx_builtin_setvar_helper. This function 23523 * locks the channel being passed into it.*/ 23524 if (current.chan1 && current.chan2) { 23525 ast_debug(3, "chan1->name: %s\n", current.chan1->name); 23526 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 23527 } 23528 23529 if (current.chan2) { 23530 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 23531 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", refer_to_domain); 23532 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 23533 /* One for the new channel */ 23534 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 23535 /* Attended transfer to remote host, prepare headers for the INVITE */ 23536 if (!ast_strlen_zero(referred_by)) { 23537 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", referred_by); 23538 } 23539 } 23540 23541 sip_pvt_lock(p); 23542 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 23543 if (!ast_strlen_zero(p->refer->replaces_callid)) { 23544 char tempheader[SIPBUFSIZE]; 23545 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 23546 p->refer->replaces_callid_totag ? ";to-tag=" : "", 23547 p->refer->replaces_callid_totag, 23548 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 23549 p->refer->replaces_callid_fromtag); 23550 23551 if (current.chan2) { 23552 sip_pvt_unlock(p); 23553 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 23554 sip_pvt_lock(p); 23555 } 23556 } 23557 23558 /* Connect the call */ 23559 23560 /* FAKE ringing if not attended transfer */ 23561 if (!p->refer->attendedtransfer) { 23562 transmit_notify_with_sipfrag(p, seqno, "180 Ringing", FALSE); 23563 } 23564 23565 /* For blind transfer, this will lead to a new call */ 23566 /* For attended transfer to remote host, this will lead to 23567 a new SIP call with a replaces header, if the dial plan allows it 23568 */ 23569 if (!current.chan2) { 23570 /* We have no bridge, so we're talking with Asterisk somehow */ 23571 /* We need to masquerade this call */ 23572 /* What to do to fix this situation: 23573 * Set up the new call in a new channel 23574 * Let the new channel masq into this channel 23575 Please add that code here :-) 23576 */ 23577 p->refer->status = REFER_FAILED; 23578 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 23579 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 23580 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 23581 res = -1; 23582 goto handle_refer_cleanup; 23583 } 23584 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 23585 23586 /* Do not hold the pvt lock during the indicate and async_goto. Those functions 23587 * lock channels which will invalidate locking order if the pvt lock is held.*/ 23588 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 23589 * servers - generate an INVITE with Replaces. Either way, let the dial plan decided 23590 * indicate before masquerade so the indication actually makes it to the real channel 23591 * when using local channels with MOH passthru */ 23592 sip_pvt_unlock(p); 23593 ast_indicate(current.chan2, AST_CONTROL_UNHOLD); 23594 res = ast_async_goto(current.chan2, refer_to_context, refer_to, 1); 23595 23596 if (!res) { 23597 ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, 23598 "TransferMethod: SIP\r\n" 23599 "TransferType: Blind\r\n" 23600 "Channel: %s\r\n" 23601 "Uniqueid: %s\r\n" 23602 "SIP-Callid: %s\r\n" 23603 "TargetChannel: %s\r\n" 23604 "TargetUniqueid: %s\r\n" 23605 "TransferExten: %s\r\n" 23606 "TransferContext: %s\r\n", 23607 current.chan1->name, 23608 current.chan1->uniqueid, 23609 callid, 23610 current.chan2->name, 23611 current.chan2->uniqueid, 23612 refer_to, 23613 refer_to_context); 23614 /* Success - we have a new channel */ 23615 ast_debug(3, "%s transfer succeeded. Telling transferer.\n", attendedtransfer? "Attended" : "Blind"); 23616 23617 /* XXX - what to we put in CEL 'extra' for attended transfers to external systems? NULL for now */ 23618 ast_channel_lock(current.chan1); 23619 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); 23620 ast_channel_unlock(current.chan1); 23621 23622 sip_pvt_lock(p); 23623 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 23624 if (p->refer->localtransfer) { 23625 p->refer->status = REFER_200OK; 23626 } 23627 if (p->owner) { 23628 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 23629 } 23630 append_history(p, "Xfer", "Refer succeeded."); 23631 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 23632 /* Do not hangup call, the other side do that when we say 200 OK */ 23633 /* We could possibly implement a timer here, auto congestion */ 23634 res = 0; 23635 } else { 23636 sip_pvt_lock(p); 23637 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 23638 ast_debug(3, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 23639 append_history(p, "Xfer", "Refer failed."); 23640 /* Failure of some kind */ 23641 p->refer->status = REFER_FAILED; 23642 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 23643 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 23644 res = -1; 23645 } 23646 23647 handle_refer_cleanup: 23648 if (current.chan1) { 23649 ast_channel_unref(current.chan1); 23650 } 23651 if (current.chan2) { 23652 ast_channel_unref(current.chan2); 23653 } 23654 23655 /* Make sure we exit with the pvt locked */ 23656 return res; 23657 }
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 24860 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().
24861 { 24862 enum check_auth_result res; 24863 24864 /* If this is not the intial request, and the initial request isn't 24865 * a register, something screwy happened, so bail */ 24866 if (p->initreq.headers && p->initreq.method != SIP_REGISTER) { 24867 ast_log(LOG_WARNING, "Ignoring spurious REGISTER with Call-ID: %s\n", p->callid); 24868 return -1; 24869 } 24870 24871 /* Use this as the basis */ 24872 copy_request(&p->initreq, req); 24873 if (sipdebug) 24874 ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 24875 check_via(p, req); 24876 if ((res = register_verify(p, addr, req, e)) < 0) { 24877 const char *reason; 24878 24879 switch (res) { 24880 case AUTH_SECRET_FAILED: 24881 reason = "Wrong password"; 24882 break; 24883 case AUTH_USERNAME_MISMATCH: 24884 reason = "Username/auth name mismatch"; 24885 break; 24886 case AUTH_NOT_FOUND: 24887 reason = "No matching peer found"; 24888 break; 24889 case AUTH_UNKNOWN_DOMAIN: 24890 reason = "Not a local domain"; 24891 break; 24892 case AUTH_PEER_NOT_DYNAMIC: 24893 reason = "Peer is not supposed to register"; 24894 break; 24895 case AUTH_ACL_FAILED: 24896 reason = "Device does not match ACL"; 24897 break; 24898 case AUTH_BAD_TRANSPORT: 24899 reason = "Device not configured to use this transport type"; 24900 break; 24901 default: 24902 reason = "Unknown failure"; 24903 break; 24904 } 24905 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 24906 get_header(req, "To"), ast_sockaddr_stringify(addr), 24907 reason); 24908 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 24909 } else { 24910 req->authenticated = 1; 24911 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 24912 } 24913 24914 if (res < 1) { 24915 /* Destroy the session, but keep us around for just a bit in case they don't 24916 get our 200 OK */ 24917 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 24918 } 24919 return res; 24920 }
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 24476 of file chan_sip.c.
References __get_header(), add_peer_mwi_subs(), ao2_lock, ao2_unlock, append_history, ast_debug, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add_destroy(), ast_extension_state_del(), AST_LIST_EMPTY, ast_log(), ast_set_flag, ast_sockaddr_stringify(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose, build_contact(), build_route(), cb_extensionstate(), cb_extensionstate_destroy(), check_user_full(), check_via(), copy_request(), dialog_unlink_all(), FALSE, get_destination(), get_header(), gettag(), handle_cc_subscribe(), LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), max_expiry, min_expiry, NONE, option_debug, parse_ok_contact(), pvt_set_needdestroy(), ref_peer(), S_OR, set_pvt_allowed_methods(), sip_cancel_destroy(), sip_cfg, sip_methods, sip_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(), and unref_peer().
Referenced by handle_incoming().
24477 { 24478 int gotdest = 0; 24479 int res = 0; 24480 int firststate; 24481 struct sip_peer *authpeer = NULL; 24482 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 24483 int resubscribe = (p->subscribed != NONE) && !req->ignore; 24484 char *temp, *event; 24485 24486 if (p->initreq.headers) { 24487 /* We already have a dialog */ 24488 if (p->initreq.method != SIP_SUBSCRIBE) { 24489 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 24490 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 24491 transmit_response(p, "403 Forbidden (within dialog)", req); 24492 /* Do not destroy session, since we will break the call if we do */ 24493 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); 24494 return 0; 24495 } else if (req->debug) { 24496 if (resubscribe) 24497 ast_debug(1, "Got a re-subscribe on existing subscription %s\n", p->callid); 24498 else 24499 ast_debug(1, "Got a new subscription %s (possibly with auth) or retransmission\n", p->callid); 24500 } 24501 } 24502 24503 /* Check if we have a global disallow setting on subscriptions. 24504 if so, we don't have to check peer settings after auth, which saves a lot of processing 24505 */ 24506 if (!sip_cfg.allowsubscribe) { 24507 transmit_response(p, "403 Forbidden (policy)", req); 24508 pvt_set_needdestroy(p, "forbidden"); 24509 return 0; 24510 } 24511 24512 if (!req->ignore && !resubscribe) { /* Set up dialog, new subscription */ 24513 const char *to = get_header(req, "To"); 24514 char totag[128]; 24515 set_pvt_allowed_methods(p, req); 24516 24517 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 24518 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 24519 if (req->debug) 24520 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 24521 transmit_response(p, "481 Subscription does not exist", req); 24522 pvt_set_needdestroy(p, "subscription does not exist"); 24523 return 0; 24524 } 24525 24526 /* Use this as the basis */ 24527 if (req->debug) 24528 ast_verbose("Creating new subscription\n"); 24529 24530 copy_request(&p->initreq, req); 24531 if (sipdebug) 24532 ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 24533 check_via(p, req); 24534 build_route(p, req, 0, 0); 24535 } else if (req->debug && req->ignore) 24536 ast_verbose("Ignoring this SUBSCRIBE request\n"); 24537 24538 /* Find parameters to Event: header value and remove them for now */ 24539 if (ast_strlen_zero(eventheader)) { 24540 transmit_response(p, "489 Bad Event", req); 24541 ast_debug(2, "Received SIP subscribe for unknown event package: <none>\n"); 24542 pvt_set_needdestroy(p, "unknown event package in subscribe"); 24543 return 0; 24544 } 24545 24546 if ( (strchr(eventheader, ';'))) { 24547 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 24548 temp = strchr(event, ';'); 24549 *temp = '\0'; /* Remove any options for now */ 24550 /* We might need to use them later :-) */ 24551 } else 24552 event = (char *) eventheader; /* XXX is this legal ? */ 24553 24554 /* Handle authentication if we're new and not a retransmission. We can't just 24555 * use if !req->ignore, because then we'll end up sending 24556 * a 200 OK if someone retransmits without sending auth */ 24557 if (p->subscribed == NONE || resubscribe) { 24558 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, addr, &authpeer); 24559 24560 /* if an authentication response was sent, we are done here */ 24561 if (res == AUTH_CHALLENGE_SENT) /* authpeer = NULL here */ 24562 return 0; 24563 if (res != AUTH_SUCCESSFUL) { 24564 if (res == AUTH_FAKE_AUTH) { 24565 ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From")); 24566 transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE); 24567 } else { 24568 ast_log(LOG_NOTICE, "Failed to authenticate device %s for SUBSCRIBE\n", get_header(req, "From")); 24569 transmit_response_reliable(p, "403 Forbidden", req); 24570 } 24571 24572 pvt_set_needdestroy(p, "authentication failed"); 24573 return 0; 24574 } 24575 } 24576 24577 /* At this point, we hold a reference to authpeer (if not NULL). It 24578 * must be released when done. 24579 */ 24580 24581 /* Check if this device is allowed to subscribe at all */ 24582 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 24583 transmit_response(p, "403 Forbidden (policy)", req); 24584 pvt_set_needdestroy(p, "subscription not allowed"); 24585 if (authpeer) { 24586 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 1)"); 24587 } 24588 return 0; 24589 } 24590 24591 if (strcmp(event, "message-summary") && strcmp(event, "call-completion")) { 24592 /* Get destination right away */ 24593 gotdest = get_destination(p, NULL, NULL); 24594 } 24595 24596 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 24597 parse_ok_contact(p, req); 24598 24599 build_contact(p); 24600 if (gotdest != SIP_GET_DEST_EXTEN_FOUND) { 24601 if (gotdest == SIP_GET_DEST_INVALID_URI) { 24602 transmit_response(p, "416 Unsupported URI scheme", req); 24603 } else { 24604 transmit_response(p, "404 Not Found", req); 24605 } 24606 pvt_set_needdestroy(p, "subscription target not found"); 24607 if (authpeer) { 24608 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)"); 24609 } 24610 return 0; 24611 } 24612 24613 /* Initialize tag for new subscriptions */ 24614 if (ast_strlen_zero(p->tag)) 24615 make_our_tag(p->tag, sizeof(p->tag)); 24616 24617 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 24618 unsigned int pidf_xml; 24619 const char *accept; 24620 int start = 0; 24621 enum subscriptiontype subscribed = NONE; 24622 const char *unknown_acceptheader = NULL; 24623 24624 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 24625 accept = __get_header(req, "Accept", &start); 24626 while ((subscribed == NONE) && !ast_strlen_zero(accept)) { 24627 pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0; 24628 24629 /* Older versions of Polycom firmware will claim pidf+xml, but really 24630 * they only support xpidf+xml. */ 24631 if (pidf_xml && strstr(p->useragent, "Polycom")) { 24632 subscribed = XPIDF_XML; 24633 } else if (pidf_xml) { 24634 subscribed = PIDF_XML; /* RFC 3863 format */ 24635 } else if (strstr(accept, "application/dialog-info+xml")) { 24636 subscribed = DIALOG_INFO_XML; 24637 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 24638 } else if (strstr(accept, "application/cpim-pidf+xml")) { 24639 subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 24640 } else if (strstr(accept, "application/xpidf+xml")) { 24641 subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 24642 } else { 24643 unknown_acceptheader = accept; 24644 } 24645 /* check to see if there is another Accept header present */ 24646 accept = __get_header(req, "Accept", &start); 24647 } 24648 24649 if (!start) { 24650 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 24651 transmit_response(p, "489 Bad Event", req); 24652 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: " 24653 "stateid: %d, laststate: %d, dialogver: %u, subscribecont: " 24654 "'%s', subscribeuri: '%s'\n", 24655 p->stateid, 24656 p->laststate, 24657 p->dialogver, 24658 p->subscribecontext, 24659 p->subscribeuri); 24660 pvt_set_needdestroy(p, "no Accept header"); 24661 if (authpeer) { 24662 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)"); 24663 } 24664 return 0; 24665 } 24666 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 24667 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 24668 } else if (subscribed == NONE) { 24669 /* Can't find a format for events that we know about */ 24670 char mybuf[200]; 24671 if (!ast_strlen_zero(unknown_acceptheader)) { 24672 snprintf(mybuf, sizeof(mybuf), "489 Bad Event (format %s)", unknown_acceptheader); 24673 } else { 24674 snprintf(mybuf, sizeof(mybuf), "489 Bad Event"); 24675 } 24676 transmit_response(p, mybuf, req); 24677 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format:" 24678 "'%s' pvt: subscribed: %d, stateid: %d, laststate: %d," 24679 "dialogver: %u, subscribecont: '%s', subscribeuri: '%s'\n", 24680 unknown_acceptheader, 24681 (int)p->subscribed, 24682 p->stateid, 24683 p->laststate, 24684 p->dialogver, 24685 p->subscribecontext, 24686 p->subscribeuri); 24687 pvt_set_needdestroy(p, "unrecognized format"); 24688 if (authpeer) { 24689 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)"); 24690 } 24691 return 0; 24692 } else { 24693 p->subscribed = subscribed; 24694 } 24695 } else if (!strcmp(event, "message-summary")) { 24696 int start = 0; 24697 int found_supported = 0; 24698 const char *acceptheader; 24699 24700 acceptheader = __get_header(req, "Accept", &start); 24701 while (!found_supported && !ast_strlen_zero(acceptheader)) { 24702 found_supported = strcmp(acceptheader, "application/simple-message-summary") ? 0 : 1; 24703 if (!found_supported && (option_debug > 2)) { 24704 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader); 24705 } 24706 acceptheader = __get_header(req, "Accept", &start); 24707 } 24708 if (start && !found_supported) { 24709 /* Format requested that we do not support */ 24710 transmit_response(p, "406 Not Acceptable", req); 24711 ast_debug(2, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader); 24712 pvt_set_needdestroy(p, "unknown format"); 24713 if (authpeer) { 24714 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)"); 24715 } 24716 return 0; 24717 } 24718 /* Looks like they actually want a mailbox status 24719 This version of Asterisk supports mailbox subscriptions 24720 The subscribed URI needs to exist in the dial plan 24721 In most devices, this is configurable to the voicemailmain extension you use 24722 */ 24723 if (!authpeer || AST_LIST_EMPTY(&authpeer->mailboxes)) { 24724 if (!authpeer) { 24725 transmit_response(p, "404 Not found", req); 24726 } else { 24727 transmit_response(p, "404 Not found (no mailbox)", req); 24728 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", S_OR(authpeer->name, "")); 24729 } 24730 pvt_set_needdestroy(p, "received 404 response"); 24731 if (authpeer) { 24732 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)"); 24733 } 24734 return 0; 24735 } 24736 24737 p->subscribed = MWI_NOTIFICATION; 24738 if (ast_test_flag(&authpeer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY)) { 24739 ao2_unlock(p); 24740 add_peer_mwi_subs(authpeer); 24741 ao2_lock(p); 24742 } 24743 if (authpeer->mwipvt != p) { /* Destroy old PVT if this is a new one */ 24744 /* We only allow one subscription per peer */ 24745 if (authpeer->mwipvt) { 24746 dialog_unlink_all(authpeer->mwipvt); 24747 authpeer->mwipvt = dialog_unref(authpeer->mwipvt, "unref dialog authpeer->mwipvt"); 24748 } 24749 authpeer->mwipvt = dialog_ref(p, "setting peers' mwipvt to p"); 24750 } 24751 if (p->relatedpeer != authpeer) { 24752 if (p->relatedpeer) { 24753 unref_peer(p->relatedpeer, "Unref previously stored relatedpeer ptr"); 24754 } 24755 p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer"); 24756 } 24757 /* Do not release authpeer here */ 24758 } else if (!strcmp(event, "call-completion")) { 24759 handle_cc_subscribe(p, req); 24760 } else { /* At this point, Asterisk does not understand the specified event */ 24761 transmit_response(p, "489 Bad Event", req); 24762 ast_debug(2, "Received SIP subscribe for unknown event package: %s\n", event); 24763 pvt_set_needdestroy(p, "unknown event package"); 24764 if (authpeer) { 24765 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 5)"); 24766 } 24767 return 0; 24768 } 24769 24770 /* Add subscription for extension state from the PBX core */ 24771 if (p->subscribed != MWI_NOTIFICATION && p->subscribed != CALL_COMPLETION && !resubscribe) { 24772 if (p->stateid != -1) { 24773 ast_extension_state_del(p->stateid, cb_extensionstate); 24774 } 24775 dialog_ref(p, "copying dialog ptr into extension state struct"); 24776 p->stateid = ast_extension_state_add_destroy(p->context, p->exten, 24777 cb_extensionstate, cb_extensionstate_destroy, p); 24778 if (p->stateid == -1) { 24779 dialog_unref(p, "copying dialog ptr into extension state struct failed"); 24780 } 24781 } 24782 24783 if (!req->ignore && p) 24784 p->lastinvite = seqno; 24785 if (p && !p->needdestroy) { 24786 p->expiry = atoi(get_header(req, "Expires")); 24787 24788 /* check if the requested expiry-time is within the approved limits from sip.conf */ 24789 if (p->expiry > max_expiry) { 24790 p->expiry = max_expiry; 24791 } else if (p->expiry < min_expiry && p->expiry > 0) { 24792 transmit_response_with_minexpires(p, "423 Interval too small", req); 24793 ast_log(LOG_WARNING, "Received subscription for extension \"%s\" context \"%s\" " 24794 "with Expire header less that 'minexpire' limit. Received \"Expire: %d\" min is %d\n", 24795 p->exten, p->context, p->expiry, min_expiry); 24796 pvt_set_needdestroy(p, "Expires is less that the min expires allowed."); 24797 if (authpeer) { 24798 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 6)"); 24799 } 24800 return 0; 24801 } 24802 24803 if (sipdebug) { 24804 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) { 24805 ast_debug(2, "Adding subscription for mailbox notification - peer %s\n", p->relatedpeer->name); 24806 } else if (p->subscribed == CALL_COMPLETION) { 24807 ast_debug(2, "Adding CC subscription for peer %s\n", p->username); 24808 } else { 24809 ast_debug(2, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 24810 } 24811 } 24812 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 24813 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 24814 if (p->expiry > 0) 24815 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 24816 24817 if (p->subscribed == MWI_NOTIFICATION) { 24818 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 24819 transmit_response(p, "200 OK", req); 24820 if (p->relatedpeer) { /* Send first notification */ 24821 struct sip_peer *peer = p->relatedpeer; 24822 ref_peer(peer, "ensure a peer ref is held during MWI sending"); 24823 ao2_unlock(p); 24824 sip_send_mwi_to_peer(peer, 0); 24825 ao2_lock(p); 24826 unref_peer(peer, "release a peer ref now that MWI is sent"); 24827 } 24828 } else if (p->subscribed != CALL_COMPLETION) { 24829 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 24830 24831 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)); 24832 transmit_response(p, "404 Not found", req); 24833 pvt_set_needdestroy(p, "no extension for SUBSCRIBE"); 24834 if (authpeer) { 24835 unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 6)"); 24836 } 24837 return 0; 24838 } 24839 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 24840 transmit_response(p, "200 OK", req); 24841 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 24842 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 24843 /* hide the 'complete' exten/context in the refer_to field for later display */ 24844 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 24845 /* Deleted the slow iteration of all sip dialogs to find old subscribes from this peer for exten@context */ 24846 24847 } 24848 if (!p->expiry) { 24849 pvt_set_needdestroy(p, "forcing expiration"); 24850 } 24851 } 24852 24853 if (authpeer) { 24854 unref_peer(authpeer, "unref pointer into (*authpeer)"); 24855 } 24856 return 1; 24857 }
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 22099 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().
22100 { 22101 if (ast_strlen_zero(get_header(req, "X-Asterisk-rpid-update"))) { 22102 transmit_response(p, "501 Method Not Implemented", req); 22103 return 0; 22104 } 22105 if (get_rpid(p, req)) { 22106 struct ast_party_connected_line connected; 22107 struct ast_set_party_connected_line update_connected; 22108 22109 ast_party_connected_line_init(&connected); 22110 memset(&update_connected, 0, sizeof(update_connected)); 22111 22112 update_connected.id.number = 1; 22113 connected.id.number.valid = 1; 22114 connected.id.number.str = (char *) p->cid_num; 22115 connected.id.number.presentation = p->callingpres; 22116 22117 update_connected.id.name = 1; 22118 connected.id.name.valid = 1; 22119 connected.id.name.str = (char *) p->cid_name; 22120 connected.id.name.presentation = p->callingpres; 22121 22122 connected.id.tag = (char *) p->cid_tag; 22123 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 22124 ast_channel_queue_connected_line_update(p->owner, &connected, &update_connected); 22125 } 22126 transmit_response(p, "200 OK", req); 22127 return 0; 22128 }
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 20881 of file chan_sip.c.
References __sip_ack(), __sip_semi_ack(), append_history, AST_CAUSE_PROTOCOL_ERROR, AST_CC_CCBS, ast_channel_set_redirecting(), ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_debug, ast_log(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_queue_control(), ast_queue_hangup_with_cause(), ast_set_flag, ast_skip_blanks(), ast_skip_nonblanks(), ast_sockaddr_stringify(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose, change_redirecting_information(), do_proxy_auth(), FALSE, find_sdp(), find_sip_method(), get_header(), gettag(), handle_response_info(), handle_response_invite(), handle_response_message(), handle_response_notify(), handle_response_peerpoke(), handle_response_publish(), handle_response_refer(), handle_response_register(), handle_response_subscribe(), handle_response_update(), hangup_sip2cause(), ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, mark_method_allowed(), mark_method_unallowed(), process_sdp(), pvt_set_needdestroy(), rh, sip_alreadygone(), sip_cancel_destroy(), sip_handle_cc(), sip_methods, stop_media_flows(), transmit_request(), TRUE, and update_redirecting().
20882 { 20883 struct ast_channel *owner; 20884 int sipmethod; 20885 const char *c = get_header(req, "Cseq"); 20886 /* 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 */ 20887 char *c_copy = ast_strdupa(c); 20888 /* Skip the Cseq and its subsequent spaces */ 20889 const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy)); 20890 20891 if (!msg) 20892 msg = ""; 20893 20894 sipmethod = find_sip_method(msg); 20895 20896 owner = p->owner; 20897 if (owner) { 20898 const char *rp = NULL, *rh = NULL; 20899 20900 owner->hangupcause = 0; 20901 if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON) && (rh = get_header(req, "Reason"))) { 20902 rh = ast_skip_blanks(rh); 20903 if (!strncasecmp(rh, "Q.850", 5)) { 20904 rp = strstr(rh, "cause="); 20905 if (rp && sscanf(rp + 6, "%30d", &owner->hangupcause) == 1) { 20906 owner->hangupcause &= 0x7f; 20907 if (req->debug) 20908 ast_verbose("Using Reason header for cause code: %d\n", owner->hangupcause); 20909 } 20910 } 20911 } 20912 20913 if (!owner->hangupcause) 20914 owner->hangupcause = hangup_sip2cause(resp); 20915 } 20916 20917 if (p->socket.type == SIP_TRANSPORT_UDP) { 20918 int ack_res = FALSE; 20919 20920 /* Acknowledge whatever it is destined for */ 20921 if ((resp >= 100) && (resp <= 199)) { 20922 /* NON-INVITE messages do not ack a 1XX response. RFC 3261 section 17.1.2.2 */ 20923 if (sipmethod == SIP_INVITE) { 20924 ack_res = __sip_semi_ack(p, seqno, 0, sipmethod); 20925 } 20926 } else { 20927 ack_res = __sip_ack(p, seqno, 0, sipmethod); 20928 } 20929 20930 if (ack_res == FALSE) { 20931 /* RFC 3261 13.2.2.4 and 17.1.1.2 - We must re-send ACKs to re-transmitted final responses */ 20932 if (sipmethod == SIP_INVITE && resp >= 200) { 20933 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, resp < 300 ? TRUE: FALSE); 20934 } 20935 20936 append_history(p, "Ignore", "Ignoring this retransmit\n"); 20937 return; 20938 } 20939 } 20940 20941 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 20942 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 20943 p->pendinginvite = 0; 20944 20945 /* Get their tag if we haven't already */ 20946 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 20947 char tag[128]; 20948 20949 gettag(req, "To", tag, sizeof(tag)); 20950 ast_string_field_set(p, theirtag, tag); 20951 } 20952 /* This needs to be configurable on a channel/peer level, 20953 not mandatory for all communication. Sadly enough, NAT implementations 20954 are not so stable so we can always rely on these headers. 20955 Temporarily disabled, while waiting for fix. 20956 Fix assigned to Rizzo :-) 20957 */ 20958 /* check_via_response(p, req); */ 20959 20960 /* RFC 3261 Section 15 specifies that if we receive a 408 or 481 20961 * in response to a BYE, then we should end the current dialog 20962 * and session. It is known that at least one phone manufacturer 20963 * potentially will send a 404 in response to a BYE, so we'll be 20964 * liberal in what we accept and end the dialog and session if we 20965 * receive any of those responses to a BYE. 20966 */ 20967 if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) { 20968 pvt_set_needdestroy(p, "received 4XX response to a BYE"); 20969 return; 20970 } 20971 20972 if (p->relatedpeer && sipmethod == SIP_OPTIONS) { 20973 /* We don't really care what the response is, just that it replied back. 20974 Well, as long as it's not a 100 response... since we might 20975 need to hang around for something more "definitive" */ 20976 if (resp != 100) 20977 handle_response_peerpoke(p, resp, req); 20978 } else if (sipmethod == SIP_REFER && resp >= 200) { 20979 handle_response_refer(p, resp, rest, req, seqno); 20980 } else if (sipmethod == SIP_PUBLISH) { 20981 /* SIP PUBLISH transcends this morass of doodoo and instead 20982 * we just always call the response handler. Good gravy! 20983 */ 20984 handle_response_publish(p, resp, rest, req, seqno); 20985 } else if (sipmethod == SIP_INFO) { 20986 /* More good gravy! */ 20987 handle_response_info(p, resp, rest, req, seqno); 20988 } else if (sipmethod == SIP_MESSAGE) { 20989 /* More good gravy! */ 20990 handle_response_message(p, resp, rest, req, seqno); 20991 } else if (sipmethod == SIP_NOTIFY) { 20992 /* The gravy train continues to roll */ 20993 handle_response_notify(p, resp, rest, req, seqno); 20994 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 20995 switch(resp) { 20996 case 100: /* 100 Trying */ 20997 case 101: /* 101 Dialog establishment */ 20998 case 183: /* 183 Session Progress */ 20999 case 180: /* 180 Ringing */ 21000 case 182: /* 182 Queued */ 21001 case 181: /* 181 Call Is Being Forwarded */ 21002 if (sipmethod == SIP_INVITE) 21003 handle_response_invite(p, resp, rest, req, seqno); 21004 break; 21005 case 200: /* 200 OK */ 21006 p->authtries = 0; /* Reset authentication counter */ 21007 if (sipmethod == SIP_INVITE) { 21008 handle_response_invite(p, resp, rest, req, seqno); 21009 } else if (sipmethod == SIP_REGISTER) { 21010 handle_response_register(p, resp, rest, req, seqno); 21011 } else if (sipmethod == SIP_SUBSCRIBE) { 21012 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 21013 handle_response_subscribe(p, resp, rest, req, seqno); 21014 } else if (sipmethod == SIP_BYE) { /* Ok, we're ready to go */ 21015 pvt_set_needdestroy(p, "received 200 response"); 21016 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 21017 } 21018 break; 21019 case 401: /* Not www-authorized on SIP method */ 21020 case 407: /* Proxy auth required */ 21021 if (sipmethod == SIP_INVITE) 21022 handle_response_invite(p, resp, rest, req, seqno); 21023 else if (sipmethod == SIP_SUBSCRIBE) 21024 handle_response_subscribe(p, resp, rest, req, seqno); 21025 else if (p->registry && sipmethod == SIP_REGISTER) 21026 handle_response_register(p, resp, rest, req, seqno); 21027 else if (sipmethod == SIP_UPDATE) { 21028 handle_response_update(p, resp, rest, req, seqno); 21029 } else if (sipmethod == SIP_BYE) { 21030 if (p->options) 21031 p->options->auth_type = resp; 21032 if (ast_strlen_zero(p->authname)) { 21033 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s but we have no matching peer!\n", 21034 msg, ast_sockaddr_stringify(&p->recv)); 21035 pvt_set_needdestroy(p, "unable to authenticate BYE"); 21036 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, sipmethod, 0)) { 21037 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 21038 pvt_set_needdestroy(p, "failed to authenticate BYE"); 21039 } 21040 } else { 21041 ast_log(LOG_WARNING, "Got authentication request (%d) on %s to '%s'\n", resp, sip_methods[sipmethod].text, get_header(req, "To")); 21042 pvt_set_needdestroy(p, "received 407 response"); 21043 } 21044 break; 21045 case 403: /* Forbidden - we failed authentication */ 21046 if (sipmethod == SIP_INVITE) 21047 handle_response_invite(p, resp, rest, req, seqno); 21048 else if (sipmethod == SIP_SUBSCRIBE) 21049 handle_response_subscribe(p, resp, rest, req, seqno); 21050 else if (p->registry && sipmethod == SIP_REGISTER) 21051 handle_response_register(p, resp, rest, req, seqno); 21052 else { 21053 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 21054 pvt_set_needdestroy(p, "received 403 response"); 21055 } 21056 break; 21057 case 404: /* Not found */ 21058 if (p->registry && sipmethod == SIP_REGISTER) 21059 handle_response_register(p, resp, rest, req, seqno); 21060 else if (sipmethod == SIP_INVITE) 21061 handle_response_invite(p, resp, rest, req, seqno); 21062 else if (sipmethod == SIP_SUBSCRIBE) 21063 handle_response_subscribe(p, resp, rest, req, seqno); 21064 else if (owner) 21065 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 21066 break; 21067 case 423: /* Interval too brief */ 21068 if (sipmethod == SIP_REGISTER) 21069 handle_response_register(p, resp, rest, req, seqno); 21070 break; 21071 case 408: /* Request timeout - terminate dialog */ 21072 if (sipmethod == SIP_INVITE) 21073 handle_response_invite(p, resp, rest, req, seqno); 21074 else if (sipmethod == SIP_REGISTER) 21075 handle_response_register(p, resp, rest, req, seqno); 21076 else if (sipmethod == SIP_BYE) { 21077 pvt_set_needdestroy(p, "received 408 response"); 21078 ast_debug(4, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 21079 } else { 21080 if (owner) 21081 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 21082 pvt_set_needdestroy(p, "received 408 response"); 21083 } 21084 break; 21085 21086 case 428: 21087 case 422: /* Session-Timers: Session Interval Too Small */ 21088 if (sipmethod == SIP_INVITE) { 21089 handle_response_invite(p, resp, rest, req, seqno); 21090 } 21091 break; 21092 21093 case 481: /* Call leg does not exist */ 21094 if (sipmethod == SIP_INVITE) { 21095 handle_response_invite(p, resp, rest, req, seqno); 21096 } else if (sipmethod == SIP_SUBSCRIBE) { 21097 handle_response_subscribe(p, resp, rest, req, seqno); 21098 } else if (sipmethod == SIP_BYE) { 21099 /* The other side has no transaction to bye, 21100 just assume it's all right then */ 21101 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 21102 } else if (sipmethod == SIP_CANCEL) { 21103 /* The other side has no transaction to cancel, 21104 just assume it's all right then */ 21105 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 21106 } else { 21107 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 21108 /* Guessing that this is not an important request */ 21109 } 21110 break; 21111 case 487: 21112 if (sipmethod == SIP_INVITE) 21113 handle_response_invite(p, resp, rest, req, seqno); 21114 break; 21115 case 415: /* Unsupported media type */ 21116 case 488: /* Not acceptable here - codec error */ 21117 case 606: /* Not Acceptable */ 21118 if (sipmethod == SIP_INVITE) 21119 handle_response_invite(p, resp, rest, req, seqno); 21120 break; 21121 case 491: /* Pending */ 21122 if (sipmethod == SIP_INVITE) 21123 handle_response_invite(p, resp, rest, req, seqno); 21124 else { 21125 ast_debug(1, "Got 491 on %s, unsupported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 21126 pvt_set_needdestroy(p, "received 491 response"); 21127 } 21128 break; 21129 case 405: /* Method not allowed */ 21130 case 501: /* Not Implemented */ 21131 mark_method_unallowed(&p->allowed_methods, sipmethod); 21132 if (p->relatedpeer) { 21133 mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod); 21134 } 21135 if (sipmethod == SIP_INVITE) 21136 handle_response_invite(p, resp, rest, req, seqno); 21137 else 21138 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_sockaddr_stringify(&p->sa), msg); 21139 break; 21140 default: 21141 if ((resp >= 300) && (resp < 700)) { 21142 /* Fatal response */ 21143 if ((resp != 487)) 21144 ast_verb(3, "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa)); 21145 21146 if (sipmethod == SIP_INVITE) 21147 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 21148 21149 /* XXX Locking issues?? XXX */ 21150 switch(resp) { 21151 case 300: /* Multiple Choices */ 21152 case 301: /* Moved permanently */ 21153 case 302: /* Moved temporarily */ 21154 case 305: /* Use Proxy */ 21155 if (p->owner) { 21156 struct ast_party_redirecting redirecting; 21157 struct ast_set_party_redirecting update_redirecting; 21158 21159 ast_party_redirecting_init(&redirecting); 21160 change_redirecting_information(p, req, &redirecting, 21161 &update_redirecting, TRUE); 21162 ast_channel_set_redirecting(p->owner, &redirecting, 21163 &update_redirecting); 21164 ast_party_redirecting_free(&redirecting); 21165 } 21166 /* Fall through */ 21167 case 486: /* Busy here */ 21168 case 600: /* Busy everywhere */ 21169 case 603: /* Decline */ 21170 if (p->owner) { 21171 sip_handle_cc(p, req, AST_CC_CCBS); 21172 ast_queue_control(p->owner, AST_CONTROL_BUSY); 21173 } 21174 break; 21175 case 482: /* Loop Detected */ 21176 case 480: /* Temporarily Unavailable */ 21177 case 404: /* Not Found */ 21178 case 410: /* Gone */ 21179 case 400: /* Bad Request */ 21180 case 500: /* Server error */ 21181 if (sipmethod == SIP_SUBSCRIBE) { 21182 handle_response_subscribe(p, resp, rest, req, seqno); 21183 break; 21184 } 21185 /* Fall through */ 21186 case 502: /* Bad gateway */ 21187 case 503: /* Service Unavailable */ 21188 case 504: /* Server Timeout */ 21189 if (owner) 21190 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 21191 break; 21192 case 484: /* Address Incomplete */ 21193 if (owner && sipmethod != SIP_BYE) { 21194 switch (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) { 21195 case SIP_PAGE2_ALLOWOVERLAP_YES: 21196 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(resp)); 21197 break; 21198 default: 21199 ast_queue_hangup_with_cause(p->owner, hangup_sip2cause(404)); 21200 break; 21201 } 21202 } 21203 break; 21204 default: 21205 /* Send hangup */ 21206 if (owner && sipmethod != SIP_BYE) 21207 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR); 21208 break; 21209 } 21210 /* ACK on invite */ 21211 if (sipmethod == SIP_INVITE) 21212 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 21213 sip_alreadygone(p); 21214 if (!p->owner) { 21215 pvt_set_needdestroy(p, "transaction completed"); 21216 } 21217 } else if ((resp >= 100) && (resp < 200)) { 21218 if (sipmethod == SIP_INVITE) { 21219 if (!req->ignore && sip_cancel_destroy(p)) 21220 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 21221 if (find_sdp(req)) 21222 process_sdp(p, req, SDP_T38_NONE); 21223 if (p->owner) { 21224 /* Queue a progress frame */ 21225 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 21226 } 21227 } 21228 } else 21229 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)); 21230 } 21231 } else { 21232 /* Responses to OUTGOING SIP requests on INCOMING calls 21233 get handled here. As well as out-of-call message responses */ 21234 if (req->debug) 21235 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 21236 21237 if (sipmethod == SIP_INVITE && resp == 200) { 21238 /* Tags in early session is replaced by the tag in 200 OK, which is 21239 the final reply to our INVITE */ 21240 char tag[128]; 21241 21242 gettag(req, "To", tag, sizeof(tag)); 21243 ast_string_field_set(p, theirtag, tag); 21244 } 21245 21246 switch(resp) { 21247 case 200: 21248 if (sipmethod == SIP_INVITE) { 21249 handle_response_invite(p, resp, rest, req, seqno); 21250 } else if (sipmethod == SIP_CANCEL) { 21251 ast_debug(1, "Got 200 OK on CANCEL\n"); 21252 21253 /* Wait for 487, then destroy */ 21254 } else if (sipmethod == SIP_BYE) { 21255 pvt_set_needdestroy(p, "transaction completed"); 21256 } 21257 break; 21258 case 401: /* www-auth */ 21259 case 407: 21260 if (sipmethod == SIP_INVITE) 21261 handle_response_invite(p, resp, rest, req, seqno); 21262 else if (sipmethod == SIP_BYE) { 21263 if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, sipmethod, 0)) { 21264 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 21265 pvt_set_needdestroy(p, "failed to authenticate BYE"); 21266 } 21267 } 21268 break; 21269 case 481: /* Call leg does not exist */ 21270 if (sipmethod == SIP_INVITE) { 21271 /* Re-invite failed */ 21272 handle_response_invite(p, resp, rest, req, seqno); 21273 } else if (sipmethod == SIP_BYE) { 21274 pvt_set_needdestroy(p, "received 481 response"); 21275 } else if (sipdebug) { 21276 ast_debug(1, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 21277 } 21278 break; 21279 case 501: /* Not Implemented */ 21280 if (sipmethod == SIP_INVITE) 21281 handle_response_invite(p, resp, rest, req, seqno); 21282 break; 21283 default: /* Errors without handlers */ 21284 if ((resp >= 100) && (resp < 200)) { 21285 if (sipmethod == SIP_INVITE) { /* re-invite */ 21286 if (!req->ignore && sip_cancel_destroy(p)) 21287 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 21288 } 21289 } 21290 if ((resp >= 300) && (resp < 700)) { 21291 if ((resp != 487)) 21292 ast_verb(3, "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa)); 21293 switch(resp) { 21294 case 415: /* Unsupported media type */ 21295 case 488: /* Not acceptable here - codec error */ 21296 case 603: /* Decline */ 21297 case 500: /* Server error */ 21298 case 502: /* Bad gateway */ 21299 case 503: /* Service Unavailable */ 21300 case 504: /* Server timeout */ 21301 21302 /* re-invite failed */ 21303 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 21304 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 21305 break; 21306 } 21307 } 21308 break; 21309 } 21310 } 21311 }
static void handle_response_info | ( | struct sip_pvt * | p, | |
int | resp, | |||
const char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 20795 of file chan_sip.c.
References ast_log(), ast_sockaddr_stringify(), ast_verb, LOG_WARNING, mark_method_allowed(), mark_method_unallowed(), sip_methods, and cfsip_methods::text.
Referenced by handle_response().
20796 { 20797 int sipmethod = SIP_INFO; 20798 20799 switch (resp) { 20800 case 401: /* Not www-authorized on SIP method */ 20801 case 407: /* Proxy auth required */ 20802 ast_log(LOG_WARNING, "Host '%s' requests authentication (%d) for '%s'\n", 20803 ast_sockaddr_stringify(&p->sa), resp, sip_methods[sipmethod].text); 20804 break; 20805 case 405: /* Method not allowed */ 20806 case 501: /* Not Implemented */ 20807 mark_method_unallowed(&p->allowed_methods, sipmethod); 20808 if (p->relatedpeer) { 20809 mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod); 20810 } 20811 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", 20812 ast_sockaddr_stringify(&p->sa), sip_methods[sipmethod].text); 20813 break; 20814 default: 20815 if (300 <= resp && resp < 700) { 20816 ast_verb(3, "Got SIP %s response %d \"%s\" back from host '%s'\n", 20817 sip_methods[sipmethod].text, resp, rest, ast_sockaddr_stringify(&p->sa)); 20818 } 20819 break; 20820 } 20821 }
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 19905 of file chan_sip.c.
References append_history, AST_CAUSE_CONGESTION, AST_CAUSE_NORMAL_CLEARING, AST_CC_CCNR, ast_channel_queue_connected_line_update(), ast_channel_queue_redirecting_update(), AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UPDATE_RTP_PEER, ast_debug, ast_log(), ast_null_frame, ast_party_connected_line_init(), ast_party_redirecting_free(), ast_party_redirecting_init(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_queue_control(), ast_queue_frame(), ast_queue_hangup_with_cause(), ast_random(), ast_rtp_instance_activate(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_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().
19906 { 19907 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 19908 int res = 0; 19909 int xmitres = 0; 19910 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 19911 char *p_hdrval; 19912 int rtn; 19913 struct ast_party_connected_line connected; 19914 struct ast_set_party_connected_line update_connected; 19915 19916 if (reinvite) 19917 ast_debug(4, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 19918 else 19919 ast_debug(4, "SIP response %d to standard invite\n", resp); 19920 19921 if (p->alreadygone) { /* This call is already gone */ 19922 ast_debug(1, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 19923 return; 19924 } 19925 19926 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 19927 /* Don't auto congest anymore since we've gotten something useful back */ 19928 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")); 19929 19930 /* RFC3261 says we must treat every 1xx response (but not 100) 19931 that we don't recognize as if it was 183. 19932 */ 19933 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 181 && resp != 182 && resp != 183) 19934 resp = 183; 19935 19936 /* Any response between 100 and 199 is PROCEEDING */ 19937 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 19938 p->invitestate = INV_PROCEEDING; 19939 19940 /* Final response, not 200 ? */ 19941 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 19942 p->invitestate = INV_COMPLETED; 19943 19944 /* Final response, clear out pending invite */ 19945 if ((resp == 200 || resp >= 300) && p->pendinginvite && seqno == p->pendinginvite) 19946 p->pendinginvite = 0; 19947 19948 /* If this is a response to our initial INVITE, we need to set what we can use 19949 * for this peer. 19950 */ 19951 if (!reinvite) { 19952 set_pvt_allowed_methods(p, req); 19953 } 19954 19955 switch (resp) { 19956 case 100: /* Trying */ 19957 case 101: /* Dialog establishment */ 19958 if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p)) 19959 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 19960 check_pendings(p); 19961 break; 19962 19963 case 180: /* 180 Ringing */ 19964 case 182: /* 182 Queued */ 19965 if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p)) 19966 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 19967 /* Store Route-set from provisional SIP responses so 19968 * early-dialog request can be routed properly 19969 * */ 19970 parse_ok_contact(p, req); 19971 if (!reinvite) { 19972 build_route(p, req, 1, resp); 19973 } 19974 if (!req->ignore && p->owner) { 19975 if (get_rpid(p, req)) { 19976 /* Queue a connected line update */ 19977 ast_party_connected_line_init(&connected); 19978 memset(&update_connected, 0, sizeof(update_connected)); 19979 19980 update_connected.id.number = 1; 19981 connected.id.number.valid = 1; 19982 connected.id.number.str = (char *) p->cid_num; 19983 connected.id.number.presentation = p->callingpres; 19984 19985 update_connected.id.name = 1; 19986 connected.id.name.valid = 1; 19987 connected.id.name.str = (char *) p->cid_name; 19988 connected.id.name.presentation = p->callingpres; 19989 19990 connected.id.tag = (char *) p->cid_tag; 19991 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 19992 ast_channel_queue_connected_line_update(p->owner, &connected, 19993 &update_connected); 19994 } 19995 sip_handle_cc(p, req, AST_CC_CCNR); 19996 ast_queue_control(p->owner, AST_CONTROL_RINGING); 19997 if (p->owner->_state != AST_STATE_UP) { 19998 ast_setstate(p->owner, AST_STATE_RINGING); 19999 } 20000 } 20001 if (find_sdp(req)) { 20002 if (p->invitestate != INV_CANCELLED) 20003 p->invitestate = INV_EARLY_MEDIA; 20004 res = process_sdp(p, req, SDP_T38_NONE); 20005 if (!req->ignore && p->owner) { 20006 /* Queue a progress frame only if we have SDP in 180 or 182 */ 20007 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 20008 } 20009 ast_rtp_instance_activate(p->rtp); 20010 } 20011 check_pendings(p); 20012 break; 20013 20014 case 181: /* Call Is Being Forwarded */ 20015 if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 20016 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20017 /* Store Route-set from provisional SIP responses so 20018 * early-dialog request can be routed properly 20019 * */ 20020 parse_ok_contact(p, req); 20021 if (!reinvite) { 20022 build_route(p, req, 1, resp); 20023 } 20024 if (!req->ignore && p->owner) { 20025 struct ast_party_redirecting redirecting; 20026 struct ast_set_party_redirecting update_redirecting; 20027 20028 ast_party_redirecting_init(&redirecting); 20029 memset(&update_redirecting, 0, sizeof(update_redirecting)); 20030 change_redirecting_information(p, req, &redirecting, &update_redirecting, 20031 FALSE); 20032 ast_channel_queue_redirecting_update(p->owner, &redirecting, 20033 &update_redirecting); 20034 ast_party_redirecting_free(&redirecting); 20035 sip_handle_cc(p, req, AST_CC_CCNR); 20036 } 20037 check_pendings(p); 20038 break; 20039 20040 case 183: /* Session progress */ 20041 if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 20042 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20043 /* Store Route-set from provisional SIP responses so 20044 * early-dialog request can be routed properly 20045 * */ 20046 parse_ok_contact(p, req); 20047 if (!reinvite) { 20048 build_route(p, req, 1, resp); 20049 } 20050 if (!req->ignore && p->owner) { 20051 if (get_rpid(p, req)) { 20052 /* Queue a connected line update */ 20053 ast_party_connected_line_init(&connected); 20054 memset(&update_connected, 0, sizeof(update_connected)); 20055 20056 update_connected.id.number = 1; 20057 connected.id.number.valid = 1; 20058 connected.id.number.str = (char *) p->cid_num; 20059 connected.id.number.presentation = p->callingpres; 20060 20061 update_connected.id.name = 1; 20062 connected.id.name.valid = 1; 20063 connected.id.name.str = (char *) p->cid_name; 20064 connected.id.name.presentation = p->callingpres; 20065 20066 connected.id.tag = (char *) p->cid_tag; 20067 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 20068 ast_channel_queue_connected_line_update(p->owner, &connected, 20069 &update_connected); 20070 } 20071 sip_handle_cc(p, req, AST_CC_CCNR); 20072 } 20073 if (find_sdp(req)) { 20074 if (p->invitestate != INV_CANCELLED) 20075 p->invitestate = INV_EARLY_MEDIA; 20076 res = process_sdp(p, req, SDP_T38_NONE); 20077 if (!req->ignore && p->owner) { 20078 /* Queue a progress frame */ 20079 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 20080 } 20081 ast_rtp_instance_activate(p->rtp); 20082 } else { 20083 /* Alcatel PBXs are known to send 183s with no SDP after sending 20084 * a 100 Trying response. We're just going to treat this sort of thing 20085 * the same as we would treat a 180 Ringing 20086 */ 20087 if (!req->ignore && p->owner) { 20088 ast_queue_control(p->owner, AST_CONTROL_RINGING); 20089 } 20090 } 20091 check_pendings(p); 20092 break; 20093 20094 case 200: /* 200 OK on invite - someone's answering our call */ 20095 if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 20096 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 20097 p->authtries = 0; 20098 if (find_sdp(req)) { 20099 if ((res = process_sdp(p, req, SDP_T38_ACCEPT)) && !req->ignore) 20100 if (!reinvite) 20101 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 20102 /* For re-invites, we try to recover */ 20103 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 20104 ast_rtp_instance_activate(p->rtp); 20105 } 20106 20107 if (!req->ignore && p->owner) { 20108 int rpid_changed; 20109 20110 rpid_changed = get_rpid(p, req); 20111 if (rpid_changed || !reinvite) { 20112 /* Queue a connected line update */ 20113 ast_party_connected_line_init(&connected); 20114 memset(&update_connected, 0, sizeof(update_connected)); 20115 if (rpid_changed 20116 || !ast_strlen_zero(p->cid_num) 20117 || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 20118 update_connected.id.number = 1; 20119 connected.id.number.valid = 1; 20120 connected.id.number.str = (char *) p->cid_num; 20121 connected.id.number.presentation = p->callingpres; 20122 } 20123 if (rpid_changed 20124 || !ast_strlen_zero(p->cid_name) 20125 || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 20126 update_connected.id.name = 1; 20127 connected.id.name.valid = 1; 20128 connected.id.name.str = (char *) p->cid_name; 20129 connected.id.name.presentation = p->callingpres; 20130 } 20131 if (update_connected.id.number || update_connected.id.name) { 20132 connected.id.tag = (char *) p->cid_tag; 20133 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 20134 ast_channel_queue_connected_line_update(p->owner, &connected, 20135 &update_connected); 20136 } 20137 } 20138 } 20139 20140 /* Parse contact header for continued conversation */ 20141 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 20142 /* This is important when we have a SIP proxy between us and the phone */ 20143 if (outgoing) { 20144 update_call_counter(p, DEC_CALL_RINGING); 20145 parse_ok_contact(p, req); 20146 /* Save Record-Route for any later requests we make on this dialogue */ 20147 if (!reinvite) 20148 build_route(p, req, 1, resp); 20149 20150 if(set_address_from_contact(p)) { 20151 /* Bad contact - we don't know how to reach this device */ 20152 /* We need to ACK, but then send a bye */ 20153 if (!p->route && !req->ignore) 20154 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 20155 } 20156 20157 } 20158 20159 if (!req->ignore && p->owner) { 20160 if (!reinvite) { 20161 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 20162 if (sip_cfg.callevents) 20163 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 20164 "Channel: %s\r\nChanneltype: %s\r\nUniqueid: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n", 20165 p->owner->name, "SIP", p->owner->uniqueid, p->callid, p->fullcontact, p->peername); 20166 } else { /* RE-invite */ 20167 if (p->t38.state == T38_DISABLED) { 20168 ast_queue_control(p->owner, AST_CONTROL_UPDATE_RTP_PEER); 20169 } else { 20170 ast_queue_frame(p->owner, &ast_null_frame); 20171 } 20172 } 20173 } else { 20174 /* It's possible we're getting an 200 OK after we've tried to disconnect 20175 by sending CANCEL */ 20176 /* First send ACK, then send bye */ 20177 if (!req->ignore) 20178 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 20179 } 20180 20181 /* Check for Session-Timers related headers */ 20182 if (st_get_mode(p, 0) != SESSION_TIMER_MODE_REFUSE && p->outgoing_call == TRUE && !reinvite) { 20183 p_hdrval = (char*)get_header(req, "Session-Expires"); 20184 if (!ast_strlen_zero(p_hdrval)) { 20185 /* UAS supports Session-Timers */ 20186 enum st_refresher tmp_st_ref = SESSION_TIMER_REFRESHER_AUTO; 20187 int tmp_st_interval = 0; 20188 rtn = parse_session_expires(p_hdrval, &tmp_st_interval, &tmp_st_ref); 20189 if (rtn != 0) { 20190 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 20191 } 20192 if (tmp_st_ref == SESSION_TIMER_REFRESHER_UAC || 20193 tmp_st_ref == SESSION_TIMER_REFRESHER_UAS) { 20194 p->stimer->st_ref = tmp_st_ref; 20195 } 20196 if (tmp_st_interval) { 20197 p->stimer->st_interval = tmp_st_interval; 20198 } 20199 p->stimer->st_active = TRUE; 20200 p->stimer->st_active_peer_ua = TRUE; 20201 start_session_timer(p); 20202 } else { 20203 /* UAS doesn't support Session-Timers */ 20204 if (st_get_mode(p, 0) == SESSION_TIMER_MODE_ORIGINATE) { 20205 p->stimer->st_ref = SESSION_TIMER_REFRESHER_UAC; 20206 p->stimer->st_active_peer_ua = FALSE; 20207 start_session_timer(p); 20208 } 20209 } 20210 } 20211 20212 20213 /* If I understand this right, the branch is different for a non-200 ACK only */ 20214 p->invitestate = INV_TERMINATED; 20215 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 20216 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 20217 check_pendings(p); 20218 break; 20219 20220 case 407: /* Proxy authentication */ 20221 case 401: /* Www auth */ 20222 /* First we ACK */ 20223 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 20224 if (p->options) 20225 p->options->auth_type = resp; 20226 20227 /* Then we AUTH */ 20228 ast_string_field_set(p, theirtag, NULL); /* forget their old tag, so we don't match tags when getting response */ 20229 if (!req->ignore) { 20230 if (p->authtries < MAX_AUTHTRIES) 20231 p->invitestate = INV_CALLING; 20232 if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, SIP_INVITE, 1)) { 20233 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 20234 pvt_set_needdestroy(p, "failed to authenticate on INVITE"); 20235 sip_alreadygone(p); 20236 if (p->owner) 20237 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 20238 } 20239 } 20240 break; 20241 20242 case 403: /* Forbidden */ 20243 /* First we ACK */ 20244 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 20245 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 20246 if (!req->ignore && p->owner) { 20247 ast_set_hangupsource(p->owner, p->owner->name, 0); 20248 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION); 20249 } 20250 break; 20251 20252 case 404: /* Not found */ 20253 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 20254 if (p->owner && !req->ignore) { 20255 ast_set_hangupsource(p->owner, p->owner->name, 0); 20256 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION); 20257 } 20258 break; 20259 20260 case 408: /* Request timeout */ 20261 case 481: /* Call leg does not exist */ 20262 /* Could be REFER caused INVITE with replaces */ 20263 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 20264 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 20265 if (p->owner) { 20266 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION); 20267 } 20268 break; 20269 20270 case 422: /* Session-Timers: Session interval too small */ 20271 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 20272 ast_string_field_set(p, theirtag, NULL); 20273 proc_422_rsp(p, req); 20274 break; 20275 20276 case 428: /* Use identity header - rfc 4474 - not supported by Asterisk yet */ 20277 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 20278 append_history(p, "Identity", "SIP identity is required. Not supported by Asterisk."); 20279 ast_log(LOG_WARNING, "SIP identity required by proxy. SIP dialog '%s'. Giving up.\n", p->callid); 20280 if (p->owner && !req->ignore) { 20281 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION); 20282 } 20283 break; 20284 20285 case 487: /* Cancelled transaction */ 20286 /* We have sent CANCEL on an outbound INVITE 20287 This transaction is already scheduled to be killed by sip_hangup(). 20288 */ 20289 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 20290 if (p->owner && !req->ignore) { 20291 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_NORMAL_CLEARING); 20292 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 20293 } else if (!req->ignore) { 20294 update_call_counter(p, DEC_CALL_LIMIT); 20295 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 20296 } 20297 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 20298 break; 20299 case 415: /* Unsupported media type */ 20300 case 488: /* Not acceptable here */ 20301 case 606: /* Not Acceptable */ 20302 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 20303 if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) { 20304 change_t38_state(p, T38_DISABLED); 20305 /* Try to reset RTP timers */ 20306 //ast_rtp_set_rtptimers_onhold(p->rtp); 20307 20308 /* Trigger a reinvite back to audio */ 20309 transmit_reinvite_with_sdp(p, FALSE, FALSE); 20310 } else { 20311 /* We can't set up this call, so give up */ 20312 if (p->owner && !req->ignore) { 20313 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION); 20314 } 20315 } 20316 break; 20317 case 491: /* Pending */ 20318 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 20319 if (p->owner && !req->ignore) { 20320 if (p->owner->_state != AST_STATE_UP) { 20321 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION); 20322 } else { 20323 /* This is a re-invite that failed. */ 20324 /* Reset the flag after a while 20325 */ 20326 int wait; 20327 /* RFC 3261, if owner of call, wait between 2.1 to 4 seconds, 20328 * if not owner of call, wait 0 to 2 seconds */ 20329 if (p->outgoing_call) { 20330 wait = 2100 + ast_random() % 2000; 20331 } else { 20332 wait = ast_random() % 2000; 20333 } 20334 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.")); 20335 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); 20336 ast_debug(2, "Reinvite race. Waiting %d secs before retry\n", wait); 20337 } 20338 } 20339 break; 20340 20341 case 405: /* Not allowed */ 20342 case 501: /* Not implemented */ 20343 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 20344 if (p->owner) { 20345 ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION); 20346 } 20347 break; 20348 } 20349 if (xmitres == XMIT_ERROR) 20350 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 20351 }
static void handle_response_message | ( | struct sip_pvt * | p, | |
int | resp, | |||
const char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 20831 of file chan_sip.c.
References ast_log(), ast_sockaddr_stringify(), ast_verb, LOG_WARNING, mark_method_allowed(), mark_method_unallowed(), sip_methods, and cfsip_methods::text.
Referenced by handle_response().
20832 { 20833 int sipmethod = SIP_MESSAGE; 20834 /* Out-of-dialog MESSAGE currently not supported. */ 20835 //int in_dialog = ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 20836 20837 switch (resp) { 20838 case 401: /* Not www-authorized on SIP method */ 20839 case 407: /* Proxy auth required */ 20840 ast_log(LOG_WARNING, "Host '%s' requests authentication (%d) for '%s'\n", 20841 ast_sockaddr_stringify(&p->sa), resp, sip_methods[sipmethod].text); 20842 break; 20843 case 405: /* Method not allowed */ 20844 case 501: /* Not Implemented */ 20845 mark_method_unallowed(&p->allowed_methods, sipmethod); 20846 if (p->relatedpeer) { 20847 mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod); 20848 } 20849 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", 20850 ast_sockaddr_stringify(&p->sa), sip_methods[sipmethod].text); 20851 break; 20852 default: 20853 if (100 <= resp && resp < 200) { 20854 /* Must allow provisional responses for out-of-dialog requests. */ 20855 } else if (200 <= resp && resp < 300) { 20856 p->authtries = 0; /* Reset authentication counter */ 20857 } else if (300 <= resp && resp < 700) { 20858 ast_verb(3, "Got SIP %s response %d \"%s\" back from host '%s'\n", 20859 sip_methods[sipmethod].text, resp, rest, ast_sockaddr_stringify(&p->sa)); 20860 } 20861 break; 20862 } 20863 }
static void handle_response_notify | ( | struct sip_pvt * | p, | |
int | resp, | |||
const char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 20356 of file chan_sip.c.
References ast_clear_flag, ast_debug, ast_log(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, cb_extensionstate(), do_proxy_auth(), get_header(), LOG_NOTICE, LOG_WARNING, NONE, and pvt_set_needdestroy().
Referenced by handle_response().
20357 { 20358 switch (resp) { 20359 case 200: /* Notify accepted */ 20360 /* They got the notify, this is the end */ 20361 if (p->owner) { 20362 if (p->refer) { 20363 ast_log(LOG_NOTICE, "Got OK on REFER Notify message\n"); 20364 } else { 20365 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 20366 } 20367 } else { 20368 if (p->subscribed == NONE && !p->refer) { 20369 ast_debug(4, "Got 200 accepted on NOTIFY %s\n", p->callid); 20370 pvt_set_needdestroy(p, "received 200 response"); 20371 } 20372 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 20373 /* Ready to send the next state we have on queue */ 20374 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 20375 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 20376 } 20377 } 20378 break; 20379 case 401: /* Not www-authorized on SIP method */ 20380 case 407: /* Proxy auth */ 20381 if (!p->notify) { 20382 break; /* Only device notify can use NOTIFY auth */ 20383 } 20384 ast_string_field_set(p, theirtag, NULL); 20385 if (ast_strlen_zero(p->authname)) { 20386 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)); 20387 pvt_set_needdestroy(p, "unable to authenticate NOTIFY"); 20388 } 20389 if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_NOTIFY, 0)) { 20390 ast_log(LOG_NOTICE, "Failed to authenticate on NOTIFY to '%s'\n", get_header(&p->initreq, "From")); 20391 pvt_set_needdestroy(p, "failed to authenticate NOTIFY"); 20392 } 20393 break; 20394 case 481: /* Call leg does not exist */ 20395 pvt_set_needdestroy(p, "Received 481 response for NOTIFY"); 20396 break; 20397 } 20398 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 20728 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().
20729 { 20730 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! */ 20731 int statechanged, is_reachable, was_reachable; 20732 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 20733 20734 /* 20735 * Compute the response time to a ping (goes in peer->lastms.) 20736 * -1 means did not respond, 0 means unknown, 20737 * 1..maxms is a valid response, >maxms means late response. 20738 */ 20739 if (pingtime < 1) { /* zero = unknown, so round up to 1 */ 20740 pingtime = 1; 20741 } 20742 20743 if (!peer->maxms) { /* this should never happens */ 20744 pvt_set_needdestroy(p, "got OPTIONS response but qualify is not enabled"); 20745 return; 20746 } 20747 20748 /* Now determine new state and whether it has changed. 20749 * Use some helper variables to simplify the writing 20750 * of the expressions. 20751 */ 20752 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 20753 is_reachable = pingtime <= peer->maxms; 20754 statechanged = peer->lastms == 0 /* yes, unknown before */ 20755 || was_reachable != is_reachable; 20756 20757 peer->lastms = pingtime; 20758 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 20759 if (statechanged) { 20760 const char *s = is_reachable ? "Reachable" : "Lagged"; 20761 char str_lastms[20]; 20762 snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime); 20763 20764 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 20765 peer->name, s, pingtime, peer->maxms); 20766 ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name); 20767 if (sip_cfg.peer_rtupdate) { 20768 ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", str_lastms, SENTINEL); 20769 } 20770 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 20771 "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 20772 peer->name, s, pingtime); 20773 if (is_reachable && sip_cfg.regextenonqualify) 20774 register_peer_exten(peer, TRUE); 20775 } 20776 20777 pvt_set_needdestroy(p, "got OPTIONS response"); 20778 20779 /* Try again eventually */ 20780 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, 20781 is_reachable ? peer->qualifyfreq : DEFAULT_FREQ_NOTOK, 20782 sip_poke_peer_s, peer, 20783 unref_peer(_data, "removing poke peer ref"), 20784 unref_peer(peer, "removing poke peer ref"), 20785 ref_peer(peer, "adding poke peer ref")); 20786 }
static void handle_response_publish | ( | struct sip_pvt * | p, | |
int | resp, | |||
const char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 19854 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().
19855 { 19856 struct sip_epa_entry *epa_entry = p->epa_entry; 19857 const char *etag = get_header(req, "Sip-ETag"); 19858 19859 ast_assert(epa_entry != NULL); 19860 19861 if (resp == 401 || resp == 407) { 19862 ast_string_field_set(p, theirtag, NULL); 19863 if (p->options) { 19864 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 19865 } 19866 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_PUBLISH, 0)) { 19867 ast_log(LOG_NOTICE, "Failed to authenticate on PUBLISH to '%s'\n", get_header(&p->initreq, "From")); 19868 pvt_set_needdestroy(p, "Failed to authenticate on PUBLISH"); 19869 sip_alreadygone(p); 19870 } 19871 return; 19872 } 19873 19874 if (resp == 501 || resp == 405) { 19875 mark_method_unallowed(&p->allowed_methods, SIP_PUBLISH); 19876 } 19877 19878 if (resp == 200) { 19879 p->authtries = 0; 19880 /* If I've read section 6, item 6 of RFC 3903 correctly, 19881 * an ESC will only generate a new etag when it sends a 200 OK 19882 */ 19883 if (!ast_strlen_zero(etag)) { 19884 ast_copy_string(epa_entry->entity_tag, etag, sizeof(epa_entry->entity_tag)); 19885 } 19886 /* The nominal case. Everything went well. Everybody is happy. 19887 * Each EPA will have a specific action to take as a result of this 19888 * development, so ... callbacks! 19889 */ 19890 if (epa_entry->static_data->handle_ok) { 19891 epa_entry->static_data->handle_ok(p, req, epa_entry); 19892 } 19893 } else { 19894 /* Rather than try to make individual callbacks for each error 19895 * type, there is just a single error callback. The callback 19896 * can distinguish between error messages and do what it needs to 19897 */ 19898 if (epa_entry->static_data->handle_error) { 19899 epa_entry->static_data->handle_error(p, resp, req, epa_entry); 19900 } 19901 } 19902 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
const char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 20484 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().
20485 { 20486 enum ast_control_transfer message = AST_TRANSFER_FAILED; 20487 20488 /* If no refer structure exists, then do nothing */ 20489 if (!p->refer) 20490 return; 20491 20492 switch (resp) { 20493 case 202: /* Transfer accepted */ 20494 /* We need to do something here */ 20495 /* The transferee is now sending INVITE to target */ 20496 p->refer->status = REFER_ACCEPTED; 20497 /* Now wait for next message */ 20498 ast_debug(3, "Got 202 accepted on transfer\n"); 20499 /* We should hang along, waiting for NOTIFY's here */ 20500 break; 20501 20502 case 401: /* Not www-authorized on SIP method */ 20503 case 407: /* Proxy auth */ 20504 if (ast_strlen_zero(p->authname)) { 20505 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s but we have no matching peer or realm auth!\n", 20506 ast_sockaddr_stringify(&p->recv)); 20507 if (p->owner) { 20508 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 20509 } 20510 pvt_set_needdestroy(p, "unable to authenticate REFER"); 20511 } 20512 if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_REFER, 0)) { 20513 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 20514 p->refer->status = REFER_NOAUTH; 20515 if (p->owner) { 20516 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 20517 } 20518 pvt_set_needdestroy(p, "failed to authenticate REFER"); 20519 } 20520 break; 20521 20522 case 405: /* Method not allowed */ 20523 /* Return to the current call onhold */ 20524 /* Status flag needed to be reset */ 20525 ast_log(LOG_NOTICE, "SIP transfer to %s failed, REFER not allowed. \n", p->refer->refer_to); 20526 pvt_set_needdestroy(p, "received 405 response"); 20527 p->refer->status = REFER_FAILED; 20528 if (p->owner) { 20529 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 20530 } 20531 break; 20532 20533 case 481: /* Call leg does not exist */ 20534 20535 /* A transfer with Replaces did not work */ 20536 /* OEJ: We should Set flag, cancel the REFER, go back 20537 to original call - but right now we can't */ 20538 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 20539 if (p->owner) 20540 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 20541 pvt_set_needdestroy(p, "received 481 response"); 20542 break; 20543 20544 case 500: /* Server error */ 20545 case 501: /* Method not implemented */ 20546 /* Return to the current call onhold */ 20547 /* Status flag needed to be reset */ 20548 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 20549 pvt_set_needdestroy(p, "received 500/501 response"); 20550 p->refer->status = REFER_FAILED; 20551 if (p->owner) { 20552 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 20553 } 20554 break; 20555 case 603: /* Transfer declined */ 20556 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 20557 p->refer->status = REFER_FAILED; 20558 pvt_set_needdestroy(p, "received 603 response"); 20559 if (p->owner) { 20560 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 20561 } 20562 break; 20563 default: 20564 /* We should treat unrecognized 9xx as 900. 400 is actually 20565 specified as a possible response, but any 4-6xx is 20566 theoretically possible. */ 20567 20568 if (resp < 299) { /* 1xx cases don't get here */ 20569 ast_log(LOG_WARNING, "SIP transfer to %s had unxpected 2xx response (%d), confusion is possible. \n", p->refer->refer_to, resp); 20570 } else { 20571 ast_log(LOG_WARNING, "SIP transfer to %s with response (%d). \n", p->refer->refer_to, resp); 20572 } 20573 20574 p->refer->status = REFER_FAILED; 20575 pvt_set_needdestroy(p, "received failure response"); 20576 if (p->owner) { 20577 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 20578 } 20579 break; 20580 } 20581 }
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 20584 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().
20585 { 20586 int expires, expires_ms; 20587 struct sip_registry *r; 20588 r=p->registry; 20589 20590 switch (resp) { 20591 case 401: /* Unauthorized */ 20592 if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) { 20593 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 20594 pvt_set_needdestroy(p, "failed to authenticate REGISTER"); 20595 } 20596 break; 20597 case 403: /* Forbidden */ 20598 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 20599 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 403")); 20600 r->regstate = REG_STATE_NOAUTH; 20601 pvt_set_needdestroy(p, "received 403 response"); 20602 break; 20603 case 404: /* Not found */ 20604 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username, p->registry->hostname); 20605 pvt_set_needdestroy(p, "received 404 response"); 20606 if (r->call) 20607 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 404"); 20608 r->regstate = REG_STATE_REJECTED; 20609 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 404")); 20610 break; 20611 case 407: /* Proxy auth */ 20612 if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) { 20613 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 20614 pvt_set_needdestroy(p, "failed to authenticate REGISTER"); 20615 } 20616 break; 20617 case 408: /* Request timeout */ 20618 /* Got a timeout response, so reset the counter of failed responses */ 20619 if (r) { 20620 r->regattempts = 0; 20621 } else { 20622 ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid); 20623 } 20624 break; 20625 case 423: /* Interval too brief */ 20626 r->expiry = atoi(get_header(req, "Min-Expires")); 20627 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); 20628 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 423")); 20629 if (r->call) { 20630 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 423"); 20631 pvt_set_needdestroy(p, "received 423 response"); 20632 } 20633 if (r->expiry > max_expiry) { 20634 ast_log(LOG_WARNING, "Required expiration time from %s@%s is too high, giving up\n", p->registry->username, p->registry->hostname); 20635 r->expiry = r->configured_expiry; 20636 r->regstate = REG_STATE_REJECTED; 20637 } else { 20638 r->regstate = REG_STATE_UNREGISTERED; 20639 transmit_register(r, SIP_REGISTER, NULL, NULL); 20640 } 20641 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)); 20642 break; 20643 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 20644 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username, p->registry->hostname); 20645 pvt_set_needdestroy(p, "received 479 response"); 20646 if (r->call) 20647 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 479"); 20648 r->regstate = REG_STATE_REJECTED; 20649 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 479")); 20650 break; 20651 case 200: /* 200 OK */ 20652 if (!r) { 20653 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)); 20654 pvt_set_needdestroy(p, "received erroneous 200 response"); 20655 return 0; 20656 } 20657 20658 r->regstate = REG_STATE_REGISTERED; 20659 r->regtime = ast_tvnow(); /* Reset time of last successful registration */ 20660 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 20661 r->regattempts = 0; 20662 ast_debug(1, "Registration successful\n"); 20663 if (r->timeout > -1) { 20664 ast_debug(1, "Cancelling timeout %d\n", r->timeout); 20665 } 20666 AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 200")); 20667 if (r->call) 20668 r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 200"); 20669 p->registry = registry_unref(p->registry, "unref registry entry p->registry"); 20670 /* Let this one hang around until we have all the responses */ 20671 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 20672 /* p->needdestroy = 1; */ 20673 20674 /* set us up for re-registering 20675 * figure out how long we got registered for 20676 * according to section 6.13 of RFC, contact headers override 20677 * expires headers, so check those first */ 20678 expires = 0; 20679 20680 /* XXX todo: try to save the extra call */ 20681 if (!ast_strlen_zero(get_header(req, "Contact"))) { 20682 const char *contact = NULL; 20683 const char *tmptmp = NULL; 20684 int start = 0; 20685 for(;;) { 20686 contact = __get_header(req, "Contact", &start); 20687 /* this loop ensures we get a contact header about our register request */ 20688 if(!ast_strlen_zero(contact)) { 20689 if( (tmptmp=strstr(contact, p->our_contact))) { 20690 contact=tmptmp; 20691 break; 20692 } 20693 } else 20694 break; 20695 } 20696 tmptmp = strcasestr(contact, "expires="); 20697 if (tmptmp) { 20698 if (sscanf(tmptmp + 8, "%30d;", &expires) != 1) 20699 expires = 0; 20700 } 20701 20702 } 20703 if (!expires) 20704 expires=atoi(get_header(req, "expires")); 20705 if (!expires) 20706 expires=default_expiry; 20707 20708 expires_ms = expires * 1000; 20709 if (expires <= EXPIRY_GUARD_LIMIT) 20710 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT), EXPIRY_GUARD_MIN); 20711 else 20712 expires_ms -= EXPIRY_GUARD_SECS * 1000; 20713 if (sipdebug) 20714 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 20715 20716 r->refresh= (int) expires_ms / 1000; 20717 20718 /* Schedule re-registration before we expire */ 20719 AST_SCHED_REPLACE_UNREF(r->expire, sched, expires_ms, sip_reregister, r, 20720 registry_unref(_data,"unref in REPLACE del fail"), 20721 registry_unref(r,"unref in REPLACE add fail"), 20722 registry_addref(r,"The Addition side of REPLACE")); 20723 } 20724 return 1; 20725 }
static void handle_response_subscribe | ( | struct sip_pvt * | p, | |
int | resp, | |||
const char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 20401 of file chan_sip.c.
References ao2_callback, ast_cc_monitor_failed(), ast_debug, ast_free, ast_log(), ast_sched_add(), ast_string_field_set, ASTOBJ_REF, ASTOBJ_UNREF, do_proxy_auth(), find_sip_monitor_instance_by_subscription_pvt(), get_header(), LOG_NOTICE, LOG_WARNING, mwi_expiry, pvt_set_needdestroy(), set_pvt_allowed_methods(), sip_alreadygone(), sip_monitor_instances, sip_subscribe_mwi_destroy(), sip_subscribe_mwi_do(), and transmit_response_with_date().
Referenced by handle_response().
20402 { 20403 if (p->subscribed == CALL_COMPLETION) { 20404 struct sip_monitor_instance *monitor_instance; 20405 20406 if (resp < 300) { 20407 return; 20408 } 20409 20410 /* Final failure response received. */ 20411 monitor_instance = ao2_callback(sip_monitor_instances, 0, 20412 find_sip_monitor_instance_by_subscription_pvt, p); 20413 if (monitor_instance) { 20414 ast_cc_monitor_failed(monitor_instance->core_id, 20415 monitor_instance->device_name, 20416 "Received error response to our SUBSCRIBE"); 20417 } 20418 return; 20419 } 20420 20421 if (p->subscribed != MWI_NOTIFICATION) { 20422 return; 20423 } 20424 if (!p->mwi) { 20425 return; 20426 } 20427 20428 switch (resp) { 20429 case 200: /* Subscription accepted */ 20430 ast_debug(3, "Got 200 OK on subscription for MWI\n"); 20431 set_pvt_allowed_methods(p, req); 20432 if (p->options) { 20433 ast_free(p->options); 20434 p->options = NULL; 20435 } 20436 p->mwi->subscribed = 1; 20437 if ((p->mwi->resub = ast_sched_add(sched, mwi_expiry * 1000, sip_subscribe_mwi_do, ASTOBJ_REF(p->mwi))) < 0) { 20438 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 20439 } 20440 break; 20441 case 401: 20442 case 407: 20443 ast_string_field_set(p, theirtag, NULL); 20444 if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_SUBSCRIBE, 0)) { 20445 ast_log(LOG_NOTICE, "Failed to authenticate on SUBSCRIBE to '%s'\n", get_header(&p->initreq, "From")); 20446 p->mwi->call = NULL; 20447 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 20448 pvt_set_needdestroy(p, "failed to authenticate SUBSCRIBE"); 20449 } 20450 break; 20451 case 403: 20452 transmit_response_with_date(p, "200 OK", req); 20453 ast_log(LOG_WARNING, "Authentication failed while trying to subscribe for MWI.\n"); 20454 p->mwi->call = NULL; 20455 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 20456 pvt_set_needdestroy(p, "received 403 response"); 20457 sip_alreadygone(p); 20458 break; 20459 case 404: 20460 ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that a mailbox may not have been configured.\n"); 20461 p->mwi->call = NULL; 20462 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 20463 pvt_set_needdestroy(p, "received 404 response"); 20464 break; 20465 case 481: 20466 ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that our dialog did not exist.\n"); 20467 p->mwi->call = NULL; 20468 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 20469 pvt_set_needdestroy(p, "received 481 response"); 20470 break; 20471 case 500: 20472 case 501: 20473 ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side may have suffered a heart attack.\n"); 20474 p->mwi->call = NULL; 20475 ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); 20476 pvt_set_needdestroy(p, "received 500/501 response"); 20477 break; 20478 } 20479 }
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 19794 of file chan_sip.c.
References ast_log(), do_proxy_auth(), get_header(), and LOG_NOTICE.
Referenced by handle_response().
19795 { 19796 if (p->options) { 19797 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 19798 } 19799 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_UPDATE, 1)) { 19800 ast_log(LOG_NOTICE, "Failed to authenticate on UPDATE to '%s'\n", get_header(&p->initreq, "From")); 19801 } 19802 }
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 24203 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().
24204 { 24205 struct sip_esc_entry *esc_entry = create_esc_entry(esc, req, expires); 24206 int res = 0; 24207 24208 if (!esc_entry) { 24209 transmit_response(p, "503 Internal Server Failure", req); 24210 return -1; 24211 } 24212 24213 if (esc->callbacks->initial_handler) { 24214 res = esc->callbacks->initial_handler(p, req, esc, esc_entry); 24215 } 24216 24217 if (!res) { 24218 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 0); 24219 } 24220 24221 ao2_ref(esc_entry, -1); 24222 return res; 24223 }
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 24253 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().
24254 { 24255 struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc); 24256 int expires_ms = expires * 1000; 24257 int res = 0; 24258 24259 if (!esc_entry) { 24260 transmit_response(p, "412 Conditional Request Failed", req); 24261 return -1; 24262 } 24263 24264 AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry, 24265 ao2_ref(_data, -1), 24266 ao2_ref(esc_entry, -1), 24267 ao2_ref(esc_entry, +1)); 24268 24269 if (esc->callbacks->modify_handler) { 24270 res = esc->callbacks->modify_handler(p, req, esc, esc_entry); 24271 } 24272 24273 if (!res) { 24274 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1); 24275 } 24276 24277 ao2_ref(esc_entry, -1); 24278 return res; 24279 }
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 24225 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().
24226 { 24227 struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc); 24228 int expires_ms = expires * 1000; 24229 int res = 0; 24230 24231 if (!esc_entry) { 24232 transmit_response(p, "412 Conditional Request Failed", req); 24233 return -1; 24234 } 24235 24236 AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry, 24237 ao2_ref(_data, -1), 24238 ao2_ref(esc_entry, -1), 24239 ao2_ref(esc_entry, +1)); 24240 24241 if (esc->callbacks->refresh_handler) { 24242 res = esc->callbacks->refresh_handler(p, req, esc, esc_entry); 24243 } 24244 24245 if (!res) { 24246 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1); 24247 } 24248 24249 ao2_ref(esc_entry, -1); 24250 return res; 24251 }
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 24281 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().
24282 { 24283 struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc); 24284 int res = 0; 24285 24286 if (!esc_entry) { 24287 transmit_response(p, "412 Conditional Request Failed", req); 24288 return -1; 24289 } 24290 24291 AST_SCHED_DEL(sched, esc_entry->sched_id); 24292 /* Scheduler's ref of the esc_entry */ 24293 ao2_ref(esc_entry, -1); 24294 24295 if (esc->callbacks->remove_handler) { 24296 res = esc->callbacks->remove_handler(p, req, esc, esc_entry); 24297 } 24298 24299 if (!res) { 24300 transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1); 24301 } 24302 24303 /* Ref from finding the esc_entry earlier in function */ 24304 ao2_unlink(esc->compositor, esc_entry); 24305 ao2_ref(esc_entry, -1); 24306 return res; 24307 }
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 26606 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(), and reload_config().
26608 { 26609 int res = 1; 26610 26611 if (!strcasecmp(v->name, "t38pt_udptl")) { 26612 char *buf = ast_strdupa(v->value); 26613 char *word, *next = buf; 26614 26615 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT); 26616 26617 while ((word = strsep(&next, ","))) { 26618 if (ast_true(word) || !strcasecmp(word, "fec")) { 26619 ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT); 26620 ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_FEC); 26621 } else if (!strcasecmp(word, "redundancy")) { 26622 ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT); 26623 ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY); 26624 } else if (!strcasecmp(word, "none")) { 26625 ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT); 26626 ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL); 26627 } else if (!strncasecmp(word, "maxdatagram=", 12)) { 26628 if (sscanf(&word[12], "%30u", maxdatagram) != 1) { 26629 ast_log(LOG_WARNING, "Invalid maxdatagram '%s' at line %d of %s\n", v->value, v->lineno, config); 26630 *maxdatagram = global_t38_maxdatagram; 26631 } 26632 } 26633 } 26634 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 26635 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 26636 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 26637 } else { 26638 res = 0; 26639 } 26640 26641 return res; 26642 }
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 6176 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().
06177 { 06178 switch (cause) { 06179 case AST_CAUSE_UNALLOCATED: /* 1 */ 06180 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 06181 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 06182 return "404 Not Found"; 06183 case AST_CAUSE_CONGESTION: /* 34 */ 06184 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 06185 return "503 Service Unavailable"; 06186 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 06187 return "408 Request Timeout"; 06188 case AST_CAUSE_NO_ANSWER: /* 19 */ 06189 case AST_CAUSE_UNREGISTERED: /* 20 */ 06190 return "480 Temporarily unavailable"; 06191 case AST_CAUSE_CALL_REJECTED: /* 21 */ 06192 return "403 Forbidden"; 06193 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 06194 return "410 Gone"; 06195 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 06196 return "480 Temporarily unavailable"; 06197 case AST_CAUSE_INVALID_NUMBER_FORMAT: 06198 return "484 Address incomplete"; 06199 case AST_CAUSE_USER_BUSY: 06200 return "486 Busy here"; 06201 case AST_CAUSE_FAILURE: 06202 return "500 Server internal failure"; 06203 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 06204 return "501 Not Implemented"; 06205 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 06206 return "503 Service Unavailable"; 06207 /* Used in chan_iax2 */ 06208 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 06209 return "502 Bad Gateway"; 06210 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 06211 return "488 Not Acceptable Here"; 06212 06213 case AST_CAUSE_NOTDEFINED: 06214 default: 06215 ast_debug(1, "AST hangup cause %d (no match found in SIP)\n", cause); 06216 return NULL; 06217 } 06218 06219 /* Never reached */ 06220 return 0; 06221 }
int hangup_sip2cause | ( | int | cause | ) |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 6054 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().
06055 { 06056 /* Possible values taken from causes.h */ 06057 06058 switch(cause) { 06059 case 401: /* Unauthorized */ 06060 return AST_CAUSE_CALL_REJECTED; 06061 case 403: /* Not found */ 06062 return AST_CAUSE_CALL_REJECTED; 06063 case 404: /* Not found */ 06064 return AST_CAUSE_UNALLOCATED; 06065 case 405: /* Method not allowed */ 06066 return AST_CAUSE_INTERWORKING; 06067 case 407: /* Proxy authentication required */ 06068 return AST_CAUSE_CALL_REJECTED; 06069 case 408: /* No reaction */ 06070 return AST_CAUSE_NO_USER_RESPONSE; 06071 case 409: /* Conflict */ 06072 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 06073 case 410: /* Gone */ 06074 return AST_CAUSE_NUMBER_CHANGED; 06075 case 411: /* Length required */ 06076 return AST_CAUSE_INTERWORKING; 06077 case 413: /* Request entity too large */ 06078 return AST_CAUSE_INTERWORKING; 06079 case 414: /* Request URI too large */ 06080 return AST_CAUSE_INTERWORKING; 06081 case 415: /* Unsupported media type */ 06082 return AST_CAUSE_INTERWORKING; 06083 case 420: /* Bad extension */ 06084 return AST_CAUSE_NO_ROUTE_DESTINATION; 06085 case 480: /* No answer */ 06086 return AST_CAUSE_NO_ANSWER; 06087 case 481: /* No answer */ 06088 return AST_CAUSE_INTERWORKING; 06089 case 482: /* Loop detected */ 06090 return AST_CAUSE_INTERWORKING; 06091 case 483: /* Too many hops */ 06092 return AST_CAUSE_NO_ANSWER; 06093 case 484: /* Address incomplete */ 06094 return AST_CAUSE_INVALID_NUMBER_FORMAT; 06095 case 485: /* Ambiguous */ 06096 return AST_CAUSE_UNALLOCATED; 06097 case 486: /* Busy everywhere */ 06098 return AST_CAUSE_BUSY; 06099 case 487: /* Request terminated */ 06100 return AST_CAUSE_INTERWORKING; 06101 case 488: /* No codecs approved */ 06102 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 06103 case 491: /* Request pending */ 06104 return AST_CAUSE_INTERWORKING; 06105 case 493: /* Undecipherable */ 06106 return AST_CAUSE_INTERWORKING; 06107 case 500: /* Server internal failure */ 06108 return AST_CAUSE_FAILURE; 06109 case 501: /* Call rejected */ 06110 return AST_CAUSE_FACILITY_REJECTED; 06111 case 502: 06112 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 06113 case 503: /* Service unavailable */ 06114 return AST_CAUSE_CONGESTION; 06115 case 504: /* Gateway timeout */ 06116 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 06117 case 505: /* SIP version not supported */ 06118 return AST_CAUSE_INTERWORKING; 06119 case 600: /* Busy everywhere */ 06120 return AST_CAUSE_USER_BUSY; 06121 case 603: /* Decline */ 06122 return AST_CAUSE_CALL_REJECTED; 06123 case 604: /* Does not exist anywhere */ 06124 return AST_CAUSE_UNALLOCATED; 06125 case 606: /* Not acceptable */ 06126 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 06127 default: 06128 if (cause < 500 && cause >= 400) { 06129 /* 4xx class error that is unknown - someting wrong with our request */ 06130 return AST_CAUSE_INTERWORKING; 06131 } else if (cause < 600 && cause >= 500) { 06132 /* 5xx class error - problem in the remote end */ 06133 return AST_CAUSE_CONGESTION; 06134 } else if (cause < 700 && cause >= 600) { 06135 /* 6xx - global errors in the 4xx class */ 06136 return AST_CAUSE_INTERWORKING; 06137 } 06138 return AST_CAUSE_NORMAL; 06139 } 06140 /* Never reached */ 06141 return 0; 06142 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 10116 of file chan_sip.c.
References ast_free, ast_str_create(), ast_str_set(), sip_methods, and cfsip_methods::text.
10117 { 10118 /* Initialize a request */ 10119 memset(req, 0, sizeof(*req)); 10120 if (!(req->data = ast_str_create(SIP_MIN_PACKET))) 10121 goto e_return; 10122 if (!(req->content = ast_str_create(SIP_MIN_PACKET))) 10123 goto e_free_data; 10124 req->method = sipmethod; 10125 req->header[0] = 0; 10126 ast_str_set(&req->data, 0, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 10127 req->headers++; 10128 return 0; 10129 10130 e_free_data: 10131 ast_free(req->data); 10132 req->data = NULL; 10133 e_return: 10134 return -1; 10135 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 10094 of file chan_sip.c.
References ast_free, ast_str_create(), and ast_str_set().
10095 { 10096 /* Initialize a response */ 10097 memset(resp, 0, sizeof(*resp)); 10098 resp->method = SIP_RESPONSE; 10099 if (!(resp->data = ast_str_create(SIP_MIN_PACKET))) 10100 goto e_return; 10101 if (!(resp->content = ast_str_create(SIP_MIN_PACKET))) 10102 goto e_free_data; 10103 resp->header[0] = 0; 10104 ast_str_set(&resp->data, 0, "SIP/2.0 %s\r\n", msg); 10105 resp->headers++; 10106 return 0; 10107 10108 e_free_data: 10109 ast_free(resp->data); 10110 resp->data = NULL; 10111 e_return: 10112 return -1; 10113 }
static int initialize_escs | ( | void | ) | [static] |
Definition at line 1067 of file chan_sip.c.
References ao2_container_alloc, ARRAY_LEN, esc_cmp_fn(), esc_hash_fn(), and event_state_compositors.
Referenced by load_module().
01068 { 01069 int i, res = 0; 01070 for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { 01071 if (!((event_state_compositors[i].compositor) = 01072 ao2_container_alloc(ESC_MAX_BUCKETS, esc_hash_fn, esc_cmp_fn))) { 01073 res = -1; 01074 } 01075 } 01076 return res; 01077 }
static void initialize_initreq | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog.
Definition at line 3068 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().
03069 { 03070 if (p->initreq.headers) { 03071 ast_debug(1, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 03072 } else { 03073 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 03074 } 03075 /* Use this as the basis */ 03076 copy_request(&p->initreq, req); 03077 parse_request(&p->initreq); 03078 if (req->debug) { 03079 ast_verbose("Initreq: %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 03080 } 03081 }
static int initialize_udptl | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 6791 of file chan_sip.c.
References ast_channel_set_fd(), ast_clear_flag, ast_debug, ast_log(), AST_LOG_WARNING, ast_test_flag, ast_udptl_fd(), ast_udptl_new_with_bindaddr(), ast_udptl_setnat(), ast_udptl_setqos(), bindaddr, global_cos_audio, global_t38_maxdatagram, global_tos_audio, io, and set_t38_capabilities().
Referenced by process_sdp(), process_sdp_a_image(), and sip_indicate().
06792 { 06793 int natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP); 06794 06795 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) { 06796 return 1; 06797 } 06798 06799 /* If we've already initialized T38, don't take any further action */ 06800 if (p->udptl) { 06801 return 0; 06802 } 06803 06804 /* T38 can be supported by this dialog, create it and set the derived properties */ 06805 if ((p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &bindaddr))) { 06806 if (p->owner) { 06807 ast_channel_set_fd(p->owner, 5, ast_udptl_fd(p->udptl)); 06808 } 06809 06810 ast_udptl_setqos(p->udptl, global_tos_audio, global_cos_audio); 06811 p->t38_maxdatagram = p->relatedpeer ? p->relatedpeer->t38_maxdatagram : global_t38_maxdatagram; 06812 set_t38_capabilities(p); 06813 06814 ast_debug(1, "Setting NAT on UDPTL to %s\n", natflags ? "On" : "Off"); 06815 ast_udptl_setnat(p->udptl, natflags); 06816 } else { 06817 ast_log(AST_LOG_WARNING, "UDPTL creation failed - disabling T38 for this dialog\n"); 06818 ast_clear_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT); 06819 return 1; 06820 } 06821 06822 return 0; 06823 }
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 11902 of file chan_sip.c.
References add_header(), add_header_max_forwards(), add_route(), AST_DIGIT_ANYNUM, ast_escape_quoted(), ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_sockaddr_port, ast_sockaddr_stringify_host_remote(), ast_str_alloca, ast_str_append(), ast_str_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().
11903 { 11904 struct ast_str *invite = ast_str_alloca(256); 11905 char from[256]; 11906 char to[256]; 11907 char tmp_n[SIPBUFSIZE/2]; /* build a local copy of 'n' if needed */ 11908 char tmp_l[SIPBUFSIZE/2]; /* build a local copy of 'l' if needed */ 11909 const char *l = NULL; /* XXX what is this, exactly ? */ 11910 const char *n = NULL; /* XXX what is this, exactly ? */ 11911 const char *d = NULL; /* domain in from header */ 11912 const char *urioptions = ""; 11913 int ourport; 11914 11915 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 11916 const char *s = p->username; /* being a string field, cannot be NULL */ 11917 11918 /* Test p->username against allowed characters in AST_DIGIT_ANY 11919 If it matches the allowed characters list, then sipuser = ";user=phone" 11920 If not, then sipuser = "" 11921 */ 11922 /* + is allowed in first position in a tel: uri */ 11923 if (*s == '+') 11924 s++; 11925 for (; *s; s++) { 11926 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 11927 break; 11928 } 11929 /* If we have only digits, add ;user=phone to the uri */ 11930 if (!*s) 11931 urioptions = ";user=phone"; 11932 } 11933 11934 11935 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 11936 11937 d = S_OR(p->fromdomain, ast_sockaddr_stringify_host_remote(&p->ourip)); 11938 if (p->owner) { 11939 if ((ast_party_id_presentation(&p->owner->connected.id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) { 11940 l = p->owner->connected.id.number.valid ? p->owner->connected.id.number.str : NULL; 11941 n = p->owner->connected.id.name.valid ? p->owner->connected.id.name.str : NULL; 11942 } else { 11943 /* Even if we are using RPID, we shouldn't leak information in the From if the user wants 11944 * their callerid restricted */ 11945 l = CALLERID_UNKNOWN; 11946 n = l; 11947 d = FROMDOMAIN_INVALID; 11948 } 11949 } 11950 11951 /* Hey, it's a NOTIFY! See if they've configured a mwi_from. 11952 * XXX Right now, this logic works because the only place that mwi_from 11953 * is set on the sip_pvt is in sip_send_mwi_to_peer. If things changed, then 11954 * we might end up putting the mwi_from setting into other types of NOTIFY 11955 * messages as well. 11956 */ 11957 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->mwi_from)) { 11958 l = p->mwi_from; 11959 } 11960 11961 if (ast_strlen_zero(l)) 11962 l = default_callerid; 11963 if (ast_strlen_zero(n)) 11964 n = l; 11965 /* Allow user to be overridden */ 11966 if (!ast_strlen_zero(p->fromuser)) 11967 l = p->fromuser; 11968 else /* Save for any further attempts */ 11969 ast_string_field_set(p, fromuser, l); 11970 11971 /* Allow user to be overridden */ 11972 if (!ast_strlen_zero(p->fromname)) 11973 n = p->fromname; 11974 else /* Save for any further attempts */ 11975 ast_string_field_set(p, fromname, n); 11976 11977 if (sip_cfg.pedanticsipchecking) { 11978 ast_escape_quoted(n, tmp_n, sizeof(tmp_n)); 11979 n = tmp_n; 11980 ast_uri_encode(l, tmp_l, sizeof(tmp_l), 0); 11981 l = tmp_l; 11982 } 11983 11984 ourport = (p->fromdomainport) ? p->fromdomainport : ast_sockaddr_port(&p->ourip); 11985 if (!sip_standard_port(p->socket.type, ourport)) { 11986 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, d, ourport, p->tag); 11987 } else { 11988 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, d, p->tag); 11989 } 11990 11991 if (!ast_strlen_zero(explicit_uri)) { 11992 ast_str_set(&invite, 0, "%s", explicit_uri); 11993 } else { 11994 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 11995 if (!ast_strlen_zero(p->fullcontact)) { 11996 /* If we have full contact, trust it */ 11997 ast_str_append(&invite, 0, "%s", p->fullcontact); 11998 } else { 11999 /* Otherwise, use the username while waiting for registration */ 12000 ast_str_append(&invite, 0, "sip:"); 12001 if (!ast_strlen_zero(p->username)) { 12002 n = p->username; 12003 if (sip_cfg.pedanticsipchecking) { 12004 ast_uri_encode(n, tmp_n, sizeof(tmp_n), 0); 12005 n = tmp_n; 12006 } 12007 ast_str_append(&invite, 0, "%s@", n); 12008 } 12009 ast_str_append(&invite, 0, "%s", p->tohost); 12010 if (p->portinuri) { 12011 ast_str_append(&invite, 0, ":%d", ast_sockaddr_port(&p->sa)); 12012 } 12013 ast_str_append(&invite, 0, "%s", urioptions); 12014 } 12015 } 12016 12017 /* If custom URI options have been provided, append them */ 12018 if (p->options && !ast_strlen_zero(p->options->uri_options)) 12019 ast_str_append(&invite, 0, ";%s", p->options->uri_options); 12020 12021 /* This is the request URI, which is the next hop of the call 12022 which may or may not be the destination of the call 12023 */ 12024 ast_string_field_set(p, uri, invite->str); 12025 12026 if (!ast_strlen_zero(p->todnid)) { 12027 /*! \todo Need to add back the VXML URL here at some point, possibly use build_string for all this junk */ 12028 if (!strchr(p->todnid, '@')) { 12029 /* We have no domain in the dnid */ 12030 snprintf(to, sizeof(to), "<sip:%s@%s>%s%s", p->todnid, p->tohost, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); 12031 } else { 12032 snprintf(to, sizeof(to), "<sip:%s>%s%s", p->todnid, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); 12033 } 12034 } else { 12035 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 12036 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 12037 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "sip:" : ""), p->uri, p->theirtag); 12038 } else if (p->options && p->options->vxml_url) { 12039 /* If there is a VXML URL append it to the SIP URL */ 12040 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 12041 } else { 12042 snprintf(to, sizeof(to), "<%s>", p->uri); 12043 } 12044 } 12045 12046 init_req(req, sipmethod, p->uri); 12047 /* now tmp_n is available so reuse it to build the CSeq */ 12048 snprintf(tmp_n, sizeof(tmp_n), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 12049 12050 add_header(req, "Via", p->via); 12051 add_header_max_forwards(p, req); 12052 /* This will be a no-op most of the time. However, under certain circumstances, 12053 * NOTIFY messages will use this function for preparing the request and should 12054 * have Route headers present. 12055 */ 12056 add_route(req, p->route); 12057 12058 add_header(req, "From", from); 12059 add_header(req, "To", to); 12060 ast_string_field_set(p, exten, l); 12061 build_contact(p); 12062 add_header(req, "Contact", p->our_contact); 12063 add_header(req, "Call-ID", p->callid); 12064 add_header(req, "CSeq", tmp_n); 12065 if (!ast_strlen_zero(global_useragent)) { 12066 add_header(req, "User-Agent", global_useragent); 12067 } 12068 }
static const char * insecure2str | ( | int | mode | ) | const [static] |
Convert Insecure setting to printable string.
Definition at line 16907 of file chan_sip.c.
References insecurestr, and map_x_s().
Referenced by _sip_show_peer().
16908 { 16909 return map_x_s(insecurestr, mode, "<error>"); 16910 }
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 6699 of file chan_sip.c.
References AST_CONTROL_T38_PARAMETERS, ast_queue_control_data(), AST_SCHED_DEL_UNREF, ast_set_flag, AST_T38_NEGOTIATED, AST_T38_REFUSED, AST_T38_REQUEST_NEGOTIATE, AST_T38_REQUEST_PARMS, AST_T38_REQUEST_TERMINATE, AST_T38_TERMINATED, ast_test_flag, ast_udptl_get_far_max_ifp(), ast_udptl_set_local_max_ifp(), change_t38_state(), FALSE, ast_control_t38_parameters::fill_bit_removal, ast_control_t38_parameters::max_ifp, MIN, ast_control_t38_parameters::request_response, transmit_reinvite_with_sdp(), transmit_response_reliable(), transmit_response_with_t38_sdp(), and TRUE.
Referenced by sip_indicate().
06700 { 06701 int res = 0; 06702 06703 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) || !p->udptl) { 06704 return -1; 06705 } 06706 switch (parameters->request_response) { 06707 case AST_T38_NEGOTIATED: 06708 case AST_T38_REQUEST_NEGOTIATE: /* Request T38 */ 06709 /* Negotiation can not take place without a valid max_ifp value. */ 06710 if (!parameters->max_ifp) { 06711 change_t38_state(p, T38_DISABLED); 06712 if (p->t38.state == T38_PEER_REINVITE) { 06713 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")); 06714 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 06715 } 06716 break; 06717 } else if (p->t38.state == T38_PEER_REINVITE) { 06718 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")); 06719 p->t38.our_parms = *parameters; 06720 /* modify our parameters to conform to the peer's parameters, 06721 * based on the rules in the ITU T.38 recommendation 06722 */ 06723 if (!p->t38.their_parms.fill_bit_removal) { 06724 p->t38.our_parms.fill_bit_removal = FALSE; 06725 } 06726 if (!p->t38.their_parms.transcoding_mmr) { 06727 p->t38.our_parms.transcoding_mmr = FALSE; 06728 } 06729 if (!p->t38.their_parms.transcoding_jbig) { 06730 p->t38.our_parms.transcoding_jbig = FALSE; 06731 } 06732 p->t38.our_parms.version = MIN(p->t38.our_parms.version, p->t38.their_parms.version); 06733 p->t38.our_parms.rate_management = p->t38.their_parms.rate_management; 06734 ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp); 06735 change_t38_state(p, T38_ENABLED); 06736 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 06737 } else if (p->t38.state != T38_ENABLED) { 06738 p->t38.our_parms = *parameters; 06739 ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp); 06740 change_t38_state(p, T38_LOCAL_REINVITE); 06741 if (!p->pendinginvite) { 06742 transmit_reinvite_with_sdp(p, TRUE, FALSE); 06743 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 06744 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 06745 } 06746 } 06747 break; 06748 case AST_T38_TERMINATED: 06749 case AST_T38_REFUSED: 06750 case AST_T38_REQUEST_TERMINATE: /* Shutdown T38 */ 06751 if (p->t38.state == T38_PEER_REINVITE) { 06752 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")); 06753 change_t38_state(p, T38_DISABLED); 06754 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 06755 } else if (p->t38.state == T38_ENABLED) 06756 transmit_reinvite_with_sdp(p, FALSE, FALSE); 06757 break; 06758 case AST_T38_REQUEST_PARMS: { /* Application wants remote's parameters re-sent */ 06759 struct ast_control_t38_parameters parameters = p->t38.their_parms; 06760 06761 if (p->t38.state == T38_PEER_REINVITE) { 06762 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")); 06763 parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); 06764 parameters.request_response = AST_T38_REQUEST_NEGOTIATE; 06765 ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)); 06766 /* we need to return a positive value here, so that applications that 06767 * send this request can determine conclusively whether it was accepted or not... 06768 * older versions of chan_sip would just silently accept it and return zero. 06769 */ 06770 res = AST_T38_REQUEST_PARMS; 06771 } 06772 break; 06773 } 06774 default: 06775 res = -1; 06776 break; 06777 } 06778 06779 return res; 06780 }
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 8327 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 14151 of file chan_sip.c.
References ast_verbose.
Referenced by build_route().
14152 { 14153 if (!route) { 14154 ast_verbose("list_route: no route\n"); 14155 } else { 14156 for (;route; route = route->next) 14157 ast_verbose("list_route: hop: <%s>\n", route->hop); 14158 } 14159 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 30204 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, dialogs_to_destroy, 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_reqresp_parser_init(), 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().
30205 { 30206 ast_verbose("SIP channel loading...\n"); 30207 30208 /* the fact that ao2_containers can't resize automatically is a major worry! */ 30209 /* if the number of objects gets above MAX_XXX_BUCKETS, things will slow down */ 30210 peers = ao2_t_container_alloc(HASH_PEER_SIZE, peer_hash_cb, peer_cmp_cb, "allocate peers"); 30211 peers_by_ip = ao2_t_container_alloc(HASH_PEER_SIZE, peer_iphash_cb, peer_ipcmp_cb, "allocate peers_by_ip"); 30212 dialogs = ao2_t_container_alloc(HASH_DIALOG_SIZE, dialog_hash_cb, dialog_cmp_cb, "allocate dialogs"); 30213 dialogs_to_destroy = ao2_t_container_alloc(1, NULL, NULL, "allocate dialogs_to_destroy"); 30214 threadt = ao2_t_container_alloc(HASH_DIALOG_SIZE, threadt_hash_cb, threadt_cmp_cb, "allocate threadt table"); 30215 if (!peers || !peers_by_ip || !dialogs || !dialogs_to_destroy || !threadt) { 30216 ast_log(LOG_ERROR, "Unable to create primary SIP container(s)\n"); 30217 return AST_MODULE_LOAD_FAILURE; 30218 } 30219 30220 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list -- not searched for anything */ 30221 ASTOBJ_CONTAINER_INIT(&submwil); /* MWI subscription object list */ 30222 30223 if (!(sched = sched_context_create())) { 30224 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 30225 return AST_MODULE_LOAD_FAILURE; 30226 } 30227 30228 if (!(io = io_context_create())) { 30229 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 30230 sched_context_destroy(sched); 30231 return AST_MODULE_LOAD_FAILURE; 30232 } 30233 30234 sip_reloadreason = CHANNEL_MODULE_LOAD; 30235 30236 can_parse_xml = sip_is_xml_parsable(); 30237 if (reload_config(sip_reloadreason)) { /* Load the configuration from sip.conf */ 30238 return AST_MODULE_LOAD_DECLINE; 30239 } 30240 30241 /* Prepare the version that does not require DTMF BEGIN frames. 30242 * We need to use tricks such as memcpy and casts because the variable 30243 * has const fields. 30244 */ 30245 memcpy(&sip_tech_info, &sip_tech, sizeof(sip_tech)); 30246 memset((void *) &sip_tech_info.send_digit_begin, 0, sizeof(sip_tech_info.send_digit_begin)); 30247 30248 /* Make sure we can register our sip channel type */ 30249 if (ast_channel_register(&sip_tech)) { 30250 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 30251 io_context_destroy(io); 30252 sched_context_destroy(sched); 30253 return AST_MODULE_LOAD_FAILURE; 30254 } 30255 30256 #ifdef TEST_FRAMEWORK 30257 AST_TEST_REGISTER(test_sip_peers_get); 30258 AST_TEST_REGISTER(test_sip_mwi_subscribe_parse); 30259 #endif 30260 30261 /* Register AstData providers */ 30262 ast_data_register_multiple(sip_data_providers, ARRAY_LEN(sip_data_providers)); 30263 30264 /* Register all CLI functions for SIP */ 30265 ast_cli_register_multiple(cli_sip, ARRAY_LEN(cli_sip)); 30266 30267 /* Tell the UDPTL subdriver that we're here */ 30268 ast_udptl_proto_register(&sip_udptl); 30269 30270 /* Tell the RTP engine about our RTP glue */ 30271 ast_rtp_glue_register(&sip_rtp_glue); 30272 30273 /* Register dialplan applications */ 30274 ast_register_application_xml(app_dtmfmode, sip_dtmfmode); 30275 ast_register_application_xml(app_sipaddheader, sip_addheader); 30276 ast_register_application_xml(app_sipremoveheader, sip_removeheader); 30277 30278 /* Register dialplan functions */ 30279 ast_custom_function_register(&sip_header_function); 30280 ast_custom_function_register(&sippeer_function); 30281 ast_custom_function_register(&sipchaninfo_function); 30282 ast_custom_function_register(&checksipdomain_function); 30283 30284 /* Register manager commands */ 30285 ast_manager_register_xml("SIPpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peers); 30286 ast_manager_register_xml("SIPshowpeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peer); 30287 ast_manager_register_xml("SIPqualifypeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_qualify_peer); 30288 ast_manager_register_xml("SIPshowregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_show_registry); 30289 ast_manager_register_xml("SIPnotify", EVENT_FLAG_SYSTEM, manager_sipnotify); 30290 sip_poke_all_peers(); 30291 sip_send_all_registers(); 30292 sip_send_all_mwi_subscriptions(); 30293 initialize_escs(); 30294 30295 if (sip_epa_register(&cc_epa_static_data)) { 30296 return AST_MODULE_LOAD_DECLINE; 30297 } 30298 30299 if (sip_reqresp_parser_init() == -1) { 30300 ast_log(LOG_ERROR, "Unable to initialize the SIP request and response parser\n"); 30301 return AST_MODULE_LOAD_DECLINE; 30302 } 30303 30304 if (can_parse_xml) { 30305 /* SIP CC agents require the ability to parse XML PIDF bodies 30306 * in incoming PUBLISH requests 30307 */ 30308 if (ast_cc_agent_register(&sip_cc_agent_callbacks)) { 30309 return AST_MODULE_LOAD_DECLINE; 30310 } 30311 } 30312 if (ast_cc_monitor_register(&sip_cc_monitor_callbacks)) { 30313 return AST_MODULE_LOAD_DECLINE; 30314 } 30315 if (!(sip_monitor_instances = ao2_container_alloc(37, sip_monitor_instance_hash_fn, sip_monitor_instance_cmp_fn))) { 30316 return AST_MODULE_LOAD_DECLINE; 30317 } 30318 30319 /* And start the monitor for the first time */ 30320 restart_monitor(); 30321 30322 ast_realtime_require_field(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", 30323 "name", RQ_CHAR, 10, 30324 "ipaddr", RQ_CHAR, INET6_ADDRSTRLEN - 1, 30325 "port", RQ_UINTEGER2, 5, 30326 "regseconds", RQ_INTEGER4, 11, 30327 "defaultuser", RQ_CHAR, 10, 30328 "fullcontact", RQ_CHAR, 35, 30329 "regserver", RQ_CHAR, 20, 30330 "useragent", RQ_CHAR, 20, 30331 "lastms", RQ_INTEGER4, 11, 30332 SENTINEL); 30333 30334 30335 sip_register_tests(); 30336 network_change_event_subscribe(); 30337 30338 return AST_MODULE_LOAD_SUCCESS; 30339 }
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 23013 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().
23014 { 23015 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 23016 /* Chan 2: Call from Asterisk to target */ 23017 int res = 0; 23018 struct sip_pvt *targetcall_pvt; 23019 struct ast_party_connected_line connected_to_transferee; 23020 struct ast_party_connected_line connected_to_target; 23021 char transferer_linkedid[32]; 23022 struct ast_channel *chans[2]; 23023 23024 /* Check if the call ID of the replaces header does exist locally */ 23025 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 23026 transferer->refer->replaces_callid_fromtag))) { 23027 if (transferer->refer->localtransfer) { 23028 /* We did not find the refered call. Sorry, can't accept then */ 23029 /* Let's fake a response from someone else in order 23030 to follow the standard */ 23031 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 23032 append_history(transferer, "Xfer", "Refer failed"); 23033 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 23034 transferer->refer->status = REFER_FAILED; 23035 return -1; 23036 } 23037 /* Fall through for remote transfers that we did not find locally */ 23038 ast_debug(3, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 23039 return 0; 23040 } 23041 23042 /* Ok, we can accept this transfer */ 23043 append_history(transferer, "Xfer", "Refer accepted"); 23044 if (!targetcall_pvt->owner) { /* No active channel */ 23045 ast_debug(4, "SIP attended transfer: Error: No owner of target call\n"); 23046 /* Cancel transfer */ 23047 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 23048 append_history(transferer, "Xfer", "Refer failed"); 23049 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 23050 transferer->refer->status = REFER_FAILED; 23051 sip_pvt_unlock(targetcall_pvt); 23052 if (targetcall_pvt) 23053 ao2_t_ref(targetcall_pvt, -1, "Drop targetcall_pvt pointer"); 23054 return -1; 23055 } 23056 23057 /* We have a channel, find the bridge */ 23058 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 23059 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 23060 23061 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 23062 /* Wrong state of new channel */ 23063 if (target.chan2) 23064 ast_debug(4, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 23065 else if (target.chan1->_state != AST_STATE_RING) 23066 ast_debug(4, "SIP attended transfer: Error: No target channel\n"); 23067 else 23068 ast_debug(4, "SIP attended transfer: Attempting transfer in ringing state\n"); 23069 } 23070 23071 /* Transfer */ 23072 if (sipdebug) { 23073 if (current->chan2) /* We have two bridges */ 23074 ast_debug(4, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 23075 else /* One bridge, propably transfer of IVR/voicemail etc */ 23076 ast_debug(4, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 23077 } 23078 23079 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 23080 23081 ast_copy_string(transferer_linkedid, transferer->owner->linkedid, sizeof(transferer_linkedid)); 23082 23083 /* Perform the transfer */ 23084 chans[0] = transferer->owner; 23085 chans[1] = target.chan1; 23086 ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, 23087 "TransferMethod: SIP\r\n" 23088 "TransferType: Attended\r\n" 23089 "Channel: %s\r\n" 23090 "Uniqueid: %s\r\n" 23091 "SIP-Callid: %s\r\n" 23092 "TargetChannel: %s\r\n" 23093 "TargetUniqueid: %s\r\n", 23094 transferer->owner->name, 23095 transferer->owner->uniqueid, 23096 transferer->callid, 23097 target.chan1->name, 23098 target.chan1->uniqueid); 23099 ast_party_connected_line_init(&connected_to_transferee); 23100 ast_party_connected_line_init(&connected_to_target); 23101 /* No need to lock current->chan1 here since it was locked in sipsock_read */ 23102 ast_party_connected_line_copy(&connected_to_transferee, ¤t->chan1->connected); 23103 /* No need to lock target.chan1 here since it was locked in get_sip_pvt_byid_locked */ 23104 ast_party_connected_line_copy(&connected_to_target, &target.chan1->connected); 23105 connected_to_target.source = connected_to_transferee.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; 23106 res = attempt_transfer(current, &target); 23107 if (res) { 23108 /* Failed transfer */ 23109 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 23110 append_history(transferer, "Xfer", "Refer failed"); 23111 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 23112 /* if transfer failed, go ahead and unlock targetcall_pvt and it's owner channel */ 23113 sip_pvt_unlock(targetcall_pvt); 23114 ast_channel_unlock(target.chan1); 23115 } else { 23116 /* Transfer succeeded! */ 23117 const char *xfersound = pbx_builtin_getvar_helper(target.chan1, "ATTENDED_TRANSFER_COMPLETE_SOUND"); 23118 23119 /* target.chan1 was locked in get_sip_pvt_byid_locked, do not unlock target.chan1 before this */ 23120 ast_cel_report_event(target.chan1, AST_CEL_ATTENDEDTRANSFER, NULL, transferer_linkedid, target.chan2); 23121 23122 /* Tell transferer that we're done. */ 23123 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 23124 append_history(transferer, "Xfer", "Refer succeeded"); 23125 transferer->refer->status = REFER_200OK; 23126 if (target.chan2 && !ast_strlen_zero(xfersound) && ast_streamfile(target.chan2, xfersound, target.chan2->language) >= 0) { 23127 ast_waitstream(target.chan2, ""); 23128 } 23129 23130 /* By forcing the masquerade, we know that target.chan1 and target.chan2 are bridged. We then 23131 * can queue connected line updates where they need to go. 23132 * 23133 * before a masquerade, all channel and pvt locks must be unlocked. Any recursive 23134 * channel locks held before this function invalidates channel container locking order. 23135 * Since we are unlocking both the pvt (transferer) and its owner channel (current.chan1) 23136 * it is possible for current.chan1 to be destroyed in the pbx thread. To prevent this 23137 * we must give c a reference before any unlocking takes place. 23138 */ 23139 23140 ast_channel_ref(current->chan1); 23141 ast_channel_unlock(current->chan1); /* current.chan1 is p->owner before the masq, it was locked by socket_read()*/ 23142 ast_channel_unlock(target.chan1); 23143 *nounlock = 1; /* we just unlocked the dialog's channel and have no plans of locking it again. */ 23144 sip_pvt_unlock(targetcall_pvt); 23145 sip_pvt_unlock(transferer); 23146 23147 ast_do_masquerade(target.chan1); 23148 23149 ast_indicate(target.chan1, AST_CONTROL_UNHOLD); 23150 if (target.chan2) { 23151 ast_indicate(target.chan2, AST_CONTROL_UNHOLD); 23152 } 23153 23154 if (current->chan2 && current->chan2->_state == AST_STATE_RING) { 23155 ast_indicate(target.chan1, AST_CONTROL_RINGING); 23156 } 23157 23158 if (target.chan2) { 23159 ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL); 23160 ast_channel_queue_connected_line_update(target.chan2, &connected_to_target, NULL); 23161 } else { 23162 /* Since target.chan1 isn't actually connected to another channel, there is no way for us 23163 * to queue a frame so that its connected line status will be updated. 23164 * 23165 * Instead, we use the somewhat hackish approach of using a special control frame type that 23166 * instructs ast_read to perform a specific action. In this case, the frame we queue tells 23167 * ast_read to call the connected line interception macro configured for target.chan1. 23168 */ 23169 struct ast_control_read_action_payload *frame_payload; 23170 int payload_size; 23171 int frame_size; 23172 unsigned char connected_line_data[1024]; 23173 payload_size = ast_connected_line_build_data(connected_line_data, 23174 sizeof(connected_line_data), &connected_to_target, NULL); 23175 frame_size = payload_size + sizeof(*frame_payload); 23176 if (payload_size != -1 && (frame_payload = alloca(frame_size))) { 23177 frame_payload->payload_size = payload_size; 23178 memcpy(frame_payload->payload, connected_line_data, payload_size); 23179 frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO; 23180 ast_queue_control_data(target.chan1, AST_CONTROL_READ_ACTION, frame_payload, frame_size); 23181 } 23182 /* In addition to queueing the read action frame so that target.chan1's connected line info 23183 * will be updated, we also are going to queue a plain old connected line update on target.chan1. This 23184 * way, either Dial or Queue can apply this connected line update to the outgoing ringing channel. 23185 */ 23186 ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL); 23187 23188 } 23189 sip_pvt_lock(transferer); /* the transferer pvt is expected to remain locked on return */ 23190 23191 ast_channel_unref(current->chan1); 23192 } 23193 23194 /* at this point if the transfer is successful only the transferer pvt should be locked. */ 23195 ast_party_connected_line_free(&connected_to_target); 23196 ast_party_connected_line_free(&connected_to_transferee); 23197 if (targetcall_pvt) 23198 ao2_t_ref(targetcall_pvt, -1, "drop targetcall_pvt"); 23199 return 1; 23200 }
static void lws2sws | ( | struct ast_str * | msgbuf | ) | [static] |
Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.
Definition at line 8415 of file chan_sip.c.
References ast_str_strlen(), and len().
Referenced by handle_request_do().
08416 { 08417 char *msgbuf = data->str; 08418 int len = ast_str_strlen(data); 08419 int h = 0, t = 0; 08420 int lws = 0; 08421 08422 for (; h < len;) { 08423 /* Eliminate all CRs */ 08424 if (msgbuf[h] == '\r') { 08425 h++; 08426 continue; 08427 } 08428 /* Check for end-of-line */ 08429 if (msgbuf[h] == '\n') { 08430 /* Check for end-of-message */ 08431 if (h + 1 == len) 08432 break; 08433 /* Check for a continuation line */ 08434 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 08435 /* Merge continuation line */ 08436 h++; 08437 continue; 08438 } 08439 /* Propagate LF and start new line */ 08440 msgbuf[t++] = msgbuf[h++]; 08441 lws = 0; 08442 continue; 08443 } 08444 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 08445 if (lws) { 08446 h++; 08447 continue; 08448 } 08449 msgbuf[t++] = msgbuf[h++]; 08450 lws = 1; 08451 continue; 08452 } 08453 msgbuf[t++] = msgbuf[h++]; 08454 if (lws) 08455 lws = 0; 08456 } 08457 msgbuf[t] = '\0'; 08458 data->used = t; 08459 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 7610 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().
07611 { 07612 snprintf(tagbuf, len, "as%08lx", ast_random()); 07613 }
static int manager_show_registry | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP registrations in the manager API.
Definition at line 16543 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().
16544 { 16545 const char *id = astman_get_header(m, "ActionID"); 16546 char idtext[256] = ""; 16547 int total = 0; 16548 16549 if (!ast_strlen_zero(id)) 16550 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 16551 16552 astman_send_listack(s, m, "Registrations will follow", "start"); 16553 16554 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 16555 ASTOBJ_RDLOCK(iterator); 16556 astman_append(s, 16557 "Event: RegistryEntry\r\n" 16558 "%s" 16559 "Host: %s\r\n" 16560 "Port: %d\r\n" 16561 "Username: %s\r\n" 16562 "Domain: %s\r\n" 16563 "DomainPort: %d\r\n" 16564 "Refresh: %d\r\n" 16565 "State: %s\r\n" 16566 "RegistrationTime: %ld\r\n" 16567 "\r\n", 16568 idtext, 16569 iterator->hostname, 16570 iterator->portno ? iterator->portno : STANDARD_SIP_PORT, 16571 iterator->username, 16572 S_OR(iterator->regdomain,iterator->hostname), 16573 iterator->regdomainport ? iterator->regdomainport : STANDARD_SIP_PORT, 16574 iterator->refresh, 16575 regstate2str(iterator->regstate), 16576 (long) iterator->regtime.tv_sec); 16577 ASTOBJ_UNLOCK(iterator); 16578 total++; 16579 } while(0)); 16580 16581 astman_append(s, 16582 "Event: RegistrationsComplete\r\n" 16583 "EventList: Complete\r\n" 16584 "ListItems: %d\r\n" 16585 "%s" 16586 "\r\n", total, idtext); 16587 16588 return 0; 16589 }
static int manager_sip_qualify_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Qualify SIP peers in the manager API.
Definition at line 17302 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().
17303 { 17304 const char *a[4]; 17305 const char *peer; 17306 17307 peer = astman_get_header(m, "Peer"); 17308 if (ast_strlen_zero(peer)) { 17309 astman_send_error(s, m, "Peer: <name> missing."); 17310 return 0; 17311 } 17312 a[0] = "sip"; 17313 a[1] = "qualify"; 17314 a[2] = "peer"; 17315 a[3] = peer; 17316 17317 _sip_qualify_peer(1, -1, s, m, 4, a); 17318 astman_append(s, "\r\n\r\n" ); 17319 return 0; 17320 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 17243 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().
17244 { 17245 const char *a[4]; 17246 const char *peer; 17247 17248 peer = astman_get_header(m, "Peer"); 17249 if (ast_strlen_zero(peer)) { 17250 astman_send_error(s, m, "Peer: <name> missing."); 17251 return 0; 17252 } 17253 a[0] = "sip"; 17254 a[1] = "show"; 17255 a[2] = "peer"; 17256 a[3] = peer; 17257 17258 _sip_show_peer(1, -1, s, m, 4, a); 17259 astman_append(s, "\r\n" ); 17260 return 0; 17261 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 16593 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().
16594 { 16595 const char *id = astman_get_header(m, "ActionID"); 16596 const char *a[] = {"sip", "show", "peers"}; 16597 char idtext[256] = ""; 16598 int total = 0; 16599 16600 if (!ast_strlen_zero(id)) 16601 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 16602 16603 astman_send_listack(s, m, "Peer status list will follow", "start"); 16604 /* List the peers in separate manager events */ 16605 _sip_show_peers(-1, &total, s, m, 3, a); 16606 /* Send final confirmation */ 16607 astman_append(s, 16608 "Event: PeerlistComplete\r\n" 16609 "EventList: Complete\r\n" 16610 "ListItems: %d\r\n" 16611 "%s" 16612 "\r\n", total, idtext); 16613 return 0; 16614 }
static int manager_sipnotify | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 12879 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(), and var.
Referenced by load_module().
12880 { 12881 const char *channame = astman_get_header(m, "Channel"); 12882 struct ast_variable *vars = astman_get_variables(m); 12883 struct sip_pvt *p; 12884 struct ast_variable *header, *var; 12885 12886 if (ast_strlen_zero(channame)) { 12887 astman_send_error(s, m, "SIPNotify requires a channel name"); 12888 return 0; 12889 } 12890 12891 if (!strncasecmp(channame, "sip/", 4)) { 12892 channame += 4; 12893 } 12894 12895 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) { 12896 astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)"); 12897 return 0; 12898 } 12899 12900 if (create_addr(p, channame, NULL, 0, NULL)) { 12901 /* Maybe they're not registered, etc. */ 12902 dialog_unlink_all(p); 12903 dialog_unref(p, "unref dialog inside for loop" ); 12904 /* sip_destroy(p); */ 12905 astman_send_error(s, m, "Could not create address"); 12906 return 0; 12907 } 12908 12909 /* Notify is outgoing call */ 12910 ast_set_flag(&p->flags[0], SIP_OUTGOING); 12911 sip_notify_allocate(p); 12912 12913 p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", ""); 12914 12915 for (var = vars; var; var = var->next) { 12916 if (!strcasecmp(var->name, "Content")) { 12917 if (ast_str_strlen(p->notify->content)) 12918 ast_str_append(&p->notify->content, 0, "\r\n"); 12919 ast_str_append(&p->notify->content, 0, "%s", var->value); 12920 } else if (!strcasecmp(var->name, "Content-Length")) { 12921 ast_log(LOG_WARNING, "it is not necessary to specify Content-Length, ignoring"); 12922 } else { 12923 header->next = ast_variable_new(var->name, var->value, ""); 12924 header = header->next; 12925 } 12926 } 12927 12928 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); 12929 transmit_invite(p, SIP_NOTIFY, 0, 2, NULL); 12930 dialog_unref(p, "bump down the count of p since we're done with it."); 12931 12932 astman_send_ack(s, m, "Notify Sent"); 12933 ast_variables_destroy(vars); 12934 return 0; 12935 }
static int map_s_x | ( | const struct _map_x_s * | table, | |
const char * | s, | |||
int | errorvalue | |||
) | [static] |
map from a string to an integer value, case insensitive. If no match is found, return errorvalue.
Definition at line 2261 of file chan_sip.c.
References table.
Referenced by str2dtmfmode(), str2stmode(), and str2strefresher().
02262 { 02263 const struct _map_x_s *cur; 02264 02265 for (cur = table; cur->s; cur++) 02266 if (!strcasecmp(cur->s, s)) 02267 return cur->x; 02268 return errorvalue; 02269 }
static const char* map_x_s | ( | const struct _map_x_s * | table, | |
int | x, | |||
const char * | errorstring | |||
) | [static] |
map from an integer value to a string. If no match is found, return errorstring
Definition at line 2248 of file chan_sip.c.
References table.
Referenced by allowoverlap2str(), dtmfmode2str(), faxec2str(), insecure2str(), referstatus2str(), regstate2str(), stmode2str(), and strefresher2str().
02249 { 02250 const struct _map_x_s *cur; 02251 02252 for (cur = table; cur->s; cur++) 02253 if (cur->x == x) 02254 return cur->s; 02255 return errorstring; 02256 }
static void mark_method_allowed | ( | unsigned int * | allowed_methods, | |
enum sipmethod | method | |||
) | [static] |
Definition at line 8316 of file chan_sip.c.
Referenced by handle_response(), handle_response_info(), handle_response_message(), mark_parsed_methods(), and set_pvt_allowed_methods().
static void mark_method_unallowed | ( | unsigned int * | allowed_methods, | |
enum sipmethod | method | |||
) | [static] |
Definition at line 8321 of file chan_sip.c.
Referenced by handle_response(), handle_response_info(), handle_response_message(), and handle_response_publish().
static void mark_parsed_methods | ( | unsigned int * | methods, | |
char * | methods_str | |||
) | [static] |
Definition at line 8332 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().
08333 { 08334 char *method; 08335 for (method = strsep(&methods_str, ","); !ast_strlen_zero(method); method = strsep(&methods_str, ",")) { 08336 int id = find_sip_method(ast_skip_blanks(method)); 08337 if (id == SIP_UNKNOWN) { 08338 continue; 08339 } 08340 mark_method_allowed(methods, id); 08341 } 08342 }
static int match_and_cleanup_peer_sched | ( | void * | peerobj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2873 of file chan_sip.c.
References ast_dnsmgr_release(), CMP_MATCH, peer_sched_cleanup(), SIP_PEERS_ALL, and unref_peer().
Referenced by unlink_peers_from_tables().
02874 { 02875 struct sip_peer *peer = peerobj; 02876 peer_unlink_flag_t which = *(peer_unlink_flag_t *)arg; 02877 02878 if (which == SIP_PEERS_ALL || peer->the_mark) { 02879 peer_sched_cleanup(peer); 02880 if (peer->dnsmgr) { 02881 ast_dnsmgr_release(peer->dnsmgr); 02882 peer->dnsmgr = NULL; 02883 unref_peer(peer, "Release peer from dnsmgr"); 02884 } 02885 return CMP_MATCH; 02886 } 02887 return 0; 02888 }
static enum match_req_res match_req_to_dialog | ( | struct sip_pvt * | sip_pvt_ptr, | |
struct match_req_args * | arg | |||
) | [static] |
Definition at line 7855 of file chan_sip.c.
References ast_strlen_zero(), ast_test_flag, match_req_args::authentication_present, match_req_args::callid, match_req_args::fromtag, match_req_args::method, match_req_args::ruri, match_req_args::seqno, SIP_REQ_LOOP_DETECTED, SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, sip_uri_cmp(), match_req_args::totag, match_req_args::viabranch, and match_req_args::viasentby.
Referenced by find_call().
07856 { 07857 const char *init_ruri = NULL; 07858 if (sip_pvt_ptr->initreq.headers) { 07859 init_ruri = REQ_OFFSET_TO_STR(&sip_pvt_ptr->initreq, rlPart2); 07860 } 07861 07862 /* 07863 * Match Tags and call-id to Dialog 07864 */ 07865 if (!ast_strlen_zero(arg->callid) && strcmp(sip_pvt_ptr->callid, arg->callid)) { 07866 /* call-id does not match. */ 07867 return SIP_REQ_NOT_MATCH; 07868 } 07869 if (arg->method == SIP_RESPONSE) { 07870 /* Verify totag if we have one stored for this dialog, but never be strict about this for 07871 * a response until the dialog is established */ 07872 if (!ast_strlen_zero(sip_pvt_ptr->theirtag) && ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 07873 if (ast_strlen_zero(arg->totag)) { 07874 /* missing totag when they already gave us one earlier */ 07875 return SIP_REQ_NOT_MATCH; 07876 } 07877 if (strcmp(arg->totag, sip_pvt_ptr->theirtag)) { 07878 /* The totag of the response does not match the one we have stored */ 07879 return SIP_REQ_NOT_MATCH; 07880 } 07881 } 07882 /* Verify fromtag of response matches the tag we gave them. */ 07883 if (strcmp(arg->fromtag, sip_pvt_ptr->tag)) { 07884 /* fromtag from response does not match our tag */ 07885 return SIP_REQ_NOT_MATCH; 07886 } 07887 } else { 07888 /* Verify the fromtag of Request matches the tag they provided earlier. 07889 * If this is a Request with authentication credentials, forget their old 07890 * tag as it is not valid after the 401 or 407 response. */ 07891 if (!arg->authentication_present && strcmp(arg->fromtag, sip_pvt_ptr->theirtag)) { 07892 /* their tag does not match the one was have stored for them */ 07893 return SIP_REQ_NOT_MATCH; 07894 } 07895 /* Verify if totag is present in Request, that it matches what we gave them as our tag earlier */ 07896 if (!ast_strlen_zero(arg->totag) && (strcmp(arg->totag, sip_pvt_ptr->tag))) { 07897 /* totag from Request does not match our tag */ 07898 return SIP_REQ_NOT_MATCH; 07899 } 07900 } 07901 07902 /* 07903 * Compare incoming request against initial transaction. 07904 * 07905 * This is a best effort attempt at distinguishing forked requests from 07906 * our initial transaction. If all the elements are NOT in place to evaluate 07907 * this, this block is ignored and the dialog match is made regardless. 07908 * Once the totag is established after the dialog is confirmed, this is not necessary. 07909 * 07910 * CRITERIA required for initial transaction matching. 07911 * 07912 * 1. Is a Request 07913 * 2. Callid and theirtag match (this is done in the dialog matching block) 07914 * 3. totag is NOT present 07915 * 4. CSeq matchs our initial transaction's cseq number 07916 * 5. pvt has init via branch parameter stored 07917 */ 07918 if ((arg->method != SIP_RESPONSE) && /* must be a Request */ 07919 ast_strlen_zero(arg->totag) && /* must not have a totag */ 07920 (sip_pvt_ptr->init_icseq == arg->seqno) && /* the cseq must be the same as this dialogs initial cseq */ 07921 !ast_strlen_zero(sip_pvt_ptr->initviabranch) && /* The dialog must have started with a RFC3261 compliant branch tag */ 07922 init_ruri) { /* the dialog must have an initial request uri associated with it */ 07923 /* This Request matches all the criteria required for Loop/Merge detection. 07924 * Now we must go down the path of comparing VIA's and RURIs. */ 07925 if (ast_strlen_zero(arg->viabranch) || 07926 strcmp(arg->viabranch, sip_pvt_ptr->initviabranch) || 07927 ast_strlen_zero(arg->viasentby) || 07928 strcmp(arg->viasentby, sip_pvt_ptr->initviasentby)) { 07929 /* At this point, this request does not match this Dialog.*/ 07930 07931 /* if methods are different this is just a mismatch */ 07932 if ((sip_pvt_ptr->method != arg->method)) { 07933 return SIP_REQ_NOT_MATCH; 07934 } 07935 07936 /* If RUIs are different, this is a forked request to a separate URI. 07937 * Returning a mismatch allows this Request to be processed separately. */ 07938 if (sip_uri_cmp(init_ruri, arg->ruri)) { 07939 /* not a match, request uris are different */ 07940 return SIP_REQ_NOT_MATCH; 07941 } 07942 07943 /* Loop/Merge Detected 07944 * 07945 * ---Current Matches to Initial Request--- 07946 * request uri 07947 * Call-id 07948 * their-tag 07949 * no totag present 07950 * method 07951 * cseq 07952 * 07953 * --- Does not Match Initial Request --- 07954 * Top Via 07955 * 07956 * Without the same Via, this can not match our initial transaction for this dialog, 07957 * but given that this Request matches everything else associated with that initial 07958 * Request this is most certainly a Forked request in which we have already received 07959 * part of the fork. 07960 */ 07961 return SIP_REQ_LOOP_DETECTED; 07962 } 07963 } /* end of Request Via check */ 07964 07965 /* Match Authentication Request. 07966 * 07967 * A Request with an Authentication header must come back with the 07968 * same Request URI. Otherwise it is not a match. 07969 */ 07970 if ((arg->method != SIP_RESPONSE) && /* Must be a Request type to even begin checking this */ 07971 ast_strlen_zero(arg->totag) && /* no totag is present to match */ 07972 arg->authentication_present && /* Authentication header is present in Request */ 07973 sip_uri_cmp(init_ruri, arg->ruri)) { /* Compare the Request URI of both the last Request and this new one */ 07974 07975 /* Authentication was provided, but the Request URI did not match the last one on this dialog. */ 07976 return SIP_REQ_NOT_MATCH; 07977 } 07978 07979 return SIP_REQ_MATCH; 07980 }
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 3155 of file chan_sip.c.
References len(), sip_methods, and text.
Referenced by __sip_autodestruct(), __sip_semi_ack(), and find_sip_method().
03156 { 03157 int len = strlen(sip_methods[id].text); 03158 int l_name = name ? strlen(name) : 0; 03159 /* true if the string is long enough, and ends with whitespace, and matches */ 03160 return (l_name >= len && name[len] < 33 && 03161 !strncasecmp(sip_methods[id].text, name, len)); 03162 }
static void mwi_event_cb | ( | const struct ast_event * | , | |
void * | ||||
) | [static] |
Receive MWI events that we have subscribed to.
Definition at line 14493 of file chan_sip.c.
References sip_send_mwi_to_peer().
14494 { 14495 struct sip_peer *peer = userdata; 14496 14497 sip_send_mwi_to_peer(peer, 0); 14498 }
static void network_change_event_cb | ( | const struct ast_event * | , | |
void * | ||||
) | [static] |
Definition at line 14523 of file chan_sip.c.
References ast_debug, ast_sched_add(), network_change_event_sched_cb(), and network_change_event_sched_id.
14524 { 14525 ast_debug(1, "SIP, got a network change event, renewing all SIP registrations.\n"); 14526 if (network_change_event_sched_id == -1) { 14527 network_change_event_sched_id = ast_sched_add(sched, 1000, network_change_event_sched_cb, NULL); 14528 } 14529 }
static int network_change_event_sched_cb | ( | const void * | data | ) | [static] |
Definition at line 14515 of file chan_sip.c.
References network_change_event_sched_id, sip_send_all_mwi_subscriptions(), and sip_send_all_registers().
14516 { 14517 network_change_event_sched_id = -1; 14518 sip_send_all_registers(); 14519 sip_send_all_mwi_subscriptions(); 14520 return 0; 14521 }
static void network_change_event_subscribe | ( | void | ) | [static] |
Definition at line 14500 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.
14501 { 14502 if (!network_change_event_subscription) { 14503 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE, 14504 network_change_event_cb, "SIP Network Change", NULL, AST_EVENT_IE_END); 14505 } 14506 }
static void network_change_event_unsubscribe | ( | void | ) | [static] |
Definition at line 14508 of file chan_sip.c.
References ast_event_unsubscribe(), and network_change_event_subscription.
14509 { 14510 if (network_change_event_subscription) { 14511 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription); 14512 } 14513 }
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 3127 of file chan_sip.c.
References append_history, ast_debug, sip_cfg, and sipdebug.
Referenced by __sip_subscribe_mwi_do(), create_addr(), create_addr_from_peer(), and transmit_register().
03128 { 03129 if (peer && peer->outboundproxy) { 03130 if (sipdebug) { 03131 ast_debug(1, "OBPROXY: Applying peer OBproxy to this call\n"); 03132 } 03133 append_history(dialog, "OBproxy", "Using peer obproxy %s", peer->outboundproxy->name); 03134 return peer->outboundproxy; 03135 } 03136 if (sip_cfg.outboundproxy.name[0]) { 03137 if (sipdebug) { 03138 ast_debug(1, "OBPROXY: Applying global OBproxy to this call\n"); 03139 } 03140 append_history(dialog, "OBproxy", "Using global obproxy %s", sip_cfg.outboundproxy.name); 03141 return &sip_cfg.outboundproxy; 03142 } 03143 if (sipdebug) { 03144 ast_debug(1, "OBPROXY: Not applying OBproxy to this call\n"); 03145 } 03146 return NULL; 03147 }
static void on_dns_update_mwi | ( | struct ast_sockaddr * | old, | |
struct ast_sockaddr * | new, | |||
void * | data | |||
) | [static] |
Definition at line 12388 of file chan_sip.c.
References ast_debug, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), and ast_strdupa.
Referenced by __sip_subscribe_mwi_do().
12389 { 12390 struct sip_subscription_mwi *mwi = data; 12391 const char *old_str; 12392 12393 /* This shouldn't happen, but just in case */ 12394 if (ast_sockaddr_isnull(new)) { 12395 ast_debug(1, "Empty sockaddr change...ignoring!\n"); 12396 return; 12397 } 12398 12399 old_str = ast_strdupa(ast_sockaddr_stringify(old)); 12400 ast_debug(1, "Changing mwi %s from %s to %s\n", mwi->hostname, old_str, ast_sockaddr_stringify(new)); 12401 ast_sockaddr_copy(&mwi->us, new); 12402 }
static void on_dns_update_peer | ( | struct ast_sockaddr * | old, | |
struct ast_sockaddr * | new, | |||
void * | data | |||
) | [static] |
Definition at line 12359 of file chan_sip.c.
References ao2_link, ao2_lock, ao2_unlink, ao2_unlock, ast_debug, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_strdupa, default_sip_port(), and peers_by_ip.
Referenced by build_peer(), and transmit_register().
12360 { 12361 struct sip_peer *peer = data; 12362 const char *old_str; 12363 12364 /* This shouldn't happen, but just in case */ 12365 if (ast_sockaddr_isnull(new)) { 12366 ast_debug(1, "Empty sockaddr change...ignoring!\n"); 12367 return; 12368 } 12369 12370 if (!ast_sockaddr_isnull(&peer->addr)) { 12371 ao2_unlink(peers_by_ip, peer); 12372 } 12373 12374 if (!ast_sockaddr_port(new)) { 12375 ast_sockaddr_set_port(new, default_sip_port(peer->socket.type)); 12376 } 12377 12378 old_str = ast_strdupa(ast_sockaddr_stringify(old)); 12379 ast_debug(1, "Changing peer %s address from %s to %s\n", peer->name, old_str, ast_sockaddr_stringify(new)); 12380 12381 ao2_lock(peer); 12382 ast_sockaddr_copy(&peer->addr, new); 12383 ao2_unlock(peer); 12384 12385 ao2_link(peers_by_ip, peer); 12386 }
static void on_dns_update_registry | ( | struct ast_sockaddr * | old, | |
struct ast_sockaddr * | new, | |||
void * | data | |||
) | [static] |
Definition at line 12338 of file chan_sip.c.
References ast_debug, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_strdupa, and S_OR.
Referenced by transmit_register().
12339 { 12340 struct sip_registry *reg = data; 12341 const char *old_str; 12342 12343 /* This shouldn't happen, but just in case */ 12344 if (ast_sockaddr_isnull(new)) { 12345 ast_debug(1, "Empty sockaddr change...ignoring!\n"); 12346 return; 12347 } 12348 12349 if (!ast_sockaddr_port(new)) { 12350 ast_sockaddr_set_port(new, reg->portno); 12351 } 12352 12353 old_str = ast_strdupa(ast_sockaddr_stringify(old)); 12354 12355 ast_debug(1, "Changing registry %s from %s to %s\n", S_OR(reg->peername, reg->hostname), old_str, ast_sockaddr_stringify(new)); 12356 ast_sockaddr_copy(®->us, new); 12357 }
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 8359 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().
08360 { 08361 char *allow = ast_strdupa(get_header(req, "Allow")); 08362 unsigned int allowed_methods = SIP_UNKNOWN; 08363 08364 if (ast_strlen_zero(allow)) { 08365 /* I have witnessed that REGISTER requests from Polycom phones do not 08366 * place the phone's allowed methods in an Allow header. Instead, they place the 08367 * allowed methods in a methods= parameter in the Contact header. 08368 */ 08369 char *contact = ast_strdupa(get_header(req, "Contact")); 08370 char *methods = strstr(contact, ";methods="); 08371 08372 if (ast_strlen_zero(methods)) { 08373 /* RFC 3261 states: 08374 * 08375 * "The absence of an Allow header field MUST NOT be 08376 * interpreted to mean that the UA sending the message supports no 08377 * methods. Rather, it implies that the UA is not providing any 08378 * information on what methods it supports." 08379 * 08380 * For simplicity, we'll assume that the peer allows all known 08381 * SIP methods if they have no Allow header. We can then clear out the necessary 08382 * bits if the peer lets us know that we have sent an unsupported method. 08383 */ 08384 return UINT_MAX; 08385 } 08386 allow = ast_strip_quoted(methods + 9, "\"", "\""); 08387 } 08388 mark_parsed_methods(&allowed_methods, allow); 08389 return allowed_methods; 08390 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 4076 of file chan_sip.c.
References copy_request(), and parse_request().
Referenced by send_request(), and send_response().
04077 { 04078 copy_request(dst, src); 04079 parse_request(dst); 04080 }
int parse_minse | ( | const char * | p_hdrval, | |
int *const | p_interval | |||
) | [static] |
Session-Timers: Function for parsing Min-SE header.
Definition at line 25961 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().
25962 { 25963 if (ast_strlen_zero(p_hdrval)) { 25964 ast_log(LOG_WARNING, "Null Min-SE header\n"); 25965 return -1; 25966 } 25967 25968 *p_interval = 0; 25969 p_hdrval = ast_skip_blanks(p_hdrval); 25970 if (!sscanf(p_hdrval, "%30d", p_interval)) { 25971 ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval); 25972 return -1; 25973 } 25974 25975 ast_debug(2, "Received Min-SE: %d\n", *p_interval); 25976 return 0; 25977 }
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 19615 of file chan_sip.c.
References ao2_ref, ast_copy_string(), ast_debug, ast_log(), ast_strdup, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), find_closing_quote(), get_header(), get_in_brackets(), get_transport(), LOG_NOTICE, pbx_builtin_setvar_helper(), remove_uri_parameters(), set_socket_transport(), and strcasestr().
Referenced by change_redirecting_information().
19616 { 19617 char contact[SIPBUFSIZE]; 19618 char *contact_name = NULL; 19619 char *contact_number = NULL; 19620 char *separator, *trans; 19621 char *domain; 19622 enum sip_transport transport = SIP_TRANSPORT_UDP; 19623 19624 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 19625 if ((separator = strchr(contact, ','))) 19626 *separator = '\0'; 19627 19628 contact_number = get_in_brackets(contact); 19629 if ((trans = strcasestr(contact_number, ";transport="))) { 19630 trans += 11; 19631 19632 if ((separator = strchr(trans, ';'))) 19633 *separator = '\0'; 19634 19635 if (!strncasecmp(trans, "tcp", 3)) 19636 transport = SIP_TRANSPORT_TCP; 19637 else if (!strncasecmp(trans, "tls", 3)) 19638 transport = SIP_TRANSPORT_TLS; 19639 else { 19640 if (strncasecmp(trans, "udp", 3)) 19641 ast_debug(1, "received contact with an invalid transport, '%s'\n", contact_number); 19642 /* This will assume UDP for all unknown transports */ 19643 transport = SIP_TRANSPORT_UDP; 19644 } 19645 } 19646 contact_number = remove_uri_parameters(contact_number); 19647 19648 if (p->socket.tcptls_session) { 19649 ao2_ref(p->socket.tcptls_session, -1); 19650 p->socket.tcptls_session = NULL; 19651 } 19652 19653 set_socket_transport(&p->socket, transport); 19654 19655 if (set_call_forward && ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 19656 char *host = NULL; 19657 if (!strncasecmp(contact_number, "sip:", 4)) 19658 contact_number += 4; 19659 else if (!strncasecmp(contact_number, "sips:", 5)) 19660 contact_number += 5; 19661 separator = strchr(contact_number, '/'); 19662 if (separator) 19663 *separator = '\0'; 19664 if ((host = strchr(contact_number, '@'))) { 19665 *host++ = '\0'; 19666 ast_debug(2, "Found promiscuous redirection to 'SIP/%s::::%s@%s'\n", contact_number, get_transport(transport), host); 19667 if (p->owner) 19668 ast_string_field_build(p->owner, call_forward, "SIP/%s::::%s@%s", contact_number, get_transport(transport), host); 19669 } else { 19670 ast_debug(2, "Found promiscuous redirection to 'SIP/::::%s@%s'\n", get_transport(transport), contact_number); 19671 if (p->owner) 19672 ast_string_field_build(p->owner, call_forward, "SIP/::::%s@%s", get_transport(transport), contact_number); 19673 } 19674 } else { 19675 separator = strchr(contact, '@'); 19676 if (separator) { 19677 *separator++ = '\0'; 19678 domain = separator; 19679 } else { 19680 /* No username part */ 19681 domain = contact; 19682 } 19683 separator = strchr(contact, '/'); /* WHEN do we hae a forward slash in the URI? */ 19684 if (separator) 19685 *separator = '\0'; 19686 19687 if (!strncasecmp(contact_number, "sip:", 4)) 19688 contact_number += 4; 19689 else if (!strncasecmp(contact_number, "sips:", 5)) 19690 contact_number += 5; 19691 separator = strchr(contact_number, ';'); /* And username ; parameters? */ 19692 if (separator) 19693 *separator = '\0'; 19694 ast_uri_decode(contact_number); 19695 if (set_call_forward) { 19696 ast_debug(2, "Received 302 Redirect to extension '%s' (domain %s)\n", contact_number, domain); 19697 if (p->owner) { 19698 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 19699 ast_string_field_set(p->owner, call_forward, contact_number); 19700 } 19701 } 19702 } 19703 19704 /* We've gotten the number for the contact, now get the name */ 19705 19706 if (*contact == '\"') { 19707 contact_name = contact + 1; 19708 if (!(separator = (char *)find_closing_quote(contact_name, NULL))) { 19709 ast_log(LOG_NOTICE, "No closing quote on name in Contact header? %s\n", contact); 19710 } 19711 *separator = '\0'; 19712 } 19713 19714 if (name && !ast_strlen_zero(contact_name)) { 19715 *name = ast_strdup(contact_name); 19716 } 19717 if (number) { 19718 *number = ast_strdup(contact_number); 19719 } 19720 }
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 13823 of file chan_sip.c.
References ast_copy_string(), ast_string_field_set, get_header(), get_in_brackets(), and TRUE.
Referenced by handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
13824 { 13825 char contact[SIPBUFSIZE]; 13826 char *c; 13827 13828 /* Look for brackets */ 13829 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 13830 c = get_in_brackets(contact); 13831 13832 /* Save full contact to call pvt for later bye or re-invite */ 13833 ast_string_field_set(pvt, fullcontact, c); 13834 13835 /* Save URI for later ACKs, BYE or RE-invites */ 13836 ast_string_field_set(pvt, okcontacturi, c); 13837 13838 /* We should return false for URI:s we can't handle, 13839 like tel:, mailto:,ldap: etc */ 13840 return TRUE; 13841 }
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 13930 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, default_sip_port(), EVENT_FLAG_SYSTEM, expire_register(), FALSE, get_header(), get_in_brackets(), get_transport_str2enum(), global_flags, LOG_NOTICE, LOG_WARNING, manager_event, max_expiry, min_expiry, parse_uri_legacy_check(), 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().
13931 { 13932 char contact[SIPBUFSIZE]; 13933 char data[SIPBUFSIZE]; 13934 const char *expires = get_header(req, "Expires"); 13935 int expire = atoi(expires); 13936 char *curi = NULL, *hostport = NULL, *transport = NULL; 13937 int transport_type; 13938 const char *useragent; 13939 struct ast_sockaddr oldsin, testsa; 13940 char *firstcuri = NULL; 13941 int start = 0; 13942 int wildcard_found = 0; 13943 int single_binding_found = 0; 13944 13945 ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact)); 13946 13947 if (ast_strlen_zero(expires)) { /* No expires header, try look in Contact: */ 13948 char *s = strcasestr(contact, ";expires="); 13949 if (s) { 13950 expires = strsep(&s, ";"); /* trim ; and beyond */ 13951 if (sscanf(expires + 9, "%30d", &expire) != 1) { 13952 expire = default_expiry; 13953 } 13954 } else { 13955 /* Nothing has been specified */ 13956 expire = default_expiry; 13957 } 13958 } 13959 13960 copy_socket_data(&pvt->socket, &req->socket); 13961 13962 do { 13963 /* Look for brackets */ 13964 curi = contact; 13965 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 13966 strsep(&curi, ";"); /* This is Header options, not URI options */ 13967 curi = get_in_brackets(contact); 13968 if (!firstcuri) { 13969 firstcuri = ast_strdupa(curi); 13970 } 13971 13972 if (!strcasecmp(curi, "*")) { 13973 wildcard_found = 1; 13974 } else { 13975 single_binding_found = 1; 13976 } 13977 13978 if (wildcard_found && (ast_strlen_zero(expires) || expire != 0 || single_binding_found)) { 13979 /* Contact header parameter "*" detected, so punt if: Expires header is missing, 13980 * Expires value is not zero, or another Contact header is present. */ 13981 return PARSE_REGISTER_FAILED; 13982 } 13983 13984 ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact)); 13985 } while (!ast_strlen_zero(contact)); 13986 curi = firstcuri; 13987 13988 /* if they did not specify Contact: or Expires:, they are querying 13989 what we currently have stored as their contact address, so return 13990 it 13991 */ 13992 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 13993 /* If we have an active registration, tell them when the registration is going to expire */ 13994 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) { 13995 pvt->expiry = ast_sched_when(sched, peer->expire); 13996 } 13997 return PARSE_REGISTER_QUERY; 13998 } else if (!strcasecmp(curi, "*") || !expire) { /* Unregister this peer */ 13999 /* This means remove all registrations and return OK */ 14000 AST_SCHED_DEL_UNREF(sched, peer->expire, 14001 unref_peer(peer, "remove register expire ref")); 14002 ast_verb(3, "Unregistered SIP '%s'\n", peer->name); 14003 expire_register(ref_peer(peer,"add ref for explicit expire_register")); 14004 return PARSE_REGISTER_UPDATE; 14005 } 14006 14007 /* Store whatever we got as a contact from the client */ 14008 ast_string_field_set(peer, fullcontact, curi); 14009 14010 /* For the 200 OK, we should use the received contact */ 14011 ast_string_field_build(pvt, our_contact, "<%s>", curi); 14012 14013 /* Make sure it's a SIP URL */ 14014 if (ast_strlen_zero(curi) || parse_uri_legacy_check(curi, "sip:,sips:", &curi, NULL, &hostport, &transport)) { 14015 ast_log(LOG_NOTICE, "Not a valid SIP contact (missing sip:/sips:) trying to use anyway\n"); 14016 } 14017 14018 /* handle the transport type specified in Contact header. */ 14019 if (!(transport_type = get_transport_str2enum(transport))) { 14020 transport_type = pvt->socket.type; 14021 } 14022 14023 /* if the peer's socket type is different than the Registration 14024 * transport type, change it. If it got this far, it is a 14025 * supported type, but check just in case */ 14026 if ((peer->socket.type != transport_type) && (peer->transports & transport_type)) { 14027 set_socket_transport(&peer->socket, transport_type); 14028 } 14029 14030 oldsin = peer->addr; 14031 14032 /* If we were already linked into the peers_by_ip container unlink ourselves so nobody can find us */ 14033 if (!ast_sockaddr_isnull(&peer->addr) && (!peer->is_realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))) { 14034 ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); 14035 } 14036 14037 if (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) && !ast_test_flag(&peer->flags[0], SIP_NAT_RPORT_PRESENT)) { 14038 /* use the data provided in the Contact header for call routing */ 14039 ast_debug(1, "Store REGISTER's Contact header for call routing.\n"); 14040 /* XXX This could block for a long time XXX */ 14041 /*! \todo Check NAPTR/SRV if we have not got a port in the URI */ 14042 if (ast_sockaddr_resolve_first(&testsa, hostport, 0)) { 14043 ast_log(LOG_WARNING, "Invalid hostport '%s'\n", hostport); 14044 ast_string_field_set(peer, fullcontact, ""); 14045 ast_string_field_set(pvt, our_contact, ""); 14046 return PARSE_REGISTER_FAILED; 14047 } 14048 14049 /* If we have a port number in the given URI, make sure we do remember to not check for NAPTR/SRV records. 14050 The hostport part is actually a host. */ 14051 peer->portinuri = ast_sockaddr_port(&testsa) ? TRUE : FALSE; 14052 14053 if (!ast_sockaddr_port(&testsa)) { 14054 ast_sockaddr_set_port(&testsa, default_sip_port(transport_type)); 14055 } 14056 14057 ast_sockaddr_copy(&peer->addr, &testsa); 14058 } else { 14059 /* Don't trust the contact field. Just use what they came to us 14060 with */ 14061 ast_debug(1, "Store REGISTER's src-IP:port for call routing.\n"); 14062 peer->addr = pvt->recv; 14063 } 14064 14065 /* Check that they're allowed to register at this IP */ 14066 if (ast_apply_ha(sip_cfg.contact_ha, &peer->addr) != AST_SENSE_ALLOW || 14067 ast_apply_ha(peer->contactha, &peer->addr) != AST_SENSE_ALLOW) { 14068 ast_log(LOG_WARNING, "Domain '%s' disallowed by contact ACL (violating IP %s)\n", hostport, 14069 ast_sockaddr_stringify_addr(&testsa)); 14070 ast_string_field_set(peer, fullcontact, ""); 14071 ast_string_field_set(pvt, our_contact, ""); 14072 return PARSE_REGISTER_DENIED; 14073 } 14074 14075 /* if the Contact header information copied into peer->addr matches the 14076 * received address, and the transport types are the same, then copy socket 14077 * data into the peer struct */ 14078 if ((peer->socket.type == pvt->socket.type) && 14079 !ast_sockaddr_cmp(&peer->addr, &pvt->recv)) { 14080 copy_socket_data(&peer->socket, &pvt->socket); 14081 } 14082 14083 /* Now that our address has been updated put ourselves back into the container for lookups */ 14084 if (!peer->is_realtime || ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 14085 ao2_t_link(peers_by_ip, peer, "ao2_link into peers_by_ip table"); 14086 } 14087 14088 /* Save SIP options profile */ 14089 peer->sipoptions = pvt->sipoptions; 14090 14091 if (!ast_strlen_zero(curi) && ast_strlen_zero(peer->username)) { 14092 ast_string_field_set(peer, username, curi); 14093 } 14094 14095 AST_SCHED_DEL_UNREF(sched, peer->expire, 14096 unref_peer(peer, "remove register expire ref")); 14097 14098 if (expire > max_expiry) { 14099 expire = max_expiry; 14100 } 14101 if (expire < min_expiry) { 14102 expire = min_expiry; 14103 } 14104 if (peer->is_realtime && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 14105 peer->expire = -1; 14106 } else { 14107 peer->expire = ast_sched_add(sched, (expire + 10) * 1000, expire_register, 14108 ref_peer(peer, "add registration ref")); 14109 if (peer->expire == -1) { 14110 unref_peer(peer, "remote registration ref"); 14111 } 14112 } 14113 pvt->expiry = expire; 14114 snprintf(data, sizeof(data), "%s:%d:%s:%s", ast_sockaddr_stringify(&peer->addr), 14115 expire, peer->username, peer->fullcontact); 14116 /* We might not immediately be able to reconnect via TCP, but try caching it anyhow */ 14117 if (!peer->rt_fromcontact || !sip_cfg.peer_rtupdate) 14118 ast_db_put("SIP/Registry", peer->name, data); 14119 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)); 14120 14121 /* Is this a new IP address for us? */ 14122 if (VERBOSITY_ATLEAST(2) && ast_sockaddr_cmp(&peer->addr, &oldsin)) { 14123 ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s\n", peer->name, 14124 ast_sockaddr_stringify(&peer->addr)); 14125 } 14126 sip_poke_peer(peer, 0); 14127 register_peer_exten(peer, 1); 14128 14129 /* Save User agent */ 14130 useragent = get_header(req, "User-Agent"); 14131 if (strcasecmp(useragent, peer->useragent)) { 14132 ast_string_field_set(peer, useragent, useragent); 14133 ast_verb(4, "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 14134 } 14135 return PARSE_REGISTER_UPDATE; 14136 }
static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 8464 of file chan_sip.c.
References ast_debug, ast_strlen_zero(), and sipdebug.
Referenced by handle_request_do(), initialize_initreq(), and parse_copy().
08465 { 08466 char *c = req->data->str; 08467 ptrdiff_t *dst = req->header; 08468 int i = 0, lim = SIP_MAX_HEADERS - 1; 08469 unsigned int skipping_headers = 0; 08470 ptrdiff_t current_header_offset = 0; 08471 char *previous_header = ""; 08472 08473 req->header[0] = 0; 08474 req->headers = -1; /* mark that we are working on the header */ 08475 for (; *c; c++) { 08476 if (*c == '\r') { /* remove \r */ 08477 *c = '\0'; 08478 } else if (*c == '\n') { /* end of this line */ 08479 *c = '\0'; 08480 current_header_offset = (c + 1) - req->data->str; 08481 previous_header = req->data->str + dst[i]; 08482 if (skipping_headers) { 08483 /* check to see if this line is blank; if so, turn off 08484 the skipping flag, so the next line will be processed 08485 as a body line */ 08486 if (ast_strlen_zero(previous_header)) { 08487 skipping_headers = 0; 08488 } 08489 dst[i] = current_header_offset; /* record start of next line */ 08490 continue; 08491 } 08492 if (sipdebug) { 08493 ast_debug(4, "%7s %2d [%3d]: %s\n", 08494 req->headers < 0 ? "Header" : "Body", 08495 i, (int) strlen(previous_header), previous_header); 08496 } 08497 if (ast_strlen_zero(previous_header) && req->headers < 0) { 08498 req->headers = i; /* record number of header lines */ 08499 dst = req->line; /* start working on the body */ 08500 i = 0; 08501 lim = SIP_MAX_LINES - 1; 08502 } else { /* move to next line, check for overflows */ 08503 if (i++ == lim) { 08504 /* if we're processing headers, then skip any remaining 08505 headers and move on to processing the body, otherwise 08506 we're done */ 08507 if (req->headers != -1) { 08508 break; 08509 } else { 08510 req->headers = i; 08511 dst = req->line; 08512 i = 0; 08513 lim = SIP_MAX_LINES - 1; 08514 skipping_headers = 1; 08515 } 08516 } 08517 } 08518 dst[i] = current_header_offset; /* record start of next line */ 08519 } 08520 } 08521 08522 /* Check for last header or body line without CRLF. The RFC for SDP requires CRLF, 08523 but since some devices send without, we'll be generous in what we accept. However, 08524 if we've already reached the maximum number of lines for portion of the message 08525 we were parsing, we can't accept any more, so just ignore it. 08526 */ 08527 previous_header = req->data->str + dst[i]; 08528 if ((i < lim) && !ast_strlen_zero(previous_header)) { 08529 if (sipdebug) { 08530 ast_debug(4, "%7s %2d [%3d]: %s\n", 08531 req->headers < 0 ? "Header" : "Body", 08532 i, (int) strlen(previous_header), previous_header ); 08533 } 08534 i++; 08535 } 08536 08537 /* update count of header or body lines */ 08538 if (req->headers >= 0) { /* we are in the body */ 08539 req->lines = i; 08540 } else { /* no body */ 08541 req->headers = i; 08542 req->lines = 0; 08543 /* req->data->used will be a NULL byte */ 08544 req->line[0] = ast_str_strlen(req->data); 08545 } 08546 08547 if (*c) { 08548 ast_log(LOG_WARNING, "Too many lines, skipping <%s>\n", c); 08549 } 08550 08551 /* Split up the first line parts */ 08552 return determine_firstline_parts(req); 08553 }
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 25981 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().
25982 { 25983 char *p_token; 25984 int ref_idx; 25985 char *p_se_hdr; 25986 25987 if (ast_strlen_zero(p_hdrval)) { 25988 ast_log(LOG_WARNING, "Null Session-Expires header\n"); 25989 return -1; 25990 } 25991 25992 *p_ref = SESSION_TIMER_REFRESHER_AUTO; 25993 *p_interval = 0; 25994 25995 p_se_hdr = ast_strdupa(p_hdrval); 25996 p_se_hdr = ast_skip_blanks(p_se_hdr); 25997 25998 while ((p_token = strsep(&p_se_hdr, ";"))) { 25999 p_token = ast_skip_blanks(p_token); 26000 if (!sscanf(p_token, "%30d", p_interval)) { 26001 ast_log(LOG_WARNING, "Parsing of Session-Expires failed\n"); 26002 return -1; 26003 } 26004 26005 ast_debug(2, "Session-Expires: %d\n", *p_interval); 26006 26007 if (!p_se_hdr) 26008 continue; 26009 26010 p_se_hdr = ast_skip_blanks(p_se_hdr); 26011 ref_idx = strlen("refresher="); 26012 if (!strncasecmp(p_se_hdr, "refresher=", ref_idx)) { 26013 p_se_hdr += ref_idx; 26014 p_se_hdr = ast_skip_blanks(p_se_hdr); 26015 26016 if (!strncasecmp(p_se_hdr, "uac", strlen("uac"))) { 26017 *p_ref = SESSION_TIMER_REFRESHER_UAC; 26018 ast_debug(2, "Refresher: UAC\n"); 26019 } else if (!strncasecmp(p_se_hdr, "uas", strlen("uas"))) { 26020 *p_ref = SESSION_TIMER_REFRESHER_UAS; 26021 ast_debug(2, "Refresher: UAS\n"); 26022 } else { 26023 ast_log(LOG_WARNING, "Invalid refresher value %s\n", p_se_hdr); 26024 return -1; 26025 } 26026 break; 26027 } 26028 } 26029 return 0; 26030 }
static int parse_uri_legacy_check | ( | char * | uri, | |
const char * | scheme, | |||
char ** | user, | |||
char ** | pass, | |||
char ** | hostport, | |||
char ** | transport | |||
) | [static] |
parse uri in a way that allows semicolon stripping if legacy mode is enabled
Definition at line 13849 of file chan_sip.c.
References parse_uri(), and sip_cfg.
Referenced by __set_address_from_contact(), check_user_full(), get_also_info(), get_destination(), parse_register_contact(), and register_verify().
13850 { 13851 int ret = parse_uri(uri, scheme, user, pass, hostport, transport); 13852 if (sip_cfg.legacy_useroption_parsing) { /* if legacy mode is active, strip semis from the user field */ 13853 char *p; 13854 if ((p = strchr(uri, (int)';'))) { 13855 *p = '\0'; 13856 } 13857 } 13858 return ret; 13859 }
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 16818 of file chan_sip.c.
References ao2_t_ref, ast_cli(), and ast_cli_args::fd.
Referenced by sip_show_objects().
16819 { 16820 struct sip_peer *peer = userobj; 16821 int refc = ao2_t_ref(userobj, 0, ""); 16822 struct ast_cli_args *a = (struct ast_cli_args *) arg; 16823 16824 ast_cli(a->fd, "name: %s\ntype: peer\nobjflags: %d\nrefcount: %d\n\n", 16825 peer->name, 0, refc); 16826 return 0; 16827 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 29645 of file chan_sip.c.
References ast_str_case_hash().
29646 { 29647 const struct sip_peer *peer = obj; 29648 29649 return ast_str_case_hash(peer->name); 29650 }
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 29703 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().
29704 { 29705 struct sip_peer *peer = obj, *peer2 = arg; 29706 29707 if (ast_sockaddr_cmp_addr(&peer->addr, &peer2->addr)) { 29708 /* IP doesn't match */ 29709 return 0; 29710 } 29711 29712 /* We matched the IP, check to see if we need to match by port as well. */ 29713 if ((peer->transports & peer2->transports) & (SIP_TRANSPORT_TLS | SIP_TRANSPORT_TCP)) { 29714 /* peer matching on port is not possible with TCP/TLS */ 29715 return CMP_MATCH | CMP_STOP; 29716 } else if (ast_test_flag(&peer2->flags[0], SIP_INSECURE_PORT)) { 29717 /* We are allowing match without port for peers configured that 29718 * way in this pass through the peers. */ 29719 return ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT) ? 29720 (CMP_MATCH | CMP_STOP) : 0; 29721 } 29722 29723 /* Now only return a match if the port matches, as well. */ 29724 return ast_sockaddr_port(&peer->addr) == ast_sockaddr_port(&peer2->addr) ? 29725 (CMP_MATCH | CMP_STOP) : 0; 29726 }
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 29667 of file chan_sip.c.
References ast_log(), ast_sockaddr_hash(), ast_sockaddr_isnull(), and LOG_ERROR.
Referenced by load_module().
29668 { 29669 const struct sip_peer *peer = obj; 29670 int ret = 0; 29671 29672 if (ast_sockaddr_isnull(&peer->addr)) { 29673 ast_log(LOG_ERROR, "Empty address\n"); 29674 } 29675 29676 ret = ast_sockaddr_hash(&peer->addr); 29677 29678 if (ret < 0) { 29679 ret = -ret; 29680 } 29681 29682 return ret; 29683 }
static void peer_mailboxes_to_str | ( | struct ast_str ** | mailbox_str, | |
struct sip_peer * | peer | |||
) | [static] |
list peer mailboxes to CLI
Definition at line 17340 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().
17341 { 17342 struct sip_mailbox *mailbox; 17343 17344 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 17345 ast_str_append(mailbox_str, 0, "%s%s%s%s", 17346 mailbox->mailbox, 17347 ast_strlen_zero(mailbox->context) ? "" : "@", 17348 S_OR(mailbox->context, ""), 17349 AST_LIST_NEXT(mailbox, entry) ? "," : ""); 17350 } 17351 }
static int peer_markall_func | ( | void * | device, | |
void * | arg, | |||
int | flags | |||
) | [static] |
static void peer_sched_cleanup | ( | struct sip_peer * | peer | ) | [static] |
Definition at line 2854 of file chan_sip.c.
References AST_SCHED_DEL_UNREF, and unref_peer().
Referenced by match_and_cleanup_peer_sched().
02855 { 02856 if (peer->pokeexpire != -1) { 02857 AST_SCHED_DEL_UNREF(sched, peer->pokeexpire, 02858 unref_peer(peer, "removing poke peer ref")); 02859 } 02860 if (peer->expire != -1) { 02861 AST_SCHED_DEL_UNREF(sched, peer->expire, 02862 unref_peer(peer, "remove register expire ref")); 02863 } 02864 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Definition at line 16408 of file chan_sip.c.
References ast_copy_string().
16409 { 16410 int res = 0; 16411 if (peer->maxms) { 16412 if (peer->lastms < 0) { 16413 ast_copy_string(status, "UNREACHABLE", statuslen); 16414 } else if (peer->lastms > peer->maxms) { 16415 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 16416 res = 1; 16417 } else if (peer->lastms) { 16418 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 16419 res = 1; 16420 } else { 16421 ast_copy_string(status, "UNKNOWN", statuslen); 16422 } 16423 } else { 16424 ast_copy_string(status, "Unmonitored", statuslen); 16425 /* Checking if port is 0 */ 16426 res = -1; 16427 } 16428 return res; 16429 }
int peercomparefunc | ( | const void * | a, | |
const void * | b | |||
) |
Definition at line 16636 of file chan_sip.c.
Referenced by _sip_show_peers().
16637 { 16638 struct sip_peer **ap = (struct sip_peer **)a; 16639 struct sip_peer **bp = (struct sip_peer **)b; 16640 return strcmp((*ap)->name, (*bp)->name); 16641 }
static int peers_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 30084 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().
30086 { 30087 struct sip_peer *peer; 30088 struct ao2_iterator i; 30089 struct ast_data *data_peer, *data_peer_mailboxes = NULL, *data_peer_mailbox, *enum_node; 30090 struct ast_data *data_sip_options; 30091 int total_mailboxes, x; 30092 struct sip_mailbox *mailbox; 30093 30094 i = ao2_iterator_init(peers, 0); 30095 while ((peer = ao2_iterator_next(&i))) { 30096 ao2_lock(peer); 30097 30098 data_peer = ast_data_add_node(data_root, "peer"); 30099 if (!data_peer) { 30100 ao2_unlock(peer); 30101 ao2_ref(peer, -1); 30102 continue; 30103 } 30104 30105 ast_data_add_structure(sip_peer, data_peer, peer); 30106 30107 /* transfer mode */ 30108 enum_node = ast_data_add_node(data_peer, "allowtransfer"); 30109 if (!enum_node) { 30110 ao2_unlock(peer); 30111 ao2_ref(peer, -1); 30112 continue; 30113 } 30114 ast_data_add_str(enum_node, "text", transfermode2str(peer->allowtransfer)); 30115 ast_data_add_int(enum_node, "value", peer->allowtransfer); 30116 30117 /* transports */ 30118 ast_data_add_str(data_peer, "transports", get_transport_list(peer->transports)); 30119 30120 /* peer type */ 30121 if ((peer->type & SIP_TYPE_USER) && (peer->type & SIP_TYPE_PEER)) { 30122 ast_data_add_str(data_peer, "type", "friend"); 30123 } else if (peer->type & SIP_TYPE_PEER) { 30124 ast_data_add_str(data_peer, "type", "peer"); 30125 } else if (peer->type & SIP_TYPE_USER) { 30126 ast_data_add_str(data_peer, "type", "user"); 30127 } 30128 30129 /* mailboxes */ 30130 total_mailboxes = 0; 30131 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 30132 if (!total_mailboxes) { 30133 data_peer_mailboxes = ast_data_add_node(data_peer, "mailboxes"); 30134 if (!data_peer_mailboxes) { 30135 break; 30136 } 30137 total_mailboxes++; 30138 } 30139 30140 data_peer_mailbox = ast_data_add_node(data_peer_mailboxes, "mailbox"); 30141 if (!data_peer_mailbox) { 30142 continue; 30143 } 30144 ast_data_add_str(data_peer_mailbox, "mailbox", mailbox->mailbox); 30145 ast_data_add_str(data_peer_mailbox, "context", mailbox->context); 30146 } 30147 30148 /* amaflags */ 30149 enum_node = ast_data_add_node(data_peer, "amaflags"); 30150 if (!enum_node) { 30151 ao2_unlock(peer); 30152 ao2_ref(peer, -1); 30153 continue; 30154 } 30155 ast_data_add_int(enum_node, "value", peer->amaflags); 30156 ast_data_add_str(enum_node, "text", ast_cdr_flags2str(peer->amaflags)); 30157 30158 /* sip options */ 30159 data_sip_options = ast_data_add_node(data_peer, "sipoptions"); 30160 if (!data_sip_options) { 30161 ao2_unlock(peer); 30162 ao2_ref(peer, -1); 30163 continue; 30164 } 30165 for (x = 0 ; x < ARRAY_LEN(sip_options); x++) { 30166 ast_data_add_bool(data_sip_options, sip_options[x].text, peer->sipoptions & sip_options[x].id); 30167 } 30168 30169 /* callingpres */ 30170 enum_node = ast_data_add_node(data_peer, "callingpres"); 30171 if (!enum_node) { 30172 ao2_unlock(peer); 30173 ao2_ref(peer, -1); 30174 continue; 30175 } 30176 ast_data_add_int(enum_node, "value", peer->callingpres); 30177 ast_data_add_str(enum_node, "text", ast_describe_caller_presentation(peer->callingpres)); 30178 30179 /* codecs */ 30180 ast_data_add_codecs(data_peer, "codecs", peer->capability); 30181 30182 if (!ast_data_search_match(search, data_peer)) { 30183 ast_data_remove_node(data_root, data_peer); 30184 } 30185 30186 ao2_unlock(peer); 30187 ao2_ref(peer, -1); 30188 } 30189 ao2_iterator_destroy(&i); 30190 30191 return 0; 30192 }
static int pidf_validate_presence | ( | struct ast_xml_doc * | doc | ) | [static] |
Definition at line 23970 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().
23971 { 23972 struct ast_xml_node *presence_node = ast_xml_get_root(doc); 23973 struct ast_xml_node *child_nodes; 23974 struct ast_xml_node *node_iterator; 23975 struct ast_xml_ns *ns; 23976 const char *entity; 23977 const char *namespace; 23978 const char presence_namespace[] = "urn:ietf:params:xml:ns:pidf"; 23979 23980 if (!presence_node) { 23981 ast_log(LOG_WARNING, "Unable to retrieve root node of the XML document\n"); 23982 return FALSE; 23983 } 23984 /* Okay, we managed to open the document! YAY! Now, let's start making sure it's all PIDF-ified 23985 * correctly. 23986 */ 23987 if (strcmp(ast_xml_node_get_name(presence_node), "presence")) { 23988 ast_log(LOG_WARNING, "Root node of PIDF document is not 'presence'. Invalid\n"); 23989 return FALSE; 23990 } 23991 23992 /* The presence element must have an entity attribute and an xmlns attribute. Furthermore 23993 * the xmlns attribute must be "urn:ietf:params:xml:ns:pidf" 23994 */ 23995 if (!(entity = ast_xml_get_attribute(presence_node, "entity"))) { 23996 ast_log(LOG_WARNING, "Presence element of PIDF document has no 'entity' attribute\n"); 23997 return FALSE; 23998 } 23999 /* We're not interested in what the entity is, just that it exists */ 24000 ast_xml_free_attr(entity); 24001 24002 if (!(ns = ast_xml_find_namespace(doc, presence_node, NULL))) { 24003 ast_log(LOG_WARNING, "Couldn't find default namespace...\n"); 24004 return FALSE; 24005 } 24006 24007 namespace = ast_xml_get_ns_href(ns); 24008 if (ast_strlen_zero(namespace) || strcmp(namespace, presence_namespace)) { 24009 ast_log(LOG_WARNING, "PIDF document has invalid namespace value %s\n", namespace); 24010 return FALSE; 24011 } 24012 24013 if (!(child_nodes = ast_xml_node_get_children(presence_node))) { 24014 ast_log(LOG_WARNING, "PIDF document has no elements as children of 'presence'. Invalid\n"); 24015 return FALSE; 24016 } 24017 24018 /* Check for tuple elements. RFC 3863 says that PIDF documents can have any number of 24019 * tuples, including 0. The big thing here is that if there are tuple elements present, 24020 * they have to have a single status element within. 24021 * 24022 * The RFC is worded such that tuples should appear as the first elements as children of 24023 * the presence element. However, we'll be accepting of documents which may place other elements 24024 * before the tuple(s). 24025 */ 24026 for (node_iterator = child_nodes; node_iterator; 24027 node_iterator = ast_xml_node_get_next(node_iterator)) { 24028 if (strcmp(ast_xml_node_get_name(node_iterator), "tuple")) { 24029 /* Not a tuple. We don't give a rat's hind quarters */ 24030 continue; 24031 } 24032 if (pidf_validate_tuple(node_iterator) == FALSE) { 24033 ast_log(LOG_WARNING, "Unable to validate tuple\n"); 24034 return FALSE; 24035 } 24036 } 24037 24038 return TRUE; 24039 }
static int pidf_validate_tuple | ( | struct ast_xml_node * | tuple_node | ) | [static] |
Definition at line 23930 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().
23931 { 23932 const char *id; 23933 int status_found = FALSE; 23934 struct ast_xml_node *tuple_children; 23935 struct ast_xml_node *tuple_children_iterator; 23936 /* Tuples have to have an id attribute or they're invalid */ 23937 if (!(id = ast_xml_get_attribute(tuple_node, "id"))) { 23938 ast_log(LOG_WARNING, "Tuple XML element has no attribute 'id'\n"); 23939 return FALSE; 23940 } 23941 /* We don't care what it actually is, just that it's there */ 23942 ast_xml_free_attr(id); 23943 /* This is a tuple. It must have a status element */ 23944 if (!(tuple_children = ast_xml_node_get_children(tuple_node))) { 23945 /* The tuple has no children. It sucks */ 23946 ast_log(LOG_WARNING, "Tuple XML element has no child elements\n"); 23947 return FALSE; 23948 } 23949 for (tuple_children_iterator = tuple_children; tuple_children_iterator; 23950 tuple_children_iterator = ast_xml_node_get_next(tuple_children_iterator)) { 23951 /* Similar to the wording used regarding tuples, the status element should appear 23952 * first. However, we will once again relax things and accept the status at any 23953 * position. We will enforce that only a single status element can be present. 23954 */ 23955 if (strcmp(ast_xml_node_get_name(tuple_children_iterator), "status")) { 23956 /* Not the status, we don't care */ 23957 continue; 23958 } 23959 if (status_found == TRUE) { 23960 /* THERE CAN BE ONLY ONE!!! */ 23961 ast_log(LOG_WARNING, "Multiple status elements found in tuple. Only one allowed\n"); 23962 return FALSE; 23963 } 23964 status_found = TRUE; 23965 } 23966 return status_found; 23967 }
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 3116 of file chan_sip.c.
References ast_strlen_zero().
Referenced by build_peer(), and sip_parse_register_line().
03117 { 03118 int port = standard; 03119 if (ast_strlen_zero(pt) || (sscanf(pt, "%30d", &port) != 1) || (port < 1) || (port > 65535)) { 03120 port = standard; 03121 } 03122 03123 return port; 03124 }
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 17177 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().
17178 { 17179 int x; 17180 format_t codec; 17181 17182 for(x = 0; x < 64 ; x++) { 17183 codec = ast_codec_pref_index(pref, x); 17184 if (!codec) 17185 break; 17186 ast_cli(fd, "%s", ast_getformatname(codec)); 17187 ast_cli(fd, ":%d", pref->framing[x]); 17188 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 17189 ast_cli(fd, ","); 17190 } 17191 if (!x) 17192 ast_cli(fd, "none"); 17193 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 16870 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
16871 { 16872 char buf[256]; 16873 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 16874 }
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 26040 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().
26041 { 26042 int rtn; 26043 const char *p_hdrval; 26044 int minse; 26045 26046 p_hdrval = get_header(rsp, "Min-SE"); 26047 if (ast_strlen_zero(p_hdrval)) { 26048 ast_log(LOG_WARNING, "422 response without a Min-SE header %s\n", p_hdrval); 26049 return; 26050 } 26051 rtn = parse_minse(p_hdrval, &minse); 26052 if (rtn != 0) { 26053 ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval); 26054 return; 26055 } 26056 p->stimer->st_interval = minse; 26057 transmit_invite(p, SIP_INVITE, 1, 2, NULL); 26058 }
static int proc_session_timer | ( | const void * | vp | ) | [static] |
Session-Timers: Process session refresh timeout event.
Definition at line 25877 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().
25878 { 25879 struct sip_pvt *p = (struct sip_pvt *) vp; 25880 int sendreinv = FALSE; 25881 int res = 0; 25882 25883 if (!p->stimer) { 25884 ast_log(LOG_WARNING, "Null stimer in proc_session_timer - %s\n", p->callid); 25885 goto return_unref; 25886 } 25887 25888 ast_debug(2, "Session timer expired: %d - %s\n", p->stimer->st_schedid, p->callid); 25889 25890 if (!p->owner) { 25891 goto return_unref; 25892 } 25893 25894 if ((p->stimer->st_active != TRUE) || (p->owner->_state != AST_STATE_UP)) { 25895 goto return_unref; 25896 } 25897 25898 switch (p->stimer->st_ref) { 25899 case SESSION_TIMER_REFRESHER_UAC: 25900 if (p->outgoing_call == TRUE) { 25901 sendreinv = TRUE; 25902 } 25903 break; 25904 case SESSION_TIMER_REFRESHER_UAS: 25905 if (p->outgoing_call != TRUE) { 25906 sendreinv = TRUE; 25907 } 25908 break; 25909 default: 25910 ast_log(LOG_ERROR, "Unknown session refresher %d\n", p->stimer->st_ref); 25911 goto return_unref; 25912 } 25913 25914 if (sendreinv == TRUE) { 25915 res = 1; 25916 transmit_reinvite_with_sdp(p, FALSE, TRUE); 25917 } else { 25918 p->stimer->st_expirys++; 25919 if (p->stimer->st_expirys >= 2) { 25920 if (p->stimer->quit_flag) { 25921 goto return_unref; 25922 } 25923 ast_log(LOG_WARNING, "Session-Timer expired - %s\n", p->callid); 25924 sip_pvt_lock(p); 25925 while (p->owner && ast_channel_trylock(p->owner)) { 25926 sip_pvt_unlock(p); 25927 usleep(1); 25928 if (p->stimer && p->stimer->quit_flag) { 25929 goto return_unref; 25930 } 25931 sip_pvt_lock(p); 25932 } 25933 25934 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 25935 ast_channel_unlock(p->owner); 25936 sip_pvt_unlock(p); 25937 } else { 25938 res = 1; 25939 } 25940 } 25941 25942 return_unref: 25943 if (!res) { 25944 /* An error occurred. Stop session timer processing */ 25945 if (p->stimer) { 25946 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 25947 p->stimer->st_schedid = -1; 25948 stop_session_timer(p); 25949 } 25950 25951 /* If we are not asking to be rescheduled, then we need to release our 25952 * reference to the dialog. */ 25953 dialog_unref(p, "removing session timer ref"); 25954 } 25955 25956 return res; 25957 }
static int process_crypto | ( | struct sip_pvt * | p, | |
struct ast_rtp_instance * | rtp, | |||
struct sip_srtp ** | srtp, | |||
const char * | a | |||
) | [static] |
Definition at line 29500 of file chan_sip.c.
References ast_debug, ast_log(), ast_set_flag, ast_test_flag, FALSE, LOG_WARNING, sdp_crypto_process(), sdp_crypto_setup(), setup_srtp(), and TRUE.
Referenced by process_sdp().
29501 { 29502 /* If no RTP instance exists for this media stream don't bother processing the crypto line */ 29503 if (!rtp) { 29504 ast_debug(3, "Received offer with crypto line for media stream that is not enabled\n"); 29505 return FALSE; 29506 } 29507 29508 if (strncasecmp(a, "crypto:", 7)) { 29509 return FALSE; 29510 } 29511 if (!*srtp) { 29512 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 29513 ast_log(LOG_WARNING, "Ignoring unexpected crypto attribute in SDP answer\n"); 29514 return FALSE; 29515 } 29516 29517 if (setup_srtp(srtp) < 0) { 29518 return FALSE; 29519 } 29520 } 29521 29522 /* For now, when we receive an INVITE just take the first successful crypto line */ 29523 if ((*srtp)->crypto && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 29524 ast_debug(3, "We've already processed a crypto attribute, skipping '%s'\n", a); 29525 return FALSE; 29526 } 29527 29528 if (!(*srtp)->crypto && !((*srtp)->crypto = sdp_crypto_setup())) { 29529 return FALSE; 29530 } 29531 29532 if (sdp_crypto_process((*srtp)->crypto, a, rtp) < 0) { 29533 return FALSE; 29534 } 29535 29536 ast_set_flag(*srtp, SRTP_CRYPTO_OFFER_OK); 29537 29538 return TRUE; 29539 }
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 8758 of file chan_sip.c.
References ast_async_goto(), ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_clear_flag, ast_codec_choose(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_exists_extension(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_T140RED, ast_getformatname_multiple(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_codecs_payload_formats(), ast_rtp_codecs_payloads_clear(), ast_rtp_codecs_payloads_copy(), ast_rtp_codecs_payloads_set_m_type(), AST_RTP_DTMF, ast_rtp_instance_fd(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_remote_address(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_remote_address(), ast_rtp_instance_stop(), ast_rtp_lookup_mime_multiple2(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, AST_RTP_PROPERTY_RTCP, ast_rtp_red_init(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_skip_blanks(), ast_sockaddr_isnull(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_str_alloca, ast_strlen_zero(), ast_test_flag, ast_udptl_get_far_max_datagram(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_peer(), ast_udptl_stop(), ast_verbose, change_hold_state(), change_t38_state(), debug, FALSE, get_sdp_iterate(), get_sdp_line(), initialize_udptl(), len(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar_helper(), process_crypto(), process_sdp_a_audio(), process_sdp_a_image(), process_sdp_a_sendonly(), process_sdp_a_text(), process_sdp_a_video(), process_sdp_c(), process_sdp_o(), S_COR, S_OR, sip_debug_test_pvt(), sockaddr_is_null_or_any(), text, TRUE, type, UDPTL_ERROR_CORRECTION_NONE, value, and VERBOSE_PREFIX_2.
08759 { 08760 /* Iterators for SDP parsing */ 08761 int start = req->sdp_start; 08762 int next = start; 08763 int iterator = start; 08764 08765 /* Temporary vars for SDP parsing */ 08766 char type = '\0'; 08767 const char *value = NULL; 08768 const char *m = NULL; /* SDP media offer */ 08769 const char *nextm = NULL; 08770 int len = -1; 08771 08772 /* Host information */ 08773 struct ast_sockaddr sessionsa; 08774 struct ast_sockaddr audiosa; 08775 struct ast_sockaddr videosa; 08776 struct ast_sockaddr textsa; 08777 struct ast_sockaddr imagesa; 08778 struct ast_sockaddr *sa = NULL; /*!< RTP Audio host IP */ 08779 struct ast_sockaddr *vsa = NULL; /*!< RTP video host IP */ 08780 struct ast_sockaddr *tsa = NULL; /*!< RTP text host IP */ 08781 struct ast_sockaddr *isa = NULL; /*!< UDPTL host ip */ 08782 int portno = -1; /*!< RTP Audio port number */ 08783 int vportno = -1; /*!< RTP Video port number */ 08784 int tportno = -1; /*!< RTP Text port number */ 08785 int udptlportno = -1; /*!< UDPTL Image port number */ 08786 08787 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 08788 format_t peercapability = 0, vpeercapability = 0, tpeercapability = 0; 08789 int peernoncodeccapability = 0, vpeernoncodeccapability = 0, tpeernoncodeccapability = 0; 08790 08791 struct ast_rtp_codecs newaudiortp, newvideortp, newtextrtp; 08792 format_t newjointcapability; /* Negotiated capability */ 08793 format_t newpeercapability; 08794 int newnoncodeccapability; 08795 08796 const char *codecs; 08797 int codec; 08798 08799 /* SRTP */ 08800 int secure_audio = FALSE; 08801 int secure_video = FALSE; 08802 08803 /* Others */ 08804 int sendonly = -1; 08805 int vsendonly = -1; 08806 int numberofports; 08807 int numberofmediastreams = 0; 08808 int last_rtpmap_codec = 0; 08809 int red_data_pt[10]; /* For T.140 red */ 08810 int red_num_gen = 0; /* For T.140 red */ 08811 char red_fmtp[100] = "empty"; /* For T.140 red */ 08812 int debug = sip_debug_test_pvt(p); 08813 08814 /* START UNKNOWN */ 08815 char buf[SIPBUFSIZE]; 08816 /* END UNKNOWN */ 08817 08818 /* Initial check */ 08819 if (!p->rtp) { 08820 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 08821 return -1; 08822 } 08823 08824 /* Make sure that the codec structures are all cleared out */ 08825 ast_rtp_codecs_payloads_clear(&newaudiortp, NULL); 08826 ast_rtp_codecs_payloads_clear(&newvideortp, NULL); 08827 ast_rtp_codecs_payloads_clear(&newtextrtp, NULL); 08828 08829 /* Update our last rtprx when we receive an SDP, too */ 08830 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 08831 08832 memset(p->offered_media, 0, sizeof(p->offered_media)); 08833 08834 08835 /* default: novideo and notext set */ 08836 p->novideo = TRUE; 08837 p->notext = TRUE; 08838 08839 if (p->vrtp) { 08840 ast_rtp_codecs_payloads_clear(&newvideortp, NULL); 08841 } 08842 08843 if (p->trtp) { 08844 ast_rtp_codecs_payloads_clear(&newtextrtp, NULL); 08845 } 08846 08847 /* Scan for the first media stream (m=) line to limit scanning of globals */ 08848 nextm = get_sdp_iterate(&next, req, "m"); 08849 if (ast_strlen_zero(nextm)) { 08850 ast_log(LOG_WARNING, "Insufficient information for SDP (m= not found)\n"); 08851 return -1; 08852 } 08853 08854 /* Scan session level SDP parameters (lines before first media stream) */ 08855 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 08856 int processed = FALSE; 08857 switch (type) { 08858 case 'o': 08859 /* If we end up receiving SDP that doesn't actually modify the session we don't want to treat this as a fatal 08860 * error. We just want to ignore the SDP and let the rest of the packet be handled as normal. 08861 */ 08862 if (!process_sdp_o(value, p)) 08863 return (p->session_modify == FALSE) ? 0 : -1; 08864 break; 08865 case 'c': 08866 if (process_sdp_c(value, &sessionsa)) { 08867 processed = TRUE; 08868 sa = &sessionsa; 08869 vsa = sa; 08870 tsa = sa; 08871 isa = sa; 08872 } 08873 break; 08874 case 'a': 08875 if (process_sdp_a_sendonly(value, &sendonly)) { 08876 processed = TRUE; 08877 vsendonly = sendonly; 08878 } 08879 else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec)) 08880 processed = TRUE; 08881 else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec)) 08882 processed = TRUE; 08883 else if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec)) 08884 processed = TRUE; 08885 else if (process_sdp_a_image(value, p)) 08886 processed = TRUE; 08887 break; 08888 } 08889 08890 ast_debug(3, "Processing session-level SDP %c=%s... %s\n", type, value, (processed == TRUE)? "OK." : "UNSUPPORTED."); 08891 } 08892 08893 08894 08895 /* Scan media stream (m=) specific parameters loop */ 08896 while (!ast_strlen_zero(nextm)) { 08897 int audio = FALSE; 08898 int video = FALSE; 08899 int image = FALSE; 08900 int text = FALSE; 08901 char protocol[5] = {0,}; 08902 int x; 08903 08904 numberofports = 1; 08905 len = -1; 08906 start = next; 08907 m = nextm; 08908 iterator = next; 08909 nextm = get_sdp_iterate(&next, req, "m"); 08910 08911 /* Search for audio media definition */ 08912 if ((sscanf(m, "audio %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) || 08913 (sscanf(m, "audio %30u RTP/%4s %n", &x, protocol, &len) == 2 && len > 0)) { 08914 if (x == 0) { 08915 ast_log(LOG_WARNING, "ignoring 'audio' media offer because port number is zero"); 08916 continue; 08917 } 08918 if (!strcmp(protocol, "SAVP")) { 08919 secure_audio = 1; 08920 } else if (strcmp(protocol, "AVP")) { 08921 ast_log(LOG_WARNING, "unknown SDP media protocol in offer: %s\n", protocol); 08922 continue; 08923 } 08924 if (p->offered_media[SDP_AUDIO].order_offered) { 08925 ast_log(LOG_WARNING, "Multiple audio streams are not supported\n"); 08926 return -3; 08927 } 08928 audio = TRUE; 08929 p->offered_media[SDP_AUDIO].order_offered = ++numberofmediastreams; 08930 portno = x; 08931 08932 /* Scan through the RTP payload types specified in a "m=" line: */ 08933 codecs = m + len; 08934 ast_copy_string(p->offered_media[SDP_AUDIO].codecs, codecs, sizeof(p->offered_media[SDP_AUDIO].codecs)); 08935 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 08936 if (sscanf(codecs, "%30u%n", &codec, &len) != 1) { 08937 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 08938 return -1; 08939 } 08940 if (debug) 08941 ast_verbose("Found RTP audio format %d\n", codec); 08942 08943 ast_rtp_codecs_payloads_set_m_type(&newaudiortp, NULL, codec); 08944 } 08945 /* Search for video media definition */ 08946 } else if ((sscanf(m, "video %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) || 08947 (sscanf(m, "video %30u RTP/%4s %n", &x, protocol, &len) == 2 && len > 0)) { 08948 if (x == 0) { 08949 ast_log(LOG_WARNING, "ignoring 'video' media offer because port number is zero"); 08950 continue; 08951 } 08952 if (!strcmp(protocol, "SAVP")) { 08953 secure_video = 1; 08954 } else if (strcmp(protocol, "AVP")) { 08955 ast_log(LOG_WARNING, "unknown SDP media protocol in offer: %s\n", protocol); 08956 continue; 08957 } 08958 if (p->offered_media[SDP_VIDEO].order_offered) { 08959 ast_log(LOG_WARNING, "Multiple video streams are not supported\n"); 08960 return -3; 08961 } 08962 video = TRUE; 08963 p->novideo = FALSE; 08964 p->offered_media[SDP_VIDEO].order_offered = ++numberofmediastreams; 08965 vportno = x; 08966 08967 /* Scan through the RTP payload types specified in a "m=" line: */ 08968 codecs = m + len; 08969 ast_copy_string(p->offered_media[SDP_VIDEO].codecs, codecs, sizeof(p->offered_media[SDP_VIDEO].codecs)); 08970 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 08971 if (sscanf(codecs, "%30u%n", &codec, &len) != 1) { 08972 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 08973 return -1; 08974 } 08975 if (debug) 08976 ast_verbose("Found RTP video format %d\n", codec); 08977 ast_rtp_codecs_payloads_set_m_type(&newvideortp, NULL, codec); 08978 } 08979 /* Search for text media definition */ 08980 } else if ((sscanf(m, "text %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 08981 (sscanf(m, "text %30u RTP/AVP %n", &x, &len) == 1 && len > 0)) { 08982 if (x == 0) { 08983 ast_log(LOG_WARNING, "ignoring 'text' media offer because port number is zero"); 08984 continue; 08985 } 08986 if (p->offered_media[SDP_TEXT].order_offered) { 08987 ast_log(LOG_WARNING, "Multiple text streams are not supported\n"); 08988 return -3; 08989 } 08990 text = TRUE; 08991 p->notext = FALSE; 08992 p->offered_media[SDP_TEXT].order_offered = ++numberofmediastreams; 08993 tportno = x; 08994 08995 /* Scan through the RTP payload types specified in a "m=" line: */ 08996 codecs = m + len; 08997 ast_copy_string(p->offered_media[SDP_TEXT].codecs, codecs, sizeof(p->offered_media[SDP_TEXT].codecs)); 08998 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 08999 if (sscanf(codecs, "%30u%n", &codec, &len) != 1) { 09000 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 09001 return -1; 09002 } 09003 if (debug) 09004 ast_verbose("Found RTP text format %d\n", codec); 09005 ast_rtp_codecs_payloads_set_m_type(&newtextrtp, NULL, codec); 09006 } 09007 /* Search for image media definition */ 09008 } else if (((sscanf(m, "image %30u udptl t38%n", &x, &len) == 1 && len > 0) || 09009 (sscanf(m, "image %30u UDPTL t38%n", &x, &len) == 1 && len > 0))) { 09010 if (x == 0) { 09011 ast_log(LOG_WARNING, "ignoring 'image' media offer because port number is zero"); 09012 continue; 09013 } 09014 if (initialize_udptl(p)) { 09015 continue; 09016 } 09017 09018 if (p->offered_media[SDP_IMAGE].order_offered) { 09019 ast_log(LOG_WARNING, "Multiple T.38 streams are not supported\n"); 09020 return -3; 09021 } 09022 image = TRUE; 09023 if (debug) 09024 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 09025 p->offered_media[SDP_IMAGE].order_offered = ++numberofmediastreams; 09026 udptlportno = x; 09027 09028 if (p->t38.state != T38_ENABLED) { 09029 memset(&p->t38.their_parms, 0, sizeof(p->t38.their_parms)); 09030 09031 /* default EC to none, the remote end should 09032 * respond with the EC they want to use */ 09033 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 09034 } 09035 } else { 09036 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 09037 continue; 09038 } 09039 09040 /* Check for number of ports */ 09041 if (numberofports > 1) 09042 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 09043 09044 /* Media stream specific parameters */ 09045 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 09046 int processed = FALSE; 09047 09048 switch (type) { 09049 case 'c': 09050 if (audio) { 09051 if (process_sdp_c(value, &audiosa)) { 09052 processed = TRUE; 09053 sa = &audiosa; 09054 } 09055 } else if (video) { 09056 if (process_sdp_c(value, &videosa)) { 09057 processed = TRUE; 09058 vsa = &videosa; 09059 } 09060 } else if (text) { 09061 if (process_sdp_c(value, &textsa)) { 09062 processed = TRUE; 09063 tsa = &textsa; 09064 } 09065 } else if (image) { 09066 if (process_sdp_c(value, &imagesa)) { 09067 processed = TRUE; 09068 isa = &imagesa; 09069 } 09070 } 09071 break; 09072 case 'a': 09073 /* Audio specific scanning */ 09074 if (audio) { 09075 if (process_sdp_a_sendonly(value, &sendonly)) 09076 processed = TRUE; 09077 else if (process_crypto(p, p->rtp, &p->srtp, value)) 09078 processed = TRUE; 09079 else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec)) 09080 processed = TRUE; 09081 } 09082 /* Video specific scanning */ 09083 else if (video) { 09084 if (process_sdp_a_sendonly(value, &vsendonly)) 09085 processed = TRUE; 09086 else if (process_crypto(p, p->vrtp, &p->vsrtp, value)) 09087 processed = TRUE; 09088 else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec)) 09089 processed = TRUE; 09090 } 09091 /* Text (T.140) specific scanning */ 09092 else if (text) { 09093 if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec)) 09094 processed = TRUE; 09095 else if (process_crypto(p, p->trtp, &p->tsrtp, value)) 09096 processed = TRUE; 09097 } 09098 /* Image (T.38 FAX) specific scanning */ 09099 else if (image) { 09100 if (process_sdp_a_image(value, p)) 09101 processed = TRUE; 09102 } 09103 break; 09104 } 09105 09106 ast_debug(3, "Processing media-level (%s) SDP %c=%s... %s\n", 09107 (audio == TRUE)? "audio" : (video == TRUE)? "video" : "image", 09108 type, value, 09109 (processed == TRUE)? "OK." : "UNSUPPORTED."); 09110 } 09111 } 09112 09113 09114 /* Sanity checks */ 09115 if (!sa && !vsa && !tsa && !isa) { 09116 ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n"); 09117 return -1; 09118 } 09119 09120 if (portno == -1 && vportno == -1 && udptlportno == -1 && tportno == -1) { 09121 /* No acceptable offer found in SDP - we have no ports */ 09122 /* Do not change RTP or VRTP if this is a re-invite */ 09123 ast_log(LOG_WARNING, "Failing due to no acceptable offer found\n"); 09124 return -2; 09125 } 09126 09127 if (secure_audio && !(p->srtp && (ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)))) { 09128 ast_log(LOG_WARNING, "Can't provide secure audio requested in SDP offer\n"); 09129 return -4; 09130 } 09131 09132 if (!secure_audio && p->srtp) { 09133 ast_log(LOG_WARNING, "We are requesting SRTP, but they responded without it!\n"); 09134 return -4; 09135 } 09136 09137 if (secure_video && !(p->vsrtp && (ast_test_flag(p->vsrtp, SRTP_CRYPTO_OFFER_OK)))) { 09138 ast_log(LOG_WARNING, "Can't provide secure video requested in SDP offer\n"); 09139 return -4; 09140 } 09141 09142 if (!p->novideo && !secure_video && p->vsrtp) { 09143 ast_log(LOG_WARNING, "We are requesting SRTP, but they responded without it!\n"); 09144 return -4; 09145 } 09146 09147 if (!(secure_audio || secure_video) && ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) { 09148 ast_log(LOG_WARNING, "Matched device setup to use SRTP, but request was not!\n"); 09149 return -4; 09150 } 09151 09152 if (udptlportno == -1) { 09153 change_t38_state(p, T38_DISABLED); 09154 } 09155 09156 /* Now gather all of the codecs that we are asked for: */ 09157 ast_rtp_codecs_payload_formats(&newaudiortp, &peercapability, &peernoncodeccapability); 09158 ast_rtp_codecs_payload_formats(&newvideortp, &vpeercapability, &vpeernoncodeccapability); 09159 ast_rtp_codecs_payload_formats(&newtextrtp, &tpeercapability, &tpeernoncodeccapability); 09160 09161 newjointcapability = p->capability & (peercapability | vpeercapability | tpeercapability); 09162 newpeercapability = (peercapability | vpeercapability | tpeercapability); 09163 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 09164 09165 if (debug) { 09166 /* shame on whoever coded this.... */ 09167 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE], s5[SIPBUFSIZE]; 09168 09169 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s/text=%s, combined - %s\n", 09170 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 09171 ast_getformatname_multiple(s2, SIPBUFSIZE, peercapability), 09172 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 09173 ast_getformatname_multiple(s4, SIPBUFSIZE, tpeercapability), 09174 ast_getformatname_multiple(s5, SIPBUFSIZE, newjointcapability)); 09175 } 09176 if (debug) { 09177 struct ast_str *s1 = ast_str_alloca(SIPBUFSIZE); 09178 struct ast_str *s2 = ast_str_alloca(SIPBUFSIZE); 09179 struct ast_str *s3 = ast_str_alloca(SIPBUFSIZE); 09180 09181 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 09182 ast_rtp_lookup_mime_multiple2(s1, p->noncodeccapability, 0, 0), 09183 ast_rtp_lookup_mime_multiple2(s2, peernoncodeccapability, 0, 0), 09184 ast_rtp_lookup_mime_multiple2(s3, newnoncodeccapability, 0, 0)); 09185 } 09186 if (!newjointcapability && udptlportno == -1) { 09187 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 09188 /* Do NOT Change current setting */ 09189 return -1; 09190 } 09191 09192 if (portno != -1 || vportno != -1 || tportno != -1) { 09193 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 09194 they are acceptable */ 09195 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 09196 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 09197 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 09198 09199 /* respond with single most preferred joint codec, limiting the other side's choice */ 09200 if (ast_test_flag(&p->flags[1], SIP_PAGE2_PREFERRED_CODEC)) { 09201 p->jointcapability = ast_codec_choose(&p->prefs, p->jointcapability, 1); 09202 } 09203 } 09204 09205 /* Setup audio address and port */ 09206 if (p->rtp) { 09207 if (portno > 0) { 09208 ast_sockaddr_set_port(sa, portno); 09209 ast_rtp_instance_set_remote_address(p->rtp, sa); 09210 if (debug) { 09211 ast_verbose("Peer audio RTP is at port %s\n", 09212 ast_sockaddr_stringify(sa)); 09213 } 09214 09215 ast_rtp_codecs_payloads_copy(&newaudiortp, ast_rtp_instance_get_codecs(p->rtp), p->rtp); 09216 /* Ensure RTCP is enabled since it may be inactive 09217 if we're coming back from a T.38 session */ 09218 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 1); 09219 /* Ensure audio RTCP reads are enabled */ 09220 if (p->owner) { 09221 ast_channel_set_fd(p->owner, 1, ast_rtp_instance_fd(p->rtp, 1)); 09222 } 09223 09224 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 09225 ast_clear_flag(&p->flags[0], SIP_DTMF); 09226 if (newnoncodeccapability & AST_RTP_DTMF) { 09227 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 09228 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 09229 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 09230 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, 1); 09231 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 09232 } else { 09233 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 09234 } 09235 } 09236 } else if (udptlportno > 0) { 09237 if (debug) 09238 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n"); 09239 /* Prevent audio RTCP reads */ 09240 if (p->owner) { 09241 ast_channel_set_fd(p->owner, 1, -1); 09242 } 09243 /* Silence RTCP while audio RTP is inactive */ 09244 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 0); 09245 } else { 09246 ast_rtp_instance_stop(p->rtp); 09247 if (debug) 09248 ast_verbose("Peer doesn't provide audio\n"); 09249 } 09250 } 09251 09252 /* Setup video address and port */ 09253 if (p->vrtp) { 09254 if (vportno > 0) { 09255 ast_sockaddr_set_port(vsa, vportno); 09256 ast_rtp_instance_set_remote_address(p->vrtp, vsa); 09257 if (debug) { 09258 ast_verbose("Peer video RTP is at port %s\n", 09259 ast_sockaddr_stringify(vsa)); 09260 } 09261 ast_rtp_codecs_payloads_copy(&newvideortp, ast_rtp_instance_get_codecs(p->vrtp), p->vrtp); 09262 } else { 09263 ast_rtp_instance_stop(p->vrtp); 09264 if (debug) 09265 ast_verbose("Peer doesn't provide video\n"); 09266 } 09267 } 09268 09269 /* Setup text address and port */ 09270 if (p->trtp) { 09271 if (tportno > 0) { 09272 ast_sockaddr_set_port(tsa, tportno); 09273 ast_rtp_instance_set_remote_address(p->trtp, tsa); 09274 if (debug) { 09275 ast_verbose("Peer T.140 RTP is at port %s\n", 09276 ast_sockaddr_stringify(tsa)); 09277 } 09278 if ((p->jointcapability & AST_FORMAT_T140RED)) { 09279 p->red = 1; 09280 ast_rtp_red_init(p->trtp, 300, red_data_pt, 2); 09281 } else { 09282 p->red = 0; 09283 } 09284 ast_rtp_codecs_payloads_copy(&newtextrtp, ast_rtp_instance_get_codecs(p->trtp), p->trtp); 09285 } else { 09286 ast_rtp_instance_stop(p->trtp); 09287 if (debug) 09288 ast_verbose("Peer doesn't provide T.140\n"); 09289 } 09290 } 09291 /* Setup image address and port */ 09292 if (p->udptl) { 09293 if (udptlportno > 0) { 09294 if (ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 09295 ast_rtp_instance_get_remote_address(p->rtp, isa); 09296 if (!ast_sockaddr_isnull(isa) && debug) { 09297 ast_debug(1, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_sockaddr_stringify(isa)); 09298 } 09299 } 09300 ast_sockaddr_set_port(isa, udptlportno); 09301 ast_udptl_set_peer(p->udptl, isa); 09302 if (debug) 09303 ast_debug(1,"Peer T.38 UDPTL is at port %s\n", ast_sockaddr_stringify(isa)); 09304 09305 /* verify the far max ifp can be calculated. this requires far max datagram to be set. */ 09306 if (!ast_udptl_get_far_max_datagram(p->udptl)) { 09307 /* setting to zero will force a default if none was provided by the SDP */ 09308 ast_udptl_set_far_max_datagram(p->udptl, 0); 09309 } 09310 09311 /* Remote party offers T38, we need to update state */ 09312 if ((t38action == SDP_T38_ACCEPT) && 09313 (p->t38.state == T38_LOCAL_REINVITE)) { 09314 change_t38_state(p, T38_ENABLED); 09315 } else if ((t38action == SDP_T38_INITIATE) && 09316 p->owner && p->lastinvite) { 09317 change_t38_state(p, T38_PEER_REINVITE); /* T38 Offered in re-invite from remote party */ 09318 /* If fax detection is enabled then send us off to the fax extension */ 09319 if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_T38)) { 09320 ast_channel_lock(p->owner); 09321 if (strcmp(p->owner->exten, "fax")) { 09322 const char *target_context = S_OR(p->owner->macrocontext, p->owner->context); 09323 ast_channel_unlock(p->owner); 09324 if (ast_exists_extension(p->owner, target_context, "fax", 1, 09325 S_COR(p->owner->caller.id.number.valid, p->owner->caller.id.number.str, NULL))) { 09326 ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to peer T.38 re-INVITE\n", p->owner->name); 09327 pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", p->owner->exten); 09328 if (ast_async_goto(p->owner, target_context, "fax", 1)) { 09329 ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", p->owner->name, target_context); 09330 } 09331 } else { 09332 ast_log(LOG_NOTICE, "T.38 re-INVITE detected but no fax extension\n"); 09333 } 09334 } else { 09335 ast_channel_unlock(p->owner); 09336 } 09337 } 09338 } 09339 } else { 09340 change_t38_state(p, T38_DISABLED); 09341 ast_udptl_stop(p->udptl); 09342 if (debug) 09343 ast_debug(1, "Peer doesn't provide T.38 UDPTL\n"); 09344 } 09345 } 09346 09347 if ((portno == -1) && (p->t38.state != T38_DISABLED)) { 09348 ast_debug(3, "Have T.38 but no audio, accepting offer anyway\n"); 09349 return 0; 09350 } 09351 09352 /* Ok, we're going with this offer */ 09353 ast_debug(2, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 09354 09355 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 09356 return 0; 09357 09358 ast_debug(4, "We have an owner, now see if we need to change this call\n"); 09359 09360 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 09361 if (debug) { 09362 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 09363 ast_debug(1, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 09364 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 09365 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 09366 } 09367 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability) | (p->capability & tpeercapability); 09368 ast_set_read_format(p->owner, p->owner->readformat); 09369 ast_set_write_format(p->owner, p->owner->writeformat); 09370 } 09371 09372 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)) { 09373 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 09374 /* Activate a re-invite */ 09375 ast_queue_frame(p->owner, &ast_null_frame); 09376 change_hold_state(p, req, FALSE, sendonly); 09377 } else if ((sockaddr_is_null_or_any(sa) && sockaddr_is_null_or_any(vsa) && sockaddr_is_null_or_any(tsa) && sockaddr_is_null_or_any(isa)) || (sendonly && sendonly != -1)) { 09378 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 09379 S_OR(p->mohsuggest, NULL), 09380 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 09381 if (sendonly) 09382 ast_rtp_instance_stop(p->rtp); 09383 /* RTCP needs to go ahead, even if we're on hold!!! */ 09384 /* Activate a re-invite */ 09385 ast_queue_frame(p->owner, &ast_null_frame); 09386 change_hold_state(p, req, TRUE, sendonly); 09387 } 09388 09389 return 0; 09390 }
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 9518 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().
09519 { 09520 int found = FALSE; 09521 int codec; 09522 char mimeSubtype[128]; 09523 char fmtp_string[64]; 09524 unsigned int sample_rate; 09525 int debug = sip_debug_test_pvt(p); 09526 09527 if (!strncasecmp(a, "ptime", 5)) { 09528 char *tmp = strrchr(a, ':'); 09529 long int framing = 0; 09530 if (tmp) { 09531 tmp++; 09532 framing = strtol(tmp, NULL, 10); 09533 if (framing == LONG_MIN || framing == LONG_MAX) { 09534 framing = 0; 09535 ast_debug(1, "Can't read framing from SDP: %s\n", a); 09536 } 09537 } 09538 if (framing && p->autoframing) { 09539 struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref; 09540 int codec_n; 09541 for (codec_n = 0; codec_n < AST_RTP_MAX_PT; codec_n++) { 09542 struct ast_rtp_payload_type format = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(p->rtp), codec_n); 09543 if (!format.asterisk_format || !format.code) /* non-codec or not found */ 09544 continue; 09545 ast_debug(1, "Setting framing for %s to %ld\n", ast_getformatname(format.code), framing); 09546 ast_codec_pref_setsize(pref, format.code, framing); 09547 } 09548 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, pref); 09549 } 09550 found = TRUE; 09551 } else if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) { 09552 /* We have a rtpmap to handle */ 09553 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 09554 if (!(ast_rtp_codecs_payloads_set_rtpmap_type_rate(newaudiortp, NULL, codec, "audio", mimeSubtype, 09555 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0, sample_rate))) { 09556 if (debug) 09557 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 09558 //found_rtpmap_codecs[last_rtpmap_codec] = codec; 09559 (*last_rtpmap_codec)++; 09560 found = TRUE; 09561 } else { 09562 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 09563 if (debug) 09564 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 09565 } 09566 } else { 09567 if (debug) 09568 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 09569 } 09570 } else if (sscanf(a, "fmtp: %30u %63s", &codec, fmtp_string) == 2) { 09571 struct ast_rtp_payload_type payload; 09572 09573 payload = ast_rtp_codecs_payload_lookup(newaudiortp, codec); 09574 if (payload.code && payload.asterisk_format) { 09575 unsigned int bit_rate; 09576 09577 switch (payload.code) { 09578 case AST_FORMAT_SIREN7: 09579 if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) { 09580 if (bit_rate != 32000) { 09581 ast_log(LOG_WARNING, "Got Siren7 offer at %d bps, but only 32000 bps supported; ignoring.\n", bit_rate); 09582 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 09583 } else { 09584 found = TRUE; 09585 } 09586 } 09587 break; 09588 case AST_FORMAT_SIREN14: 09589 if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) { 09590 if (bit_rate != 48000) { 09591 ast_log(LOG_WARNING, "Got Siren14 offer at %d bps, but only 48000 bps supported; ignoring.\n", bit_rate); 09592 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 09593 } else { 09594 found = TRUE; 09595 } 09596 } 09597 break; 09598 case AST_FORMAT_G719: 09599 if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) { 09600 if (bit_rate != 64000) { 09601 ast_log(LOG_WARNING, "Got G.719 offer at %d bps, but only 64000 bps supported; ignoring.\n", bit_rate); 09602 ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec); 09603 } else { 09604 found = TRUE; 09605 } 09606 } 09607 } 09608 } 09609 } 09610 09611 return found; 09612 }
static int process_sdp_a_image | ( | const char * | a, | |
struct sip_pvt * | p | |||
) | [static] |
Definition at line 9697 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, initialize_udptl(), TRUE, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by process_sdp().
09698 { 09699 int found = FALSE; 09700 char s[256]; 09701 unsigned int x; 09702 09703 if (initialize_udptl(p)) { 09704 return found; 09705 } 09706 09707 if ((sscanf(a, "T38FaxMaxBuffer:%30u", &x) == 1)) { 09708 ast_debug(3, "MaxBufferSize:%d\n", x); 09709 found = TRUE; 09710 } else if ((sscanf(a, "T38MaxBitRate:%30u", &x) == 1) || (sscanf(a, "T38FaxMaxRate:%30u", &x) == 1)) { 09711 ast_debug(3, "T38MaxBitRate: %d\n", x); 09712 switch (x) { 09713 case 14400: 09714 p->t38.their_parms.rate = AST_T38_RATE_14400; 09715 break; 09716 case 12000: 09717 p->t38.their_parms.rate = AST_T38_RATE_12000; 09718 break; 09719 case 9600: 09720 p->t38.their_parms.rate = AST_T38_RATE_9600; 09721 break; 09722 case 7200: 09723 p->t38.their_parms.rate = AST_T38_RATE_7200; 09724 break; 09725 case 4800: 09726 p->t38.their_parms.rate = AST_T38_RATE_4800; 09727 break; 09728 case 2400: 09729 p->t38.their_parms.rate = AST_T38_RATE_2400; 09730 break; 09731 } 09732 found = TRUE; 09733 } else if ((sscanf(a, "T38FaxVersion:%30u", &x) == 1)) { 09734 ast_debug(3, "FaxVersion: %u\n", x); 09735 p->t38.their_parms.version = x; 09736 found = TRUE; 09737 } else if ((sscanf(a, "T38FaxMaxDatagram:%30u", &x) == 1) || (sscanf(a, "T38MaxDatagram:%30u", &x) == 1)) { 09738 /* override the supplied value if the configuration requests it */ 09739 if (((signed int) p->t38_maxdatagram >= 0) && ((unsigned int) p->t38_maxdatagram > x)) { 09740 ast_debug(1, "Overriding T38FaxMaxDatagram '%d' with '%d'\n", x, p->t38_maxdatagram); 09741 x = p->t38_maxdatagram; 09742 } 09743 ast_debug(3, "FaxMaxDatagram: %u\n", x); 09744 ast_udptl_set_far_max_datagram(p->udptl, x); 09745 found = TRUE; 09746 } else if ((strncmp(a, "T38FaxFillBitRemoval", 20) == 0)) { 09747 if (sscanf(a, "T38FaxFillBitRemoval:%30u", &x) == 1) { 09748 ast_debug(3, "FillBitRemoval: %d\n", x); 09749 if (x == 1) { 09750 p->t38.their_parms.fill_bit_removal = TRUE; 09751 } 09752 } else { 09753 ast_debug(3, "FillBitRemoval\n"); 09754 p->t38.their_parms.fill_bit_removal = TRUE; 09755 } 09756 found = TRUE; 09757 } else if ((strncmp(a, "T38FaxTranscodingMMR", 20) == 0)) { 09758 if (sscanf(a, "T38FaxTranscodingMMR:%30u", &x) == 1) { 09759 ast_debug(3, "Transcoding MMR: %d\n", x); 09760 if (x == 1) { 09761 p->t38.their_parms.transcoding_mmr = TRUE; 09762 } 09763 } else { 09764 ast_debug(3, "Transcoding MMR\n"); 09765 p->t38.their_parms.transcoding_mmr = TRUE; 09766 } 09767 found = TRUE; 09768 } else if ((strncmp(a, "T38FaxTranscodingJBIG", 21) == 0)) { 09769 if (sscanf(a, "T38FaxTranscodingJBIG:%30u", &x) == 1) { 09770 ast_debug(3, "Transcoding JBIG: %d\n", x); 09771 if (x == 1) { 09772 p->t38.their_parms.transcoding_jbig = TRUE; 09773 } 09774 } else { 09775 ast_debug(3, "Transcoding JBIG\n"); 09776 p->t38.their_parms.transcoding_jbig = TRUE; 09777 } 09778 found = TRUE; 09779 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 09780 ast_debug(3, "RateManagement: %s\n", s); 09781 if (!strcasecmp(s, "localTCF")) 09782 p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_LOCAL_TCF; 09783 else if (!strcasecmp(s, "transferredTCF")) 09784 p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF; 09785 found = TRUE; 09786 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 09787 ast_debug(3, "UDP EC: %s\n", s); 09788 if (!strcasecmp(s, "t38UDPRedundancy")) { 09789 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 09790 } else if (!strcasecmp(s, "t38UDPFEC")) { 09791 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 09792 } else { 09793 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 09794 } 09795 found = TRUE; 09796 } 09797 09798 return found; 09799 }
static int process_sdp_a_sendonly | ( | const char * | a, | |
int * | sendonly | |||
) | [static] |
Definition at line 9498 of file chan_sip.c.
Referenced by process_sdp().
09499 { 09500 int found = FALSE; 09501 09502 if (!strcasecmp(a, "sendonly")) { 09503 if (*sendonly == -1) 09504 *sendonly = 1; 09505 found = TRUE; 09506 } else if (!strcasecmp(a, "inactive")) { 09507 if (*sendonly == -1) 09508 *sendonly = 2; 09509 found = TRUE; 09510 } else if (!strcasecmp(a, "sendrecv")) { 09511 if (*sendonly == -1) 09512 *sendonly = 0; 09513 found = TRUE; 09514 } 09515 return found; 09516 }
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 9648 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().
09649 { 09650 int found = FALSE; 09651 int codec; 09652 char mimeSubtype[128]; 09653 unsigned int sample_rate; 09654 char *red_cp; 09655 int debug = sip_debug_test_pvt(p); 09656 09657 if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) { 09658 /* We have a rtpmap to handle */ 09659 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 09660 if (!strncasecmp(mimeSubtype, "T140", 4)) { /* Text */ 09661 if (p->trtp) { 09662 /* ast_verbose("Adding t140 mimeSubtype to textrtp struct\n"); */ 09663 ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate); 09664 found = TRUE; 09665 } 09666 } else if (!strncasecmp(mimeSubtype, "RED", 3)) { /* Text with Redudancy */ 09667 if (p->trtp) { 09668 ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate); 09669 sprintf(red_fmtp, "fmtp:%d ", codec); 09670 if (debug) 09671 ast_verbose("RED submimetype has payload type: %d\n", codec); 09672 found = TRUE; 09673 } 09674 } 09675 } else { 09676 if (debug) 09677 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 09678 } 09679 } else if (!strncmp(a, red_fmtp, strlen(red_fmtp))) { 09680 /* count numbers of generations in fmtp */ 09681 red_cp = &red_fmtp[strlen(red_fmtp)]; 09682 strncpy(red_fmtp, a, 100); 09683 09684 sscanf(red_cp, "%30u", &red_data_pt[*red_num_gen]); 09685 red_cp = strtok(red_cp, "/"); 09686 while (red_cp && (*red_num_gen)++ < AST_RED_MAX_GENERATION) { 09687 sscanf(red_cp, "%30u", &red_data_pt[*red_num_gen]); 09688 red_cp = strtok(NULL, "/"); 09689 } 09690 red_cp = red_fmtp; 09691 found = TRUE; 09692 } 09693 09694 return found; 09695 }
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 9614 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().
09615 { 09616 int found = FALSE; 09617 int codec; 09618 char mimeSubtype[128]; 09619 unsigned int sample_rate; 09620 int debug = sip_debug_test_pvt(p); 09621 09622 if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) { 09623 /* We have a rtpmap to handle */ 09624 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 09625 /* Note: should really look at the '#chans' params too */ 09626 if (!strncasecmp(mimeSubtype, "H26", 3) || !strncasecmp(mimeSubtype, "MP4", 3)) { 09627 if (!(ast_rtp_codecs_payloads_set_rtpmap_type_rate(newvideortp, NULL, codec, "video", mimeSubtype, 0, sample_rate))) { 09628 if (debug) 09629 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 09630 //found_rtpmap_codecs[last_rtpmap_codec] = codec; 09631 (*last_rtpmap_codec)++; 09632 found = TRUE; 09633 } else { 09634 ast_rtp_codecs_payloads_unset(newvideortp, NULL, codec); 09635 if (debug) 09636 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 09637 } 09638 } 09639 } else { 09640 if (debug) 09641 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 09642 } 09643 } 09644 09645 return found; 09646 }
static int process_sdp_c | ( | const char * | c, | |
struct ast_sockaddr * | addr | |||
) | [static] |
Definition at line 9471 of file chan_sip.c.
References ast_log(), ast_sockaddr_resolve_first_af(), FALSE, LOG_WARNING, and TRUE.
Referenced by process_sdp().
09472 { 09473 char proto[4], host[258]; 09474 int af; 09475 09476 /* Check for Media-description-level-address */ 09477 if (sscanf(c, "IN %3s %255s", proto, host) == 2) { 09478 if (!strcmp("IP4", proto)) { 09479 af = AF_INET; 09480 } else if (!strcmp("IP6", proto)) { 09481 af = AF_INET6; 09482 } else { 09483 ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto); 09484 return FALSE; 09485 } 09486 if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) { 09487 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in c= line, '%s'\n", c); 09488 return FALSE; 09489 } 09490 return TRUE; 09491 } else { 09492 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 09493 return FALSE; 09494 } 09495 return FALSE; 09496 }
static int process_sdp_o | ( | const char * | o, | |
struct sip_pvt * | p | |||
) | [static] |
Definition at line 9392 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().
09393 { 09394 char *o_copy; 09395 char *token; 09396 int64_t rua_version; 09397 09398 /* Store the SDP version number of remote UA. This will allow us to 09399 distinguish between session modifications and session refreshes. If 09400 the remote UA does not send an incremented SDP version number in a 09401 subsequent RE-INVITE then that means its not changing media session. 09402 The RE-INVITE may have been sent to update connected party, remote 09403 target or to refresh the session (Session-Timers). Asterisk must not 09404 change media session and increment its own version number in answer 09405 SDP in this case. */ 09406 09407 p->session_modify = TRUE; 09408 09409 if (ast_strlen_zero(o)) { 09410 ast_log(LOG_WARNING, "SDP syntax error. SDP without an o= line\n"); 09411 return FALSE; 09412 } 09413 09414 o_copy = ast_strdupa(o); 09415 token = strsep(&o_copy, " "); /* Skip username */ 09416 if (!o_copy) { 09417 ast_log(LOG_WARNING, "SDP syntax error in o= line username\n"); 09418 return FALSE; 09419 } 09420 token = strsep(&o_copy, " "); /* Skip session-id */ 09421 if (!o_copy) { 09422 ast_log(LOG_WARNING, "SDP syntax error in o= line session-id\n"); 09423 return FALSE; 09424 } 09425 token = strsep(&o_copy, " "); /* Version */ 09426 if (!o_copy) { 09427 ast_log(LOG_WARNING, "SDP syntax error in o= line\n"); 09428 return FALSE; 09429 } 09430 if (!sscanf(token, "%30" SCNd64, &rua_version)) { 09431 ast_log(LOG_WARNING, "SDP syntax error in o= line version\n"); 09432 return FALSE; 09433 } 09434 09435 /* we need to check the SDP version number the other end sent us; 09436 * our rules for deciding what to accept are a bit complex. 09437 * 09438 * 1) if 'ignoresdpversion' has been set for this dialog, then 09439 * we will just accept whatever they sent and assume it is 09440 * a modification of the session, even if it is not 09441 * 2) otherwise, if this is the first SDP we've seen from them 09442 * we accept it 09443 * 3) otherwise, if the new SDP version number is higher than the 09444 * old one, we accept it 09445 * 4) otherwise, if this SDP is in response to us requesting a switch 09446 * to T.38, we accept the SDP, but also generate a warning message 09447 * that this peer should have the 'ignoresdpversion' option set, 09448 * because it is not following the SDP offer/answer RFC; if we did 09449 * not request a switch to T.38, then we stop parsing the SDP, as it 09450 * has not changed from the previous version 09451 */ 09452 09453 if (ast_test_flag(&p->flags[1], SIP_PAGE2_IGNORESDPVERSION) || 09454 (p->sessionversion_remote < 0) || 09455 (p->sessionversion_remote < rua_version)) { 09456 p->sessionversion_remote = rua_version; 09457 } else { 09458 if (p->t38.state == T38_LOCAL_REINVITE) { 09459 p->sessionversion_remote = rua_version; 09460 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); 09461 } else { 09462 p->session_modify = FALSE; 09463 ast_debug(2, "Call %s responded to our reinvite without changing SDP version; ignoring SDP.\n", p->callid); 09464 return FALSE; 09465 } 09466 } 09467 09468 return TRUE; 09469 }
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 7799 of file chan_sip.c.
References addr_is_multicast(), ast_log(), ast_sockaddr_resolve_first(), ast_sockaddr_set_port, free_via(), get_header(), LOG_ERROR, LOG_WARNING, PARSE_PORT_FORBID, parse_via(), and sipsock.
Referenced by respprep().
07800 { 07801 struct sip_via *via = parse_via(get_header(req, "Via")); 07802 07803 if (!via) { 07804 ast_log(LOG_ERROR, "error processing via header\n"); 07805 return -1; 07806 } 07807 07808 if (via->maddr) { 07809 if (ast_sockaddr_resolve_first(&p->sa, via->maddr, PARSE_PORT_FORBID)) { 07810 ast_log(LOG_WARNING, "Can't find address for maddr '%s'\n", via->maddr); 07811 ast_log(LOG_ERROR, "error processing via header\n"); 07812 free_via(via); 07813 return -1; 07814 } 07815 07816 if (addr_is_multicast(&p->sa)) { 07817 setsockopt(sipsock, IPPROTO_IP, IP_MULTICAST_TTL, &via->ttl, sizeof(via->ttl)); 07818 } 07819 } 07820 07821 ast_sockaddr_set_port(&p->sa, via->port ? via->port : STANDARD_SIP_PORT); 07822 07823 free_via(via); 07824 return 0; 07825 }
static int proxy_update | ( | struct sip_proxy * | proxy | ) | [static] |
Resolve DNS srv name or host name in a sip_proxy structure
Definition at line 3091 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().
03092 { 03093 /* if it's actually an IP address and not a name, 03094 there's no need for a managed lookup */ 03095 if (!ast_sockaddr_parse(&proxy->ip, proxy->name, 0)) { 03096 /* Ok, not an IP address, then let's check if it's a domain or host */ 03097 /* XXX Todo - if we have proxy port, don't do SRV */ 03098 proxy->ip.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */ 03099 if (ast_get_ip_or_srv(&proxy->ip, proxy->name, sip_cfg.srvlookup ? "_sip._udp" : NULL) < 0) { 03100 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name); 03101 return FALSE; 03102 } 03103 03104 } 03105 03106 ast_sockaddr_set_port(&proxy->ip, proxy->port); 03107 03108 proxy->last_dnsupdate = time(NULL); 03109 return TRUE; 03110 }
static int publish_expire | ( | const void * | data | ) | [static] |
Definition at line 1020 of file chan_sip.c.
References ao2_ref, ao2_unlink, ast_assert, event_state_compositor::compositor, and get_esc().
Referenced by create_esc_entry(), handle_sip_publish_modify(), and handle_sip_publish_refresh().
01021 { 01022 struct sip_esc_entry *esc_entry = (struct sip_esc_entry *) data; 01023 struct event_state_compositor *esc = get_esc(esc_entry->event); 01024 01025 ast_assert(esc != NULL); 01026 01027 ao2_unlink(esc->compositor, esc_entry); 01028 ao2_ref(esc_entry, -1); 01029 return 0; 01030 }
static void pvt_set_needdestroy | ( | struct sip_pvt * | pvt, | |
const char * | reason | |||
) | [inline, static] |
Definition at line 3056 of file chan_sip.c.
References append_history.
Referenced by __sip_autodestruct(), handle_incoming(), handle_request_publish(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_notify(), handle_response_peerpoke(), handle_response_publish(), handle_response_refer(), handle_response_register(), handle_response_subscribe(), retrans_pkt(), sip_hangup(), and sip_reg_timeout().
03057 { 03058 if (pvt->final_destruction_scheduled) { 03059 return; /* This is already scheduled for final destruction, let the scheduler take care of it. */ 03060 } 03061 append_history(pvt, "NeedDestroy", "Setting needdestroy because %s", reason); 03062 pvt->needdestroy = 1; 03063 }
static struct sip_peer * realtime_peer | ( | const char * | newpeername, | |
struct ast_sockaddr * | addr, | |||
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 4930 of file chan_sip.c.
References ast_check_realtime(), ast_copy_string(), ast_sockaddr_stringify_addr(), cleanup(), ipaddr, ast_variable::name, ast_variable::next, realtime_peer_by_addr(), realtime_peer_by_name(), ast_variable::value, and var.
04931 { 04932 struct sip_peer *peer = NULL; 04933 struct ast_variable *var = NULL; 04934 struct ast_variable *varregs = NULL; 04935 char ipaddr[INET6_ADDRSTRLEN]; 04936 int realtimeregs = ast_check_realtime("sipregs"); 04937 04938 if (addr) { 04939 ast_copy_string(ipaddr, ast_sockaddr_stringify_addr(addr), sizeof(ipaddr)); 04940 } else { 04941 ipaddr[0] = '\0'; 04942 } 04943 04944 if (newpeername && realtime_peer_by_name(&newpeername, addr, ipaddr, &var, realtimeregs ? &varregs : NULL)) { 04945 ; 04946 } else if (addr && realtime_peer_by_addr(&newpeername, addr, ipaddr, &var, realtimeregs ? &varregs : NULL)) { 04947 ; 04948 } else { 04949 return NULL; 04950 } 04951 04952 /* If we're looking for users, don't return peers (although this check 04953 * should probably be done in realtime_peer_by_* instead...) */ 04954 if (which_objects == FINDUSERS) { 04955 struct ast_variable *tmp; 04956 for (tmp = var; tmp; tmp = tmp->next) { 04957 if (!strcasecmp(tmp->name, "type") && (!strcasecmp(tmp->value, "peer"))) { 04958 goto cleanup; 04959 } 04960 } 04961 } 04962 04963 /* Peer found in realtime, now build it in memory */ 04964 peer = build_peer(newpeername, var, varregs, TRUE, devstate_only); 04965 if (!peer) { 04966 goto cleanup; 04967 } 04968 04969 ast_debug(3, "-REALTIME- loading peer from database to memory. Name: %s. Peer objects: %d\n", peer->name, rpeerobjs); 04970 04971 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) { 04972 /* Cache peer */ 04973 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 04974 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 04975 AST_SCHED_REPLACE_UNREF(peer->expire, sched, sip_cfg.rtautoclear * 1000, expire_register, peer, 04976 unref_peer(_data, "remove registration ref"), 04977 unref_peer(peer, "remove registration ref"), 04978 ref_peer(peer, "add registration ref")); 04979 } 04980 ao2_t_link(peers, peer, "link peer into peers table"); 04981 if (!ast_sockaddr_isnull(&peer->addr)) { 04982 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 04983 } 04984 } 04985 peer->is_realtime = 1; 04986 04987 cleanup: 04988 ast_variables_destroy(var); 04989 ast_variables_destroy(varregs); 04990 return peer; 04991 }
static int realtime_peer_by_addr | ( | const char ** | name, | |
struct ast_sockaddr * | addr, | |||
const char * | ipaddr, | |||
struct ast_variable ** | var, | |||
struct ast_variable ** | varregs | |||
) | [static] |
Definition at line 4861 of file chan_sip.c.
References ast_copy_string(), ast_load_realtime(), ast_log(), ast_sockaddr_stringify_port(), ast_variables_destroy(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), get_name_from_variable(), LOG_WARNING, realtime_peer_get_sippeer_helper(), SENTINEL, and var.
Referenced by realtime_peer().
04862 { 04863 char portstring[6]; /* up to 5 digits plus null terminator */ 04864 ast_copy_string(portstring, ast_sockaddr_stringify_port(addr), sizeof(portstring)); 04865 04866 /* We're not finding this peer by this name anymore. Reset it. */ 04867 *name = NULL; 04868 04869 /* First check for fixed IP hosts */ 04870 if ((*var = ast_load_realtime("sippeers", "host", ipaddr, "port", portstring, SENTINEL))) { 04871 ; 04872 /* Check for registered hosts (in sipregs) */ 04873 } else if (varregs && (*varregs = ast_load_realtime("sipregs", "ipaddr", ipaddr, "port", portstring, SENTINEL)) && 04874 (*var = realtime_peer_get_sippeer_helper(name, varregs))) { 04875 ; 04876 /* Check for registered hosts (in sippeers) */ 04877 } else if (!varregs && (*var = ast_load_realtime("sippeers", "ipaddr", ipaddr, "port", portstring, SENTINEL))) { 04878 ; 04879 /* We couldn't match on ipaddress and port, so we need to check if port is insecure */ 04880 } else if ((*var = get_insecure_variable_from_sippeers("host", ipaddr))) { 04881 ; 04882 /* Same as above, but try the IP address field (in sipregs) 04883 * Observe that it fetches the name/var at the same time, without the 04884 * realtime_peer_get_sippeer_helper. Also note that it is quite inefficient. 04885 * Avoid sipregs if possible. */ 04886 } else if (varregs && (*varregs = get_insecure_variable_from_sipregs("ipaddr", ipaddr, var))) { 04887 ; 04888 /* Same as above, but try the IP address field (in sippeers) */ 04889 } else if (!varregs && (*var = get_insecure_variable_from_sippeers("ipaddr", ipaddr))) { 04890 ; 04891 } 04892 04893 /* Nothing found? */ 04894 if (!*var) { 04895 return 0; 04896 } 04897 04898 /* Check peer name. It must not be empty. There may exist a 04899 * different match that does have a name, but it's too late for 04900 * that now. */ 04901 if (!*name && !(*name = get_name_from_variable(*var))) { 04902 ast_log(LOG_WARNING, "Found peer for IP %s but it has no name\n", ipaddr); 04903 ast_variables_destroy(*var); 04904 *var = NULL; 04905 if (varregs && *varregs) { 04906 ast_variables_destroy(*varregs); 04907 *varregs = NULL; 04908 } 04909 return 0; 04910 } 04911 04912 /* Make sure varregs is populated if var is. The inverse, 04913 * ensuring that var is set when varregs is, is taken 04914 * care of by realtime_peer_get_sippeer_helper(). */ 04915 if (varregs && !*varregs) { 04916 *varregs = ast_load_realtime("sipregs", "name", *name, SENTINEL); 04917 } 04918 return 1; 04919 }
static int realtime_peer_by_name | ( | const char *const * | name, | |
struct ast_sockaddr * | addr, | |||
const char * | ipaddr, | |||
struct ast_variable ** | var, | |||
struct ast_variable ** | varregs | |||
) | [static] |
Definition at line 4789 of file chan_sip.c.
References ast_free, ast_load_realtime(), ast_sockaddr_cmp(), ast_sockaddr_resolve(), ast_variables_destroy(), bindaddr, get_address_family_filter(), ast_variable::name, ast_variable::next, PARSE_PORT_FORBID, SENTINEL, ast_variable::value, and var.
Referenced by realtime_peer().
04790 { 04791 /* Peer by name and host=dynamic */ 04792 if ((*var = ast_load_realtime("sippeers", "name", *name, "host", "dynamic", SENTINEL))) { 04793 ; 04794 /* Peer by name and host=IP */ 04795 } else if (addr && !(*var = ast_load_realtime("sippeers", "name", *name, "host", ipaddr, SENTINEL))) { 04796 ; 04797 /* Peer by name and host=HOSTNAME */ 04798 } else if ((*var = ast_load_realtime("sippeers", "name", *name, SENTINEL))) { 04799 /*!\note 04800 * If this one loaded something, then we need to ensure that the host 04801 * field matched. The only reason why we can't have this as a criteria 04802 * is because we only have the IP address and the host field might be 04803 * set as a name (and the reverse PTR might not match). 04804 */ 04805 if (addr) { 04806 struct ast_variable *tmp; 04807 for (tmp = *var; tmp; tmp = tmp->next) { 04808 if (!strcasecmp(tmp->name, "host")) { 04809 struct ast_sockaddr *addrs = NULL; 04810 04811 if (ast_sockaddr_resolve(&addrs, 04812 tmp->value, 04813 PARSE_PORT_FORBID, 04814 get_address_family_filter(&bindaddr)) <= 0 || 04815 ast_sockaddr_cmp(&addrs[0], addr)) { 04816 /* No match */ 04817 ast_variables_destroy(*var); 04818 *var = NULL; 04819 } 04820 ast_free(addrs); 04821 break; 04822 } 04823 } 04824 } 04825 } 04826 04827 /* Did we find anything? */ 04828 if (*var) { 04829 if (varregs) { 04830 *varregs = ast_load_realtime("sipregs", "name", *name, SENTINEL); 04831 } 04832 return 1; 04833 } 04834 return 0; 04835 }
static struct ast_variable* realtime_peer_get_sippeer_helper | ( | const char ** | name, | |
struct ast_variable ** | varregs | |||
) | [static] |
Definition at line 4843 of file chan_sip.c.
References ast_load_realtime(), ast_log(), ast_variables_destroy(), get_name_from_variable(), LOG_WARNING, SENTINEL, and var.
Referenced by realtime_peer_by_addr().
04843 { 04844 struct ast_variable *var = NULL; 04845 const char *old_name = *name; 04846 *name = get_name_from_variable(*varregs); 04847 if (!*name || !(var = ast_load_realtime("sippeers", "name", *name, SENTINEL))) { 04848 if (!*name) { 04849 ast_log(LOG_WARNING, "Found sipreg but it has no name\n"); 04850 } 04851 ast_variables_destroy(*varregs); 04852 *varregs = NULL; 04853 *name = old_name; 04854 } 04855 return var; 04856 }
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 4499 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.
04500 { 04501 char port[10]; 04502 char ipaddr[INET6_ADDRSTRLEN]; 04503 char regseconds[20]; 04504 char *tablename = NULL; 04505 char str_lastms[20]; 04506 04507 const char *sysname = ast_config_AST_SYSTEM_NAME; 04508 char *syslabel = NULL; 04509 04510 time_t nowtime = time(NULL) + expirey; 04511 const char *fc = fullcontact ? "fullcontact" : NULL; 04512 04513 int realtimeregs = ast_check_realtime("sipregs"); 04514 04515 tablename = realtimeregs ? "sipregs" : "sippeers"; 04516 04517 04518 snprintf(str_lastms, sizeof(str_lastms), "%d", lastms); 04519 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 04520 ast_copy_string(ipaddr, ast_sockaddr_stringify_addr(addr), sizeof(ipaddr)); 04521 ast_copy_string(port, ast_sockaddr_stringify_port(addr), sizeof(port)); 04522 04523 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 04524 sysname = NULL; 04525 else if (sip_cfg.rtsave_sysname) 04526 syslabel = "regserver"; 04527 04528 /* XXX IMPORTANT: Anytime you add a new parameter to be updated, you 04529 * must also add it to contrib/scripts/asterisk.ldap-schema, 04530 * contrib/scripts/asterisk.ldif, 04531 * and to configs/res_ldap.conf.sample as described in 04532 * bugs 15156 and 15895 04533 */ 04534 if (fc) { 04535 ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr, 04536 "port", port, "regseconds", regseconds, 04537 deprecated_username ? "username" : "defaultuser", defaultuser, 04538 "useragent", useragent, "lastms", str_lastms, 04539 fc, fullcontact, syslabel, sysname, SENTINEL); /* note fc and syslabel _can_ be NULL */ 04540 } else { 04541 ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr, 04542 "port", port, "regseconds", regseconds, 04543 "useragent", useragent, "lastms", str_lastms, 04544 deprecated_username ? "username" : "defaultuser", defaultuser, 04545 syslabel, sysname, SENTINEL); /* note syslabel _can_ be NULL */ 04546 } 04547 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 16253 of file chan_sip.c.
References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose, f, get_header(), get_msg_text(), LOG_WARNING, sip_debug_test_pvt(), sip_scheddestroy(), and transmit_response().
Referenced by handle_request_message().
16254 { 16255 char buf[1400]; 16256 char *bufp; 16257 struct ast_frame f; 16258 const char *content_type = get_header(req, "Content-Type"); 16259 16260 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 16261 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 16262 if (!p->owner) 16263 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16264 return; 16265 } 16266 16267 if (get_msg_text(buf, sizeof(buf), req)) { 16268 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 16269 transmit_response(p, "500 Internal Server Error", req); 16270 if (!p->owner) { 16271 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16272 } 16273 return; 16274 } 16275 16276 /* Strip trailing line feeds from message body. (get_msg_text may add 16277 * a trailing linefeed and we don't need any at the end) */ 16278 bufp = buf + strlen(buf); 16279 while (--bufp >= buf && *bufp == '\n') { 16280 *bufp = '\0'; 16281 } 16282 16283 if (p->owner) { 16284 if (sip_debug_test_pvt(p)) 16285 ast_verbose("SIP Text message received: '%s'\n", buf); 16286 memset(&f, 0, sizeof(f)); 16287 f.frametype = AST_FRAME_TEXT; 16288 f.subclass.integer = 0; 16289 f.offset = 0; 16290 f.data.ptr = buf; 16291 f.datalen = strlen(buf) + 1; 16292 ast_queue_frame(p->owner, &f); 16293 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 16294 return; 16295 } 16296 16297 /* Message outside of a call, we do not support that */ 16298 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); 16299 transmit_response(p, "405 Method Not Allowed", req); 16300 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16301 return; 16302 }
static struct sip_peer* ref_peer | ( | struct sip_peer * | peer, | |
char * | tag | |||
) | [static] |
Definition at line 2847 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().
02848 { 02849 ao2_t_ref(peer, 1, tag); 02850 return peer; 02851 }
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 2929 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().
02930 { 02931 struct sip_proxy *old_obproxy = pvt->outboundproxy; 02932 /* The sip_cfg.outboundproxy is statically allocated, and so 02933 * we don't ever need to adjust refcounts for it 02934 */ 02935 if (proxy && proxy != &sip_cfg.outboundproxy) { 02936 ao2_ref(proxy, +1); 02937 } 02938 pvt->outboundproxy = proxy; 02939 if (old_obproxy && old_obproxy != &sip_cfg.outboundproxy) { 02940 ao2_ref(old_obproxy, -1); 02941 } 02942 }
static const char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 3051 of file chan_sip.c.
References map_x_s(), and referstatusstrings.
Referenced by show_channels_cb().
03052 { 03053 return map_x_s(referstatusstrings, rstatus, ""); 03054 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 13759 of file chan_sip.c.
References args, AST_APP_ARG, ast_db_get(), ast_debug, AST_DECLARE_APP_ARGS, AST_NONSTANDARD_RAW_ARGS, ast_random(), AST_SCHED_REPLACE_UNREF, ast_sockaddr_copy(), ast_sockaddr_parse(), ast_sockaddr_stringify_host(), ast_string_field_set, expire_register(), ref_peer(), register_peer_exten(), sip_cfg, sip_poke_peer(), sip_poke_peer_s(), sipsock, TRUE, and unref_peer().
13760 { 13761 char data[256]; 13762 struct ast_sockaddr sa; 13763 int expire; 13764 char full_addr[128]; 13765 AST_DECLARE_APP_ARGS(args, 13766 AST_APP_ARG(addr); 13767 AST_APP_ARG(port); 13768 AST_APP_ARG(expiry_str); 13769 AST_APP_ARG(username); 13770 AST_APP_ARG(contact); 13771 ); 13772 13773 /* If read-only RT backend, then refresh from local DB cache */ 13774 if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) { 13775 return; 13776 } 13777 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) { 13778 return; 13779 } 13780 13781 AST_NONSTANDARD_RAW_ARGS(args, data, ':'); 13782 13783 snprintf(full_addr, sizeof(full_addr), "%s:%s", args.addr, args.port); 13784 13785 if (!ast_sockaddr_parse(&sa, full_addr, 0)) { 13786 return; 13787 } 13788 13789 if (args.expiry_str) { 13790 expire = atoi(args.expiry_str); 13791 } else { 13792 return; 13793 } 13794 13795 if (args.username) { 13796 ast_string_field_set(peer, username, args.username); 13797 } 13798 if (args.contact) { 13799 ast_string_field_set(peer, fullcontact, args.contact); 13800 } 13801 13802 ast_debug(2, "SIP Seeding peer from astdb: '%s' at %s@%s for %d\n", 13803 peer->name, peer->username, ast_sockaddr_stringify_host(&sa), expire); 13804 13805 ast_sockaddr_copy(&peer->addr, &sa); 13806 if (sipsock < 0) { 13807 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 13808 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer, 13809 unref_peer(_data, "removing poke peer ref"), 13810 unref_peer(peer, "removing poke peer ref"), 13811 ref_peer(peer, "adding poke peer ref")); 13812 } else { 13813 sip_poke_peer(peer, 0); 13814 } 13815 AST_SCHED_REPLACE_UNREF(peer->expire, sched, (expire + 10) * 1000, expire_register, peer, 13816 unref_peer(_data, "remove registration ref"), 13817 unref_peer(peer, "remove registration ref"), 13818 ref_peer(peer, "add registration ref")); 13819 register_peer_exten(peer, TRUE); 13820 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 4550 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().
04551 { 04552 char multi[256]; 04553 char *stringp, *ext, *context; 04554 struct pbx_find_info q = { .stacklen = 0 }; 04555 04556 /* XXX note that sip_cfg.regcontext is both a global 'enable' flag and 04557 * the name of the global regexten context, if not specified 04558 * individually. 04559 */ 04560 if (ast_strlen_zero(sip_cfg.regcontext)) 04561 return; 04562 04563 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 04564 stringp = multi; 04565 while ((ext = strsep(&stringp, "&"))) { 04566 if ((context = strchr(ext, '@'))) { 04567 *context++ = '\0'; /* split ext@context */ 04568 if (!ast_context_find(context)) { 04569 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 04570 continue; 04571 } 04572 } else { 04573 context = sip_cfg.regcontext; 04574 } 04575 if (onoff) { 04576 if (!ast_exists_extension(NULL, context, ext, 1, NULL)) { 04577 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 04578 ast_strdup(peer->name), ast_free_ptr, "SIP"); 04579 } 04580 } else if (pbx_find_extension(NULL, NULL, &q, context, ext, 1, NULL, "", E_MATCH)) { 04581 ast_context_remove_extension(context, ext, 1, NULL); 04582 } 04583 } 04584 }
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 14707 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(), EVENT_FLAG_SYSTEM, exten, extract_host_from_hostport(), FALSE, find_peer(), get_header(), get_in_brackets(), global_authfailureevents, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, name, parse_register_contact(), parse_uri_legacy_check(), 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().
14709 { 14710 enum check_auth_result res = AUTH_NOT_FOUND; 14711 struct sip_peer *peer; 14712 char tmp[256]; 14713 char *c, *name, *unused_password, *domain; 14714 char *uri2 = ast_strdupa(uri); 14715 14716 terminate_uri(uri2); 14717 14718 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 14719 14720 c = get_in_brackets(tmp); 14721 c = remove_uri_parameters(c); 14722 14723 if (parse_uri_legacy_check(c, "sip:,sips:", &name, &unused_password, &domain, NULL)) { 14724 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_sockaddr_stringify_addr(addr)); 14725 return -1; 14726 } 14727 14728 SIP_PEDANTIC_DECODE(name); 14729 SIP_PEDANTIC_DECODE(domain); 14730 14731 extract_host_from_hostport(&domain); 14732 14733 if (ast_strlen_zero(domain)) { 14734 /* <sip:name@[EMPTY]>, never good */ 14735 transmit_response(p, "404 Not found", &p->initreq); 14736 return AUTH_UNKNOWN_DOMAIN; 14737 } 14738 14739 if (ast_strlen_zero(name)) { 14740 /* <sip:[EMPTY][@]hostport>, unsure whether valid for 14741 * registration. RFC 3261, 10.2 states: 14742 * "The To header field and the Request-URI field typically 14743 * differ, as the former contains a user name." 14744 * But, Asterisk has always treated the domain-only uri as a 14745 * username: we allow admins to create accounts described by 14746 * domain name. */ 14747 name = domain; 14748 } 14749 14750 /* This here differs from 1.4 and 1.6: the domain matching ACLs were 14751 * skipped if it was a domain-only URI (used as username). Here we treat 14752 * <sip:hostport> as <sip:host@hostport> and won't forget to test the 14753 * domain ACLs against host. */ 14754 if (!AST_LIST_EMPTY(&domain_list)) { 14755 if (!check_sip_domain(domain, NULL, 0)) { 14756 if (sip_cfg.alwaysauthreject) { 14757 transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE); 14758 } else { 14759 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 14760 } 14761 return AUTH_UNKNOWN_DOMAIN; 14762 } 14763 } 14764 14765 ast_string_field_set(p, exten, name); 14766 build_contact(p); 14767 if (req->ignore) { 14768 /* Expires is a special case, where we only want to load the peer if this isn't a deregistration attempt */ 14769 const char *expires = get_header(req, "Expires"); 14770 int expire = atoi(expires); 14771 14772 if (ast_strlen_zero(expires)) { /* No expires header; look in Contact */ 14773 if ((expires = strcasestr(get_header(req, "Contact"), ";expires="))) { 14774 expire = atoi(expires + 9); 14775 } 14776 } 14777 if (!ast_strlen_zero(expires) && expire == 0) { 14778 transmit_response_with_date(p, "200 OK", req); 14779 return 0; 14780 } 14781 } 14782 peer = find_peer(name, NULL, TRUE, FINDPEERS, FALSE, 0); 14783 14784 if (!(peer && ast_apply_ha(peer->ha, addr))) { 14785 /* Peer fails ACL check */ 14786 if (peer) { 14787 unref_peer(peer, "register_verify: unref_peer: from find_peer operation"); 14788 peer = NULL; 14789 res = AUTH_ACL_FAILED; 14790 } else { 14791 res = AUTH_NOT_FOUND; 14792 } 14793 } 14794 14795 if (peer) { 14796 ao2_lock(peer); 14797 if (!peer->host_dynamic) { 14798 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 14799 res = AUTH_PEER_NOT_DYNAMIC; 14800 } else { 14801 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT_FORCE_RPORT); 14802 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri2, XMIT_UNRELIABLE, req->ignore))) { 14803 if (sip_cancel_destroy(p)) 14804 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 14805 14806 if (check_request_transport(peer, req)) { 14807 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 14808 transmit_response_with_date(p, "403 Forbidden", req); 14809 res = AUTH_BAD_TRANSPORT; 14810 } else { 14811 14812 /* We have a successful registration attempt with proper authentication, 14813 now, update the peer */ 14814 switch (parse_register_contact(p, peer, req)) { 14815 case PARSE_REGISTER_DENIED: 14816 ast_log(LOG_WARNING, "Registration denied because of contact ACL\n"); 14817 transmit_response_with_date(p, "603 Denied", req); 14818 peer->lastmsgssent = -1; 14819 res = 0; 14820 break; 14821 case PARSE_REGISTER_FAILED: 14822 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 14823 transmit_response_with_date(p, "400 Bad Request", req); 14824 peer->lastmsgssent = -1; 14825 res = 0; 14826 break; 14827 case PARSE_REGISTER_QUERY: 14828 ast_string_field_set(p, fullcontact, peer->fullcontact); 14829 transmit_response_with_date(p, "200 OK", req); 14830 peer->lastmsgssent = -1; 14831 res = 0; 14832 break; 14833 case PARSE_REGISTER_UPDATE: 14834 ast_string_field_set(p, fullcontact, peer->fullcontact); 14835 update_peer(peer, p->expiry); 14836 /* Say OK and ask subsystem to retransmit msg counter */ 14837 transmit_response_with_date(p, "200 OK", req); 14838 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 14839 peer->lastmsgssent = -1; 14840 res = 0; 14841 break; 14842 } 14843 } 14844 14845 } 14846 } 14847 ao2_unlock(peer); 14848 } 14849 if (!peer && sip_cfg.autocreatepeer) { 14850 /* Create peer if we have autocreate mode enabled */ 14851 peer = temp_peer(name); 14852 if (peer) { 14853 ao2_t_link(peers, peer, "link peer into peer table"); 14854 if (!ast_sockaddr_isnull(&peer->addr)) { 14855 ao2_t_link(peers_by_ip, peer, "link peer into peers-by-ip table"); 14856 } 14857 ao2_lock(peer); 14858 if (sip_cancel_destroy(p)) 14859 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 14860 switch (parse_register_contact(p, peer, req)) { 14861 case PARSE_REGISTER_DENIED: 14862 ast_log(LOG_WARNING, "Registration denied because of contact ACL\n"); 14863 transmit_response_with_date(p, "403 Forbidden (ACL)", req); 14864 peer->lastmsgssent = -1; 14865 res = 0; 14866 break; 14867 case PARSE_REGISTER_FAILED: 14868 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 14869 transmit_response_with_date(p, "400 Bad Request", req); 14870 peer->lastmsgssent = -1; 14871 res = 0; 14872 break; 14873 case PARSE_REGISTER_QUERY: 14874 ast_string_field_set(p, fullcontact, peer->fullcontact); 14875 transmit_response_with_date(p, "200 OK", req); 14876 peer->lastmsgssent = -1; 14877 res = 0; 14878 break; 14879 case PARSE_REGISTER_UPDATE: 14880 ast_string_field_set(p, fullcontact, peer->fullcontact); 14881 /* Say OK and ask subsystem to retransmit msg counter */ 14882 transmit_response_with_date(p, "200 OK", req); 14883 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)); 14884 peer->lastmsgssent = -1; 14885 res = 0; 14886 break; 14887 } 14888 ao2_unlock(peer); 14889 } 14890 } 14891 if (!res) { 14892 ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name); 14893 } 14894 if (res < 0) { 14895 switch (res) { 14896 case AUTH_SECRET_FAILED: 14897 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 14898 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 14899 if (global_authfailureevents) { 14900 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 14901 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 14902 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 14903 "ChannelType: SIP\r\n" 14904 "Peer: SIP/%s\r\n" 14905 "PeerStatus: Rejected\r\n" 14906 "Cause: AUTH_SECRET_FAILED\r\n" 14907 "Address: %s\r\n" 14908 "Port: %s\r\n", 14909 name, peer_addr, peer_port); 14910 } 14911 break; 14912 case AUTH_USERNAME_MISMATCH: 14913 /* Username and digest username does not match. 14914 Asterisk uses the From: username for authentication. We need the 14915 devices to use the same authentication user name until we support 14916 proper authentication by digest auth name */ 14917 case AUTH_NOT_FOUND: 14918 case AUTH_PEER_NOT_DYNAMIC: 14919 case AUTH_ACL_FAILED: 14920 if (sip_cfg.alwaysauthreject) { 14921 transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE); 14922 if (global_authfailureevents) { 14923 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 14924 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 14925 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 14926 "ChannelType: SIP\r\n" 14927 "Peer: SIP/%s\r\n" 14928 "PeerStatus: Rejected\r\n" 14929 "Cause: %s\r\n" 14930 "Address: %s\r\n" 14931 "Port: %s\r\n", 14932 name, 14933 res == AUTH_PEER_NOT_DYNAMIC ? "AUTH_PEER_NOT_DYNAMIC" : "URI_NOT_FOUND", 14934 peer_addr, peer_port); 14935 } 14936 } else { 14937 /* URI not found */ 14938 if (res == AUTH_PEER_NOT_DYNAMIC) { 14939 transmit_response(p, "403 Forbidden", &p->initreq); 14940 if (global_authfailureevents) { 14941 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 14942 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 14943 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 14944 "ChannelType: SIP\r\n" 14945 "Peer: SIP/%s\r\n" 14946 "PeerStatus: Rejected\r\n" 14947 "Cause: AUTH_PEER_NOT_DYNAMIC\r\n" 14948 "Address: %s\r\n" 14949 "Port: %s\r\n", 14950 name, peer_addr, peer_port); 14951 } 14952 } else { 14953 transmit_response(p, "404 Not found", &p->initreq); 14954 if (global_authfailureevents) { 14955 const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); 14956 const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); 14957 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 14958 "ChannelType: SIP\r\n" 14959 "Peer: SIP/%s\r\n" 14960 "PeerStatus: Rejected\r\n" 14961 "Cause: %s\r\n" 14962 "Address: %s\r\n" 14963 "Port: %s\r\n", 14964 name, 14965 (res == AUTH_USERNAME_MISMATCH) ? "AUTH_USERNAME_MISMATCH" : "URI_NOT_FOUND", 14966 peer_addr, peer_port); 14967 } 14968 } 14969 } 14970 break; 14971 case AUTH_BAD_TRANSPORT: 14972 default: 14973 break; 14974 } 14975 } 14976 if (peer) { 14977 unref_peer(peer, "register_verify: unref_peer: tossing stack peer pointer at end of func"); 14978 } 14979 14980 return res; 14981 }
static struct sip_registry* registry_addref | ( | struct sip_registry * | reg, | |
char * | tag | |||
) | [static] |
Add object reference to SIP registry.
Definition at line 3033 of file chan_sip.c.
References ast_debug, and ASTOBJ_REF.
Referenced by handle_response_register(), sip_send_all_registers(), and transmit_register().
03034 { 03035 ast_debug(3, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount + 1); 03036 return ASTOBJ_REF(reg); /* Add pointer to registry in packet */ 03037 }
void * registry_unref | ( | struct sip_registry * | reg, | |
char * | tag | |||
) | [static] |
Definition at line 3025 of file chan_sip.c.
References ast_debug, ASTOBJ_UNREF, and sip_registry_destroy().
Referenced by __sip_destroy(), cleanup_all_regs(), dialog_unlink_all(), handle_response_register(), sip_reg_timeout(), sip_register(), sip_registry_destroy(), sip_reregister(), sip_send_all_registers(), and transmit_register().
03026 { 03027 ast_debug(3, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount - 1); 03028 ASTOBJ_UNREF(reg, sip_registry_destroy); 03029 return NULL; 03030 }
static const char * regstate2str | ( | enum sipregistrystate | regstate | ) | const [static] |
Convert registration state status to string.
Definition at line 13031 of file chan_sip.c.
References map_x_s(), and regstatestrings.
13032 { 13033 return map_x_s(regstatestrings, regstate, "Unknown"); 13034 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 29601 of file chan_sip.c.
References sip_reload().
29602 { 29603 if (sip_reload(0, 0, NULL)) 29604 return 0; 29605 return 1; 29606 }
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
< Default to nat=force_rport
Definition at line 27868 of file chan_sip.c.
References ao2_t_callback, ao2_t_ref, AST_CERTFILE, ast_clear_flag, ast_config_AST_SYSTEM_NAME, ast_config_destroy(), ast_config_load, ast_copy_string(), ast_debug, AST_FLAGS_ALL, ast_free, ast_free_ha(), ast_get_version(), ast_jb_read_conf(), ast_log(), AST_MAX_CONTEXT, ast_mutex_lock, ast_mutex_unlock, ast_set_flag, ast_sockaddr_parse(), ast_strdup, ast_test_flag, ast_tls_read_conf(), ast_unload_realtime(), ast_variable_browse(), ASTOBJ_CONTAINER_DESTROYALL, authl, authl_lock, authlimit, authtimeout, bindaddr, ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, CHANNEL_MODULE_LOAD, ast_tls_config::cipher, cleanup_all_regs(), clear_sip_domains(), config, CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, context, DEFAULT_AUTHLIMIT, DEFAULT_AUTHTIMEOUT, default_callerid, DEFAULT_CONTEXT, default_engine, default_fromdomain, default_fromdomainport, default_jbconf, default_language, default_maxcallbitrate, default_mohinterpret, default_mohsuggest, default_mwi_from, default_notifymime, DEFAULT_PARKINGLOT, default_parkinglot, default_prefs, default_primary_transport, default_qualify, DEFAULT_REALM, default_tls_cfg, default_transports, default_vmexten, dummy(), dumphistory, ast_tls_config::enabled, externaddr, externexpire, externhost, externrefresh, externtcpport, externtlsport, FALSE, global_authfailureevents, global_autoframing, global_callcounter, global_cos_audio, global_cos_sip, global_cos_text, global_cos_video, global_dynamic_exclude_static, global_flags, global_jbconf, global_match_auth_username, global_max_se, global_min_se, global_prematuremediafilter, global_qualify_gap, global_qualify_peers, global_qualifyfreq, global_reg_timeout, global_regattempts_max, global_relaxdtmf, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_sdpowner, global_sdpsession, global_shrinkcallerid, global_st_mode, global_st_refresher, global_store_sip_cause, global_t1, global_t1min, global_t38_maxdatagram, global_timer_b, global_tos_audio, global_tos_sip, global_tos_text, global_tos_video, global_useragent, handle_common_options(), handle_t38_options(), internip, localaddr, LOG_ERROR, LOG_NOTICE, media_address, ast_variable::name, ast_variable::next, OBJ_NODATA, ourport_tcp, ourport_tls, peer_markall_func(), ast_tls_config::pvtfile, recordhistory, regl, S_OR, sip_cfg, sip_registry_destroy(), sip_tls_desc, TRUE, and ast_variable::value.
27869 { 27870 struct ast_config *cfg, *ucfg; 27871 struct ast_variable *v; 27872 struct sip_peer *peer; 27873 char *cat, *stringp, *context, *oldregcontext; 27874 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 27875 struct ast_flags dummy[2]; 27876 struct ast_flags config_flags = { reason == CHANNEL_MODULE_LOAD ? 0 : ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? 0 : CONFIG_FLAG_FILEUNCHANGED }; 27877 int auto_sip_domains = FALSE; 27878 struct ast_sockaddr old_bindaddr = bindaddr; 27879 int registry_count = 0, peer_count = 0, timerb_set = 0, timert1_set = 0; 27880 int subscribe_network_change = 1; 27881 time_t run_start, run_end; 27882 int bindport = 0; 27883 27884 run_start = time(0); 27885 ast_unload_realtime("sipregs"); 27886 ast_unload_realtime("sippeers"); 27887 cfg = ast_config_load(config, config_flags); 27888 27889 /* We *must* have a config file otherwise stop immediately */ 27890 if (!cfg) { 27891 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 27892 return -1; 27893 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 27894 ucfg = ast_config_load("users.conf", config_flags); 27895 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) { 27896 return 1; 27897 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 27898 ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n"); 27899 return 1; 27900 } 27901 /* Must reread both files, because one changed */ 27902 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 27903 if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) { 27904 ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config); 27905 ast_config_destroy(ucfg); 27906 return 1; 27907 } 27908 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 27909 ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config); 27910 return 1; 27911 } else { 27912 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 27913 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 27914 ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n"); 27915 ast_config_destroy(cfg); 27916 return 1; 27917 } 27918 } 27919 27920 ast_free_ha(sip_cfg.contact_ha); 27921 sip_cfg.contact_ha = NULL; 27922 27923 default_tls_cfg.enabled = FALSE; /* Default: Disable TLS */ 27924 27925 if (reason != CHANNEL_MODULE_LOAD) { 27926 ast_debug(4, "--------------- SIP reload started\n"); 27927 27928 clear_sip_domains(); 27929 ast_mutex_lock(&authl_lock); 27930 if (authl) { 27931 ao2_t_ref(authl, -1, "Removing old global authentication"); 27932 authl = NULL; 27933 } 27934 ast_mutex_unlock(&authl_lock); 27935 27936 27937 cleanup_all_regs(); 27938 /* Then, actually destroy users and registry */ 27939 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 27940 ast_debug(4, "--------------- Done destroying registry list\n"); 27941 ao2_t_callback(peers, OBJ_NODATA, peer_markall_func, NULL, "callback to mark all peers"); 27942 } 27943 27944 /* Reset certificate handling for TLS sessions */ 27945 if (reason != CHANNEL_MODULE_LOAD) { 27946 ast_free(default_tls_cfg.certfile); 27947 ast_free(default_tls_cfg.pvtfile); 27948 ast_free(default_tls_cfg.cipher); 27949 ast_free(default_tls_cfg.cafile); 27950 ast_free(default_tls_cfg.capath); 27951 } 27952 default_tls_cfg.certfile = ast_strdup(AST_CERTFILE); /*XXX Not sure if this is useful */ 27953 default_tls_cfg.pvtfile = ast_strdup(""); 27954 default_tls_cfg.cipher = ast_strdup(""); 27955 default_tls_cfg.cafile = ast_strdup(""); 27956 default_tls_cfg.capath = ast_strdup(""); 27957 27958 /* Initialize copy of current sip_cfg.regcontext for later use in removing stale contexts */ 27959 ast_copy_string(oldcontexts, sip_cfg.regcontext, sizeof(oldcontexts)); 27960 oldregcontext = oldcontexts; 27961 27962 /* Clear all flags before setting default values */ 27963 /* Preserve debugging settings for console */ 27964 sipdebug &= sip_debug_console; 27965 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 27966 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 27967 ast_clear_flag(&global_flags[2], AST_FLAGS_ALL); 27968 27969 /* Reset IP addresses */ 27970 ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0); 27971 memset(&internip, 0, sizeof(internip)); 27972 27973 /* Free memory for local network address mask */ 27974 ast_free_ha(localaddr); 27975 memset(&localaddr, 0, sizeof(localaddr)); 27976 memset(&externaddr, 0, sizeof(externaddr)); 27977 memset(&media_address, 0, sizeof(media_address)); 27978 memset(&default_prefs, 0 , sizeof(default_prefs)); 27979 memset(&sip_cfg.outboundproxy, 0, sizeof(struct sip_proxy)); 27980 sip_cfg.outboundproxy.force = FALSE; /*!< Don't force proxy usage, use route: headers */ 27981 default_transports = 0; /*!< Reset default transport to zero here, default value later on */ 27982 default_primary_transport = 0; /*!< Reset default primary transport to zero here, default value later on */ 27983 ourport_tcp = STANDARD_SIP_PORT; 27984 ourport_tls = STANDARD_TLS_PORT; 27985 externtcpport = STANDARD_SIP_PORT; 27986 externtlsport = STANDARD_TLS_PORT; 27987 sip_cfg.srvlookup = DEFAULT_SRVLOOKUP; 27988 global_tos_sip = DEFAULT_TOS_SIP; 27989 global_tos_audio = DEFAULT_TOS_AUDIO; 27990 global_tos_video = DEFAULT_TOS_VIDEO; 27991 global_tos_text = DEFAULT_TOS_TEXT; 27992 global_cos_sip = DEFAULT_COS_SIP; 27993 global_cos_audio = DEFAULT_COS_AUDIO; 27994 global_cos_video = DEFAULT_COS_VIDEO; 27995 global_cos_text = DEFAULT_COS_TEXT; 27996 27997 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 27998 externexpire = 0; /* Expiration for DNS re-issuing */ 27999 externrefresh = 10; 28000 28001 /* Reset channel settings to default before re-configuring */ 28002 sip_cfg.allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 28003 sip_cfg.regcontext[0] = '\0'; 28004 sip_cfg.capability = DEFAULT_CAPABILITY; 28005 sip_cfg.regextenonqualify = DEFAULT_REGEXTENONQUALIFY; 28006 sip_cfg.legacy_useroption_parsing = DEFAULT_LEGACY_USEROPTION_PARSING; 28007 sip_cfg.notifyringing = DEFAULT_NOTIFYRINGING; 28008 sip_cfg.notifycid = DEFAULT_NOTIFYCID; 28009 sip_cfg.notifyhold = FALSE; /*!< Keep track of hold status for a peer */ 28010 sip_cfg.directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 28011 sip_cfg.alwaysauthreject = DEFAULT_ALWAYSAUTHREJECT; 28012 sip_cfg.auth_options_requests = DEFAULT_AUTH_OPTIONS; 28013 sip_cfg.allowsubscribe = FALSE; 28014 sip_cfg.disallowed_methods = SIP_UNKNOWN; 28015 sip_cfg.contact_ha = NULL; /* Reset the contact ACL */ 28016 snprintf(global_useragent, sizeof(global_useragent), "%s %s", DEFAULT_USERAGENT, ast_get_version()); 28017 snprintf(global_sdpsession, sizeof(global_sdpsession), "%s %s", DEFAULT_SDPSESSION, ast_get_version()); 28018 snprintf(global_sdpowner, sizeof(global_sdpowner), "%s", DEFAULT_SDPOWNER); 28019 global_prematuremediafilter = TRUE; 28020 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 28021 ast_copy_string(sip_cfg.realm, S_OR(ast_config_AST_SYSTEM_NAME, DEFAULT_REALM), sizeof(sip_cfg.realm)); 28022 sip_cfg.domainsasrealm = DEFAULT_DOMAINSASREALM; 28023 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 28024 ast_copy_string(default_mwi_from, DEFAULT_MWI_FROM, sizeof(default_mwi_from)); 28025 sip_cfg.compactheaders = DEFAULT_COMPACTHEADERS; 28026 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 28027 global_regattempts_max = 0; 28028 sip_cfg.pedanticsipchecking = DEFAULT_PEDANTIC; 28029 sip_cfg.autocreatepeer = DEFAULT_AUTOCREATEPEER; 28030 global_autoframing = 0; 28031 sip_cfg.allowguest = DEFAULT_ALLOWGUEST; 28032 global_callcounter = DEFAULT_CALLCOUNTER; 28033 global_match_auth_username = FALSE; /*!< Match auth username if available instead of From: Default off. */ 28034 global_rtptimeout = 0; 28035 global_rtpholdtimeout = 0; 28036 global_rtpkeepalive = DEFAULT_RTPKEEPALIVE; 28037 sip_cfg.allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 28038 sip_cfg.rtautoclear = 120; 28039 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for all devices: TRUE */ 28040 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP_YES); /* Default for all devices: Yes */ 28041 sip_cfg.peer_rtupdate = TRUE; 28042 global_dynamic_exclude_static = 0; /* Exclude static peers */ 28043 sip_cfg.tcp_enabled = FALSE; 28044 28045 /* Session-Timers */ 28046 global_st_mode = SESSION_TIMER_MODE_ACCEPT; 28047 global_st_refresher = SESSION_TIMER_REFRESHER_UAS; 28048 global_min_se = DEFAULT_MIN_SE; 28049 global_max_se = DEFAULT_MAX_SE; 28050 28051 /* Peer poking settings */ 28052 global_qualify_gap = DEFAULT_QUALIFY_GAP; 28053 global_qualify_peers = DEFAULT_QUALIFY_PEERS; 28054 28055 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for devices */ 28056 ast_copy_string(sip_cfg.default_context, DEFAULT_CONTEXT, sizeof(sip_cfg.default_context)); 28057 sip_cfg.default_subscribecontext[0] = '\0'; 28058 sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS; 28059 default_language[0] = '\0'; 28060 default_fromdomain[0] = '\0'; 28061 default_fromdomainport = 0; 28062 default_qualify = DEFAULT_QUALIFY; 28063 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 28064 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 28065 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 28066 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 28067 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 28068 ast_set_flag(&global_flags[0], SIP_DIRECT_MEDIA); /*!< Allow re-invites */ 28069 ast_set_flag(&global_flags[0], SIP_NAT_FORCE_RPORT); /*!< Default to nat=force_rport */ 28070 ast_copy_string(default_engine, DEFAULT_ENGINE, sizeof(default_engine)); 28071 ast_copy_string(default_parkinglot, DEFAULT_PARKINGLOT, sizeof(default_parkinglot)); 28072 28073 /* Debugging settings, always default to off */ 28074 dumphistory = FALSE; 28075 recordhistory = FALSE; 28076 sipdebug &= ~sip_debug_config; 28077 28078 /* Misc settings for the channel */ 28079 global_relaxdtmf = FALSE; 28080 sip_cfg.callevents = DEFAULT_CALLEVENTS; 28081 global_authfailureevents = FALSE; 28082 global_t1 = DEFAULT_TIMER_T1; 28083 global_timer_b = 64 * DEFAULT_TIMER_T1; 28084 global_t1min = DEFAULT_T1MIN; 28085 global_qualifyfreq = DEFAULT_QUALIFYFREQ; 28086 global_t38_maxdatagram = -1; 28087 global_shrinkcallerid = 1; 28088 authlimit = DEFAULT_AUTHLIMIT; 28089 authtimeout = DEFAULT_AUTHTIMEOUT; 28090 global_store_sip_cause = DEFAULT_STORE_SIP_CAUSE; 28091 28092 sip_cfg.matchexternaddrlocally = DEFAULT_MATCHEXTERNADDRLOCALLY; 28093 28094 /* Copy the default jb config over global_jbconf */ 28095 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 28096 28097 ast_clear_flag(&global_flags[1], SIP_PAGE2_FAX_DETECT); 28098 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_VIDEOSUPPORT_ALWAYS); 28099 ast_clear_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT); 28100 ast_clear_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION); 28101 28102 28103 /* Read the [general] config section of sip.conf (or from realtime config) */ 28104 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 28105 if (handle_common_options(&global_flags[0], &dummy[0], v)) { 28106 continue; 28107 } 28108 if (handle_t38_options(&global_flags[0], &dummy[0], v, &global_t38_maxdatagram)) { 28109 continue; 28110 } 28111 /* handle jb conf */ 28112 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 28113 continue; 28114 28115 /* handle tls conf */ 28116 if (!ast_tls_read_conf(&default_tls_cfg, &sip_tls_desc, v->name, v->value)) { 28117 continue; 28118 } 28119 28120 if (!strcasecmp(v->name, "context")) { 28121 ast_copy_string(sip_cfg.default_context, v->value, sizeof(sip_cfg.default_context)); 28122 } else if (!strcasecmp(v->name, "subscribecontext")) { 28123 ast_copy_string(sip_cfg.default_subscribecontext, v->value, sizeof(sip_cfg.default_subscribecontext)); 28124 } else if (!strcasecmp(v->name, "callcounter")) { 28125 global_callcounter = ast_true(v->value) ? 1 : 0; 28126 } else if (!strcasecmp(v->name, "allowguest")) { 28127 sip_cfg.allowguest = ast_true(v->value) ? 1 : 0; 28128 } else if (!strcasecmp(v->name, "realm")) { 28129 ast_copy_string(sip_cfg.realm, v->value, sizeof(sip_cfg.realm)); 28130 } else if (!strcasecmp(v->name, "domainsasrealm")) { 28131 sip_cfg.domainsasrealm = ast_true(v->value); 28132 } else if (!strcasecmp(v->name, "useragent")) { 28133 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 28134 ast_debug(1, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 28135 } else if (!strcasecmp(v->name, "sdpsession")) { 28136 ast_copy_string(global_sdpsession, v->value, sizeof(global_sdpsession)); 28137 } else if (!strcasecmp(v->name, "sdpowner")) { 28138 /* Field cannot contain spaces */ 28139 if (!strstr(v->value, " ")) { 28140 ast_copy_string(global_sdpowner, v->value, sizeof(global_sdpowner)); 28141 } else { 28142 ast_log(LOG_WARNING, "'%s' must not contain spaces at line %d. Using default.\n", v->value, v->lineno); 28143 } 28144 } else if (!strcasecmp(v->name, "allowtransfer")) { 28145 sip_cfg.allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 28146 } else if (!strcasecmp(v->name, "rtcachefriends")) { 28147 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 28148 } else if (!strcasecmp(v->name, "rtsavesysname")) { 28149 sip_cfg.rtsave_sysname = ast_true(v->value); 28150 } else if (!strcasecmp(v->name, "rtupdate")) { 28151 sip_cfg.peer_rtupdate = ast_true(v->value); 28152 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 28153 sip_cfg.ignore_regexpire = ast_true(v->value); 28154 } else if (!strcasecmp(v->name, "timert1")) { 28155 /* Defaults to 500ms, but RFC 3261 states that it is recommended 28156 * for the value to be set higher, though a lower value is only 28157 * allowed on private networks unconnected to the Internet. */ 28158 global_t1 = atoi(v->value); 28159 } else if (!strcasecmp(v->name, "timerb")) { 28160 int tmp = atoi(v->value); 28161 if (tmp < 500) { 28162 global_timer_b = global_t1 * 64; 28163 ast_log(LOG_WARNING, "Invalid value for timerb ('%s'). Setting to default ('%d').\n", v->value, global_timer_b); 28164 } 28165 timerb_set = 1; 28166 } else if (!strcasecmp(v->name, "t1min")) { 28167 global_t1min = atoi(v->value); 28168 } else if (!strcasecmp(v->name, "transport") && !ast_strlen_zero(v->value)) { 28169 char *val = ast_strdupa(v->value); 28170 char *trans; 28171 28172 while ((trans = strsep(&val, ","))) { 28173 trans = ast_skip_blanks(trans); 28174 28175 if (!strncasecmp(trans, "udp", 3)) { 28176 default_transports |= SIP_TRANSPORT_UDP; 28177 } else if (!strncasecmp(trans, "tcp", 3)) { 28178 default_transports |= SIP_TRANSPORT_TCP; 28179 } else if (!strncasecmp(trans, "tls", 3)) { 28180 default_transports |= SIP_TRANSPORT_TLS; 28181 } else { 28182 ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, udp will be used.\n", trans); 28183 } 28184 if (default_primary_transport == 0) { 28185 default_primary_transport = default_transports; 28186 } 28187 } 28188 } else if (!strcasecmp(v->name, "tcpenable")) { 28189 if (!ast_false(v->value)) { 28190 ast_debug(2, "Enabling TCP socket for listening\n"); 28191 sip_cfg.tcp_enabled = TRUE; 28192 } 28193 } else if (!strcasecmp(v->name, "tcpbindaddr")) { 28194 if (ast_parse_arg(v->value, PARSE_ADDR, 28195 &sip_tcp_desc.local_address)) { 28196 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", 28197 v->name, v->value, v->lineno, config); 28198 } 28199 ast_debug(2, "Setting TCP socket address to %s\n", 28200 ast_sockaddr_stringify(&sip_tcp_desc.local_address)); 28201 } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) { 28202 global_dynamic_exclude_static = ast_true(v->value); 28203 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 28204 int ha_error = 0; 28205 sip_cfg.contact_ha = ast_append_ha(v->name + 7, v->value, sip_cfg.contact_ha, &ha_error); 28206 if (ha_error) { 28207 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 28208 } 28209 } else if (!strcasecmp(v->name, "rtautoclear")) { 28210 int i = atoi(v->value); 28211 if (i > 0) { 28212 sip_cfg.rtautoclear = i; 28213 } else { 28214 i = 0; 28215 } 28216 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 28217 } else if (!strcasecmp(v->name, "usereqphone")) { 28218 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 28219 } else if (!strcasecmp(v->name, "prematuremedia")) { 28220 global_prematuremediafilter = ast_true(v->value); 28221 } else if (!strcasecmp(v->name, "relaxdtmf")) { 28222 global_relaxdtmf = ast_true(v->value); 28223 } else if (!strcasecmp(v->name, "vmexten")) { 28224 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 28225 } else if (!strcasecmp(v->name, "rtptimeout")) { 28226 if ((sscanf(v->value, "%30d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 28227 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 28228 global_rtptimeout = 0; 28229 } 28230 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 28231 if ((sscanf(v->value, "%30d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 28232 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 28233 global_rtpholdtimeout = 0; 28234 } 28235 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 28236 if ((sscanf(v->value, "%30d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 28237 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 28238 global_rtpkeepalive = DEFAULT_RTPKEEPALIVE; 28239 } 28240 } else if (!strcasecmp(v->name, "compactheaders")) { 28241 sip_cfg.compactheaders = ast_true(v->value); 28242 } else if (!strcasecmp(v->name, "notifymimetype")) { 28243 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 28244 } else if (!strcasecmp(v->name, "directrtpsetup")) { 28245 sip_cfg.directrtpsetup = ast_true(v->value); 28246 } else if (!strcasecmp(v->name, "notifyringing")) { 28247 sip_cfg.notifyringing = ast_true(v->value); 28248 } else if (!strcasecmp(v->name, "notifyhold")) { 28249 sip_cfg.notifyhold = ast_true(v->value); 28250 } else if (!strcasecmp(v->name, "notifycid")) { 28251 if (!strcasecmp(v->value, "ignore-context")) { 28252 sip_cfg.notifycid = IGNORE_CONTEXT; 28253 } else { 28254 sip_cfg.notifycid = ast_true(v->value) ? ENABLED : DISABLED; 28255 } 28256 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 28257 sip_cfg.alwaysauthreject = ast_true(v->value); 28258 } else if (!strcasecmp(v->name, "auth_options_requests")) { 28259 if (ast_true(v->value)) { 28260 sip_cfg.auth_options_requests = 1; 28261 } 28262 } else if (!strcasecmp(v->name, "mohinterpret")) { 28263 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 28264 } else if (!strcasecmp(v->name, "mohsuggest")) { 28265 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 28266 } else if (!strcasecmp(v->name, "language")) { 28267 ast_copy_string(default_language, v->value, sizeof(default_language)); 28268 } else if (!strcasecmp(v->name, "regcontext")) { 28269 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 28270 stringp = newcontexts; 28271 /* Let's remove any contexts that are no longer defined in regcontext */ 28272 cleanup_stale_contexts(stringp, oldregcontext); 28273 /* Create contexts if they don't exist already */ 28274 while ((context = strsep(&stringp, "&"))) { 28275 ast_copy_string(used_context, context, sizeof(used_context)); 28276 ast_context_find_or_create(NULL, NULL, context, "SIP"); 28277 } 28278 ast_copy_string(sip_cfg.regcontext, v->value, sizeof(sip_cfg.regcontext)); 28279 } else if (!strcasecmp(v->name, "regextenonqualify")) { 28280 sip_cfg.regextenonqualify = ast_true(v->value); 28281 } else if (!strcasecmp(v->name, "legacy_useroption_parsing")) { 28282 sip_cfg.legacy_useroption_parsing = ast_true(v->value); 28283 } else if (!strcasecmp(v->name, "callerid")) { 28284 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 28285 } else if (!strcasecmp(v->name, "mwi_from")) { 28286 ast_copy_string(default_mwi_from, v->value, sizeof(default_mwi_from)); 28287 } else if (!strcasecmp(v->name, "fromdomain")) { 28288 char *fromdomainport; 28289 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 28290 if ((fromdomainport = strchr(default_fromdomain, ':'))) { 28291 *fromdomainport++ = '\0'; 28292 if (!(default_fromdomainport = port_str2int(fromdomainport, 0))) { 28293 ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport); 28294 } 28295 } else { 28296 default_fromdomainport = STANDARD_SIP_PORT; 28297 } 28298 } else if (!strcasecmp(v->name, "outboundproxy")) { 28299 char *tok, *proxyname; 28300 28301 if (ast_strlen_zero(v->value)) { 28302 ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf.", v->lineno); 28303 continue; 28304 } 28305 28306 tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ",")); 28307 28308 sip_parse_host(tok, v->lineno, &proxyname, 28309 &sip_cfg.outboundproxy.port, 28310 &sip_cfg.outboundproxy.transport); 28311 28312 if ((tok = strtok(NULL, ","))) { 28313 sip_cfg.outboundproxy.force = !strncasecmp(ast_skip_blanks(tok), "force", 5); 28314 } else { 28315 sip_cfg.outboundproxy.force = FALSE; 28316 } 28317 28318 if (ast_strlen_zero(proxyname)) { 28319 ast_log(LOG_WARNING, "you must specify a name for the outboundproxy on line %d of sip.conf.", v->lineno); 28320 sip_cfg.outboundproxy.name[0] = '\0'; 28321 continue; 28322 } 28323 28324 ast_copy_string(sip_cfg.outboundproxy.name, proxyname, sizeof(sip_cfg.outboundproxy.name)); 28325 28326 proxy_update(&sip_cfg.outboundproxy); 28327 } else if (!strcasecmp(v->name, "autocreatepeer")) { 28328 sip_cfg.autocreatepeer = ast_true(v->value); 28329 } else if (!strcasecmp(v->name, "match_auth_username")) { 28330 global_match_auth_username = ast_true(v->value); 28331 } else if (!strcasecmp(v->name, "srvlookup")) { 28332 sip_cfg.srvlookup = ast_true(v->value); 28333 } else if (!strcasecmp(v->name, "pedantic")) { 28334 sip_cfg.pedanticsipchecking = ast_true(v->value); 28335 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 28336 max_expiry = atoi(v->value); 28337 if (max_expiry < 1) { 28338 max_expiry = DEFAULT_MAX_EXPIRY; 28339 } 28340 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 28341 min_expiry = atoi(v->value); 28342 if (min_expiry < 1) { 28343 min_expiry = DEFAULT_MIN_EXPIRY; 28344 } 28345 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 28346 default_expiry = atoi(v->value); 28347 if (default_expiry < 1) { 28348 default_expiry = DEFAULT_DEFAULT_EXPIRY; 28349 } 28350 } else if (!strcasecmp(v->name, "mwiexpiry") || !strcasecmp(v->name, "mwiexpirey")) { 28351 mwi_expiry = atoi(v->value); 28352 if (mwi_expiry < 1) { 28353 mwi_expiry = DEFAULT_MWI_EXPIRY; 28354 } 28355 } else if (!strcasecmp(v->name, "tcpauthtimeout")) { 28356 if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE, 28357 &authtimeout, DEFAULT_AUTHTIMEOUT, 1, INT_MAX)) { 28358 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", 28359 v->name, v->value, v->lineno, config); 28360 } 28361 } else if (!strcasecmp(v->name, "tcpauthlimit")) { 28362 if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE, 28363 &authlimit, DEFAULT_AUTHLIMIT, 1, INT_MAX)) { 28364 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", 28365 v->name, v->value, v->lineno, config); 28366 } 28367 } else if (!strcasecmp(v->name, "sipdebug")) { 28368 if (ast_true(v->value)) 28369 sipdebug |= sip_debug_config; 28370 } else if (!strcasecmp(v->name, "dumphistory")) { 28371 dumphistory = ast_true(v->value); 28372 } else if (!strcasecmp(v->name, "recordhistory")) { 28373 recordhistory = ast_true(v->value); 28374 } else if (!strcasecmp(v->name, "registertimeout")) { 28375 global_reg_timeout = atoi(v->value); 28376 if (global_reg_timeout < 1) { 28377 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 28378 } 28379 } else if (!strcasecmp(v->name, "registerattempts")) { 28380 global_regattempts_max = atoi(v->value); 28381 } else if (!strcasecmp(v->name, "bindaddr") || !strcasecmp(v->name, "udpbindaddr")) { 28382 if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) { 28383 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 28384 } 28385 } else if (!strcasecmp(v->name, "localnet")) { 28386 struct ast_ha *na; 28387 int ha_error = 0; 28388 28389 if (!(na = ast_append_ha("d", v->value, localaddr, &ha_error))) { 28390 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 28391 } else { 28392 localaddr = na; 28393 } 28394 if (ha_error) { 28395 ast_log(LOG_ERROR, "Bad localnet configuration value line %d : %s\n", v->lineno, v->value); 28396 } 28397 } else if (!strcasecmp(v->name, "media_address")) { 28398 if (ast_parse_arg(v->value, PARSE_ADDR, &media_address)) 28399 ast_log(LOG_WARNING, "Invalid address for media_address keyword: %s\n", v->value); 28400 } else if (!strcasecmp(v->name, "externaddr") || !strcasecmp(v->name, "externip")) { 28401 if (ast_parse_arg(v->value, PARSE_ADDR, &externaddr)) { 28402 ast_log(LOG_WARNING, 28403 "Invalid address for externaddr keyword: %s\n", 28404 v->value); 28405 } 28406 externexpire = 0; 28407 } else if (!strcasecmp(v->name, "externhost")) { 28408 ast_copy_string(externhost, v->value, sizeof(externhost)); 28409 if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) { 28410 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 28411 } 28412 externexpire = time(NULL); 28413 } else if (!strcasecmp(v->name, "externrefresh")) { 28414 if (sscanf(v->value, "%30d", &externrefresh) != 1) { 28415 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 28416 externrefresh = 10; 28417 } 28418 } else if (!strcasecmp(v->name, "externtcpport")) { 28419 if (!(externtcpport = port_str2int(v->value, 0))) { 28420 ast_log(LOG_WARNING, "Invalid externtcpport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno); 28421 externtcpport = 0; 28422 } 28423 } else if (!strcasecmp(v->name, "externtlsport")) { 28424 if (!(externtlsport = port_str2int(v->value, STANDARD_TLS_PORT))) { 28425 ast_log(LOG_WARNING, "Invalid externtlsport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno); 28426 } 28427 } else if (!strcasecmp(v->name, "allow")) { 28428 int error = ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, TRUE); 28429 if (error) { 28430 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 28431 } 28432 } else if (!strcasecmp(v->name, "disallow")) { 28433 int error = ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, FALSE); 28434 if (error) { 28435 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 28436 } 28437 } else if (!strcasecmp(v->name, "preferred_codec_only")) { 28438 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC); 28439 } else if (!strcasecmp(v->name, "autoframing")) { 28440 global_autoframing = ast_true(v->value); 28441 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 28442 sip_cfg.allow_external_domains = ast_true(v->value); 28443 } else if (!strcasecmp(v->name, "autodomain")) { 28444 auto_sip_domains = ast_true(v->value); 28445 } else if (!strcasecmp(v->name, "domain")) { 28446 char *domain = ast_strdupa(v->value); 28447 char *cntx = strchr(domain, ','); 28448 28449 if (cntx) { 28450 *cntx++ = '\0'; 28451 } 28452 28453 if (ast_strlen_zero(cntx)) { 28454 ast_debug(1, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 28455 } 28456 if (ast_strlen_zero(domain)) { 28457 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 28458 } else { 28459 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, cntx ? ast_strip(cntx) : ""); 28460 } 28461 } else if (!strcasecmp(v->name, "register")) { 28462 if (sip_register(v->value, v->lineno) == 0) { 28463 registry_count++; 28464 } 28465 } else if (!strcasecmp(v->name, "mwi")) { 28466 sip_subscribe_mwi(v->value, v->lineno); 28467 } else if (!strcasecmp(v->name, "tos_sip")) { 28468 if (ast_str2tos(v->value, &global_tos_sip)) { 28469 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, refer to QoS documentation\n", v->lineno); 28470 } 28471 } else if (!strcasecmp(v->name, "tos_audio")) { 28472 if (ast_str2tos(v->value, &global_tos_audio)) { 28473 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno); 28474 } 28475 } else if (!strcasecmp(v->name, "tos_video")) { 28476 if (ast_str2tos(v->value, &global_tos_video)) { 28477 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, refer to QoS documentation\n", v->lineno); 28478 } 28479 } else if (!strcasecmp(v->name, "tos_text")) { 28480 if (ast_str2tos(v->value, &global_tos_text)) { 28481 ast_log(LOG_WARNING, "Invalid tos_text value at line %d, refer to QoS documentation\n", v->lineno); 28482 } 28483 } else if (!strcasecmp(v->name, "cos_sip")) { 28484 if (ast_str2cos(v->value, &global_cos_sip)) { 28485 ast_log(LOG_WARNING, "Invalid cos_sip value at line %d, refer to QoS documentation\n", v->lineno); 28486 } 28487 } else if (!strcasecmp(v->name, "cos_audio")) { 28488 if (ast_str2cos(v->value, &global_cos_audio)) { 28489 ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno); 28490 } 28491 } else if (!strcasecmp(v->name, "cos_video")) { 28492 if (ast_str2cos(v->value, &global_cos_video)) { 28493 ast_log(LOG_WARNING, "Invalid cos_video value at line %d, refer to QoS documentation\n", v->lineno); 28494 } 28495 } else if (!strcasecmp(v->name, "cos_text")) { 28496 if (ast_str2cos(v->value, &global_cos_text)) { 28497 ast_log(LOG_WARNING, "Invalid cos_text value at line %d, refer to QoS documentation\n", v->lineno); 28498 } 28499 } else if (!strcasecmp(v->name, "bindport")) { 28500 if (sscanf(v->value, "%5d", &bindport) != 1) { 28501 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 28502 } 28503 } else if (!strcasecmp(v->name, "qualify")) { 28504 if (!strcasecmp(v->value, "no")) { 28505 default_qualify = 0; 28506 } else if (!strcasecmp(v->value, "yes")) { 28507 default_qualify = DEFAULT_MAXMS; 28508 } else if (sscanf(v->value, "%30d", &default_qualify) != 1) { 28509 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 28510 default_qualify = 0; 28511 } 28512 } else if (!strcasecmp(v->name, "qualifyfreq")) { 28513 int i; 28514 if (sscanf(v->value, "%30d", &i) == 1) { 28515 global_qualifyfreq = i * 1000; 28516 } else { 28517 ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config); 28518 global_qualifyfreq = DEFAULT_QUALIFYFREQ; 28519 } 28520 } else if (!strcasecmp(v->name, "callevents")) { 28521 sip_cfg.callevents = ast_true(v->value); 28522 } else if (!strcasecmp(v->name, "authfailureevents")) { 28523 global_authfailureevents = ast_true(v->value); 28524 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 28525 default_maxcallbitrate = atoi(v->value); 28526 if (default_maxcallbitrate < 0) 28527 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 28528 } else if (!strcasecmp(v->name, "matchexternaddrlocally") || !strcasecmp(v->name, "matchexterniplocally")) { 28529 sip_cfg.matchexternaddrlocally = ast_true(v->value); 28530 } else if (!strcasecmp(v->name, "session-timers")) { 28531 int i = (int) str2stmode(v->value); 28532 if (i < 0) { 28533 ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config); 28534 global_st_mode = SESSION_TIMER_MODE_ACCEPT; 28535 } else { 28536 global_st_mode = i; 28537 } 28538 } else if (!strcasecmp(v->name, "session-expires")) { 28539 if (sscanf(v->value, "%30d", &global_max_se) != 1) { 28540 ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config); 28541 global_max_se = DEFAULT_MAX_SE; 28542 } 28543 } else if (!strcasecmp(v->name, "session-minse")) { 28544 if (sscanf(v->value, "%30d", &global_min_se) != 1) { 28545 ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config); 28546 global_min_se = DEFAULT_MIN_SE; 28547 } 28548 if (global_min_se < 90) { 28549 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); 28550 global_min_se = DEFAULT_MIN_SE; 28551 } 28552 } else if (!strcasecmp(v->name, "session-refresher")) { 28553 int i = (int) str2strefresher(v->value); 28554 if (i < 0) { 28555 ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config); 28556 global_st_refresher = SESSION_TIMER_REFRESHER_UAS; 28557 } else { 28558 global_st_refresher = i; 28559 } 28560 } else if (!strcasecmp(v->name, "storesipcause")) { 28561 global_store_sip_cause = ast_true(v->value); 28562 } else if (!strcasecmp(v->name, "qualifygap")) { 28563 if (sscanf(v->value, "%30d", &global_qualify_gap) != 1) { 28564 ast_log(LOG_WARNING, "Invalid qualifygap '%s' at line %d of %s\n", v->value, v->lineno, config); 28565 global_qualify_gap = DEFAULT_QUALIFY_GAP; 28566 } 28567 } else if (!strcasecmp(v->name, "qualifypeers")) { 28568 if (sscanf(v->value, "%30d", &global_qualify_peers) != 1) { 28569 ast_log(LOG_WARNING, "Invalid pokepeers '%s' at line %d of %s\n", v->value, v->lineno, config); 28570 global_qualify_peers = DEFAULT_QUALIFY_PEERS; 28571 } 28572 } else if (!strcasecmp(v->name, "disallowed_methods")) { 28573 char *disallow = ast_strdupa(v->value); 28574 mark_parsed_methods(&sip_cfg.disallowed_methods, disallow); 28575 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 28576 if (ast_true(v->value)) { 28577 global_shrinkcallerid = 1; 28578 } else if (ast_false(v->value)) { 28579 global_shrinkcallerid = 0; 28580 } else { 28581 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 28582 } 28583 } else if (!strcasecmp(v->name, "use_q850_reason")) { 28584 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON); 28585 } else if (!strcasecmp(v->name, "maxforwards")) { 28586 if ((sscanf(v->value, "%30d", &sip_cfg.default_max_forwards) != 1) || (sip_cfg.default_max_forwards < 1)) { 28587 ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d. Using default.\n", v->value, v->lineno); 28588 sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS; 28589 } 28590 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) { 28591 if (ast_true(v->value)) { 28592 subscribe_network_change = 1; 28593 } else if (ast_false(v->value)) { 28594 subscribe_network_change = 0; 28595 } else { 28596 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno); 28597 } 28598 } else if (!strcasecmp(v->name, "snom_aoc_enabled")) { 28599 ast_set2_flag(&global_flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC); 28600 } else if (!strcasecmp(v->name, "parkinglot")) { 28601 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot)); 28602 } 28603 } 28604 28605 if (subscribe_network_change) { 28606 network_change_event_subscribe(); 28607 } else { 28608 network_change_event_unsubscribe(); 28609 } 28610 28611 if (global_t1 < global_t1min) { 28612 ast_log(LOG_WARNING, "'t1min' (%d) cannot be greater than 't1timer' (%d). Resetting 't1timer' to the value of 't1min'\n", global_t1min, global_t1); 28613 global_t1 = global_t1min; 28614 } 28615 28616 if (global_timer_b < global_t1 * 64) { 28617 if (timerb_set && timert1_set) { 28618 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); 28619 } else if (timerb_set) { 28620 if ((global_t1 = global_timer_b / 64) < global_t1min) { 28621 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); 28622 global_t1 = global_t1min; 28623 global_timer_b = global_t1 * 64; 28624 } 28625 } else { 28626 global_timer_b = global_t1 * 64; 28627 } 28628 } 28629 if (!sip_cfg.allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 28630 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 28631 sip_cfg.allow_external_domains = 1; 28632 } 28633 /* If not or badly configured, set default transports */ 28634 if (!sip_cfg.tcp_enabled && (default_transports & SIP_TRANSPORT_TCP)) { 28635 ast_log(LOG_WARNING, "Cannot use 'tcp' transport with tcpenable=no. Removing from available transports.\n"); 28636 default_primary_transport &= ~SIP_TRANSPORT_TCP; 28637 default_transports &= ~SIP_TRANSPORT_TCP; 28638 } 28639 if (!default_tls_cfg.enabled && (default_transports & SIP_TRANSPORT_TLS)) { 28640 ast_log(LOG_WARNING, "Cannot use 'tls' transport with tlsenable=no. Removing from available transports.\n"); 28641 default_primary_transport &= ~SIP_TRANSPORT_TLS; 28642 default_transports &= ~SIP_TRANSPORT_TLS; 28643 } 28644 if (!default_transports) { 28645 ast_log(LOG_WARNING, "No valid transports available, falling back to 'udp'.\n"); 28646 default_transports = default_primary_transport = SIP_TRANSPORT_UDP; 28647 } else if (!default_primary_transport) { 28648 ast_log(LOG_WARNING, "No valid default transport. Selecting 'udp' as default.\n"); 28649 default_primary_transport = SIP_TRANSPORT_UDP; 28650 } 28651 28652 /* Build list of authentication to various SIP realms, i.e. service providers */ 28653 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 28654 /* Format for authentication is auth = username:password@realm */ 28655 if (!strcasecmp(v->name, "auth")) { 28656 add_realm_authentication(&authl, v->value, v->lineno); 28657 } 28658 } 28659 28660 if (bindport) { 28661 if (ast_sockaddr_port(&bindaddr)) { 28662 ast_log(LOG_WARNING, "bindport is also specified in bindaddr. " 28663 "Using %d.\n", bindport); 28664 } 28665 ast_sockaddr_set_port(&bindaddr, bindport); 28666 } 28667 28668 if (!ast_sockaddr_port(&bindaddr)) { 28669 ast_sockaddr_set_port(&bindaddr, STANDARD_SIP_PORT); 28670 } 28671 28672 /* Set UDP address and open socket */ 28673 ast_sockaddr_copy(&internip, &bindaddr); 28674 if (ast_find_ourip(&internip, &bindaddr, 0)) { 28675 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 28676 ast_config_destroy(cfg); 28677 return 0; 28678 } 28679 28680 ast_mutex_lock(&netlock); 28681 if ((sipsock > -1) && (ast_sockaddr_cmp(&old_bindaddr, &bindaddr))) { 28682 close(sipsock); 28683 sipsock = -1; 28684 } 28685 if (sipsock < 0) { 28686 sipsock = socket(ast_sockaddr_is_ipv6(&bindaddr) ? 28687 AF_INET6 : AF_INET, SOCK_DGRAM, 0); 28688 if (sipsock < 0) { 28689 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 28690 ast_config_destroy(cfg); 28691 ast_mutex_unlock(&netlock); 28692 return -1; 28693 } else { 28694 /* Allow SIP clients on the same host to access us: */ 28695 const int reuseFlag = 1; 28696 28697 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 28698 (const char*)&reuseFlag, 28699 sizeof reuseFlag); 28700 28701 ast_enable_packet_fragmentation(sipsock); 28702 28703 if (ast_bind(sipsock, &bindaddr) < 0) { 28704 ast_log(LOG_WARNING, "Failed to bind to %s: %s\n", 28705 ast_sockaddr_stringify(&bindaddr), strerror(errno)); 28706 close(sipsock); 28707 sipsock = -1; 28708 } else { 28709 ast_verb(2, "SIP Listening on %s\n", ast_sockaddr_stringify(&bindaddr)); 28710 ast_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP"); 28711 } 28712 } 28713 } else { 28714 ast_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP"); 28715 } 28716 ast_mutex_unlock(&netlock); 28717 28718 /* Start TCP server */ 28719 if (sip_cfg.tcp_enabled) { 28720 if (ast_sockaddr_isnull(&sip_tcp_desc.local_address)) { 28721 ast_sockaddr_copy(&sip_tcp_desc.local_address, &bindaddr); 28722 } 28723 if (!ast_sockaddr_port(&sip_tcp_desc.local_address)) { 28724 ast_sockaddr_set_port(&sip_tcp_desc.local_address, STANDARD_SIP_PORT); 28725 } 28726 } else { 28727 ast_sockaddr_setnull(&sip_tcp_desc.local_address); 28728 } 28729 ast_tcptls_server_start(&sip_tcp_desc); 28730 if (sip_cfg.tcp_enabled && sip_tcp_desc.accept_fd == -1) { 28731 /* TCP server start failed. Tell the admin */ 28732 ast_log(LOG_ERROR, "SIP TCP Server start failed. Not listening on TCP socket.\n"); 28733 } else { 28734 ast_debug(2, "SIP TCP server started\n"); 28735 } 28736 28737 /* Start TLS server if needed */ 28738 memcpy(sip_tls_desc.tls_cfg, &default_tls_cfg, sizeof(default_tls_cfg)); 28739 28740 if (ast_ssl_setup(sip_tls_desc.tls_cfg)) { 28741 if (ast_sockaddr_isnull(&sip_tls_desc.local_address)) { 28742 ast_sockaddr_copy(&sip_tls_desc.local_address, &bindaddr); 28743 ast_sockaddr_set_port(&sip_tls_desc.local_address, 28744 STANDARD_TLS_PORT); 28745 } 28746 if (!ast_sockaddr_port(&sip_tls_desc.local_address)) { 28747 ast_sockaddr_set_port(&sip_tls_desc.local_address, 28748 STANDARD_TLS_PORT); 28749 } 28750 ast_tcptls_server_start(&sip_tls_desc); 28751 if (default_tls_cfg.enabled && sip_tls_desc.accept_fd == -1) { 28752 ast_log(LOG_ERROR, "TLS Server start failed. Not listening on TLS socket.\n"); 28753 sip_tls_desc.tls_cfg = NULL; 28754 } 28755 } else if (sip_tls_desc.tls_cfg->enabled) { 28756 sip_tls_desc.tls_cfg = NULL; 28757 ast_log(LOG_WARNING, "SIP TLS server did not load because of errors.\n"); 28758 } 28759 28760 if (ucfg) { 28761 struct ast_variable *gen; 28762 int genhassip, genregistersip; 28763 const char *hassip, *registersip; 28764 28765 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 28766 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 28767 gen = ast_variable_browse(ucfg, "general"); 28768 cat = ast_category_browse(ucfg, NULL); 28769 while (cat) { 28770 if (strcasecmp(cat, "general")) { 28771 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 28772 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 28773 if (ast_true(hassip) || (!hassip && genhassip)) { 28774 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, 0); 28775 if (peer) { 28776 /* user.conf entries are always of type friend */ 28777 peer->type = SIP_TYPE_USER | SIP_TYPE_PEER; 28778 ao2_t_link(peers, peer, "link peer into peer table"); 28779 if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) { 28780 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 28781 } 28782 28783 unref_peer(peer, "unref_peer: from reload_config"); 28784 peer_count++; 28785 } 28786 } 28787 if (ast_true(registersip) || (!registersip && genregistersip)) { 28788 char tmp[256]; 28789 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 28790 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 28791 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 28792 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 28793 const char *authuser = ast_variable_retrieve(ucfg, cat, "authuser"); 28794 if (!host) { 28795 host = ast_variable_retrieve(ucfg, "general", "host"); 28796 } 28797 if (!username) { 28798 username = ast_variable_retrieve(ucfg, "general", "username"); 28799 } 28800 if (!secret) { 28801 secret = ast_variable_retrieve(ucfg, "general", "secret"); 28802 } 28803 if (!contact) { 28804 contact = "s"; 28805 } 28806 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 28807 if (!ast_strlen_zero(secret)) { 28808 if (!ast_strlen_zero(authuser)) { 28809 snprintf(tmp, sizeof(tmp), "%s?%s:%s:%s@%s/%s", cat, username, secret, authuser, host, contact); 28810 } else { 28811 snprintf(tmp, sizeof(tmp), "%s?%s:%s@%s/%s", cat, username, secret, host, contact); 28812 } 28813 } else if (!ast_strlen_zero(authuser)) { 28814 snprintf(tmp, sizeof(tmp), "%s?%s::%s@%s/%s", cat, username, authuser, host, contact); 28815 } else { 28816 snprintf(tmp, sizeof(tmp), "%s?%s@%s/%s", cat, username, host, contact); 28817 } 28818 if (sip_register(tmp, 0) == 0) { 28819 registry_count++; 28820 } 28821 } 28822 } 28823 } 28824 cat = ast_category_browse(ucfg, cat); 28825 } 28826 ast_config_destroy(ucfg); 28827 } 28828 28829 /* Load peers, users and friends */ 28830 cat = NULL; 28831 while ( (cat = ast_category_browse(cfg, cat)) ) { 28832 const char *utype; 28833 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 28834 continue; 28835 utype = ast_variable_retrieve(cfg, cat, "type"); 28836 if (!utype) { 28837 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 28838 continue; 28839 } else { 28840 if (!strcasecmp(utype, "user")) { 28841 ; 28842 } else if (!strcasecmp(utype, "friend")) { 28843 ; 28844 } else if (!strcasecmp(utype, "peer")) { 28845 ; 28846 } else { 28847 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 28848 continue; 28849 } 28850 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0); 28851 if (peer) { 28852 display_nat_warning(cat, reason, &peer->flags[0]); 28853 ao2_t_link(peers, peer, "link peer into peers table"); 28854 if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) { 28855 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 28856 } 28857 unref_peer(peer, "unref the result of the build_peer call. Now, the links from the tables are the only ones left."); 28858 peer_count++; 28859 } 28860 } 28861 } 28862 28863 /* Add default domains - host name, IP address and IP:port 28864 * Only do this if user added any sip domain with "localdomains" 28865 * In order to *not* break backwards compatibility 28866 * Some phones address us at IP only, some with additional port number 28867 */ 28868 if (auto_sip_domains) { 28869 char temp[MAXHOSTNAMELEN]; 28870 28871 /* First our default IP address */ 28872 if (!ast_sockaddr_isnull(&bindaddr) && !ast_sockaddr_is_any(&bindaddr)) { 28873 add_sip_domain(ast_sockaddr_stringify_addr(&bindaddr), 28874 SIP_DOMAIN_AUTO, NULL); 28875 } else if (!ast_sockaddr_isnull(&internip) && !ast_sockaddr_is_any(&internip)) { 28876 /* Our internal IP address, if configured */ 28877 add_sip_domain(ast_sockaddr_stringify_addr(&internip), 28878 SIP_DOMAIN_AUTO, NULL); 28879 } else { 28880 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 28881 } 28882 28883 /* If TCP is running on a different IP than UDP, then add it too */ 28884 if (!ast_sockaddr_isnull(&sip_tcp_desc.local_address) && 28885 !ast_sockaddr_cmp(&bindaddr, &sip_tcp_desc.local_address)) { 28886 add_sip_domain(ast_sockaddr_stringify_addr(&sip_tcp_desc.local_address), 28887 SIP_DOMAIN_AUTO, NULL); 28888 } 28889 28890 /* If TLS is running on a different IP than UDP and TCP, then add that too */ 28891 if (!ast_sockaddr_isnull(&sip_tls_desc.local_address) && 28892 !ast_sockaddr_cmp(&bindaddr, &sip_tls_desc.local_address) && 28893 !ast_sockaddr_cmp(&sip_tcp_desc.local_address, 28894 &sip_tls_desc.local_address)) { 28895 add_sip_domain(ast_sockaddr_stringify_addr(&sip_tcp_desc.local_address), 28896 SIP_DOMAIN_AUTO, NULL); 28897 } 28898 28899 /* Our extern IP address, if configured */ 28900 if (!ast_sockaddr_isnull(&externaddr)) { 28901 add_sip_domain(ast_sockaddr_stringify_addr(&externaddr), 28902 SIP_DOMAIN_AUTO, NULL); 28903 } 28904 28905 /* Extern host name (NAT traversal support) */ 28906 if (!ast_strlen_zero(externhost)) { 28907 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 28908 } 28909 28910 /* Our host name */ 28911 if (!gethostname(temp, sizeof(temp))) { 28912 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 28913 } 28914 } 28915 28916 /* Release configuration from memory */ 28917 ast_config_destroy(cfg); 28918 28919 /* Load the list of manual NOTIFY types to support */ 28920 if (notify_types) 28921 ast_config_destroy(notify_types); 28922 if ((notify_types = ast_config_load(notify_config, config_flags)) == CONFIG_STATUS_FILEINVALID) { 28923 ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed.\n", notify_config); 28924 notify_types = NULL; 28925 } 28926 28927 /* Done, tell the manager */ 28928 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); 28929 run_end = time(0); 28930 ast_debug(4, "SIP reload_config done...Runtime= %d sec\n", (int)(run_end-run_start)); 28931 28932 return 0; 28933 }
static char * remove_uri_parameters | ( | char * | uri | ) | [static] |
Definition at line 11856 of file chan_sip.c.
Referenced by extract_uri(), parse_moved_contact(), register_verify(), reqprep(), and transmit_state_notify().
11857 { 11858 char *atsign; 11859 atsign = strchr(uri, '@'); /* First, locate the at sign */ 11860 if (!atsign) { 11861 atsign = uri; /* Ok hostname only, let's stick with the rest */ 11862 } 11863 atsign = strchr(atsign, ';'); /* Locate semi colon */ 11864 if (atsign) 11865 *atsign = '\0'; /* Kill at the semi colon */ 11866 return uri; 11867 }
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 19115 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().
19116 { 19117 char tmp[512]; 19118 char *c; 19119 char oldnonce[256]; 19120 19121 /* table of recognised keywords, and places where they should be copied */ 19122 const struct x { 19123 const char *key; 19124 const ast_string_field *field; 19125 } *i, keys[] = { 19126 { "realm=", &p->realm }, 19127 { "nonce=", &p->nonce }, 19128 { "opaque=", &p->opaque }, 19129 { "qop=", &p->qop }, 19130 { "domain=", &p->domain }, 19131 { NULL, 0 }, 19132 }; 19133 19134 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 19135 if (ast_strlen_zero(tmp)) 19136 return -1; 19137 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 19138 ast_log(LOG_WARNING, "missing Digest.\n"); 19139 return -1; 19140 } 19141 c = tmp + strlen("Digest "); 19142 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 19143 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 19144 for (i = keys; i->key != NULL; i++) { 19145 char *src, *separator; 19146 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 19147 continue; 19148 /* Found. Skip keyword, take text in quotes or up to the separator. */ 19149 c += strlen(i->key); 19150 if (*c == '"') { 19151 src = ++c; 19152 separator = "\""; 19153 } else { 19154 src = c; 19155 separator = ","; 19156 } 19157 strsep(&c, separator); /* clear separator and move ptr */ 19158 ast_string_field_ptr_set(p, i->field, src); 19159 break; 19160 } 19161 if (i->key == NULL) /* not found, try ',' */ 19162 strsep(&c, ","); 19163 } 19164 /* Reset nonce count */ 19165 if (strcmp(p->nonce, oldnonce)) 19166 p->noncecount = 0; 19167 19168 /* Save auth data for following registrations */ 19169 if (p->registry) { 19170 struct sip_registry *r = p->registry; 19171 19172 if (strcmp(r->nonce, p->nonce)) { 19173 ast_string_field_set(r, realm, p->realm); 19174 ast_string_field_set(r, nonce, p->nonce); 19175 ast_string_field_set(r, authdomain, p->domain); 19176 ast_string_field_set(r, opaque, p->opaque); 19177 ast_string_field_set(r, qop, p->qop); 19178 r->noncecount = 0; 19179 } 19180 } 19181 return build_reply_digest(p, sipmethod, digest, digest_len); 19182 }
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 10289 of file chan_sip.c.
References add_header(), add_header_max_forwards(), add_route(), ast_copy_string(), ast_debug, ast_random(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_via(), copy_header(), FALSE, get_header(), get_in_brackets(), global_useragent, init_req(), remove_uri_parameters(), set_destination(), sip_methods, st_get_se(), strcasestr(), strefresher2str(), text, cfsip_methods::text, TRUE, and url.
10290 { 10291 struct sip_request *orig = &p->initreq; 10292 char stripped[80]; 10293 char tmp[80]; 10294 char newto[256]; 10295 const char *c; 10296 const char *ot, *of; 10297 int is_strict = FALSE; /*!< Strict routing flag */ 10298 int is_outbound = ast_test_flag(&p->flags[0], SIP_OUTGOING); /* Session direction */ 10299 10300 memset(req, 0, sizeof(struct sip_request)); 10301 10302 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 10303 10304 if (!seqno) { 10305 p->ocseq++; 10306 seqno = p->ocseq; 10307 } 10308 10309 /* A CANCEL must have the same branch as the INVITE that it is canceling. */ 10310 if (sipmethod == SIP_CANCEL) { 10311 p->branch = p->invite_branch; 10312 build_via(p); 10313 } else if (newbranch && (sipmethod == SIP_INVITE)) { 10314 p->branch ^= ast_random(); 10315 p->invite_branch = p->branch; 10316 build_via(p); 10317 } else if (newbranch) { 10318 p->branch ^= ast_random(); 10319 build_via(p); 10320 } 10321 10322 /* Check for strict or loose router */ 10323 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop, ";lr") == NULL) { 10324 is_strict = TRUE; 10325 if (sipdebug) 10326 ast_debug(1, "Strict routing enforced for session %s\n", p->callid); 10327 } 10328 10329 if (sipmethod == SIP_CANCEL) 10330 c = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); /* Use original URI */ 10331 else if (sipmethod == SIP_ACK) { 10332 /* Use URI from Contact: in 200 OK (if INVITE) 10333 (we only have the contacturi on INVITEs) */ 10334 if (!ast_strlen_zero(p->okcontacturi)) 10335 c = is_strict ? p->route->hop : p->okcontacturi; 10336 else 10337 c = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); 10338 } else if (!ast_strlen_zero(p->okcontacturi)) 10339 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 10340 else if (!ast_strlen_zero(p->uri)) 10341 c = p->uri; 10342 else { 10343 char *n; 10344 /* We have no URI, use To: or From: header as URI (depending on direction) */ 10345 ast_copy_string(stripped, get_header(orig, is_outbound ? "To" : "From"), 10346 sizeof(stripped)); 10347 n = get_in_brackets(stripped); 10348 c = remove_uri_parameters(n); 10349 } 10350 init_req(req, sipmethod, c); 10351 10352 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 10353 10354 add_header(req, "Via", p->via); 10355 /* 10356 * Use the learned route set unless this is a CANCEL on an ACK for a non-2xx 10357 * final response. For a CANCEL or ACK, we have to send to the same destination 10358 * as the original INVITE. 10359 */ 10360 if (sipmethod == SIP_CANCEL || 10361 (sipmethod == SIP_ACK && (p->invitestate == INV_COMPLETED || p->invitestate == INV_CANCELLED))) { 10362 set_destination(p, ast_strdupa(p->uri)); 10363 } else if (p->route) { 10364 set_destination(p, p->route->hop); 10365 add_route(req, is_strict ? p->route->next : p->route); 10366 } 10367 add_header_max_forwards(p, req); 10368 10369 ot = get_header(orig, "To"); 10370 of = get_header(orig, "From"); 10371 10372 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 10373 as our original request, including tag (or presumably lack thereof) */ 10374 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 10375 /* Add the proper tag if we don't have it already. If they have specified 10376 their tag, use it. Otherwise, use our own tag */ 10377 if (is_outbound && !ast_strlen_zero(p->theirtag)) 10378 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 10379 else if (!is_outbound) 10380 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 10381 else 10382 snprintf(newto, sizeof(newto), "%s", ot); 10383 ot = newto; 10384 } 10385 10386 if (is_outbound) { 10387 add_header(req, "From", of); 10388 add_header(req, "To", ot); 10389 } else { 10390 add_header(req, "From", ot); 10391 add_header(req, "To", of); 10392 } 10393 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 10394 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 10395 add_header(req, "Contact", p->our_contact); 10396 10397 copy_header(req, orig, "Call-ID"); 10398 add_header(req, "CSeq", tmp); 10399 10400 if (!ast_strlen_zero(global_useragent)) 10401 add_header(req, "User-Agent", global_useragent); 10402 10403 if (!ast_strlen_zero(p->url)) { 10404 add_header(req, "Access-URL", p->url); 10405 ast_string_field_set(p, url, NULL); 10406 } 10407 10408 /* Add Session-Timers related headers if the feature is active for this session. 10409 An exception to this behavior is the ACK request. Since Asterisk never requires 10410 session-timers support from a remote end-point (UAS) in an INVITE, it must 10411 not send 'Require: timer' header in the ACK request. 10412 This should only be added in the INVITE transactions, not MESSAGE or REFER or other 10413 in-dialog messages. 10414 */ 10415 if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE 10416 && sipmethod == SIP_INVITE) { 10417 char se_hdr[256]; 10418 snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval, 10419 strefresher2str(p->stimer->st_ref)); 10420 add_header(req, "Session-Expires", se_hdr); 10421 snprintf(se_hdr, sizeof(se_hdr), "%d", st_get_se(p, FALSE)); 10422 add_header(req, "Min-SE", se_hdr); 10423 } 10424 10425 return 0; 10426 }
static int resp_needs_contact | ( | const char * | msg, | |
enum sipmethod | method | |||
) | [inline, static] |
Test if this response needs a contact header.
Definition at line 10152 of file chan_sip.c.
Referenced by respprep().
10152 { 10153 /* Requirements for Contact header inclusion in responses generated 10154 * from the header tables found in the following RFCs. Where the 10155 * Contact header was marked mandatory (m) or optional (o) this 10156 * function returns 1. 10157 * 10158 * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER) 10159 * - RFC 2976 (INFO) 10160 * - RFC 3262 (PRACK) 10161 * - RFC 3265 (SUBSCRIBE, NOTIFY) 10162 * - RFC 3311 (UPDATE) 10163 * - RFC 3428 (MESSAGE) 10164 * - RFC 3515 (REFER) 10165 * - RFC 3903 (PUBLISH) 10166 */ 10167 10168 switch (method) { 10169 /* 1xx, 2xx, 3xx, 485 */ 10170 case SIP_INVITE: 10171 case SIP_UPDATE: 10172 case SIP_SUBSCRIBE: 10173 case SIP_NOTIFY: 10174 if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3)) 10175 return 1; 10176 break; 10177 10178 /* 2xx, 3xx, 485 */ 10179 case SIP_REGISTER: 10180 case SIP_OPTIONS: 10181 if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3)) 10182 return 1; 10183 break; 10184 10185 /* 3xx, 485 */ 10186 case SIP_BYE: 10187 case SIP_PRACK: 10188 case SIP_MESSAGE: 10189 case SIP_PUBLISH: 10190 if (msg[0] == '3' || !strncmp(msg, "485", 3)) 10191 return 1; 10192 break; 10193 10194 /* 2xx, 3xx, 4xx, 5xx, 6xx */ 10195 case SIP_REFER: 10196 if (msg[0] >= '2' && msg[0] <= '6') 10197 return 1; 10198 break; 10199 10200 /* contact will not be included for everything else */ 10201 case SIP_ACK: 10202 case SIP_CANCEL: 10203 case SIP_INFO: 10204 case SIP_PING: 10205 default: 10206 return 0; 10207 } 10208 return 0; 10209 }
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 10212 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.
10213 { 10214 char newto[256]; 10215 const char *ot; 10216 10217 init_resp(resp, msg); 10218 copy_via_headers(p, resp, req, "Via"); 10219 if (msg[0] == '1' || msg[0] == '2') 10220 copy_all_header(resp, req, "Record-Route"); 10221 copy_header(resp, req, "From"); 10222 ot = get_header(req, "To"); 10223 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 10224 /* Add the proper tag if we don't have it already. If they have specified 10225 their tag, use it. Otherwise, use our own tag */ 10226 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 10227 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 10228 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 10229 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 10230 else 10231 ast_copy_string(newto, ot, sizeof(newto)); 10232 ot = newto; 10233 } 10234 add_header(resp, "To", ot); 10235 copy_header(resp, req, "Call-ID"); 10236 copy_header(resp, req, "CSeq"); 10237 if (!ast_strlen_zero(global_useragent)) 10238 add_header(resp, "Server", global_useragent); 10239 add_header(resp, "Allow", ALLOWED_METHODS); 10240 add_supported_header(p, resp); 10241 10242 /* If this is an invite, add Session-Timers related headers if the feature is active for this session */ 10243 if (p->method == SIP_INVITE && p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE) { 10244 char se_hdr[256]; 10245 snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval, 10246 strefresher2str(p->stimer->st_ref)); 10247 add_header(resp, "Session-Expires", se_hdr); 10248 } 10249 10250 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 10251 /* For registration responses, we also need expiry and 10252 contact info */ 10253 char tmp[256]; 10254 10255 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 10256 add_header(resp, "Expires", tmp); 10257 if (p->expiry) { /* Only add contact if we have an expiry time */ 10258 char contact[SIPBUFSIZE]; 10259 const char *contact_uri = p->method == SIP_SUBSCRIBE ? p->our_contact : p->fullcontact; 10260 char *brackets = strchr(contact_uri, '<'); 10261 snprintf(contact, sizeof(contact), "%s%s%s;expires=%d", brackets ? "" : "<", contact_uri, brackets ? "" : ">", p->expiry); 10262 add_header(resp, "Contact", contact); /* Not when we unregister */ 10263 } 10264 } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) { 10265 add_header(resp, "Contact", p->our_contact); 10266 } 10267 10268 if (!ast_strlen_zero(p->url)) { 10269 add_header(resp, "Access-URL", p->url); 10270 ast_string_field_set(p, url, NULL); 10271 } 10272 10273 /* default to routing the response to the address where the request 10274 * came from. Since we don't have a transport layer, we do this here. 10275 * The process_via() function will update the port to either the port 10276 * specified in the via header or the default port later on (per RFC 10277 * 3261 section 18.2.2). 10278 */ 10279 p->sa = p->recv; 10280 10281 if (process_via(p, req)) { 10282 ast_log(LOG_WARNING, "error processing via header, will send response to originating address\n"); 10283 } 10284 10285 return 0; 10286 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 25788 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.
25789 { 25790 /* If we're supposed to be stopped -- stay stopped */ 25791 if (monitor_thread == AST_PTHREADT_STOP) 25792 return 0; 25793 ast_mutex_lock(&monlock); 25794 if (monitor_thread == pthread_self()) { 25795 ast_mutex_unlock(&monlock); 25796 ast_log(LOG_WARNING, "Cannot kill myself\n"); 25797 return -1; 25798 } 25799 if (monitor_thread != AST_PTHREADT_NULL) { 25800 /* Wake up the thread */ 25801 pthread_kill(monitor_thread, SIGURG); 25802 } else { 25803 /* Start a new monitor */ 25804 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 25805 ast_mutex_unlock(&monlock); 25806 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 25807 return -1; 25808 } 25809 } 25810 ast_mutex_unlock(&monlock); 25811 return 0; 25812 }
static void restart_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Restart session timer.
Definition at line 25816 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().
25817 { 25818 if (!p->stimer) { 25819 ast_log(LOG_WARNING, "Null stimer in restart_session_timer - %s\n", p->callid); 25820 return; 25821 } 25822 25823 if (p->stimer->st_active == TRUE) { 25824 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 25825 AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid, 25826 dialog_unref(p, "Removing session timer ref")); 25827 start_session_timer(p); 25828 } 25829 }
static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 3550 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.
03551 { 03552 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 03553 int reschedule = DEFAULT_RETRANS; 03554 int xmitres = 0; 03555 /* how many ms until retrans timeout is reached */ 03556 int64_t diff = pkt->retrans_stop_time - ast_tvdiff_ms(ast_tvnow(), pkt->time_sent); 03557 03558 /* Do not retransmit if time out is reached. This will be negative if the time between 03559 * the first transmission and now is larger than our timeout period. This is a fail safe 03560 * check in case the scheduler gets behind or the clock is changed. */ 03561 if ((diff <= 0) || (diff > pkt->retrans_stop_time)) { 03562 pkt->retrans_stop = 1; 03563 } 03564 03565 /* Lock channel PVT */ 03566 sip_pvt_lock(pkt->owner); 03567 03568 if (!pkt->retrans_stop) { 03569 pkt->retrans++; 03570 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 03571 if (sipdebug) { 03572 ast_debug(4, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n", 03573 pkt->retransid, 03574 sip_methods[pkt->method].text, 03575 pkt->method); 03576 } 03577 } else { 03578 int siptimer_a; 03579 03580 if (sipdebug) { 03581 ast_debug(4, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", 03582 pkt->retransid, 03583 pkt->retrans, 03584 sip_methods[pkt->method].text, 03585 pkt->method); 03586 } 03587 if (!pkt->timer_a) { 03588 pkt->timer_a = 2 ; 03589 } else { 03590 pkt->timer_a = 2 * pkt->timer_a; 03591 } 03592 03593 /* For non-invites, a maximum of 4 secs */ 03594 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 03595 if (pkt->method != SIP_INVITE && siptimer_a > 4000) { 03596 siptimer_a = 4000; 03597 } 03598 03599 /* Reschedule re-transmit */ 03600 reschedule = siptimer_a; 03601 ast_debug(4, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n", 03602 pkt->retrans + 1, 03603 siptimer_a, 03604 pkt->timer_t1, 03605 pkt->retransid); 03606 } 03607 03608 if (sip_debug_test_pvt(pkt->owner)) { 03609 const struct ast_sockaddr *dst = sip_real_dst(pkt->owner); 03610 ast_verbose("Retransmitting #%d (%s) to %s:\n%s\n---\n", 03611 pkt->retrans, sip_nat_mode(pkt->owner), 03612 ast_sockaddr_stringify(dst), 03613 pkt->data->str); 03614 } 03615 03616 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data->str); 03617 xmitres = __sip_xmit(pkt->owner, pkt->data); 03618 03619 /* If there was no error during the network transmission, schedule the next retransmission, 03620 * but if the next retransmission is going to be beyond our timeout period, mark the packet's 03621 * stop_retrans value and set the next retransmit to be the exact time of timeout. This will 03622 * allow any responses to the packet to be processed before the packet is destroyed on the next 03623 * call to this function by the scheduler. */ 03624 if (xmitres != XMIT_ERROR) { 03625 if (reschedule >= diff) { 03626 pkt->retrans_stop = 1; 03627 reschedule = diff; 03628 } 03629 sip_pvt_unlock(pkt->owner); 03630 return reschedule; 03631 } 03632 } 03633 03634 /* At this point, either the packet's retransmission timed out, or there was a 03635 * transmission error, either way destroy the scheduler item and this packet. */ 03636 03637 pkt->retransid = -1; /* Kill this scheduler item */ 03638 03639 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 03640 if (pkt->is_fatal || sipdebug) { /* Tell us if it's critical or if we're debugging */ 03641 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" 03642 "Packet timed out after %dms with no response\n", 03643 pkt->owner->callid, 03644 pkt->seqno, 03645 pkt->is_fatal ? "Critical" : "Non-critical", 03646 pkt->is_resp ? "Response" : "Request", 03647 (int) ast_tvdiff_ms(ast_tvnow(), pkt->time_sent)); 03648 } 03649 } else if (pkt->method == SIP_OPTIONS && sipdebug) { 03650 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); 03651 } 03652 03653 if (xmitres == XMIT_ERROR) { 03654 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission on Call ID %s\n", pkt->owner->callid); 03655 append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 03656 } else { 03657 append_history(pkt->owner, "MaxRetries", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 03658 } 03659 03660 if (pkt->is_fatal) { 03661 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 03662 sip_pvt_unlock(pkt->owner); /* SIP_PVT, not channel */ 03663 usleep(1); 03664 sip_pvt_lock(pkt->owner); 03665 } 03666 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) { 03667 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 03668 } 03669 if (pkt->owner->owner) { 03670 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); 03671 03672 if (pkt->is_resp && 03673 (pkt->response_code >= 200) && 03674 (pkt->response_code < 300) && 03675 pkt->owner->pendinginvite && 03676 ast_test_flag(&pkt->owner->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 03677 /* This is a timeout of the 2XX response to a pending INVITE. In this case terminate the INVITE 03678 * transaction just as if we received the ACK, but immediately hangup with a BYE (sip_hangup 03679 * will send the BYE as long as the dialog is not set as "alreadygone") 03680 * RFC 3261 section 13.3.1.4. 03681 * "If the server retransmits the 2xx response for 64*T1 seconds without receiving 03682 * an ACK, the dialog is confirmed, but the session SHOULD be terminated. This is 03683 * accomplished with a BYE, as described in Section 15." */ 03684 pkt->owner->invitestate = INV_TERMINATED; 03685 pkt->owner->pendinginvite = 0; 03686 } else { 03687 /* there is nothing left to do, mark the dialog as gone */ 03688 sip_alreadygone(pkt->owner); 03689 } 03690 ast_queue_hangup_with_cause(pkt->owner->owner, AST_CAUSE_PROTOCOL_ERROR); 03691 ast_channel_unlock(pkt->owner->owner); 03692 } else { 03693 /* If no channel owner, destroy now */ 03694 03695 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 03696 if (pkt->method != SIP_OPTIONS && pkt->method != SIP_REGISTER) { 03697 pvt_set_needdestroy(pkt->owner, "no response to critical packet"); 03698 sip_alreadygone(pkt->owner); 03699 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 03700 } 03701 } 03702 } 03703 03704 if (pkt->method == SIP_BYE) { 03705 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 03706 sip_alreadygone(pkt->owner); 03707 if (pkt->owner->owner) { 03708 ast_channel_unlock(pkt->owner->owner); 03709 } 03710 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 03711 pvt_set_needdestroy(pkt->owner, "no response to BYE"); 03712 } 03713 03714 /* Remove the packet */ 03715 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 03716 if (cur == pkt) { 03717 UNLINK(cur, pkt->owner->packets, prev); 03718 sip_pvt_unlock(pkt->owner); 03719 if (pkt->owner) { 03720 pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now"); 03721 } 03722 if (pkt->data) { 03723 ast_free(pkt->data); 03724 } 03725 pkt->data = NULL; 03726 ast_free(pkt); 03727 return 0; 03728 } 03729 } 03730 /* error case */ 03731 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 03732 sip_pvt_unlock(pkt->owner); 03733 return 0; 03734 }
static int send_provisional_keepalive | ( | const void * | data | ) | [static] |
Definition at line 4140 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
04140 { 04141 struct sip_pvt *pvt = (struct sip_pvt *) data; 04142 04143 return send_provisional_keepalive_full(pvt, 0); 04144 }
static int send_provisional_keepalive_full | ( | struct sip_pvt * | pvt, | |
int | with_sdp | |||
) | [static] |
Definition at line 4091 of file chan_sip.c.
References ast_channel_unlock, ast_channel_unref, FALSE, S_OR, sip_pvt_lock_full(), sip_pvt_unlock, transmit_response(), and transmit_response_with_sdp().
Referenced by send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().
04092 { 04093 const char *msg = NULL; 04094 struct ast_channel *chan; 04095 int res = 0; 04096 04097 chan = sip_pvt_lock_full(pvt); 04098 04099 if (!pvt->last_provisional || !strncasecmp(pvt->last_provisional, "100", 3)) { 04100 msg = "183 Session Progress"; 04101 } 04102 04103 if (pvt->invitestate < INV_COMPLETED) { 04104 if (with_sdp) { 04105 transmit_response_with_sdp(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq, XMIT_UNRELIABLE, FALSE, FALSE); 04106 } else { 04107 transmit_response(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq); 04108 } 04109 res = PROVIS_KEEPALIVE_TIMEOUT; 04110 } 04111 04112 if (chan) { 04113 ast_channel_unlock(chan); 04114 chan = ast_channel_unref(chan); 04115 } 04116 04117 if (!res) { 04118 pvt->provisional_keepalive_sched_id = -1; 04119 } 04120 04121 sip_pvt_unlock(pvt); 04122 04123 #if 0 04124 /* 04125 * XXX BUG TODO 04126 * 04127 * Without this code, it appears as if this function is leaking its 04128 * reference to the sip_pvt. However, adding it introduces a crash. 04129 * This points to some sort of reference count imbalance elsewhere, 04130 * but I'm not sure where ... 04131 */ 04132 if (!res) { 04133 dialog_unref(pvt, "dialog ref for provisional keepalive"); 04134 } 04135 #endif 04136 04137 return res; 04138 }
static int send_provisional_keepalive_with_sdp | ( | const void * | data | ) | [static] |
Definition at line 4146 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
04146 { 04147 struct sip_pvt *pvt = (void *)data; 04148 04149 return send_provisional_keepalive_full(pvt, 1); 04150 }
static int send_request | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
enum xmittype | reliable, | |||
int | seqno | |||
) | [static] |
Definition at line 4203 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.
04204 { 04205 int res; 04206 04207 /* If we have an outbound proxy, reset peer address 04208 Only do this once. 04209 */ 04210 if (p->outboundproxy) { 04211 p->sa = p->outboundproxy->ip; 04212 } 04213 04214 finalize_content(req); 04215 add_blank(req); 04216 if (sip_debug_test_pvt(p)) { 04217 if (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) { 04218 ast_verbose("%sTransmitting (NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->recv), req->data->str); 04219 } else { 04220 ast_verbose("%sTransmitting (no NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->sa), req->data->str); 04221 } 04222 } 04223 if (p->do_history) { 04224 struct sip_request tmp = { .rlPart1 = 0, }; 04225 parse_copy(&tmp, req); 04226 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data->str, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 04227 deinit_req(&tmp); 04228 } 04229 res = (reliable) ? 04230 __sip_reliable_xmit(p, seqno, 0, req->data, (reliable == XMIT_CRITICAL), req->method) : 04231 __sip_xmit(p, req->data); 04232 deinit_req(req); 04233 return res; 04234 }
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 4161 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.
04162 { 04163 int res; 04164 04165 finalize_content(req); 04166 add_blank(req); 04167 if (sip_debug_test_pvt(p)) { 04168 const struct ast_sockaddr *dst = sip_real_dst(p); 04169 04170 ast_verbose("\n<--- %sTransmitting (%s) to %s --->\n%s\n<------------>\n", 04171 reliable ? "Reliably " : "", sip_nat_mode(p), 04172 ast_sockaddr_stringify(dst), 04173 req->data->str); 04174 } 04175 if (p->do_history) { 04176 struct sip_request tmp = { .rlPart1 = 0, }; 04177 parse_copy(&tmp, req); 04178 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data->str, get_header(&tmp, "CSeq"), 04179 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? REQ_OFFSET_TO_STR(&tmp, rlPart2) : sip_methods[tmp.method].text); 04180 deinit_req(&tmp); 04181 } 04182 04183 /* If we are sending a final response to an INVITE, stop retransmitting provisional responses */ 04184 if (p->initreq.method == SIP_INVITE && reliable == XMIT_CRITICAL) { 04185 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")); 04186 } 04187 04188 res = (reliable) ? 04189 __sip_reliable_xmit(p, seqno, 1, req->data, (reliable == XMIT_CRITICAL), req->method) : 04190 __sip_xmit(p, req->data); 04191 deinit_req(req); 04192 if (res > 0) { 04193 return 0; 04194 } 04195 return res; 04196 }
static enum ast_cc_service_type service_string_to_service_type | ( | const char *const | service_string | ) | [static] |
Definition at line 841 of file chan_sip.c.
References AST_CC_CCBS, AST_CC_CCNL, AST_CC_NONE, service, and sip_cc_service_map.
Referenced by sip_get_cc_information().
00842 { 00843 enum ast_cc_service_type service; 00844 for (service = AST_CC_CCBS; service <= AST_CC_CCNL; ++service) { 00845 if (!strcasecmp(service_string, sip_cc_service_map[service].service_string)) { 00846 return service; 00847 } 00848 } 00849 return AST_CC_NONE; 00850 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 13916 of file chan_sip.c.
References __set_address_from_contact(), and ast_test_flag.
Referenced by handle_response_invite().
13917 { 13918 if (ast_test_flag(&pvt->flags[0], SIP_NAT_FORCE_RPORT)) { 13919 /* NAT: Don't trust the contact field. Just use what they came to us 13920 with. */ 13921 /*! \todo We need to save the TRANSPORT here too */ 13922 pvt->sa = pvt->recv; 13923 return 0; 13924 } 13925 13926 return __set_address_from_contact(pvt->fullcontact, &pvt->sa, pvt->socket.type == SIP_TRANSPORT_TLS ? 1 : 0); 13927 }
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 10021 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().
10022 { 10023 char *h, *maddr, hostname[256]; 10024 int hn; 10025 int debug=sip_debug_test_pvt(p); 10026 int tls_on = FALSE; 10027 10028 if (debug) 10029 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 10030 10031 /* Find and parse hostname */ 10032 h = strchr(uri, '@'); 10033 if (h) 10034 ++h; 10035 else { 10036 h = uri; 10037 if (!strncasecmp(h, "sip:", 4)) { 10038 h += 4; 10039 } else if (!strncasecmp(h, "sips:", 5)) { 10040 h += 5; 10041 tls_on = TRUE; 10042 } 10043 } 10044 hn = strcspn(h, ";>") + 1; 10045 if (hn > sizeof(hostname)) 10046 hn = sizeof(hostname); 10047 ast_copy_string(hostname, h, hn); 10048 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 10049 h += hn - 1; 10050 10051 /*! \todo XXX If we have sip_cfg.srvlookup on, then look for NAPTR/SRV, 10052 * otherwise, just look for A records */ 10053 if (ast_sockaddr_resolve_first(&p->sa, hostname, 0)) { 10054 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 10055 return; 10056 } 10057 10058 /* Got the hostname - but maybe there's a "maddr=" to override address? */ 10059 maddr = strstr(h, "maddr="); 10060 if (maddr) { 10061 int port; 10062 10063 maddr += 6; 10064 hn = strspn(maddr, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 10065 "0123456789-.:[]") + 1; 10066 if (hn > sizeof(hostname)) 10067 hn = sizeof(hostname); 10068 ast_copy_string(hostname, maddr, hn); 10069 10070 port = ast_sockaddr_port(&p->sa); 10071 10072 /*! \todo XXX If we have sip_cfg.srvlookup on, then look for 10073 * NAPTR/SRV, otherwise, just look for A records */ 10074 if (ast_sockaddr_resolve_first(&p->sa, hostname, PARSE_PORT_FORBID)) { 10075 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 10076 return; 10077 } 10078 10079 ast_sockaddr_set_port(&p->sa, port); 10080 } 10081 10082 if (!ast_sockaddr_port(&p->sa)) { 10083 ast_sockaddr_set_port(&p->sa, tls_on ? 10084 STANDARD_TLS_PORT : STANDARD_SIP_PORT); 10085 } 10086 10087 if (debug) { 10088 ast_verbose("set_destination: set destination to %s\n", 10089 ast_sockaddr_stringify(&p->sa)); 10090 } 10091 }
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 26580 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(), get_insecure_variable_from_sipregs(), and handle_common_options().
26581 { 26582 if (ast_strlen_zero(value)) 26583 return; 26584 26585 if (!ast_false(value)) { 26586 char buf[64]; 26587 char *word, *next; 26588 26589 ast_copy_string(buf, value, sizeof(buf)); 26590 next = buf; 26591 while ((word = strsep(&next, ","))) { 26592 if (!strcasecmp(word, "port")) 26593 ast_set_flag(&flags[0], SIP_INSECURE_PORT); 26594 else if (!strcasecmp(word, "invite")) 26595 ast_set_flag(&flags[0], SIP_INSECURE_INVITE); 26596 else 26597 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 26598 } 26599 } 26600 }
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 14276 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().
14277 { 14278 if (p->stalenonce || forceupdate || ast_strlen_zero(p->randdata)) { 14279 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 14280 p->stalenonce = 0; 14281 } 14282 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 27000 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().
27001 { 27002 if (peer->expire == 0) { 27003 /* Don't reset expire or port time during reload 27004 if we have an active registration 27005 */ 27006 peer->expire = -1; 27007 peer->pokeexpire = -1; 27008 set_socket_transport(&peer->socket, SIP_TRANSPORT_UDP); 27009 } 27010 peer->type = SIP_TYPE_PEER; 27011 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 27012 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 27013 ast_copy_flags(&peer->flags[2], &global_flags[2], SIP_PAGE3_FLAGS_TO_COPY); 27014 ast_string_field_set(peer, context, sip_cfg.default_context); 27015 ast_string_field_set(peer, subscribecontext, sip_cfg.default_subscribecontext); 27016 ast_string_field_set(peer, language, default_language); 27017 ast_string_field_set(peer, mohinterpret, default_mohinterpret); 27018 ast_string_field_set(peer, mohsuggest, default_mohsuggest); 27019 ast_string_field_set(peer, engine, default_engine); 27020 ast_sockaddr_setnull(&peer->addr); 27021 ast_sockaddr_setnull(&peer->defaddr); 27022 peer->capability = sip_cfg.capability; 27023 peer->maxcallbitrate = default_maxcallbitrate; 27024 peer->rtptimeout = global_rtptimeout; 27025 peer->rtpholdtimeout = global_rtpholdtimeout; 27026 peer->rtpkeepalive = global_rtpkeepalive; 27027 peer->allowtransfer = sip_cfg.allowtransfer; 27028 peer->autoframing = global_autoframing; 27029 peer->t38_maxdatagram = global_t38_maxdatagram; 27030 peer->qualifyfreq = global_qualifyfreq; 27031 if (global_callcounter) 27032 peer->call_limit=INT_MAX; 27033 ast_string_field_set(peer, vmexten, default_vmexten); 27034 ast_string_field_set(peer, secret, ""); 27035 ast_string_field_set(peer, remotesecret, ""); 27036 ast_string_field_set(peer, md5secret, ""); 27037 ast_string_field_set(peer, cid_num, ""); 27038 ast_string_field_set(peer, cid_name, ""); 27039 ast_string_field_set(peer, cid_tag, ""); 27040 ast_string_field_set(peer, fromdomain, ""); 27041 ast_string_field_set(peer, fromuser, ""); 27042 ast_string_field_set(peer, regexten, ""); 27043 peer->callgroup = 0; 27044 peer->pickupgroup = 0; 27045 peer->maxms = default_qualify; 27046 peer->prefs = default_prefs; 27047 peer->stimer.st_mode_oper = global_st_mode; /* Session-Timers */ 27048 peer->stimer.st_ref = global_st_refresher; 27049 peer->stimer.st_min_se = global_min_se; 27050 peer->stimer.st_max_se = global_max_se; 27051 peer->timer_t1 = global_t1; 27052 peer->timer_b = global_timer_b; 27053 clear_peer_mailboxes(peer); 27054 peer->disallowed_methods = sip_cfg.disallowed_methods; 27055 peer->transports = default_transports; 27056 peer->default_outbound_transport = default_primary_transport; 27057 }
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 8401 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().
08402 { 08403 pvt->allowed_methods = parse_allowed_methods(req); 08404 08405 if (ast_test_flag(&pvt->flags[1], SIP_PAGE2_RPID_UPDATE)) { 08406 mark_method_allowed(&pvt->allowed_methods, SIP_UPDATE); 08407 } 08408 pvt->allowed_methods &= ~(pvt->disallowed_methods); 08409 08410 return pvt->allowed_methods; 08411 }
static void set_socket_transport | ( | struct sip_socket * | socket, | |
int | transport | |||
) | [static] |
Definition at line 13670 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().
13671 { 13672 /* if the transport type changes, clear all socket data */ 13673 if (socket->type != transport) { 13674 socket->fd = -1; 13675 socket->type = transport; 13676 if (socket->tcptls_session) { 13677 ao2_ref(socket->tcptls_session, -1); 13678 socket->tcptls_session = NULL; 13679 } 13680 } 13681 }
static void set_t38_capabilities | ( | struct sip_pvt * | p | ) | [static] |
Set the global T38 capabilities on a SIP dialog structure.
Definition at line 5159 of file chan_sip.c.
References ast_test_flag, ast_udptl_set_error_correction_scheme(), UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by check_peer_ok(), and initialize_udptl().
05160 { 05161 if (p->udptl) { 05162 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY) { 05163 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05164 } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL_FEC) { 05165 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05166 } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL) { 05167 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05168 } 05169 } 05170 }
static int setup_srtp | ( | struct sip_srtp ** | srtp | ) | [static] |
Definition at line 29486 of file chan_sip.c.
References ast_log(), ast_rtp_engine_srtp_is_registered(), LOG_ERROR, and sip_srtp_alloc().
Referenced by process_crypto(), and sip_call().
29487 { 29488 if (!ast_rtp_engine_srtp_is_registered()) { 29489 ast_log(LOG_ERROR, "No SRTP module loaded, can't setup SRTP session.\n"); 29490 return -1; 29491 } 29492 29493 if (!(*srtp = sip_srtp_alloc())) { /* Allocate SRTP data structure */ 29494 return -1; 29495 } 29496 29497 return 0; 29498 }
static int show_channels_cb | ( | void * | __cur, | |
void * | __arg, | |||
int | flags | |||
) | [static] |
callback for show channel|subscription
Definition at line 18275 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().
18276 { 18277 struct sip_pvt *cur = __cur; 18278 struct __show_chan_arg *arg = __arg; 18279 const struct ast_sockaddr *dst = sip_real_dst(cur); 18280 18281 /* XXX indentation preserved to reduce diff. Will be fixed later */ 18282 if (cur->subscribed == NONE && !arg->subscriptions) { 18283 /* set if SIP transfer in progress */ 18284 const char *referstatus = cur->refer ? referstatus2str(cur->refer->status) : ""; 18285 char formatbuf[SIPBUFSIZE/2]; 18286 18287 ast_cli(arg->fd, FORMAT, ast_sockaddr_stringify_addr(dst), 18288 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 18289 cur->callid, 18290 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 18291 AST_CLI_YESNO(ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD)), 18292 cur->needdestroy ? "(d)" : "", 18293 cur->lastmsg , 18294 referstatus, 18295 cur->relatedpeer ? cur->relatedpeer->name : "<guest>" 18296 ); 18297 arg->numchans++; 18298 } 18299 if (cur->subscribed != NONE && arg->subscriptions) { 18300 struct ast_str *mailbox_str = ast_str_alloca(512); 18301 if (cur->subscribed == MWI_NOTIFICATION && cur->relatedpeer) 18302 peer_mailboxes_to_str(&mailbox_str, cur->relatedpeer); 18303 ast_cli(arg->fd, FORMAT4, ast_sockaddr_stringify_addr(dst), 18304 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 18305 cur->callid, 18306 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 18307 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 18308 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 18309 subscription_type2str(cur->subscribed), 18310 cur->subscribed == MWI_NOTIFICATION ? S_OR(mailbox_str->str, "<none>") : "<none>", 18311 cur->expiry 18312 ); 18313 arg->numchans++; 18314 } 18315 return 0; /* don't care, we scan all channels */ 18316 }
static int show_chanstats_cb | ( | void * | __cur, | |
void * | __arg, | |||
int | flags | |||
) | [static] |
Callback for show_chanstats.
Definition at line 17889 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().
17890 { 17891 #define FORMAT2 "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n" 17892 #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" 17893 struct sip_pvt *cur = __cur; 17894 struct ast_rtp_instance_stats stats; 17895 char durbuf[10]; 17896 int duration; 17897 int durh, durm, durs; 17898 struct ast_channel *c = cur->owner; 17899 struct __show_chan_arg *arg = __arg; 17900 int fd = arg->fd; 17901 17902 17903 if (cur->subscribed != NONE) /* Subscriptions */ 17904 return 0; /* don't care, we scan all channels */ 17905 17906 if (!cur->rtp) { 17907 if (sipdebug) { 17908 ast_cli(fd, "%-15.15s %-11.11s (inv state: %s) -- %s\n", 17909 ast_sockaddr_stringify_addr(&cur->sa), cur->callid, 17910 invitestate2string[cur->invitestate].desc, 17911 "-- No RTP active"); 17912 } 17913 return 0; /* don't care, we scan all channels */ 17914 } 17915 17916 ast_rtp_instance_get_stats(cur->rtp, &stats, AST_RTP_INSTANCE_STAT_ALL); 17917 17918 if (c && c->cdr && !ast_tvzero(c->cdr->start)) { 17919 duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000); 17920 durh = duration / 3600; 17921 durm = (duration % 3600) / 60; 17922 durs = duration % 60; 17923 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs); 17924 } else { 17925 durbuf[0] = '\0'; 17926 } 17927 17928 ast_cli(fd, FORMAT, 17929 ast_sockaddr_stringify_addr(&cur->sa), 17930 cur->callid, 17931 durbuf, 17932 stats.rxcount > (unsigned int) 100000 ? (unsigned int) (stats.rxcount)/(unsigned int) 1000 : stats.rxcount, 17933 stats.rxcount > (unsigned int) 100000 ? "K":" ", 17934 stats.rxploss, 17935 (stats.rxcount + stats.rxploss) > 0 ? (double) stats.rxploss / (stats.rxcount + stats.rxploss) * 100 : 0, 17936 stats.rxjitter, 17937 stats.txcount > (unsigned int) 100000 ? (unsigned int) (stats.txcount)/(unsigned int) 1000 : stats.txcount, 17938 stats.txcount > (unsigned int) 100000 ? "K":" ", 17939 stats.txploss, 17940 stats.txcount > 0 ? (double) stats.txploss / stats.txcount * 100 : 0, 17941 stats.txjitter 17942 ); 17943 arg->numchans++; 17944 17945 return 0; /* don't care, we scan all channels */ 17946 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 29278 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().
29279 { 29280 int no = 0; 29281 int ok = FALSE; 29282 char varbuf[30]; 29283 const char *inbuf = data; 29284 char *subbuf; 29285 29286 if (ast_strlen_zero(inbuf)) { 29287 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 29288 return 0; 29289 } 29290 ast_channel_lock(chan); 29291 29292 /* Check for headers */ 29293 while (!ok && no <= 50) { 29294 no++; 29295 snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no); 29296 29297 /* Compare without the leading underscores */ 29298 if ((pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL)) { 29299 ok = TRUE; 29300 } 29301 } 29302 if (ok) { 29303 size_t len = strlen(inbuf); 29304 subbuf = alloca(len + 1); 29305 ast_get_encoded_str(inbuf, subbuf, len + 1); 29306 pbx_builtin_setvar_helper(chan, varbuf, subbuf); 29307 if (sipdebug) { 29308 ast_debug(1, "SIP Header added \"%s\" as %s\n", inbuf, varbuf); 29309 } 29310 } else { 29311 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 29312 } 29313 ast_channel_unlock(chan); 29314 return 0; 29315 }
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 7639 of file chan_sip.c.
References ao2_t_alloc, ao2_t_link, ao2_t_ref, ast_cc_config_params_init, ast_copy_flags, ast_debug, AST_LIST_HEAD_INIT_NOLOCK, ast_random(), AST_RTP_DTMF, ast_sip_ouraddrfor(), ast_sockaddr_copy(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_callid_pvt(), build_via(), context, default_engine, default_fromdomain, default_fromdomainport, default_maxcallbitrate, default_mohinterpret, default_mohsuggest, default_parkinglot, default_prefs, dialogs, do_setnat(), free_via(), get_header(), global_autoframing, global_flags, global_t1, global_timer_b, internip, make_our_tag(), mohinterpret, mohsuggest, NONE, parkinglot, parse_via(), recordhistory, set_socket_transport(), sip_cfg, sip_destroy_fn(), sip_methods, cfsip_methods::text, and TRUE.
Referenced by __sip_subscribe_mwi_do(), find_call(), manager_sipnotify(), sip_cc_monitor_request_cc(), sip_cli_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), and transmit_register().
07641 { 07642 struct sip_pvt *p; 07643 07644 if (!(p = ao2_t_alloc(sizeof(*p), sip_destroy_fn, "allocate a dialog(pvt) struct"))) 07645 return NULL; 07646 07647 if (ast_string_field_init(p, 512)) { 07648 ao2_t_ref(p, -1, "failed to string_field_init, drop p"); 07649 return NULL; 07650 } 07651 07652 if (!(p->cc_params = ast_cc_config_params_init())) { 07653 ao2_t_ref(p, -1, "Yuck, couldn't allocate cc_params struct. Get rid o' p"); 07654 return NULL; 07655 } 07656 07657 /* If this dialog is created as the result of an incoming Request. Lets store 07658 * some information about that request */ 07659 if (req) { 07660 struct sip_via *via; 07661 const char *cseq = get_header(req, "Cseq"); 07662 unsigned int seqno; 07663 07664 /* get branch parameter from initial Request that started this dialog */ 07665 via = parse_via(get_header(req, "Via")); 07666 if (via) { 07667 /* only store the branch if it begins with the magic prefix "z9hG4bK", otherwise 07668 * it is not useful to us to have it */ 07669 if (!ast_strlen_zero(via->branch) && !strncasecmp(via->branch, "z9hG4bK", 7)) { 07670 ast_string_field_set(p, initviabranch, via->branch); 07671 ast_string_field_set(p, initviasentby, via->sent_by); 07672 } 07673 free_via(via); 07674 } 07675 07676 /* Store initial incoming cseq. An error in sscanf here is ignored. There is no approperiate 07677 * except not storing the number. CSeq validation must take place before dialog creation in find_call */ 07678 if (!ast_strlen_zero(cseq) && (sscanf(cseq, "%30u", &seqno) == 1)) { 07679 p->init_icseq = seqno; 07680 } 07681 /* Later in ast_sip_ouraddrfor we need this to choose the right ip and port for the specific transport */ 07682 set_socket_transport(&p->socket, req->socket.type); 07683 } else { 07684 set_socket_transport(&p->socket, SIP_TRANSPORT_UDP); 07685 } 07686 07687 p->socket.fd = -1; 07688 p->method = intended_method; 07689 p->initid = -1; 07690 p->waitid = -1; 07691 p->autokillid = -1; 07692 p->request_queue_sched_id = -1; 07693 p->provisional_keepalive_sched_id = -1; 07694 p->t38id = -1; 07695 p->subscribed = NONE; 07696 p->stateid = -1; 07697 p->sessionversion_remote = -1; 07698 p->session_modify = TRUE; 07699 p->stimer = NULL; 07700 p->prefs = default_prefs; /* Set default codecs for this call */ 07701 p->maxforwards = sip_cfg.default_max_forwards; 07702 07703 if (intended_method != SIP_OPTIONS) { /* Peerpoke has it's own system */ 07704 p->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */ 07705 p->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */ 07706 } 07707 07708 if (!addr) { 07709 p->ourip = internip; 07710 } else { 07711 ast_sockaddr_copy(&p->sa, addr); 07712 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 07713 } 07714 07715 /* Copy global flags to this PVT at setup. */ 07716 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 07717 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 07718 ast_copy_flags(&p->flags[2], &global_flags[2], SIP_PAGE3_FLAGS_TO_COPY); 07719 07720 p->do_history = recordhistory; 07721 07722 p->branch = ast_random(); 07723 make_our_tag(p->tag, sizeof(p->tag)); 07724 p->ocseq = INITIAL_CSEQ; 07725 p->allowed_methods = UINT_MAX; 07726 07727 if (sip_methods[intended_method].need_rtp) { 07728 p->maxcallbitrate = default_maxcallbitrate; 07729 p->autoframing = global_autoframing; 07730 } 07731 07732 if (useglobal_nat && addr) { 07733 /* Setup NAT structure according to global settings if we have an address */ 07734 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT); 07735 ast_sockaddr_copy(&p->recv, addr); 07736 07737 do_setnat(p); 07738 } 07739 07740 if (p->method != SIP_REGISTER) { 07741 ast_string_field_set(p, fromdomain, default_fromdomain); 07742 p->fromdomainport = default_fromdomainport; 07743 } 07744 build_via(p); 07745 if (!callid) 07746 build_callid_pvt(p); 07747 else 07748 ast_string_field_set(p, callid, callid); 07749 /* Assign default music on hold class */ 07750 ast_string_field_set(p, mohinterpret, default_mohinterpret); 07751 ast_string_field_set(p, mohsuggest, default_mohsuggest); 07752 p->capability = sip_cfg.capability; 07753 p->allowtransfer = sip_cfg.allowtransfer; 07754 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 07755 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 07756 p->noncodeccapability |= AST_RTP_DTMF; 07757 } 07758 ast_string_field_set(p, context, sip_cfg.default_context); 07759 ast_string_field_set(p, parkinglot, default_parkinglot); 07760 ast_string_field_set(p, engine, default_engine); 07761 07762 AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue); 07763 07764 /* Add to active dialog list */ 07765 07766 ao2_t_link(dialogs, p, "link pvt into dialogs table"); 07767 07768 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"); 07769 return p; 07770 }
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 3084 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().
03085 { 03086 ast_debug(3, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 03087 dialog->alreadygone = 1; 03088 }
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 6464 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().
06465 { 06466 int res = 0; 06467 struct sip_pvt *p = ast->tech_pvt; 06468 06469 sip_pvt_lock(p); 06470 if (ast->_state != AST_STATE_UP) { 06471 try_suggested_sip_codec(p); 06472 06473 ast_setstate(ast, AST_STATE_UP); 06474 ast_debug(1, "SIP answering channel: %s\n", ast->name); 06475 ast_rtp_instance_update_source(p->rtp); 06476 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL, FALSE, TRUE); 06477 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 06478 } 06479 sip_pvt_unlock(p); 06480 return res; 06481 }
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 5533 of file chan_sip.c.
References ast_channel::_state, ao2_t_ref, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_USER_BUSY, ast_cc_get_monitor_by_recall_core_id(), ast_cc_is_recall(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_channel_queue_connected_line_update(), ast_clear_flag, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, ast_copy_string(), ast_debug, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), ast_party_connected_line_init(), ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_rtp_instance_available_formats(), AST_SCHED_REPLACE_UNREF, ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_var_name(), ast_var_value(), auto_congest(), ast_channel::caller, cid_name, connected, ast_channel::hangupcause, ast_party_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.
05534 { 05535 int res; 05536 struct sip_pvt *p = ast->tech_pvt; /* chan is locked, so the reference cannot go away */ 05537 struct varshead *headp; 05538 struct ast_var_t *current; 05539 const char *referer = NULL; /* SIP referrer */ 05540 int cc_core_id; 05541 char uri[SIPBUFSIZE] = ""; 05542 05543 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 05544 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 05545 return -1; 05546 } 05547 05548 if (ast_cc_is_recall(ast, &cc_core_id, "SIP")) { 05549 char device_name[AST_CHANNEL_NAME]; 05550 struct ast_cc_monitor *recall_monitor; 05551 struct sip_monitor_instance *monitor_instance; 05552 ast_channel_get_device_name(ast, device_name, sizeof(device_name)); 05553 if ((recall_monitor = ast_cc_get_monitor_by_recall_core_id(cc_core_id, device_name))) { 05554 monitor_instance = recall_monitor->private_data; 05555 ast_copy_string(uri, monitor_instance->notify_uri, sizeof(uri)); 05556 ao2_t_ref(recall_monitor, -1, "Got the URI we need so unreffing monitor"); 05557 } 05558 } 05559 05560 /* Check whether there is vxml_url, distinctive ring variables */ 05561 headp=&ast->varshead; 05562 AST_LIST_TRAVERSE(headp, current, entries) { 05563 /* Check whether there is a VXML_URL variable */ 05564 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 05565 p->options->vxml_url = ast_var_value(current); 05566 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 05567 p->options->uri_options = ast_var_value(current); 05568 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 05569 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 05570 p->options->addsipheaders = 1; 05571 } else if (!strcasecmp(ast_var_name(current), "SIPFROMDOMAIN")) { 05572 ast_string_field_set(p, fromdomain, ast_var_value(current)); 05573 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 05574 /* This is a transfered call */ 05575 p->options->transfer = 1; 05576 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 05577 /* This is the referrer */ 05578 referer = ast_var_value(current); 05579 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 05580 /* We're replacing a call. */ 05581 p->options->replaces = ast_var_value(current); 05582 } else if (!strcasecmp(ast_var_name(current), "SIP_MAX_FORWARDS")) { 05583 if (sscanf(ast_var_value(current), "%d", &(p->maxforwards)) != 1) { 05584 ast_log(LOG_WARNING, "The SIP_MAX_FORWARDS channel variable is not a valid integer."); 05585 } 05586 } 05587 } 05588 05589 /* Check to see if we should try to force encryption */ 05590 if (p->req_secure_signaling && p->socket.type != SIP_TRANSPORT_TLS) { 05591 ast_log(LOG_WARNING, "Encrypted signaling is required\n"); 05592 ast->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05593 return -1; 05594 } 05595 05596 if (ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) { 05597 if (ast_test_flag(&p->flags[0], SIP_REINVITE)) { 05598 ast_debug(1, "Direct media not possible when using SRTP, ignoring canreinvite setting\n"); 05599 ast_clear_flag(&p->flags[0], SIP_REINVITE); 05600 } 05601 05602 if (p->rtp && !p->srtp && setup_srtp(&p->srtp) < 0) { 05603 ast_log(LOG_WARNING, "SRTP audio setup failed\n"); 05604 return -1; 05605 } 05606 05607 if (p->vrtp && !p->vsrtp && setup_srtp(&p->vsrtp) < 0) { 05608 ast_log(LOG_WARNING, "SRTP video setup failed\n"); 05609 return -1; 05610 } 05611 05612 if (p->trtp && !p->tsrtp && setup_srtp(&p->tsrtp) < 0) { 05613 ast_log(LOG_WARNING, "SRTP text setup failed\n"); 05614 return -1; 05615 } 05616 } 05617 05618 res = 0; 05619 ast_set_flag(&p->flags[0], SIP_OUTGOING); 05620 05621 /* T.38 re-INVITE FAX detection should never be done for outgoing calls, 05622 * so ensure it is disabled. 05623 */ 05624 ast_clear_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_T38); 05625 05626 if (p->options->transfer) { 05627 char buf[SIPBUFSIZE/2]; 05628 05629 if (referer) { 05630 if (sipdebug) 05631 ast_debug(3, "Call for %s transfered by %s\n", p->username, referer); 05632 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 05633 } else 05634 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 05635 ast_string_field_set(p, cid_name, buf); 05636 } 05637 ast_debug(1, "Outgoing Call for %s\n", p->username); 05638 05639 res = update_call_counter(p, INC_CALL_RINGING); 05640 05641 if (res == -1) { 05642 ast->hangupcause = AST_CAUSE_USER_BUSY; 05643 return res; 05644 } 05645 p->callingpres = ast_party_id_presentation(&ast->caller.id); 05646 p->jointcapability = ast_rtp_instance_available_formats(p->rtp, p->capability, p->prefcodec); 05647 p->jointnoncodeccapability = p->noncodeccapability; 05648 05649 /* If there are no audio formats left to offer, punt */ 05650 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05651 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 05652 res = -1; 05653 } else { 05654 int xmitres; 05655 struct ast_party_connected_line connected; 05656 struct ast_set_party_connected_line update_connected; 05657 05658 sip_pvt_lock(p); 05659 05660 /* Supply initial connected line information if available. */ 05661 memset(&update_connected, 0, sizeof(update_connected)); 05662 ast_party_connected_line_init(&connected); 05663 if (!ast_strlen_zero(p->cid_num) 05664 || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 05665 update_connected.id.number = 1; 05666 connected.id.number.valid = 1; 05667 connected.id.number.str = (char *) p->cid_num; 05668 connected.id.number.presentation = p->callingpres; 05669 } 05670 if (!ast_strlen_zero(p->cid_name) 05671 || (p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { 05672 update_connected.id.name = 1; 05673 connected.id.name.valid = 1; 05674 connected.id.name.str = (char *) p->cid_name; 05675 connected.id.name.presentation = p->callingpres; 05676 } 05677 if (update_connected.id.number || update_connected.id.name) { 05678 connected.id.tag = (char *) p->cid_tag; 05679 connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 05680 ast_channel_queue_connected_line_update(ast, &connected, &update_connected); 05681 } 05682 05683 xmitres = transmit_invite(p, SIP_INVITE, 1, 2, uri); 05684 sip_pvt_unlock(p); 05685 if (xmitres == XMIT_ERROR) 05686 return -1; 05687 p->invitestate = INV_CALLING; 05688 05689 /* Initialize auto-congest time */ 05690 AST_SCHED_REPLACE_UNREF(p->initid, sched, p->timer_b, auto_congest, p, 05691 dialog_unref(_data, "dialog ptr dec when SCHED_REPLACE del op succeeded"), 05692 dialog_unref(p, "dialog ptr dec when SCHED_REPLACE add failed"), 05693 dialog_ref(p, "dialog ptr inc when SCHED_REPLACE add succeeded") ); 05694 } 05695 return res; 05696 }
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 3953 of file chan_sip.c.
References append_history, and AST_SCHED_DEL_UNREF.
Referenced by handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), sip_hangup(), and sip_scheddestroy().
03954 { 03955 if (p->final_destruction_scheduled) { 03956 return 0; 03957 } 03958 03959 if (p->autokillid > -1) { 03960 append_history(p, "CancelDestroy", ""); 03961 AST_SCHED_DEL_UNREF(sched, p->autokillid, dialog_unref(p, "remove ref for autokillid")); 03962 } 03963 return 0; 03964 }
static void sip_cc_agent_destructor | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1812 of file chan_sip.c.
References ast_free, ast_test_flag, ast_cc_agent::private_data, sip_cc_agent_stop_offer_timer(), sip_pvt_lock, sip_pvt_unlock, and transmit_response().
01813 { 01814 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01815 01816 if (!agent_pvt) { 01817 /* The agent constructor probably failed. */ 01818 return; 01819 } 01820 01821 sip_cc_agent_stop_offer_timer(agent); 01822 if (agent_pvt->subscribe_pvt) { 01823 sip_pvt_lock(agent_pvt->subscribe_pvt); 01824 if (!ast_test_flag(&agent_pvt->subscribe_pvt->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 01825 /* If we haven't sent a 200 OK for the SUBSCRIBE dialog yet, then we need to send a response letting 01826 * the subscriber know something went wrong 01827 */ 01828 transmit_response(agent_pvt->subscribe_pvt, "500 Internal Server Error", &agent_pvt->subscribe_pvt->initreq); 01829 } 01830 sip_pvt_unlock(agent_pvt->subscribe_pvt); 01831 agent_pvt->subscribe_pvt = dialog_unref(agent_pvt->subscribe_pvt, "SIP CC agent destructor: Remove ref to subscription"); 01832 } 01833 ast_free(agent_pvt); 01834 }
static int sip_cc_agent_init | ( | struct ast_cc_agent * | agent, | |
struct ast_channel * | chan | |||
) | [static] |
Definition at line 1699 of file chan_sip.c.
References ast_assert, ast_calloc, ast_copy_string(), ast_set_flag, ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech, ast_channel::tech_pvt, and ast_channel_tech::type.
01700 { 01701 struct sip_cc_agent_pvt *agent_pvt = ast_calloc(1, sizeof(*agent_pvt)); 01702 struct sip_pvt *call_pvt = chan->tech_pvt; 01703 01704 if (!agent_pvt) { 01705 return -1; 01706 } 01707 01708 ast_assert(!strcmp(chan->tech->type, "SIP")); 01709 01710 ast_copy_string(agent_pvt->original_callid, call_pvt->callid, sizeof(agent_pvt->original_callid)); 01711 ast_copy_string(agent_pvt->original_exten, call_pvt->exten, sizeof(agent_pvt->original_exten)); 01712 agent_pvt->offer_timer_id = -1; 01713 agent->private_data = agent_pvt; 01714 sip_pvt_lock(call_pvt); 01715 ast_set_flag(&call_pvt->flags[0], SIP_OFFER_CC); 01716 sip_pvt_unlock(call_pvt); 01717 return 0; 01718 }
static int sip_cc_agent_recall | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1792 of file chan_sip.c.
References ast_cc_agent_caller_busy(), ast_cc_agent::core_id, ast_cc_agent::device_name, ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, and transmit_cc_notify().
01793 { 01794 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01795 /* If we have received a PUBLISH beforehand stating that the caller in question 01796 * is not available, we can save ourself a bit of effort here and just report 01797 * the caller as busy 01798 */ 01799 if (!agent_pvt->is_available) { 01800 return ast_cc_agent_caller_busy(agent->core_id, "Caller %s is busy, reporting to the core", 01801 agent->device_name); 01802 } 01803 /* Otherwise, we transmit a NOTIFY to the caller and await either 01804 * a PUBLISH or an INVITE 01805 */ 01806 sip_pvt_lock(agent_pvt->subscribe_pvt); 01807 transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_READY); 01808 sip_pvt_unlock(agent_pvt->subscribe_pvt); 01809 return 0; 01810 }
static void sip_cc_agent_respond | ( | struct ast_cc_agent * | agent, | |
enum ast_cc_agent_response_reason | reason | |||
) | [static] |
Definition at line 1748 of file chan_sip.c.
References AST_CC_AGENT_RESPONSE_SUCCESS, ast_set_flag, ast_strlen_zero(), ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, transmit_cc_notify(), transmit_response(), and TRUE.
01749 { 01750 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01751 01752 sip_pvt_lock(agent_pvt->subscribe_pvt); 01753 ast_set_flag(&agent_pvt->subscribe_pvt->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 01754 if (reason == AST_CC_AGENT_RESPONSE_SUCCESS || !ast_strlen_zero(agent_pvt->notify_uri)) { 01755 /* The second half of this if statement may be a bit hard to grasp, 01756 * so here's an explanation. When a subscription comes into 01757 * chan_sip, as long as it is not malformed, it will be passed 01758 * to the CC core. If the core senses an out-of-order state transition, 01759 * then the core will call this callback with the "reason" set to a 01760 * failure condition. 01761 * However, an out-of-order state transition will occur during a resubscription 01762 * for CC. In such a case, we can see that we have already generated a notify_uri 01763 * and so we can detect that this isn't a *real* failure. Rather, it is just 01764 * something the core doesn't recognize as a legitimate SIP state transition. 01765 * Thus we respond with happiness and flowers. 01766 */ 01767 transmit_response(agent_pvt->subscribe_pvt, "200 OK", &agent_pvt->subscribe_pvt->initreq); 01768 transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_QUEUED); 01769 } else { 01770 transmit_response(agent_pvt->subscribe_pvt, "500 Internal Error", &agent_pvt->subscribe_pvt->initreq); 01771 } 01772 sip_pvt_unlock(agent_pvt->subscribe_pvt); 01773 agent_pvt->is_available = TRUE; 01774 }
static int sip_cc_agent_start_monitoring | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1783 of file chan_sip.c.
01784 { 01785 /* To start monitoring just means to wait for an incoming PUBLISH 01786 * to tell us that the caller has become available again. No special 01787 * action is needed 01788 */ 01789 return 0; 01790 }
static int sip_cc_agent_start_offer_timer | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1730 of file chan_sip.c.
References ast_get_cc_offer_timer(), ast_sched_add(), ast_cc_agent::cc_params, ast_cc_agent::private_data, sched, and sip_offer_timer_expire().
01731 { 01732 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01733 int when; 01734 01735 when = ast_get_cc_offer_timer(agent->cc_params) * 1000; 01736 agent_pvt->offer_timer_id = ast_sched_add(sched, when, sip_offer_timer_expire, agent); 01737 return 0; 01738 }
static int sip_cc_agent_status_request | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1776 of file chan_sip.c.
References ast_cc_agent_status_response(), AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, ast_device_state(), ast_cc_agent::core_id, and ast_cc_agent::private_data.
01777 { 01778 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01779 enum ast_device_state state = agent_pvt->is_available ? AST_DEVICE_NOT_INUSE : AST_DEVICE_INUSE; 01780 return ast_cc_agent_status_response(agent->core_id, state); 01781 }
static int sip_cc_agent_stop_offer_timer | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 1740 of file chan_sip.c.
References AST_SCHED_DEL, ast_cc_agent::private_data, and sched.
Referenced by sip_cc_agent_destructor().
01741 { 01742 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01743 01744 AST_SCHED_DEL(sched, agent_pvt->offer_timer_id); 01745 return 0; 01746 }
static int sip_cc_monitor_cancel_available_timer | ( | struct ast_cc_monitor * | monitor, | |
int * | sched_id | |||
) | [static] |
Definition at line 2051 of file chan_sip.c.
References ao2_t_ref, AST_SCHED_DEL, monitor, and sched.
02052 { 02053 if (*sched_id != -1) { 02054 AST_SCHED_DEL(sched, *sched_id); 02055 ao2_t_ref(monitor, -1, "Removing scheduler's reference to the monitor"); 02056 } 02057 return 0; 02058 }
static void sip_cc_monitor_destructor | ( | void * | private_data | ) | [static] |
Definition at line 2060 of file chan_sip.c.
References ao2_unlink, ast_module_unref(), and sip_monitor_instances.
02061 { 02062 struct sip_monitor_instance *monitor_instance = private_data; 02063 ao2_unlink(sip_monitor_instances, monitor_instance); 02064 ast_module_unref(ast_module_info->self); 02065 }
static int sip_cc_monitor_request_cc | ( | struct ast_cc_monitor * | monitor, | |
int * | available_timer_id | |||
) | [static] |
Definition at line 1918 of file chan_sip.c.
References ao2_t_ref, ast_cc_available_timer_expire(), AST_CC_CCBS, ast_get_ccbs_available_timer(), ast_get_ccnr_available_timer(), ast_sched_add(), ast_set_flag, ast_sip_ouraddrfor(), create_addr(), FALSE, monitor, sched, service, sip_alloc(), sip_pvt_lock, sip_pvt_unlock, and transmit_invite().
01919 { 01920 struct sip_monitor_instance *monitor_instance = monitor->private_data; 01921 enum ast_cc_service_type service = monitor->service_offered; 01922 int when; 01923 01924 if (!monitor_instance) { 01925 return -1; 01926 } 01927 01928 if (!(monitor_instance->subscription_pvt = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL))) { 01929 return -1; 01930 } 01931 01932 when = service == AST_CC_CCBS ? ast_get_ccbs_available_timer(monitor->interface->config_params) : 01933 ast_get_ccnr_available_timer(monitor->interface->config_params); 01934 01935 sip_pvt_lock(monitor_instance->subscription_pvt); 01936 ast_set_flag(&monitor_instance->subscription_pvt->flags[0], SIP_OUTGOING); 01937 create_addr(monitor_instance->subscription_pvt, monitor_instance->peername, 0, 1, NULL); 01938 ast_sip_ouraddrfor(&monitor_instance->subscription_pvt->sa, &monitor_instance->subscription_pvt->ourip, monitor_instance->subscription_pvt); 01939 monitor_instance->subscription_pvt->subscribed = CALL_COMPLETION; 01940 monitor_instance->subscription_pvt->expiry = when; 01941 01942 transmit_invite(monitor_instance->subscription_pvt, SIP_SUBSCRIBE, FALSE, 2, monitor_instance->subscribe_uri); 01943 sip_pvt_unlock(monitor_instance->subscription_pvt); 01944 01945 ao2_t_ref(monitor, +1, "Adding a ref to the monitor for the scheduler"); 01946 *available_timer_id = ast_sched_add(sched, when * 1000, ast_cc_available_timer_expire, monitor); 01947 return 0; 01948 }
static int sip_cc_monitor_suspend | ( | struct ast_cc_monitor * | monitor | ) | [static] |
Definition at line 1976 of file chan_sip.c.
References ao2_ref, ast_calloc, ast_log(), ast_strlen_zero(), construct_pidf_body(), create_epa_entry(), LOG_WARNING, monitor, and transmit_publish().
01977 { 01978 struct sip_monitor_instance *monitor_instance = monitor->private_data; 01979 enum sip_publish_type publish_type; 01980 struct cc_epa_entry *cc_entry; 01981 01982 if (!monitor_instance) { 01983 return -1; 01984 } 01985 01986 if (!monitor_instance->suspension_entry) { 01987 /* We haven't yet allocated the suspension entry, so let's give it a shot */ 01988 if (!(monitor_instance->suspension_entry = create_epa_entry("call-completion", monitor_instance->peername))) { 01989 ast_log(LOG_WARNING, "Unable to allocate sip EPA entry for call-completion\n"); 01990 ao2_ref(monitor_instance, -1); 01991 return -1; 01992 } 01993 if (!(cc_entry = ast_calloc(1, sizeof(*cc_entry)))) { 01994 ast_log(LOG_WARNING, "Unable to allocate space for instance data of EPA entry for call-completion\n"); 01995 ao2_ref(monitor_instance, -1); 01996 return -1; 01997 } 01998 cc_entry->core_id = monitor->core_id; 01999 monitor_instance->suspension_entry->instance_data = cc_entry; 02000 publish_type = SIP_PUBLISH_INITIAL; 02001 } else { 02002 publish_type = SIP_PUBLISH_MODIFY; 02003 cc_entry = monitor_instance->suspension_entry->instance_data; 02004 } 02005 02006 cc_entry->current_state = CC_CLOSED; 02007 02008 if (ast_strlen_zero(monitor_instance->notify_uri)) { 02009 /* If we have no set notify_uri, then what this means is that we have 02010 * not received a NOTIFY from this destination stating that he is 02011 * currently available. 02012 * 02013 * This situation can arise when the core calls the suspend callbacks 02014 * of multiple destinations. If one of the other destinations aside 02015 * from this one notified Asterisk that he is available, then there 02016 * is no reason to take any suspension action on this device. Rather, 02017 * we should return now and if we receive a NOTIFY while monitoring 02018 * is still "suspended" then we can immediately respond with the 02019 * proper PUBLISH to let this endpoint know what is going on. 02020 */ 02021 return 0; 02022 } 02023 construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername); 02024 return transmit_publish(monitor_instance->suspension_entry, publish_type, monitor_instance->notify_uri); 02025 }
static int sip_cc_monitor_unsuspend | ( | struct ast_cc_monitor * | monitor | ) | [static] |
Definition at line 2027 of file chan_sip.c.
References ast_assert, ast_strlen_zero(), construct_pidf_body(), monitor, and transmit_publish().
02028 { 02029 struct sip_monitor_instance *monitor_instance = monitor->private_data; 02030 struct cc_epa_entry *cc_entry; 02031 02032 if (!monitor_instance) { 02033 return -1; 02034 } 02035 02036 ast_assert(monitor_instance->suspension_entry != NULL); 02037 02038 cc_entry = monitor_instance->suspension_entry->instance_data; 02039 cc_entry->current_state = CC_OPEN; 02040 if (ast_strlen_zero(monitor_instance->notify_uri)) { 02041 /* This means we are being asked to unsuspend a call leg we never 02042 * sent a PUBLISH on. As such, there is no reason to send another 02043 * PUBLISH at this point either. We can just return instead. 02044 */ 02045 return 0; 02046 } 02047 construct_pidf_body(CC_OPEN, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername); 02048 return transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_MODIFY, monitor_instance->notify_uri); 02049 }
static int sip_check_authtimeout | ( | time_t | start | ) | [static] |
Check if the authtimeout has expired.
start | the time when the session started |
0 | the timeout has expired | |
-1 | error |
Definition at line 2481 of file chan_sip.c.
References ast_log(), authtimeout, errno, and LOG_ERROR.
Referenced by _sip_tcp_helper_thread().
02482 { 02483 int timeout; 02484 time_t now; 02485 if(time(&now) == -1) { 02486 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno)); 02487 return -1; 02488 } 02489 02490 timeout = (authtimeout - (now - start)) * 1000; 02491 if (timeout < 0) { 02492 /* we have timed out */ 02493 return 0; 02494 } 02495 02496 return timeout; 02497 }
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 18952 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(), ast_cli_entry::usage, var, and ast_cli_args::word.
18953 { 18954 struct ast_variable *varlist; 18955 int i; 18956 18957 switch (cmd) { 18958 case CLI_INIT: 18959 e->command = "sip notify"; 18960 e->usage = 18961 "Usage: sip notify <type> <peer> [<peer>...]\n" 18962 " Send a NOTIFY message to a SIP peer or peers\n" 18963 " Message types are defined in sip_notify.conf\n"; 18964 return NULL; 18965 case CLI_GENERATE: 18966 return complete_sipnotify(a->line, a->word, a->pos, a->n); 18967 } 18968 18969 if (a->argc < 4) 18970 return CLI_SHOWUSAGE; 18971 18972 if (!notify_types) { 18973 ast_cli(a->fd, "No %s file found, or no types listed there\n", notify_config); 18974 return CLI_FAILURE; 18975 } 18976 18977 varlist = ast_variable_browse(notify_types, a->argv[2]); 18978 18979 if (!varlist) { 18980 ast_cli(a->fd, "Unable to find notify type '%s'\n", a->argv[2]); 18981 return CLI_FAILURE; 18982 } 18983 18984 for (i = 3; i < a->argc; i++) { 18985 struct sip_pvt *p; 18986 char buf[512]; 18987 struct ast_variable *header, *var; 18988 18989 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) { 18990 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 18991 return CLI_FAILURE; 18992 } 18993 18994 if (create_addr(p, a->argv[i], NULL, 1, NULL)) { 18995 /* Maybe they're not registered, etc. */ 18996 dialog_unlink_all(p); 18997 dialog_unref(p, "unref dialog inside for loop" ); 18998 /* sip_destroy(p); */ 18999 ast_cli(a->fd, "Could not create address for '%s'\n", a->argv[i]); 19000 continue; 19001 } 19002 19003 /* Notify is outgoing call */ 19004 ast_set_flag(&p->flags[0], SIP_OUTGOING); 19005 sip_notify_allocate(p); 19006 p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", ""); 19007 19008 for (var = varlist; var; var = var->next) { 19009 ast_copy_string(buf, var->value, sizeof(buf)); 19010 ast_unescape_semicolon(buf); 19011 19012 if (!strcasecmp(var->name, "Content")) { 19013 if (ast_str_strlen(p->notify->content)) 19014 ast_str_append(&p->notify->content, 0, "\r\n"); 19015 ast_str_append(&p->notify->content, 0, "%s", buf); 19016 } else if (!strcasecmp(var->name, "Content-Length")) { 19017 ast_log(LOG_WARNING, "it is not necessary to specify Content-Length in sip_notify.conf, ignoring"); 19018 } else { 19019 header->next = ast_variable_new(var->name, buf, ""); 19020 header = header->next; 19021 } 19022 } 19023 19024 /* Recalculate our side, and recalculate Call ID */ 19025 ast_cli(a->fd, "Sending NOTIFY of type '%s' to '%s'\n", a->argv[2], a->argv[i]); 19026 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); 19027 transmit_invite(p, SIP_NOTIFY, 0, 2, NULL); 19028 dialog_unref(p, "bump down the count of p since we're done with it."); 19029 } 19030 19031 return CLI_SUCCESS; 19032 }
static int sip_debug_test_addr | ( | const struct ast_sockaddr * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 3181 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().
03182 { 03183 /* Can't debug if sipdebug is not enabled */ 03184 if (!sipdebug) { 03185 return 0; 03186 } 03187 03188 /* A null debug_addr means we'll debug any address */ 03189 if (ast_sockaddr_isnull(&debugaddr)) { 03190 return 1; 03191 } 03192 03193 /* If no port was specified for a debug address, just compare the 03194 * addresses, otherwise compare the address and port 03195 */ 03196 if (ast_sockaddr_port(&debugaddr)) { 03197 return !ast_sockaddr_cmp(&debugaddr, addr); 03198 } else { 03199 return !ast_sockaddr_cmp_addr(&debugaddr, addr); 03200 } 03201 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 3220 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().
03221 { 03222 if (!sipdebug) { 03223 return 0; 03224 } 03225 return sip_debug_test_addr(sip_real_dst(p)); 03226 }
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 6046 of file chan_sip.c.
References __sip_destroy(), ast_debug, and TRUE.
Referenced by sip_destroy_fn(), and sip_subscribe_mwi_destroy().
06047 { 06048 ast_debug(3, "Destroying SIP dialog %s\n", p->callid); 06049 __sip_destroy(p, TRUE, TRUE); 06050 return NULL; 06051 }
static void sip_destroy_fn | ( | void * | p | ) | [static] |
Definition at line 6036 of file chan_sip.c.
References sip_destroy().
Referenced by sip_alloc().
06037 { 06038 sip_destroy(p); 06039 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 4609 of file chan_sip.c.
References ao2_ref, ao2_t_ref, apeerobjs, ast_atomic_fetchadd_int(), ast_cc_config_params_destroy(), ast_debug, ast_free_ha(), ast_string_field_free_memory, ast_test_flag, ast_variables_destroy(), clear_peer_mailboxes(), dialog_unlink_all(), FALSE, global_flags, register_peer_exten(), rpeerobjs, and speerobjs.
Referenced by sip_destroy_peer_fn().
04610 { 04611 ast_debug(3, "Destroying SIP peer %s\n", peer->name); 04612 04613 /* 04614 * Remove any mailbox event subscriptions for this peer before 04615 * we destroy anything. An event subscription callback may be 04616 * happening right now. 04617 */ 04618 clear_peer_mailboxes(peer); 04619 04620 if (peer->outboundproxy) { 04621 ao2_ref(peer->outboundproxy, -1); 04622 peer->outboundproxy = NULL; 04623 } 04624 04625 /* Delete it, it needs to disappear */ 04626 if (peer->call) { 04627 dialog_unlink_all(peer->call); 04628 peer->call = dialog_unref(peer->call, "peer->call is being unset"); 04629 } 04630 04631 if (peer->mwipvt) { /* We have an active subscription, delete it */ 04632 dialog_unlink_all(peer->mwipvt); 04633 peer->mwipvt = dialog_unref(peer->mwipvt, "unreffing peer->mwipvt"); 04634 } 04635 04636 if (peer->chanvars) { 04637 ast_variables_destroy(peer->chanvars); 04638 peer->chanvars = NULL; 04639 } 04640 04641 register_peer_exten(peer, FALSE); 04642 ast_free_ha(peer->ha); 04643 ast_free_ha(peer->directmediaha); 04644 if (peer->selfdestruct) 04645 ast_atomic_fetchadd_int(&apeerobjs, -1); 04646 else if (!ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->is_realtime) { 04647 ast_atomic_fetchadd_int(&rpeerobjs, -1); 04648 ast_debug(3, "-REALTIME- peer Destroyed. Name: %s. Realtime Peer objects: %d\n", peer->name, rpeerobjs); 04649 } else 04650 ast_atomic_fetchadd_int(&speerobjs, -1); 04651 if (peer->auth) { 04652 ao2_t_ref(peer->auth, -1, "Removing peer authentication"); 04653 peer->auth = NULL; 04654 } 04655 04656 if (peer->socket.tcptls_session) { 04657 ao2_ref(peer->socket.tcptls_session, -1); 04658 peer->socket.tcptls_session = NULL; 04659 } 04660 04661 ast_cc_config_params_destroy(peer->cc_params); 04662 04663 ast_string_field_free_memory(peer); 04664 }
static void sip_destroy_peer_fn | ( | void * | peer | ) | [static] |
Definition at line 4603 of file chan_sip.c.
References sip_destroy_peer().
Referenced by build_peer(), and temp_peer().
04604 { 04605 sip_destroy_peer(peer); 04606 }
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 26300 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().
26301 { 26302 char *host; 26303 char *tmp; 26304 struct sip_peer *p; 26305 26306 int res = AST_DEVICE_INVALID; 26307 26308 /* make sure data is not null. Maybe unnecessary, but better be safe */ 26309 host = ast_strdupa(data ? data : ""); 26310 if ((tmp = strchr(host, '@'))) 26311 host = tmp + 1; 26312 26313 ast_debug(3, "Checking device state for peer %s\n", host); 26314 26315 /* If find_peer asks for a realtime peer, then this breaks rtautoclear. This 26316 * is because when a peer tries to autoexpire, the last thing it does is to 26317 * queue up an event telling the system that the devicestate has changed 26318 * (presumably to unavailable). If we ask for a realtime peer here, this would 26319 * load it BACK into memory, thus defeating the point of trying to clear dead 26320 * hosts out of memory. 26321 */ 26322 if ((p = find_peer(host, NULL, FALSE, FINDALLDEVICES, TRUE, 0))) { 26323 if (!(ast_sockaddr_isnull(&p->addr) && ast_sockaddr_isnull(&p->defaddr))) { 26324 /* we have an address for the peer */ 26325 26326 /* Check status in this order 26327 - Hold 26328 - Ringing 26329 - Busy (enforced only by call limit) 26330 - Inuse (we have a call) 26331 - Unreachable (qualify) 26332 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 26333 for registered devices */ 26334 26335 if (p->onHold) 26336 /* First check for hold or ring states */ 26337 res = AST_DEVICE_ONHOLD; 26338 else if (p->inRinging) { 26339 if (p->inRinging == p->inUse) 26340 res = AST_DEVICE_RINGING; 26341 else 26342 res = AST_DEVICE_RINGINUSE; 26343 } else if (p->call_limit && (p->inUse == p->call_limit)) 26344 /* check call limit */ 26345 res = AST_DEVICE_BUSY; 26346 else if (p->call_limit && p->busy_level && p->inUse >= p->busy_level) 26347 /* We're forcing busy before we've reached the call limit */ 26348 res = AST_DEVICE_BUSY; 26349 else if (p->call_limit && p->inUse) 26350 /* Not busy, but we do have a call */ 26351 res = AST_DEVICE_INUSE; 26352 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 26353 /* We don't have a call. Are we reachable at all? Requires qualify= */ 26354 res = AST_DEVICE_UNAVAILABLE; 26355 else /* Default reply if we're registered and have no other data */ 26356 res = AST_DEVICE_NOT_INUSE; 26357 } else { 26358 /* there is no address, it's unavailable */ 26359 res = AST_DEVICE_UNAVAILABLE; 26360 } 26361 unref_peer(p, "unref_peer, from sip_devicestate, release ref from find_peer"); 26362 } else { 26363 res = AST_DEVICE_UNKNOWN; 26364 } 26365 26366 return res; 26367 }
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 18909 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.
18910 { 18911 int oldsipdebug = sipdebug & sip_debug_console; 18912 const char *what; 18913 18914 if (cmd == CLI_INIT) { 18915 e->command = "sip set debug {on|off|ip|peer}"; 18916 e->usage = 18917 "Usage: sip set debug {off|on|ip addr[:port]|peer peername}\n" 18918 " Globally disables dumping of SIP packets,\n" 18919 " or enables it either globally or for a (single)\n" 18920 " IP address or registered peer.\n"; 18921 return NULL; 18922 } else if (cmd == CLI_GENERATE) { 18923 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) 18924 return complete_sip_peer(a->word, a->n, 0); 18925 return NULL; 18926 } 18927 18928 what = a->argv[e->args-1]; /* guaranteed to exist */ 18929 if (a->argc == e->args) { /* on/off */ 18930 if (!strcasecmp(what, "on")) { 18931 sipdebug |= sip_debug_console; 18932 sipdebug_text = 1; /*! \note this can be a special debug command - "sip debug text" or something */ 18933 memset(&debugaddr, 0, sizeof(debugaddr)); 18934 ast_cli(a->fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 18935 return CLI_SUCCESS; 18936 } else if (!strcasecmp(what, "off")) { 18937 sipdebug &= ~sip_debug_console; 18938 sipdebug_text = 0; 18939 ast_cli(a->fd, "SIP Debugging Disabled\n"); 18940 return CLI_SUCCESS; 18941 } 18942 } else if (a->argc == e->args +1) {/* ip/peer */ 18943 if (!strcasecmp(what, "ip")) 18944 return sip_do_debug_ip(a->fd, a->argv[e->args]); 18945 else if (!strcasecmp(what, "peer")) 18946 return sip_do_debug_peer(a->fd, a->argv[e->args]); 18947 } 18948 return CLI_SHOWUSAGE; /* default, failure */ 18949 }
static char * sip_do_debug_ip | ( | int | fd, | |
const char * | arg | |||
) | [static] |
Enable SIP Debugging for a single IP.
Definition at line 18878 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().
18879 { 18880 if (ast_sockaddr_resolve_first(&debugaddr, arg, 0)) { 18881 return CLI_SHOWUSAGE; 18882 } 18883 18884 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr)); 18885 sipdebug |= sip_debug_console; 18886 18887 return CLI_SUCCESS; 18888 }
static char * sip_do_debug_peer | ( | int | fd, | |
const char * | arg | |||
) | [static] |
Turn on SIP debugging for a given peer.
Definition at line 18891 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().
18892 { 18893 struct sip_peer *peer = find_peer(arg, NULL, TRUE, FINDPEERS, FALSE, 0); 18894 if (!peer) 18895 ast_cli(fd, "No such peer '%s'\n", arg); 18896 else if (ast_sockaddr_isnull(&peer->addr)) 18897 ast_cli(fd, "Unable to get IP address of peer '%s'\n", arg); 18898 else { 18899 ast_sockaddr_copy(&debugaddr, &peer->addr); 18900 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr)); 18901 sipdebug |= sip_debug_console; 18902 } 18903 if (peer) 18904 unref_peer(peer, "sip_do_debug_peer: unref_peer, from find_peer call"); 18905 return CLI_SUCCESS; 18906 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 29542 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().
29543 { 29544 time_t start_poke, end_poke; 29545 29546 reload_config(reason); 29547 ast_sched_dump(sched); 29548 29549 start_poke = time(0); 29550 /* Prune peers who still are supposed to be deleted */ 29551 unlink_marked_peers_from_tables(); 29552 29553 ast_debug(4, "--------------- Done destroying pruned peers\n"); 29554 29555 /* Send qualify (OPTIONS) to all peers */ 29556 sip_poke_all_peers(); 29557 29558 /* Register with all services */ 29559 sip_send_all_registers(); 29560 29561 sip_send_all_mwi_subscriptions(); 29562 29563 end_poke = time(0); 29564 29565 ast_debug(4, "do_reload finished. peer poke/prune reg contact time = %d sec.\n", (int)(end_poke-start_poke)); 29566 29567 ast_debug(4, "--------------- SIP reload done\n"); 29568 29569 return 0; 29570 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 29224 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().
29225 { 29226 struct sip_pvt *p; 29227 const char *mode = data; 29228 29229 if (!data) { 29230 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 29231 return 0; 29232 } 29233 ast_channel_lock(chan); 29234 if (!IS_SIP_TECH(chan->tech)) { 29235 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 29236 ast_channel_unlock(chan); 29237 return 0; 29238 } 29239 p = chan->tech_pvt; 29240 if (!p) { 29241 ast_channel_unlock(chan); 29242 return 0; 29243 } 29244 sip_pvt_lock(p); 29245 if (!strcasecmp(mode, "info")) { 29246 ast_clear_flag(&p->flags[0], SIP_DTMF); 29247 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 29248 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 29249 } else if (!strcasecmp(mode, "shortinfo")) { 29250 ast_clear_flag(&p->flags[0], SIP_DTMF); 29251 ast_set_flag(&p->flags[0], SIP_DTMF_SHORTINFO); 29252 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 29253 } else if (!strcasecmp(mode, "rfc2833")) { 29254 ast_clear_flag(&p->flags[0], SIP_DTMF); 29255 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 29256 p->jointnoncodeccapability |= AST_RTP_DTMF; 29257 } else if (!strcasecmp(mode, "inband")) { 29258 ast_clear_flag(&p->flags[0], SIP_DTMF); 29259 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 29260 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 29261 } else { 29262 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n", mode); 29263 } 29264 if (p->rtp) 29265 ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 29266 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 29267 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 29268 enable_dsp_detect(p); 29269 } else { 29270 disable_dsp_detect(p); 29271 } 29272 sip_pvt_unlock(p); 29273 ast_channel_unlock(chan); 29274 return 0; 29275 }
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 18678 of file chan_sip.c.
References ast_debug, AST_LIST_TRAVERSE, ast_log(), LOG_NOTICE, and option_debug.
Referenced by __sip_destroy().
18679 { 18680 int x = 0; 18681 struct sip_history *hist; 18682 static int errmsg = 0; 18683 18684 if (!dialog) 18685 return; 18686 18687 if (!option_debug && !sipdebug) { 18688 if (!errmsg) { 18689 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 18690 errmsg = 1; 18691 } 18692 return; 18693 } 18694 18695 ast_debug(1, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 18696 if (dialog->subscribed) 18697 ast_debug(1, " * Subscription\n"); 18698 else 18699 ast_debug(1, " * SIP Call\n"); 18700 if (dialog->history) 18701 AST_LIST_TRAVERSE(dialog->history, hist, list) 18702 ast_debug(1, " %-3.3d. %s\n", ++x, hist->event); 18703 if (!x) 18704 ast_debug(1, "Call '%s' has no history\n", dialog->callid); 18705 ast_debug(1, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 18706 }
static int sip_epa_register | ( | const struct epa_static_data * | static_data | ) | [static] |
Definition at line 862 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, and AST_LIST_UNLOCK.
Referenced by load_module().
00863 { 00864 struct epa_backend *backend = ast_calloc(1, sizeof(*backend)); 00865 00866 if (!backend) { 00867 return -1; 00868 } 00869 00870 backend->static_data = static_data; 00871 00872 AST_LIST_LOCK(&epa_static_data_list); 00873 AST_LIST_INSERT_TAIL(&epa_static_data_list, backend, next); 00874 AST_LIST_UNLOCK(&epa_static_data_list); 00875 return 0; 00876 }
static void sip_epa_unregister_all | ( | void | ) | [static] |
Definition at line 878 of file chan_sip.c.
References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.
Referenced by unload_module().
00879 { 00880 struct epa_backend *backend; 00881 00882 AST_LIST_LOCK(&epa_static_data_list); 00883 while ((backend = AST_LIST_REMOVE_HEAD(&epa_static_data_list, next))) { 00884 ast_free(backend); 00885 } 00886 AST_LIST_UNLOCK(&epa_static_data_list); 00887 }
static int sip_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links
Definition at line 6592 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.
06593 { 06594 int ret = -1; 06595 struct sip_pvt *p; 06596 06597 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE)) 06598 ast_debug(1, "New channel is zombie\n"); 06599 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE)) 06600 ast_debug(1, "Old channel is zombie\n"); 06601 06602 if (!newchan || !newchan->tech_pvt) { 06603 if (!newchan) 06604 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 06605 else 06606 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 06607 return -1; 06608 } 06609 p = newchan->tech_pvt; 06610 06611 sip_pvt_lock(p); 06612 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 06613 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 06614 if (p->owner != oldchan) 06615 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 06616 else { 06617 p->owner = newchan; 06618 /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native 06619 RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be 06620 able to do this if the masquerade happens before the bridge breaks (e.g., AMI 06621 redirect of both channels). Note that a channel can not be masqueraded *into* 06622 a native bridge. So there is no danger that this breaks a native bridge that 06623 should stay up. */ 06624 sip_set_rtp_peer(newchan, NULL, NULL, 0, 0, 0); 06625 ret = 0; 06626 } 06627 ast_debug(3, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 06628 06629 sip_pvt_unlock(p); 06630 return ret; 06631 }
static const char * sip_get_callid | ( | struct ast_channel * | chan | ) | [static] |
Deliver SIP call ID for the call.
Definition at line 4457 of file chan_sip.c.
References ast_channel::tech_pvt.
static int sip_get_cc_information | ( | struct sip_request * | req, | |
char * | subscribe_uri, | |||
size_t | size, | |||
enum ast_cc_service_type * | service | |||
) | [static] |
Definition at line 2067 of file chan_sip.c.
References AST_CC_NONE, ast_copy_string(), ast_strdupa, ast_strlen_zero(), get_header(), get_in_brackets(), service_string_to_service_type(), and strsep().
Referenced by sip_handle_cc().
02068 { 02069 char *call_info = ast_strdupa(get_header(req, "Call-Info")); 02070 char *uri; 02071 char *purpose; 02072 char *service_str; 02073 static const char cc_purpose[] = "purpose=call-completion"; 02074 static const int cc_purpose_len = sizeof(cc_purpose) - 1; 02075 02076 if (ast_strlen_zero(call_info)) { 02077 /* No Call-Info present. Definitely no CC offer */ 02078 return -1; 02079 } 02080 02081 uri = strsep(&call_info, ";"); 02082 02083 while ((purpose = strsep(&call_info, ";"))) { 02084 if (!strncmp(purpose, cc_purpose, cc_purpose_len)) { 02085 break; 02086 } 02087 } 02088 if (!purpose) { 02089 /* We didn't find the appropriate purpose= parameter. Oh well */ 02090 return -1; 02091 } 02092 02093 /* Okay, call-completion has been offered. Let's figure out what type of service this is */ 02094 while ((service_str = strsep(&call_info, ";"))) { 02095 if (!strncmp(service_str, "m=", 2)) { 02096 break; 02097 } 02098 } 02099 if (!service_str) { 02100 /* So they didn't offer a particular service, We'll just go with CCBS since it really 02101 * doesn't matter anyway 02102 */ 02103 service_str = "BS"; 02104 } else { 02105 /* We already determined that there is an "m=" so no need to check 02106 * the result of this strsep 02107 */ 02108 strsep(&service_str, "="); 02109 } 02110 02111 if ((*service = service_string_to_service_type(service_str)) == AST_CC_NONE) { 02112 /* Invalid service offered */ 02113 return -1; 02114 } 02115 02116 ast_copy_string(subscribe_uri, get_in_brackets(uri), size); 02117 02118 return 0; 02119 }
static format_t sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 29204 of file chan_sip.c.
References ast_channel::tech_pvt.
29205 { 29206 struct sip_pvt *p = chan->tech_pvt; 29207 return p->peercapability ? p->peercapability : p->capability; 29208 }
static enum ast_rtp_glue_result sip_get_rtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp_instance ** | instance | |||
) | [static] |
Definition at line 29017 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.
29018 { 29019 struct sip_pvt *p = NULL; 29020 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL; 29021 29022 if (!(p = chan->tech_pvt)) { 29023 return AST_RTP_GLUE_RESULT_FORBID; 29024 } 29025 29026 sip_pvt_lock(p); 29027 if (!(p->rtp)) { 29028 sip_pvt_unlock(p); 29029 return AST_RTP_GLUE_RESULT_FORBID; 29030 } 29031 29032 ao2_ref(p->rtp, +1); 29033 *instance = p->rtp; 29034 29035 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 29036 res = AST_RTP_GLUE_RESULT_REMOTE; 29037 if (!apply_directmedia_ha(p, "audio")) { 29038 res = AST_RTP_GLUE_RESULT_FORBID; 29039 } 29040 } else if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) { 29041 res = AST_RTP_GLUE_RESULT_REMOTE; 29042 } else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) { 29043 res = AST_RTP_GLUE_RESULT_FORBID; 29044 } 29045 29046 if (p->srtp) { 29047 res = AST_RTP_GLUE_RESULT_FORBID; 29048 } 29049 29050 sip_pvt_unlock(p); 29051 29052 return res; 29053 }
static enum ast_rtp_glue_result sip_get_trtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp_instance ** | instance | |||
) | [static] |
Definition at line 29085 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.
29086 { 29087 struct sip_pvt *p = NULL; 29088 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID; 29089 29090 if (!(p = chan->tech_pvt)) { 29091 return AST_RTP_GLUE_RESULT_FORBID; 29092 } 29093 29094 sip_pvt_lock(p); 29095 if (!(p->trtp)) { 29096 sip_pvt_unlock(p); 29097 return AST_RTP_GLUE_RESULT_FORBID; 29098 } 29099 29100 ao2_ref(p->trtp, +1); 29101 *instance = p->trtp; 29102 29103 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 29104 res = AST_RTP_GLUE_RESULT_REMOTE; 29105 if (!apply_directmedia_ha(p, "text")) { 29106 res = AST_RTP_GLUE_RESULT_FORBID; 29107 } 29108 } 29109 29110 sip_pvt_unlock(p); 29111 29112 return res; 29113 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 28954 of file chan_sip.c.
References apply_directmedia_ha(), ast_test_flag, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.
28955 { 28956 struct sip_pvt *p; 28957 struct ast_udptl *udptl = NULL; 28958 28959 p = chan->tech_pvt; 28960 if (!p) { 28961 return NULL; 28962 } 28963 28964 sip_pvt_lock(p); 28965 if (p->udptl && ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 28966 if (apply_directmedia_ha(p, "UDPTL T.38 data")) { 28967 udptl = p->udptl; 28968 } 28969 } 28970 sip_pvt_unlock(p); 28971 return udptl; 28972 }
static enum ast_rtp_glue_result sip_get_vrtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp_instance ** | instance | |||
) | [static] |
Definition at line 29055 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.
29056 { 29057 struct sip_pvt *p = NULL; 29058 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID; 29059 29060 if (!(p = chan->tech_pvt)) { 29061 return AST_RTP_GLUE_RESULT_FORBID; 29062 } 29063 29064 sip_pvt_lock(p); 29065 if (!(p->vrtp)) { 29066 sip_pvt_unlock(p); 29067 return AST_RTP_GLUE_RESULT_FORBID; 29068 } 29069 29070 ao2_ref(p->vrtp, +1); 29071 *instance = p->vrtp; 29072 29073 if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 29074 res = AST_RTP_GLUE_RESULT_REMOTE; 29075 if (!apply_directmedia_ha(p, "video")) { 29076 res = AST_RTP_GLUE_RESULT_FORBID; 29077 } 29078 } 29079 29080 sip_pvt_unlock(p); 29081 29082 return res; 29083 }
static void sip_handle_cc | ( | struct sip_pvt * | pvt, | |
struct sip_request * | req, | |||
enum ast_cc_service_type | service | |||
) | [static] |
Definition at line 2138 of file chan_sip.c.
References ao2_ref, AST_CC_GENERIC_MONITOR_TYPE, ast_cc_get_current_core_id(), AST_CC_MONITOR_ALWAYS, AST_CC_MONITOR_GENERIC, AST_CC_MONITOR_NATIVE, AST_CC_MONITOR_NEVER, ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_get_cc_monitor_policy(), ast_module_ref(), ast_queue_cc_frame(), sip_get_cc_information(), and sip_monitor_instance_init().
Referenced by handle_response(), and handle_response_invite().
02139 { 02140 enum ast_cc_monitor_policies monitor_policy = ast_get_cc_monitor_policy(pvt->cc_params); 02141 int core_id; 02142 char interface_name[AST_CHANNEL_NAME]; 02143 02144 if (monitor_policy == AST_CC_MONITOR_NEVER) { 02145 /* Don't bother, just return */ 02146 return; 02147 } 02148 02149 if ((core_id = ast_cc_get_current_core_id(pvt->owner)) == -1) { 02150 /* For some reason, CC is invalid, so don't try it! */ 02151 return; 02152 } 02153 02154 ast_channel_get_device_name(pvt->owner, interface_name, sizeof(interface_name)); 02155 02156 if (monitor_policy == AST_CC_MONITOR_ALWAYS || monitor_policy == AST_CC_MONITOR_NATIVE) { 02157 char subscribe_uri[SIPBUFSIZE]; 02158 char device_name[AST_CHANNEL_NAME]; 02159 enum ast_cc_service_type offered_service; 02160 struct sip_monitor_instance *monitor_instance; 02161 if (sip_get_cc_information(req, subscribe_uri, sizeof(subscribe_uri), &offered_service)) { 02162 /* If CC isn't being offered to us, or for some reason the CC offer is 02163 * not formatted correctly, then it may still be possible to use generic 02164 * call completion since the monitor policy may be "always" 02165 */ 02166 goto generic; 02167 } 02168 ast_channel_get_device_name(pvt->owner, device_name, sizeof(device_name)); 02169 if (!(monitor_instance = sip_monitor_instance_init(core_id, subscribe_uri, pvt->peername, device_name))) { 02170 /* Same deal. We can try using generic still */ 02171 goto generic; 02172 } 02173 /* We bump the refcount of chan_sip because once we queue this frame, the CC core 02174 * will have a reference to callbacks in this module. We decrement the module 02175 * refcount once the monitor destructor is called 02176 */ 02177 ast_module_ref(ast_module_info->self); 02178 ast_queue_cc_frame(pvt->owner, "SIP", pvt->dialstring, offered_service, monitor_instance); 02179 ao2_ref(monitor_instance, -1); 02180 return; 02181 } 02182 02183 generic: 02184 if (monitor_policy == AST_CC_MONITOR_GENERIC || monitor_policy == AST_CC_MONITOR_ALWAYS) { 02185 ast_queue_cc_frame(pvt->owner, AST_CC_GENERIC_MONITOR_TYPE, interface_name, service, NULL); 02186 } 02187 }
static int sip_hangup | ( | struct ast_channel * | ast | ) | [static] |
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup
Definition at line 6225 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().
06226 { 06227 struct sip_pvt *p = ast->tech_pvt; 06228 int needcancel = FALSE; 06229 int needdestroy = 0; 06230 struct ast_channel *oldowner = ast; 06231 06232 if (!p) { 06233 ast_debug(1, "Asked to hangup channel that was not connected\n"); 06234 return 0; 06235 } 06236 if (ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE) || ast->hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE) { 06237 ast_debug(1, "This call was answered elsewhere"); 06238 if (ast->hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE) { 06239 ast_debug(1, "####### It's the cause code, buddy. The cause code!!!\n"); 06240 } 06241 append_history(p, "Cancel", "Call answered elsewhere"); 06242 p->answered_elsewhere = TRUE; 06243 } 06244 06245 /* Store hangupcause locally in PVT so we still have it before disconnect */ 06246 if (p->owner) 06247 p->hangupcause = p->owner->hangupcause; 06248 06249 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 06250 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 06251 if (sipdebug) 06252 ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 06253 update_call_counter(p, DEC_CALL_LIMIT); 06254 } 06255 ast_debug(4, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 06256 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06257 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 06258 p->needdestroy = 0; 06259 p->owner->tech_pvt = dialog_unref(p->owner->tech_pvt, "unref p->owner->tech_pvt"); 06260 sip_pvt_lock(p); 06261 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 06262 sip_pvt_unlock(p); 06263 ast_module_unref(ast_module_info->self); 06264 return 0; 06265 } 06266 06267 if (ast_test_flag(ast, AST_FLAG_ZOMBIE)) { 06268 if (p->refer) 06269 ast_debug(1, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 06270 else 06271 ast_debug(1, "Hanging up zombie call. Be scared.\n"); 06272 } else 06273 ast_debug(1, "Hangup call %s, SIP callid %s\n", ast->name, p->callid); 06274 06275 sip_pvt_lock(p); 06276 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 06277 if (sipdebug) 06278 ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 06279 update_call_counter(p, DEC_CALL_LIMIT); 06280 } 06281 06282 /* Determine how to disconnect */ 06283 if (p->owner != ast) { 06284 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 06285 sip_pvt_unlock(p); 06286 return 0; 06287 } 06288 /* If the call is not UP, we need to send CANCEL instead of BYE */ 06289 /* In case of re-invites, the call might be UP even though we have an incomplete invite transaction */ 06290 if (p->invitestate < INV_COMPLETED && p->owner->_state != AST_STATE_UP) { 06291 needcancel = TRUE; 06292 ast_debug(4, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 06293 } 06294 06295 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 06296 06297 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->hangupcause) : "Unknown"); 06298 06299 /* Disconnect */ 06300 disable_dsp_detect(p); 06301 06302 p->owner = NULL; 06303 ast->tech_pvt = dialog_unref(ast->tech_pvt, "unref ast->tech_pvt"); 06304 06305 ast_module_unref(ast_module_info->self); 06306 /* Do not destroy this pvt until we have timeout or 06307 get an answer to the BYE or INVITE/CANCEL 06308 If we get no answer during retransmit period, drop the call anyway. 06309 (Sorry, mother-in-law, you can't deny a hangup by sending 06310 603 declined to BYE...) 06311 */ 06312 if (p->alreadygone) 06313 needdestroy = 1; /* Set destroy flag at end of this function */ 06314 else if (p->invitestate != INV_CALLING) 06315 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06316 06317 /* Start the process if it's not already started */ 06318 if (!p->alreadygone && p->initreq.data && !ast_strlen_zero(p->initreq.data->str)) { 06319 if (needcancel) { /* Outgoing call, not up */ 06320 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06321 /* if we can't send right now, mark it pending */ 06322 if (p->invitestate == INV_CALLING) { 06323 /* We can't send anything in CALLING state */ 06324 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 06325 /* 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. */ 06326 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06327 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 06328 } else { 06329 struct sip_pkt *cur; 06330 06331 for (cur = p->packets; cur; cur = cur->next) { 06332 __sip_semi_ack(p, cur->seqno, cur->is_resp, cur->method ? cur->method : find_sip_method(cur->data->str)); 06333 } 06334 p->invitestate = INV_CANCELLED; 06335 /* Send a new request: CANCEL */ 06336 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 06337 /* Actually don't destroy us yet, wait for the 487 on our original 06338 INVITE, but do set an autodestruct just in case we never get it. */ 06339 needdestroy = 0; 06340 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 06341 } 06342 } else { /* Incoming call, not up */ 06343 const char *res; 06344 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")); 06345 if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause))) 06346 transmit_response_reliable(p, res, &p->initreq); 06347 else 06348 transmit_response_reliable(p, "603 Declined", &p->initreq); 06349 p->invitestate = INV_TERMINATED; 06350 } 06351 } else { /* Call is in UP state, send BYE */ 06352 if (p->stimer->st_active == TRUE) { 06353 stop_session_timer(p); 06354 } 06355 06356 if (!p->pendinginvite) { 06357 struct ast_channel *bridge = ast_bridged_channel(oldowner); 06358 char quality_buf[AST_MAX_USER_FIELD], *quality; 06359 06360 /* We need to get the lock on bridge because ast_rtp_instance_set_stats_vars will attempt 06361 * to lock the bridge. This may get hairy... 06362 */ 06363 while (bridge && ast_channel_trylock(bridge)) { 06364 sip_pvt_unlock(p); 06365 do { 06366 CHANNEL_DEADLOCK_AVOIDANCE(oldowner); 06367 } while (sip_pvt_trylock(p)); 06368 bridge = ast_bridged_channel(oldowner); 06369 } 06370 06371 if (p->rtp) { 06372 ast_rtp_instance_set_stats_vars(oldowner, p->rtp); 06373 } 06374 06375 if (bridge) { 06376 struct sip_pvt *q = bridge->tech_pvt; 06377 06378 if (IS_SIP_TECH(bridge->tech) && q && q->rtp) { 06379 ast_rtp_instance_set_stats_vars(bridge, q->rtp); 06380 } 06381 ast_channel_unlock(bridge); 06382 } 06383 06384 if (p->do_history || oldowner) { 06385 if (p->rtp && (quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 06386 if (p->do_history) { 06387 append_history(p, "RTCPaudio", "Quality:%s", quality); 06388 } 06389 if (oldowner) { 06390 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", quality); 06391 } 06392 } 06393 if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 06394 if (p->do_history) { 06395 append_history(p, "RTCPvideo", "Quality:%s", quality); 06396 } 06397 if (oldowner) { 06398 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", quality); 06399 } 06400 } 06401 if (p->trtp && (quality = ast_rtp_instance_get_quality(p->trtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 06402 if (p->do_history) { 06403 append_history(p, "RTCPtext", "Quality:%s", quality); 06404 } 06405 if (oldowner) { 06406 pbx_builtin_setvar_helper(oldowner, "RTPTEXTQOS", quality); 06407 } 06408 } 06409 } 06410 06411 /* Send a hangup */ 06412 if (oldowner->_state == AST_STATE_UP) { 06413 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 06414 } 06415 06416 } else { 06417 /* Note we will need a BYE when this all settles out 06418 but we can't send one while we have "INVITE" outstanding. */ 06419 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 06420 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 06421 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")); 06422 if (sip_cancel_destroy(p)) 06423 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 06424 } 06425 } 06426 } 06427 if (needdestroy) { 06428 pvt_set_needdestroy(p, "hangup"); 06429 } 06430 sip_pvt_unlock(p); 06431 return 0; 06432 }
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 6830 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_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, ast_debug, ast_log(), ast_moh_start(), ast_moh_stop(), ast_rtp_instance_change_source(), ast_rtp_instance_update_source(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, initialize_udptl(), interpret_t38_parameters(), LOG_ERROR, LOG_WARNING, sip_alreadygone(), sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_info_with_aoc(), transmit_info_with_vidupdate(), transmit_provisional_response(), transmit_response(), transmit_response_reliable(), TRUE, update_connectedline(), and update_redirecting().
06831 { 06832 struct sip_pvt *p = ast->tech_pvt; 06833 int res = 0; 06834 06835 sip_pvt_lock(p); 06836 switch(condition) { 06837 case AST_CONTROL_RINGING: 06838 if (ast->_state == AST_STATE_RING) { 06839 p->invitestate = INV_EARLY_MEDIA; 06840 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 06841 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 06842 /* Send 180 ringing if out-of-band seems reasonable */ 06843 transmit_provisional_response(p, "180 Ringing", &p->initreq, 0); 06844 ast_set_flag(&p->flags[0], SIP_RINGING); 06845 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 06846 break; 06847 } else { 06848 /* Well, if it's not reasonable, just send in-band */ 06849 } 06850 } 06851 res = -1; 06852 break; 06853 case AST_CONTROL_BUSY: 06854 if (ast->_state != AST_STATE_UP) { 06855 transmit_response_reliable(p, "486 Busy Here", &p->initreq); 06856 p->invitestate = INV_COMPLETED; 06857 sip_alreadygone(p); 06858 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 06859 break; 06860 } 06861 res = -1; 06862 break; 06863 case AST_CONTROL_CONGESTION: 06864 if (ast->_state != AST_STATE_UP) { 06865 transmit_response_reliable(p, "503 Service Unavailable", &p->initreq); 06866 p->invitestate = INV_COMPLETED; 06867 sip_alreadygone(p); 06868 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 06869 break; 06870 } 06871 res = -1; 06872 break; 06873 case AST_CONTROL_INCOMPLETE: 06874 if (ast->_state != AST_STATE_UP) { 06875 switch (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) { 06876 case SIP_PAGE2_ALLOWOVERLAP_YES: 06877 transmit_response_reliable(p, "484 Address Incomplete", &p->initreq); 06878 p->invitestate = INV_COMPLETED; 06879 sip_alreadygone(p); 06880 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 06881 break; 06882 case SIP_PAGE2_ALLOWOVERLAP_DTMF: 06883 /* Just wait for inband DTMF digits */ 06884 break; 06885 default: 06886 /* it actually means no support for overlap */ 06887 transmit_response_reliable(p, "404 Not Found", &p->initreq); 06888 p->invitestate = INV_COMPLETED; 06889 sip_alreadygone(p); 06890 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 06891 break; 06892 } 06893 } 06894 break; 06895 case AST_CONTROL_PROCEEDING: 06896 if ((ast->_state != AST_STATE_UP) && 06897 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06898 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06899 transmit_response(p, "100 Trying", &p->initreq); 06900 p->invitestate = INV_PROCEEDING; 06901 break; 06902 } 06903 res = -1; 06904 break; 06905 case AST_CONTROL_PROGRESS: 06906 if ((ast->_state != AST_STATE_UP) && 06907 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06908 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06909 p->invitestate = INV_EARLY_MEDIA; 06910 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 06911 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 06912 break; 06913 } 06914 res = -1; 06915 break; 06916 case AST_CONTROL_HOLD: 06917 ast_rtp_instance_update_source(p->rtp); 06918 ast_moh_start(ast, data, p->mohinterpret); 06919 break; 06920 case AST_CONTROL_UNHOLD: 06921 ast_rtp_instance_update_source(p->rtp); 06922 ast_moh_stop(ast); 06923 break; 06924 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 06925 if (p->vrtp && !p->novideo) { 06926 transmit_info_with_vidupdate(p); 06927 /* ast_rtcp_send_h261fur(p->vrtp); */ 06928 } else 06929 res = -1; 06930 break; 06931 case AST_CONTROL_T38_PARAMETERS: 06932 res = -1; 06933 if (datalen != sizeof(struct ast_control_t38_parameters)) { 06934 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); 06935 } else { 06936 const struct ast_control_t38_parameters *parameters = data; 06937 if (!initialize_udptl(p)) { 06938 res = interpret_t38_parameters(p, parameters); 06939 } 06940 } 06941 break; 06942 case AST_CONTROL_SRCUPDATE: 06943 ast_rtp_instance_update_source(p->rtp); 06944 break; 06945 case AST_CONTROL_SRCCHANGE: 06946 ast_rtp_instance_change_source(p->rtp); 06947 break; 06948 case AST_CONTROL_CONNECTED_LINE: 06949 update_connectedline(p, data, datalen); 06950 break; 06951 case AST_CONTROL_REDIRECTING: 06952 update_redirecting(p, data, datalen); 06953 break; 06954 case AST_CONTROL_AOC: 06955 { 06956 struct ast_aoc_decoded *decoded = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, ast); 06957 if (!decoded) { 06958 ast_log(LOG_ERROR, "Error decoding indicated AOC data\n"); 06959 res = -1; 06960 break; 06961 } 06962 switch (ast_aoc_get_msg_type(decoded)) { 06963 case AST_AOC_REQUEST: 06964 if (ast_aoc_get_termination_request(decoded)) { 06965 /* TODO, once there is a way to get AOC-E on hangup, attempt that here 06966 * before hanging up the channel.*/ 06967 06968 /* The other side has already initiated the hangup. This frame 06969 * just says they are waiting to get AOC-E before completely tearing 06970 * the call down. Since SIP does not support this at the moment go 06971 * ahead and terminate the call here to avoid an unnecessary timeout. */ 06972 ast_debug(1, "AOC-E termination request received on %s. This is not yet supported on sip. Continue with hangup \n", p->owner->name); 06973 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 06974 } 06975 break; 06976 case AST_AOC_D: 06977 case AST_AOC_E: 06978 if (ast_test_flag(&p->flags[2], SIP_PAGE3_SNOM_AOC)) { 06979 transmit_info_with_aoc(p, decoded); 06980 } 06981 break; 06982 case AST_AOC_S: /* S not supported yet */ 06983 default: 06984 break; 06985 } 06986 ast_aoc_destroy_decoded(decoded); 06987 } 06988 break; 06989 case AST_CONTROL_UPDATE_RTP_PEER: /* Absorb this since it is handled by the bridge */ 06990 break; 06991 case -1: 06992 res = -1; 06993 break; 06994 default: 06995 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 06996 res = -1; 06997 break; 06998 } 06999 sip_pvt_unlock(p); 07000 return res; 07001 }
static int sip_is_xml_parsable | ( | void | ) | [static] |
Definition at line 29409 of file chan_sip.c.
Referenced by load_module().
29410 { 29411 #ifdef HAVE_LIBXML2 29412 return TRUE; 29413 #else 29414 return FALSE; 29415 #endif 29416 }
static int sip_monitor_instance_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1844 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_module().
01845 { 01846 struct sip_monitor_instance *monitor_instance1 = obj; 01847 struct sip_monitor_instance *monitor_instance2 = arg; 01848 01849 return monitor_instance1->core_id == monitor_instance2->core_id ? CMP_MATCH | CMP_STOP : 0; 01850 }
static void sip_monitor_instance_destructor | ( | void * | data | ) | [static] |
Definition at line 1852 of file chan_sip.c.
References ao2_t_ref, ast_string_field_free_memory, FALSE, sip_pvt_lock, sip_pvt_unlock, transmit_invite(), and transmit_publish().
Referenced by sip_monitor_instance_init().
01853 { 01854 struct sip_monitor_instance *monitor_instance = data; 01855 if (monitor_instance->subscription_pvt) { 01856 sip_pvt_lock(monitor_instance->subscription_pvt); 01857 monitor_instance->subscription_pvt->expiry = 0; 01858 transmit_invite(monitor_instance->subscription_pvt, SIP_SUBSCRIBE, FALSE, 0, monitor_instance->subscribe_uri); 01859 sip_pvt_unlock(monitor_instance->subscription_pvt); 01860 dialog_unref(monitor_instance->subscription_pvt, "Unref monitor instance ref of subscription pvt"); 01861 } 01862 if (monitor_instance->suspension_entry) { 01863 monitor_instance->suspension_entry->body[0] = '\0'; 01864 transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_REMOVE ,monitor_instance->notify_uri); 01865 ao2_t_ref(monitor_instance->suspension_entry, -1, "Decrementing suspension entry refcount in sip_monitor_instance_destructor"); 01866 } 01867 ast_string_field_free_memory(monitor_instance); 01868 }
static int sip_monitor_instance_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1838 of file chan_sip.c.
Referenced by load_module().
01839 { 01840 const struct sip_monitor_instance *monitor_instance = obj; 01841 return monitor_instance->core_id; 01842 }
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 1870 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().
01871 { 01872 struct sip_monitor_instance *monitor_instance = ao2_alloc(sizeof(*monitor_instance), sip_monitor_instance_destructor); 01873 01874 if (!monitor_instance) { 01875 return NULL; 01876 } 01877 01878 if (ast_string_field_init(monitor_instance, 256)) { 01879 ao2_ref(monitor_instance, -1); 01880 return NULL; 01881 } 01882 01883 ast_string_field_set(monitor_instance, subscribe_uri, subscribe_uri); 01884 ast_string_field_set(monitor_instance, peername, peername); 01885 ast_string_field_set(monitor_instance, device_name, device_name); 01886 monitor_instance->core_id = core_id; 01887 ao2_link(sip_monitor_instances, monitor_instance); 01888 return monitor_instance; 01889 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 3214 of file chan_sip.c.
References ast_test_flag.
Referenced by check_via(), retrans_pkt(), and send_response().
03215 { 03216 return ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) ? "NAT" : "no NAT"; 03217 }
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.
Definition at line 7014 of file chan_sip.c.
References accountcode, ast_channel::adsicpe, ast_channel::amaflags, ast_party_caller::ani, append_history, AST_ADSI_UNAVAILABLE, ast_atomic_fetchadd_int(), ast_best_codec(), ast_channel_alloc, ast_channel_cc_params_init(), ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_codec_choose(), ast_copy_string(), ast_debug, ast_exists_extension(), AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_get_encoded_str(), ast_getformatname_multiple(), ast_jb_configure(), ast_log(), ast_module_ref(), AST_RTP_DTMF_MODE_INBAND, AST_RTP_DTMF_MODE_RFC2833, ast_rtp_instance_dtmf_mode_set(), ast_rtp_instance_fd(), ast_rtp_instance_set_read_format(), ast_rtp_instance_set_write_format(), AST_STATE_RING, ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), ast_uri_decode(), ast_channel::caller, ast_channel::callgroup, chan_idx, ast_channel::context, ast_channel::dialed, enable_dsp_detect(), EVENT_FLAG_SYSTEM, ast_channel::exten, exten, ast_party_redirecting::from, global_jbconf, 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().
07015 { 07016 struct ast_channel *tmp; 07017 struct ast_variable *v = NULL; 07018 format_t fmt; 07019 format_t what; 07020 format_t video; 07021 format_t text; 07022 format_t needvideo = 0; 07023 int needtext = 0; 07024 char buf[SIPBUFSIZE]; 07025 char *exten; 07026 07027 { 07028 const char *my_name; /* pick a good name */ 07029 07030 if (title) { 07031 my_name = title; 07032 } else { 07033 my_name = ast_strdupa(i->fromdomain); 07034 } 07035 07036 sip_pvt_unlock(i); 07037 /* Don't hold a sip pvt lock while we allocate a channel */ 07038 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)); 07039 } 07040 if (!tmp) { 07041 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 07042 sip_pvt_lock(i); 07043 return NULL; 07044 } 07045 ast_channel_lock(tmp); 07046 sip_pvt_lock(i); 07047 ast_channel_cc_params_init(tmp, i->cc_params); 07048 tmp->caller.id.tag = ast_strdup(i->cid_tag); 07049 07050 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; 07051 07052 /* Select our native format based on codec preference until we receive 07053 something from another device to the contrary. */ 07054 if (i->jointcapability) { /* The joint capabilities of us and peer */ 07055 what = i->jointcapability; 07056 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 07057 text = i->jointcapability & AST_FORMAT_TEXT_MASK; 07058 } else if (i->capability) { /* Our configured capability for this peer */ 07059 what = i->capability; 07060 video = i->capability & AST_FORMAT_VIDEO_MASK; 07061 text = i->capability & AST_FORMAT_TEXT_MASK; 07062 } else { 07063 what = sip_cfg.capability; /* Global codec support */ 07064 video = sip_cfg.capability & AST_FORMAT_VIDEO_MASK; 07065 text = sip_cfg.capability & AST_FORMAT_TEXT_MASK; 07066 } 07067 07068 /* Set the native formats for audio and merge in video */ 07069 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video | text; 07070 ast_debug(3, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 07071 ast_debug(3, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 07072 ast_debug(3, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 07073 ast_debug(3, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 07074 if (i->prefcodec) 07075 ast_debug(3, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 07076 07077 /* XXX Why are we choosing a codec from the native formats?? */ 07078 fmt = ast_best_codec(tmp->nativeformats); 07079 07080 /* If we have a prefcodec setting, we have an inbound channel that set a 07081 preferred format for this call. Otherwise, we check the jointcapability 07082 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 07083 */ 07084 if (i->vrtp) { 07085 if (ast_test_flag(&i->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 07086 needvideo = AST_FORMAT_VIDEO_MASK; 07087 else if (i->prefcodec) 07088 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 07089 else 07090 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 07091 } 07092 07093 if (i->trtp) { 07094 if (i->prefcodec) 07095 needtext = i->prefcodec & AST_FORMAT_TEXT_MASK; /* Outbound call */ 07096 else 07097 needtext = i->jointcapability & AST_FORMAT_TEXT_MASK; /* Inbound call */ 07098 } 07099 07100 if (needvideo) 07101 ast_debug(3, "This channel can handle video! HOLLYWOOD next!\n"); 07102 else 07103 ast_debug(3, "This channel will not be able to handle video.\n"); 07104 07105 enable_dsp_detect(i); 07106 07107 if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 07108 (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 07109 if (i->rtp) { 07110 ast_rtp_instance_dtmf_mode_set(i->rtp, AST_RTP_DTMF_MODE_INBAND); 07111 } 07112 } else if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) { 07113 if (i->rtp) { 07114 ast_rtp_instance_dtmf_mode_set(i->rtp, AST_RTP_DTMF_MODE_RFC2833); 07115 } 07116 } 07117 07118 /* Set file descriptors for audio, video, and realtime text. Since 07119 * UDPTL is created as needed in the lifetime of a dialog, its file 07120 * descriptor is set in initialize_udptl */ 07121 if (i->rtp) { 07122 ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(i->rtp, 0)); 07123 ast_channel_set_fd(tmp, 1, ast_rtp_instance_fd(i->rtp, 1)); 07124 } 07125 if (needvideo && i->vrtp) { 07126 ast_channel_set_fd(tmp, 2, ast_rtp_instance_fd(i->vrtp, 0)); 07127 ast_channel_set_fd(tmp, 3, ast_rtp_instance_fd(i->vrtp, 1)); 07128 } 07129 if (needtext && i->trtp) { 07130 ast_channel_set_fd(tmp, 4, ast_rtp_instance_fd(i->trtp, 0)); 07131 } 07132 if (i->udptl) { 07133 ast_channel_set_fd(tmp, 5, ast_udptl_fd(i->udptl)); 07134 } 07135 07136 if (state == AST_STATE_RING) 07137 tmp->rings = 1; 07138 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 07139 07140 tmp->writeformat = fmt; 07141 tmp->rawwriteformat = fmt; 07142 ast_rtp_instance_set_write_format(i->rtp, fmt); 07143 07144 tmp->readformat = fmt; 07145 tmp->rawreadformat = fmt; 07146 ast_rtp_instance_set_read_format(i->rtp, fmt); 07147 07148 tmp->tech_pvt = dialog_ref(i, "sip_new: set chan->tech_pvt to i"); 07149 07150 tmp->callgroup = i->callgroup; 07151 tmp->pickupgroup = i->pickupgroup; 07152 tmp->caller.id.name.presentation = i->callingpres; 07153 tmp->caller.id.number.presentation = i->callingpres; 07154 if (!ast_strlen_zero(i->parkinglot)) 07155 ast_string_field_set(tmp, parkinglot, i->parkinglot); 07156 if (!ast_strlen_zero(i->accountcode)) 07157 ast_string_field_set(tmp, accountcode, i->accountcode); 07158 if (i->amaflags) 07159 tmp->amaflags = i->amaflags; 07160 if (!ast_strlen_zero(i->language)) 07161 ast_string_field_set(tmp, language, i->language); 07162 i->owner = tmp; 07163 ast_module_ref(ast_module_info->self); 07164 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 07165 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 07166 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 07167 * structure so that there aren't issues when forming URI's 07168 */ 07169 exten = ast_strdupa(i->exten); 07170 sip_pvt_unlock(i); 07171 ast_channel_unlock(tmp); 07172 if (!ast_exists_extension(NULL, i->context, i->exten, 1, i->cid_num)) { 07173 ast_uri_decode(exten); 07174 } 07175 ast_channel_lock(tmp); 07176 sip_pvt_lock(i); 07177 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 07178 07179 /* Don't use ast_set_callerid() here because it will 07180 * generate an unnecessary NewCallerID event */ 07181 if (!ast_strlen_zero(i->cid_num)) { 07182 tmp->caller.ani.number.valid = 1; 07183 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 07184 } 07185 if (!ast_strlen_zero(i->rdnis)) { 07186 tmp->redirecting.from.number.valid = 1; 07187 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 07188 } 07189 07190 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) { 07191 tmp->dialed.number.str = ast_strdup(i->exten); 07192 } 07193 07194 tmp->priority = 1; 07195 if (!ast_strlen_zero(i->uri)) 07196 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 07197 if (!ast_strlen_zero(i->domain)) 07198 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 07199 if (!ast_strlen_zero(i->callid)) 07200 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 07201 if (i->rtp) 07202 ast_jb_configure(tmp, &global_jbconf); 07203 07204 /* Set channel variables for this call from configuration */ 07205 for (v = i->chanvars ; v ; v = v->next) { 07206 char valuebuf[1024]; 07207 pbx_builtin_setvar_helper(tmp, v->name, ast_get_encoded_str(v->value, valuebuf, sizeof(valuebuf))); 07208 } 07209 07210 if (i->do_history) 07211 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 07212 07213 /* Inform manager user about new channel and their SIP call ID */ 07214 if (sip_cfg.callevents) 07215 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 07216 "Channel: %s\r\nUniqueid: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\n", 07217 tmp->name, tmp->uniqueid, "SIP", i->callid, i->fullcontact); 07218 07219 return tmp; 07220 }
static int sip_notify_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 13429 of file chan_sip.c.
References ast_calloc, and ast_str_create().
Referenced by manager_sipnotify(), and sip_cli_notify().
13430 { 13431 p->notify = ast_calloc(1, sizeof(struct sip_notify)); 13432 if (p->notify) { 13433 p->notify->content = ast_str_create(128); 13434 } 13435 return p->notify ? 1 : 0; 13436 }
static int sip_offer_timer_expire | ( | const void * | data | ) | [static] |
Definition at line 1720 of file chan_sip.c.
References ast_cc_failed(), ast_cc_agent::core_id, ast_cc_agent::device_name, and ast_cc_agent::private_data.
Referenced by sip_cc_agent_start_offer_timer().
01721 { 01722 struct ast_cc_agent *agent = (struct ast_cc_agent *) data; 01723 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 01724 01725 agent_pvt->offer_timer_id = -1; 01726 01727 return ast_cc_failed(agent->core_id, "SIP agent %s's offer timer expired", agent->device_name); 01728 }
static int sip_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2, | |||
struct sip_request * | req, | |||
int | seqno, | |||
const char * | park_exten, | |||
const char * | park_context | |||
) | [static] |
DO NOT hold any locks while calling sip_park
Definition at line 21367 of file chan_sip.c.
References ast_channel::accountcode, ast_channel::amaflags, ast_calloc, ast_channel_alloc, ast_channel_masquerade(), ast_copy_string(), ast_do_masquerade(), ast_free, ast_hangup(), ast_pthread_create_detached_background, AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_channel::context, copy_request(), deinit_req(), ast_channel::exten, ast_channel::linkedid, ast_channel::name, ast_channel::parkinglot, parkinglot, ast_channel::priority, ast_channel::readformat, sip_park_thread(), and ast_channel::writeformat.
Referenced by handle_request_refer().
21368 { 21369 struct sip_dual *d; 21370 struct ast_channel *transferee, *transferer; 21371 pthread_t th; 21372 21373 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name); 21374 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "SIPPeer/%s", chan2->name); 21375 d = ast_calloc(1, sizeof(*d)); 21376 if (!transferee || !transferer || !d) { 21377 if (transferee) { 21378 ast_hangup(transferee); 21379 } 21380 if (transferer) { 21381 ast_hangup(transferer); 21382 } 21383 ast_free(d); 21384 return -1; 21385 } 21386 d->park_exten = ast_strdup(park_exten); 21387 d->park_context = ast_strdup(park_context); 21388 if (!d->park_exten || !d->park_context) { 21389 ast_hangup(transferee); 21390 ast_hangup(transferer); 21391 ast_free(d->park_exten); 21392 ast_free(d->park_context); 21393 ast_free(d); 21394 return -1; 21395 } 21396 21397 /* Make formats okay */ 21398 transferee->readformat = chan1->readformat; 21399 transferee->writeformat = chan1->writeformat; 21400 21401 /* Prepare for taking over the channel */ 21402 if (ast_channel_masquerade(transferee, chan1)) { 21403 ast_hangup(transferee); 21404 ast_hangup(transferer); 21405 ast_free(d->park_exten); 21406 ast_free(d->park_context); 21407 ast_free(d); 21408 return -1; 21409 } 21410 21411 /* Setup the extensions and such */ 21412 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 21413 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 21414 transferee->priority = chan1->priority; 21415 21416 ast_do_masquerade(transferee); 21417 21418 /* We make a clone of the peer channel too, so we can play 21419 back the announcement */ 21420 21421 /* Make formats okay */ 21422 transferer->readformat = chan2->readformat; 21423 transferer->writeformat = chan2->writeformat; 21424 ast_string_field_set(transferer, parkinglot, chan2->parkinglot); 21425 21426 /* Prepare for taking over the channel */ 21427 if (ast_channel_masquerade(transferer, chan2)) { 21428 ast_hangup(transferer); 21429 ast_free(d->park_exten); 21430 ast_free(d->park_context); 21431 ast_free(d); 21432 return -1; 21433 } 21434 21435 /* Setup the extensions and such */ 21436 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 21437 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 21438 transferer->priority = chan2->priority; 21439 21440 ast_do_masquerade(transferer); 21441 21442 /* Save original request for followup */ 21443 copy_request(&d->req, req); 21444 d->chan1 = transferee; /* Transferee */ 21445 d->chan2 = transferer; /* Transferer */ 21446 d->seqno = seqno; 21447 if (ast_pthread_create_detached_background(&th, NULL, sip_park_thread, d) < 0) { 21448 /* Could not start thread */ 21449 deinit_req(&d->req); 21450 ast_free(d->park_exten); 21451 ast_free(d->park_context); 21452 ast_free(d); /* We don't need it anymore. If thread is created, d will be free'd 21453 by sip_park_thread() */ 21454 return -1; 21455 } 21456 return 0; 21457 }
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 21319 of file chan_sip.c.
References append_history, AST_CAUSE_NORMAL_CLEARING, ast_debug, ast_free, ast_hangup(), ast_park_call_exten(), deinit_req(), ext, ast_channel::hangupcause, ast_channel::name, ast_channel::tech_pvt, transmit_message_with_text(), transmit_notify_with_sipfrag(), and TRUE.
Referenced by sip_park().
21320 { 21321 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 21322 struct sip_dual *d; 21323 int ext; 21324 int res; 21325 21326 d = stuff; 21327 transferee = d->chan1; 21328 transferer = d->chan2; 21329 21330 ast_debug(4, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 21331 21332 res = ast_park_call_exten(transferee, transferer, d->park_exten, d->park_context, 0, &ext); 21333 21334 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 21335 if (res) { 21336 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 21337 } else { 21338 /* Then tell the transferer what happened */ 21339 sprintf(buf, "Call parked on extension '%d'", ext); 21340 transmit_message_with_text(transferer->tech_pvt, buf); 21341 } 21342 #endif 21343 21344 /* Any way back to the current call??? */ 21345 /* Transmit response to the REFER request */ 21346 if (!res) { 21347 /* Transfer succeeded */ 21348 append_history(transferer->tech_pvt, "SIPpark", "Parked call on %d", ext); 21349 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 21350 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 21351 ast_hangup(transferer); /* This will cause a BYE */ 21352 ast_debug(1, "SIP Call parked on extension '%d'\n", ext); 21353 } else { 21354 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 21355 append_history(transferer->tech_pvt, "SIPpark", "Parking failed\n"); 21356 ast_debug(1, "SIP Call parked failed \n"); 21357 /* Do not hangup call */ 21358 } 21359 deinit_req(&d->req); 21360 ast_free(d->park_exten); 21361 ast_free(d->park_context); 21362 ast_free(d); 21363 return NULL; 21364 }
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 14477 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().
14478 { 14479 if (!p->relatedpeer) { 14480 return; 14481 } 14482 14483 /* If they put someone on hold, increment the value... otherwise decrement it */ 14484 ast_atomic_fetchadd_int(&p->relatedpeer->onHold, (hold ? +1 : -1)); 14485 14486 /* Request device state update */ 14487 ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", p->relatedpeer->name); 14488 14489 return; 14490 }
static int sip_pickup | ( | struct ast_channel * | chan | ) | [static] |
Pickup a call using the subsystem in features.c This is executed in a separate thread.
Definition at line 21482 of file chan_sip.c.
References ast_channel_ref, ast_channel_unref, ast_debug, ast_pthread_create_detached_background, ast_channel::name, and sip_pickup_thread().
Referenced by handle_request_invite().
21483 { 21484 pthread_t threadid; 21485 21486 ast_channel_ref(chan); 21487 21488 if (ast_pthread_create_detached_background(&threadid, NULL, sip_pickup_thread, chan)) { 21489 ast_debug(1, "Unable to start Group pickup thread on channel %s\n", chan->name); 21490 ast_channel_unref(chan); 21491 return -1; 21492 } 21493 ast_debug(1, "Started Group pickup thread on channel %s\n", chan->name); 21494 return 0; 21495 }
static void * sip_pickup_thread | ( | void * | stuff | ) | [static] |
SIP pickup support function Starts in a new thread, then pickup the call.
Definition at line 21463 of file chan_sip.c.
References AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_unref, ast_hangup(), ast_pickup_call(), and ast_channel::hangupcause.
Referenced by sip_pickup().
21464 { 21465 struct ast_channel *chan; 21466 chan = stuff; 21467 21468 if (ast_pickup_call(chan)) { 21469 chan->hangupcause = AST_CAUSE_CALL_REJECTED; 21470 } else { 21471 chan->hangupcause = AST_CAUSE_NORMAL_CLEARING; 21472 } 21473 ast_hangup(chan); 21474 ast_channel_unref(chan); 21475 chan = NULL; 21476 return NULL; 21477 }
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 24056 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().
24057 { 24058 struct ast_xml_doc *doc; 24059 int content_length; 24060 const char *content_length_str = get_header(req, "Content-Length"); 24061 const char *content_type = get_header(req, "Content-Type"); 24062 char pidf_body[SIPBUFSIZE]; 24063 int res; 24064 24065 if (ast_strlen_zero(content_type) || strcmp(content_type, "application/pidf+xml")) { 24066 ast_log(LOG_WARNING, "Content type is not PIDF\n"); 24067 return FALSE; 24068 } 24069 24070 if (ast_strlen_zero(content_length_str)) { 24071 ast_log(LOG_WARNING, "No content length. Can't determine bounds of PIDF document\n"); 24072 return FALSE; 24073 } 24074 24075 if (sscanf(content_length_str, "%30d", &content_length) != 1) { 24076 ast_log(LOG_WARNING, "Invalid content length provided\n"); 24077 return FALSE; 24078 } 24079 24080 if (content_length > sizeof(pidf_body)) { 24081 ast_log(LOG_WARNING, "Content length of PIDF document truncated to %d bytes\n", (int) sizeof(pidf_body)); 24082 content_length = sizeof(pidf_body); 24083 } 24084 24085 get_pidf_body(req, pidf_body, content_length); 24086 24087 if (!(doc = ast_xml_read_memory(pidf_body, content_length))) { 24088 ast_log(LOG_WARNING, "Unable to open XML PIDF document. Is it malformed?\n"); 24089 return FALSE; 24090 } 24091 24092 res = pidf_validate_presence(doc); 24093 if (res == TRUE) { 24094 *pidf_doc = doc; 24095 } else { 24096 ast_xml_close(doc); 24097 } 24098 return res; 24099 }
static void sip_poke_all_peers | ( | void | ) | [static] |
Send a poke to all known peers.
Definition at line 29419 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().
29420 { 29421 int ms = 0, num = 0; 29422 struct ao2_iterator i; 29423 struct sip_peer *peer; 29424 29425 if (!speerobjs) { /* No peers, just give up */ 29426 return; 29427 } 29428 29429 i = ao2_iterator_init(peers, 0); 29430 while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 29431 ao2_lock(peer); 29432 if (num == global_qualify_peers) { 29433 ms += global_qualify_gap; 29434 num = 0; 29435 } else { 29436 num++; 29437 } 29438 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, ms, sip_poke_peer_s, peer, 29439 unref_peer(_data, "removing poke peer ref"), 29440 unref_peer(peer, "removing poke peer ref"), 29441 ref_peer(peer, "adding poke peer ref")); 29442 ao2_unlock(peer); 29443 unref_peer(peer, "toss iterator peer ptr"); 29444 } 29445 ao2_iterator_destroy(&i); 29446 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 26134 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(), and unref_peer().
Referenced by sip_poke_peer(), and sip_show_sched().
26135 { 26136 struct sip_peer *peer = (struct sip_peer *)data; 26137 26138 peer->pokeexpire = -1; 26139 26140 if (peer->lastms > -1) { 26141 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 26142 if (sip_cfg.peer_rtupdate) { 26143 ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", "-1", SENTINEL); 26144 } 26145 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 26146 if (sip_cfg.regextenonqualify) { 26147 register_peer_exten(peer, FALSE); 26148 } 26149 } 26150 26151 if (peer->call) { 26152 dialog_unlink_all(peer->call); 26153 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 26154 /* peer->call = sip_destroy(peer->call);*/ 26155 } 26156 26157 /* Don't send a devstate change if nothing changed. */ 26158 if (peer->lastms > -1) { 26159 peer->lastms = -1; 26160 ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name); 26161 } 26162 26163 /* Try again quickly */ 26164 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, 26165 DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer, 26166 unref_peer(_data, "removing poke peer ref"), 26167 unref_peer(peer, "removing poke peer ref"), 26168 ref_peer(peer, "adding poke peer ref")); 26169 26170 /* Release the ref held by the running scheduler entry */ 26171 unref_peer(peer, "release peer poke noanswer ref"); 26172 26173 return 0; 26174 }
static int sip_poke_peer | ( | struct sip_peer * | peer, | |
int | force | |||
) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 26181 of file chan_sip.c.
References ast_copy_flags, ast_copy_string(), ast_log(), AST_SCHED_DEL_UNREF, AST_SCHED_REPLACE_UNREF, ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_isnull(), ast_sockaddr_stringify_host_remote(), ast_string_field_set, ast_strlen_zero(), ast_tvnow(), build_via(), change_callid_pvt(), copy_socket_data(), dialog_unlink_all(), LOG_NOTICE, ref_peer(), sip_alloc(), sip_poke_noanswer(), transmit_invite(), and unref_peer().
Referenced by _sip_qualify_peer(), build_peer(), parse_register_contact(), reg_source_db(), and sip_poke_peer_s().
26182 { 26183 struct sip_pvt *p; 26184 int xmitres = 0; 26185 26186 if ((!peer->maxms && !force) || ast_sockaddr_isnull(&peer->addr)) { 26187 /* IF we have no IP, or this isn't to be monitored, return 26188 immediately after clearing things out */ 26189 AST_SCHED_DEL_UNREF(sched, peer->pokeexpire, 26190 unref_peer(peer, "removing poke peer ref")); 26191 26192 peer->lastms = 0; 26193 if (peer->call) { 26194 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 26195 } 26196 return 0; 26197 } 26198 if (peer->call) { 26199 if (sipdebug) { 26200 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 26201 } 26202 dialog_unlink_all(peer->call); 26203 peer->call = dialog_unref(peer->call, "unref dialog peer->call"); 26204 /* peer->call = sip_destroy(peer->call); */ 26205 } 26206 if (!(p = sip_alloc(NULL, NULL, 0, SIP_OPTIONS, NULL))) { 26207 return -1; 26208 } 26209 peer->call = dialog_ref(p, "copy sip alloc from p to peer->call"); 26210 26211 p->sa = peer->addr; 26212 p->recv = peer->addr; 26213 copy_socket_data(&p->socket, &peer->socket); 26214 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 26215 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 26216 ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY); 26217 26218 /* Send OPTIONs to peer's fullcontact */ 26219 if (!ast_strlen_zero(peer->fullcontact)) { 26220 ast_string_field_set(p, fullcontact, peer->fullcontact); 26221 } 26222 26223 if (!ast_strlen_zero(peer->fromuser)) { 26224 ast_string_field_set(p, fromuser, peer->fromuser); 26225 } 26226 26227 if (!ast_strlen_zero(peer->tohost)) { 26228 ast_string_field_set(p, tohost, peer->tohost); 26229 } else { 26230 ast_string_field_set(p, tohost, ast_sockaddr_stringify_host_remote(&peer->addr)); 26231 } 26232 26233 /* Recalculate our side, and recalculate Call ID */ 26234 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 26235 build_via(p); 26236 26237 /* Change the dialog callid. */ 26238 change_callid_pvt(p, NULL); 26239 26240 AST_SCHED_DEL_UNREF(sched, peer->pokeexpire, 26241 unref_peer(peer, "removing poke peer ref")); 26242 26243 if (p->relatedpeer) 26244 p->relatedpeer = unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else."); 26245 p->relatedpeer = ref_peer(peer, "setting the relatedpeer field in the dialog"); 26246 ast_set_flag(&p->flags[0], SIP_OUTGOING); 26247 #ifdef VOCAL_DATA_HACK 26248 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 26249 xmitres = transmit_invite(p, SIP_INVITE, 0, 2, NULL); /* sinks the p refcount */ 26250 #else 26251 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2, NULL); /* sinks the p refcount */ 26252 #endif 26253 peer->ps = ast_tvnow(); 26254 if (xmitres == XMIT_ERROR) { 26255 /* Immediately unreachable, network problems */ 26256 sip_poke_noanswer(ref_peer(peer, "add ref for peerexpire (fake, for sip_poke_noanswer to remove)")); 26257 } else if (!force) { 26258 AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, peer->maxms * 2, sip_poke_noanswer, peer, 26259 unref_peer(_data, "removing poke peer ref"), 26260 unref_peer(peer, "removing poke peer ref"), 26261 ref_peer(peer, "adding poke peer ref")); 26262 } 26263 dialog_unref(p, "unref dialog at end of sip_poke_peer, obtained from sip_alloc, just before it goes out of scope"); 26264 return 0; 26265 }
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 13734 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().
13735 { 13736 struct sip_peer *peer = (struct sip_peer *)data; 13737 struct sip_peer *foundpeer; 13738 13739 peer->pokeexpire = -1; 13740 13741 foundpeer = ao2_find(peers, peer, OBJ_POINTER); 13742 if (!foundpeer) { 13743 unref_peer(peer, "removing poke peer ref"); 13744 return 0; 13745 } else if (foundpeer->name != peer->name) { 13746 unref_peer(foundpeer, "removing above peer ref"); 13747 unref_peer(peer, "removing poke peer ref"); 13748 return 0; 13749 } 13750 13751 unref_peer(foundpeer, "removing above peer ref"); 13752 sip_poke_peer(peer, 0); 13753 unref_peer(peer, "removing poke peer ref"); 13754 13755 return 0; 13756 }
static int sip_prepare_socket | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 25389 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_tcptls_close_session_file(), 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().
25390 { 25391 struct sip_socket *s = &p->socket; 25392 static const char name[] = "SIP socket"; 25393 struct sip_threadinfo *th = NULL; 25394 struct ast_tcptls_session_instance *tcptls_session; 25395 struct ast_tcptls_session_args *ca; 25396 struct ast_sockaddr sa_tmp; 25397 25398 /* check to see if a socket is already active */ 25399 if ((s->fd != -1) && (s->type == SIP_TRANSPORT_UDP)) { 25400 return s->fd; 25401 } 25402 if ((s->type & (SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS)) && 25403 (s->tcptls_session) && 25404 (s->tcptls_session->fd != -1)) { 25405 return s->tcptls_session->fd; 25406 } 25407 25408 /*! \todo Check this... This might be wrong, depending on the proxy configuration 25409 If proxy is in "force" mode its correct. 25410 */ 25411 if (p->outboundproxy && p->outboundproxy->transport) { 25412 s->type = p->outboundproxy->transport; 25413 } 25414 25415 if (s->type == SIP_TRANSPORT_UDP) { 25416 s->fd = sipsock; 25417 return s->fd; 25418 } 25419 25420 /* At this point we are dealing with a TCP/TLS connection 25421 * 1. We need to check to see if a connectin thread exists 25422 * for this address, if so use that. 25423 * 2. If a thread does not exist for this address, but the tcptls_session 25424 * exists on the socket, the connection was closed. 25425 * 3. If no tcptls_session thread exists for the address, and no tcptls_session 25426 * already exists on the socket, create a new one and launch a new thread. 25427 */ 25428 25429 /* 1. check for existing threads */ 25430 ast_sockaddr_copy(&sa_tmp, sip_real_dst(p)); 25431 if ((tcptls_session = sip_tcp_locate(&sa_tmp))) { 25432 s->fd = tcptls_session->fd; 25433 if (s->tcptls_session) { 25434 ao2_ref(s->tcptls_session, -1); 25435 s->tcptls_session = NULL; 25436 } 25437 s->tcptls_session = tcptls_session; 25438 return s->fd; 25439 /* 2. Thread not found, if tcptls_session already exists, it once had a thread and is now terminated */ 25440 } else if (s->tcptls_session) { 25441 return s->fd; /* XXX whether reconnection is ever necessary here needs to be investigated further */ 25442 } 25443 25444 /* 3. Create a new TCP/TLS client connection */ 25445 /* create new session arguments for the client connection */ 25446 if (!(ca = ao2_alloc(sizeof(*ca), sip_tcptls_client_args_destructor)) || 25447 !(ca->name = ast_strdup(name))) { 25448 goto create_tcptls_session_fail; 25449 } 25450 ca->accept_fd = -1; 25451 ast_sockaddr_copy(&ca->remote_address,sip_real_dst(p)); 25452 /* if type is TLS, we need to create a tls cfg for this session arg */ 25453 if (s->type == SIP_TRANSPORT_TLS) { 25454 if (!(ca->tls_cfg = ast_calloc(1, sizeof(*ca->tls_cfg)))) { 25455 goto create_tcptls_session_fail; 25456 } 25457 memcpy(ca->tls_cfg, &default_tls_cfg, sizeof(*ca->tls_cfg)); 25458 25459 if (!(ca->tls_cfg->certfile = ast_strdup(default_tls_cfg.certfile)) || 25460 !(ca->tls_cfg->pvtfile = ast_strdup(default_tls_cfg.pvtfile)) || 25461 !(ca->tls_cfg->cipher = ast_strdup(default_tls_cfg.cipher)) || 25462 !(ca->tls_cfg->cafile = ast_strdup(default_tls_cfg.cafile)) || 25463 !(ca->tls_cfg->capath = ast_strdup(default_tls_cfg.capath))) { 25464 25465 goto create_tcptls_session_fail; 25466 } 25467 25468 /* this host is used as the common name in ssl/tls */ 25469 if (!ast_strlen_zero(p->tohost)) { 25470 ast_copy_string(ca->hostname, p->tohost, sizeof(ca->hostname)); 25471 } 25472 } 25473 25474 /* Create a client connection for address, this does not start the connection, just sets it up. */ 25475 if (!(s->tcptls_session = ast_tcptls_client_create(ca))) { 25476 goto create_tcptls_session_fail; 25477 } 25478 25479 s->fd = s->tcptls_session->fd; 25480 25481 /* client connections need to have the sip_threadinfo object created before 25482 * the thread is detached. This ensures the alert_pipe is up before it will 25483 * be used. Note that this function links the new threadinfo object into the 25484 * threadt container. */ 25485 if (!(th = sip_threadinfo_create(s->tcptls_session, s->type))) { 25486 goto create_tcptls_session_fail; 25487 } 25488 25489 /* Give the new thread a reference to the tcptls_session */ 25490 ao2_ref(s->tcptls_session, +1); 25491 25492 if (ast_pthread_create_background(&ca->master, NULL, sip_tcp_worker_fn, s->tcptls_session)) { 25493 ast_debug(1, "Unable to launch '%s'.", ca->name); 25494 ao2_ref(s->tcptls_session, -1); /* take away the thread ref we just gave it */ 25495 goto create_tcptls_session_fail; 25496 } 25497 25498 return s->fd; 25499 25500 create_tcptls_session_fail: 25501 if (ca) { 25502 ao2_t_ref(ca, -1, "failed to create client, getting rid of client tcptls_session arguments"); 25503 } 25504 if (s->tcptls_session) { 25505 ast_tcptls_close_session_file(tcptls_session); 25506 s->fd = -1; 25507 ao2_ref(s->tcptls_session, -1); 25508 s->tcptls_session = NULL; 25509 } 25510 if (th) { 25511 ao2_t_unlink(threadt, th, "Removing tcptls thread info object, thread failed to open"); 25512 } 25513 25514 return -1; 25515 }
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 17038 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.
17039 { 17040 struct sip_peer *peer, *pi; 17041 int prunepeer = FALSE; 17042 int multi = FALSE; 17043 const char *name = NULL; 17044 regex_t regexbuf; 17045 int havepattern = 0; 17046 struct ao2_iterator i; 17047 static const char * const choices[] = { "all", "like", NULL }; 17048 char *cmplt; 17049 17050 if (cmd == CLI_INIT) { 17051 e->command = "sip prune realtime [peer|all]"; 17052 e->usage = 17053 "Usage: sip prune realtime [peer [<name>|all|like <pattern>]|all]\n" 17054 " Prunes object(s) from the cache.\n" 17055 " Optional regular expression pattern is used to filter the objects.\n"; 17056 return NULL; 17057 } else if (cmd == CLI_GENERATE) { 17058 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) { 17059 cmplt = ast_cli_complete(a->word, choices, a->n); 17060 if (!cmplt) 17061 cmplt = complete_sip_peer(a->word, a->n - sizeof(choices), SIP_PAGE2_RTCACHEFRIENDS); 17062 return cmplt; 17063 } 17064 if (a->pos == 5 && !strcasecmp(a->argv[4], "like")) 17065 return complete_sip_peer(a->word, a->n, SIP_PAGE2_RTCACHEFRIENDS); 17066 return NULL; 17067 } 17068 switch (a->argc) { 17069 case 4: 17070 name = a->argv[3]; 17071 /* we accept a name in position 3, but keywords are not good. */ 17072 if (!strcasecmp(name, "peer") || !strcasecmp(name, "like")) 17073 return CLI_SHOWUSAGE; 17074 prunepeer = TRUE; 17075 if (!strcasecmp(name, "all")) { 17076 multi = TRUE; 17077 name = NULL; 17078 } 17079 /* else a single name, already set */ 17080 break; 17081 case 5: 17082 /* sip prune realtime {peer|like} name */ 17083 name = a->argv[4]; 17084 if (!strcasecmp(a->argv[3], "peer")) 17085 prunepeer = TRUE; 17086 else if (!strcasecmp(a->argv[3], "like")) { 17087 prunepeer = TRUE; 17088 multi = TRUE; 17089 } else 17090 return CLI_SHOWUSAGE; 17091 if (!strcasecmp(name, "like")) 17092 return CLI_SHOWUSAGE; 17093 if (!multi && !strcasecmp(name, "all")) { 17094 multi = TRUE; 17095 name = NULL; 17096 } 17097 break; 17098 case 6: 17099 name = a->argv[5]; 17100 multi = TRUE; 17101 /* sip prune realtime {peer} like name */ 17102 if (strcasecmp(a->argv[4], "like")) 17103 return CLI_SHOWUSAGE; 17104 if (!strcasecmp(a->argv[3], "peer")) { 17105 prunepeer = TRUE; 17106 } else 17107 return CLI_SHOWUSAGE; 17108 break; 17109 default: 17110 return CLI_SHOWUSAGE; 17111 } 17112 17113 if (multi && name) { 17114 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) { 17115 return CLI_SHOWUSAGE; 17116 } 17117 havepattern = 1; 17118 } 17119 17120 if (multi) { 17121 if (prunepeer) { 17122 int pruned = 0; 17123 17124 i = ao2_iterator_init(peers, 0); 17125 while ((pi = ao2_t_iterator_next(&i, "iterate thru peers table"))) { 17126 ao2_lock(pi); 17127 if (name && regexec(®exbuf, pi->name, 0, NULL, 0)) { 17128 ao2_unlock(pi); 17129 unref_peer(pi, "toss iterator peer ptr before continue"); 17130 continue; 17131 }; 17132 if (ast_test_flag(&pi->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 17133 pi->the_mark = 1; 17134 pruned++; 17135 } 17136 ao2_unlock(pi); 17137 unref_peer(pi, "toss iterator peer ptr"); 17138 } 17139 ao2_iterator_destroy(&i); 17140 if (pruned) { 17141 unlink_marked_peers_from_tables(); 17142 ast_cli(a->fd, "%d peers pruned.\n", pruned); 17143 } else 17144 ast_cli(a->fd, "No peers found to prune.\n"); 17145 } 17146 } else { 17147 if (prunepeer) { 17148 struct sip_peer tmp; 17149 ast_copy_string(tmp.name, name, sizeof(tmp.name)); 17150 if ((peer = ao2_t_find(peers, &tmp, OBJ_POINTER | OBJ_UNLINK, "finding to unlink from peers"))) { 17151 if (!ast_sockaddr_isnull(&peer->addr)) { 17152 ao2_t_unlink(peers_by_ip, peer, "unlinking peer from peers_by_ip also"); 17153 } 17154 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 17155 ast_cli(a->fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 17156 /* put it back! */ 17157 ao2_t_link(peers, peer, "link peer into peer table"); 17158 if (!ast_sockaddr_isnull(&peer->addr)) { 17159 ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table"); 17160 } 17161 } else 17162 ast_cli(a->fd, "Peer '%s' pruned.\n", name); 17163 unref_peer(peer, "sip_prune_realtime: unref_peer: tossing temp peer ptr"); 17164 } else 17165 ast_cli(a->fd, "Peer '%s' not found.\n", name); 17166 } 17167 } 17168 17169 if (havepattern) { 17170 regfree(®exbuf); 17171 } 17172 17173 return CLI_SUCCESS; 17174 }
static struct ast_channel * sip_pvt_lock_full | ( | struct sip_pvt * | pvt | ) | [static] |
Definition at line 7999 of file chan_sip.c.
References ast_channel_lock, ast_channel_ref, ast_channel_unlock, ast_channel_unref, sip_pvt_lock, and sip_pvt_unlock.
Referenced by __sip_autodestruct(), dialog_unlink_all(), handle_request_do(), and send_provisional_keepalive_full().
08000 { 08001 struct ast_channel *chan; 08002 08003 /* Locking is simple when it is done right. If you see a deadlock resulting 08004 * in this function, it is not this function's fault, Your problem exists elsewhere. 08005 * This function is perfect... seriously. */ 08006 for (;;) { 08007 /* First, get the channel and grab a reference to it */ 08008 sip_pvt_lock(pvt); 08009 chan = pvt->owner; 08010 if (chan) { 08011 /* The channel can not go away while we hold the pvt lock. 08012 * Give the channel a ref so it will not go away after we let 08013 * the pvt lock go. */ 08014 ast_channel_ref(chan); 08015 } else { 08016 /* no channel, return pvt locked */ 08017 return NULL; 08018 } 08019 08020 /* We had to hold the pvt lock while getting a ref to the owner channel 08021 * but now we have to let this lock go in order to preserve proper 08022 * locking order when grabbing the channel lock */ 08023 sip_pvt_unlock(pvt); 08024 08025 /* Look, no deadlock avoidance, hooray! */ 08026 ast_channel_lock(chan); 08027 sip_pvt_lock(pvt); 08028 08029 if (pvt->owner == chan) { 08030 /* done */ 08031 break; 08032 } 08033 08034 /* If the owner changed while everything was unlocked, no problem, 08035 * just start over and everthing will work. This is rare, do not be 08036 * confused by this loop and think this it is an expensive operation. 08037 * The majority of the calls to this function will never involve multiple 08038 * executions of this loop. */ 08039 ast_channel_unlock(chan); 08040 ast_channel_unref(chan); 08041 sip_pvt_unlock(pvt); 08042 } 08043 08044 /* If owner exists, it is locked and reffed */ 08045 return pvt->owner; 08046 }
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 17323 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.
17324 { 17325 switch (cmd) { 17326 case CLI_INIT: 17327 e->command = "sip qualify peer"; 17328 e->usage = 17329 "Usage: sip qualify peer <name> [load]\n" 17330 " Requests a response from one SIP peer and the current status.\n" 17331 " Option \"load\" forces lookup of peer in realtime storage.\n"; 17332 return NULL; 17333 case CLI_GENERATE: 17334 return complete_sip_show_peer(a->line, a->word, a->pos, a->n); 17335 } 17336 return _sip_qualify_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv); 17337 }
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 4339 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.
04340 { 04341 int res = -1; 04342 enum ast_t38_state state = T38_STATE_UNAVAILABLE; 04343 struct sip_pvt *p = (struct sip_pvt *) chan->tech_pvt; 04344 char *cp; 04345 04346 sip_pvt_lock(p); 04347 04348 switch (option) { 04349 case AST_OPTION_T38_STATE: 04350 /* Make sure we got an ast_t38_state enum passed in */ 04351 if (*datalen != sizeof(enum ast_t38_state)) { 04352 ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option. Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen); 04353 break; 04354 } 04355 04356 /* 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 */ 04357 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) { 04358 switch (p->t38.state) { 04359 case T38_LOCAL_REINVITE: 04360 case T38_PEER_REINVITE: 04361 state = T38_STATE_NEGOTIATING; 04362 break; 04363 case T38_ENABLED: 04364 state = T38_STATE_NEGOTIATED; 04365 break; 04366 default: 04367 state = T38_STATE_UNKNOWN; 04368 } 04369 } 04370 04371 *((enum ast_t38_state *) data) = state; 04372 res = 0; 04373 04374 break; 04375 case AST_OPTION_DIGIT_DETECT: 04376 cp = (char *) data; 04377 *cp = p->dsp ? 1 : 0; 04378 ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", chan->name); 04379 break; 04380 case AST_OPTION_SECURE_SIGNALING: 04381 *((unsigned int *) data) = p->req_secure_signaling; 04382 res = 0; 04383 break; 04384 case AST_OPTION_SECURE_MEDIA: 04385 *((unsigned int *) data) = ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP) ? 1 : 0; 04386 res = 0; 04387 break; 04388 case AST_OPTION_DEVICE_NAME: 04389 if (p && p->outgoing_call) { 04390 cp = (char *) data; 04391 ast_copy_string(cp, p->dialstring, *datalen); 04392 res = 0; 04393 } 04394 /* We purposely break with a return of -1 in the 04395 * implied else case here 04396 */ 04397 break; 04398 default: 04399 break; 04400 } 04401 04402 sip_pvt_unlock(p); 04403 04404 return res; 04405 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
Read SIP RTP from channel.
Definition at line 7467 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, ast_channel::caller, ast_channel::context, ast_channel::exten, FALSE, ast_frame::frametype, ast_party_caller::id, LOG_NOTICE, ast_channel::macrocontext, ast_party_id::number, pbx_builtin_setvar_helper(), S_COR, S_OR, sip_pvt_lock, sip_pvt_unlock, sip_rtp_read(), ast_party_number::str, ast_channel::tech_pvt, ast_party_number::valid, and VERBOSE_PREFIX_2.
07468 { 07469 struct ast_frame *fr; 07470 struct sip_pvt *p = ast->tech_pvt; 07471 int faxdetected = FALSE; 07472 07473 sip_pvt_lock(p); 07474 fr = sip_rtp_read(ast, p, &faxdetected); 07475 p->lastrtprx = time(NULL); 07476 07477 /* If we detect a CNG tone and fax detection is enabled then send us off to the fax extension */ 07478 if (faxdetected && ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) { 07479 if (strcmp(ast->exten, "fax")) { 07480 const char *target_context = S_OR(ast->macrocontext, ast->context); 07481 /* We need to unlock 'ast' here because 07482 * ast_exists_extension has the potential to start and 07483 * stop an autoservice on the channel. Such action is 07484 * prone to deadlock if the channel is locked. 07485 */ 07486 sip_pvt_unlock(p); 07487 ast_channel_unlock(ast); 07488 if (ast_exists_extension(ast, target_context, "fax", 1, 07489 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) { 07490 ast_channel_lock(ast); 07491 sip_pvt_lock(p); 07492 ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to CNG detection\n", ast->name); 07493 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 07494 if (ast_async_goto(ast, target_context, "fax", 1)) { 07495 ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 07496 } 07497 fr = &ast_null_frame; 07498 } else { 07499 ast_channel_lock(ast); 07500 sip_pvt_lock(p); 07501 ast_log(LOG_NOTICE, "FAX CNG detected but no fax extension\n"); 07502 } 07503 } 07504 } 07505 07506 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 07507 if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 07508 fr = &ast_null_frame; 07509 } 07510 07511 sip_pvt_unlock(p); 07512 07513 return fr; 07514 }
static struct ast_sockaddr * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static] |
The real destination address for a write.
Definition at line 3204 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().
03205 { 03206 if (p->outboundproxy) { 03207 return &p->outboundproxy->ip; 03208 } 03209 03210 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; 03211 }
static const char* sip_reason_code_to_str | ( | enum AST_REDIRECTING_REASON | code | ) | [static] |
Definition at line 2286 of file chan_sip.c.
References ARRAY_LEN, sip_reason_table, and sip_reasons::text.
Referenced by add_diversion_header().
02287 { 02288 if (code >= 0 && code < ARRAY_LEN(sip_reason_table)) { 02289 return sip_reason_table[code].text; 02290 } 02291 02292 return "unknown"; 02293 }
static enum AST_REDIRECTING_REASON sip_reason_str_to_code | ( | const char * | text | ) | [static] |
Definition at line 2271 of file chan_sip.c.
References ARRAY_LEN, AST_REDIRECTING_REASON_UNKNOWN, sip_reasons::code, and sip_reason_table.
Referenced by get_rdnis().
02272 { 02273 enum AST_REDIRECTING_REASON ast = AST_REDIRECTING_REASON_UNKNOWN; 02274 int i; 02275 02276 for (i = 0; i < ARRAY_LEN(sip_reason_table); ++i) { 02277 if (!strcasecmp(text, sip_reason_table[i].text)) { 02278 ast = sip_reason_table[i].code; 02279 break; 02280 } 02281 } 02282 02283 return ast; 02284 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 13422 of file chan_sip.c.
References ast_calloc.
Referenced by get_also_info(), handle_request_invite(), handle_request_refer(), and transmit_refer().
13423 { 13424 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 13425 return p->refer ? 1 : 0; 13426 }
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 13085 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().
13086 { 13087 13088 /* if we are here, our registration timed out, so we'll just do it over */ 13089 struct sip_registry *r = (struct sip_registry *)data; /* the ref count should have been bumped when the sched item was added */ 13090 struct sip_pvt *p; 13091 13092 /* if we couldn't get a reference to the registry object, punt */ 13093 if (!r) { 13094 return 0; 13095 } 13096 13097 if (r->dnsmgr) { 13098 /* If the registration has timed out, maybe the IP changed. Force a refresh. */ 13099 ast_dnsmgr_refresh(r->dnsmgr); 13100 } 13101 13102 /* If the initial tranmission failed, we may not have an existing dialog, 13103 * so it is possible that r->call == NULL. 13104 * Otherwise destroy it, as we have a timeout so we don't want it. 13105 */ 13106 if (r->call) { 13107 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 13108 in the single SIP manager thread. */ 13109 p = r->call; 13110 sip_pvt_lock(p); 13111 pvt_set_needdestroy(p, "registration timeout"); 13112 /* Pretend to ACK anything just in case */ 13113 __sip_pretend_ack(p); 13114 sip_pvt_unlock(p); 13115 13116 /* decouple the two objects */ 13117 /* p->registry == r, so r has 2 refs, and the unref won't take the object away */ 13118 if (p->registry) { 13119 p->registry = registry_unref(p->registry, "p->registry unreffed"); 13120 } 13121 r->call = dialog_unref(r->call, "unrefing r->call"); 13122 } 13123 /* If we have a limit, stop registration and give up */ 13124 r->timeout = -1; 13125 if (global_regattempts_max && r->regattempts >= global_regattempts_max) { 13126 /* Ok, enough is enough. Don't try any more */ 13127 /* We could add an external notification here... 13128 steal it from app_voicemail :-) */ 13129 ast_log(LOG_NOTICE, " -- Last Registration Attempt #%d failed, Giving up forever trying to register '%s@%s'\n", r->regattempts, r->username, r->hostname); 13130 r->regstate = REG_STATE_FAILED; 13131 } else { 13132 r->regstate = REG_STATE_UNREGISTERED; 13133 transmit_register(r, SIP_REGISTER, NULL, NULL); 13134 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 13135 } 13136 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)); 13137 registry_unref(r, "unreffing registry_unref r"); 13138 return 0; 13139 }
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 8213 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, regobjs, and sip_parse_register_line().
Referenced by build_peer().
08214 { 08215 struct sip_registry *reg; 08216 08217 if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) { 08218 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 08219 return -1; 08220 } 08221 08222 ast_atomic_fetchadd_int(®objs, 1); 08223 ASTOBJ_INIT(reg); 08224 08225 if (sip_parse_register_line(reg, default_expiry, value, lineno)) { 08226 registry_unref(reg, "failure to parse, unref the reg pointer"); 08227 return -1; 08228 } 08229 08230 /* set default expiry if necessary */ 08231 if (reg->refresh && !reg->expiry && !reg->configured_expiry) { 08232 reg->refresh = reg->expiry = reg->configured_expiry = default_expiry; 08233 } 08234 08235 /* Add the new registry entry to the list */ 08236 ASTOBJ_CONTAINER_LINK(®l, reg); 08237 08238 /* release the reference given by ASTOBJ_INIT. The container has another reference */ 08239 registry_unref(reg, "unref the reg pointer"); 08240 08241 return 0; 08242 }
static void sip_register_tests | ( | void | ) | [static] |
SIP test registration.
Definition at line 29801 of file chan_sip.c.
References sip_config_parser_register_tests(), sip_dialplan_function_register_tests(), and sip_request_parser_register_tests().
Referenced by load_module().
29802 { 29803 sip_config_parser_register_tests(); 29804 sip_request_parser_register_tests(); 29805 sip_dialplan_function_register_tests(); 29806 }
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 5700 of file chan_sip.c.
References ast_atomic_fetchadd_int(), ast_debug, ast_free, AST_SCHED_DEL, ast_string_field_free_memory, dialog_unlink_all(), registry_unref(), and regobjs.
Referenced by registry_unref(), reload_config(), and unload_module().
05701 { 05702 /* Really delete */ 05703 ast_debug(3, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 05704 05705 if (reg->call) { 05706 /* Clear registry before destroying to ensure 05707 we don't get reentered trying to grab the registry lock */ 05708 reg->call->registry = registry_unref(reg->call->registry, "destroy reg->call->registry"); 05709 ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 05710 dialog_unlink_all(reg->call); 05711 reg->call = dialog_unref(reg->call, "unref reg->call"); 05712 /* reg->call = sip_destroy(reg->call); */ 05713 } 05714 AST_SCHED_DEL(sched, reg->expire); 05715 AST_SCHED_DEL(sched, reg->timeout); 05716 05717 ast_string_field_free_memory(reg); 05718 ast_atomic_fetchadd_int(®objs, -1); 05719 ast_free(reg); 05720 }
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 19767 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().
19768 { 19769 struct sip_pvt *p = (struct sip_pvt *) data; 19770 struct ast_channel *owner; 19771 19772 sip_pvt_lock(p); /* called from schedule thread which requires a lock */ 19773 while ((owner = p->owner) && ast_channel_trylock(owner)) { 19774 sip_pvt_unlock(p); 19775 usleep(1); 19776 sip_pvt_lock(p); 19777 } 19778 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 19779 p->waitid = -1; 19780 check_pendings(p); 19781 sip_pvt_unlock(p); 19782 if (owner) { 19783 ast_channel_unlock(owner); 19784 } 19785 dialog_unref(p, "unref the dialog ptr from sip_reinvite_retry, because it held a dialog ptr"); 19786 return 0; 19787 }
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 29573 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().
29574 { 29575 29576 switch (cmd) { 29577 case CLI_INIT: 29578 e->command = "sip reload"; 29579 e->usage = 29580 "Usage: sip reload\n" 29581 " Reloads SIP configuration from sip.conf\n"; 29582 return NULL; 29583 case CLI_GENERATE: 29584 return NULL; 29585 } 29586 29587 ast_mutex_lock(&sip_reload_lock); 29588 if (sip_reloading) { 29589 ast_verbose("Previous SIP reload not yet done\n"); 29590 } else { 29591 sip_reloading = TRUE; 29592 sip_reloadreason = (a && a->fd) ? CHANNEL_CLI_RELOAD : CHANNEL_MODULE_RELOAD; 29593 } 29594 ast_mutex_unlock(&sip_reload_lock); 29595 restart_monitor(); 29596 29597 return CLI_SUCCESS; 29598 }
static int sip_removeheader | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Remove SIP headers added previously with SipAddHeader application.
Definition at line 29318 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().
29319 { 29320 struct ast_var_t *newvariable; 29321 struct varshead *headp; 29322 int removeall = 0; 29323 char *inbuf = (char *) data; 29324 29325 if (ast_strlen_zero(inbuf)) { 29326 removeall = 1; 29327 } 29328 ast_channel_lock(chan); 29329 29330 headp=&chan->varshead; 29331 AST_LIST_TRAVERSE_SAFE_BEGIN (headp, newvariable, entries) { 29332 if (strncasecmp(ast_var_name(newvariable), "SIPADDHEADER", strlen("SIPADDHEADER")) == 0) { 29333 if (removeall || (!strncasecmp(ast_var_value(newvariable),inbuf,strlen(inbuf)))) { 29334 if (sipdebug) 29335 ast_debug(1,"removing SIP Header \"%s\" as %s\n", 29336 ast_var_value(newvariable), 29337 ast_var_name(newvariable)); 29338 AST_LIST_REMOVE_CURRENT(entries); 29339 ast_var_delete(newvariable); 29340 } 29341 } 29342 } 29343 AST_LIST_TRAVERSE_SAFE_END; 29344 29345 ast_channel_unlock(chan); 29346 return 0; 29347 }
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 26379 of file chan_sip.c.
References args, AST_APP_ARG, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CHANNEL_UNACCEPTABLE, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, ast_channel_unlock, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, AST_FORMAT_AUDIO_MASK, ast_getformatname(), ast_getformatname_multiple(), ast_log(), AST_NONSTANDARD_APP_ARGS, ast_sip_ouraddrfor(), ast_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_via(), change_callid_pvt(), create_addr(), dialog_unlink_all(), 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.
26380 { 26381 struct sip_pvt *p; 26382 struct ast_channel *tmpc = NULL; 26383 char *ext = NULL, *host; 26384 char tmp[256]; 26385 char *dest = data; 26386 char *dnid; 26387 char *secret = NULL; 26388 char *md5secret = NULL; 26389 char *authname = NULL; 26390 char *trans = NULL; 26391 char dialstring[256]; 26392 char *remote_address; 26393 enum sip_transport transport = 0; 26394 struct ast_sockaddr remote_address_sa = { {0,} }; 26395 format_t oldformat = format; 26396 AST_DECLARE_APP_ARGS(args, 26397 AST_APP_ARG(peerorhost); 26398 AST_APP_ARG(exten); 26399 AST_APP_ARG(remote_address); 26400 ); 26401 26402 /* mask request with some set of allowed formats. 26403 * XXX this needs to be fixed. 26404 * The original code uses AST_FORMAT_AUDIO_MASK, but it is 26405 * unclear what to use here. We have global_capabilities, which is 26406 * configured from sip.conf, and sip_tech.capabilities, which is 26407 * hardwired to all audio formats. 26408 */ 26409 format &= AST_FORMAT_AUDIO_MASK; 26410 if (!format) { 26411 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)); 26412 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 26413 return NULL; 26414 } 26415 ast_debug(1, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 26416 26417 if (ast_strlen_zero(dest)) { 26418 ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n"); 26419 *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE; 26420 return NULL; 26421 } 26422 26423 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE, NULL))) { 26424 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", dest); 26425 *cause = AST_CAUSE_SWITCH_CONGESTION; 26426 return NULL; 26427 } 26428 26429 p->outgoing_call = TRUE; 26430 26431 snprintf(dialstring, sizeof(dialstring), "%s/%s", type, dest); 26432 ast_string_field_set(p, dialstring, dialstring); 26433 26434 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 26435 dialog_unlink_all(p); 26436 dialog_unref(p, "unref dialog p from mem fail"); 26437 /* sip_destroy(p); */ 26438 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 26439 *cause = AST_CAUSE_SWITCH_CONGESTION; 26440 return NULL; 26441 } 26442 26443 /* Save the destination, the SIP dial string */ 26444 ast_copy_string(tmp, dest, sizeof(tmp)); 26445 26446 /* Find DNID and take it away */ 26447 dnid = strchr(tmp, '!'); 26448 if (dnid != NULL) { 26449 *dnid++ = '\0'; 26450 ast_string_field_set(p, todnid, dnid); 26451 } 26452 26453 /* Divvy up the items separated by slashes */ 26454 AST_NONSTANDARD_APP_ARGS(args, tmp, '/'); 26455 26456 /* Find at sign - @ */ 26457 host = strchr(args.peerorhost, '@'); 26458 if (host) { 26459 *host++ = '\0'; 26460 ext = args.peerorhost; 26461 secret = strchr(ext, ':'); 26462 } 26463 if (secret) { 26464 *secret++ = '\0'; 26465 md5secret = strchr(secret, ':'); 26466 } 26467 if (md5secret) { 26468 *md5secret++ = '\0'; 26469 authname = strchr(md5secret, ':'); 26470 } 26471 if (authname) { 26472 *authname++ = '\0'; 26473 trans = strchr(authname, ':'); 26474 } 26475 if (trans) { 26476 *trans++ = '\0'; 26477 if (!strcasecmp(trans, "tcp")) 26478 transport = SIP_TRANSPORT_TCP; 26479 else if (!strcasecmp(trans, "tls")) 26480 transport = SIP_TRANSPORT_TLS; 26481 else { 26482 if (strcasecmp(trans, "udp")) 26483 ast_log(LOG_WARNING, "'%s' is not a valid transport option to Dial() for SIP calls, using udp by default.\n", trans); 26484 transport = SIP_TRANSPORT_UDP; 26485 } 26486 } else { /* use default */ 26487 transport = SIP_TRANSPORT_UDP; 26488 } 26489 26490 if (!host) { 26491 ext = args.exten; 26492 host = args.peerorhost; 26493 remote_address = args.remote_address; 26494 } else { 26495 remote_address = args.remote_address; 26496 if (!ast_strlen_zero(args.exten)) { 26497 ast_log(LOG_NOTICE, "Conflicting extension values given. Using '%s' and not '%s'\n", ext, args.exten); 26498 } 26499 } 26500 26501 if (!ast_strlen_zero(remote_address)) { 26502 if (ast_sockaddr_resolve_first(&remote_address_sa, remote_address, 0)) { 26503 ast_log(LOG_WARNING, "Unable to find IP address for host %s. We will not use this remote IP address\n", remote_address); 26504 } else { 26505 if (!ast_sockaddr_port(&remote_address_sa)) { 26506 ast_sockaddr_set_port(&remote_address_sa, 26507 transport & SIP_TRANSPORT_TLS ? 26508 STANDARD_TLS_PORT : 26509 STANDARD_SIP_PORT); 26510 } 26511 } 26512 } 26513 26514 set_socket_transport(&p->socket, transport); 26515 26516 /* We now have 26517 host = peer name, DNS host name or DNS domain (for SRV) 26518 ext = extension (user part of URI) 26519 dnid = destination of the call (applies to the To: header) 26520 */ 26521 if (create_addr(p, host, NULL, 1, &remote_address_sa)) { 26522 *cause = AST_CAUSE_UNREGISTERED; 26523 ast_debug(3, "Cant create SIP call - target device not registered\n"); 26524 dialog_unlink_all(p); 26525 dialog_unref(p, "unref dialog p UNREGISTERED"); 26526 /* sip_destroy(p); */ 26527 return NULL; 26528 } 26529 if (ast_strlen_zero(p->peername) && ext) 26530 ast_string_field_set(p, peername, ext); 26531 /* Recalculate our side, and recalculate Call ID */ 26532 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 26533 build_via(p); 26534 26535 /* Change the dialog callid. */ 26536 change_callid_pvt(p, NULL); 26537 26538 /* We have an extension to call, don't use the full contact here */ 26539 /* This to enable dialing registered peers with extension dialling, 26540 like SIP/peername/extension 26541 SIP/peername will still use the full contact 26542 */ 26543 if (ext) { 26544 ast_string_field_set(p, username, ext); 26545 ast_string_field_set(p, fullcontact, NULL); 26546 } 26547 if (secret && !ast_strlen_zero(secret)) 26548 ast_string_field_set(p, peersecret, secret); 26549 26550 if (md5secret && !ast_strlen_zero(md5secret)) 26551 ast_string_field_set(p, peermd5secret, md5secret); 26552 26553 if (authname && !ast_strlen_zero(authname)) 26554 ast_string_field_set(p, authname, authname); 26555 #if 0 26556 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 26557 #endif 26558 p->prefcodec = oldformat; /* Format for this call */ 26559 p->jointcapability = oldformat & p->capability; 26560 sip_pvt_lock(p); 26561 tmpc = sip_new(p, AST_STATE_DOWN, host, requestor ? requestor->linkedid : NULL); /* Place the call */ 26562 if (sip_cfg.callevents) 26563 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 26564 "Channel: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n", 26565 p->owner? p->owner->name : "", "SIP", p->callid, p->fullcontact, p->peername); 26566 sip_pvt_unlock(p); 26567 if (!tmpc) { 26568 dialog_unlink_all(p); 26569 /* sip_destroy(p); */ 26570 } else { 26571 ast_channel_unlock(tmpc); 26572 } 26573 dialog_unref(p, "toss pvt ptr at end of sip_request_call"); 26574 ast_update_use_count(); 26575 restart_monitor(); 26576 return tmpc; 26577 }
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 13042 of file chan_sip.c.
References __sip_do_register(), append_history, ast_log(), LOG_NOTICE, and registry_unref().
Referenced by handle_response_register(), sip_send_all_registers(), and sip_show_sched().
13043 { 13044 /* if we are here, we know that we need to reregister. */ 13045 struct sip_registry *r = (struct sip_registry *) data; 13046 13047 /* if we couldn't get a reference to the registry object, punt */ 13048 if (!r) { 13049 return 0; 13050 } 13051 13052 if (r->call && r->call->do_history) { 13053 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 13054 } 13055 /* Since registry's are only added/removed by the the monitor thread, this 13056 may be overkill to reference/dereference at all here */ 13057 if (sipdebug) { 13058 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 13059 } 13060 13061 r->expire = -1; 13062 r->expiry = r->configured_expiry; 13063 __sip_do_register(r); 13064 registry_unref(r, "unref the re-register scheduled event"); 13065 return 0; 13066 }
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 7378 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().
07379 { 07380 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 07381 struct ast_frame *f; 07382 07383 if (!p->rtp) { 07384 /* We have no RTP allocated for this channel */ 07385 return &ast_null_frame; 07386 } 07387 07388 switch(ast->fdno) { 07389 case 0: 07390 f = ast_rtp_instance_read(p->rtp, 0); /* RTP Audio */ 07391 break; 07392 case 1: 07393 f = ast_rtp_instance_read(p->rtp, 1); /* RTCP Control Channel */ 07394 break; 07395 case 2: 07396 f = ast_rtp_instance_read(p->vrtp, 0); /* RTP Video */ 07397 break; 07398 case 3: 07399 f = ast_rtp_instance_read(p->vrtp, 1); /* RTCP Control Channel for video */ 07400 break; 07401 case 4: 07402 f = ast_rtp_instance_read(p->trtp, 0); /* RTP Text */ 07403 if (sipdebug_text) { 07404 int i; 07405 unsigned char* arr = f->data.ptr; 07406 for (i=0; i < f->datalen; i++) 07407 ast_verbose("%c", (arr[i] > ' ' && arr[i] < '}') ? arr[i] : '.'); 07408 ast_verbose(" -> "); 07409 for (i=0; i < f->datalen; i++) 07410 ast_verbose("%02X ", arr[i]); 07411 ast_verbose("\n"); 07412 } 07413 break; 07414 case 5: 07415 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 07416 break; 07417 default: 07418 f = &ast_null_frame; 07419 } 07420 /* Don't forward RFC2833 if we're not supposed to */ 07421 if (f && (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && 07422 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) { 07423 ast_debug(1, "Ignoring DTMF (%c) RTP frame because dtmfmode is not RFC2833\n", f->subclass.integer); 07424 return &ast_null_frame; 07425 } 07426 07427 /* We already hold the channel lock */ 07428 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 07429 return f; 07430 07431 if (f && f->subclass.codec != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 07432 if (!(f->subclass.codec & p->jointcapability)) { 07433 ast_debug(1, "Bogus frame of format '%s' received from '%s'!\n", 07434 ast_getformatname(f->subclass.codec), p->owner->name); 07435 return &ast_null_frame; 07436 } 07437 ast_debug(1, "Oooh, format changed to %s\n", 07438 ast_getformatname(f->subclass.codec)); 07439 p->owner->nativeformats = (p->owner->nativeformats & (AST_FORMAT_VIDEO_MASK | AST_FORMAT_TEXT_MASK)) | f->subclass.codec; 07440 ast_set_read_format(p->owner, p->owner->readformat); 07441 ast_set_write_format(p->owner, p->owner->writeformat); 07442 } 07443 07444 if (f && p->dsp) { 07445 f = ast_dsp_process(p->owner, p->dsp, f); 07446 if (f && f->frametype == AST_FRAME_DTMF) { 07447 if (f->subclass.integer == 'f') { 07448 ast_debug(1, "Fax CNG detected on %s\n", ast->name); 07449 *faxdetect = 1; 07450 /* If we only needed this DSP for fax detection purposes we can just drop it now */ 07451 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 07452 ast_dsp_set_features(p->dsp, DSP_FEATURE_DIGIT_DETECT); 07453 } else { 07454 ast_dsp_free(p->dsp); 07455 p->dsp = NULL; 07456 } 07457 } else { 07458 ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.integer); 07459 } 07460 } 07461 } 07462 07463 return f; 07464 }
static const char* sip_sanitized_host | ( | const char * | host | ) | [static] |
Definition at line 13141 of file chan_sip.c.
References ast_sockaddr_parse(), ast_sockaddr_stringify_host_remote(), and PARSE_PORT_FORBID.
Referenced by transmit_register().
13142 { 13143 struct ast_sockaddr addr = { { 0, 0, }, }; 13144 13145 /* peer/sip_pvt->tohost and sip_registry->hostname should never have a port 13146 * in them, so we use PARSE_PORT_FORBID here. If this lookup fails, we return 13147 * the original host which is most likely a host name and not an IP. */ 13148 if (!ast_sockaddr_parse(&addr, host, PARSE_PORT_FORBID)) { 13149 return host; 13150 } 13151 return ast_sockaddr_stringify_host_remote(&addr); 13152 }
void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) |
Schedule destruction of SIP dialog.
Definition at line 3917 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().
03918 { 03919 if (p->final_destruction_scheduled) { 03920 return; /* already set final destruction */ 03921 } 03922 03923 if (ms < 0) { 03924 if (p->timer_t1 == 0) { 03925 p->timer_t1 = global_t1; /* Set timer T1 if not set (RFC 3261) */ 03926 } 03927 if (p->timer_b == 0) { 03928 p->timer_b = global_timer_b; /* Set timer B if not set (RFC 3261) */ 03929 } 03930 ms = p->timer_t1 * 64; 03931 } 03932 if (sip_debug_test_pvt(p)) { 03933 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 03934 } 03935 if (sip_cancel_destroy(p)) { 03936 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03937 } 03938 03939 if (p->do_history) { 03940 append_history(p, "SchedDestroy", "%d ms", ms); 03941 } 03942 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, dialog_ref(p, "setting ref as passing into ast_sched_add for __sip_autodestruct")); 03943 03944 if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_schedid > 0) { 03945 stop_session_timer(p); 03946 } 03947 }
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 3904 of file chan_sip.c.
References sip_scheddestroy().
Referenced by handle_request_bye().
03905 { 03906 if (p->final_destruction_scheduled) { 03907 return; /* already set final destruction */ 03908 } 03909 03910 sip_scheddestroy(p, ms); 03911 if (p->autokillid != -1) { 03912 p->final_destruction_scheduled = 1; 03913 } 03914 }
static void sip_send_all_mwi_subscriptions | ( | void | ) | [static] |
Send all MWI subscriptions.
Definition at line 29473 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().
29474 { 29475 ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { 29476 ASTOBJ_WRLOCK(iterator); 29477 AST_SCHED_DEL(sched, iterator->resub); 29478 if ((iterator->resub = ast_sched_add(sched, 1, sip_subscribe_mwi_do, ASTOBJ_REF(iterator))) < 0) { 29479 ASTOBJ_UNREF(iterator, sip_subscribe_mwi_destroy); 29480 } 29481 ASTOBJ_UNLOCK(iterator); 29482 } while (0)); 29483 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 29449 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().
29450 { 29451 int ms; 29452 int regspacing; 29453 if (!regobjs) 29454 return; 29455 regspacing = default_expiry * 1000/regobjs; 29456 if (regspacing > 100) { 29457 regspacing = 100; 29458 } 29459 ms = regspacing; 29460 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 29461 ASTOBJ_WRLOCK(iterator); 29462 ms += regspacing; 29463 AST_SCHED_REPLACE_UNREF(iterator->expire, sched, ms, sip_reregister, iterator, 29464 registry_unref(_data, "REPLACE sched del decs the refcount"), 29465 registry_unref(iterator, "REPLACE sched add failure decs the refcount"), 29466 registry_addref(iterator, "REPLACE sched add incs the refcount")); 29467 ASTOBJ_UNLOCK(iterator); 29468 } while (0) 29469 ); 29470 }
static int sip_send_mwi_to_peer | ( | struct sip_peer * | peer, | |
int | cache_only | |||
) | [static] |
Send message waiting indication to alert peer that they've got voicemail.
Definition at line 25547 of file chan_sip.c.
References ao2_lock, ao2_unlock, ast_app_inboxcount(), ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_isnull(), ast_str_alloca, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_via(), change_callid_pvt(), create_addr_from_peer(), default_mwi_from, dialog_unlink_all(), get_cached_mwi(), peer_mailboxes_to_str(), set_socket_transport(), sip_alloc(), sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), and transmit_notify_with_mwi().
Referenced by build_peer(), handle_request_subscribe(), and mwi_event_cb().
25548 { 25549 /* Called with peer lock, but releases it */ 25550 struct sip_pvt *p; 25551 int newmsgs = 0, oldmsgs = 0; 25552 const char *vmexten = NULL; 25553 25554 ao2_lock(peer); 25555 25556 if (peer->vmexten) { 25557 vmexten = ast_strdupa(peer->vmexten); 25558 } 25559 25560 if (ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY) && !peer->mwipvt) { 25561 ao2_unlock(peer); 25562 return 0; 25563 } 25564 25565 /* Do we have an IP address? If not, skip this peer */ 25566 if (ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) { 25567 ao2_unlock(peer); 25568 return 0; 25569 } 25570 25571 /* Attempt to use cached mwi to get message counts. */ 25572 if (!get_cached_mwi(peer, &newmsgs, &oldmsgs) && !cache_only) { 25573 /* Fall back to manually checking the mailbox if not cache_only and get_cached_mwi failed */ 25574 struct ast_str *mailbox_str = ast_str_alloca(512); 25575 peer_mailboxes_to_str(&mailbox_str, peer); 25576 ao2_unlock(peer); 25577 ast_app_inboxcount(mailbox_str->str, &newmsgs, &oldmsgs); 25578 ao2_lock(peer); 25579 } 25580 25581 if (peer->mwipvt) { 25582 /* Base message on subscription */ 25583 p = dialog_ref(peer->mwipvt, "sip_send_mwi_to_peer: Setting dialog ptr p from peer->mwipvt"); 25584 ao2_unlock(peer); 25585 } else { 25586 ao2_unlock(peer); 25587 /* Build temporary dialog for this message */ 25588 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) { 25589 return -1; 25590 } 25591 25592 /* If we don't set the socket type to 0, then create_addr_from_peer will fail immediately if the peer 25593 * uses any transport other than UDP. We set the type to 0 here and then let create_addr_from_peer copy 25594 * the peer's socket information to the sip_pvt we just allocated 25595 */ 25596 set_socket_transport(&p->socket, 0); 25597 if (create_addr_from_peer(p, peer)) { 25598 /* Maybe they're not registered, etc. */ 25599 dialog_unlink_all(p); 25600 dialog_unref(p, "unref dialog p just created via sip_alloc"); 25601 /* sip_destroy(p); */ 25602 return 0; 25603 } 25604 /* Recalculate our side, and recalculate Call ID */ 25605 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 25606 build_via(p); 25607 25608 ao2_lock(peer); 25609 if (!ast_strlen_zero(peer->mwi_from)) { 25610 ast_string_field_set(p, mwi_from, peer->mwi_from); 25611 } else if (!ast_strlen_zero(default_mwi_from)) { 25612 ast_string_field_set(p, mwi_from, default_mwi_from); 25613 } 25614 ao2_unlock(peer); 25615 25616 /* Change the dialog callid. */ 25617 change_callid_pvt(p, NULL); 25618 25619 /* Destroy this session after 32 secs */ 25620 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 25621 } 25622 25623 /* We have multiple threads (mwi events and monitor retransmits) working with this PVT and as we modify the sip history if that's turned on, 25624 we really need to have a lock on it */ 25625 sip_pvt_lock(p); 25626 25627 /* Send MWI */ 25628 ast_set_flag(&p->flags[0], SIP_OUTGOING); 25629 /* the following will decrement the refcount on p as it finishes */ 25630 transmit_notify_with_mwi(p, newmsgs, oldmsgs, vmexten); 25631 sip_pvt_unlock(p); 25632 dialog_unref(p, "unref dialog ptr p just before it goes out of scope at the end of sip_send_mwi_to_peer."); 25633 25634 return 0; 25635 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 6633 of file chan_sip.c.
References ast_rtp_instance_dtmf_begin(), ast_test_flag, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.
06634 { 06635 struct sip_pvt *p = ast->tech_pvt; 06636 int res = 0; 06637 06638 sip_pvt_lock(p); 06639 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 06640 case SIP_DTMF_INBAND: 06641 res = -1; /* Tell Asterisk to generate inband indications */ 06642 break; 06643 case SIP_DTMF_RFC2833: 06644 if (p->rtp) 06645 ast_rtp_instance_dtmf_begin(p->rtp, digit); 06646 break; 06647 default: 06648 break; 06649 } 06650 sip_pvt_unlock(p); 06651 06652 return res; 06653 }
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 6657 of file chan_sip.c.
References ast_rtp_instance_dtmf_end_with_duration(), ast_test_flag, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and transmit_info_with_digit().
06658 { 06659 struct sip_pvt *p = ast->tech_pvt; 06660 int res = 0; 06661 06662 sip_pvt_lock(p); 06663 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 06664 case SIP_DTMF_INFO: 06665 case SIP_DTMF_SHORTINFO: 06666 transmit_info_with_digit(p, digit, duration); 06667 break; 06668 case SIP_DTMF_RFC2833: 06669 if (p->rtp) 06670 ast_rtp_instance_dtmf_end_with_duration(p->rtp, digit, duration); 06671 break; 06672 case SIP_DTMF_INBAND: 06673 res = -1; /* Tell Asterisk to stop inband indications */ 06674 break; 06675 } 06676 sip_pvt_unlock(p); 06677 06678 return res; 06679 }
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 4423 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.
04424 { 04425 struct sip_pvt *p = chan->tech_pvt; 04426 04427 if (subclass != AST_HTML_URL) 04428 return -1; 04429 04430 ast_string_field_build(p, url, "<%s>;mode=active", data); 04431 04432 if (sip_debug_test_pvt(p)) 04433 ast_debug(1, "Send URL %s, state = %d!\n", data, chan->_state); 04434 04435 switch (chan->_state) { 04436 case AST_STATE_RING: 04437 transmit_response(p, "100 Trying", &p->initreq); 04438 break; 04439 case AST_STATE_RINGING: 04440 transmit_response(p, "180 Ringing", &p->initreq); 04441 break; 04442 case AST_STATE_UP: 04443 if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 04444 transmit_reinvite_with_sdp(p, FALSE, FALSE); 04445 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04446 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04447 } 04448 break; 04449 default: 04450 ast_log(LOG_WARNING, "Don't know how to send URI when state is %d!\n", chan->_state); 04451 } 04452 04453 return 0; 04454 }
static int sip_sendtext | ( | struct ast_channel * | ast, | |
const char * | text | |||
) | [static] |
Definition at line 4467 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().
04468 { 04469 struct sip_pvt *dialog = ast->tech_pvt; 04470 int debug; 04471 04472 if (!dialog) { 04473 return -1; 04474 } 04475 /* NOT ast_strlen_zero, because a zero-length message is specifically 04476 * allowed by RFC 3428 (See section 10, Examples) */ 04477 if (!text) { 04478 return 0; 04479 } 04480 if(!is_method_allowed(&dialog->allowed_methods, SIP_MESSAGE)) { 04481 ast_debug(2, "Trying to send MESSAGE to device that does not support it.\n"); 04482 return(0); 04483 } 04484 04485 debug = sip_debug_test_pvt(dialog); 04486 if (debug) { 04487 ast_verbose("Sending text %s on %s\n", text, ast->name); 04488 } 04489 04490 transmit_message_with_text(dialog, text); 04491 return 0; 04492 }
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 19035 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.
19036 { 19037 switch (cmd) { 19038 case CLI_INIT: 19039 e->command = "sip set history {on|off}"; 19040 e->usage = 19041 "Usage: sip set history {on|off}\n" 19042 " Enables/Disables recording of SIP dialog history for debugging purposes.\n" 19043 " Use 'sip show history' to view the history of a call number.\n"; 19044 return NULL; 19045 case CLI_GENERATE: 19046 return NULL; 19047 } 19048 19049 if (a->argc != e->args) 19050 return CLI_SHOWUSAGE; 19051 19052 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 19053 recordhistory = TRUE; 19054 ast_cli(a->fd, "SIP History Recording Enabled (use 'sip show history')\n"); 19055 } else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) { 19056 recordhistory = FALSE; 19057 ast_cli(a->fd, "SIP History Recording Disabled\n"); 19058 } else { 19059 return CLI_SHOWUSAGE; 19060 } 19061 return CLI_SUCCESS; 19062 }
static void sip_set_redirstr | ( | struct sip_pvt * | p, | |
char * | reason | |||
) | [static] |
Translate referring cause.
Definition at line 14984 of file chan_sip.c.
References ast_string_field_set.
Referenced by get_rdnis().
14984 { 14985 14986 if (!strcmp(reason, "unknown")) { 14987 ast_string_field_set(p, redircause, "UNKNOWN"); 14988 } else if (!strcmp(reason, "user-busy")) { 14989 ast_string_field_set(p, redircause, "BUSY"); 14990 } else if (!strcmp(reason, "no-answer")) { 14991 ast_string_field_set(p, redircause, "NOANSWER"); 14992 } else if (!strcmp(reason, "unavailable")) { 14993 ast_string_field_set(p, redircause, "UNREACHABLE"); 14994 } else if (!strcmp(reason, "unconditional")) { 14995 ast_string_field_set(p, redircause, "UNCONDITIONAL"); 14996 } else if (!strcmp(reason, "time-of-day")) { 14997 ast_string_field_set(p, redircause, "UNKNOWN"); 14998 } else if (!strcmp(reason, "do-not-disturb")) { 14999 ast_string_field_set(p, redircause, "UNKNOWN"); 15000 } else if (!strcmp(reason, "deflection")) { 15001 ast_string_field_set(p, redircause, "UNKNOWN"); 15002 } else if (!strcmp(reason, "follow-me")) { 15003 ast_string_field_set(p, redircause, "UNKNOWN"); 15004 } else if (!strcmp(reason, "out-of-service")) { 15005 ast_string_field_set(p, redircause, "UNREACHABLE"); 15006 } else if (!strcmp(reason, "away")) { 15007 ast_string_field_set(p, redircause, "UNREACHABLE"); 15008 } else { 15009 ast_string_field_set(p, redircause, "UNKNOWN"); 15010 } 15011 }
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 29115 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), ast_channel_lock, 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, ast_channel::name, sip_cfg, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and transmit_reinvite_with_sdp().
Referenced by sip_fixup().
29116 { 29117 struct sip_pvt *p; 29118 int changed = 0; 29119 29120 /* Lock the channel and the private safely. */ 29121 ast_channel_lock(chan); 29122 p = chan->tech_pvt; 29123 if (!p) { 29124 ast_channel_unlock(chan); 29125 return -1; 29126 } 29127 sip_pvt_lock(p); 29128 if (p->owner != chan) { 29129 /* I suppose it could be argued that if this happens it is a bug. */ 29130 ast_debug(1, "The private is not owned by channel %s anymore.\n", chan->name); 29131 sip_pvt_unlock(p); 29132 ast_channel_unlock(chan); 29133 return 0; 29134 } 29135 29136 /* Disable early RTP bridge */ 29137 if ((instance || vinstance || tinstance) && 29138 !ast_bridged_channel(chan) && 29139 !sip_cfg.directrtpsetup) { 29140 sip_pvt_unlock(p); 29141 ast_channel_unlock(chan); 29142 return 0; 29143 } 29144 29145 if (p->alreadygone) { 29146 /* If we're destroyed, don't bother */ 29147 sip_pvt_unlock(p); 29148 ast_channel_unlock(chan); 29149 return 0; 29150 } 29151 29152 /* if this peer cannot handle reinvites of the media stream to devices 29153 that are known to be behind a NAT, then stop the process now 29154 */ 29155 if (nat_active && !ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) { 29156 sip_pvt_unlock(p); 29157 ast_channel_unlock(chan); 29158 return 0; 29159 } 29160 29161 if (instance) { 29162 changed |= ast_rtp_instance_get_and_cmp_remote_address(instance, &p->redirip); 29163 } else if (!ast_sockaddr_isnull(&p->redirip)) { 29164 memset(&p->redirip, 0, sizeof(p->redirip)); 29165 changed = 1; 29166 } 29167 if (vinstance) { 29168 changed |= ast_rtp_instance_get_and_cmp_remote_address(vinstance, &p->vredirip); 29169 } else if (!ast_sockaddr_isnull(&p->vredirip)) { 29170 memset(&p->vredirip, 0, sizeof(p->vredirip)); 29171 changed = 1; 29172 } 29173 if (tinstance) { 29174 changed |= ast_rtp_instance_get_and_cmp_remote_address(tinstance, &p->tredirip); 29175 } else if (!ast_sockaddr_isnull(&p->tredirip)) { 29176 memset(&p->tredirip, 0, sizeof(p->tredirip)); 29177 changed = 1; 29178 } 29179 if (codecs && (p->redircodecs != codecs)) { 29180 p->redircodecs = codecs; 29181 changed = 1; 29182 } 29183 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 29184 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 29185 if (p->do_history) 29186 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 29187 ast_debug(1, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip)); 29188 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 29189 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)); 29190 transmit_reinvite_with_sdp(p, FALSE, FALSE); 29191 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 29192 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)); 29193 /* We have a pending Invite. Send re-invite when we're done with the invite */ 29194 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 29195 } 29196 } 29197 /* Reset lastrtprx timer */ 29198 p->lastrtprx = p->lastrtptx = time(NULL); 29199 sip_pvt_unlock(p); 29200 ast_channel_unlock(chan); 29201 return 0; 29202 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 28974 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, ast_set_flag, ast_sockaddr_stringify(), ast_test_flag, ast_udptl_get_peer(), FALSE, ast_channel::name, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), and TRUE.
28975 { 28976 struct sip_pvt *p; 28977 28978 /* Lock the channel and the private safely. */ 28979 ast_channel_lock(chan); 28980 p = chan->tech_pvt; 28981 if (!p) { 28982 ast_channel_unlock(chan); 28983 return -1; 28984 } 28985 sip_pvt_lock(p); 28986 if (p->owner != chan) { 28987 /* I suppose it could be argued that if this happens it is a bug. */ 28988 ast_debug(1, "The private is not owned by channel %s anymore.\n", chan->name); 28989 sip_pvt_unlock(p); 28990 ast_channel_unlock(chan); 28991 return 0; 28992 } 28993 28994 if (udptl) { 28995 ast_udptl_get_peer(udptl, &p->udptlredirip); 28996 } else { 28997 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 28998 } 28999 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 29000 if (!p->pendinginvite) { 29001 ast_debug(3, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s\n", 29002 p->callid, ast_sockaddr_stringify(udptl ? &p->udptlredirip : &p->ourip)); 29003 transmit_reinvite_with_sdp(p, TRUE, FALSE); 29004 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 29005 ast_debug(3, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s\n", 29006 p->callid, ast_sockaddr_stringify(udptl ? &p->udptlredirip : &p->ourip)); 29007 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 29008 } 29009 } 29010 /* Reset lastrtprx timer */ 29011 p->lastrtprx = p->lastrtptx = time(NULL); 29012 sip_pvt_unlock(p); 29013 ast_channel_unlock(chan); 29014 return 0; 29015 }
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 4279 of file chan_sip.c.
References ast_debug, ast_log(), AST_OPTION_DIGIT_DETECT, AST_OPTION_FORMAT_READ, AST_OPTION_FORMAT_WRITE, AST_OPTION_MAKE_COMPATIBLE, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, ast_rtp_instance_make_compatible(), ast_rtp_instance_set_read_format(), ast_rtp_instance_set_write_format(), ast_set2_flag, ast_test_flag, disable_dsp_detect(), enable_dsp_detect(), LOG_ERROR, ast_channel::name, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.
04280 { 04281 int res = -1; 04282 struct sip_pvt *p = chan->tech_pvt; 04283 04284 if (!p) { 04285 ast_log(LOG_ERROR, "Attempt to Ref a null pointer. sip private structure is gone!\n"); 04286 return -1; 04287 } 04288 04289 sip_pvt_lock(p); 04290 04291 switch (option) { 04292 case AST_OPTION_FORMAT_READ: 04293 if (p->rtp) { 04294 res = ast_rtp_instance_set_read_format(p->rtp, *(int *) data); 04295 } 04296 break; 04297 case AST_OPTION_FORMAT_WRITE: 04298 if (p->rtp) { 04299 res = ast_rtp_instance_set_write_format(p->rtp, *(int *) data); 04300 } 04301 break; 04302 case AST_OPTION_MAKE_COMPATIBLE: 04303 if (p->rtp) { 04304 res = ast_rtp_instance_make_compatible(chan, p->rtp, (struct ast_channel *) data); 04305 } 04306 break; 04307 case AST_OPTION_DIGIT_DETECT: 04308 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || 04309 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 04310 char *cp = (char *) data; 04311 04312 ast_debug(1, "%sabling digit detection on %s\n", *cp ? "En" : "Dis", chan->name); 04313 if (*cp) { 04314 enable_dsp_detect(p); 04315 } else { 04316 disable_dsp_detect(p); 04317 } 04318 res = 0; 04319 } 04320 break; 04321 case AST_OPTION_SECURE_SIGNALING: 04322 p->req_secure_signaling = *(unsigned int *) data; 04323 res = 0; 04324 break; 04325 case AST_OPTION_SECURE_MEDIA: 04326 ast_set2_flag(&p->flags[1], *(unsigned int *) data, SIP_PAGE2_USE_SRTP); 04327 res = 0; 04328 break; 04329 default: 04330 break; 04331 } 04332 04333 sip_pvt_unlock(p); 04334 04335 return res; 04336 }
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 18502 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.
18503 { 18504 struct sip_pvt *cur; 18505 size_t len; 18506 int found = 0; 18507 struct ao2_iterator i; 18508 18509 switch (cmd) { 18510 case CLI_INIT: 18511 e->command = "sip show channel"; 18512 e->usage = 18513 "Usage: sip show channel <call-id>\n" 18514 " Provides detailed status on a given SIP dialog (identified by SIP call-id).\n"; 18515 return NULL; 18516 case CLI_GENERATE: 18517 return complete_sipch(a->line, a->word, a->pos, a->n); 18518 } 18519 18520 if (a->argc != 4) 18521 return CLI_SHOWUSAGE; 18522 len = strlen(a->argv[3]); 18523 18524 i = ao2_iterator_init(dialogs, 0); 18525 while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 18526 sip_pvt_lock(cur); 18527 18528 if (!strncasecmp(cur->callid, a->argv[3], len)) { 18529 char formatbuf[SIPBUFSIZE/2]; 18530 ast_cli(a->fd, "\n"); 18531 if (cur->subscribed != NONE) 18532 ast_cli(a->fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 18533 else 18534 ast_cli(a->fd, " * SIP Call\n"); 18535 ast_cli(a->fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 18536 ast_cli(a->fd, " Call-ID: %s\n", cur->callid); 18537 ast_cli(a->fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 18538 ast_cli(a->fd, " Our Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->capability)); 18539 ast_cli(a->fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 18540 ast_cli(a->fd, " Their Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->peercapability)); 18541 ast_cli(a->fd, " Joint Codec Capability: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->jointcapability)); 18542 ast_cli(a->fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 18543 ast_cli(a->fd, " T.38 support %s\n", AST_CLI_YESNO(cur->udptl != NULL)); 18544 ast_cli(a->fd, " Video support %s\n", AST_CLI_YESNO(cur->vrtp != NULL)); 18545 ast_cli(a->fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 18546 ast_cli(a->fd, " Theoretical Address: %s\n", ast_sockaddr_stringify(&cur->sa)); 18547 ast_cli(a->fd, " Received Address: %s\n", ast_sockaddr_stringify(&cur->recv)); 18548 ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 18549 ast_cli(a->fd, " Force rport: %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_NAT_FORCE_RPORT))); 18550 if (ast_sockaddr_isnull(&cur->redirip)) { 18551 ast_cli(a->fd, 18552 " Audio IP: %s (local)\n", 18553 ast_sockaddr_stringify_addr(&cur->ourip)); 18554 } else { 18555 ast_cli(a->fd, 18556 " Audio IP: %s (Outside bridge)\n", 18557 ast_sockaddr_stringify_addr(&cur->redirip)); 18558 } 18559 ast_cli(a->fd, " Our Tag: %s\n", cur->tag); 18560 ast_cli(a->fd, " Their Tag: %s\n", cur->theirtag); 18561 ast_cli(a->fd, " SIP User agent: %s\n", cur->useragent); 18562 if (!ast_strlen_zero(cur->username)) 18563 ast_cli(a->fd, " Username: %s\n", cur->username); 18564 if (!ast_strlen_zero(cur->peername)) 18565 ast_cli(a->fd, " Peername: %s\n", cur->peername); 18566 if (!ast_strlen_zero(cur->uri)) 18567 ast_cli(a->fd, " Original uri: %s\n", cur->uri); 18568 if (!ast_strlen_zero(cur->cid_num)) 18569 ast_cli(a->fd, " Caller-ID: %s\n", cur->cid_num); 18570 ast_cli(a->fd, " Need Destroy: %s\n", AST_CLI_YESNO(cur->needdestroy)); 18571 ast_cli(a->fd, " Last Message: %s\n", cur->lastmsg); 18572 ast_cli(a->fd, " Promiscuous Redir: %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR))); 18573 ast_cli(a->fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 18574 ast_cli(a->fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 18575 ast_cli(a->fd, " SIP Options: "); 18576 if (cur->sipoptions) { 18577 int x; 18578 for (x = 0 ; x < ARRAY_LEN(sip_options); x++) { 18579 if (cur->sipoptions & sip_options[x].id) 18580 ast_cli(a->fd, "%s ", sip_options[x].text); 18581 } 18582 ast_cli(a->fd, "\n"); 18583 } else 18584 ast_cli(a->fd, "(none)\n"); 18585 18586 if (!cur->stimer) 18587 ast_cli(a->fd, " Session-Timer: Uninitiallized\n"); 18588 else { 18589 ast_cli(a->fd, " Session-Timer: %s\n", cur->stimer->st_active ? "Active" : "Inactive"); 18590 if (cur->stimer->st_active == TRUE) { 18591 ast_cli(a->fd, " S-Timer Interval: %d\n", cur->stimer->st_interval); 18592 ast_cli(a->fd, " S-Timer Refresher: %s\n", strefresher2str(cur->stimer->st_ref)); 18593 ast_cli(a->fd, " S-Timer Expirys: %d\n", cur->stimer->st_expirys); 18594 ast_cli(a->fd, " S-Timer Sched Id: %d\n", cur->stimer->st_schedid); 18595 ast_cli(a->fd, " S-Timer Peer Sts: %s\n", cur->stimer->st_active_peer_ua ? "Active" : "Inactive"); 18596 ast_cli(a->fd, " S-Timer Cached Min-SE: %d\n", cur->stimer->st_cached_min_se); 18597 ast_cli(a->fd, " S-Timer Cached SE: %d\n", cur->stimer->st_cached_max_se); 18598 ast_cli(a->fd, " S-Timer Cached Ref: %s\n", strefresher2str(cur->stimer->st_cached_ref)); 18599 ast_cli(a->fd, " S-Timer Cached Mode: %s\n", stmode2str(cur->stimer->st_cached_mode)); 18600 } 18601 } 18602 18603 ast_cli(a->fd, "\n\n"); 18604 18605 found++; 18606 } 18607 18608 sip_pvt_unlock(cur); 18609 18610 ao2_t_ref(cur, -1, "toss dialog ptr set by iterator_next"); 18611 } 18612 ao2_iterator_destroy(&i); 18613 18614 if (!found) 18615 ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]); 18616 18617 return CLI_SUCCESS; 18618 }
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 18323 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.
18324 { 18325 struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 }; 18326 18327 18328 if (cmd == CLI_INIT) { 18329 e->command = "sip show {channels|subscriptions}"; 18330 e->usage = 18331 "Usage: sip show channels\n" 18332 " Lists all currently active SIP calls (dialogs).\n" 18333 "Usage: sip show subscriptions\n" 18334 " Lists active SIP subscriptions.\n"; 18335 return NULL; 18336 } else if (cmd == CLI_GENERATE) 18337 return NULL; 18338 18339 if (a->argc != e->args) 18340 return CLI_SHOWUSAGE; 18341 arg.subscriptions = !strcasecmp(a->argv[e->args - 1], "subscriptions"); 18342 if (!arg.subscriptions) 18343 ast_cli(arg.fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Format", "Hold", "Last Message", "Expiry", "Peer"); 18344 else 18345 ast_cli(arg.fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry"); 18346 18347 /* iterate on the container and invoke the callback on each item */ 18348 ao2_t_callback(dialogs, OBJ_NODATA, show_channels_cb, &arg, "callback to show channels"); 18349 18350 /* print summary information */ 18351 ast_cli(arg.fd, "%d active SIP %s%s\n", arg.numchans, 18352 (arg.subscriptions ? "subscription" : "dialog"), 18353 ESS(arg.numchans)); /* ESS(n) returns an "s" if n>1 */ 18354 return CLI_SUCCESS; 18355 #undef FORMAT 18356 #undef FORMAT2 18357 #undef FORMAT3 18358 }
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 17949 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.
17950 { 17951 struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 }; 17952 17953 switch (cmd) { 17954 case CLI_INIT: 17955 e->command = "sip show channelstats"; 17956 e->usage = 17957 "Usage: sip show channelstats\n" 17958 " Lists all currently active SIP channel's RTCP statistics.\n" 17959 " Note that calls in the much optimized RTP P2P bridge mode will not show any packets here."; 17960 return NULL; 17961 case CLI_GENERATE: 17962 return NULL; 17963 } 17964 17965 if (a->argc != 3) 17966 return CLI_SHOWUSAGE; 17967 17968 ast_cli(a->fd, FORMAT2, "Peer", "Call ID", "Duration", "Recv: Pack", "Lost", "Jitter", "Send: Pack", "Lost", "Jitter"); 17969 /* iterate on the container and invoke the callback on each item */ 17970 ao2_t_callback(dialogs, OBJ_NODATA, show_chanstats_cb, &arg, "callback to sip show chanstats"); 17971 ast_cli(a->fd, "%d active SIP channel%s\n", arg.numchans, (arg.numchans != 1) ? "s" : ""); 17972 return CLI_SUCCESS; 17973 }
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 17209 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.
17210 { 17211 struct domain *d; 17212 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 17213 17214 switch (cmd) { 17215 case CLI_INIT: 17216 e->command = "sip show domains"; 17217 e->usage = 17218 "Usage: sip show domains\n" 17219 " Lists all configured SIP local domains.\n" 17220 " Asterisk only responds to SIP messages to local domains.\n"; 17221 return NULL; 17222 case CLI_GENERATE: 17223 return NULL; 17224 } 17225 17226 if (AST_LIST_EMPTY(&domain_list)) { 17227 ast_cli(a->fd, "SIP Domain support not enabled.\n\n"); 17228 return CLI_SUCCESS; 17229 } else { 17230 ast_cli(a->fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 17231 AST_LIST_LOCK(&domain_list); 17232 AST_LIST_TRAVERSE(&domain_list, d, list) 17233 ast_cli(a->fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 17234 domain_mode_to_text(d->mode)); 17235 AST_LIST_UNLOCK(&domain_list); 17236 ast_cli(a->fd, "\n"); 17237 return CLI_SUCCESS; 17238 } 17239 }
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 18621 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.
18622 { 18623 struct sip_pvt *cur; 18624 size_t len; 18625 int found = 0; 18626 struct ao2_iterator i; 18627 18628 switch (cmd) { 18629 case CLI_INIT: 18630 e->command = "sip show history"; 18631 e->usage = 18632 "Usage: sip show history <call-id>\n" 18633 " Provides detailed dialog history on a given SIP call (specified by call-id).\n"; 18634 return NULL; 18635 case CLI_GENERATE: 18636 return complete_sip_show_history(a->line, a->word, a->pos, a->n); 18637 } 18638 18639 if (a->argc != 4) 18640 return CLI_SHOWUSAGE; 18641 18642 if (!recordhistory) 18643 ast_cli(a->fd, "\n***Note: History recording is currently DISABLED. Use 'sip set history on' to ENABLE.\n"); 18644 18645 len = strlen(a->argv[3]); 18646 18647 i = ao2_iterator_init(dialogs, 0); 18648 while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 18649 sip_pvt_lock(cur); 18650 if (!strncasecmp(cur->callid, a->argv[3], len)) { 18651 struct sip_history *hist; 18652 int x = 0; 18653 18654 ast_cli(a->fd, "\n"); 18655 if (cur->subscribed != NONE) 18656 ast_cli(a->fd, " * Subscription\n"); 18657 else 18658 ast_cli(a->fd, " * SIP Call\n"); 18659 if (cur->history) 18660 AST_LIST_TRAVERSE(cur->history, hist, list) 18661 ast_cli(a->fd, "%d. %s\n", ++x, hist->event); 18662 if (x == 0) 18663 ast_cli(a->fd, "Call '%s' has no history\n", cur->callid); 18664 found++; 18665 } 18666 sip_pvt_unlock(cur); 18667 ao2_t_ref(cur, -1, "toss dialog ptr from iterator_next"); 18668 } 18669 ao2_iterator_destroy(&i); 18670 18671 if (!found) 18672 ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]); 18673 18674 return CLI_SUCCESS; 18675 }
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 16305 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.
16306 { 16307 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 16308 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 16309 char ilimits[40]; 16310 char iused[40]; 16311 int showall = FALSE; 16312 struct ao2_iterator i; 16313 struct sip_peer *peer; 16314 16315 switch (cmd) { 16316 case CLI_INIT: 16317 e->command = "sip show inuse"; 16318 e->usage = 16319 "Usage: sip show inuse [all]\n" 16320 " List all SIP devices usage counters and limits.\n" 16321 " Add option \"all\" to show all devices, not only those with a limit.\n"; 16322 return NULL; 16323 case CLI_GENERATE: 16324 return NULL; 16325 } 16326 16327 if (a->argc < 3) 16328 return CLI_SHOWUSAGE; 16329 16330 if (a->argc == 4 && !strcmp(a->argv[3], "all")) 16331 showall = TRUE; 16332 16333 ast_cli(a->fd, FORMAT, "* Peer name", "In use", "Limit"); 16334 16335 i = ao2_iterator_init(peers, 0); 16336 while ((peer = ao2_t_iterator_next(&i, "iterate thru peer table"))) { 16337 ao2_lock(peer); 16338 if (peer->call_limit) 16339 snprintf(ilimits, sizeof(ilimits), "%d", peer->call_limit); 16340 else 16341 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 16342 snprintf(iused, sizeof(iused), "%d/%d/%d", peer->inUse, peer->inRinging, peer->onHold); 16343 if (showall || peer->call_limit) 16344 ast_cli(a->fd, FORMAT2, peer->name, iused, ilimits); 16345 ao2_unlock(peer); 16346 unref_peer(peer, "toss iterator pointer"); 16347 } 16348 ao2_iterator_destroy(&i); 16349 16350 return CLI_SUCCESS; 16351 #undef FORMAT 16352 #undef FORMAT2 16353 }
static char * sip_show_mwi | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 18206 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.
18207 { 18208 #define FORMAT "%-30.30s %-12.12s %-10.10s %-10.10s\n" 18209 char host[80]; 18210 18211 switch (cmd) { 18212 case CLI_INIT: 18213 e->command = "sip show mwi"; 18214 e->usage = 18215 "Usage: sip show mwi\n" 18216 " Provides a list of MWI subscriptions and status.\n"; 18217 return NULL; 18218 case CLI_GENERATE: 18219 return NULL; 18220 } 18221 18222 ast_cli(a->fd, FORMAT, "Host", "Username", "Mailbox", "Subscribed"); 18223 18224 ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { 18225 ASTOBJ_RDLOCK(iterator); 18226 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 18227 ast_cli(a->fd, FORMAT, host, iterator->username, iterator->mailbox, AST_CLI_YESNO(iterator->subscribed)); 18228 ASTOBJ_UNLOCK(iterator); 18229 } while(0)); 18230 18231 return CLI_SUCCESS; 18232 #undef FORMAT 18233 }
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 16842 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(), peers_by_ip, regl, regobjs, rpeerobjs, speerobjs, and ast_cli_entry::usage.
16843 { 16844 char tmp[256]; 16845 16846 switch (cmd) { 16847 case CLI_INIT: 16848 e->command = "sip show objects"; 16849 e->usage = 16850 "Usage: sip show objects\n" 16851 " Lists status of known SIP objects\n"; 16852 return NULL; 16853 case CLI_GENERATE: 16854 return NULL; 16855 } 16856 16857 if (a->argc != 3) 16858 return CLI_SHOWUSAGE; 16859 ast_cli(a->fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 16860 ao2_t_callback(peers, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers"); 16861 ast_cli(a->fd, "-= Peer objects by IP =-\n\n"); 16862 ao2_t_callback(peers_by_ip, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers_by_ip"); 16863 ast_cli(a->fd, "-= Registry objects: %d =-\n\n", regobjs); 16864 ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), ®l); 16865 ast_cli(a->fd, "-= Dialog objects:\n\n"); 16866 ao2_t_callback(dialogs, OBJ_NODATA, dialog_dump_func, a, "initiate ao2_callback to dump dialogs"); 16867 return CLI_SUCCESS; 16868 }
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 17264 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.
17265 { 17266 switch (cmd) { 17267 case CLI_INIT: 17268 e->command = "sip show peer"; 17269 e->usage = 17270 "Usage: sip show peer <name> [load]\n" 17271 " Shows all details on one SIP peer and the current status.\n" 17272 " Option \"load\" forces lookup of peer in realtime storage.\n"; 17273 return NULL; 17274 case CLI_GENERATE: 17275 return complete_sip_show_peer(a->line, a->word, a->pos, a->n); 17276 } 17277 return _sip_show_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv); 17278 }
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 16617 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.
16618 { 16619 switch (cmd) { 16620 case CLI_INIT: 16621 e->command = "sip show peers"; 16622 e->usage = 16623 "Usage: sip show peers [like <pattern>]\n" 16624 " Lists all known SIP peers.\n" 16625 " Optional regular expression pattern is used to filter the peer list.\n"; 16626 return NULL; 16627 case CLI_GENERATE: 16628 return NULL; 16629 } 16630 16631 return _sip_show_peers(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv); 16632 }
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 17798 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.
17799 { 17800 #define FORMAT2 "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n" 17801 #define FORMAT "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n" 17802 char host[80]; 17803 char user[80]; 17804 char tmpdat[256]; 17805 struct ast_tm tm; 17806 int counter = 0; 17807 17808 switch (cmd) { 17809 case CLI_INIT: 17810 e->command = "sip show registry"; 17811 e->usage = 17812 "Usage: sip show registry\n" 17813 " Lists all registration requests and status.\n"; 17814 return NULL; 17815 case CLI_GENERATE: 17816 return NULL; 17817 } 17818 17819 if (a->argc != 3) 17820 return CLI_SHOWUSAGE; 17821 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Refresh", "State", "Reg.Time"); 17822 17823 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17824 ASTOBJ_RDLOCK(iterator); 17825 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 17826 snprintf(user, sizeof(user), "%s", iterator->username); 17827 if (!ast_strlen_zero(iterator->regdomain)) { 17828 snprintf(tmpdat, sizeof(tmpdat), "%s", user); 17829 snprintf(user, sizeof(user), "%s@%s", tmpdat, iterator->regdomain);} 17830 if (iterator->regdomainport) { 17831 snprintf(tmpdat, sizeof(tmpdat), "%s", user); 17832 snprintf(user, sizeof(user), "%s:%d", tmpdat, iterator->regdomainport);} 17833 if (iterator->regtime.tv_sec) { 17834 ast_localtime(&iterator->regtime, &tm, NULL); 17835 ast_strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 17836 } else 17837 tmpdat[0] = '\0'; 17838 ast_cli(a->fd, FORMAT, host, (iterator->dnsmgr) ? "Y" : "N", user, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 17839 ASTOBJ_UNLOCK(iterator); 17840 counter++; 17841 } while(0)); 17842 ast_cli(a->fd, "%d SIP registrations.\n", counter); 17843 return CLI_SUCCESS; 17844 #undef FORMAT 17845 #undef FORMAT2 17846 }
static char * sip_show_sched | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 17755 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.
17756 { 17757 struct ast_str *cbuf; 17758 struct ast_cb_names cbnames = {9, { "retrans_pkt", 17759 "__sip_autodestruct", 17760 "expire_register", 17761 "auto_congest", 17762 "sip_reg_timeout", 17763 "sip_poke_peer_s", 17764 "sip_poke_noanswer", 17765 "sip_reregister", 17766 "sip_reinvite_retry"}, 17767 { retrans_pkt, 17768 __sip_autodestruct, 17769 expire_register, 17770 auto_congest, 17771 sip_reg_timeout, 17772 sip_poke_peer_s, 17773 sip_poke_noanswer, 17774 sip_reregister, 17775 sip_reinvite_retry}}; 17776 17777 switch (cmd) { 17778 case CLI_INIT: 17779 e->command = "sip show sched"; 17780 e->usage = 17781 "Usage: sip show sched\n" 17782 " Shows stats on what's in the sched queue at the moment\n"; 17783 return NULL; 17784 case CLI_GENERATE: 17785 return NULL; 17786 } 17787 17788 cbuf = ast_str_alloca(2048); 17789 17790 ast_cli(a->fd, "\n"); 17791 ast_sched_report(sched, &cbuf, &cbnames); 17792 ast_cli(a->fd, "%s", cbuf->str); 17793 17794 return CLI_SUCCESS; 17795 }
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 17978 of file chan_sip.c.
References ast_ha::addr, allowoverlap2str(), ao2_t_ref, ast_cli_args::argc, ast_check_realtime(), ast_cli(), AST_CLI_ONOFF, AST_CLI_YESNO, ast_getformatname_multiple(), AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, AST_LIST_EMPTY, AST_LIST_TRAVERSE, ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_tos2str(), authl, authl_lock, 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_store_sip_cause, global_t1, global_t1min, global_t38_maxdatagram, global_timer_b, global_tos_audio, global_tos_sip, global_tos_text, global_tos_video, global_useragent, 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(), ast_jb_conf::target_extra, transfermode2str(), and ast_cli_entry::usage.
17979 { 17980 int realtimepeers; 17981 int realtimeregs; 17982 char codec_buf[SIPBUFSIZE]; 17983 const char *msg; /* temporary msg pointer */ 17984 struct sip_auth_container *credentials; 17985 17986 switch (cmd) { 17987 case CLI_INIT: 17988 e->command = "sip show settings"; 17989 e->usage = 17990 "Usage: sip show settings\n" 17991 " Provides detailed list of the configuration of the SIP channel.\n"; 17992 return NULL; 17993 case CLI_GENERATE: 17994 return NULL; 17995 } 17996 17997 if (a->argc != 3) 17998 return CLI_SHOWUSAGE; 17999 18000 realtimepeers = ast_check_realtime("sippeers"); 18001 realtimeregs = ast_check_realtime("sipregs"); 18002 18003 ast_mutex_lock(&authl_lock); 18004 credentials = authl; 18005 if (credentials) { 18006 ao2_t_ref(credentials, +1, "Ref global auth for show"); 18007 } 18008 ast_mutex_unlock(&authl_lock); 18009 18010 ast_cli(a->fd, "\n\nGlobal Settings:\n"); 18011 ast_cli(a->fd, "----------------\n"); 18012 ast_cli(a->fd, " UDP Bindaddress: %s\n", ast_sockaddr_stringify(&bindaddr)); 18013 if (ast_sockaddr_is_ipv6(&bindaddr) && ast_sockaddr_is_any(&bindaddr)) { 18014 ast_cli(a->fd, " ** Additional Info:\n"); 18015 ast_cli(a->fd, " [::] may include IPv4 in addition to IPv6, if such a feature is enabled in the OS.\n"); 18016 } 18017 ast_cli(a->fd, " TCP SIP Bindaddress: %s\n", 18018 sip_cfg.tcp_enabled != FALSE ? 18019 ast_sockaddr_stringify(&sip_tcp_desc.local_address) : 18020 "Disabled"); 18021 ast_cli(a->fd, " TLS SIP Bindaddress: %s\n", 18022 default_tls_cfg.enabled != FALSE ? 18023 ast_sockaddr_stringify(&sip_tls_desc.local_address) : 18024 "Disabled"); 18025 ast_cli(a->fd, " Videosupport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT))); 18026 ast_cli(a->fd, " Textsupport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT))); 18027 ast_cli(a->fd, " Ignore SDP sess. ver.: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION))); 18028 ast_cli(a->fd, " AutoCreate Peer: %s\n", AST_CLI_YESNO(sip_cfg.autocreatepeer)); 18029 ast_cli(a->fd, " Match Auth Username: %s\n", AST_CLI_YESNO(global_match_auth_username)); 18030 ast_cli(a->fd, " Allow unknown access: %s\n", AST_CLI_YESNO(sip_cfg.allowguest)); 18031 ast_cli(a->fd, " Allow subscriptions: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))); 18032 ast_cli(a->fd, " Allow overlap dialing: %s\n", allowoverlap2str(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP))); 18033 ast_cli(a->fd, " Allow promisc. redir: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_PROMISCREDIR))); 18034 ast_cli(a->fd, " Enable call counters: %s\n", AST_CLI_YESNO(global_callcounter)); 18035 ast_cli(a->fd, " SIP domain support: %s\n", AST_CLI_YESNO(!AST_LIST_EMPTY(&domain_list))); 18036 ast_cli(a->fd, " Realm. auth: %s\n", AST_CLI_YESNO(credentials != NULL)); 18037 if (credentials) { 18038 struct sip_auth *auth; 18039 18040 AST_LIST_TRAVERSE(&credentials->list, auth, node) { 18041 ast_cli(a->fd, " Realm. auth entry: Realm %-15.15s User %-10.20s %s\n", 18042 auth->realm, 18043 auth->username, 18044 !ast_strlen_zero(auth->secret) 18045 ? "<Secret set>" 18046 : (!ast_strlen_zero(auth->md5secret) 18047 ? "<MD5secret set>" : "<Not set>")); 18048 } 18049 ao2_t_ref(credentials, -1, "Unref global auth for show"); 18050 } 18051 ast_cli(a->fd, " Our auth realm %s\n", sip_cfg.realm); 18052 ast_cli(a->fd, " Use domains as realms: %s\n", AST_CLI_YESNO(sip_cfg.domainsasrealm)); 18053 ast_cli(a->fd, " Call to non-local dom.: %s\n", AST_CLI_YESNO(sip_cfg.allow_external_domains)); 18054 ast_cli(a->fd, " URI user is phone no: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USEREQPHONE))); 18055 ast_cli(a->fd, " Always auth rejects: %s\n", AST_CLI_YESNO(sip_cfg.alwaysauthreject)); 18056 ast_cli(a->fd, " Direct RTP setup: %s\n", AST_CLI_YESNO(sip_cfg.directrtpsetup)); 18057 ast_cli(a->fd, " User Agent: %s\n", global_useragent); 18058 ast_cli(a->fd, " SDP Session Name: %s\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession); 18059 ast_cli(a->fd, " SDP Owner Name: %s\n", ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner); 18060 ast_cli(a->fd, " Reg. context: %s\n", S_OR(sip_cfg.regcontext, "(not set)")); 18061 ast_cli(a->fd, " Regexten on Qualify: %s\n", AST_CLI_YESNO(sip_cfg.regextenonqualify)); 18062 ast_cli(a->fd, " Legacy userfield parse: %s\n", AST_CLI_YESNO(sip_cfg.legacy_useroption_parsing)); 18063 ast_cli(a->fd, " Caller ID: %s\n", default_callerid); 18064 if ((default_fromdomainport) && (default_fromdomainport != STANDARD_SIP_PORT)) { 18065 ast_cli(a->fd, " From: Domain: %s:%d\n", default_fromdomain, default_fromdomainport); 18066 } else { 18067 ast_cli(a->fd, " From: Domain: %s\n", default_fromdomain); 18068 } 18069 ast_cli(a->fd, " Record SIP history: %s\n", AST_CLI_ONOFF(recordhistory)); 18070 ast_cli(a->fd, " Call Events: %s\n", AST_CLI_ONOFF(sip_cfg.callevents)); 18071 ast_cli(a->fd, " Auth. Failure Events: %s\n", AST_CLI_ONOFF(global_authfailureevents)); 18072 18073 ast_cli(a->fd, " T.38 support: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT))); 18074 ast_cli(a->fd, " T.38 EC mode: %s\n", faxec2str(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT))); 18075 ast_cli(a->fd, " T.38 MaxDtgrm: %d\n", global_t38_maxdatagram); 18076 if (!realtimepeers && !realtimeregs) 18077 ast_cli(a->fd, " SIP realtime: Disabled\n" ); 18078 else 18079 ast_cli(a->fd, " SIP realtime: Enabled\n" ); 18080 ast_cli(a->fd, " Qualify Freq : %d ms\n", global_qualifyfreq); 18081 ast_cli(a->fd, " Q.850 Reason header: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_Q850_REASON))); 18082 ast_cli(a->fd, " Store SIP_CAUSE: %s\n", AST_CLI_YESNO(global_store_sip_cause)); 18083 ast_cli(a->fd, "\nNetwork QoS Settings:\n"); 18084 ast_cli(a->fd, "---------------------------\n"); 18085 ast_cli(a->fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 18086 ast_cli(a->fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 18087 ast_cli(a->fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 18088 ast_cli(a->fd, " IP ToS RTP text: %s\n", ast_tos2str(global_tos_text)); 18089 ast_cli(a->fd, " 802.1p CoS SIP: %d\n", global_cos_sip); 18090 ast_cli(a->fd, " 802.1p CoS RTP audio: %d\n", global_cos_audio); 18091 ast_cli(a->fd, " 802.1p CoS RTP video: %d\n", global_cos_video); 18092 ast_cli(a->fd, " 802.1p CoS RTP text: %d\n", global_cos_text); 18093 ast_cli(a->fd, " Jitterbuffer enabled: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_ENABLED))); 18094 if (ast_test_flag(&global_jbconf, AST_JB_ENABLED)) { 18095 ast_cli(a->fd, " Jitterbuffer forced: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_FORCED))); 18096 ast_cli(a->fd, " Jitterbuffer max size: %ld\n", global_jbconf.max_size); 18097 ast_cli(a->fd, " Jitterbuffer resync: %ld\n", global_jbconf.resync_threshold); 18098 ast_cli(a->fd, " Jitterbuffer impl: %s\n", global_jbconf.impl); 18099 if (!strcasecmp(global_jbconf.impl, "adaptive")) { 18100 ast_cli(a->fd, " Jitterbuffer tgt extra: %ld\n", global_jbconf.target_extra); 18101 } 18102 ast_cli(a->fd, " Jitterbuffer log: %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_LOG))); 18103 } 18104 18105 ast_cli(a->fd, "\nNetwork Settings:\n"); 18106 ast_cli(a->fd, "---------------------------\n"); 18107 /* determine if/how SIP address can be remapped */ 18108 if (localaddr == NULL) 18109 msg = "Disabled, no localnet list"; 18110 else if (ast_sockaddr_isnull(&externaddr)) 18111 msg = "Disabled"; 18112 else if (!ast_strlen_zero(externhost)) 18113 msg = "Enabled using externhost"; 18114 else 18115 msg = "Enabled using externaddr"; 18116 ast_cli(a->fd, " SIP address remapping: %s\n", msg); 18117 ast_cli(a->fd, " Externhost: %s\n", S_OR(externhost, "<none>")); 18118 ast_cli(a->fd, " Externaddr: %s\n", ast_sockaddr_stringify(&externaddr)); 18119 ast_cli(a->fd, " Externrefresh: %d\n", externrefresh); 18120 { 18121 struct ast_ha *d; 18122 const char *prefix = "Localnet:"; 18123 18124 for (d = localaddr; d ; prefix = "", d = d->next) { 18125 const char *addr = ast_strdupa(ast_sockaddr_stringify_addr(&d->addr)); 18126 const char *mask = ast_strdupa(ast_sockaddr_stringify_addr(&d->netmask)); 18127 ast_cli(a->fd, " %-24s%s/%s\n", prefix, addr, mask); 18128 } 18129 } 18130 ast_cli(a->fd, "\nGlobal Signalling Settings:\n"); 18131 ast_cli(a->fd, "---------------------------\n"); 18132 ast_cli(a->fd, " Codecs: "); 18133 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, sip_cfg.capability); 18134 ast_cli(a->fd, "%s\n", codec_buf); 18135 ast_cli(a->fd, " Codec Order: "); 18136 print_codec_to_cli(a->fd, &default_prefs); 18137 ast_cli(a->fd, "\n"); 18138 ast_cli(a->fd, " Relax DTMF: %s\n", AST_CLI_YESNO(global_relaxdtmf)); 18139 ast_cli(a->fd, " RFC2833 Compensation: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE))); 18140 ast_cli(a->fd, " Symmetric RTP: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_SYMMETRICRTP))); 18141 ast_cli(a->fd, " Compact SIP headers: %s\n", AST_CLI_YESNO(sip_cfg.compactheaders)); 18142 ast_cli(a->fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 18143 ast_cli(a->fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 18144 ast_cli(a->fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 18145 ast_cli(a->fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 18146 ast_cli(a->fd, " DNS SRV lookup: %s\n", AST_CLI_YESNO(sip_cfg.srvlookup)); 18147 ast_cli(a->fd, " Pedantic SIP support: %s\n", AST_CLI_YESNO(sip_cfg.pedanticsipchecking)); 18148 ast_cli(a->fd, " Reg. min duration %d secs\n", min_expiry); 18149 ast_cli(a->fd, " Reg. max duration: %d secs\n", max_expiry); 18150 ast_cli(a->fd, " Reg. default duration: %d secs\n", default_expiry); 18151 ast_cli(a->fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 18152 ast_cli(a->fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 18153 ast_cli(a->fd, " Notify ringing state: %s\n", AST_CLI_YESNO(sip_cfg.notifyringing)); 18154 if (sip_cfg.notifyringing) { 18155 ast_cli(a->fd, " Include CID: %s%s\n", 18156 AST_CLI_YESNO(sip_cfg.notifycid), 18157 sip_cfg.notifycid == IGNORE_CONTEXT ? " (Ignoring context)" : ""); 18158 } 18159 ast_cli(a->fd, " Notify hold state: %s\n", AST_CLI_YESNO(sip_cfg.notifyhold)); 18160 ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(sip_cfg.allowtransfer)); 18161 ast_cli(a->fd, " Max Call Bitrate: %d kbps\n", default_maxcallbitrate); 18162 ast_cli(a->fd, " Auto-Framing: %s\n", AST_CLI_YESNO(global_autoframing)); 18163 ast_cli(a->fd, " Outb. proxy: %s %s\n", ast_strlen_zero(sip_cfg.outboundproxy.name) ? "<not set>" : sip_cfg.outboundproxy.name, 18164 sip_cfg.outboundproxy.force ? "(forced)" : ""); 18165 ast_cli(a->fd, " Session Timers: %s\n", stmode2str(global_st_mode)); 18166 ast_cli(a->fd, " Session Refresher: %s\n", strefresher2str (global_st_refresher)); 18167 ast_cli(a->fd, " Session Expires: %d secs\n", global_max_se); 18168 ast_cli(a->fd, " Session Min-SE: %d secs\n", global_min_se); 18169 ast_cli(a->fd, " Timer T1: %d\n", global_t1); 18170 ast_cli(a->fd, " Timer T1 minimum: %d\n", global_t1min); 18171 ast_cli(a->fd, " Timer B: %d\n", global_timer_b); 18172 ast_cli(a->fd, " No premature media: %s\n", AST_CLI_YESNO(global_prematuremediafilter)); 18173 ast_cli(a->fd, " Max forwards: %d\n", sip_cfg.default_max_forwards); 18174 18175 ast_cli(a->fd, "\nDefault Settings:\n"); 18176 ast_cli(a->fd, "-----------------\n"); 18177 ast_cli(a->fd, " Allowed transports: %s\n", get_transport_list(default_transports)); 18178 ast_cli(a->fd, " Outbound transport: %s\n", get_transport(default_primary_transport)); 18179 ast_cli(a->fd, " Context: %s\n", sip_cfg.default_context); 18180 ast_cli(a->fd, " Force rport: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_NAT_FORCE_RPORT))); 18181 ast_cli(a->fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 18182 ast_cli(a->fd, " Qualify: %d\n", default_qualify); 18183 ast_cli(a->fd, " Use ClientCode: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USECLIENTCODE))); 18184 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))); 18185 ast_cli(a->fd, " Language: %s\n", default_language); 18186 ast_cli(a->fd, " MOH Interpret: %s\n", default_mohinterpret); 18187 ast_cli(a->fd, " MOH Suggest: %s\n", default_mohsuggest); 18188 ast_cli(a->fd, " Voice Mail Extension: %s\n", default_vmexten); 18189 18190 18191 if (realtimepeers || realtimeregs) { 18192 ast_cli(a->fd, "\nRealtime SIP Settings:\n"); 18193 ast_cli(a->fd, "----------------------\n"); 18194 ast_cli(a->fd, " Realtime Peers: %s\n", AST_CLI_YESNO(realtimepeers)); 18195 ast_cli(a->fd, " Realtime Regs: %s\n", AST_CLI_YESNO(realtimeregs)); 18196 ast_cli(a->fd, " Cache Friends: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))); 18197 ast_cli(a->fd, " Update: %s\n", AST_CLI_YESNO(sip_cfg.peer_rtupdate)); 18198 ast_cli(a->fd, " Ignore Reg. Expire: %s\n", AST_CLI_YESNO(sip_cfg.ignore_regexpire)); 18199 ast_cli(a->fd, " Save sys. name: %s\n", AST_CLI_YESNO(sip_cfg.rtsave_sysname)); 18200 ast_cli(a->fd, " Auto Clear: %d (%s)\n", sip_cfg.rtautoclear, ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR) ? "Enabled" : "Disabled"); 18201 } 18202 ast_cli(a->fd, "\n----\n"); 18203 return CLI_SUCCESS; 18204 }
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 16432 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.
16433 { 16434 struct sip_threadinfo *th; 16435 struct ao2_iterator i; 16436 16437 #define FORMAT2 "%-47.47s %9.9s %6.6s\n" 16438 #define FORMAT "%-47.47s %-9.9s %-6.6s\n" 16439 16440 switch (cmd) { 16441 case CLI_INIT: 16442 e->command = "sip show tcp"; 16443 e->usage = 16444 "Usage: sip show tcp\n" 16445 " Lists all active TCP/TLS sessions.\n"; 16446 return NULL; 16447 case CLI_GENERATE: 16448 return NULL; 16449 } 16450 16451 if (a->argc != 3) 16452 return CLI_SHOWUSAGE; 16453 16454 ast_cli(a->fd, FORMAT2, "Address", "Transport", "Type"); 16455 16456 i = ao2_iterator_init(threadt, 0); 16457 while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) { 16458 ast_cli(a->fd, FORMAT, 16459 ast_sockaddr_stringify(&th->tcptls_session->remote_address), 16460 get_transport(th->type), 16461 (th->tcptls_session->client ? "Client" : "Server")); 16462 ao2_t_ref(th, -1, "decrement ref from iterator"); 16463 } 16464 ao2_iterator_destroy(&i); 16465 16466 return CLI_SUCCESS; 16467 #undef FORMAT 16468 #undef FORMAT2 16469 }
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 17679 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.
17680 { 17681 char cbuf[256]; 17682 struct sip_peer *user; 17683 struct ast_variable *v; 17684 int load_realtime; 17685 17686 switch (cmd) { 17687 case CLI_INIT: 17688 e->command = "sip show user"; 17689 e->usage = 17690 "Usage: sip show user <name> [load]\n" 17691 " Shows all details on one SIP user and the current status.\n" 17692 " Option \"load\" forces lookup of peer in realtime storage.\n"; 17693 return NULL; 17694 case CLI_GENERATE: 17695 return complete_sip_show_user(a->line, a->word, a->pos, a->n); 17696 } 17697 17698 if (a->argc < 4) 17699 return CLI_SHOWUSAGE; 17700 17701 /* Load from realtime storage? */ 17702 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? TRUE : FALSE; 17703 17704 if ((user = find_peer(a->argv[3], NULL, load_realtime, FINDUSERS, FALSE, 0))) { 17705 ao2_lock(user); 17706 ast_cli(a->fd, "\n\n"); 17707 ast_cli(a->fd, " * Name : %s\n", user->name); 17708 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 17709 ast_cli(a->fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 17710 ast_cli(a->fd, " Context : %s\n", user->context); 17711 ast_cli(a->fd, " Language : %s\n", user->language); 17712 if (!ast_strlen_zero(user->accountcode)) 17713 ast_cli(a->fd, " Accountcode : %s\n", user->accountcode); 17714 ast_cli(a->fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 17715 ast_cli(a->fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 17716 ast_cli(a->fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 17717 ast_cli(a->fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 17718 ast_cli(a->fd, " Call limit : %d\n", user->call_limit); 17719 ast_cli(a->fd, " Callgroup : "); 17720 print_group(a->fd, user->callgroup, 0); 17721 ast_cli(a->fd, " Pickupgroup : "); 17722 print_group(a->fd, user->pickupgroup, 0); 17723 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 17724 ast_cli(a->fd, " ACL : %s\n", AST_CLI_YESNO(user->ha != NULL)); 17725 ast_cli(a->fd, " Sess-Timers : %s\n", stmode2str(user->stimer.st_mode_oper)); 17726 ast_cli(a->fd, " Sess-Refresh : %s\n", strefresher2str(user->stimer.st_ref)); 17727 ast_cli(a->fd, " Sess-Expires : %d secs\n", user->stimer.st_max_se); 17728 ast_cli(a->fd, " Sess-Min-SE : %d secs\n", user->stimer.st_min_se); 17729 ast_cli(a->fd, " RTP Engine : %s\n", user->engine); 17730 17731 ast_cli(a->fd, " Codec Order : ("); 17732 print_codec_to_cli(a->fd, &user->prefs); 17733 ast_cli(a->fd, ")\n"); 17734 17735 ast_cli(a->fd, " Auto-Framing: %s \n", AST_CLI_YESNO(user->autoframing)); 17736 if (user->chanvars) { 17737 ast_cli(a->fd, " Variables :\n"); 17738 for (v = user->chanvars ; v ; v = v->next) 17739 ast_cli(a->fd, " %s = %s\n", v->name, v->value); 17740 } 17741 17742 ast_cli(a->fd, "\n"); 17743 17744 ao2_unlock(user); 17745 unref_peer(user, "sip show user"); 17746 } else { 17747 ast_cli(a->fd, "User %s not found.\n", a->argv[3]); 17748 ast_cli(a->fd, "\n"); 17749 } 17750 17751 return CLI_SUCCESS; 17752 }
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 16472 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_CLI_YESNO, ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, FORMAT, TRUE, unref_peer(), and ast_cli_entry::usage.
16473 { 16474 regex_t regexbuf; 16475 int havepattern = FALSE; 16476 struct ao2_iterator user_iter; 16477 struct sip_peer *user; 16478 16479 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 16480 16481 switch (cmd) { 16482 case CLI_INIT: 16483 e->command = "sip show users"; 16484 e->usage = 16485 "Usage: sip show users [like <pattern>]\n" 16486 " Lists all known SIP users.\n" 16487 " Optional regular expression pattern is used to filter the user list.\n"; 16488 return NULL; 16489 case CLI_GENERATE: 16490 return NULL; 16491 } 16492 16493 switch (a->argc) { 16494 case 5: 16495 if (!strcasecmp(a->argv[3], "like")) { 16496 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 16497 return CLI_SHOWUSAGE; 16498 havepattern = TRUE; 16499 } else 16500 return CLI_SHOWUSAGE; 16501 case 3: 16502 break; 16503 default: 16504 return CLI_SHOWUSAGE; 16505 } 16506 16507 ast_cli(a->fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "ForcerPort"); 16508 16509 user_iter = ao2_iterator_init(peers, 0); 16510 while ((user = ao2_t_iterator_next(&user_iter, "iterate thru peers table"))) { 16511 ao2_lock(user); 16512 if (!(user->type & SIP_TYPE_USER)) { 16513 ao2_unlock(user); 16514 unref_peer(user, "sip show users"); 16515 continue; 16516 } 16517 16518 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) { 16519 ao2_unlock(user); 16520 unref_peer(user, "sip show users"); 16521 continue; 16522 } 16523 16524 ast_cli(a->fd, FORMAT, user->name, 16525 user->secret, 16526 user->accountcode, 16527 user->context, 16528 AST_CLI_YESNO(user->ha != NULL), 16529 AST_CLI_YESNO(ast_test_flag(&user->flags[0], SIP_NAT_FORCE_RPORT))); 16530 ao2_unlock(user); 16531 unref_peer(user, "sip show users"); 16532 } 16533 ao2_iterator_destroy(&user_iter); 16534 16535 if (havepattern) 16536 regfree(®exbuf); 16537 16538 return CLI_SUCCESS; 16539 #undef FORMAT 16540 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 29355 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().
29356 { 29357 char *cdest; 29358 char *extension, *domain; 29359 29360 cdest = ast_strdupa(dest); 29361 29362 extension = strsep(&cdest, "@"); 29363 domain = strsep(&cdest, ":"); 29364 if (ast_strlen_zero(extension)) { 29365 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 29366 return 0; 29367 } 29368 29369 /* we'll issue the redirect message here */ 29370 if (!domain) { 29371 char *local_to_header; 29372 char to_header[256]; 29373 29374 ast_copy_string(to_header, get_header(&p->initreq, "To"), sizeof(to_header)); 29375 if (ast_strlen_zero(to_header)) { 29376 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 29377 return 0; 29378 } 29379 if (((local_to_header = strcasestr(to_header, "sip:")) || (local_to_header = strcasestr(to_header, "sips:"))) 29380 && (local_to_header = strchr(local_to_header, '@'))) { 29381 char ldomain[256]; 29382 29383 memset(ldomain, 0, sizeof(ldomain)); 29384 local_to_header++; 29385 /* This is okey because lhost and lport are as big as tmp */ 29386 sscanf(local_to_header, "%256[^<>; ]", ldomain); 29387 if (ast_strlen_zero(ldomain)) { 29388 ast_log(LOG_ERROR, "Can't find the host address\n"); 29389 return 0; 29390 } 29391 domain = ast_strdupa(ldomain); 29392 } 29393 } 29394 29395 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s>", extension, domain); 29396 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 29397 29398 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 29399 sip_alreadygone(p); 29400 29401 if (p->owner) { 29402 enum ast_control_transfer message = AST_TRANSFER_SUCCESS; 29403 ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message)); 29404 } 29405 /* hangup here */ 29406 return 0; 29407 }
static struct sip_st_dlg * sip_st_alloc | ( | struct sip_pvt *const | p | ) | [static] |
Allocate Session-Timers struct w/in dialog.
Definition at line 7616 of file chan_sip.c.
References ast_calloc, ast_log(), and LOG_ERROR.
Referenced by handle_request_invite(), and st_get_mode().
07617 { 07618 struct sip_st_dlg *stp; 07619 07620 if (p->stimer) { 07621 ast_log(LOG_ERROR, "Session-Timer struct already allocated\n"); 07622 return p->stimer; 07623 } 07624 07625 if (!(stp = ast_calloc(1, sizeof(struct sip_st_dlg)))) 07626 return NULL; 07627 07628 p->stimer = stp; 07629 07630 stp->st_schedid = -1; /* Session-Timers ast_sched scheduler id */ 07631 07632 return p->stimer; 07633 }
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 25336 of file chan_sip.c.
Referenced by initreqprep(), and transmit_notify_with_mwi().
25337 { 25338 if (type & SIP_TRANSPORT_TLS) 25339 return port == STANDARD_TLS_PORT; 25340 else 25341 return port == STANDARD_SIP_PORT; 25342 }
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 8245 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.
08246 { 08247 struct sip_subscription_mwi *mwi; 08248 int portnum = 0; 08249 enum sip_transport transport = SIP_TRANSPORT_UDP; 08250 char buf[256] = ""; 08251 char *username = NULL, *hostname = NULL, *secret = NULL, *authuser = NULL, *porta = NULL, *mailbox = NULL, *at = NULL; 08252 08253 if (!value) { 08254 return -1; 08255 } 08256 08257 ast_copy_string(buf, value, sizeof(buf)); 08258 08259 if (!(at = strstr(buf, "@"))) { 08260 return -1; 08261 } 08262 08263 if ((hostname = strrchr(buf, '@'))) { 08264 *hostname++ = '\0'; 08265 username = buf; 08266 } 08267 08268 if ((secret = strchr(username, ':'))) { 08269 *secret++ = '\0'; 08270 if ((authuser = strchr(secret, ':'))) { 08271 *authuser++ = '\0'; 08272 } 08273 } 08274 08275 if ((mailbox = strchr(hostname, '/'))) { 08276 *mailbox++ = '\0'; 08277 } 08278 08279 if (ast_strlen_zero(username) || ast_strlen_zero(hostname) || ast_strlen_zero(mailbox)) { 08280 ast_log(LOG_WARNING, "Format for MWI subscription is user[:secret[:authuser]]@host[:port]/mailbox at line %d\n", lineno); 08281 return -1; 08282 } 08283 08284 if ((porta = strchr(hostname, ':'))) { 08285 *porta++ = '\0'; 08286 if (!(portnum = atoi(porta))) { 08287 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 08288 return -1; 08289 } 08290 } 08291 08292 if (!(mwi = ast_calloc_with_stringfields(1, struct sip_subscription_mwi, 256))) { 08293 return -1; 08294 } 08295 08296 ASTOBJ_INIT(mwi); 08297 ast_string_field_set(mwi, username, username); 08298 if (secret) { 08299 ast_string_field_set(mwi, secret, secret); 08300 } 08301 if (authuser) { 08302 ast_string_field_set(mwi, authuser, authuser); 08303 } 08304 ast_string_field_set(mwi, hostname, hostname); 08305 ast_string_field_set(mwi, mailbox, mailbox); 08306 mwi->resub = -1; 08307 mwi->portno = portnum; 08308 mwi->transport = transport; 08309 08310 ASTOBJ_CONTAINER_LINK(&submwil, mwi); 08311 ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy); 08312 08313 return 0; 08314 }
static void sip_subscribe_mwi_destroy | ( | struct sip_subscription_mwi * | mwi | ) | [static] |
Destroy MWI subscription object.
Definition at line 5723 of file chan_sip.c.
References ast_free, AST_SCHED_DEL, ast_string_field_free_memory, and sip_destroy().
Referenced by __sip_subscribe_mwi_do(), handle_response_subscribe(), sip_send_all_mwi_subscriptions(), sip_subscribe_mwi(), sip_subscribe_mwi_do(), and unload_module().
05724 { 05725 if (mwi->call) { 05726 mwi->call->mwi = NULL; 05727 sip_destroy(mwi->call); 05728 } 05729 05730 AST_SCHED_DEL(sched, mwi->resub); 05731 ast_string_field_free_memory(mwi); 05732 ast_free(mwi); 05733 }
static int sip_subscribe_mwi_do | ( | const void * | data | ) | [static] |
Send a subscription or resubscription for MWI.
Definition at line 12323 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().
12324 { 12325 struct sip_subscription_mwi *mwi = (struct sip_subscription_mwi*)data; 12326 12327 if (!mwi) { 12328 return -1; 12329 } 12330 12331 mwi->resub = -1; 12332 __sip_subscribe_mwi_do(mwi); 12333 ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy); 12334 12335 return 0; 12336 }
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 22068 of file chan_sip.c.
References change_t38_state(), sip_pvt_lock, sip_pvt_unlock, and transmit_response_reliable().
Referenced by handle_request_invite().
22069 { 22070 struct sip_pvt *p = (struct sip_pvt *) data; 22071 22072 sip_pvt_lock(p); 22073 /* an application may have taken ownership of the T.38 negotiation on this 22074 * channel while we were waiting to grab the lock... if it did, the scheduler 22075 * id will have been reset to -1, which is our indication that we do *not* 22076 * want to abort the negotiation process 22077 */ 22078 if (p->t38id != -1) { 22079 change_t38_state(p, T38_DISABLED); 22080 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 22081 p->t38id = -1; 22082 dialog_unref(p, "unref the dialog ptr from sip_t38_abort, because it held a dialog ptr"); 22083 } 22084 sip_pvt_unlock(p); 22085 return 0; 22086 }
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 25361 of file chan_sip.c.
References ao2_callback, ao2_ref, ao2_t_ref, threadinfo_locate_cb(), and threadt.
Referenced by sip_prepare_socket().
25362 { 25363 struct sip_threadinfo *th; 25364 struct ast_tcptls_session_instance *tcptls_instance = NULL; 25365 25366 if ((th = ao2_callback(threadt, 0, threadinfo_locate_cb, s))) { 25367 tcptls_instance = (ao2_ref(th->tcptls_session, +1), th->tcptls_session); 25368 ao2_t_ref(th, -1, "decrement ref from callback"); 25369 } 25370 25371 return tcptls_instance; 25372 }
static void * sip_tcp_worker_fn | ( | void * | ) | [static] |
SIP TCP connection handler.
Definition at line 2467 of file chan_sip.c.
References _sip_tcp_helper_thread().
Referenced by sip_prepare_socket().
02468 { 02469 struct ast_tcptls_session_instance *tcptls_session = data; 02470 02471 return _sip_tcp_helper_thread(NULL, tcptls_session); 02472 }
static void sip_tcptls_client_args_destructor | ( | void * | obj | ) | [static] |
Definition at line 2349 of file chan_sip.c.
References args, and ast_free.
Referenced by sip_prepare_socket().
02350 { 02351 struct ast_tcptls_session_args *args = obj; 02352 if (args->tls_cfg) { 02353 ast_free(args->tls_cfg->certfile); 02354 ast_free(args->tls_cfg->pvtfile); 02355 ast_free(args->tls_cfg->cipher); 02356 ast_free(args->tls_cfg->cafile); 02357 ast_free(args->tls_cfg->capath); 02358 } 02359 ast_free(args->tls_cfg); 02360 ast_free((char *) args->name); 02361 }
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 2409 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().
02410 { 02411 int res = len; 02412 struct sip_threadinfo *th = NULL; 02413 struct tcptls_packet *packet = NULL; 02414 struct sip_threadinfo tmp = { 02415 .tcptls_session = tcptls_session, 02416 }; 02417 enum sip_tcptls_alert alert = TCPTLS_ALERT_DATA; 02418 02419 if (!tcptls_session) { 02420 return XMIT_ERROR; 02421 } 02422 02423 ast_mutex_lock(&tcptls_session->lock); 02424 02425 if ((tcptls_session->fd == -1) || 02426 !(th = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread")) || 02427 !(packet = ao2_alloc(sizeof(*packet), tcptls_packet_destructor)) || 02428 !(packet->data = ast_str_create(len))) { 02429 goto tcptls_write_setup_error; 02430 } 02431 02432 /* goto tcptls_write_error should _NOT_ be used beyond this point */ 02433 ast_str_set(&packet->data, 0, "%s", (char *) buf); 02434 packet->len = len; 02435 02436 /* alert tcptls thread handler that there is a packet to be sent. 02437 * must lock the thread info object to guarantee control of the 02438 * packet queue */ 02439 ao2_lock(th); 02440 if (write(th->alert_pipe[1], &alert, sizeof(alert)) == -1) { 02441 ast_log(LOG_ERROR, "write() to alert pipe failed: %s\n", strerror(errno)); 02442 ao2_t_ref(packet, -1, "could not write to alert pipe, remove packet"); 02443 packet = NULL; 02444 res = XMIT_ERROR; 02445 } else { /* it is safe to queue the frame after issuing the alert when we hold the threadinfo lock */ 02446 AST_LIST_INSERT_TAIL(&th->packet_q, packet, entry); 02447 } 02448 ao2_unlock(th); 02449 02450 ast_mutex_unlock(&tcptls_session->lock); 02451 ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo object after finding it"); 02452 return res; 02453 02454 tcptls_write_setup_error: 02455 if (th) { 02456 ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo obj, could not create packet"); 02457 } 02458 if (packet) { 02459 ao2_t_ref(packet, -1, "could not allocate packet's data"); 02460 } 02461 ast_mutex_unlock(&tcptls_session->lock); 02462 02463 return XMIT_ERROR; 02464 }
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 2385 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().
02386 { 02387 struct sip_threadinfo *th; 02388 02389 if (!tcptls_session || !(th = ao2_alloc(sizeof(*th), sip_threadinfo_destructor))) { 02390 return NULL; 02391 } 02392 02393 th->alert_pipe[0] = th->alert_pipe[1] = -1; 02394 02395 if (pipe(th->alert_pipe) == -1) { 02396 ao2_t_ref(th, -1, "Failed to open alert pipe on sip_threadinfo"); 02397 ast_log(LOG_ERROR, "Could not create sip alert pipe in tcptls thread, error %s\n", strerror(errno)); 02398 return NULL; 02399 } 02400 ao2_t_ref(tcptls_session, +1, "tcptls_session ref for sip_threadinfo object"); 02401 th->tcptls_session = tcptls_session; 02402 th->type = transport ? transport : (tcptls_session->ssl ? SIP_TRANSPORT_TLS: SIP_TRANSPORT_TCP); 02403 ao2_t_link(threadt, th, "Adding new tcptls helper thread"); 02404 ao2_t_ref(th, -1, "Decrementing threadinfo ref from alloc, only table ref remains"); 02405 return th; 02406 }
static void sip_threadinfo_destructor | ( | void * | obj | ) | [static] |
Definition at line 2363 of file chan_sip.c.
References ao2_t_ref, and AST_LIST_REMOVE_HEAD.
Referenced by sip_threadinfo_create().
02364 { 02365 struct sip_threadinfo *th = obj; 02366 struct tcptls_packet *packet; 02367 if (th->alert_pipe[1] > -1) { 02368 close(th->alert_pipe[0]); 02369 } 02370 if (th->alert_pipe[1] > -1) { 02371 close(th->alert_pipe[1]); 02372 } 02373 th->alert_pipe[0] = th->alert_pipe[1] = -1; 02374 02375 while ((packet = AST_LIST_REMOVE_HEAD(&th->packet_q, entry))) { 02376 ao2_t_ref(packet, -1, "thread destruction, removing packet from frame queue"); 02377 } 02378 02379 if (th->tcptls_session) { 02380 ao2_t_ref(th->tcptls_session, -1, "remove tcptls_session for sip_threadinfo object"); 02381 } 02382 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 6682 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().
06683 { 06684 struct sip_pvt *p = ast->tech_pvt; 06685 int res; 06686 06687 if (dest == NULL) /* functions below do not take a NULL */ 06688 dest = ""; 06689 sip_pvt_lock(p); 06690 if (ast->_state == AST_STATE_RING) 06691 res = sip_sipredirect(p, dest); 06692 else 06693 res = transmit_refer(p, dest); 06694 sip_pvt_unlock(p); 06695 return res; 06696 }
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 17852 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.
17853 { 17854 struct sip_peer *peer; 17855 int load_realtime = 0; 17856 17857 switch (cmd) { 17858 case CLI_INIT: 17859 e->command = "sip unregister"; 17860 e->usage = 17861 "Usage: sip unregister <peer>\n" 17862 " Unregister (force expiration) a SIP peer from the registry\n"; 17863 return NULL; 17864 case CLI_GENERATE: 17865 return complete_sip_unregister(a->line, a->word, a->pos, a->n); 17866 } 17867 17868 if (a->argc != 3) 17869 return CLI_SHOWUSAGE; 17870 17871 if ((peer = find_peer(a->argv[2], NULL, load_realtime, FINDPEERS, TRUE, 0))) { 17872 if (peer->expire > 0) { 17873 AST_SCHED_DEL_UNREF(sched, peer->expire, 17874 unref_peer(peer, "remove register expire ref")); 17875 expire_register(ref_peer(peer, "ref for expire_register")); 17876 ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]); 17877 } else { 17878 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 17879 } 17880 unref_peer(peer, "sip_unregister: unref_peer via sip_unregister: done with peer from find_peer call"); 17881 } else { 17882 ast_cli(a->fd, "Peer unknown: \'%s\'. Not unregistered.\n", a->argv[2]); 17883 } 17884 17885 return CLI_SUCCESS; 17886 }
static void sip_unregister_tests | ( | void | ) | [static] |
SIP test registration.
Definition at line 29809 of file chan_sip.c.
References sip_config_parser_unregister_tests(), sip_dialplan_function_unregister_tests(), and sip_request_parser_unregister_tests().
29810 { 29811 sip_config_parser_unregister_tests(); 29812 sip_request_parser_unregister_tests(); 29813 sip_dialplan_function_unregister_tests(); 29814 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 6484 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.
06485 { 06486 struct sip_pvt *p = ast->tech_pvt; 06487 int res = 0; 06488 06489 switch (frame->frametype) { 06490 case AST_FRAME_VOICE: 06491 if (!(frame->subclass.codec & ast->nativeformats)) { 06492 char s1[512], s2[512], s3[512]; 06493 ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s read/write = %s/%s\n", 06494 ast_getformatname(frame->subclass.codec), 06495 ast_getformatname_multiple(s1, sizeof(s1), ast->nativeformats & AST_FORMAT_AUDIO_MASK), 06496 ast_getformatname_multiple(s2, sizeof(s2), ast->readformat), 06497 ast_getformatname_multiple(s3, sizeof(s3), ast->writeformat)); 06498 return 0; 06499 } 06500 if (p) { 06501 sip_pvt_lock(p); 06502 if (p->t38.state == T38_ENABLED) { 06503 /* drop frame, can't sent VOICE frames while in T.38 mode */ 06504 sip_pvt_unlock(p); 06505 break; 06506 } else if (p->rtp) { 06507 /* If channel is not up, activate early media session */ 06508 if ((ast->_state != AST_STATE_UP) && 06509 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06510 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06511 ast_rtp_instance_update_source(p->rtp); 06512 if (!global_prematuremediafilter) { 06513 p->invitestate = INV_EARLY_MEDIA; 06514 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 06515 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 06516 } 06517 } 06518 p->lastrtptx = time(NULL); 06519 res = ast_rtp_instance_write(p->rtp, frame); 06520 } 06521 sip_pvt_unlock(p); 06522 } 06523 break; 06524 case AST_FRAME_VIDEO: 06525 if (p) { 06526 sip_pvt_lock(p); 06527 if (p->vrtp) { 06528 /* Activate video early media */ 06529 if ((ast->_state != AST_STATE_UP) && 06530 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06531 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06532 p->invitestate = INV_EARLY_MEDIA; 06533 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 06534 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 06535 } 06536 p->lastrtptx = time(NULL); 06537 res = ast_rtp_instance_write(p->vrtp, frame); 06538 } 06539 sip_pvt_unlock(p); 06540 } 06541 break; 06542 case AST_FRAME_TEXT: 06543 if (p) { 06544 sip_pvt_lock(p); 06545 if (p->red) { 06546 ast_rtp_red_buffer(p->trtp, frame); 06547 } else { 06548 if (p->trtp) { 06549 /* Activate text early media */ 06550 if ((ast->_state != AST_STATE_UP) && 06551 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 06552 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06553 p->invitestate = INV_EARLY_MEDIA; 06554 transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); 06555 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 06556 } 06557 p->lastrtptx = time(NULL); 06558 res = ast_rtp_instance_write(p->trtp, frame); 06559 } 06560 } 06561 sip_pvt_unlock(p); 06562 } 06563 break; 06564 case AST_FRAME_IMAGE: 06565 return 0; 06566 break; 06567 case AST_FRAME_MODEM: 06568 if (p) { 06569 sip_pvt_lock(p); 06570 /* UDPTL requires two-way communication, so early media is not needed here. 06571 we simply forget the frames if we get modem frames before the bridge is up. 06572 Fax will re-transmit. 06573 */ 06574 if ((ast->_state == AST_STATE_UP) && 06575 p->udptl && 06576 (p->t38.state == T38_ENABLED)) { 06577 res = ast_udptl_write(p->udptl, frame); 06578 } 06579 sip_pvt_unlock(p); 06580 } 06581 break; 06582 default: 06583 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 06584 return 0; 06585 } 06586 06587 return res; 06588 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP UDP socket.
Definition at line 25207 of file chan_sip.c.
References AST_DYNSTR_BUILD_FAILED, ast_log(), ast_recvfrom(), ast_sockaddr_port, ast_str_create(), ast_str_set(), bindaddr, deinit_req(), errno, handle_request_do(), LOG_NOTICE, LOG_WARNING, set_socket_transport(), and sipsock.
Referenced by do_monitor().
25208 { 25209 struct sip_request req; 25210 struct ast_sockaddr addr; 25211 int res; 25212 static char readbuf[65535]; 25213 25214 memset(&req, 0, sizeof(req)); 25215 res = ast_recvfrom(fd, readbuf, sizeof(readbuf) - 1, 0, &addr); 25216 if (res < 0) { 25217 #if !defined(__FreeBSD__) 25218 if (errno == EAGAIN) 25219 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 25220 else 25221 #endif 25222 if (errno != ECONNREFUSED) 25223 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 25224 return 1; 25225 } 25226 25227 readbuf[res] = '\0'; 25228 25229 if (!(req.data = ast_str_create(SIP_MIN_PACKET))) { 25230 return 1; 25231 } 25232 25233 if (ast_str_set(&req.data, 0, "%s", readbuf) == AST_DYNSTR_BUILD_FAILED) { 25234 return -1; 25235 } 25236 25237 req.socket.fd = sipsock; 25238 set_socket_transport(&req.socket, SIP_TRANSPORT_UDP); 25239 req.socket.tcptls_session = NULL; 25240 req.socket.port = htons(ast_sockaddr_port(&bindaddr)); 25241 25242 handle_request_do(&req, &addr); 25243 deinit_req(&req); 25244 25245 return 1; 25246 }
static int sockaddr_is_null_or_any | ( | const struct ast_sockaddr * | addr | ) | [static] |
Definition at line 8748 of file chan_sip.c.
References ast_sockaddr_is_any(), and ast_sockaddr_isnull().
Referenced by process_sdp().
08749 { 08750 return ast_sockaddr_isnull(addr) || ast_sockaddr_is_any(addr); 08751 }
enum st_mode st_get_mode | ( | struct sip_pvt * | p, | |
int | no_cached | |||
) | [static] |
Get the session-timer mode.
p | pointer to the SIP dialog | |
no_cached,set | this to true in order to force a peername lookup on the session timer mode. |
Definition at line 26115 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().
26116 { 26117 if (!p->stimer) 26118 sip_st_alloc(p); 26119 26120 if (!no_cached && p->stimer->st_cached_mode != SESSION_TIMER_MODE_INVALID) 26121 return p->stimer->st_cached_mode; 26122 26123 if (p->relatedpeer) { 26124 p->stimer->st_cached_mode = p->relatedpeer->stimer.st_mode_oper; 26125 return p->stimer->st_cached_mode; 26126 } 26127 26128 p->stimer->st_cached_mode = global_st_mode; 26129 return global_st_mode; 26130 }
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 26094 of file chan_sip.c.
References global_st_refresher.
Referenced by handle_request_invite().
26095 { 26096 if (p->stimer->st_cached_ref != SESSION_TIMER_REFRESHER_AUTO) 26097 return p->stimer->st_cached_ref; 26098 26099 if (p->relatedpeer) { 26100 p->stimer->st_cached_ref = p->relatedpeer->stimer.st_ref; 26101 return p->stimer->st_cached_ref; 26102 } 26103 26104 p->stimer->st_cached_ref = global_st_refresher; 26105 return global_st_refresher; 26106 }
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 26065 of file chan_sip.c.
References global_max_se, global_min_se, and TRUE.
Referenced by handle_request_invite(), reqprep(), and transmit_invite().
26066 { 26067 if (max == TRUE) { 26068 if (p->stimer->st_cached_max_se) { 26069 return p->stimer->st_cached_max_se; 26070 } 26071 if (p->relatedpeer) { 26072 p->stimer->st_cached_max_se = p->relatedpeer->stimer.st_max_se; 26073 return (p->stimer->st_cached_max_se); 26074 } 26075 p->stimer->st_cached_max_se = global_max_se; 26076 return (p->stimer->st_cached_max_se); 26077 } 26078 /* Find Min SE timer */ 26079 if (p->stimer->st_cached_min_se) { 26080 return p->stimer->st_cached_min_se; 26081 } 26082 if (p->relatedpeer) { 26083 p->stimer->st_cached_min_se = p->relatedpeer->stimer.st_min_se; 26084 return (p->stimer->st_cached_min_se); 26085 } 26086 p->stimer->st_cached_min_se = global_min_se; 26087 return (p->stimer->st_cached_min_se); 26088 }
static void start_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Start session timer.
Definition at line 25850 of file chan_sip.c.
References ast_debug, ast_log(), ast_sched_add(), AST_SCHED_DEL_UNREF, LOG_ERROR, LOG_WARNING, proc_session_timer(), and TRUE.
Referenced by handle_request_invite(), handle_response_invite(), and restart_session_timer().
25851 { 25852 if (!p->stimer) { 25853 ast_log(LOG_WARNING, "Null stimer in start_session_timer - %s\n", p->callid); 25854 return; 25855 } 25856 25857 if (p->stimer->st_schedid > -1) { 25858 /* in the event a timer is already going, stop it */ 25859 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 25860 AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid, 25861 dialog_unref(p, "unref stimer->st_schedid from dialog")); 25862 } 25863 25864 p->stimer->st_schedid = ast_sched_add(sched, p->stimer->st_interval * 1000 / 2, proc_session_timer, 25865 dialog_ref(p, "adding session timer ref")); 25866 if (p->stimer->st_schedid < 0) { 25867 dialog_unref(p, "removing session timer ref"); 25868 ast_log(LOG_ERROR, "ast_sched_add failed - %s\n", p->callid); 25869 } else { 25870 p->stimer->st_active = TRUE; 25871 ast_debug(2, "Session timer started: %d - %s\n", p->stimer->st_schedid, p->callid); 25872 } 25873 }
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 12508 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().
12509 { 12510 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 12511 const char *statestring = "terminated"; 12512 const char *pidfstate = "--"; 12513 const char *pidfnote= "Ready"; 12514 char hint[AST_MAX_EXTENSION]; 12515 12516 switch (state) { 12517 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 12518 statestring = (sip_cfg.notifyringing) ? "early" : "confirmed"; 12519 local_state = NOTIFY_INUSE; 12520 pidfstate = "busy"; 12521 pidfnote = "Ringing"; 12522 break; 12523 case AST_EXTENSION_RINGING: 12524 statestring = "early"; 12525 local_state = NOTIFY_INUSE; 12526 pidfstate = "busy"; 12527 pidfnote = "Ringing"; 12528 break; 12529 case AST_EXTENSION_INUSE: 12530 statestring = "confirmed"; 12531 local_state = NOTIFY_INUSE; 12532 pidfstate = "busy"; 12533 pidfnote = "On the phone"; 12534 break; 12535 case AST_EXTENSION_BUSY: 12536 statestring = "confirmed"; 12537 local_state = NOTIFY_CLOSED; 12538 pidfstate = "busy"; 12539 pidfnote = "On the phone"; 12540 break; 12541 case AST_EXTENSION_UNAVAILABLE: 12542 statestring = "terminated"; 12543 local_state = NOTIFY_CLOSED; 12544 pidfstate = "away"; 12545 pidfnote = "Unavailable"; 12546 break; 12547 case AST_EXTENSION_ONHOLD: 12548 statestring = "confirmed"; 12549 local_state = NOTIFY_CLOSED; 12550 pidfstate = "busy"; 12551 pidfnote = "On hold"; 12552 break; 12553 case AST_EXTENSION_NOT_INUSE: 12554 default: 12555 /* Default setting */ 12556 break; 12557 } 12558 12559 /* Check which device/devices we are watching and if they are registered */ 12560 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten)) { 12561 char *hint2 = hint, *individual_hint = NULL; 12562 int hint_count = 0, unavailable_count = 0; 12563 12564 while ((individual_hint = strsep(&hint2, "&"))) { 12565 hint_count++; 12566 12567 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 12568 unavailable_count++; 12569 } 12570 12571 /* If none of the hinted devices are registered, we will 12572 * override notification and show no availability. 12573 */ 12574 if (hint_count > 0 && hint_count == unavailable_count) { 12575 local_state = NOTIFY_CLOSED; 12576 pidfstate = "away"; 12577 pidfnote = "Not online"; 12578 } 12579 } 12580 12581 switch (subscribed) { 12582 case XPIDF_XML: 12583 case CPIM_PIDF_XML: 12584 ast_str_append(tmp, 0, 12585 "<?xml version=\"1.0\"?>\n" 12586 "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n" 12587 "<presence>\n"); 12588 ast_str_append(tmp, 0, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 12589 ast_str_append(tmp, 0, "<atom id=\"%s\">\n", exten); 12590 ast_str_append(tmp, 0, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 12591 ast_str_append(tmp, 0, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 12592 ast_str_append(tmp, 0, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 12593 ast_str_append(tmp, 0, "</address>\n</atom>\n</presence>\n"); 12594 break; 12595 case PIDF_XML: /* Eyebeam supports this format */ 12596 ast_str_append(tmp, 0, 12597 "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" 12598 "<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); 12599 ast_str_append(tmp, 0, "<pp:person><status>\n"); 12600 if (pidfstate[0] != '-') { 12601 ast_str_append(tmp, 0, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 12602 } 12603 ast_str_append(tmp, 0, "</status></pp:person>\n"); 12604 ast_str_append(tmp, 0, "<note>%s</note>\n", pidfnote); /* Note */ 12605 ast_str_append(tmp, 0, "<tuple id=\"%s\">\n", exten); /* Tuple start */ 12606 ast_str_append(tmp, 0, "<contact priority=\"1\">%s</contact>\n", mto); 12607 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 12608 ast_str_append(tmp, 0, "<status><basic>open</basic></status>\n"); 12609 else 12610 ast_str_append(tmp, 0, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 12611 ast_str_append(tmp, 0, "</tuple>\n</presence>\n"); 12612 break; 12613 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 12614 ast_str_append(tmp, 0, "<?xml version=\"1.0\"?>\n"); 12615 ast_str_append(tmp, 0, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%u\" state=\"%s\" entity=\"%s\">\n", p->dialogver, full ? "full" : "partial", mto); 12616 if ((state & AST_EXTENSION_RINGING) && sip_cfg.notifyringing) { 12617 const char *local_display = exten; 12618 char *local_target = ast_strdupa(mto); 12619 12620 /* There are some limitations to how this works. The primary one is that the 12621 callee must be dialing the same extension that is being monitored. Simply dialing 12622 the hint'd device is not sufficient. */ 12623 if (sip_cfg.notifycid) { 12624 struct ast_channel *caller; 12625 12626 if ((caller = ast_channel_callback(find_calling_channel, NULL, p, 0))) { 12627 char *cid_num; 12628 int need; 12629 12630 ast_channel_lock(caller); 12631 cid_num = S_COR(caller->caller.id.number.valid, 12632 caller->caller.id.number.str, ""); 12633 need = strlen(cid_num) + strlen(p->fromdomain) + sizeof("sip:@"); 12634 local_target = alloca(need); 12635 snprintf(local_target, need, "sip:%s@%s", cid_num, p->fromdomain); 12636 local_display = ast_strdupa(S_COR(caller->caller.id.name.valid, 12637 caller->caller.id.name.str, "")); 12638 ast_channel_unlock(caller); 12639 caller = ast_channel_unref(caller); 12640 } 12641 12642 /* We create a fake call-id which the phone will send back in an INVITE 12643 Replaces header which we can grab and do some magic with. */ 12644 if (sip_cfg.pedanticsipchecking) { 12645 ast_str_append(tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" local-tag=\"%s\" remote-tag=\"%s\" direction=\"recipient\">\n", 12646 exten, p->callid, p->theirtag, p->tag); 12647 } else { 12648 ast_str_append(tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" direction=\"recipient\">\n", 12649 exten, p->callid); 12650 } 12651 ast_str_append(tmp, 0, 12652 "<remote>\n" 12653 /* See the limitations of this above. Luckily the phone seems to still be 12654 happy when these values are not correct. */ 12655 "<identity display=\"%s\">%s</identity>\n" 12656 "<target uri=\"%s\"/>\n" 12657 "</remote>\n" 12658 "<local>\n" 12659 "<identity>%s</identity>\n" 12660 "<target uri=\"%s\"/>\n" 12661 "</local>\n", 12662 local_display, local_target, local_target, mto, mto); 12663 } else { 12664 ast_str_append(tmp, 0, "<dialog id=\"%s\" direction=\"recipient\">\n", exten); 12665 } 12666 12667 } else { 12668 ast_str_append(tmp, 0, "<dialog id=\"%s\">\n", exten); 12669 } 12670 ast_str_append(tmp, 0, "<state>%s</state>\n", statestring); 12671 if (state == AST_EXTENSION_ONHOLD) { 12672 ast_str_append(tmp, 0, "<local>\n<target uri=\"%s\">\n" 12673 "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n" 12674 "</target>\n</local>\n", mto); 12675 } 12676 ast_str_append(tmp, 0, "</dialog>\n</dialog-info>\n"); 12677 break; 12678 case NONE: 12679 default: 12680 break; 12681 } 12682 }
static const char* stmode2str | ( | enum st_mode | m | ) | [static] |
Definition at line 16379 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 20866 of file chan_sip.c.
References ast_rtp_instance_stop(), and ast_udptl_stop().
Referenced by __sip_autodestruct(), handle_request_bye(), handle_request_cancel(), handle_response(), and sip_hangup().
20867 { 20868 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 20869 if (p->rtp) 20870 ast_rtp_instance_stop(p->rtp); 20871 if (p->vrtp) 20872 ast_rtp_instance_stop(p->vrtp); 20873 if (p->trtp) 20874 ast_rtp_instance_stop(p->trtp); 20875 if (p->udptl) 20876 ast_udptl_stop(p->udptl); 20877 }
static void stop_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Stop session timer.
Definition at line 25833 of file chan_sip.c.
References ast_debug, ast_log(), AST_SCHED_DEL_UNREF, FALSE, LOG_WARNING, and TRUE.
Referenced by __sip_destroy(), dialog_unlink_all(), handle_request_bye(), proc_session_timer(), sip_hangup(), and sip_scheddestroy().
25834 { 25835 if (!p->stimer) { 25836 ast_log(LOG_WARNING, "Null stimer in stop_session_timer - %s\n", p->callid); 25837 return; 25838 } 25839 25840 if (p->stimer->st_active == TRUE) { 25841 p->stimer->st_active = FALSE; 25842 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 25843 AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid, 25844 dialog_unref(p, "removing session timer ref")); 25845 } 25846 }
static int str2dtmfmode | ( | const char * | str | ) | [static] |
static enum st_mode str2stmode | ( | const char * | s | ) | [static] |
Definition at line 16384 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 16402 of file chan_sip.c.
References map_s_x(), and strefreshers.
Referenced by build_peer().
16403 { 16404 return map_s_x(strefreshers, s, -1); 16405 }
static const char * strefresher2str | ( | enum st_refresher | r | ) | [static] |
Definition at line 16397 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().
16398 { 16399 return map_x_s(strefreshers, r, "Unknown"); 16400 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 18237 of file chan_sip.c.
References ARRAY_LEN, subscription_types, cfsubscription_types::text, and type.
Referenced by show_channels_cb(), and sip_show_channel().
18238 { 18239 int i; 18240 18241 for (i = 1; i < ARRAY_LEN(subscription_types); i++) { 18242 if (subscription_types[i].type == subtype) { 18243 return subscription_types[i].text; 18244 } 18245 } 18246 return subscription_types[0].text; 18247 }
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 11059 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().
11060 { 11061 switch (rate) { 11062 case AST_T38_RATE_2400: 11063 return 2400; 11064 case AST_T38_RATE_4800: 11065 return 4800; 11066 case AST_T38_RATE_7200: 11067 return 7200; 11068 case AST_T38_RATE_9600: 11069 return 9600; 11070 case AST_T38_RATE_12000: 11071 return 12000; 11072 case AST_T38_RATE_14400: 11073 return 14400; 11074 default: 11075 return 0; 11076 } 11077 }
static void tcptls_packet_destructor | ( | void * | obj | ) | [static] |
Definition at line 2342 of file chan_sip.c.
References ast_free.
Referenced by sip_tcptls_write().
02343 { 02344 struct tcptls_packet *packet = obj; 02345 02346 ast_free(packet->data); 02347 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 27060 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().
27061 { 27062 struct sip_peer *peer; 27063 27064 if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct"))) 27065 return NULL; 27066 27067 if (ast_string_field_init(peer, 512)) { 27068 ao2_t_ref(peer, -1, "failed to string_field_init, drop peer"); 27069 return NULL; 27070 } 27071 27072 if (!(peer->cc_params = ast_cc_config_params_init())) { 27073 ao2_t_ref(peer, -1, "failed to allocate cc_params for peer"); 27074 return NULL; 27075 } 27076 27077 ast_atomic_fetchadd_int(&apeerobjs, 1); 27078 set_peer_defaults(peer); 27079 27080 ast_copy_string(peer->name, name, sizeof(peer->name)); 27081 27082 peer->selfdestruct = TRUE; 27083 peer->host_dynamic = TRUE; 27084 peer->prefs = default_prefs; 27085 reg_source_db(peer); 27086 27087 return peer; 27088 }
static void temp_pvt_cleanup | ( | void * | ) | [static] |
Definition at line 10509 of file chan_sip.c.
References ast_free, and ast_string_field_free_memory.
10510 { 10511 struct sip_pvt *p = data; 10512 10513 ast_string_field_free_memory(p); 10514 10515 ast_free(data); 10516 }
static int temp_pvt_init | ( | void * | ) | [static] |
Definition at line 10501 of file chan_sip.c.
References ast_string_field_init.
10502 { 10503 struct sip_pvt *p = data; 10504 10505 p->do_history = 0; /* XXX do we need it ? isn't already all 0 ? */ 10506 return ast_string_field_init(p, 512); 10507 }
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 14680 of file chan_sip.c.
Referenced by check_user_full(), and register_verify().
14681 { 14682 char *t = uri; 14683 while (*t && *t > ' ' && *t != ';') { 14684 t++; 14685 } 14686 *t = '\0'; 14687 return uri; 14688 }
static int threadinfo_locate_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 25344 of file chan_sip.c.
References ast_sockaddr_cmp(), CMP_MATCH, and CMP_STOP.
Referenced by sip_tcp_locate().
25345 { 25346 struct sip_threadinfo *th = obj; 25347 struct ast_sockaddr *s = arg; 25348 25349 if (!ast_sockaddr_cmp(s, &th->tcptls_session->remote_address)) { 25350 return CMP_MATCH | CMP_STOP; 25351 } 25352 25353 return 0; 25354 }
static int threadt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 29736 of file chan_sip.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_module().
29737 { 29738 struct sip_threadinfo *th = obj, *th2 = arg; 29739 29740 return (th->tcptls_session == th2->tcptls_session) ? CMP_MATCH | CMP_STOP : 0; 29741 }
static int threadt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 29729 of file chan_sip.c.
References ast_sockaddr_hash().
Referenced by load_module().
29730 { 29731 const struct sip_threadinfo *th = obj; 29732 29733 return ast_sockaddr_hash(&th->tcptls_session->remote_address); 29734 }
static char * transfermode2str | ( | enum transfermodes | mode | ) | const [static] |
Convert transfer mode to text string.
Definition at line 16357 of file chan_sip.c.
Referenced by _sip_show_peer(), peers_data_provider_get(), sip_show_channel(), sip_show_settings(), and sip_show_user().
16358 { 16359 if (mode == TRANSFER_OPENFORALL) 16360 return "open"; 16361 else if (mode == TRANSFER_CLOSED) 16362 return "closed"; 16363 return "strict"; 16364 }
static int transmit_cc_notify | ( | struct ast_cc_agent * | agent, | |
struct sip_pvt * | subscription, | |||
enum sip_cc_notify_state | state | |||
) | [static] |
Definition at line 12684 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().
12685 { 12686 struct sip_request req; 12687 struct sip_cc_agent_pvt *agent_pvt = agent->private_data; 12688 char uri[SIPBUFSIZE]; 12689 char state_str[64]; 12690 char subscription_state_hdr[64]; 12691 12692 if (state < CC_QUEUED || state > CC_READY) { 12693 ast_log(LOG_WARNING, "Invalid state provided for transmit_cc_notify (%d)\n", state); 12694 return -1; 12695 } 12696 12697 reqprep(&req, subscription, SIP_NOTIFY, 0, TRUE); 12698 snprintf(state_str, sizeof(state_str), "%s\r\n", sip_cc_notify_state_map[state].state_string); 12699 add_header(&req, "Event", "call-completion"); 12700 add_header(&req, "Content-Type", "application/call-completion"); 12701 snprintf(subscription_state_hdr, sizeof(subscription_state_hdr), "active;expires=%d", subscription->expiry); 12702 add_header(&req, "Subscription-State", subscription_state_hdr); 12703 if (state == CC_READY) { 12704 generate_uri(subscription, agent_pvt->notify_uri, sizeof(agent_pvt->notify_uri)); 12705 snprintf(uri, sizeof(uri) - 1, "cc-URI: %s\r\n", agent_pvt->notify_uri); 12706 } 12707 add_content(&req, state_str); 12708 if (state == CC_READY) { 12709 add_content(&req, uri); 12710 } 12711 return send_request(subscription, &req, XMIT_RELIABLE, subscription->ocseq); 12712 }
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 14579 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().
14580 { 14581 /* We have to emulate EXACTLY what we'd get with a good peer 14582 * and a bad password, or else we leak information. */ 14583 const char *response = "401 Unauthorized"; 14584 const char *reqheader = "Authorization"; 14585 const char *respheader = "WWW-Authenticate"; 14586 const char *authtoken; 14587 struct ast_str *buf; 14588 char *c; 14589 14590 /* table of recognised keywords, and their value in the digest */ 14591 enum keys { K_NONCE, K_LAST }; 14592 struct x { 14593 const char *key; 14594 const char *s; 14595 } *i, keys[] = { 14596 [K_NONCE] = { "nonce=", "" }, 14597 [K_LAST] = { NULL, NULL} 14598 }; 14599 14600 authtoken = get_header(req, reqheader); 14601 if (req->ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 14602 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 14603 * information */ 14604 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 14605 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 14606 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14607 return; 14608 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 14609 /* We have no auth, so issue challenge and request authentication */ 14610 set_nonce_randdata(p, 1); 14611 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 14612 /* Schedule auto destroy in 32 seconds */ 14613 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14614 return; 14615 } 14616 14617 if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 14618 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 14619 return; 14620 } 14621 14622 /* Make a copy of the response and parse it */ 14623 if (ast_str_set(&buf, 0, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) { 14624 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 14625 return; 14626 } 14627 14628 c = buf->str; 14629 14630 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 14631 for (i = keys; i->key != NULL; i++) { 14632 const char *separator = ","; /* default */ 14633 14634 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 14635 continue; 14636 } 14637 /* Found. Skip keyword, take text in quotes or up to the separator. */ 14638 c += strlen(i->key); 14639 if (*c == '"') { /* in quotes. Skip first and look for last */ 14640 c++; 14641 separator = "\""; 14642 } 14643 i->s = c; 14644 strsep(&c, separator); 14645 break; 14646 } 14647 if (i->key == NULL) { /* not found, jump after space or comma */ 14648 strsep(&c, " ,"); 14649 } 14650 } 14651 14652 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 14653 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { 14654 if (!req->ignore) { 14655 set_nonce_randdata(p, 1); 14656 } 14657 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 14658 14659 /* Schedule auto destroy in 32 seconds */ 14660 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14661 } else { 14662 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 14663 } 14664 }
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 13516 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().
13517 { 13518 struct sip_request req; 13519 struct ast_str *str = ast_str_alloca(512); 13520 const struct ast_aoc_unit_entry *unit_entry = ast_aoc_get_unit_info(decoded, 0); 13521 enum ast_aoc_charge_type charging = ast_aoc_get_charge_type(decoded); 13522 13523 reqprep(&req, p, SIP_INFO, 0, 1); 13524 13525 if (ast_aoc_get_msg_type(decoded) == AST_AOC_D) { 13526 ast_str_append(&str, 0, "type=active;"); 13527 } else if (ast_aoc_get_msg_type(decoded) == AST_AOC_E) { 13528 ast_str_append(&str, 0, "type=terminated;"); 13529 } else { 13530 /* unsupported message type */ 13531 return -1; 13532 } 13533 13534 switch (charging) { 13535 case AST_AOC_CHARGE_FREE: 13536 ast_str_append(&str, 0, "free-of-charge;"); 13537 break; 13538 case AST_AOC_CHARGE_CURRENCY: 13539 ast_str_append(&str, 0, "charging;"); 13540 ast_str_append(&str, 0, "charging-info=currency;"); 13541 ast_str_append(&str, 0, "amount=%u;", ast_aoc_get_currency_amount(decoded)); 13542 ast_str_append(&str, 0, "multiplier=%s;", ast_aoc_get_currency_multiplier_decimal(decoded)); 13543 if (!ast_strlen_zero(ast_aoc_get_currency_name(decoded))) { 13544 ast_str_append(&str, 0, "currency=%s;", ast_aoc_get_currency_name(decoded)); 13545 } 13546 break; 13547 case AST_AOC_CHARGE_UNIT: 13548 ast_str_append(&str, 0, "charging;"); 13549 ast_str_append(&str, 0, "charging-info=pulse;"); 13550 if (unit_entry) { 13551 ast_str_append(&str, 0, "recorded-units=%u;", unit_entry->amount); 13552 } 13553 break; 13554 default: 13555 ast_str_append(&str, 0, "not-available;"); 13556 }; 13557 13558 add_header(&req, "AOC", ast_str_buffer(str)); 13559 13560 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 13561 }
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 13564 of file chan_sip.c.
References add_digit(), ast_test_flag, reqprep(), and send_request().
Referenced by sip_senddigit_end().
13565 { 13566 struct sip_request req; 13567 13568 reqprep(&req, p, SIP_INFO, 0, 1); 13569 add_digit(&req, digit, duration, (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO)); 13570 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 13571 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 13574 of file chan_sip.c.
References add_vidupdate(), reqprep(), and send_request().
Referenced by sip_indicate().
13575 { 13576 struct sip_request req; 13577 13578 reqprep(&req, p, SIP_INFO, 0, 1); 13579 add_vidupdate(&req); 13580 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 13581 }
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 12156 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().
12157 { 12158 struct sip_request req; 12159 struct ast_variable *var; 12160 12161 req.method = sipmethod; 12162 if (init) {/* Bump branch even on initial requests */ 12163 p->branch ^= ast_random(); 12164 p->invite_branch = p->branch; 12165 build_via(p); 12166 } 12167 if (init > 1) { 12168 initreqprep(&req, p, sipmethod, explicit_uri); 12169 } else { 12170 /* If init=1, we should not generate a new branch. If it's 0, we need a new branch. */ 12171 reqprep(&req, p, sipmethod, 0, init ? 0 : 1); 12172 } 12173 12174 if (p->options && p->options->auth) { 12175 add_header(&req, p->options->authheader, p->options->auth); 12176 } 12177 append_date(&req); 12178 if (sipmethod == SIP_REFER) { /* Call transfer */ 12179 if (p->refer) { 12180 char buf[SIPBUFSIZE]; 12181 if (!ast_strlen_zero(p->refer->refer_to)) { 12182 add_header(&req, "Refer-To", p->refer->refer_to); 12183 } 12184 if (!ast_strlen_zero(p->refer->referred_by)) { 12185 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 12186 add_header(&req, "Referred-By", buf); 12187 } 12188 } 12189 } else if (sipmethod == SIP_SUBSCRIBE) { 12190 char buf[SIPBUFSIZE]; 12191 if (p->subscribed == MWI_NOTIFICATION) { 12192 add_header(&req, "Event", "message-summary"); 12193 add_header(&req, "Accept", "application/simple-message-summary"); 12194 } else if (p->subscribed == CALL_COMPLETION) { 12195 add_header(&req, "Event", "call-completion"); 12196 add_header(&req, "Accept", "application/call-completion"); 12197 } 12198 snprintf(buf, sizeof(buf), "%d", p->expiry); 12199 add_header(&req, "Expires", buf); 12200 } 12201 12202 /* This new INVITE is part of an attended transfer. Make sure that the 12203 other end knows and replace the current call with this new call */ 12204 if (p->options && !ast_strlen_zero(p->options->replaces)) { 12205 add_header(&req, "Replaces", p->options->replaces); 12206 add_header(&req, "Require", "replaces"); 12207 } 12208 12209 /* Add Session-Timers related headers */ 12210 if (st_get_mode(p, 0) == SESSION_TIMER_MODE_ORIGINATE) { 12211 char i2astr[10]; 12212 12213 if (!p->stimer->st_interval) { 12214 p->stimer->st_interval = st_get_se(p, TRUE); 12215 } 12216 12217 p->stimer->st_active = TRUE; 12218 12219 snprintf(i2astr, sizeof(i2astr), "%d", p->stimer->st_interval); 12220 add_header(&req, "Session-Expires", i2astr); 12221 snprintf(i2astr, sizeof(i2astr), "%d", st_get_se(p, FALSE)); 12222 add_header(&req, "Min-SE", i2astr); 12223 } 12224 12225 add_header(&req, "Allow", ALLOWED_METHODS); 12226 add_supported_header(p, &req); 12227 12228 if (p->options && p->options->addsipheaders && p->owner) { 12229 struct ast_channel *chan = p->owner; /* The owner channel */ 12230 struct varshead *headp; 12231 12232 ast_channel_lock(chan); 12233 12234 headp = &chan->varshead; 12235 12236 if (!headp) { 12237 ast_log(LOG_WARNING, "No Headp for the channel...ooops!\n"); 12238 } else { 12239 const struct ast_var_t *current; 12240 AST_LIST_TRAVERSE(headp, current, entries) { 12241 /* SIPADDHEADER: Add SIP header to outgoing call */ 12242 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 12243 char *content, *end; 12244 const char *header = ast_var_value(current); 12245 char *headdup = ast_strdupa(header); 12246 12247 /* Strip of the starting " (if it's there) */ 12248 if (*headdup == '"') { 12249 headdup++; 12250 } 12251 if ((content = strchr(headdup, ':'))) { 12252 *content++ = '\0'; 12253 content = ast_skip_blanks(content); /* Skip white space */ 12254 /* Strip the ending " (if it's there) */ 12255 end = content + strlen(content) -1; 12256 if (*end == '"') { 12257 *end = '\0'; 12258 } 12259 12260 add_header(&req, headdup, content); 12261 if (sipdebug) { 12262 ast_debug(1, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 12263 } 12264 } 12265 } 12266 } 12267 } 12268 12269 ast_channel_unlock(chan); 12270 } 12271 if ((sipmethod == SIP_INVITE || sipmethod == SIP_UPDATE) && ast_test_flag(&p->flags[0], SIP_SENDRPID)) 12272 add_rpid(&req, p); 12273 if (sipmethod == SIP_INVITE) { 12274 add_diversion_header(&req, p); 12275 } 12276 if (sdp) { 12277 memset(p->offered_media, 0, sizeof(p->offered_media)); 12278 if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) { 12279 ast_debug(1, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12280 add_sdp(&req, p, FALSE, FALSE, TRUE); 12281 } else if (p->rtp) { 12282 try_suggested_sip_codec(p); 12283 add_sdp(&req, p, FALSE, TRUE, FALSE); 12284 } 12285 } else if (p->notify) { 12286 for (var = p->notify->headers; var; var = var->next) { 12287 add_header(&req, var->name, var->value); 12288 } 12289 if (ast_str_strlen(p->notify->content)) { 12290 add_content(&req, ast_str_buffer(p->notify->content)); 12291 } 12292 } else if (sipmethod == SIP_PUBLISH) { 12293 char expires[SIPBUFSIZE]; 12294 12295 switch (p->epa_entry->static_data->event) { 12296 case CALL_COMPLETION: 12297 snprintf(expires, sizeof(expires), "%d", p->expiry); 12298 add_header(&req, "Event", "call-completion"); 12299 add_header(&req, "Expires", expires); 12300 if (p->epa_entry->publish_type != SIP_PUBLISH_INITIAL) { 12301 add_header(&req, "SIP-If-Match", p->epa_entry->entity_tag); 12302 } 12303 12304 if (!ast_strlen_zero(p->epa_entry->body)) { 12305 add_header(&req, "Content-Type", "application/pidf+xml"); 12306 add_content(&req, p->epa_entry->body); 12307 } 12308 default: 12309 break; 12310 } 12311 } 12312 12313 if (!p->initreq.headers || init > 2) { 12314 initialize_initreq(p, &req); 12315 } 12316 if (sipmethod == SIP_INVITE || sipmethod == SIP_SUBSCRIBE) { 12317 p->lastinvite = p->ocseq; 12318 } 12319 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 12320 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 13412 of file chan_sip.c.
References add_text(), reqprep(), and send_request().
Referenced by sip_park_thread(), and sip_sendtext().
13413 { 13414 struct sip_request req; 13415 13416 reqprep(&req, p, SIP_MESSAGE, 0, 1); 13417 add_text(&req, text); 13418 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 13419 }
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 12804 of file chan_sip.c.
References add_content(), add_header(), ast_sockaddr_port, ast_sockaddr_stringify_host_remote(), ast_str_alloca, ast_str_append(), ast_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().
12805 { 12806 struct sip_request req; 12807 struct ast_str *out = ast_str_alloca(500); 12808 int ourport = (p->fromdomainport) ? p->fromdomainport : ast_sockaddr_port(&p->ourip); 12809 const char *domain; 12810 const char *exten = S_OR(vmexten, default_vmexten); 12811 12812 initreqprep(&req, p, SIP_NOTIFY, NULL); 12813 add_header(&req, "Event", "message-summary"); 12814 add_header(&req, "Content-Type", default_notifymime); 12815 ast_str_append(&out, 0, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 12816 12817 /* domain initialization occurs here because initreqprep changes ast_sockaddr_stringify string. */ 12818 domain = S_OR(p->fromdomain, ast_sockaddr_stringify_host_remote(&p->ourip)); 12819 12820 if (!sip_standard_port(p->socket.type, ourport)) { 12821 if (p->socket.type == SIP_TRANSPORT_UDP) { 12822 ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d\r\n", exten, domain, ourport); 12823 } else { 12824 ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d;transport=%s\r\n", exten, domain, ourport, get_transport(p->socket.type)); 12825 } 12826 } else { 12827 if (p->socket.type == SIP_TRANSPORT_UDP) { 12828 ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n", exten, domain); 12829 } else { 12830 ast_str_append(&out, 0, "Message-Account: sip:%s@%s;transport=%s\r\n", exten, domain, get_transport(p->socket.type)); 12831 } 12832 } 12833 /* Cisco has a bug in the SIP stack where it can't accept the 12834 (0/0) notification. This can temporarily be disabled in 12835 sip.conf with the "buggymwi" option */ 12836 ast_str_append(&out, 0, "Voice-Message: %d/%d%s\r\n", 12837 newmsgs, oldmsgs, (ast_test_flag(&p->flags[1], SIP_PAGE2_BUGGY_MWI) ? "" : " (0/0)")); 12838 12839 if (p->subscribed) { 12840 if (p->expiry) { 12841 add_header(&req, "Subscription-State", "active"); 12842 } else { /* Expired */ 12843 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 12844 } 12845 } 12846 12847 add_content(&req, out->str); 12848 12849 if (!p->initreq.headers) { 12850 initialize_initreq(p, &req); 12851 } 12852 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 12853 }
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 12856 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().
12857 { 12858 struct sip_request req; 12859 char tmp[SIPBUFSIZE/2]; 12860 12861 reqprep(&req, p, SIP_NOTIFY, 0, 1); 12862 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 12863 add_header(&req, "Event", tmp); 12864 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 12865 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 12866 add_header(&req, "Allow", ALLOWED_METHODS); 12867 add_supported_header(p, &req); 12868 12869 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 12870 add_content(&req, tmp); 12871 12872 if (!p->initreq.headers) { 12873 initialize_initreq(p, &req); 12874 } 12875 12876 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 12877 }
static int transmit_provisional_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req, | |||
int | with_sdp | |||
) | [static] |
Definition at line 10775 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().
10776 { 10777 int res; 10778 10779 if (!(res = with_sdp ? transmit_response_with_sdp(p, msg, req, XMIT_UNRELIABLE, FALSE, FALSE) : transmit_response(p, msg, req))) { 10780 p->last_provisional = msg; 10781 update_provisional_keepalive(p, with_sdp); 10782 } 10783 10784 return res; 10785 }
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 12112 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().
12113 { 12114 struct sip_pvt *pvt; 12115 int expires; 12116 12117 epa_entry->publish_type = publish_type; 12118 12119 if (!(pvt = sip_alloc(NULL, NULL, 0, SIP_PUBLISH, NULL))) { 12120 return -1; 12121 } 12122 12123 sip_pvt_lock(pvt); 12124 12125 if (create_addr(pvt, epa_entry->destination, NULL, TRUE, NULL)) { 12126 sip_pvt_unlock(pvt); 12127 dialog_unlink_all(pvt); 12128 dialog_unref(pvt, "create_addr failed in transmit_publish. Unref dialog"); 12129 return -1; 12130 } 12131 ast_sip_ouraddrfor(&pvt->sa, &pvt->ourip, pvt); 12132 ast_set_flag(&pvt->flags[0], SIP_OUTGOING); 12133 expires = (publish_type == SIP_PUBLISH_REMOVE) ? 0 : DEFAULT_PUBLISH_EXPIRES; 12134 pvt->expiry = expires; 12135 12136 /* Bump refcount for sip_pvt's reference */ 12137 ao2_ref(epa_entry, +1); 12138 pvt->epa_entry = epa_entry; 12139 12140 transmit_invite(pvt, SIP_PUBLISH, FALSE, 2, explicit_uri); 12141 sip_pvt_unlock(pvt); 12142 sip_scheddestroy(pvt, DEFAULT_TRANS_TIMEOUT); 12143 dialog_unref(pvt, "Done with the sip_pvt allocated for transmitting PUBLISH"); 12144 return 0; 12145 }
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 13443 of file chan_sip.c.
References add_header(), add_supported_header(), ast_copy_string(), ast_debug, ast_log(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, FALSE, get_header(), get_in_brackets(), LOG_NOTICE, reqprep(), send_request(), sip_refer_allocate(), and TRUE.
Referenced by sip_transfer().
13444 { 13445 struct sip_request req = { 13446 .headers = 0, 13447 }; 13448 char from[256]; 13449 const char *of; 13450 char *c; 13451 char referto[256]; 13452 int use_tls=FALSE; 13453 13454 if (sipdebug) { 13455 ast_debug(1, "SIP transfer of %s to %s\n", p->callid, dest); 13456 } 13457 13458 /* Are we transfering an inbound or outbound call ? */ 13459 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 13460 of = get_header(&p->initreq, "To"); 13461 } else { 13462 of = get_header(&p->initreq, "From"); 13463 } 13464 13465 ast_copy_string(from, of, sizeof(from)); 13466 of = get_in_brackets(from); 13467 ast_string_field_set(p, from, of); 13468 if (!strncasecmp(of, "sip:", 4)) { 13469 of += 4; 13470 } else if (!strncasecmp(of, "sips:", 5)) { 13471 of += 5; 13472 use_tls = TRUE; 13473 } else { 13474 ast_log(LOG_NOTICE, "From address missing 'sip(s):', assuming sip:\n"); 13475 } 13476 /* Get just the username part */ 13477 if ((c = strchr(dest, '@'))) { 13478 c = NULL; 13479 } else if ((c = strchr(of, '@'))) { 13480 *c++ = '\0'; 13481 } 13482 if (c) { 13483 snprintf(referto, sizeof(referto), "<sip%s:%s@%s>", use_tls ? "s" : "", dest, c); 13484 } else { 13485 snprintf(referto, sizeof(referto), "<sip%s:%s>", use_tls ? "s" : "", dest); 13486 } 13487 13488 /* save in case we get 407 challenge */ 13489 sip_refer_allocate(p); 13490 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 13491 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 13492 p->refer->status = REFER_SENT; /* Set refer status */ 13493 13494 reqprep(&req, p, SIP_REFER, 0, 1); 13495 13496 add_header(&req, "Refer-To", referto); 13497 add_header(&req, "Allow", ALLOWED_METHODS); 13498 add_supported_header(p, &req); 13499 if (!ast_strlen_zero(p->our_contact)) { 13500 add_header(&req, "Referred-By", p->our_contact); 13501 } 13502 13503 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 13504 13505 /* We should propably wait for a NOTIFY here until we ack the transfer */ 13506 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 13507 13508 /*! \todo In theory, we should hang around and wait for a reply, before 13509 returning to the dial plan here. Don't know really how that would 13510 affect the transfer() app or the pbx, but, well, to make this 13511 useful we should have a STATUS code on transfer(). 13512 */ 13513 }
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 13157 of file chan_sip.c.
References add_header(), add_header_max_forwards(), append_history, ast_debug, ast_dnsmgr_lookup_cb(), ast_log(), ast_random(), ast_sched_add(), AST_SCHED_REPLACE_UNREF, ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_cmp(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_string_field_set, ast_strlen_zero(), ast_verbose, 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, obproxy_get(), on_dns_update_peer(), on_dns_update_registry(), REG_STATE_AUTHSENT, REG_STATE_REGSENT, registry_addref(), registry_unref(), S_OR, send_request(), set_socket_transport(), sip_alloc(), sip_cfg, sip_debug_test_pvt(), sip_methods, sip_reg_timeout(), sip_sanitized_host(), sip_tcp_desc, cfsip_methods::text, TRUE, and unref_peer().
Referenced by __sip_do_register(), do_register_auth(), handle_response_register(), and sip_reg_timeout().
13158 { 13159 struct sip_request req; 13160 char from[256]; 13161 char to[256]; 13162 char tmp[80]; 13163 char addr[80]; 13164 struct sip_pvt *p; 13165 struct sip_peer *peer = NULL; 13166 int res; 13167 int portno = 0; 13168 13169 /* exit if we are already in process with this registrar ?*/ 13170 if (r == NULL || ((auth == NULL) && (r->regstate == REG_STATE_REGSENT || r->regstate == REG_STATE_AUTHSENT))) { 13171 if (r) { 13172 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 13173 } 13174 return 0; 13175 } 13176 13177 if (r->dnsmgr == NULL) { 13178 char transport[MAXHOSTNAMELEN]; 13179 peer = find_peer(r->hostname, NULL, TRUE, FINDPEERS, FALSE, 0); 13180 snprintf(transport, sizeof(transport), "_%s._%s",get_srv_service(r->transport), get_srv_protocol(r->transport)); /* have to use static get_transport function */ 13181 r->us.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */ 13182 13183 /* No point in doing a DNS lookup of the register hostname if we're just going to 13184 * end up using an outbound proxy. obproxy_get is safe to call with either of r->call 13185 * or peer NULL. Since we're only concerned with its existence, we're not going to 13186 * bother getting a ref to the proxy*/ 13187 if (!obproxy_get(r->call, peer)) { 13188 registry_addref(r, "add reg ref for dnsmgr"); 13189 ast_dnsmgr_lookup_cb(peer ? peer->tohost : r->hostname, &r->us, &r->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_registry, r); 13190 if (!r->dnsmgr) { 13191 /*dnsmgr refresh disabled, no reference added! */ 13192 registry_unref(r, "remove reg ref, dnsmgr disabled"); 13193 } 13194 } 13195 if (peer) { 13196 peer = unref_peer(peer, "removing peer ref for dnsmgr_lookup"); 13197 } 13198 } 13199 13200 if (r->call) { /* We have a registration */ 13201 if (!auth) { 13202 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 13203 return 0; 13204 } else { 13205 p = dialog_ref(r->call, "getting a copy of the r->call dialog in transmit_register"); 13206 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 13207 ast_string_field_set(p, theirtag, NULL); /* forget their old tag, so we don't match tags when getting response */ 13208 } 13209 } else { 13210 /* Build callid for registration if we haven't registered before */ 13211 if (!r->callid_valid) { 13212 build_callid_registry(r, &internip, default_fromdomain); 13213 r->callid_valid = TRUE; 13214 } 13215 /* Allocate SIP dialog for registration */ 13216 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER, NULL))) { 13217 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 13218 return 0; 13219 } 13220 13221 if (p->do_history) { 13222 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 13223 } 13224 13225 /* Use port number specified if no SRV record was found */ 13226 if (!ast_sockaddr_isnull(&r->us)) { 13227 if (!ast_sockaddr_port(&r->us) && r->portno) { 13228 ast_sockaddr_set_port(&r->us, r->portno); 13229 } 13230 13231 /* It is possible that DNS was unavailable at the time the peer was created. 13232 * Here, if we've updated the address in the registry via manually calling 13233 * ast_dnsmgr_lookup_cb() above, then we call the same function that dnsmgr would 13234 * call if it was updating a peer's address */ 13235 if ((peer = find_peer(S_OR(r->peername, r->hostname), NULL, TRUE, FINDPEERS, FALSE, 0))) { 13236 if (ast_sockaddr_cmp(&peer->addr, &r->us)) { 13237 on_dns_update_peer(&peer->addr, &r->us, peer); 13238 } 13239 peer = unref_peer(peer, "unref after find_peer"); 13240 } 13241 } 13242 13243 /* Find address to hostname */ 13244 if (create_addr(p, S_OR(r->peername, r->hostname), &r->us, 0, NULL)) { 13245 /* we have what we hope is a temporary network error, 13246 * probably DNS. We need to reschedule a registration try */ 13247 dialog_unlink_all(p); 13248 p = dialog_unref(p, "unref dialog after unlink_all"); 13249 if (r->timeout > -1) { 13250 AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r, 13251 registry_unref(_data, "del for REPLACE of registry ptr"), 13252 registry_unref(r, "object ptr dec when SCHED_REPLACE add failed"), 13253 registry_addref(r,"add for REPLACE registry ptr")); 13254 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 13255 } else { 13256 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, registry_addref(r, "add for REPLACE registry ptr")); 13257 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); 13258 } 13259 r->regattempts++; 13260 return 0; 13261 } 13262 13263 /* Copy back Call-ID in case create_addr changed it */ 13264 ast_string_field_set(r, callid, p->callid); 13265 13266 if (!r->dnsmgr && r->portno) { 13267 ast_sockaddr_set_port(&p->sa, r->portno); 13268 ast_sockaddr_set_port(&p->recv, r->portno); 13269 } 13270 if (!ast_strlen_zero(p->fromdomain)) { 13271 portno = (p->fromdomainport) ? p->fromdomainport : STANDARD_SIP_PORT; 13272 } else if (!ast_strlen_zero(r->regdomain)) { 13273 portno = (r->regdomainport) ? r->regdomainport : STANDARD_SIP_PORT; 13274 } else { 13275 portno = ast_sockaddr_port(&p->sa); 13276 } 13277 13278 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 13279 r->call = dialog_ref(p, "copying dialog into registry r->call"); /* Save pointer to SIP dialog */ 13280 p->registry = registry_addref(r, "transmit_register: addref to p->registry in transmit_register"); /* Add pointer to registry in packet */ 13281 if (!ast_strlen_zero(r->secret)) { /* Secret (password) */ 13282 ast_string_field_set(p, peersecret, r->secret); 13283 } 13284 if (!ast_strlen_zero(r->md5secret)) 13285 ast_string_field_set(p, peermd5secret, r->md5secret); 13286 /* User name in this realm 13287 - if authuser is set, use that, otherwise use username */ 13288 if (!ast_strlen_zero(r->authuser)) { 13289 ast_string_field_set(p, peername, r->authuser); 13290 ast_string_field_set(p, authname, r->authuser); 13291 } else if (!ast_strlen_zero(r->username)) { 13292 ast_string_field_set(p, peername, r->username); 13293 ast_string_field_set(p, authname, r->username); 13294 ast_string_field_set(p, fromuser, r->username); 13295 } 13296 if (!ast_strlen_zero(r->username)) { 13297 ast_string_field_set(p, username, r->username); 13298 } 13299 /* Save extension in packet */ 13300 if (!ast_strlen_zero(r->callback)) { 13301 ast_string_field_set(p, exten, r->callback); 13302 } 13303 13304 /* Set transport and port so the correct contact is built */ 13305 set_socket_transport(&p->socket, r->transport); 13306 if (r->transport == SIP_TRANSPORT_TLS || r->transport == SIP_TRANSPORT_TCP) { 13307 p->socket.port = 13308 htons(ast_sockaddr_port(&sip_tcp_desc.local_address)); 13309 } 13310 13311 /* 13312 check which address we should use in our contact header 13313 based on whether the remote host is on the external or 13314 internal network so we can register through nat 13315 */ 13316 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 13317 build_contact(p); 13318 } 13319 13320 /* set up a timeout */ 13321 if (auth == NULL) { 13322 if (r->timeout > -1) { 13323 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 13324 } 13325 AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r, 13326 registry_unref(_data,"reg ptr unrefed from del in SCHED_REPLACE"), 13327 registry_unref(r,"reg ptr unrefed from add failure in SCHED_REPLACE"), 13328 registry_addref(r,"reg ptr reffed from add in SCHED_REPLACE")); 13329 ast_debug(1, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 13330 } 13331 13332 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost)), p->tag); 13333 if (!ast_strlen_zero(p->theirtag)) { 13334 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost)), p->theirtag); 13335 } else { 13336 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, S_OR(r->regdomain, sip_sanitized_host(p->tohost))); 13337 } 13338 13339 /* Fromdomain is what we are registering to, regardless of actual 13340 host name from SRV */ 13341 if (portno && portno != STANDARD_SIP_PORT) { 13342 snprintf(addr, sizeof(addr), "sip:%s:%d", S_OR(p->fromdomain,S_OR(r->regdomain, sip_sanitized_host(r->hostname))), portno); 13343 } else { 13344 snprintf(addr, sizeof(addr), "sip:%s", S_OR(p->fromdomain,S_OR(r->regdomain, sip_sanitized_host(r->hostname)))); 13345 } 13346 13347 ast_string_field_set(p, uri, addr); 13348 13349 p->branch ^= ast_random(); 13350 13351 init_req(&req, sipmethod, addr); 13352 13353 /* Add to CSEQ */ 13354 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 13355 p->ocseq = r->ocseq; 13356 13357 build_via(p); 13358 add_header(&req, "Via", p->via); 13359 add_header_max_forwards(p, &req); 13360 add_header(&req, "From", from); 13361 add_header(&req, "To", to); 13362 add_header(&req, "Call-ID", p->callid); 13363 add_header(&req, "CSeq", tmp); 13364 if (!ast_strlen_zero(global_useragent)) 13365 add_header(&req, "User-Agent", global_useragent); 13366 13367 if (auth) { /* Add auth header */ 13368 add_header(&req, authheader, auth); 13369 } else if (!ast_strlen_zero(r->nonce)) { 13370 char digest[1024]; 13371 13372 /* We have auth data to reuse, build a digest header. 13373 * Note, this is not always useful because some parties do not 13374 * like nonces to be reused (for good reasons!) so they will 13375 * challenge us anyways. 13376 */ 13377 if (sipdebug) { 13378 ast_debug(1, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 13379 } 13380 ast_string_field_set(p, realm, r->realm); 13381 ast_string_field_set(p, nonce, r->nonce); 13382 ast_string_field_set(p, domain, r->authdomain); 13383 ast_string_field_set(p, opaque, r->opaque); 13384 ast_string_field_set(p, qop, r->qop); 13385 p->noncecount = ++r->noncecount; 13386 13387 memset(digest, 0, sizeof(digest)); 13388 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 13389 add_header(&req, "Authorization", digest); 13390 } else { 13391 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 13392 } 13393 } 13394 13395 snprintf(tmp, sizeof(tmp), "%d", r->expiry); 13396 add_header(&req, "Expires", tmp); 13397 add_header(&req, "Contact", p->our_contact); 13398 13399 initialize_initreq(p, &req); 13400 if (sip_debug_test_pvt(p)) { 13401 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 13402 } 13403 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 13404 r->regattempts++; /* Another attempt */ 13405 ast_debug(4, "REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 13406 res = send_request(p, &req, XMIT_CRITICAL, p->ocseq); 13407 dialog_unref(p, "p is finished here at the end of transmit_register"); 13408 return res; 13409 }
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 11817 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().
11818 { 11819 struct sip_request req; 11820 11821 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 11822 11823 add_header(&req, "Allow", ALLOWED_METHODS); 11824 add_supported_header(p, &req); 11825 if (sipdebug) { 11826 if (oldsdp == TRUE) 11827 add_header(&req, "X-asterisk-Info", "SIP re-invite (Session-Timers)"); 11828 else 11829 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 11830 } 11831 11832 if (ast_test_flag(&p->flags[0], SIP_SENDRPID)) 11833 add_rpid(&req, p); 11834 11835 if (p->do_history) { 11836 append_history(p, "ReInv", "Re-invite sent"); 11837 } 11838 memset(p->offered_media, 0, sizeof(p->offered_media)); 11839 11840 try_suggested_sip_codec(p); 11841 if (t38version) { 11842 add_sdp(&req, p, oldsdp, FALSE, TRUE); 11843 } else { 11844 add_sdp(&req, p, oldsdp, TRUE, FALSE); 11845 } 11846 11847 /* Use this as the basis */ 11848 initialize_initreq(p, &req); 11849 p->lastinvite = p->ocseq; 11850 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 11851 11852 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 11853 }
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 13586 of file chan_sip.c.
References add_header(), reqprep(), and send_request().
Referenced by check_pendings(), handle_response(), handle_response_invite(), and sip_hangup().
13587 { 13588 struct sip_request resp; 13589 13590 reqprep(&resp, p, sipmethod, seqno, newbranch); 13591 if (sipmethod == SIP_CANCEL && p->answered_elsewhere) { 13592 add_header(&resp, "Reason", "SIP;cause=200;text=\"Call completed elsewhere\""); 13593 } 13594 13595 if (sipmethod == SIP_ACK) { 13596 p->invitestate = INV_CONFIRMED; 13597 } 13598 13599 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 13600 }
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 13618 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().
13619 { 13620 struct sip_request resp; 13621 13622 reqprep(&resp, p, sipmethod, seqno, newbranch); 13623 if (!ast_strlen_zero(p->realm)) { 13624 char digest[1024]; 13625 13626 memset(digest, 0, sizeof(digest)); 13627 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 13628 char *dummy, *response; 13629 enum sip_auth_type code = p->options ? p->options->auth_type : PROXY_AUTH; /* XXX force 407 if unknown */ 13630 auth_headers(code, &dummy, &response); 13631 add_header(&resp, response, digest); 13632 } else { 13633 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 13634 } 13635 } 13636 /* If we are hanging up and know a cause for that, send it in clear text to make 13637 debugging easier. */ 13638 if (sipmethod == SIP_BYE) { 13639 char buf[20]; 13640 13641 if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON) && p->hangupcause) { 13642 sprintf(buf, "Q.850;cause=%i", p->hangupcause & 0x7f); 13643 add_header(&resp, "Reason", buf); 13644 } 13645 13646 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->hangupcause)); 13647 snprintf(buf, sizeof(buf), "%d", p->hangupcause); 13648 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 13649 } 13650 13651 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 13652 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 10572 of file chan_sip.c.
References __transmit_response().
10573 { 10574 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 10575 }
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 10605 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().
10606 { 10607 return __transmit_response(p, msg, req, req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL); 10608 }
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 10519 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().
10520 { 10521 struct sip_pvt *p = NULL; 10522 10523 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 10524 ast_log(LOG_ERROR, "Failed to get temporary pvt\n"); 10525 return -1; 10526 } 10527 10528 /* XXX the structure may be dirty from previous usage. 10529 * Here we should state clearly how we should reinitialize it 10530 * before using it. 10531 * E.g. certainly the threadstorage should be left alone, 10532 * but other thihngs such as flags etc. maybe need cleanup ? 10533 */ 10534 10535 /* Initialize the bare minimum */ 10536 p->method = intended_method; 10537 10538 if (!addr) { 10539 ast_sockaddr_copy(&p->ourip, &internip); 10540 } else { 10541 ast_sockaddr_copy(&p->sa, addr); 10542 ast_sip_ouraddrfor(&p->sa, &p->ourip, p); 10543 } 10544 10545 p->branch = ast_random(); 10546 make_our_tag(p->tag, sizeof(p->tag)); 10547 p->ocseq = INITIAL_CSEQ; 10548 10549 if (useglobal_nat && addr) { 10550 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT); 10551 ast_sockaddr_copy(&p->recv, addr); 10552 do_setnat(p); 10553 } 10554 10555 ast_string_field_set(p, fromdomain, default_fromdomain); 10556 p->fromdomainport = default_fromdomainport; 10557 build_via(p); 10558 ast_string_field_set(p, callid, callid); 10559 10560 copy_socket_data(&p->socket, &req->socket); 10561 10562 /* Use this temporary pvt structure to send the message */ 10563 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 10564 10565 /* Free the string fields, but not the pool space */ 10566 ast_string_field_init(p, 0); 10567 10568 return 0; 10569 }
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 10641 of file chan_sip.c.
References add_header(), respprep(), and send_response().
Referenced by handle_incoming(), and handle_request_options().
10642 { 10643 struct sip_request resp; 10644 respprep(&resp, p, msg, req); 10645 add_header(&resp, "Accept", "application/sdp"); 10646 return send_response(p, &resp, reliable, 0); 10647 }
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 10662 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().
10663 { 10664 struct sip_request resp; 10665 char tmp[512]; 10666 int seqno = 0; 10667 10668 if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) { 10669 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 10670 return -1; 10671 } 10672 /* Choose Realm */ 10673 get_realm(p, req); 10674 10675 /* Stale means that they sent us correct authentication, but 10676 based it on an old challenge (nonce) */ 10677 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", p->realm, randdata, stale ? ", stale=true" : ""); 10678 respprep(&resp, p, msg, req); 10679 add_header(&resp, header, tmp); 10680 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 10681 return send_response(p, &resp, reliable, seqno); 10682 }
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 10632 of file chan_sip.c.
References append_date(), respprep(), and send_response().
Referenced by handle_response_subscribe(), and register_verify().
10633 { 10634 struct sip_request resp; 10635 respprep(&resp, p, msg, req); 10636 append_date(&resp); 10637 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 10638 }
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 10650 of file chan_sip.c.
References add_header(), min_expiry, respprep(), and send_response().
Referenced by handle_request_publish(), and handle_request_subscribe().
10651 { 10652 struct sip_request resp; 10653 char tmp[32]; 10654 10655 snprintf(tmp, sizeof(tmp), "%d", min_expiry); 10656 respprep(&resp, p, msg, req); 10657 add_header(&resp, "Min-Expires", tmp); 10658 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 10659 }
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 10588 of file chan_sip.c.
References add_header(), append_date(), respprep(), and send_response().
Referenced by handle_request_invite().
10589 { 10590 struct sip_request resp; 10591 char minse_str[20]; 10592 10593 respprep(&resp, p, msg, req); 10594 append_date(&resp); 10595 10596 snprintf(minse_str, sizeof(minse_str), "%d", minse_int); 10597 add_header(&resp, "Min-SE", minse_str); 10598 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 10599 }
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 10623 of file chan_sip.c.
References add_header(), respprep(), and send_response().
Referenced by handle_incoming().
10624 { 10625 struct sip_request resp; 10626 respprep(&resp, p, msg, req); 10627 add_header(&resp, "Retry-After", seconds); 10628 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 10629 }
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 11727 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().
11728 { 11729 struct sip_request resp; 11730 int seqno; 11731 if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) { 11732 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 11733 return -1; 11734 } 11735 respprep(&resp, p, msg, req); 11736 if (rpid == TRUE) { 11737 add_rpid(&resp, p); 11738 } 11739 if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) { 11740 add_cc_call_info_to_response(p, &resp); 11741 } 11742 if (p->rtp) { 11743 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 11744 ast_debug(1, "Setting framing from config on incoming call\n"); 11745 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &p->prefs); 11746 } 11747 ast_rtp_instance_activate(p->rtp); 11748 try_suggested_sip_codec(p); 11749 if (p->t38.state == T38_ENABLED) { 11750 add_sdp(&resp, p, oldsdp, TRUE, TRUE); 11751 } else { 11752 add_sdp(&resp, p, oldsdp, TRUE, FALSE); 11753 } 11754 } else 11755 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 11756 if (reliable && !p->pendinginvite) 11757 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 11758 return send_response(p, &resp, reliable, seqno); 11759 }
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 10488 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().
10489 { 10490 struct sip_request resp; 10491 10492 if (need_new_etag) { 10493 create_new_sip_etag(esc_entry, 1); 10494 } 10495 respprep(&resp, p, msg, req); 10496 add_header(&resp, "SIP-ETag", esc_entry->entity_tag); 10497 10498 return send_response(p, &resp, 0, 0); 10499 }
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 11645 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().
11646 { 11647 struct sip_request resp; 11648 int seqno; 11649 11650 if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) { 11651 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 11652 return -1; 11653 } 11654 respprep(&resp, p, msg, req); 11655 if (p->udptl) { 11656 add_sdp(&resp, p, 0, 0, 1); 11657 } else 11658 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 11659 if (retrans && !p->pendinginvite) 11660 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 11661 return send_response(p, &resp, retrans, seqno); 11662 }
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 10578 of file chan_sip.c.
References add_header(), append_date(), respprep(), and send_response().
Referenced by handle_request_bye(), and handle_request_invite().
10579 { 10580 struct sip_request resp; 10581 respprep(&resp, p, msg, req); 10582 append_date(&resp); 10583 add_header(&resp, "Unsupported", unsupported); 10584 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 10585 }
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 12715 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(), get_in_brackets(), LOG_WARNING, cfsubscription_types::mediatype, NONE, remove_uri_parameters(), reqprep(), send_request(), and state_notify_build_xml().
Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe().
12716 { 12717 struct ast_str *tmp = ast_str_alloca(4000); 12718 char from[256], to[256]; 12719 char *c, *mfrom, *mto; 12720 struct sip_request req; 12721 const struct cfsubscription_types *subscriptiontype; 12722 12723 memset(from, 0, sizeof(from)); 12724 memset(to, 0, sizeof(to)); 12725 12726 subscriptiontype = find_subscription_type(p->subscribed); 12727 12728 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 12729 c = get_in_brackets(from); 12730 if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) { 12731 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 12732 return -1; 12733 } 12734 12735 mfrom = remove_uri_parameters(c); 12736 12737 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 12738 c = get_in_brackets(to); 12739 if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) { 12740 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 12741 return -1; 12742 } 12743 mto = remove_uri_parameters(c); 12744 12745 reqprep(&req, p, SIP_NOTIFY, 0, 1); 12746 12747 switch(state) { 12748 case AST_EXTENSION_DEACTIVATED: 12749 if (timeout) 12750 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 12751 else { 12752 add_header(&req, "Subscription-State", "terminated;reason=probation"); 12753 add_header(&req, "Retry-After", "60"); 12754 } 12755 break; 12756 case AST_EXTENSION_REMOVED: 12757 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 12758 break; 12759 default: 12760 if (p->expiry) 12761 add_header(&req, "Subscription-State", "active"); 12762 else /* Expired */ 12763 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 12764 } 12765 12766 switch (p->subscribed) { 12767 case XPIDF_XML: 12768 case CPIM_PIDF_XML: 12769 add_header(&req, "Event", subscriptiontype->event); 12770 state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto); 12771 add_header(&req, "Content-Type", subscriptiontype->mediatype); 12772 p->dialogver++; 12773 break; 12774 case PIDF_XML: /* Eyebeam supports this format */ 12775 add_header(&req, "Event", subscriptiontype->event); 12776 state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto); 12777 add_header(&req, "Content-Type", subscriptiontype->mediatype); 12778 p->dialogver++; 12779 break; 12780 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 12781 add_header(&req, "Event", subscriptiontype->event); 12782 state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto); 12783 add_header(&req, "Content-Type", subscriptiontype->mediatype); 12784 p->dialogver++; 12785 break; 12786 case NONE: 12787 default: 12788 break; 12789 } 12790 12791 add_content(&req, tmp->str); 12792 12793 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 12794 12795 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 12796 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 6435 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().
06436 { 06437 format_t fmt; 06438 const char *codec; 06439 06440 if (p->outgoing_call) { 06441 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_OUTBOUND"); 06442 } else if (!(codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_INBOUND"))) { 06443 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 06444 } 06445 06446 if (!codec) 06447 return; 06448 06449 fmt = ast_getformatbyname(codec); 06450 if (fmt) { 06451 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 06452 if (p->jointcapability & fmt) { 06453 p->jointcapability &= fmt; 06454 p->capability &= fmt; 06455 } else 06456 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 06457 } else 06458 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 06459 return; 06460 }
static void unlink_all_peers_from_tables | ( | void | ) | [static] |
Definition at line 2904 of file chan_sip.c.
References SIP_PEERS_ALL, and unlink_peers_from_tables().
Referenced by unload_module().
02905 { 02906 unlink_peers_from_tables(SIP_PEERS_ALL); 02907 }
static void unlink_marked_peers_from_tables | ( | void | ) | [static] |
Definition at line 2899 of file chan_sip.c.
References SIP_PEERS_MARKED, and unlink_peers_from_tables().
Referenced by sip_do_reload(), and sip_prune_realtime().
02900 { 02901 unlink_peers_from_tables(SIP_PEERS_MARKED); 02902 }
static void unlink_peer_from_tables | ( | struct sip_peer * | peer | ) | [static] |
Definition at line 2910 of file chan_sip.c.
References ao2_t_unlink, ast_sockaddr_isnull(), and peers_by_ip.
Referenced by expire_register().
02911 { 02912 ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table"); 02913 if (!ast_sockaddr_isnull(&peer->addr)) { 02914 ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table"); 02915 } 02916 }
static void unlink_peers_from_tables | ( | peer_unlink_flag_t | flag | ) | [static] |
Definition at line 2890 of file chan_sip.c.
References ao2_t_callback, match_and_cleanup_peer_sched(), OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, and peers_by_ip.
Referenced by unlink_all_peers_from_tables(), and unlink_marked_peers_from_tables().
02891 { 02892 ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, 02893 match_and_cleanup_peer_sched, &flag, "initiating callback to remove marked peers"); 02894 ao2_t_callback(peers_by_ip, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, 02895 match_and_cleanup_peer_sched, &flag, "initiating callback to remove marked peers"); 02896 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 30342 of file chan_sip.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_data_unregister, ast_dnsmgr_release(), ast_free, ast_free_ha(), ast_manager_unregister(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_glue_unregister(), ast_sched_dump(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_tcptls_server_stop(), AST_TEST_UNREGISTER, ast_udptl_proto_unregister(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, authl, authl_lock, ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, checksipdomain_function, ast_tls_config::cipher, cleanup_all_regs(), cli_sip, default_tls_cfg, destroy_escs(), dialog_unlink_all(), dialogs, localaddr, ast_tcptls_session_args::master, monitor_thread, monlock, network_change_event_unsubscribe(), ast_tls_config::pvtfile, regl, sip_epa_unregister_all(), sip_header_function, sip_registry_destroy(), sip_rtp_glue, sip_subscribe_mwi_destroy(), sip_tcp_desc, sip_tech, sip_tls_desc, sip_udptl, sipchaninfo_function, sippeer_function, submwil, thread, threadt, and unlink_all_peers_from_tables().
30343 { 30344 struct sip_pvt *p; 30345 struct sip_threadinfo *th; 30346 struct ast_context *con; 30347 struct ao2_iterator i; 30348 30349 network_change_event_unsubscribe(); 30350 30351 ast_sched_dump(sched); 30352 30353 /* First, take us out of the channel type list */ 30354 ast_channel_unregister(&sip_tech); 30355 30356 /* Unregister dial plan functions */ 30357 ast_custom_function_unregister(&sipchaninfo_function); 30358 ast_custom_function_unregister(&sippeer_function); 30359 ast_custom_function_unregister(&sip_header_function); 30360 ast_custom_function_unregister(&checksipdomain_function); 30361 30362 /* Unregister dial plan applications */ 30363 ast_unregister_application(app_dtmfmode); 30364 ast_unregister_application(app_sipaddheader); 30365 ast_unregister_application(app_sipremoveheader); 30366 30367 #ifdef TEST_FRAMEWORK 30368 AST_TEST_UNREGISTER(test_sip_peers_get); 30369 AST_TEST_UNREGISTER(test_sip_mwi_subscribe_parse); 30370 #endif 30371 /* Unregister all the AstData providers */ 30372 ast_data_unregister(NULL); 30373 30374 /* Unregister CLI commands */ 30375 ast_cli_unregister_multiple(cli_sip, ARRAY_LEN(cli_sip)); 30376 30377 /* Disconnect from UDPTL */ 30378 ast_udptl_proto_unregister(&sip_udptl); 30379 30380 /* Disconnect from RTP engine */ 30381 ast_rtp_glue_unregister(&sip_rtp_glue); 30382 30383 /* Unregister AMI actions */ 30384 ast_manager_unregister("SIPpeers"); 30385 ast_manager_unregister("SIPshowpeer"); 30386 ast_manager_unregister("SIPqualifypeer"); 30387 ast_manager_unregister("SIPshowregistry"); 30388 ast_manager_unregister("SIPnotify"); 30389 30390 /* Kill TCP/TLS server threads */ 30391 if (sip_tcp_desc.master) { 30392 ast_tcptls_server_stop(&sip_tcp_desc); 30393 } 30394 if (sip_tls_desc.master) { 30395 ast_tcptls_server_stop(&sip_tls_desc); 30396 } 30397 30398 /* Kill all existing TCP/TLS threads */ 30399 i = ao2_iterator_init(threadt, 0); 30400 while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) { 30401 pthread_t thread = th->threadid; 30402 th->stop = 1; 30403 pthread_kill(thread, SIGURG); 30404 pthread_join(thread, NULL); 30405 ao2_t_ref(th, -1, "decrement ref from iterator"); 30406 } 30407 ao2_iterator_destroy(&i); 30408 30409 /* Hangup all dialogs if they have an owner */ 30410 i = ao2_iterator_init(dialogs, 0); 30411 while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 30412 if (p->owner) 30413 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 30414 ao2_t_ref(p, -1, "toss dialog ptr from iterator_next"); 30415 } 30416 ao2_iterator_destroy(&i); 30417 30418 unlink_all_peers_from_tables(); 30419 30420 ast_mutex_lock(&monlock); 30421 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 30422 pthread_cancel(monitor_thread); 30423 pthread_kill(monitor_thread, SIGURG); 30424 pthread_join(monitor_thread, NULL); 30425 } 30426 monitor_thread = AST_PTHREADT_STOP; 30427 ast_mutex_unlock(&monlock); 30428 30429 /* Destroy all the dialogs and free their memory */ 30430 i = ao2_iterator_init(dialogs, 0); 30431 while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) { 30432 dialog_unlink_all(p); 30433 ao2_t_ref(p, -1, "throw away iterator result"); 30434 } 30435 ao2_iterator_destroy(&i); 30436 30437 /* Free memory for local network address mask */ 30438 ast_free_ha(localaddr); 30439 30440 ast_mutex_lock(&authl_lock); 30441 if (authl) { 30442 ao2_t_ref(authl, -1, "Removing global authentication"); 30443 authl = NULL; 30444 } 30445 ast_mutex_unlock(&authl_lock); 30446 30447 sip_epa_unregister_all(); 30448 destroy_escs(); 30449 30450 if (default_tls_cfg.certfile) { 30451 ast_free(default_tls_cfg.certfile); 30452 } 30453 if (default_tls_cfg.pvtfile) { 30454 ast_free(default_tls_cfg.pvtfile); 30455 } 30456 if (default_tls_cfg.cipher) { 30457 ast_free(default_tls_cfg.cipher); 30458 } 30459 if (default_tls_cfg.cafile) { 30460 ast_free(default_tls_cfg.cafile); 30461 } 30462 if (default_tls_cfg.capath) { 30463 ast_free(default_tls_cfg.capath); 30464 } 30465 30466 cleanup_all_regs(); 30467 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 30468 ASTOBJ_CONTAINER_DESTROY(®l); 30469 30470 ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { 30471 ASTOBJ_WRLOCK(iterator); 30472 if (iterator->dnsmgr) { 30473 ast_dnsmgr_release(iterator->dnsmgr); 30474 iterator->dnsmgr = NULL; 30475 ASTOBJ_UNREF(iterator, sip_subscribe_mwi_destroy); 30476 } 30477 ASTOBJ_UNLOCK(iterator); 30478 } while(0)); 30479 ASTOBJ_CONTAINER_DESTROYALL(&submwil, sip_subscribe_mwi_destroy); 30480 ASTOBJ_CONTAINER_DESTROY(&submwil); 30481 30482 ao2_t_ref(peers, -1, "unref the peers table"); 30483 ao2_t_ref(peers_by_ip, -1, "unref the peers_by_ip table"); 30484 ao2_t_ref(dialogs, -1, "unref the dialogs table"); 30485 ao2_t_ref(dialogs_to_destroy, -1, "unref dialogs_to_destroy"); 30486 ao2_t_ref(threadt, -1, "unref the thread table"); 30487 ao2_t_ref(sip_monitor_instances, -1, "unref the sip_monitor_instances table"); 30488 30489 clear_sip_domains(); 30490 ast_free_ha(sip_cfg.contact_ha); 30491 close(sipsock); 30492 sched_context_destroy(sched); 30493 con = ast_context_find(used_context); 30494 if (con) { 30495 ast_context_destroy(con, "SIP"); 30496 } 30497 ast_unload_realtime("sipregs"); 30498 ast_unload_realtime("sippeers"); 30499 ast_cc_monitor_unregister(&sip_cc_monitor_callbacks); 30500 ast_cc_agent_unregister(&sip_cc_agent_callbacks); 30501 30502 sip_reqresp_parser_exit(); 30503 sip_unregister_tests(); 30504 30505 return 0; 30506 }
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 2841 of file chan_sip.c.
References ao2_t_ref.
Referenced by __sip_destroy(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), build_peer(), check_peer_ok(), complete_sip_peer(), complete_sip_registered_peer(), complete_sip_user(), create_addr(), expire_register(), find_peer(), function_sippeer(), handle_request_invite(), handle_request_notify(), handle_request_subscribe(), handle_response_peerpoke(), match_and_cleanup_peer_sched(), parse_register_contact(), peer_sched_cleanup(), 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().
02842 { 02843 ao2_t_ref(peer, -1, tag); 02844 return NULL; 02845 }
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 5893 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().
05894 { 05895 char name[256]; 05896 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 05897 int outgoing = fup->outgoing_call; 05898 struct sip_peer *p = NULL; 05899 05900 ast_debug(3, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 05901 05902 05903 /* Test if we need to check call limits, in order to avoid 05904 realtime lookups if we do not need it */ 05905 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 05906 return 0; 05907 05908 ast_copy_string(name, fup->username, sizeof(name)); 05909 05910 /* Check the list of devices */ 05911 if (fup->relatedpeer) { 05912 p = ref_peer(fup->relatedpeer, "ref related peer for update_call_counter"); 05913 inuse = &p->inUse; 05914 call_limit = &p->call_limit; 05915 inringing = &p->inRinging; 05916 ast_copy_string(name, fup->peername, sizeof(name)); 05917 } 05918 if (!p) { 05919 ast_debug(2, "%s is not a local device, no call limit\n", name); 05920 return 0; 05921 } 05922 05923 switch(event) { 05924 /* incoming and outgoing affects the inUse counter */ 05925 case DEC_CALL_LIMIT: 05926 /* Decrement inuse count if applicable */ 05927 if (inuse) { 05928 sip_pvt_lock(fup); 05929 ao2_lock(p); 05930 if (*inuse > 0) { 05931 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 05932 (*inuse)--; 05933 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 05934 } 05935 } else { 05936 *inuse = 0; 05937 } 05938 ao2_unlock(p); 05939 sip_pvt_unlock(fup); 05940 } 05941 05942 /* Decrement ringing count if applicable */ 05943 if (inringing) { 05944 sip_pvt_lock(fup); 05945 ao2_lock(p); 05946 if (*inringing > 0) { 05947 if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 05948 (*inringing)--; 05949 ast_clear_flag(&fup->flags[0], SIP_INC_RINGING); 05950 } 05951 } else { 05952 *inringing = 0; 05953 } 05954 ao2_unlock(p); 05955 sip_pvt_unlock(fup); 05956 } 05957 05958 /* Decrement onhold count if applicable */ 05959 sip_pvt_lock(fup); 05960 ao2_lock(p); 05961 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && sip_cfg.notifyhold) { 05962 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 05963 ao2_unlock(p); 05964 sip_pvt_unlock(fup); 05965 sip_peer_hold(fup, FALSE); 05966 } else { 05967 ao2_unlock(p); 05968 sip_pvt_unlock(fup); 05969 } 05970 if (sipdebug) 05971 ast_debug(2, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", "peer", name, *call_limit); 05972 break; 05973 05974 case INC_CALL_RINGING: 05975 case INC_CALL_LIMIT: 05976 /* If call limit is active and we have reached the limit, reject the call */ 05977 if (*call_limit > 0 ) { 05978 if (*inuse >= *call_limit) { 05979 ast_log(LOG_NOTICE, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", "peer", name, *call_limit); 05980 unref_peer(p, "update_call_counter: unref peer p, call limit exceeded"); 05981 return -1; 05982 } 05983 } 05984 if (inringing && (event == INC_CALL_RINGING)) { 05985 sip_pvt_lock(fup); 05986 ao2_lock(p); 05987 if (!ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 05988 (*inringing)++; 05989 ast_set_flag(&fup->flags[0], SIP_INC_RINGING); 05990 } 05991 ao2_unlock(p); 05992 sip_pvt_unlock(fup); 05993 } 05994 if (inuse) { 05995 sip_pvt_lock(fup); 05996 ao2_lock(p); 05997 if (!ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 05998 (*inuse)++; 05999 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 06000 } 06001 ao2_unlock(p); 06002 sip_pvt_unlock(fup); 06003 } 06004 if (sipdebug) { 06005 ast_debug(2, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", "peer", name, *inuse, *call_limit); 06006 } 06007 break; 06008 06009 case DEC_CALL_RINGING: 06010 if (inringing) { 06011 sip_pvt_lock(fup); 06012 ao2_lock(p); 06013 if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 06014 if (*inringing > 0) { 06015 (*inringing)--; 06016 } 06017 ast_clear_flag(&fup->flags[0], SIP_INC_RINGING); 06018 } 06019 ao2_unlock(p); 06020 sip_pvt_unlock(fup); 06021 } 06022 break; 06023 06024 default: 06025 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 06026 } 06027 06028 if (p) { 06029 ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", p->name); 06030 unref_peer(p, "update_call_counter: unref_peer from call counter"); 06031 } 06032 return 0; 06033 }
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 12953 of file chan_sip.c.
References add_header(), add_rpid(), add_sdp(), add_supported_header(), append_history, ast_clear_flag, ast_debug, ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, FALSE, initialize_initreq(), is_method_allowed(), reqprep(), respprep(), S_COR, send_request(), send_response(), and TRUE.
Referenced by sip_indicate(), and skinny_indicate().
12954 { 12955 12956 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) { 12957 return; 12958 } 12959 if (!p->owner->connected.id.number.valid 12960 || ast_strlen_zero(p->owner->connected.id.number.str)) { 12961 return; 12962 } 12963 12964 append_history(p, "ConnectedLine", "%s party is now %s <%s>", 12965 ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "Calling" : "Called", 12966 S_COR(p->owner->connected.id.name.valid, p->owner->connected.id.name.str, ""), 12967 S_COR(p->owner->connected.id.number.valid, p->owner->connected.id.number.str, "")); 12968 12969 if (p->owner->_state == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12970 struct sip_request req; 12971 12972 if (p->invitestate == INV_CONFIRMED || p->invitestate == INV_TERMINATED) { 12973 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 12974 12975 add_header(&req, "Allow", ALLOWED_METHODS); 12976 add_supported_header(p, &req); 12977 add_rpid(&req, p); 12978 add_sdp(&req, p, FALSE, TRUE, FALSE); 12979 12980 initialize_initreq(p, &req); 12981 p->lastinvite = p->ocseq; 12982 ast_set_flag(&p->flags[0], SIP_OUTGOING); 12983 p->invitestate = INV_CALLING; 12984 send_request(p, &req, XMIT_CRITICAL, p->ocseq); 12985 } else if ((is_method_allowed(&p->allowed_methods, SIP_UPDATE)) && (!ast_strlen_zero(p->okcontacturi))) { 12986 reqprep(&req, p, SIP_UPDATE, 0, 1); 12987 add_rpid(&req, p); 12988 add_header(&req, "X-Asterisk-rpid-update", "Yes"); 12989 send_request(p, &req, XMIT_CRITICAL, p->ocseq); 12990 } else { 12991 /* We cannot send the update yet, so we have to wait until we can */ 12992 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 12993 } 12994 } else { 12995 ast_set_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 12996 if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPID_IMMEDIATE)) { 12997 struct sip_request resp; 12998 12999 if ((p->owner->_state == AST_STATE_RING) && !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT)) { 13000 ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 13001 respprep(&resp, p, "180 Ringing", &p->initreq); 13002 add_rpid(&resp, p); 13003 send_response(p, &resp, XMIT_UNRELIABLE, 0); 13004 ast_set_flag(&p->flags[0], SIP_RINGING); 13005 } else if (p->owner->_state == AST_STATE_RINGING) { 13006 ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND); 13007 respprep(&resp, p, "183 Session Progress", &p->initreq); 13008 add_rpid(&resp, p); 13009 send_response(p, &resp, XMIT_UNRELIABLE, 0); 13010 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 13011 } else { 13012 ast_debug(1, "Unable able to send update to '%s' in state '%s'\n", p->owner->name, ast_state2str(p->owner->_state)); 13013 } 13014 } 13015 } 13016 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expire | |||
) | [static] |
Update peer data in database (if used).
Definition at line 4667 of file chan_sip.c.
References ast_test_flag, realtime_update_peer(), and sip_cfg.
Referenced by register_verify().
04668 { 04669 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 04670 if (sip_cfg.peer_rtupdate && 04671 (p->is_realtime || rtcachefriends)) { 04672 realtime_update_peer(p->name, &p->addr, p->username, p->fullcontact, p->useragent, expire, p->deprecated_username, p->lastms); 04673 } 04674 }
static void update_provisional_keepalive | ( | struct sip_pvt * | pvt, | |
int | with_sdp | |||
) | [static] |
Definition at line 4152 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().
04153 { 04154 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")); 04155 04156 pvt->provisional_keepalive_sched_id = ast_sched_add(sched, PROVIS_KEEPALIVE_TIMEOUT, 04157 with_sdp ? send_provisional_keepalive_with_sdp : send_provisional_keepalive, dialog_ref(pvt, "Increment refcount to pass dialog pointer to sched callback")); 04158 }
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 12939 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().
12940 { 12941 struct sip_request resp; 12942 12943 if (p->owner->_state == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12944 return; 12945 } 12946 12947 respprep(&resp, p, "181 Call is being forwarded", &p->initreq); 12948 add_diversion_header(&resp, p); 12949 send_response(p, &resp, XMIT_UNRELIABLE, 0); 12950 }
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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto,chan_local", } [static] |
Definition at line 30514 of file chan_sip.c.
struct _map_x_s allowoverlapstr[] [static] |
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 766 of file chan_sip.c.
Referenced by sip_destroy_peer(), sip_show_objects(), and temp_peer().
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 29219 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 29220 of file chan_sip.c.
char* app_sipremoveheader = "SIPRemoveHeader" [static] |
Definition at line 29221 of file chan_sip.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 30514 of file chan_sip.c.
struct sip_auth_container* authl = NULL [static] |
Authentication container for realm authentication.
Definition at line 1130 of file chan_sip.c.
Referenced by build_reply_digest(), reload_config(), sip_show_settings(), and unload_module().
ast_mutex_t authl_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Global authentication container protection while adjusting the references.
Definition at line 1132 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 564 of file chan_sip.c.
Referenced by __init_manager(), _sip_tcp_helper_thread(), reload_config(), and session_do().
int authtimeout = DEFAULT_AUTHTIMEOUT [static] |
Definition at line 565 of file chan_sip.c.
Referenced by __init_manager(), do_message(), reload_config(), and sip_check_authtimeout().
struct ast_sockaddr bindaddr |
UDP: The address we bind to
Definition at line 1152 of file chan_sip.c.
int can_parse_xml [static] |
We use libxml2 in order to parse XML that may appear in the body of a SIP message. Currently, the only usage is for parsing PIDF bodies of incoming PUBLISH requests in the call-completion event package. This variable is set at module load time and may be checked at runtime to determine if XML parsing support was found.
Definition at line 759 of file chan_sip.c.
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 946 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 14284 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 19368 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 29774 of file chan_sip.c.
Referenced by load_module(), and unload_module().
const char config[] = "sip.conf" [static] |
Main configuration file
Definition at line 579 of file chan_sip.c.
struct ast_sockaddr debugaddr [static] |
Definition at line 1196 of file chan_sip.c.
char default_callerid[AST_MAX_EXTENSION] [static] |
Default caller ID for sip messages
Definition at line 680 of file chan_sip.c.
Referenced by initreqprep(), reload_config(), and sip_show_settings().
char default_engine[256] [static] |
Default RTP engine
Definition at line 691 of file chan_sip.c.
Referenced by ast_speech_register(), ast_speech_unregister(), find_engine(), reload_config(), set_peer_defaults(), and sip_alloc().
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 560 of file chan_sip.c.
Referenced by AST_TEST_DEFINE(), 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 682 of file chan_sip.c.
Referenced by reload_config(), 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 683 of file chan_sip.c.
Referenced by reload_config(), 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 569 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Default language setting for new channels
Definition at line 679 of file chan_sip.c.
Referenced by reload_config(), set_peer_defaults(), and sip_show_settings().
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 692 of file chan_sip.c.
Referenced by build_peer(), reload_config(), 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 687 of file chan_sip.c.
Referenced by reload_config(), 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 688 of file chan_sip.c.
Referenced by reload_config(), set_peer_defaults(), sip_alloc(), and sip_show_settings().
char default_mwi_from[80] [static] |
Default caller ID for MWI updates
Definition at line 681 of file chan_sip.c.
Referenced by reload_config(), and sip_send_mwi_to_peer().
char default_notifymime[AST_MAX_EXTENSION] [static] |
Default MIME media type for MWI notify messages
Definition at line 684 of file chan_sip.c.
Referenced by reload_config(), sip_show_settings(), and transmit_notify_with_mwi().
char default_parkinglot[AST_MAX_CONTEXT] [static] |
Parkinglot
Definition at line 690 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 693 of file chan_sip.c.
Referenced by config_load(), config_parse_variables(), reload_config(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and temp_peer().
unsigned int default_primary_transport [static] |
Default primary Transport (enum sip_transport) for outbound connections to devices
Definition at line 695 of file chan_sip.c.
Referenced by build_peer(), reload_config(), set_peer_defaults(), and sip_show_settings().
const int DEFAULT_PUBLISH_EXPIRES = 3600 [static] |
Definition at line 941 of file chan_sip.c.
Referenced by determine_sip_publish_type(), and transmit_publish().
int default_qualify [static] |
Default Qualify= setting
Definition at line 686 of file chan_sip.c.
Referenced by build_peer(), reload_config(), set_peer_defaults(), and sip_show_settings().
struct ast_tls_config default_tls_cfg [static] |
Default TLS connection configuration.
Definition at line 2193 of file chan_sip.c.
Referenced by build_peer(), 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 694 of file chan_sip.c.
Referenced by build_peer(), reload_config(), set_peer_defaults(), and sip_show_settings().
char default_vmexten[AST_MAX_EXTENSION] [static] |
Default From Username on MWI updates
Definition at line 685 of file chan_sip.c.
Referenced by reload_config(), 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 1101 of file chan_sip.c.
Referenced by change_callid_pvt(), complete_sipch(), dialog_unlink_all(), do_monitor(), find_call(), get_sip_pvt_byid_locked(), load_module(), sip_alloc(), sip_show_channel(), sip_show_channels(), sip_show_channelstats(), sip_show_history(), sip_show_objects(), and unload_module().
struct ao2_container* dialogs_to_destroy |
This container holds the dialogs that will be destroyed immediately.
Definition at line 1091 of file chan_sip.c.
Referenced by dialog_needdestroy(), do_monitor(), and load_module().
struct _map_x_s dtmfstr[] [static] |
mapping between dtmf flags and strings
Definition at line 16877 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 730 of file chan_sip.c.
Referenced by __sip_destroy(), append_history_full(), and reload_config().
int esc_etag_counter [static] |
Used to create new entity IDs by ESCs.
Definition at line 940 of file chan_sip.c.
const int ESC_MAX_BUCKETS = 37 [static] |
Definition at line 975 of file chan_sip.c.
struct event_state_compositor event_state_compositors[] [static] |
The Event State Compositors.
An Event State Compositor is an entity which accepts PUBLISH requests and acts appropriately based on these requests.
The actual event_state_compositor structure is simply an ao2_container of sip_esc_entrys. When an incoming PUBLISH is received, we can match the appropriate sip_esc_entry using the entity ID of the incoming PUBLISH.
Referenced by destroy_escs(), get_esc(), and initialize_escs().
struct ast_sockaddr externaddr [static] |
our external IP address/port for SIP sessions. externaddr.sin_addr is only set when we know we might be behind a NAT, and this is done using a variety of (mutually exclusive) ways from the config file:
+ with "externaddr = host[:port]" we specify the address/port explicitly. The address is looked up only once when (re)loading the config file;
+ with "externhost = host[:port]" we do a similar thing, but the hostname is stored in externhost, and the hostname->IP mapping is refreshed every 'externrefresh' seconds;
Other variables (externhost, externexpire, externrefresh) are used to support the above functions. External IP address if we are behind NAT
Definition at line 1177 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), and sip_show_settings().
time_t externexpire [static] |
Expiration counter for re-resolving external host name in dynamic DNS
Definition at line 1181 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
char externhost[MAXHOSTNAMELEN] [static] |
External host name
Definition at line 1180 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), and sip_show_settings().
int externrefresh = 10 [static] |
Refresh timer for DNS-based external address (dyndns)
Definition at line 1182 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), and sip_show_settings().
uint16_t externtcpport [static] |
external tcp port
Definition at line 1183 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
uint16_t externtlsport [static] |
external tls port
Definition at line 1184 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
struct _map_x_s faxecmodes[] [static] |
int global_authfailureevents [static] |
Whether we send authentication failure manager events or not. Default no.
Definition at line 734 of file chan_sip.c.
Referenced by register_verify(), reload_config(), and sip_show_settings().
unsigned int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 738 of file chan_sip.c.
Referenced by reload_config(), 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 718 of file chan_sip.c.
Referenced by reload_config(), 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 726 of file chan_sip.c.
Referenced by dialog_initialize_rtp(), initialize_udptl(), reload_config(), and sip_show_settings().
unsigned int global_cos_sip [static] |
802.1p class of service for SIP packets
Definition at line 725 of file chan_sip.c.
Referenced by reload_config(), and sip_show_settings().
unsigned int global_cos_text [static] |
802.1p class of service for text RTP packets
Definition at line 728 of file chan_sip.c.
Referenced by reload_config(), and sip_show_settings().
unsigned int global_cos_video [static] |
802.1p class of service for video RTP packets
Definition at line 727 of file chan_sip.c.
Referenced by reload_config(), and sip_show_settings().
int global_dynamic_exclude_static = 0 [static] |
Exclude static peers from contact registrations
Definition at line 750 of file chan_sip.c.
Referenced by build_peer(), and reload_config().
struct ast_flags global_flags[3] = {{0}} [static] |
global SIP_ flags
Definition at line 770 of file chan_sip.c.
struct ast_jb_conf global_jbconf [static] |
Global jitterbuffer configuration
Definition at line 577 of file chan_sip.c.
int global_match_auth_username [static] |
Match auth username if available instead of From: Default off.
Definition at line 708 of file chan_sip.c.
Referenced by check_user_full(), reload_config(), and sip_show_settings().
int global_max_se [static] |
Highest threshold for session refresh interval
Definition at line 746 of file chan_sip.c.
Referenced by build_peer(), handle_request_invite(), reload_config(), set_peer_defaults(), sip_show_settings(), and st_get_se().
int global_min_se [static] |
Lowest threshold for session refresh interval
Definition at line 745 of file chan_sip.c.
Referenced by build_peer(), reload_config(), 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 711 of file chan_sip.c.
Referenced by reload_config(), sip_show_settings(), and sip_write().
int global_qualify_gap [static] |
Time between our group of peer pokes
Definition at line 740 of file chan_sip.c.
Referenced by reload_config(), and sip_poke_all_peers().
int global_qualify_peers [static] |
Number of peers to poke at a given time
Definition at line 741 of file chan_sip.c.
Referenced by reload_config(), and sip_poke_all_peers().
int global_qualifyfreq [static] |
Qualify frequency
Definition at line 739 of file chan_sip.c.
Referenced by build_peer(), reload_config(), set_peer_defaults(), and sip_show_settings().
int global_reg_timeout [static] |
Global time between attempts for outbound registrations
Definition at line 715 of file chan_sip.c.
Referenced by reload_config(), sip_show_settings(), and transmit_register().
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 716 of file chan_sip.c.
Referenced by reload_config(), sip_reg_timeout(), and sip_show_settings().
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 710 of file chan_sip.c.
Referenced by enable_dsp_detect(), reload_config(), and sip_show_settings().
int global_rtpholdtimeout [static] |
Time out call if no RTP during hold
Definition at line 713 of file chan_sip.c.
Referenced by build_peer(), check_user_full(), create_addr(), reload_config(), set_peer_defaults(), and sip_show_settings().
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 714 of file chan_sip.c.
Referenced by build_peer(), check_user_full(), create_addr(), reload_config(), set_peer_defaults(), and sip_show_settings().
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 712 of file chan_sip.c.
Referenced by build_peer(), check_user_full(), create_addr(), reload_config(), set_peer_defaults(), and sip_show_settings().
char global_sdpowner[AST_MAX_EXTENSION] [static] |
SDP owner name for the SIP channel
Definition at line 733 of file chan_sip.c.
Referenced by add_sdp(), reload_config(), and sip_show_settings().
char global_sdpsession[AST_MAX_EXTENSION] [static] |
SDP session name for the SIP channel
Definition at line 732 of file chan_sip.c.
Referenced by add_sdp(), reload_config(), and sip_show_settings().
int global_shrinkcallerid [static] |
enable or disable shrinking of caller id
Definition at line 717 of file chan_sip.c.
Referenced by check_peer_ok(), check_user_full(), get_pai(), get_rpid(), and reload_config().
enum st_mode global_st_mode [static] |
Mode of operation for Session-Timers
Definition at line 743 of file chan_sip.c.
Referenced by build_peer(), reload_config(), set_peer_defaults(), sip_show_settings(), and st_get_mode().
enum st_refresher global_st_refresher [static] |
Session-Timer refresher
Definition at line 744 of file chan_sip.c.
Referenced by build_peer(), reload_config(), set_peer_defaults(), sip_show_settings(), and st_get_refresher().
int global_store_sip_cause [static] |
Whether the MASTER_CHANNEL(HASH(SIP_CAUSE,[chan_name])) var should be set
Definition at line 748 of file chan_sip.c.
Referenced by do_monitor(), handle_incoming(), reload_config(), and sip_show_settings().
int global_t1 [static] |
T1 time
Definition at line 735 of file chan_sip.c.
Referenced by create_addr(), reload_config(), set_peer_defaults(), sip_alloc(), sip_scheddestroy(), and sip_show_settings().
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 736 of file chan_sip.c.
Referenced by build_peer(), check_peer_ok(), create_addr_from_peer(), reload_config(), and sip_show_settings().
int global_t38_maxdatagram [static] |
global T.38 FaxMaxDatagram override
Definition at line 771 of file chan_sip.c.
Referenced by handle_t38_options(), initialize_udptl(), reload_config(), set_peer_defaults(), and sip_show_settings().
int global_timer_b [static] |
Timer B - RFC 3261 Section 17.1.1.2
Definition at line 737 of file chan_sip.c.
Referenced by build_peer(), create_addr(), reload_config(), 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 722 of file chan_sip.c.
Referenced by dialog_initialize_rtp(), initialize_udptl(), reload_config(), and sip_show_settings().
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 721 of file chan_sip.c.
Referenced by reload_config(), and sip_show_settings().
unsigned int global_tos_text [static] |
IP type of service for text RTP packets
Definition at line 724 of file chan_sip.c.
Referenced by reload_config(), and sip_show_settings().
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 723 of file chan_sip.c.
Referenced by reload_config(), and sip_show_settings().
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 731 of file chan_sip.c.
Referenced by curl_instance_init(), initreqprep(), reload_config(), 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 827 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 1160 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), sip_alloc(), transmit_register(), and transmit_response_using_temp().
struct invstate2stringtable invitestate2string[] [static] |
Readable descriptions of device states.
Referenced by show_chanstats_cb().
struct io_context* io [static] |
The IO context
Definition at line 794 of file chan_sip.c.
List of local networks We store "localnet" addresses from the config file into an access list, marked as 'DENY', so the call to ast_apply_ha() will return AST_SENSE_DENY for 'local' addresses, and AST_SENSE_ALLOW for 'non local' (i.e. presumably public) addresses.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1192 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), sip_show_settings(), and unload_module().
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 559 of file chan_sip.c.
Referenced by handle_request_publish(), 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 1178 of file chan_sip.c.
Referenced by get_our_media_address(), and reload_config().
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 558 of file chan_sip.c.
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 788 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 782 of file chan_sip.c.
int mwi_expiry = DEFAULT_MWI_EXPIRY [static] |
Definition at line 561 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 778 of file chan_sip.c.
int network_change_event_sched_id = -1 [static] |
Definition at line 774 of file chan_sip.c.
struct ast_event_sub* network_change_event_subscription [static] |
subscription id for network change events
Definition at line 773 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Configuration file for sending Notify with CLI commands to reconfigure or reboot phones
Definition at line 580 of file chan_sip.c.
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 1198 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 1194 of file chan_sip.c.
Referenced by reload_config().
int ourport_tls [static] |
The port used for TCP/TLS connections
Definition at line 1195 of file chan_sip.c.
Referenced by reload_config().
struct ao2_container* peers [static] |
struct ao2_container* peers_by_ip [static] |
Definition at line 1111 of file chan_sip.c.
Referenced by build_peer(), expire_register(), find_peer(), load_module(), on_dns_update_peer(), parse_register_contact(), register_verify(), sip_prune_realtime(), sip_show_objects(), unlink_peer_from_tables(), and unlink_peers_from_tables().
struct ast_data_handler peers_data_provider [static] |
Initial value:
{ .version = AST_DATA_HANDLER_VERSION, .get = peers_data_provider_get }
Definition at line 30194 of file chan_sip.c.
unsigned int recordhistory [static] |
Record SIP history. Off by default
Definition at line 729 of file chan_sip.c.
Referenced by append_history_full(), reload_config(), 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 cleanup_all_regs(), load_module(), manager_show_registry(), reload_config(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().
int regobjs = 0 [static] |
Registry objects
Definition at line 767 of file chan_sip.c.
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 765 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 793 of file chan_sip.c.
Definition at line 832 of file chan_sip.c.
Referenced by cc_generic_monitor_request_cc(), create_addr(), launch_ha_netscript(), service_string_to_service_type(), sig_pri_handle_subcmds(), and sip_cc_monitor_request_cc().
const char* service_string |
Definition at line 833 of file chan_sip.c.
struct ast_cc_agent_callbacks sip_cc_agent_callbacks [static] |
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 698 of file chan_sip.c.
Referenced by __get_header(), __sip_subscribe_mwi_do(), _sip_show_peer(), add_header(), ast_sip_ouraddrfor(), build_peer(), change_hold_state(), check_user_full(), create_addr(), destroy_association(), do_magic_pickup(), find_call(), find_calling_channel(), get_also_info(), get_destination(), get_realm(), get_refer_info(), get_sip_pvt_byid_locked(), handle_incoming(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_options(), handle_request_refer(), handle_request_subscribe(), handle_response_invite(), handle_response_peerpoke(), initreqprep(), obproxy_get(), parse_register_contact(), parse_uri_legacy_check(), proxy_update(), realtime_update_peer(), ref_proxy(), reg_source_db(), register_peer_exten(), register_verify(), reload_config(), set_peer_defaults(), sip_alloc(), sip_new(), sip_poke_noanswer(), sip_request_call(), sip_set_rtp_peer(), sip_show_settings(), state_notify_build_xml(), transmit_register(), 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 30199 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 19349 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(), handle_response_info(), handle_response_message(), init_req(), initialize_initreq(), initreqprep(), method_match(), reqprep(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_scheddestroy(), and transmit_register().
struct ao2_container* sip_monitor_instances |
Definition at line 1836 of file chan_sip.c.
Referenced by cc_handle_publish_error(), handle_cc_notify(), handle_response_subscribe(), 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 790 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 791 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 2196 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 1596 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 1631 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 2207 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), 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 3040 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 19533 of file chan_sip.c.
Referenced by load_module(), and unload_module().
enum sip_debug_e sipdebug [static] |
Definition at line 801 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(), 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 807 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 19467 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 1150 of file chan_sip.c.
Referenced by do_monitor(), process_via(), reg_source_db(), sip_prepare_socket(), and sipsock_read().
int* sipsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 795 of file chan_sip.c.
Referenced by do_monitor().
int speerobjs = 0 [static] |
Static peers
Definition at line 764 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 853 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(), moh_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 16372 of file chan_sip.c.
Referenced by stmode2str(), and str2stmode().
struct _map_x_s strefreshers[] [static] |
Definition at line 16390 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 1107 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 563 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 776 of file chan_sip.c.