Mon Jun 27 16:51:07 2011

Asterisk developer's documentation


chan_sip.c File Reference

Implementation of Session Initiation Protocol. More...

#include "asterisk.h"
#include <signal.h>
#include <sys/signal.h>
#include <regex.h>
#include <inttypes.h>
#include "asterisk/network.h"
#include "asterisk/paths.h"
#include "asterisk/lock.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj2.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/monitor.h"
#include "asterisk/netsock2.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
#include "asterisk/ast_version.h"
#include "asterisk/event.h"
#include "asterisk/cel.h"
#include "asterisk/data.h"
#include "asterisk/aoc.h"
#include "sip/include/sip.h"
#include "sip/include/globals.h"
#include "sip/include/config_parser.h"
#include "sip/include/reqresp_parser.h"
#include "sip/include/sip_utils.h"
#include "sip/include/srtp.h"
#include "sip/include/sdp_crypto.h"
#include "asterisk/ccss.h"
#include "asterisk/xml.h"
#include "sip/include/dialog.h"
#include "sip/include/dialplan_functions.h"

Go to the source code of this file.

Data Structures

struct  ast_register_list
 The register list: Other SIP proxies we register with and receive calls from. More...
struct  ast_subscription_mwi_list
 The MWI subscription list. More...
struct  cfsip_methods
 The core structure to setup dialogs. We parse incoming messages by using structure and then route the messages according to the type. More...
struct  cfsubscription_types
 Subscription types that we support. We support
  • dialoginfo updates (really device status, not dialog info as was the original intent of the standard)
  • SIMPLE presence used for device status
  • Voicemail notification subscriptions.
More...
struct  domain_list
struct  epa_static_data_list
struct  event_state_compositor
 The Event State Compositors. More...
struct  invstate2stringtable
 Readable descriptions of device states. More...
struct  match_req_args
struct  sip_history_head
struct  sip_reasons
 Diversion header reasons. More...

Object counters @{

Bug:
These counters are not handled in a thread-safe way ast_atomic_fetchadd_int() should be used to modify these values.


#define append_history(p, event, fmt, args...)   append_history_full(p, "%-15s " fmt, event, ## args)
 Append to SIP dialog history.
#define CHECK_AUTH_BUF_INITLEN   256
#define check_request_transport(peer, tmpl)
 generic function for determining if a correct transport is being used to contact a peer
#define DATA_EXPORT_SIP_PEER(MEMBER)
#define FORMAT   "%-15.15s %-15.15s %-15.15s %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s %-10.10s\n"
#define FORMAT   "%-30.30s %-12.12s %-10.10s %-10.10s\n"
#define FORMAT   "%-15.15s %-11.11s %-8.8s %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf\n"
#define FORMAT   "%-39.39s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n"
#define FORMAT   "%-40.40s %-20.20s %-16.16s\n"
#define FORMAT   "%-25.25s %-39.39s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n"
#define FORMAT   "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"
#define FORMAT   "%-47.47s %-9.9s %-6.6s\n"
#define FORMAT   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT2   "%-15.15s %-15.15s %-15.15s %-15.15s %-7.7s %-15.15s %-10.10s %-10.10s\n"
#define FORMAT2   "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n"
#define FORMAT2   "%-39.39s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n"
#define FORMAT2   "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n"
#define FORMAT2   "%-47.47s %9.9s %6.6s\n"
#define FORMAT2   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT3   "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6s\n"
#define FORMAT4   "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6d\n"
#define sip_pvt_lock(x)   ao2_lock(x)
#define sip_pvt_trylock(x)   ao2_trylock(x)
#define sip_pvt_unlock(x)   ao2_unlock(x)
#define UNLINK(element, head, prev)
enum  match_req_res { SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, SIP_REQ_LOOP_DETECTED }
static const char * __get_header (const struct sip_request *req, const char *name, int *start)
static void __init_check_auth_buf (void)
static void __init_ts_temp_pvt (void)
 A per-thread temporary pvt structure.
static void __reg_module (void)
static int __set_address_from_contact (const char *fullcontact, struct ast_sockaddr *addr, int tcp)
int __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod)
 Acknowledges receipt of a packet and stops retransmission called with p locked.
static int __sip_autodestruct (const void *data)
 Kill a SIP dialog (called only by the scheduler) The scheduler has a reference to this dialog when p->autokillid != -1, and we are called using that reference. So if the event is not rescheduled, we need to call dialog_unref().
void __sip_destroy (struct sip_pvt *p, int lockowner, int lockdialoglist)
 Execute destruction of SIP dialog structure, release memory.
static int __sip_do_register (struct sip_registry *r)
 Register with SIP proxy.
void __sip_pretend_ack (struct sip_pvt *p)
 Pretend to ack all packets called with p locked.
static int __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, struct ast_str *data, int len, int fatal, int sipmethod)
 Transmit packet with retransmits.
int __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod)
 Acks receipt of packet, keep it around (used for provisional responses).
static int __sip_subscribe_mwi_do (struct sip_subscription_mwi *mwi)
 Actually setup an MWI subscription or resubscribe.
static int __sip_xmit (struct sip_pvt *p, struct ast_str *data, int len)
 Transmit SIP message Sends a SIP request or response on a given socket (in the pvt) Called by retrans_pkt, send_request, send_response and __sip_reliable_xmit.
static int __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Base transmit response function.
static void __unreg_module (void)
static char * _sip_qualify_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[])
 Send qualify message to peer from cli or manager. Mostly for debugging.
static char * _sip_show_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[])
 Show one peer in detail (main function).
static char * _sip_show_peers (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[])
 Execute sip show peers command.
static void * _sip_tcp_helper_thread (struct sip_pvt *pvt, struct ast_tcptls_session_instance *tcptls_session)
 SIP TCP thread management function This function reads from the socket, parses the packet into a request.
static void add_blank (struct sip_request *req)
 add a blank line if no body
static void add_cc_call_info_to_response (struct sip_pvt *p, struct sip_request *resp)
static void add_codec_to_sdp (const struct sip_pvt *p, format_t codec, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size)
 Add codec offer to SDP offer/answer body in INVITE or 200 OK.
static int add_content (struct sip_request *req, const char *line)
 Add content (not header) to SIP message.
static int add_digit (struct sip_request *req, char digit, unsigned int duration, int mode)
 Add DTMF INFO tone to sip message Mode = 0 for application/dtmf-relay (Cisco) 1 for application/dtmf.
static void add_diversion_header (struct sip_request *req, struct sip_pvt *pvt)
 Add "Diversion" header to outgoing message.
static int add_header (struct sip_request *req, const char *var, const char *value)
 Add header to SIP message.
static int add_header_max_forwards (struct sip_pvt *dialog, struct sip_request *req)
 Add 'Max-Forwards' header to SIP message.
static void add_noncodec_to_sdp (const struct sip_pvt *p, int format, struct ast_str **m_buf, struct ast_str **a_buf, int debug)
 Add RFC 2833 DTMF offer to SDP.
static void add_peer_mailboxes (struct sip_peer *peer, const char *value)
static void add_peer_mwi_subs (struct sip_peer *peer)
static struct sip_auth * add_realm_authentication (struct sip_auth *authlist, const char *configuration, int lineno)
 Add realm authentication in list.
static void add_route (struct sip_request *req, struct sip_route *route)
 Add route header into request per learned route.
static int add_rpid (struct sip_request *req, struct sip_pvt *p)
 Add Remote-Party-ID header to SIP message.
static enum sip_result add_sdp (struct sip_request *resp, struct sip_pvt *p, int oldsdp, int add_audio, int add_t38)
 Add Session Description Protocol message.
static int add_sip_domain (const char *domain, const enum domain_mode mode, const char *context)
 Add SIP domain to list of domains we are responsible for.
static int add_supported_header (struct sip_pvt *pvt, struct sip_request *req)
 Add "Supported" header to sip message. Since some options may be disabled in the config, the sip_pvt must be inspected to determine what is supported for this dialog.
static void add_tcodec_to_sdp (const struct sip_pvt *p, int codec, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size)
 Add text codec offer to SDP offer/answer body in INVITE or 200 OK.
static int add_text (struct sip_request *req, const char *text)
 Add text body to SIP message.
static struct ast_variable * add_var (const char *buf, struct ast_variable *list)
 implement the setvar config line
static void add_vcodec_to_sdp (const struct sip_pvt *p, format_t codec, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size)
 Add video codec offer to SDP offer/answer body in INVITE or 200 OK.
static int add_vidupdate (struct sip_request *req)
 add XML encoded media control with update
static int addr_is_multicast (const struct ast_sockaddr *addr)
 Check if an ip is an multicast IP. addr the address to check.
static void append_date (struct sip_request *req)
 Append date to SIP message.
static void append_history_full (struct sip_pvt *p, const char *fmt,...)
 Append to SIP dialog history with arg list.
static void append_history_va (struct sip_pvt *p, const char *fmt, va_list ap)
 Append to SIP dialog history with arg list.
static int apply_directmedia_ha (struct sip_pvt *p, const char *op)
 AST_DATA_STRUCTURE (sip_peer, DATA_EXPORT_SIP_PEER)
static void ast_quiet_chan (struct ast_channel *chan)
 Turn off generator data XXX Does this function belong in the SIP channel?
static void ast_sip_ouraddrfor (const struct ast_sockaddr *them, struct ast_sockaddr *us, struct sip_pvt *p)
 NAT fix - decide which IP address to use for Asterisk server?
static int ast_sockaddr_resolve_first (struct ast_sockaddr *addr, const char *name, int flag)
 Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr.
static int ast_sockaddr_resolve_first_af (struct ast_sockaddr *addr, const char *name, int flag, int family)
 Return the first entry from ast_sockaddr_resolve filtered by address family.
static int attempt_transfer (struct sip_dual *transferer, struct sip_dual *target)
 Attempt transfer of SIP call This fix for attended transfers on a local PBX.
static void auth_headers (enum sip_auth_type code, char **header, char **respheader)
 return the request and response heade for a 401 or 407 code
static int auto_congest (const void *arg)
 Scheduled congestion on a call. Only called by the scheduler, must return the reference when done.
static void build_callid_pvt (struct sip_pvt *pvt)
 Build SIP Call-ID value for a non-REGISTER transaction.
static void build_callid_registry (struct sip_registry *reg, const struct ast_sockaddr *ourip, const char *fromdomain)
 Build SIP Call-ID value for a REGISTER transaction.
static void build_contact (struct sip_pvt *p)
 Build contact header - the contact header we send out.
static struct sip_peer * build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only)
 Build peer from configuration (file or realtime static/dynamic).
static int build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len)
 Build reply digest.
static void build_route (struct sip_pvt *p, struct sip_request *req, int backwards)
 Build route list from Record-Route header.
static void build_via (struct sip_pvt *p)
 Build a Via header for a request.
static int cb_extensionstate (char *context, char *exten, int state, void *data)
 Callback for the devicestate notification (SUBSCRIBE) support subsystem.
static void cc_epa_destructor (void *data)
static int cc_esc_publish_handler (struct sip_pvt *pvt, struct sip_request *req, struct event_state_compositor *esc, struct sip_esc_entry *esc_entry)
static void cc_handle_publish_error (struct sip_pvt *pvt, const int resp, struct sip_request *req, struct sip_epa_entry *epa_entry)
static void change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly)
 Change hold state for a call.
static void change_redirecting_information (struct sip_pvt *p, struct sip_request *req, struct ast_party_redirecting *redirecting, struct ast_set_party_redirecting *update_redirecting, int set_call_forward)
 update redirecting information for a channel based on headers
static void change_t38_state (struct sip_pvt *p, int state)
 Change the T38 state on a SIP dialog.
static enum check_auth_result check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, const char *uri, enum xmittype reliable, int ignore)
 Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
static enum check_auth_result check_peer_ok (struct sip_pvt *p, char *of, struct sip_request *req, int sipmethod, struct ast_sockaddr *addr, struct sip_peer **authpeer, enum xmittype reliable, char *calleridname, char *uri2)
 Validate device authentication.
static void check_pendings (struct sip_pvt *p)
 Check pending actions on SIP call.
static void check_rtp_timeout (struct sip_pvt *dialog, time_t t)
 helper function for the monitoring thread -- seems to be called with the assumption that the dialog is locked
static int check_sip_domain (const char *domain, char *context, size_t len)
 check_sip_domain: Check if domain part of uri is local to our server
static int check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, const char *uri, enum xmittype reliable, struct ast_sockaddr *addr)
 Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced.
static enum check_auth_result check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, const char *uri, enum xmittype reliable, struct ast_sockaddr *addr, struct sip_peer **authpeer)
 Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests.
static void check_via (struct sip_pvt *p, struct sip_request *req)
 check Via: header for hostname, port and rport request/answer
static attribute_unused void check_via_response (struct sip_pvt *p, struct sip_request *req)
 check received= and rport= in a SIP response. If we get a response with received= and/or rport= in the Via: line, use them as 'p->ourip' (see RFC 3581 for rport, and RFC 3261 for received). Using these two fields SIP can produce the correct address and port in the SIP headers without the need for STUN. The address part is also reused for the media sessions. Note that ast_sip_ouraddrfor() still rewrites p->ourip if you specify externaddr/seternaddr/.
static void cleanup_stale_contexts (char *new, char *old)
 Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly.
static void clear_peer_mailboxes (struct sip_peer *peer)
static int clear_realm_authentication (struct sip_auth *authlist)
 Clear realm authentication list (at reload).
static void clear_sip_domains (void)
 Clear our domain list (at reload).
static char * complete_sip_peer (const char *word, int state, int flags2)
 Do completion on peer name.
static char * complete_sip_registered_peer (const char *word, int state, int flags2)
 Do completion on registered peer name.
static char * complete_sip_show_history (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show history' CLI.
static char * complete_sip_show_peer (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show peer' CLI.
static char * complete_sip_show_user (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show user' CLI.
static char * complete_sip_unregister (const char *line, const char *word, int pos, int state)
 Support routine for 'sip unregister' CLI.
static char * complete_sip_user (const char *word, int state)
 Do completion on user name.
static char * complete_sipch (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show channel' and 'sip show history' CLI This is in charge of generating all strings that match a prefix in the given position. As many functions of this kind, each invokation has O(state) time complexity so be careful in using it.
static char * complete_sipnotify (const char *line, const char *word, int pos, int state)
 Support routine for 'sip notify' CLI.
static int construct_pidf_body (enum sip_cc_publish_state state, char *pidf_body, size_t size, const char *presentity)
static int copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy all headers from one request to another.
static int copy_header (struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy one header field from one request to another.
static void copy_request (struct sip_request *dst, const struct sip_request *src)
 copy SIP request (mostly used to save request for responses)
static void copy_socket_data (struct sip_socket *to_sock, const struct sip_socket *from_sock)
static struct ast_variable * copy_vars (struct ast_variable *src)
 duplicate a list of channel variables,
static int copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy SIP VIA Headers from the request to the response.
static int create_addr (struct sip_pvt *dialog, const char *opeer, struct ast_sockaddr *addr, int newdialog, struct ast_sockaddr *remote_address)
 create address structure from device name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success
static int create_addr_from_peer (struct sip_pvt *dialog, struct sip_peer *peer)
 Create address structure from peer reference. This function copies data from peer to the dialog, so we don't have to look up the peer again from memory or database during the life time of the dialog.
static struct sip_epa_entry * create_epa_entry (const char *const event_package, const char *const destination)
static struct sip_esc_entry * create_esc_entry (struct event_state_compositor *esc, struct sip_request *req, const int expires)
static void create_new_sip_etag (struct sip_esc_entry *esc_entry, int is_linked)
static void deinit_req (struct sip_request *req)
 Deinitialize SIP response/request.
static void destroy_association (struct sip_peer *peer)
 Remove registration data from realtime database or AST/DB when registration expires.
static void destroy_escs (void)
static void destroy_mailbox (struct sip_mailbox *mailbox)
static int determine_firstline_parts (struct sip_request *req)
 Parse first line of incoming SIP request.
static enum sip_publish_type determine_sip_publish_type (struct sip_request *req, const char *const event, const char *const etag, const char *const expires, int *expires_int)
static int dialog_cmp_cb (void *obj, void *arg, int flags)
static int dialog_dump_func (void *userobj, void *arg, int flags)
static int dialog_find_multiple (void *obj, void *arg, int flags)
static int dialog_hash_cb (const void *obj, const int flags)
static int dialog_initialize_rtp (struct sip_pvt *dialog)
 Initialize RTP portion of a dialog.
static int dialog_needdestroy (void *dialogobj, void *arg, int flags)
 Match dialogs that need to be destroyed.
sip_pvt * dialog_ref_debug (struct sip_pvt *p, char *tag, char *file, int line, const char *func)
void * dialog_unlink_all (struct sip_pvt *dialog, int lockowner, int lockdialoglist)
 Unlink a dialog from the dialogs container, as well as any other places that it may be currently stored.
sip_pvt * dialog_unref_debug (struct sip_pvt *p, char *tag, char *file, int line, const char *func)
static void disable_dsp_detect (struct sip_pvt *p)
static int do_magic_pickup (struct ast_channel *channel, const char *extension, const char *context)
static void * do_monitor (void *data)
 The SIP monitoring thread.
static int do_proxy_auth (struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code, int sipmethod, int init)
 Add authentication on outbound SIP packet.
static int do_register_auth (struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code)
 Authenticate for outbound registration.
static void do_setnat (struct sip_pvt *p)
 Set nat mode on the various data sockets.
static const char * domain_mode_to_text (const enum domain_mode mode)
 Print domain mode to cli.
static const char * dtmfmode2str (int mode)
 Convert DTMF mode to printable string.
static void enable_dsp_detect (struct sip_pvt *p)
static int esc_cmp_fn (void *obj, void *arg, int flags)
static void esc_entry_destructor (void *obj)
static int esc_hash_fn (const void *obj, const int flags)
static int expire_register (const void *data)
 Expire registration of SIP peer.
static void extract_uri (struct sip_pvt *p, struct sip_request *req)
 Check Contact: URI of SIP message.
static const char * faxec2str (int faxec)
static int finalize_content (struct sip_request *req)
 Add 'Content-Length' header and content to SIP message.
static const char * find_alias (const char *name, const char *_default)
 Find compressed SIP alias.
static int find_by_callid_helper (void *obj, void *arg, int flags)
static int find_by_name (void *obj, void *arg, void *data, int flags)
static int find_by_notify_uri_helper (void *obj, void *arg, int flags)
static int find_by_subscribe_uri_helper (void *obj, void *arg, int flags)
static struct sip_pvt * find_call (struct sip_request *req, struct ast_sockaddr *addr, const int intended_method)
 find or create a dialog structure for an incoming SIP message. Connect incoming SIP message to current dialog or create new dialog structure Returns a reference to the sip_pvt object, remember to give it back once done. Called by handle_incoming(), sipsock_read
static int find_calling_channel (void *obj, void *arg, void *data, int flags)
 Find the channel that is causing the RINGING update.
const char * find_closing_quote (const char *start, const char *lim)
 Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote.
static struct sip_peer * find_peer (const char *peer, struct ast_sockaddr *addr, int realtime, int which_objects, int devstate_only, int transport)
 Locate device by name or ip address.
static struct sip_auth * find_realm_authentication (struct sip_auth *authlist, const char *realm)
 Find authentication for a specific realm.
static int find_sdp (struct sip_request *req)
 Determine whether a SIP message contains an SDP in its body.
static struct ast_cc_agent * find_sip_cc_agent_by_notify_uri (const char *const uri)
static struct ast_cc_agent * find_sip_cc_agent_by_original_callid (struct sip_pvt *pvt)
static struct ast_cc_agent * find_sip_cc_agent_by_subscribe_uri (const char *const uri)
static int find_sip_method (const char *msg)
 find_sip_method: Find SIP method from header
static int find_sip_monitor_instance_by_subscription_pvt (void *obj, void *arg, int flags)
static int find_sip_monitor_instance_by_suspension_entry (void *obj, void *arg, int flags)
static struct epa_static_data * find_static_data (const char *const event_package)
static struct cfsubscription_types * find_subscription_type (enum subscriptiontype subtype)
 Find subscription type in array.
static void free_old_route (struct sip_route *route)
 Remove route from route list.
static int func_check_sipdomain (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 Dial plan function to check if domain is local.
static int func_header_read (struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
 Read SIP header (dialplan function).
static int function_sipchaninfo_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 ${SIPCHANINFO()} Dialplan function - reads sip channel data
static int function_sippeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 ${SIPPEER()} Dialplan function - reads peer data
static char * generate_random_string (char *buf, size_t size)
 Generate 32 byte random string for callid's etc.
static char * generate_uri (struct sip_pvt *pvt, char *buf, size_t size)
static int get_address_family_filter (const struct ast_sockaddr *addr)
 Helper for dns resolution to filter by address family.
static int get_also_info (struct sip_pvt *p, struct sip_request *oreq)
 Call transfer support (old way, deprecated by the IETF).
static char * get_body (struct sip_request *req, char *name, char delimiter)
 Get a specific line from the message body.
static char * get_body_by_line (const char *line, const char *name, int nameLen, char delimiter)
 Reads one line of SIP message body.
static int get_cached_mwi (struct sip_peer *peer, int *new, int *old)
 Get cached MWI info.
static void get_crypto_attrib (struct sip_srtp *srtp, const char **a_crypto)
static enum sip_get_dest_result get_destination (struct sip_pvt *p, struct sip_request *oreq, int *cc_recall_core_id)
 Find out who the call is for. We use the request uri as a destination. This code assumes authentication has been done, so that the device (peer/user) context is already set.
static int get_domain (const char *str, char *domain, int len)
 Extract domain from SIP To/From header.
static struct event_state_compositor * get_esc (const char *const event_package)
static struct sip_esc_entry * get_esc_entry (const char *entity_tag, struct event_state_compositor *esc)
static const char * get_header (const struct sip_request *req, const char *name)
 Get header from SIP request.
static struct ast_variable * get_insecure_variable_from_config (struct ast_config *config)
static int get_ip_and_port_from_sdp (struct sip_request *req, const enum media_type media, struct ast_sockaddr *addr)
static int get_msg_text (char *buf, int len, struct sip_request *req, int addnewline)
 Get text out of a SIP MESSAGE packet.
static const char * get_name_from_variable (struct ast_variable *var, const char *newpeername)
static void get_our_media_address (struct sip_pvt *p, int needvideo, int needtext, struct ast_sockaddr *addr, struct ast_sockaddr *vaddr, struct ast_sockaddr *taddr, struct ast_sockaddr *dest, struct ast_sockaddr *vdest, struct ast_sockaddr *tdest)
 Set all IP media addresses for this call.
static int get_pai (struct sip_pvt *p, struct sip_request *req)
 Parse the parts of the P-Asserted-Identity header on an incoming packet. Returns 1 if a valid header is found and it is different from the current caller id.
static void get_pidf_body (struct sip_request *req, char *pidf_body, size_t size)
static int get_rdnis (struct sip_pvt *p, struct sip_request *oreq, char **name, char **number, int *reason)
 Get referring dnis.
static void get_realm (struct sip_pvt *p, const struct sip_request *req)
 Choose realm based on From header and then To header or use globaly configured realm. Realm from From/To header should be listed among served domains in config file: domain=...
static int get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req)
 Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure.
static int get_rpid (struct sip_pvt *p, struct sip_request *oreq)
 Get name, number and presentation from remote party id header, returns true if a valid header was found and it was different from the current caller id.
static const char * get_sdp_iterate (int *start, struct sip_request *req, const char *name)
 Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number.
static char get_sdp_line (int *start, int stop, struct sip_request *req, const char **value)
 Fetches the next valid SDP line between the 'start' line (inclusive) and the 'stop' line (exclusive). Returns the type ('a', 'c', ...) and matching line in reference 'start' is updated with the next line number.
static struct sip_pvt * get_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag)
 Lock dialog lock and find matching pvt lock.
static const char * get_srv_protocol (enum sip_transport t)
 Return protocol string for srv dns query.
static const char * get_srv_service (enum sip_transport t)
 Return service string for srv dns query.
static const char * get_transport (enum sip_transport t)
 Return transport as string.
static const char * get_transport_list (unsigned int transports)
 Return configuration of transports for a device.
static const char * get_transport_pvt (struct sip_pvt *p)
 Return transport of dialog.
static int get_transport_str2enum (const char *transport)
 Return int representing a bit field of transport types found in const char *transport.
static const char * gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize)
 Get tag from packet.
static int handle_cc_notify (struct sip_pvt *pvt, struct sip_request *req)
static int handle_cc_subscribe (struct sip_pvt *p, struct sip_request *req)
static int handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v)
 Handle flag-type options common to configuration of devices - peers.
static int handle_incoming (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int *recount, int *nounlock)
 Handle incoming SIP requests (methods).
static int handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct ast_sockaddr *addr, int *nounlock)
 Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. Used only once. XXX 'ignore' is unused.
static int handle_request_bye (struct sip_pvt *p, struct sip_request *req)
 Handle incoming BYE request.
static int handle_request_cancel (struct sip_pvt *p, struct sip_request *req)
 Handle incoming CANCEL request.
static int handle_request_do (struct sip_request *req, struct ast_sockaddr *addr)
 Handle incoming SIP message - request or response.
static void handle_request_info (struct sip_pvt *p, struct sip_request *req)
 Receive SIP INFO Message.
static int handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct ast_sockaddr *addr, int *recount, const char *e, int *nounlock)
 Handle incoming INVITE request.
static int handle_request_message (struct sip_pvt *p, struct sip_request *req)
 Handle incoming MESSAGE request.
static int handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int seqno, const char *e)
 Handle incoming notifications.
static int handle_request_options (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e)
 Handle incoming OPTIONS request An OPTIONS request should be answered like an INVITE from the same UA, including SDP.
static int handle_request_publish (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const int seqno, const char *uri)
static int handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, int *nounlock)
static int handle_request_register (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e)
 Handle incoming REGISTER request.
static int handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, int seqno, const char *e)
 Handle incoming SUBSCRIBE request.
static int handle_request_update (struct sip_pvt *p, struct sip_request *req)
 bare-bones support for SIP UPDATE
static void handle_response (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
 Handle SIP response in dialogue.
static void handle_response_invite (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
 Handle SIP response to INVITE dialogue.
static void handle_response_notify (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
static void handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req)
 Handle qualification responses (OPTIONS).
static void handle_response_publish (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
static void handle_response_refer (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
static int handle_response_register (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
 Handle responses on REGISTER to services.
static void handle_response_subscribe (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
static void handle_response_update (struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
 Handle authentication challenge for SIP UPDATE.
static int handle_sip_publish_initial (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const int expires)
static int handle_sip_publish_modify (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag, const int expires)
static int handle_sip_publish_refresh (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag, const int expires)
static int handle_sip_publish_remove (struct sip_pvt *p, struct sip_request *req, struct event_state_compositor *esc, const char *const etag)
static int handle_t38_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v, int *maxdatagram)
 Handle T.38 configuration options common to users and peers.
const char * hangup_cause2sip (int cause)
 Convert Asterisk hangup causes to SIP codes.
int hangup_sip2cause (int cause)
 Convert SIP hangup causes to Asterisk hangup causes.
static int init_req (struct sip_request *req, int sipmethod, const char *recip)
 Initialize SIP request.
static int init_resp (struct sip_request *resp, const char *msg)
 Initialize SIP response, based on SIP request.
static int initialize_escs (void)
static void initialize_initreq (struct sip_pvt *p, struct sip_request *req)
 Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog.
static void initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, const char *const explicit_uri)
 Initiate new SIP request to peer/user.
static const char * insecure2str (int mode)
 Convert Insecure setting to printable string.
static int interpret_t38_parameters (struct sip_pvt *p, const struct ast_control_t38_parameters *parameters)
 Helper function which updates T.38 capability information and triggers a reinvite.
static int is_method_allowed (unsigned int *allowed_methods, enum sipmethod method)
 Check if method is allowed for a device or a dialog.
static void list_route (struct sip_route *route)
 List all routes - mostly for debugging.
static int load_module (void)
 PBX load module - initialization.
static int local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno, int *nounlock)
 Find all call legs and bridge transferee with target called from handle_request_refer.
static int lws2sws (char *msgbuf, int len)
 Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.
static void make_our_tag (char *tagbuf, size_t len)
 Make our SIP dialog tag.
static int manager_show_registry (struct mansession *s, const struct message *m)
 Show SIP registrations in the manager API.
static int manager_sip_qualify_peer (struct mansession *s, const struct message *m)
 Qualify SIP peers in the manager API.
static int manager_sip_show_peer (struct mansession *s, const struct message *m)
 Show SIP peers in the manager API.
static int manager_sip_show_peers (struct mansession *s, const struct message *m)
 Show SIP peers in the manager API.
static int manager_sipnotify (struct mansession *s, const struct message *m)
static int map_s_x (const struct _map_x_s *table, const char *s, int errorvalue)
 map from a string to an integer value, case insensitive. If no match is found, return errorvalue.
static const char * map_x_s (const struct _map_x_s *table, int x, const char *errorstring)
 map from an integer value to a string. If no match is found, return errorstring
static void mark_method_allowed (unsigned int *allowed_methods, enum sipmethod method)
static void mark_method_unallowed (unsigned int *allowed_methods, enum sipmethod method)
static void mark_parsed_methods (unsigned int *methods, char *methods_str)
static enum match_req_res match_req_to_dialog (struct sip_pvt *sip_pvt_ptr, struct match_req_args *arg)
static int method_match (enum sipmethod id, const char *name)
 returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send
static void mwi_event_cb (const struct ast_event *event, void *userdata)
 Receive MWI events that we have subscribed to.
static void network_change_event_cb (const struct ast_event *, void *)
static int network_change_event_sched_cb (const void *data)
static void network_change_event_subscribe (void)
static void network_change_event_unsubscribe (void)
static struct sip_proxy * obproxy_get (struct sip_pvt *dialog, struct sip_peer *peer)
 Get default outbound proxy or global proxy.
static unsigned int parse_allowed_methods (struct sip_request *req)
 parse the Allow header to see what methods the endpoint we are communicating with allows.
static void parse_copy (struct sip_request *dst, const struct sip_request *src)
 Copy SIP request, parse it.
static int parse_minse (const char *p_hdrval, int *const p_interval)
 Session-Timers: Function for parsing Min-SE header.
static void parse_moved_contact (struct sip_pvt *p, struct sip_request *req, char **name, char **number, int set_call_forward)
 Parse 302 Moved temporalily response.
static int parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req)
 Save contact header for 200 OK on INVITE.
static enum parse_register_result parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req)
 Parse contact header and save registration (peer registration).
static int parse_request (struct sip_request *req)
 Parse a SIP message.
static int parse_session_expires (const char *p_hdrval, int *const p_interval, enum st_refresher *const p_ref)
 Session-Timers: Function for parsing Session-Expires header.
static int peer_cmp_cb (void *obj, void *arg, int flags)
static int peer_dump_func (void *userobj, void *arg, int flags)
static int peer_hash_cb (const void *obj, const int flags)
static int peer_ipcmp_cb (void *obj, void *arg, int flags)
static int peer_iphash_cb (const void *obj, const int flags)
static int peer_is_marked (void *peerobj, void *arg, int flags)
static void peer_mailboxes_to_str (struct ast_str **mailbox_str, struct sip_peer *peer)
 list peer mailboxes to CLI
static int peer_markall_func (void *device, void *arg, int flags)
static int peer_status (struct sip_peer *peer, char *status, int statuslen)
int peercomparefunc (const void *a, const void *b)
static int peers_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root)
static int pidf_validate_presence (struct ast_xml_doc *doc)
static int pidf_validate_tuple (struct ast_xml_node *tuple_node)
unsigned int port_str2int (const char *pt, unsigned int standard)
 converts ascii port to int representation. If no pt buffer is provided or the pt has errors when being converted to an int value, the port provided as the standard is used.
static void print_codec_to_cli (int fd, struct ast_codec_pref *pref)
 Print codec list from preference to CLI/manager.
static void print_group (int fd, ast_group_t group, int crlf)
 Print call group and pickup group.
static void proc_422_rsp (struct sip_pvt *p, struct sip_request *rsp)
 Handle 422 response to INVITE with session-timer requested.
static int proc_session_timer (const void *vp)
 Session-Timers: Process session refresh timeout event.
static int process_crypto (struct sip_pvt *p, struct ast_rtp_instance *rtp, struct sip_srtp **srtp, const char *a)
static void process_request_queue (struct sip_pvt *p, int *recount, int *nounlock)
static int process_sdp (struct sip_pvt *p, struct sip_request *req, int t38action)
 Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp().
static int process_sdp_a_audio (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newaudiortp, int *last_rtpmap_codec)
static int process_sdp_a_image (const char *a, struct sip_pvt *p)
static int process_sdp_a_sendonly (const char *a, int *sendonly)
static int process_sdp_a_text (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newtextrtp, char *red_fmtp, int *red_num_gen, int *red_data_pt, int *last_rtpmap_codec)
static int process_sdp_a_video (const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newvideortp, int *last_rtpmap_codec)
static int process_sdp_c (const char *c, struct ast_sockaddr *addr)
static int process_sdp_o (const char *o, struct sip_pvt *p)
static int process_via (struct sip_pvt *p, const struct sip_request *req)
 Process the Via header according to RFC 3261 section 18.2.2.
static int proxy_update (struct sip_proxy *proxy)
static int publish_expire (const void *data)
static void pvt_set_needdestroy (struct sip_pvt *pvt, const char *reason)
static int queue_request (struct sip_pvt *p, const struct sip_request *req)
static struct sip_peer * realtime_peer (const char *newpeername, struct ast_sockaddr *addr, int devstate_only, int which_objects)
 realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf Checks the "sipregs" realtime family from extconfig.conf if it's configured. This returns a pointer to a peer and because we use build_peer, we can rest assured that the refcount is bumped.
static void realtime_update_peer (const char *peername, struct ast_sockaddr *addr, const char *defaultuser, const char *fullcontact, const char *useragent, int expirey, unsigned short deprecated_username, int lastms)
 Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.
static void receive_message (struct sip_pvt *p, struct sip_request *req)
 Receive SIP MESSAGE method messages.
static struct sip_peer * ref_peer (struct sip_peer *peer, char *tag)
static void ref_proxy (struct sip_pvt *pvt, struct sip_proxy *proxy)
 maintain proper refcounts for a sip_pvt's outboundproxy
static const char * referstatus2str (enum referstatus rstatus)
 Convert transfer status to string.
static void reg_source_db (struct sip_peer *peer)
 Get registration details from Asterisk DB.
static void register_peer_exten (struct sip_peer *peer, int onoff)
 Automatically add peer extension to dial plan.
static enum check_auth_result register_verify (struct sip_pvt *p, struct ast_sockaddr *addr, struct sip_request *req, const char *uri)
 Verify registration of user
  • Registration is done in several steps, first a REGISTER without auth to get a challenge (nonce) then a second one with auth
  • Registration requests are only matched with peers that are marked as "dynamic".

static struct sip_registry * registry_addref (struct sip_registry *reg, char *tag)
 Add object reference to SIP registry.
static void * registry_unref (struct sip_registry *reg, char *tag)
static const char * regstate2str (enum sipregistrystate regstate)
 Convert registration state status to string.
static int reload (void)
 Part of Asterisk module interface.
static int reload_config (enum channelreloadreason reason)
 Re-read SIP.conf config file.
static char * remove_uri_parameters (char *uri)
static int reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len)
 reply to authentication for outbound registrations
static int reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch)
 Initialize a SIP request message (not the initial one in a dialog).
static int resp_needs_contact (const char *msg, enum sipmethod method)
 Test if this response needs a contact header.
static int respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Prepare SIP response packet.
static int restart_monitor (void)
 Start the channel monitor thread.
static void restart_session_timer (struct sip_pvt *p)
 Session-Timers: Restart session timer.
static int retrans_pkt (const void *data)
 Retransmit SIP message if no answer (Called from scheduler).
static int scheduler_process_request_queue (const void *data)
static int send_provisional_keepalive (const void *data)
static int send_provisional_keepalive_full (struct sip_pvt *pvt, int with_sdp)
static int send_provisional_keepalive_with_sdp (const void *data)
static int send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno)
 Send SIP Request to the other part of the dialogue.
static int send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno)
 Transmit response on SIP request.
static enum ast_cc_service_type service_string_to_service_type (const char *const service_string)
static int set_address_from_contact (struct sip_pvt *pvt)
 Change the other partys IP address based on given contact.
static void set_destination (struct sip_pvt *p, char *uri)
 Set destination from SIP URI.
static void set_insecure_flags (struct ast_flags *flags, const char *value, int lineno)
 Parse insecure= setting in sip.conf and set flags according to setting.
static void set_nonce_randdata (struct sip_pvt *p, int forceupdate)
 builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one.
static void set_peer_defaults (struct sip_peer *peer)
 Set peer defaults before configuring specific configurations.
static unsigned int set_pvt_allowed_methods (struct sip_pvt *pvt, struct sip_request *req)
static void set_socket_transport (struct sip_socket *socket, int transport)
static void set_t38_capabilities (struct sip_pvt *p)
 Set the global T38 capabilities on a SIP dialog structure.
static int setup_srtp (struct sip_srtp **srtp)
static int show_channels_cb (void *__cur, void *__arg, int flags)
 callback for show channel|subscription
static int show_chanstats_cb (void *__cur, void *__arg, int flags)
 Callback for show_chanstats.
static int sip_addheader (struct ast_channel *chan, const char *data)
 Add a SIP header to an outbound INVITE.
sip_pvt * sip_alloc (ast_string_field callid, struct ast_sockaddr *addr, int useglobal_nat, const int intended_method, struct sip_request *req)
 Allocate sip_pvt structure, set defaults and link in the container. Returns a reference to the object so whoever uses it later must remember to release the reference.
static void sip_alreadygone (struct sip_pvt *dialog)
 Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.
static int sip_answer (struct ast_channel *ast)
 sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface
static int sip_call (struct ast_channel *ast, char *dest, int timeout)
 Initiate SIP call from PBX used from the dial() application.
int sip_cancel_destroy (struct sip_pvt *p)
 Cancel destruction of SIP dialog. Be careful as this also absorbs the reference - if you call it from within the scheduler, this might be the last reference.
static void sip_cc_agent_destructor (struct ast_cc_agent *agent)
static int sip_cc_agent_init (struct ast_cc_agent *agent, struct ast_channel *chan)
static int sip_cc_agent_recall (struct ast_cc_agent *agent)
static void sip_cc_agent_respond (struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason)
static int sip_cc_agent_start_monitoring (struct ast_cc_agent *agent)
static int sip_cc_agent_start_offer_timer (struct ast_cc_agent *agent)
static int sip_cc_agent_status_request (struct ast_cc_agent *agent)
static int sip_cc_agent_stop_offer_timer (struct ast_cc_agent *agent)
static int sip_cc_monitor_cancel_available_timer (struct ast_cc_monitor *monitor, int *sched_id)
static void sip_cc_monitor_destructor (void *private_data)
static int sip_cc_monitor_request_cc (struct ast_cc_monitor *monitor, int *available_timer_id)
static int sip_cc_monitor_suspend (struct ast_cc_monitor *monitor)
static int sip_cc_monitor_unsuspend (struct ast_cc_monitor *monitor)
static int sip_check_authtimeout (time_t start)
 Check if the authtimeout has expired.
static char * sip_cli_notify (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Cli command to send SIP notify to peer.
static int sip_debug_test_addr (const struct ast_sockaddr *addr)
 See if we pass debug IP filter.
static int sip_debug_test_pvt (struct sip_pvt *p)
 Test PVT for debugging output.
sip_pvt * sip_destroy (struct sip_pvt *p)
 Destroy SIP call structure. Make it return NULL so the caller can do things like foo = sip_destroy(foo); and reduce the chance of bugs due to dangling pointers.
static void sip_destroy_fn (void *p)
static void sip_destroy_peer (struct sip_peer *peer)
 Destroy peer object from memory.
static void sip_destroy_peer_fn (void *peer)
static int sip_devicestate (void *data)
 Part of PBX channel interface.
static char * sip_do_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Turn on SIP debugging (CLI command).
static char * sip_do_debug_ip (int fd, const char *arg)
 Enable SIP Debugging for a single IP.
static char * sip_do_debug_peer (int fd, const char *arg)
 Turn on SIP debugging for a given peer.
static int sip_do_reload (enum channelreloadreason reason)
 Reload module.
static int sip_dtmfmode (struct ast_channel *chan, const char *data)
 Set the DTMFmode for an outbound SIP call (application).
static void sip_dump_history (struct sip_pvt *dialog)
 Dump SIP history to debug log file at end of lifespan for SIP dialog.
static int sip_epa_register (const struct epa_static_data *static_data)
static int sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links
static const char * sip_get_callid (struct ast_channel *chan)
 Deliver SIP call ID for the call.
static int sip_get_cc_information (struct sip_request *req, char *subscribe_uri, size_t size, enum ast_cc_service_type *service)
static format_t sip_get_codec (struct ast_channel *chan)
static enum ast_rtp_glue_result sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance)
static enum ast_rtp_glue_result sip_get_trtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance)
static struct ast_udptl * sip_get_udptl_peer (struct ast_channel *chan)
static enum ast_rtp_glue_result sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance)
static void sip_handle_cc (struct sip_pvt *pvt, struct sip_request *req, enum ast_cc_service_type service)
static int sip_hangup (struct ast_channel *ast)
 sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup
static int sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen)
 Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc.
static int sip_is_xml_parsable (void)
static int sip_monitor_instance_cmp_fn (void *obj, void *arg, int flags)
static void sip_monitor_instance_destructor (void *data)
static int sip_monitor_instance_hash_fn (const void *obj, const int flags)
static struct sip_monitor_instance * sip_monitor_instance_init (int core_id, const char *const subscribe_uri, const char *const peername, const char *const device_name)
static const char * sip_nat_mode (const struct sip_pvt *p)
 Display SIP nat mode.
static struct ast_channel * sip_new (struct sip_pvt *i, int state, const char *title, const char *linkedid)
 Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.
static int sip_notify_allocate (struct sip_pvt *p)
 Allocate SIP refer structure.
static int sip_offer_timer_expire (const void *data)
static int sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno, char *parkexten)
 Park a call using the subsystem in res_features.c This is executed in a separate thread.
static void * sip_park_thread (void *stuff)
 Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup.
static void sip_peer_hold (struct sip_pvt *p, int hold)
 Change onhold state of a peer using a pvt structure.
static int sip_pidf_validate (struct sip_request *req, struct ast_xml_doc **pidf_doc)
 Makes sure that body is properly formatted PIDF.
static void sip_poke_all_peers (void)
 Send a poke to all known peers.
static int sip_poke_noanswer (const void *data)
 React to lack of answer to Qualify poke.
static int sip_poke_peer (struct sip_peer *peer, int force)
 Check availability of peer, also keep NAT open.
static int sip_poke_peer_s (const void *data)
 Poke peer (send qualify to check if peer is alive and well).
static int sip_prepare_socket (struct sip_pvt *p)
static char * sip_prune_realtime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Remove temporary realtime objects from memory (CLI).
static char * sip_qualify_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Send an OPTIONS packet to a SIP peer.
static int sip_queryoption (struct ast_channel *chan, int option, void *data, int *datalen)
 Query an option on a SIP dialog.
static struct ast_frame * sip_read (struct ast_channel *ast)
 Read SIP RTP from channel.
static struct ast_sockaddr * sip_real_dst (const struct sip_pvt *p)
 The real destination address for a write.
static const char * sip_reason_code_to_str (enum AST_REDIRECTING_REASON code)
static enum AST_REDIRECTING_REASON sip_reason_str_to_code (const char *text)
static int sip_refer_allocate (struct sip_pvt *p)
 Allocate SIP refer structure.
static int sip_reg_timeout (const void *data)
 Registration timeout, register again Registered as a timeout handler during transmit_register(), to retransmit the packet if a reply does not come back. This is called by the scheduler so the event is not pending anymore when we are called.
static int sip_register (const char *value, int lineno)
 create sip_registry object from register=> line in sip.conf and link into reg container
static void sip_register_tests (void)
 SIP test registration.
static void sip_registry_destroy (struct sip_registry *reg)
 Destroy registry object Objects created with the register= statement in static configuration.
static int sip_reinvite_retry (const void *data)
 Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler.
static char * sip_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Force reload of module from cli.
static int sip_removeheader (struct ast_channel *chan, const char *data)
 Remove SIP headers added previously with SipAddHeader application.
static struct ast_channel * sip_request_call (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
 PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
static int sip_reregister (const void *data)
 Update registration with SIP Proxy. Called from the scheduler when the previous registration expires, so we don't have to cancel the pending event. We assume the reference so the sip_registry is valid, since it is stored in the scheduled event anyways.
static struct ast_frame * sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect)
 Read RTP from network.
void sip_scheddestroy (struct sip_pvt *p, int ms)
 Schedule destruction of SIP dialog.
void sip_scheddestroy_final (struct sip_pvt *p, int ms)
 Schedule final destruction of SIP dialog. This can not be canceled. This function is used to keep a dialog around for a period of time in order to properly respond to any retransmits.
static void sip_send_all_mwi_subscriptions (void)
 Send all MWI subscriptions.
static void sip_send_all_registers (void)
 Send all known registrations.
static int sip_send_mwi_to_peer (struct sip_peer *peer, const struct ast_event *event, int cache_only)
 Send message waiting indication to alert peer that they've got voicemail.
static int sip_senddigit_begin (struct ast_channel *ast, char digit)
static int sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration)
 Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously.
static int sip_sendhtml (struct ast_channel *chan, int subclass, const char *data, int datalen)
 Send message with Access-URL header, if this is an HTML URL only!
static int sip_sendtext (struct ast_channel *ast, const char *text)
 Send SIP MESSAGE text within a call Called from PBX core sendtext() application.
static char * sip_set_history (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Enable/Disable SIP History logging (CLI).
static void sip_set_redirstr (struct sip_pvt *p, char *reason)
 Translate referring cause.
static int sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, format_t codecs, int nat_active)
static int sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl)
static int sip_setoption (struct ast_channel *chan, int option, void *data, int datalen)
 Set an option on a SIP dialog.
static char * sip_show_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show details of one active dialog.
static char * sip_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI for show channels or subscriptions. This is a new-style CLI handler so a single function contains the prototype for the function, the 'generator' to produce multiple entries in case it is required, and the actual handler for the command.
static char * sip_show_channelstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 SIP show channelstats CLI (main function).
static char * sip_show_domains (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command to list local domains.
static char * sip_show_history (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show history details of one dialog.
static char * sip_show_inuse (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI Command to show calls within limits set by call_limit.
static char * sip_show_mwi (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * sip_show_objects (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 List all allocated SIP Objects (realtime or static).
static char * sip_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show one peer in detail.
static char * sip_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI Show Peers command.
static char * sip_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show SIP Registry (registrations with other SIP proxies.
static char * sip_show_sched (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * sip_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 List global settings for the SIP channel.
static char * sip_show_tcp (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show active TCP connections.
static char * sip_show_user (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show one user in detail.
static char * sip_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI Command 'SIP Show Users'.
static int sip_sipredirect (struct sip_pvt *p, const char *dest)
 Transfer call before connect with a 302 redirect.
static struct sip_st_dlg * sip_st_alloc (struct sip_pvt *const p)
 Allocate Session-Timers struct w/in dialog.
static int sip_standard_port (enum sip_transport type, int port)
 Returns the port to use for this socket.
static int sip_subscribe_mwi (const char *value, int lineno)
 Parse mwi=> line in sip.conf and add to list.
static void sip_subscribe_mwi_destroy (struct sip_subscription_mwi *mwi)
 Destroy MWI subscription object.
static int sip_subscribe_mwi_do (const void *data)
 Send a subscription or resubscription for MWI.
static int sip_t38_abort (const void *data)
 Called to deny a T38 reinvite if the core does not respond to our request.
static struct ast_tcptls_session_instance * sip_tcp_locate (struct ast_sockaddr *s)
 Find thread for TCP/TLS session (based on IP/Port.
static void * sip_tcp_worker_fn (void *data)
 SIP TCP connection handler.
static void sip_tcptls_client_args_destructor (void *obj)
static int sip_tcptls_write (struct ast_tcptls_session_instance *tcptls_session, const void *buf, size_t len)
 used to indicate to a tcptls thread that data is ready to be written
static struct sip_threadinfo * sip_threadinfo_create (struct ast_tcptls_session_instance *tcptls_session, int transport)
 creates a sip_threadinfo object and links it into the threadt table.
static void sip_threadinfo_destructor (void *obj)
static int sip_transfer (struct ast_channel *ast, const char *dest)
 Transfer SIP call.
static char * sip_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Unregister (force expiration) a SIP peer in the registry via CLI.
static void sip_unregister_tests (void)
 SIP test registration.
static int sip_write (struct ast_channel *ast, struct ast_frame *frame)
 Send frame to media channel (rtp).
static int sipsock_read (int *id, int fd, short events, void *ignore)
 Read data from SIP UDP socket.
static enum st_mode st_get_mode (struct sip_pvt *p)
 Get the session-timer mode.
static enum st_refresher st_get_refresher (struct sip_pvt *p)
 Get the entity (UAC or UAS) that's acting as the session-timer refresher.
static int st_get_se (struct sip_pvt *p, int max)
 Get Max or Min SE (session timer expiry).
static void start_session_timer (struct sip_pvt *p)
 Session-Timers: Start session timer.
static void state_notify_build_xml (int state, int full, const char *exten, const char *context, struct ast_str **tmp, struct sip_pvt *p, int subscribed, const char *mfrom, const char *mto)
 Builds XML portion of NOTIFY messages for presence or dialog updates.
static const char * stmode2str (enum st_mode m)
static void stop_media_flows (struct sip_pvt *p)
 Immediately stop RTP, VRTP and UDPTL as applicable.
static void stop_session_timer (struct sip_pvt *p)
 Session-Timers: Stop session timer.
static int str2dtmfmode (const char *str)
 maps a string to dtmfmode, returns -1 on error
static enum st_mode str2stmode (const char *s)
static enum st_refresher str2strefresher (const char *s)
static const char * strefresher2str (enum st_refresher r)
static const char * subscription_type2str (enum subscriptiontype subtype)
 Show subscription type in string format.
static unsigned int t38_get_rate (enum ast_control_t38_rate rate)
 Get Max T.38 Transmission rate from T38 capabilities.
static void tcptls_packet_destructor (void *obj)
static struct sip_peer * temp_peer (const char *name)
 Create temporary peer (used in autocreatepeer mode).
static void temp_pvt_cleanup (void *)
static int temp_pvt_init (void *)
static char * terminate_uri (char *uri)
static int threadinfo_locate_cb (void *obj, void *arg, int flags)
static int threadt_cmp_cb (void *obj, void *arg, int flags)
static int threadt_hash_cb (const void *obj, const int flags)
static char * transfermode2str (enum transfermodes mode)
 Convert transfer mode to text string.
static int transmit_cc_notify (struct ast_cc_agent *agent, struct sip_pvt *subscription, enum sip_cc_notify_state state)
static void transmit_fake_auth_response (struct sip_pvt *p, int sipmethod, struct sip_request *req, enum xmittype reliable)
 Send a fake 401 Unauthorized response when the administrator wants to hide the names of local devices from fishers.
static int transmit_info_with_aoc (struct sip_pvt *p, struct ast_aoc_decoded *decoded)
 Send SIP INFO advice of charge message.
static int transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration)
 Send SIP INFO dtmf message, see Cisco documentation on cisco.com.
static int transmit_info_with_vidupdate (struct sip_pvt *p)
 Send SIP INFO with video update request.
static int transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init, const char *const explicit_uri)
 Build REFER/INVITE/OPTIONS/SUBSCRIBE message and transmit it.
static int transmit_message_with_text (struct sip_pvt *p, const char *text)
 Transmit text with SIP MESSAGE method.
static int transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, const char *vmexten)
 Notify user of messages waiting in voicemail (RFC3842).
static int transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate)
 Notify a transferring party of the status of transfer (RFC3515).
static int transmit_provisional_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, int with_sdp)
static int transmit_publish (struct sip_epa_entry *epa_entry, enum sip_publish_type publish_type, const char *const explicit_uri)
static int transmit_refer (struct sip_pvt *p, const char *dest)
 Transmit SIP REFER message (initiated by the transfer() dialplan application.
static int transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader)
 Transmit register to SIP proxy or UA auth = NULL on the initial registration (from sip_reregister()).
static int transmit_reinvite_with_sdp (struct sip_pvt *p, int t38version, int oldsdp)
 Transmit reinvite with SDP.
static int transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
 Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).
static int transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
 Transmit SIP request, auth added.
static int transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, no retransmits.
static int transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK.
static int transmit_response_using_temp (ast_string_field callid, struct ast_sockaddr *addr, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg)
 Transmit response, no retransmits, using a temporary pvt structure.
static int transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Append Accept header, content length before transmitting response.
static int transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale)
 Respond with authorization request.
static int transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Append date and content length before transmitting response.
static int transmit_response_with_minexpires (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Append Min-Expires header, content length before transmitting response.
static int transmit_response_with_minse (struct sip_pvt *p, const char *msg, const struct sip_request *req, int minse_int)
 Transmit 422 response with Min-SE header (Session-Timers).
static int transmit_response_with_retry_after (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *seconds)
 Append Retry-After header field when transmitting response.
static int transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable, int oldsdp, int rpid)
 Used for 200 OK and 183 early media.
static int transmit_response_with_sip_etag (struct sip_pvt *p, const char *msg, const struct sip_request *req, struct sip_esc_entry *esc_entry, int need_new_etag)
static int transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans)
 Used for 200 OK and 183 early media.
static int transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported)
 Transmit response, no retransmits.
static int transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout)
 Used in the SUBSCRIBE notification subsystem (RFC3265).
static void try_suggested_sip_codec (struct sip_pvt *p)
 Try setting codec suggested by the SIP_CODEC channel variable.
static void unlink_marked_peers_from_tables (void)
static void unlink_peer_from_tables (struct sip_peer *peer)
static int unload_module (void)
 PBX unload module API.
static void * unref_peer (struct sip_peer *peer, char *tag)
static int update_call_counter (struct sip_pvt *fup, int event)
 update_call_counter: Handle call_limit for SIP devices Setting a call-limit will cause calls above the limit not to be accepted.
static void update_connectedline (struct sip_pvt *p, const void *data, size_t datalen)
 Notify peer that the connected line has changed.
static void update_peer (struct sip_peer *p, int expire)
 Update peer data in database (if used).
static void update_provisional_keepalive (struct sip_pvt *pvt, int with_sdp)
static void update_redirecting (struct sip_pvt *p, const void *data, size_t datalen)
 Send a provisional response indicating that a call was redirected.
static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Session Initiation Protocol (SIP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto,chan_local", }
static int apeerobjs = 0
static char * app_dtmfmode = "SIPDtmfMode"
static char * app_sipaddheader = "SIPAddHeader"
static char * app_sipremoveheader = "SIPRemoveHeader"
static struct ast_module_info * ast_module_info = &__mod_info
static struct sip_auth * authl = NULL
 Authentication list for realm authentication.
ast_sockaddr bindaddr
static struct epa_static_data cc_epa_static_data
static struct sip_esc_publish_callbacks cc_esc_publish_callbacks
static struct ast_threadstorage check_auth_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_check_auth_buf , .custom_init = NULL , }
static struct ast_custom_function checksipdomain_function
static struct ast_cli_entry cli_sip []
 SIP Cli commands definition.
static struct ast_sockaddr debugaddr
static const int DEFAULT_PUBLISH_EXPIRES = 3600
static struct ast_tls_config default_tls_cfg
 Default TLS connection configuration.
static struct ao2_container * dialogs
 Here we implement the container for dialogs (sip_pvt), defining generic wrapper functions to ease the transition from the current implementation (a single linked list) to a different container. In addition to a reference to the container, we need functions to lock/unlock the container and individual items, and functions to add/remove references to the individual items.
static struct _map_x_s dtmfstr []
 mapping between dtmf flags and strings
static int esc_etag_counter
static const int ESC_MAX_BUCKETS = 37
static struct event_state_compositor event_state_compositors []
 The Event State Compositors.
static struct ast_sockaddr externaddr
 our external IP address/port for SIP sessions. externaddr.sin_addr is only set when we know we might be behind a NAT, and this is done using a variety of (mutually exclusive) ways from the config file:
static time_t externexpire
static char externhost [MAXHOSTNAMELEN]
static int externrefresh = 10
static uint16_t externtcpport
static uint16_t externtlsport
static struct _map_x_s faxecmodes []
static struct ast_flags global_flags [3] = {{0}}
static int global_t38_maxdatagram
static const int HASH_DIALOG_SIZE = 563
static const int HASH_PEER_SIZE = 563
static struct _map_x_s insecurestr []
static struct ast_sockaddr internip
 our (internal) default address/port to put in SIP/SDP messages internip is initialized picking a suitable address from one of the interfaces, and the same port number we bind to. It is used as the default address/port in SIP messages, and as the default address (but not port) in SDP messages.
static struct io_context * io
static struct ast_ha * localaddr
 List of local networks We store "localnet" addresses from the config file into an access list, marked as 'DENY', so the call to ast_apply_ha() will return AST_SENSE_DENY for 'local' addresses, and AST_SENSE_ALLOW for 'non local' (i.e. presumably public) addresses.
static struct ast_sockaddr media_address
static pthread_t monitor_thread = AST_PTHREADT_NULL
 This is the thread for the monitor which checks for input on the channels which are not currently in use.
static ast_mutex_t monlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
static ast_mutex_t netlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static int network_change_event_sched_id = -1
static struct ast_event_sub * network_change_event_subscription
static struct ast_config * notify_types = NULL
static int ourport_tcp
static int ourport_tls
static struct ao2_container * peers
 The peer list: Users, Peers and Friends.
static struct ao2_container * peers_by_ip
static struct ast_data_handler peers_data_provider
static struct _map_x_s referstatusstrings []
static struct ast_register_list regl
 The register list: Other SIP proxies we register with and receive calls from.
static int regobjs = 0
static struct _map_x_s regstatestrings []
static int rpeerobjs = 0
sched_context * sched
static struct ast_cc_agent_callbacks sip_cc_agent_callbacks
static struct ast_cc_monitor_callbacks sip_cc_monitor_callbacks
struct {
   enum sip_cc_notify_state   state
   const char *   state_string
} sip_cc_notify_state_map []
struct {
   enum ast_cc_service_type   service
   const char *   service_string
} sip_cc_service_map []
static struct ast_data_entry sip_data_providers []
static struct ast_custom_function sip_header_function
ao2_container * sip_monitor_instances
static ast_mutex_t sip_reload_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static int sip_reloading = FALSE
static enum channelreloadreason sip_reloadreason
static struct ast_rtp_glue sip_rtp_glue
static struct ast_tcptls_session_args sip_tcp_desc
 The TCP server definition.
ast_channel_tech sip_tech
 Definition of this channel for PBX channel registration.
ast_channel_tech sip_tech_info
 This version of the sip channel tech has no send_digit_begin callback so that the core knows that the channel does not want DTMF BEGIN frames. The struct is initialized just before registering the channel driver, and is for use with channels using SIP INFO DTMF.
static struct ast_tls_config sip_tls_cfg
 Working TLS connection configuration.
static struct ast_tcptls_session_args sip_tls_desc
 The TCP/TLS server definition.
static struct ast_udptl_protocol sip_udptl
 Interface structure with callbacks used to connect to UDPTL module.
static struct ast_custom_function sipchaninfo_function
 Structure to declare a dialplan function: SIPCHANINFO.
static enum sip_debug_e sipdebug
static int sipdebug_text
 extra debugging for 'text' related events. At the moment this is set together with sip_debug_console.
static struct ast_custom_function sippeer_function
 Structure to declare a dialplan function: SIPPEER.
static int sipsock = -1
 Main socket for UDP SIP communication.
static int * sipsock_read_id
static int speerobjs = 0
static struct _map_x_s stmodes []
 Report Peer status in character string.
static struct _map_x_s strefreshers []
static struct ast_subscription_mwi_list submwil
 The MWI subscription list.
static struct ao2_container * threadt
 The table of TCP threads.
static struct ast_threadstorage ts_temp_pvt = { .once = PTHREAD_ONCE_INIT , .key_init = __init_ts_temp_pvt , .custom_init = temp_pvt_init , }
static char used_context [AST_MAX_CONTEXT]

DefaultSettings

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

static char default_callerid [AST_MAX_EXTENSION]
static char default_engine [256]
static char default_fromdomain [AST_MAX_EXTENSION]
static int default_fromdomainport
static char default_language [MAX_LANGUAGE]
static int default_maxcallbitrate
static char default_mohinterpret [MAX_MUSICCLASS]
static char default_mohsuggest [MAX_MUSICCLASS]
static char default_mwi_from [80]
static char default_notifymime [AST_MAX_EXTENSION]
static char default_parkinglot [AST_MAX_CONTEXT]
static struct ast_codec_pref default_prefs
static unsigned int default_primary_transport
static int default_qualify
static unsigned int default_transports
static char default_vmexten [AST_MAX_EXTENSION]

Defines

#define SIP_PEDANTIC_DECODE(str)

Variables

static int authlimit = DEFAULT_AUTHLIMIT
static int authtimeout = DEFAULT_AUTHTIMEOUT
static int can_parse_xml
static unsigned int chan_idx
static const char config [] = "sip.conf"
static int default_expiry = DEFAULT_DEFAULT_EXPIRY
static struct ast_jb_conf default_jbconf
 Global jitterbuffer configuration - by default, jb is disabled.
static unsigned int dumphistory
static int global_authfailureevents
static unsigned int global_autoframing
static int global_callcounter
static unsigned int global_cos_audio
static unsigned int global_cos_sip
static unsigned int global_cos_text
static unsigned int global_cos_video
static int global_dynamic_exclude_static = 0
static struct ast_jb_conf global_jbconf
static int global_match_auth_username
static int global_max_se
static int global_min_se
static int global_prematuremediafilter
static int global_qualify_gap
static int global_qualify_peers
static int global_qualifyfreq
static int global_reg_timeout
static int global_regattempts_max
static int global_relaxdtmf
static int global_rtpholdtimeout
static int global_rtpkeepalive
static int global_rtptimeout
static char global_sdpowner [AST_MAX_EXTENSION]
static char global_sdpsession [AST_MAX_EXTENSION]
static int global_shrinkcallerid
static enum st_mode global_st_mode
static enum st_refresher global_st_refresher
static int global_t1
static int global_t1min
static int global_timer_b
static unsigned int global_tos_audio
static unsigned int global_tos_sip
static unsigned int global_tos_text
static unsigned int global_tos_video
static char global_useragent [AST_MAX_EXTENSION]
static struct invstate2stringtable invitestate2string []
 Readable descriptions of device states.
static int max_expiry = DEFAULT_MAX_EXPIRY
static int min_expiry = DEFAULT_MIN_EXPIRY
static int mwi_expiry = DEFAULT_MWI_EXPIRY
static const char notify_config [] = "sip_notify.conf"
static unsigned int recordhistory
static struct sip_settings sip_cfg
static struct cfsip_methods sip_methods []
 The core structure to setup dialogs. We parse incoming messages by using structure and then route the messages according to the type.
static struct sip_reasons sip_reason_table []
 Diversion header reasons.
static struct cfsubscription_types subscription_types []
 Subscription types that we support. We support
  • dialoginfo updates (really device status, not dialog info as was the original intent of the standard)
  • SIMPLE presence used for device status
  • Voicemail notification subscriptions.

static int unauth_sessions = 0


Detailed Description

Implementation of Session Initiation Protocol.

Author:
Mark Spencer <markster@digium.com>
See Also: Implementation of RFC 3261 - without S/MIME, and experimental TCP and TLS support Configuration file sip.conf

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

Note:
TCP/TLS support is EXPERIMENTAL and WILL CHANGE. This applies to configuration settings, dialplan commands and dialplans apps/functions See SIP TCP and TLS support
******** General TODO:s
Todo:
Better support of forking

VIA branch tag transaction checking

Transaction support

******** Wishlist: Improvements

Overview of the handling of SIP sessions
The SIP channel handles several types of SIP sessions, or dialogs, not all of them being "telephone calls".
In the SIP channel, there's a list of active SIP dialogs, which includes all of these when they are active. "sip show channels" in the CLI will show most of these, excluding subscriptions which are shown by "sip show subscriptions"

incoming packets
Incoming packets are received in the monitoring thread, then handled by sipsock_read() for udp only. In tcp, packets are read by the tcp_helper thread. sipsock_read() function parses the packet and matches an existing dialog or starts a new SIP dialog.
sipsock_read sends the packet to handle_incoming(), that parses a bit more. If it is a response to an outbound request, the packet is sent to handle_response(). If it is a request, handle_incoming() sends it to one of a list of functions depending on the request type - INVITE, OPTIONS, REFER, BYE, CANCEL etc sipsock_read locks the ast_channel if it exists (an active call) and unlocks it after we have processed the SIP message.

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

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

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

Definition in file chan_sip.c.


Define Documentation

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

Append to SIP dialog history.

Returns:
Always returns 0

Definition at line 2190 of file chan_sip.c.

Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), cb_extensionstate(), change_hold_state(), do_register_auth(), handle_invite_replaces(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), handle_response_invite(), local_attended_transfer(), obproxy_get(), pvt_set_needdestroy(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_fixup(), sip_hangup(), sip_new(), sip_park_thread(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_response_with_auth(), and update_connectedline().

#define CHECK_AUTH_BUF_INITLEN   256

Definition at line 13585 of file chan_sip.c.

Referenced by check_auth(), and transmit_fake_auth_response().

#define check_request_transport ( peer,
tmpl   ) 

generic function for determining if a correct transport is being used to contact a peer

this is done as a macro so that the "tmpl" var can be passed either a sip_request or a sip_peer

Definition at line 2273 of file chan_sip.c.

Referenced by create_addr_from_peer(), and register_verify().

#define DATA_EXPORT_SIP_PEER ( MEMBER   ) 

Definition at line 28855 of file chan_sip.c.

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

Definition at line 17420 of file chan_sip.c.

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

Definition at line 17420 of file chan_sip.c.

#define FORMAT   "%-15.15s %-11.11s %-8.8s %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf\n"

Definition at line 17420 of file chan_sip.c.

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

Definition at line 17420 of file chan_sip.c.

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

Definition at line 17420 of file chan_sip.c.

#define FORMAT   "%-25.25s %-39.39s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n"

Definition at line 17420 of file chan_sip.c.

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

Definition at line 17420 of file chan_sip.c.

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

Definition at line 17420 of file chan_sip.c.

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

Definition at line 17420 of file chan_sip.c.

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

Definition at line 17419 of file chan_sip.c.

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

Definition at line 17419 of file chan_sip.c.

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

Definition at line 17419 of file chan_sip.c.

#define FORMAT2   "%-25.25s %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n"

Definition at line 17419 of file chan_sip.c.

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

Definition at line 17419 of file chan_sip.c.

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

Definition at line 17419 of file chan_sip.c.

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

Definition at line 17418 of file chan_sip.c.

Referenced by sip_show_channels().

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

Definition at line 17417 of file chan_sip.c.

Referenced by show_channels_cb().

#define SIP_PEDANTIC_DECODE ( str   ) 

Value:

if (sip_cfg.pedanticsipchecking && !ast_strlen_zero(str)) { \
      ast_uri_decode(str); \
   }  \

Definition at line 700 of file chan_sip.c.

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

#define sip_pvt_lock ( x   )     ao2_lock(x)

Definition at line 1081 of file chan_sip.c.

Referenced by __sip_ack(), __sip_autodestruct(), auto_congest(), cb_extensionstate(), check_rtp_timeout(), complete_sipch(), find_call(), get_sip_pvt_byid_locked(), handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_invite(), handle_request_refer(), local_attended_transfer(), proc_session_timer(), retrans_pkt(), scheduler_process_request_queue(), sip_answer(), sip_call(), sip_cc_agent_destructor(), sip_cc_agent_init(), sip_cc_agent_recall(), sip_cc_agent_respond(), sip_cc_monitor_request_cc(), sip_dtmfmode(), sip_fixup(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), sip_hangup(), sip_indicate(), sip_monitor_instance_destructor(), sip_new(), sip_park(), sip_queryoption(), sip_read(), sip_reg_timeout(), sip_reinvite_retry(), sip_request_call(), sip_senddigit_begin(), sip_senddigit_end(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_show_channel(), sip_show_history(), sip_t38_abort(), sip_transfer(), sip_write(), transmit_publish(), and update_call_counter().

#define sip_pvt_trylock ( x   )     ao2_trylock(x)

Definition at line 1082 of file chan_sip.c.

Referenced by dialog_needdestroy(), and sip_hangup().

#define sip_pvt_unlock ( x   )     ao2_unlock(x)

Definition at line 1083 of file chan_sip.c.

Referenced by __sip_ack(), __sip_autodestruct(), auto_congest(), cb_extensionstate(), check_rtp_timeout(), complete_sipch(), dialog_needdestroy(), get_sip_pvt_byid_locked(), handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_refer(), local_attended_transfer(), proc_session_timer(), retrans_pkt(), scheduler_process_request_queue(), sip_answer(), sip_call(), sip_cc_agent_destructor(), sip_cc_agent_init(), sip_cc_agent_recall(), sip_cc_agent_respond(), sip_cc_monitor_request_cc(), sip_dtmfmode(), sip_fixup(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), sip_hangup(), sip_indicate(), sip_monitor_instance_destructor(), sip_new(), sip_park(), sip_queryoption(), sip_read(), sip_reg_timeout(), sip_reinvite_retry(), sip_request_call(), sip_senddigit_begin(), sip_senddigit_end(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_show_channel(), sip_show_history(), sip_t38_abort(), sip_transfer(), sip_write(), transmit_publish(), and update_call_counter().

#define UNLINK ( element,
head,
prev   ) 

some list management macros.

Definition at line 1180 of file chan_sip.c.

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


Enumeration Type Documentation

enum match_req_res

Enumerator:
SIP_REQ_MATCH 
SIP_REQ_NOT_MATCH 
SIP_REQ_LOOP_DETECTED 

Definition at line 7460 of file chan_sip.c.

07460                    {
07461    SIP_REQ_MATCH,
07462    SIP_REQ_NOT_MATCH,
07463    SIP_REQ_LOOP_DETECTED,
07464 };


Function Documentation

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

Definition at line 6987 of file chan_sip.c.

References ast_skip_blanks(), find_alias(), len(), pass, and sip_cfg.

06988 {
06989    int pass;
06990 
06991    /*
06992     * Technically you can place arbitrary whitespace both before and after the ':' in
06993     * a header, although RFC3261 clearly says you shouldn't before, and place just
06994     * one afterwards.  If you shouldn't do it, what absolute idiot decided it was
06995     * a good idea to say you can do it, and if you can do it, why in the hell would.
06996     * you say you shouldn't.
06997     * Anyways, pedanticsipchecking controls whether we allow spaces before ':',
06998     * and we always allow spaces after that for compatibility.
06999     */
07000    for (pass = 0; name && pass < 2;pass++) {
07001       int x, len = strlen(name);
07002       for (x = *start; x < req->headers; x++) {
07003          const char *header = REQ_OFFSET_TO_STR(req, header[x]);
07004          if (!strncasecmp(header, name, len)) {
07005             const char *r = header + len; /* skip name */
07006             if (sip_cfg.pedanticsipchecking)
07007                r = ast_skip_blanks(r);
07008 
07009             if (*r == ':') {
07010                *start = x+1;
07011                return ast_skip_blanks(r+1);
07012             }
07013          }
07014       }
07015       if (pass == 0) /* Try aliases */
07016          name = find_alias(name, NULL);
07017    }
07018 
07019    /* Don't return NULL, so get_header is always a valid pointer */
07020    return "";
07021 }

static void __init_check_auth_buf ( void   )  [static]

Definition at line 13584 of file chan_sip.c.

13595 {

static void __init_ts_temp_pvt ( void   )  [static]

A per-thread temporary pvt structure.

Definition at line 1106 of file chan_sip.c.

01130 : The address we bind to */

static void __reg_module ( void   )  [static]

Definition at line 29295 of file chan_sip.c.

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

Definition at line 13151 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, get_transport_str2enum(), and LOG_WARNING.

Referenced by build_peer(), and set_address_from_contact().

13152 {
13153    char *domain, *transport;
13154    char contact_buf[256];
13155    char *contact;
13156 
13157    /* Work on a copy */
13158    ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf));
13159    contact = contact_buf;
13160 
13161    /* 
13162     * We have only the part in <brackets> here so we just need to parse a SIP URI.
13163     *
13164     * Note: The outbound proxy could be using UDP between the proxy and Asterisk.
13165     * We still need to be able to send to the remote agent through the proxy.
13166     */
13167 
13168    if (parse_uri(contact, "sip:,sips:", &contact, NULL, &domain,
13169             &transport)) {
13170       ast_log(LOG_WARNING, "Invalid contact uri %s (missing sip: or sips:), attempting to use anyway\n", fullcontact);
13171    }
13172 
13173    /* XXX This could block for a long time XXX */
13174    /* We should only do this if it's a name, not an IP */
13175    /* \todo - if there's no PORT number in contact - we are required to check NAPTR/SRV records
13176       to find transport, port address and hostname. If there's a port number, we have to
13177       assume that the domain part is a host name and only look for an A/AAAA record in DNS.
13178    */
13179 
13180    if (ast_sockaddr_resolve_first(addr, domain, 0)) {
13181       ast_log(LOG_WARNING, "Invalid host name in Contact: (can't "
13182          "resolve in DNS) : '%s'\n", domain);
13183       return -1;
13184    }
13185 
13186    /* set port */
13187    if (!ast_sockaddr_port(addr)) {
13188       ast_sockaddr_set_port(addr,
13189                   (get_transport_str2enum(transport) ==
13190                    SIP_TRANSPORT_TLS ||
13191                    !strncasecmp(fullcontact, "sips", 4)) ?
13192                   STANDARD_TLS_PORT : STANDARD_SIP_PORT);
13193    }
13194 
13195    return 0;
13196 }

int __sip_ack ( struct sip_pvt *  p,
int  seqno,
int  resp,
int  sipmethod 
)

Acknowledges receipt of a packet and stops retransmission called with p locked.

Definition at line 3885 of file chan_sip.c.

References ast_debug, ast_free, ast_sched_del(), FALSE, ref_proxy(), sip_pvt_lock, sip_pvt_unlock, sipdebug, TRUE, and UNLINK.

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

03886 {
03887    struct sip_pkt *cur, *prev = NULL;
03888    const char *msg = "Not Found";   /* used only for debugging */
03889    int res = FALSE;
03890 
03891    /* If we have an outbound proxy for this dialog, then delete it now since
03892      the rest of the requests in this dialog needs to follow the routing.
03893      If obforcing is set, we will keep the outbound proxy during the whole
03894      dialog, regardless of what the SIP rfc says
03895    */
03896    if (p->outboundproxy && !p->outboundproxy->force){
03897       ref_proxy(p, NULL);
03898    }
03899 
03900    for (cur = p->packets; cur; prev = cur, cur = cur->next) {
03901       if (cur->seqno != seqno || cur->is_resp != resp) {
03902          continue;
03903       }
03904       if (cur->is_resp || cur->method == sipmethod) {
03905          res = TRUE;
03906          msg = "Found";
03907          if (!resp && (seqno == p->pendinginvite)) {
03908             ast_debug(1, "Acked pending invite %d\n", p->pendinginvite);
03909             p->pendinginvite = 0;
03910          }
03911          if (cur->retransid > -1) {
03912             if (sipdebug)
03913                ast_debug(4, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
03914          }
03915          /* This odd section is designed to thwart a
03916           * race condition in the packet scheduler. There are
03917           * two conditions under which deleting the packet from the
03918           * scheduler can fail.
03919           *
03920           * 1. The packet has been removed from the scheduler because retransmission
03921           * is being attempted. The problem is that if the packet is currently attempting
03922           * retransmission and we are at this point in the code, then that MUST mean
03923           * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the
03924           * lock temporarily to allow retransmission.
03925           *
03926           * 2. The packet has reached its maximum number of retransmissions and has
03927           * been permanently removed from the packet scheduler. If this is the case, then
03928           * the packet's retransid will be set to -1. The atomicity of the setting and checking
03929           * of the retransid to -1 is ensured since in both cases p's lock is held.
03930           */
03931          while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) {
03932             sip_pvt_unlock(p);
03933             usleep(1);
03934             sip_pvt_lock(p);
03935          }
03936          UNLINK(cur, p->packets, prev);
03937          dialog_unref(cur->owner, "unref pkt cur->owner dialog from sip ack before freeing pkt");
03938          if (cur->data) {
03939             ast_free(cur->data);
03940          }
03941          ast_free(cur);
03942          break;
03943       }
03944    }
03945    ast_debug(1, "Stopping retransmission on '%s' of %s %d: Match %s\n",
03946       p->callid, resp ? "Response" : "Request", seqno, msg);
03947    return res;
03948 }

static int __sip_autodestruct ( const void *  data  )  [static]

Kill a SIP dialog (called only by the scheduler) The scheduler has a reference to this dialog when p->autokillid != -1, and we are called using that reference. So if the event is not rescheduled, we need to call dialog_unref().

Definition at line 3741 of file chan_sip.c.

References __sip_pretend_ack(), append_history, AST_CAUSE_PROTOCOL_ERROR, ast_channel_trylock, ast_channel_unlock, ast_debug, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup_with_cause(), dialog_unlink_all(), LOG_WARNING, method_match(), NONE, pvt_set_needdestroy(), sip_methods, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), cfsip_methods::text, transmit_request_with_auth(), transmit_state_notify(), and TRUE.

Referenced by sip_scheddestroy(), and sip_show_sched().

03742 {
03743    struct sip_pvt *p = (struct sip_pvt *)data;
03744 
03745    /* If this is a subscription, tell the phone that we got a timeout */
03746    if (p->subscribed && p->subscribed != MWI_NOTIFICATION && p->subscribed != CALL_COMPLETION) {
03747       transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE);  /* Send last notification */
03748       p->subscribed = NONE;
03749       append_history(p, "Subscribestatus", "timeout");
03750       ast_debug(3, "Re-scheduled destruction of SIP subscription %s\n", p->callid ? p->callid : "<unknown>");
03751       return 10000;  /* Reschedule this destruction so that we know that it's gone */
03752    }
03753 
03754    /* If there are packets still waiting for delivery, delay the destruction */
03755    if (p->packets) {
03756       if (!p->needdestroy) {
03757          char method_str[31];
03758          ast_debug(3, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>");
03759          append_history(p, "ReliableXmit", "timeout");
03760          if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) {
03761             if (method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) {
03762                pvt_set_needdestroy(p, "autodestruct");
03763             }
03764          }
03765          return 10000;
03766       } else {
03767          /* They've had their chance to respond. Time to bail */
03768          __sip_pretend_ack(p);
03769       }
03770    }
03771 
03772    /* Reset schedule ID */
03773    p->autokillid = -1;
03774 
03775 
03776    /*
03777     * Lock both the pvt and the channel safely so that we can queue up a frame.
03778     */
03779    sip_pvt_lock(p);
03780    while (p->owner && ast_channel_trylock(p->owner)) {
03781       sip_pvt_unlock(p);
03782       sched_yield();
03783       sip_pvt_lock(p);
03784    }
03785 
03786    if (p->owner) {
03787       ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text);
03788       ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR);
03789       ast_channel_unlock(p->owner);
03790    } else if (p->refer && !p->alreadygone) {
03791       ast_debug(3, "Finally hanging up channel after transfer: %s\n", p->callid);
03792       transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
03793       append_history(p, "ReferBYE", "Sending BYE on transferer call leg %s", p->callid);
03794       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03795    } else {
03796       append_history(p, "AutoDestroy", "%s", p->callid);
03797       ast_debug(3, "Auto destroying SIP dialog '%s'\n", p->callid);
03798       dialog_unlink_all(p, TRUE, TRUE); /* once it's unlinked and unrefd everywhere, it'll be freed automagically */
03799       /* dialog_unref(p, "unref dialog-- no other matching conditions"); -- unlink all now should finish off the dialog's references and free it. */
03800       /* sip_destroy(p); */      /* Go ahead and destroy dialog. All attempts to recover is done */
03801       /* sip_destroy also absorbs the reference */
03802    }
03803 
03804    sip_pvt_unlock(p);
03805 
03806    dialog_unref(p, "The ref to a dialog passed to this sched callback is going out of scope; unref it.");
03807 
03808    return 0;
03809 }

void __sip_destroy ( struct sip_pvt *  p,
int  lockowner,
int  lockdialoglist 
)

Execute destruction of SIP dialog structure, release memory.

Definition at line 5453 of file chan_sip.c.

References ao2_ref, ast_cc_config_params_destroy(), ast_channel_lock, ast_channel_unlock, ast_debug, ast_free, ast_free_ha(), AST_LIST_REMOVE_HEAD, ast_rtp_instance_destroy(), AST_SCHED_DEL_UNREF, AST_SOFTHANGUP_DEV, ast_string_field_free_memory, ast_test_flag, ast_udptl_destroy(), ast_variables_destroy(), ast_verbose, deinit_req(), dumphistory, free_old_route(), registry_unref(), sip_debug_test_pvt(), sip_dump_history(), sip_methods, cfsip_methods::text, TRUE, unref_peer(), and update_call_counter().

Referenced by sip_destroy().

05454 {
05455    struct sip_request *req;
05456 
05457    if (p->stimer) {
05458       ast_free(p->stimer);
05459       p->stimer = NULL;
05460    }
05461 
05462    if (sip_debug_test_pvt(p))
05463       ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
05464 
05465    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
05466       update_call_counter(p, DEC_CALL_LIMIT);
05467       ast_debug(2, "This call did not properly clean up call limits. Call ID %s\n", p->callid);
05468    }
05469 
05470    /* Unlink us from the owner if we have one */
05471    if (p->owner) {
05472       if (lockowner)
05473          ast_channel_lock(p->owner);
05474       ast_debug(1, "Detaching from %s\n", p->owner->name);
05475       p->owner->tech_pvt = NULL;
05476       /* Make sure that the channel knows its backend is going away */
05477       p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
05478       if (lockowner)
05479          ast_channel_unlock(p->owner);
05480       /* Give the channel a chance to react before deallocation */
05481       usleep(1);
05482    }
05483 
05484    /* Remove link from peer to subscription of MWI */
05485    if (p->relatedpeer && p->relatedpeer->mwipvt)
05486       p->relatedpeer->mwipvt = dialog_unref(p->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt");
05487    if (p->relatedpeer && p->relatedpeer->call == p)
05488       p->relatedpeer->call = dialog_unref(p->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself");
05489    
05490    if (p->relatedpeer)
05491       p->relatedpeer = unref_peer(p->relatedpeer,"unsetting a dialog relatedpeer field in sip_destroy");
05492    
05493    if (p->registry) {
05494       if (p->registry->call == p)
05495          p->registry->call = dialog_unref(p->registry->call, "nulling out the registry's call dialog field in unlink_all");
05496       p->registry = registry_unref(p->registry, "delete p->registry");
05497    }
05498    
05499    if (p->mwi) {
05500       p->mwi->call = NULL;
05501    }
05502 
05503    if (dumphistory)
05504       sip_dump_history(p);
05505 
05506    if (p->options)
05507       ast_free(p->options);
05508 
05509    if (p->notify) {
05510       ast_variables_destroy(p->notify->headers);
05511       ast_free(p->notify->content);
05512       ast_free(p->notify);
05513    }
05514    if (p->rtp) {
05515       ast_rtp_instance_destroy(p->rtp);
05516    }
05517    if (p->vrtp) {
05518       ast_rtp_instance_destroy(p->vrtp);
05519    }
05520    if (p->trtp) {
05521       ast_rtp_instance_destroy(p->trtp);
05522    }
05523    if (p->udptl)
05524       ast_udptl_destroy(p->udptl);
05525    if (p->refer)
05526       ast_free(p->refer);
05527    if (p->route) {
05528       free_old_route(p->route);
05529       p->route = NULL;
05530    }
05531    deinit_req(&p->initreq);
05532 
05533    /* Destroy Session-Timers if allocated */
05534    if (p->stimer) {
05535       p->stimer->quit_flag = 1;
05536       if (p->stimer->st_active == TRUE && p->stimer->st_schedid > -1) {
05537          AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
05538                dialog_unref(p, "removing session timer ref"));
05539       }
05540       ast_free(p->stimer);
05541       p->stimer = NULL;
05542    }
05543 
05544    /* Clear history */
05545    if (p->history) {
05546       struct sip_history *hist;
05547       while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) {
05548          ast_free(hist);
05549          p->history_entries--;
05550       }
05551       ast_free(p->history);
05552       p->history = NULL;
05553    }
05554 
05555    while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) {
05556       ast_free(req);
05557    }
05558 
05559    if (p->chanvars) {
05560       ast_variables_destroy(p->chanvars);
05561       p->chanvars = NULL;
05562    }
05563 
05564    if (p->srtp) {
05565       sip_srtp_destroy(p->srtp);
05566       p->srtp = NULL;
05567    }
05568 
05569    if (p->vsrtp) {
05570       sip_srtp_destroy(p->vsrtp);
05571       p->vsrtp = NULL;
05572    }
05573 
05574    if (p->tsrtp) {
05575       sip_srtp_destroy(p->tsrtp);
05576       p->tsrtp = NULL;
05577    }
05578 
05579    if (p->directmediaha) {
05580       ast_free_ha(p->directmediaha);
05581       p->directmediaha = NULL;
05582    }
05583 
05584    ast_string_field_free_memory(p);
05585 
05586    ast_cc_config_params_destroy(p->cc_params);
05587 
05588    if (p->epa_entry) {
05589       ao2_ref(p->epa_entry, -1);
05590       p->epa_entry = NULL;
05591    }
05592 
05593    if (p->socket.tcptls_session) {
05594       ao2_ref(p->socket.tcptls_session, -1);
05595       p->socket.tcptls_session = NULL;
05596    }
05597 }

static int __sip_do_register ( struct sip_registry *  r  )  [static]

Register with SIP proxy.

Returns:
see __sip_xmit

Definition at line 12416 of file chan_sip.c.

References transmit_register().

Referenced by sip_reregister().

12417 {
12418    int res;
12419 
12420    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
12421    return res;
12422 }

void __sip_pretend_ack ( struct sip_pvt *  p  ) 

Pretend to ack all packets called with p locked.

Definition at line 3952 of file chan_sip.c.

References __sip_ack(), ast_log(), find_sip_method(), LOG_WARNING, sip_methods, and cfsip_methods::text.

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

03953 {
03954    struct sip_pkt *cur = NULL;
03955 
03956    while (p->packets) {
03957       int method;
03958       if (cur == p->packets) {
03959          ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
03960          return;
03961       }
03962       cur = p->packets;
03963       method = (cur->method) ? cur->method : find_sip_method(cur->data->str);
03964       __sip_ack(p, cur->seqno, cur->is_resp, method);
03965    }
03966 }

static enum sip_result __sip_reliable_xmit ( struct sip_pvt *  p,
int  seqno,
int  resp,
struct ast_str *  data,
int  len,
int  fatal,
int  sipmethod 
) [static]

Transmit packet with retransmits.

Returns:
0 on success, -1 on failure to allocate packet

Todo:
According to the RFC some packets need to be retransmitted even if its TCP, so this needs to get revisited

Definition at line 3649 of file chan_sip.c.

References __sip_xmit(), append_history, ast_calloc, ast_debug, ast_free, ast_log(), AST_PTHREADT_NULL, AST_SCHED_DEL, AST_SCHED_REPLACE_VARIABLE, ast_str_buffer(), ast_str_create(), ast_str_set(), ast_tvnow(), DEFAULT_RETRANS, LOG_ERROR, monitor_thread, retrans_pkt(), and sipdebug.

Referenced by send_request(), and send_response().

03650 {
03651    struct sip_pkt *pkt = NULL;
03652    int siptimer_a = DEFAULT_RETRANS;
03653    int xmitres = 0;
03654    int respid;
03655 
03656    if (sipmethod == SIP_INVITE) {
03657       /* Note this is a pending invite */
03658       p->pendinginvite = seqno;
03659    }
03660 
03661    /* If the transport is something reliable (TCP or TLS) then don't really send this reliably */
03662    /* I removed the code from retrans_pkt that does the same thing so it doesn't get loaded into the scheduler */
03663    /*! \todo According to the RFC some packets need to be retransmitted even if its TCP, so this needs to get revisited */
03664    if (!(p->socket.type & SIP_TRANSPORT_UDP)) {
03665       xmitres = __sip_xmit(p, data, len); /* Send packet */
03666       if (xmitres == XMIT_ERROR) {  /* Serious network trouble, no need to try again */
03667          append_history(p, "XmitErr", "%s", fatal ? "(Critical)" : "(Non-critical)");
03668          return AST_FAILURE;
03669       } else {
03670          return AST_SUCCESS;
03671       }
03672    }
03673 
03674    if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) {
03675       return AST_FAILURE;
03676    }
03677    /* copy data, add a terminator and save length */
03678    if (!(pkt->data = ast_str_create(len))) {
03679       ast_free(pkt);
03680       return AST_FAILURE;
03681    }
03682    ast_str_set(&pkt->data, 0, "%s%s", data->str, "\0");
03683    pkt->packetlen = len;
03684    /* copy other parameters from the caller */
03685    pkt->method = sipmethod;
03686    pkt->seqno = seqno;
03687    pkt->is_resp = resp;
03688    pkt->is_fatal = fatal;
03689    pkt->owner = dialog_ref(p, "__sip_reliable_xmit: setting pkt->owner");
03690    pkt->next = p->packets;
03691    p->packets = pkt; /* Add it to the queue */
03692    if (resp) {
03693       /* Parse out the response code */
03694       if (sscanf(ast_str_buffer(pkt->data), "SIP/2.0 %30u", &respid) == 1) {
03695          pkt->response_code = respid;
03696       }
03697    }
03698    pkt->timer_t1 = p->timer_t1;  /* Set SIP timer T1 */
03699    pkt->retransid = -1;
03700    if (pkt->timer_t1) {
03701       siptimer_a = pkt->timer_t1;
03702    }
03703 
03704    pkt->time_sent = ast_tvnow(); /* time packet was sent */
03705    pkt->retrans_stop_time = 64 * (pkt->timer_t1 ? pkt->timer_t1 : DEFAULT_TIMER_T1); /* time in ms after pkt->time_sent to stop retransmission */
03706 
03707    /* Schedule retransmission */
03708    AST_SCHED_REPLACE_VARIABLE(pkt->retransid, sched, siptimer_a, retrans_pkt, pkt, 1);
03709    if (sipdebug) {
03710       ast_debug(4, "*** SIP TIMER: Initializing retransmit timer on packet: Id  #%d\n", pkt->retransid);
03711    }
03712 
03713    xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);   /* Send packet */
03714 
03715    if (xmitres == XMIT_ERROR) {  /* Serious network trouble, no need to try again */
03716       append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
03717       ast_log(LOG_ERROR, "Serious Network Trouble; __sip_xmit returns error for pkt data\n");
03718       AST_SCHED_DEL(sched, pkt->retransid);
03719       p->packets = pkt->next;
03720       pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now");
03721       ast_free(pkt->data);
03722       ast_free(pkt);
03723       return AST_FAILURE;
03724    } else {
03725       /* This is odd, but since the retrans timer starts at 500ms and the do_monitor thread
03726        * only wakes up every 1000ms by default, we have to poke the thread here to make
03727        * sure it successfully detects this must be retransmitted in less time than
03728        * it usually sleeps for. Otherwise it might not retransmit this packet for 1000ms. */
03729       if (monitor_thread != AST_PTHREADT_NULL) {
03730          pthread_kill(monitor_thread, SIGURG);
03731       }
03732       return AST_SUCCESS;
03733    }
03734 }

int __sip_semi_ack ( struct sip_pvt *  p,
int  seqno,
int  resp,
int  sipmethod 
)

Acks receipt of packet, keep it around (used for provisional responses).

Definition at line 3969 of file chan_sip.c.

References ast_debug, AST_SCHED_DEL, FALSE, method_match(), sip_methods, sipdebug, cfsip_methods::text, and TRUE.

Referenced by handle_response(), and sip_hangup().

03970 {
03971    struct sip_pkt *cur;
03972    int res = FALSE;
03973 
03974    for (cur = p->packets; cur; cur = cur->next) {
03975       if (cur->seqno == seqno && cur->is_resp == resp &&
03976          (cur->is_resp || method_match(sipmethod, cur->data->str))) {
03977          /* this is our baby */
03978          if (cur->retransid > -1) {
03979             if (sipdebug)
03980                ast_debug(4, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
03981          }
03982          AST_SCHED_DEL(sched, cur->retransid);
03983          res = TRUE;
03984          break;
03985       }
03986    }
03987    ast_debug(1, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res == -1 ? "Not Found" : "Found");
03988    return res;
03989 }

static int __sip_subscribe_mwi_do ( struct sip_subscription_mwi *  mwi  )  [static]

Actually setup an MWI subscription or resubscribe.

Definition at line 11763 of file chan_sip.c.

References ast_dnsmgr_lookup(), ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_port, ast_sockaddr_set_port, ast_string_field_set, ast_strlen_zero(), ASTOBJ_REF, bindaddr, build_callid_pvt(), build_contact(), build_via(), create_addr(), dialog_unlink_all(), get_address_family_filter(), get_srv_protocol(), get_srv_service(), MAXHOSTNAMELEN, mwi_expiry, obproxy_get(), ref_proxy(), set_socket_transport(), sip_alloc(), sip_cfg, transmit_invite(), and TRUE.

Referenced by sip_subscribe_mwi_do().

11764 {
11765    /* If we have no DNS manager let's do a lookup */
11766    if (!mwi->dnsmgr) {
11767       char transport[MAXHOSTNAMELEN];
11768       snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(mwi->transport), get_srv_protocol(mwi->transport));
11769 
11770       mwi->us.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */
11771       ast_dnsmgr_lookup(mwi->hostname, &mwi->us, &mwi->dnsmgr, sip_cfg.srvlookup ? transport : NULL);
11772    }
11773 
11774    /* If we already have a subscription up simply send a resubscription */
11775    if (mwi->call) {
11776       transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 0, NULL);
11777       return 0;
11778    }
11779    
11780    /* Create a dialog that we will use for the subscription */
11781    if (!(mwi->call = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL))) {
11782       return -1;
11783    }
11784 
11785    ref_proxy(mwi->call, obproxy_get(mwi->call, NULL));
11786 
11787    if (!ast_sockaddr_port(&mwi->us) && mwi->portno) {
11788       ast_sockaddr_set_port(&mwi->us, mwi->portno);
11789    }
11790    
11791    /* Setup the destination of our subscription */
11792    if (create_addr(mwi->call, mwi->hostname, &mwi->us, 0, NULL)) {
11793       dialog_unlink_all(mwi->call, TRUE, TRUE);
11794       mwi->call = dialog_unref(mwi->call, "unref dialog after unlink_all");
11795       return 0;
11796    }
11797 
11798    mwi->call->expiry = mwi_expiry;
11799    
11800    if (!mwi->dnsmgr && mwi->portno) {
11801       ast_sockaddr_set_port(&mwi->call->sa, mwi->portno);
11802       ast_sockaddr_set_port(&mwi->call->recv, mwi->portno);
11803    } else {
11804       mwi->portno = ast_sockaddr_port(&mwi->call->sa);
11805    }
11806    
11807    /* Set various other information */
11808    if (!ast_strlen_zero(mwi->authuser)) {
11809       ast_string_field_set(mwi->call, peername, mwi->authuser);
11810       ast_string_field_set(mwi->call, authname, mwi->authuser);
11811       ast_string_field_set(mwi->call, fromuser, mwi->authuser);
11812    } else {
11813       ast_string_field_set(mwi->call, peername, mwi->username);
11814       ast_string_field_set(mwi->call, authname, mwi->username);
11815       ast_string_field_set(mwi->call, fromuser, mwi->username);
11816    }
11817    ast_string_field_set(mwi->call, username, mwi->username);
11818    if (!ast_strlen_zero(mwi->secret)) {
11819       ast_string_field_set(mwi->call, peersecret, mwi->secret);
11820    }
11821    set_socket_transport(&mwi->call->socket, mwi->transport);
11822    mwi->call->socket.port = htons(mwi->portno);
11823    ast_sip_ouraddrfor(&mwi->call->sa, &mwi->call->ourip, mwi->call);
11824    build_contact(mwi->call);
11825    build_via(mwi->call);
11826    build_callid_pvt(mwi->call);
11827    ast_set_flag(&mwi->call->flags[0], SIP_OUTGOING);
11828    
11829    /* Associate the call with us */
11830    mwi->call->mwi = ASTOBJ_REF(mwi);
11831 
11832    mwi->call->subscribed = MWI_NOTIFICATION;
11833 
11834    /* Actually send the packet */
11835    transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 2, NULL);
11836 
11837    return 0;
11838 }

static int __sip_xmit ( struct sip_pvt *  p,
struct ast_str *  data,
int  len 
) [static]

Transmit SIP message Sends a SIP request or response on a given socket (in the pvt) Called by retrans_pkt, send_request, send_response and __sip_reliable_xmit.

Returns:
length of transmitted message, XMIT_ERROR on known network failures -1 on other failures.

Definition at line 3249 of file chan_sip.c.

References ast_debug, ast_log(), ast_sendto(), ast_sockaddr_stringify(), errno, get_transport_pvt(), LOG_WARNING, sip_prepare_socket(), sip_real_dst(), and sip_tcptls_write().

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

03250 {
03251    int res = 0;
03252    const struct ast_sockaddr *dst = sip_real_dst(p);
03253 
03254    ast_debug(2, "Trying to put '%.11s' onto %s socket destined for %s\n", data->str, get_transport_pvt(p), ast_sockaddr_stringify(dst));
03255 
03256    if (sip_prepare_socket(p) < 0) {
03257       return XMIT_ERROR;
03258    }
03259 
03260    if (p->socket.type == SIP_TRANSPORT_UDP) {
03261       res = ast_sendto(p->socket.fd, data->str, len, 0, dst);
03262    } else if (p->socket.tcptls_session) {
03263       res = sip_tcptls_write(p->socket.tcptls_session, data->str, len);
03264    } else {
03265       ast_debug(2, "Socket type is TCP but no tcptls_session is present to write to\n");
03266       return XMIT_ERROR;
03267    }
03268 
03269    if (res == -1) {
03270       switch (errno) {
03271       case EBADF:       /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */
03272       case EHOSTUNREACH:   /* Host can't be reached */
03273       case ENETDOWN:       /* Interface down */
03274       case ENETUNREACH: /* Network failure */
03275       case ECONNREFUSED:      /* ICMP port unreachable */
03276          res = XMIT_ERROR; /* Don't bother with trying to transmit again */
03277       }
03278    }
03279    if (res != len) {
03280       ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s returned %d: %s\n", data, len, ast_sockaddr_stringify(dst), res, strerror(errno));
03281    }
03282 
03283    return res;
03284 }

static int __transmit_response ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req,
enum xmittype  reliable 
) [static]

Base transmit response function.

Definition at line 9921 of file chan_sip.c.

References add_cc_call_info_to_response(), add_header(), add_rpid(), ast_cause2str(), ast_clear_flag, ast_log(), ast_test_flag, get_header(), hangup_sip2cause(), LOG_WARNING, respprep(), and send_response().

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

09922 {
09923    struct sip_request resp;
09924    int seqno = 0;
09925 
09926    if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) {
09927       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
09928       return -1;
09929    }
09930    respprep(&resp, p, msg, req);
09931 
09932    if (ast_test_flag(&p->flags[0], SIP_SENDRPID)
09933          && ast_test_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND)
09934          && (!strncmp(msg, "180", 3) || !strncmp(msg, "183", 3))) {
09935       ast_clear_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND);
09936       add_rpid(&resp, p);
09937    }
09938    if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) {
09939       add_cc_call_info_to_response(p, &resp);
09940    }
09941 
09942    /* If we are cancelling an incoming invite for some reason, add information
09943       about the reason why we are doing this in clear text */
09944    if (p->method == SIP_INVITE && msg[0] != '1') {
09945       char buf[20];
09946 
09947       if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON)) {
09948          int hangupcause = 0;
09949 
09950          if (p->owner && p->owner->hangupcause) {
09951             hangupcause = p->owner->hangupcause;
09952          } else if (p->hangupcause) {
09953             hangupcause = p->hangupcause;
09954          } else {
09955             int respcode;
09956             if (sscanf(msg, "%30d ", &respcode))
09957                hangupcause = hangup_sip2cause(respcode);
09958          }
09959 
09960          if (hangupcause) {
09961             sprintf(buf, "Q.850;cause=%i", hangupcause & 0x7f);
09962             add_header(&resp, "Reason", buf);
09963          }
09964       }
09965 
09966       if (p->owner && p->owner->hangupcause) {
09967          add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
09968          snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
09969          add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
09970       }
09971    }
09972    return send_response(p, &resp, reliable, seqno);
09973 }

static void __unreg_module ( void   )  [static]

Definition at line 29295 of file chan_sip.c.

static char * _sip_qualify_peer ( int  type,
int  fd,
struct mansession *  s,
const struct message *  m,
int  argc,
const char *  argv[] 
) [static]

Send qualify message to peer from cli or manager. Mostly for debugging.

Definition at line 16474 of file chan_sip.c.

References ast_cli(), astman_send_error(), CLI_SHOWUSAGE, CLI_SUCCESS, FALSE, find_peer(), sip_poke_peer(), TRUE, and unref_peer().

Referenced by manager_sip_qualify_peer(), and sip_qualify_peer().

16475 {
16476    struct sip_peer *peer;
16477    int load_realtime;
16478 
16479    if (argc < 4)
16480       return CLI_SHOWUSAGE;
16481 
16482    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
16483    if ((peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0))) {
16484       sip_poke_peer(peer, 1);
16485       unref_peer(peer, "qualify: done with peer");
16486    } else if (type == 0) {
16487       ast_cli(fd, "Peer '%s' not found\n", argv[3]);
16488    } else {
16489       astman_send_error(s, m, "Peer not found");
16490    }
16491    return CLI_SUCCESS;
16492 }

static char * _sip_show_peer ( int  type,
int  fd,
struct mansession *  s,
const struct message *  m,
int  argc,
const char *  argv[] 
) [static]

Show one peer in detail (main function).

Definition at line 16559 of file chan_sip.c.

References ARRAY_LEN, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), AST_CLI_YESNO, ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_print_group(), ast_sched_when(), ast_sockaddr_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), CLI_SHOWUSAGE, CLI_SUCCESS, dtmfmode2str(), FALSE, faxec2str(), find_peer(), get_transport(), get_transport_list(), insecure2str(), ast_variable::name, ast_variable::next, peer_mailboxes_to_str(), peer_status(), print_codec_to_cli(), print_group(), S_OR, sip_cfg, status, stmode2str(), strefresher2str(), transfermode2str(), TRUE, unref_peer(), and ast_variable::value.

Referenced by manager_sip_show_peer(), and sip_show_peer().

16560 {
16561    char status[30] = "";
16562    char cbuf[256];
16563    struct sip_peer *peer;
16564    char codec_buf[512];
16565    struct ast_codec_pref *pref;
16566    struct ast_variable *v;
16567    struct sip_auth *auth;
16568    int x = 0, load_realtime;
16569    format_t codec = 0;
16570    int realtimepeers;
16571 
16572    realtimepeers = ast_check_realtime("sippeers");
16573 
16574    if (argc < 4)
16575       return CLI_SHOWUSAGE;
16576 
16577    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
16578    peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0);
16579 
16580    if (s) {    /* Manager */
16581       if (peer) {
16582          const char *id = astman_get_header(m, "ActionID");
16583 
16584          astman_append(s, "Response: Success\r\n");
16585          if (!ast_strlen_zero(id))
16586             astman_append(s, "ActionID: %s\r\n", id);
16587       } else {
16588          snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]);
16589          astman_send_error(s, m, cbuf);
16590          return CLI_SUCCESS;
16591       }
16592    }
16593    if (peer && type==0 ) { /* Normal listing */
16594       struct ast_str *mailbox_str = ast_str_alloca(512);
16595       ast_cli(fd, "\n\n");
16596       ast_cli(fd, "  * Name       : %s\n", peer->name);
16597       if (realtimepeers) { /* Realtime is enabled */
16598          ast_cli(fd, "  Realtime peer: %s\n", peer->is_realtime ? "Yes, cached" : "No");
16599       }
16600       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
16601       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>");
16602       ast_cli(fd, "  Remote Secret: %s\n", ast_strlen_zero(peer->remotesecret)?"<Not set>":"<Set>");
16603       for (auth = peer->auth; auth; auth = auth->next) {
16604          ast_cli(fd, "  Realm-auth   : Realm %-15.15s User %-10.20s ", auth->realm, auth->username);
16605          ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>"));
16606       }
16607       ast_cli(fd, "  Context      : %s\n", peer->context);
16608       ast_cli(fd, "  Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") );
16609       ast_cli(fd, "  Language     : %s\n", peer->language);
16610       if (!ast_strlen_zero(peer->accountcode))
16611          ast_cli(fd, "  Accountcode  : %s\n", peer->accountcode);
16612       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(peer->amaflags));
16613       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(peer->allowtransfer));
16614       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(peer->callingpres));
16615       if (!ast_strlen_zero(peer->fromuser))
16616          ast_cli(fd, "  FromUser     : %s\n", peer->fromuser);
16617       if (!ast_strlen_zero(peer->fromdomain))
16618          ast_cli(fd, "  FromDomain   : %s Port %d\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT);
16619       ast_cli(fd, "  Callgroup    : ");
16620       print_group(fd, peer->callgroup, 0);
16621       ast_cli(fd, "  Pickupgroup  : ");
16622       print_group(fd, peer->pickupgroup, 0);
16623       peer_mailboxes_to_str(&mailbox_str, peer);
16624       ast_cli(fd, "  MOH Suggest  : %s\n", peer->mohsuggest);
16625       ast_cli(fd, "  Mailbox      : %s\n", mailbox_str->str);
16626       ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
16627       ast_cli(fd, "  LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
16628       ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
16629       ast_cli(fd, "  Max forwards : %d\n", peer->maxforwards);
16630       if (peer->busy_level)
16631          ast_cli(fd, "  Busy level   : %d\n", peer->busy_level);
16632       ast_cli(fd, "  Dynamic      : %s\n", AST_CLI_YESNO(peer->host_dynamic));
16633       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
16634       ast_cli(fd, "  MaxCallBR    : %d kbps\n", peer->maxcallbitrate);
16635       ast_cli(fd, "  Expire       : %ld\n", ast_sched_when(sched, peer->expire));
16636       ast_cli(fd, "  Insecure     : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE)));
16637       ast_cli(fd, "  Force rport  : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT)));
16638       ast_cli(fd, "  ACL          : %s\n", AST_CLI_YESNO(peer->ha != NULL));
16639       ast_cli(fd, "  DirectMedACL : %s\n", AST_CLI_YESNO(peer->directmediaha != NULL));
16640       ast_cli(fd, "  T.38 support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
16641       ast_cli(fd, "  T.38 EC mode : %s\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
16642       ast_cli(fd, "  T.38 MaxDtgrm: %d\n", peer->t38_maxdatagram);
16643       ast_cli(fd, "  DirectMedia  : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)));
16644       ast_cli(fd, "  PromiscRedir : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)));
16645       ast_cli(fd, "  User=Phone   : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)));
16646       ast_cli(fd, "  Video Support: %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) || ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS)));
16647       ast_cli(fd, "  Text Support : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT)));
16648       ast_cli(fd, "  Ign SDP ver  : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_IGNORESDPVERSION)));
16649       ast_cli(fd, "  Trust RPID   : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_TRUSTRPID)));
16650       ast_cli(fd, "  Send RPID    : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_SENDRPID)));
16651       ast_cli(fd, "  Subscriptions: %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)));
16652       ast_cli(fd, "  Overlap dial : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP)));
16653       if (peer->outboundproxy)
16654          ast_cli(fd, "  Outb. proxy  : %s %s\n", ast_strlen_zero(peer->outboundproxy->name) ? "<not set>" : peer->outboundproxy->name,
16655                      peer->outboundproxy->force ? "(forced)" : "");
16656 
16657       /* - is enumerated */
16658       ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
16659       ast_cli(fd, "  Timer T1     : %d\n", peer->timer_t1);
16660       ast_cli(fd, "  Timer B      : %d\n", peer->timer_b);
16661       ast_cli(fd, "  ToHost       : %s\n", peer->tohost);
16662       ast_cli(fd, "  Addr->IP     : %s\n", ast_sockaddr_stringify(&peer->addr));
16663       ast_cli(fd, "  Defaddr->IP  : %s\n", ast_sockaddr_stringify(&peer->defaddr));
16664       ast_cli(fd, "  Prim.Transp. : %s\n", get_transport(peer->socket.type));
16665       ast_cli(fd, "  Allowed.Trsp : %s\n", get_transport_list(peer->transports));
16666       if (!ast_strlen_zero(sip_cfg.regcontext))
16667          ast_cli(fd, "  Reg. exten   : %s\n", peer->regexten);
16668       ast_cli(fd, "  Def. Username: %s\n", peer->username);
16669       ast_cli(fd, "  SIP Options  : ");
16670       if (peer->sipoptions) {
16671          int lastoption = -1;
16672          for (x = 0 ; x < ARRAY_LEN(sip_options); x++) {
16673             if (sip_options[x].id != lastoption) {
16674                if (peer->sipoptions & sip_options[x].id)
16675                   ast_cli(fd, "%s ", sip_options[x].text);
16676                lastoption = x;
16677             }
16678          }
16679       } else
16680          ast_cli(fd, "(none)");
16681 
16682       ast_cli(fd, "\n");
16683       ast_cli(fd, "  Codecs       : ");
16684       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
16685       ast_cli(fd, "%s\n", codec_buf);
16686       ast_cli(fd, "  Codec Order  : (");
16687       print_codec_to_cli(fd, &peer->prefs);
16688       ast_cli(fd, ")\n");
16689 
16690       ast_cli(fd, "  Auto-Framing :  %s \n", AST_CLI_YESNO(peer->autoframing));
16691       ast_cli(fd, "  100 on REG   : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_REGISTERTRYING)));
16692       ast_cli(fd, "  Status       : ");
16693       peer_status(peer, status, sizeof(status));
16694       ast_cli(fd, "%s\n", status);
16695       ast_cli(fd, "  Useragent    : %s\n", peer->useragent);
16696       ast_cli(fd, "  Reg. Contact : %s\n", peer->fullcontact);
16697       ast_cli(fd, "  Qualify Freq : %d ms\n", peer->qualifyfreq);
16698       if (peer->chanvars) {
16699          ast_cli(fd, "  Variables    :\n");
16700          for (v = peer->chanvars ; v ; v = v->next)
16701             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
16702       }
16703 
16704       ast_cli(fd, "  Sess-Timers  : %s\n", stmode2str(peer->stimer.st_mode_oper));
16705       ast_cli(fd, "  Sess-Refresh : %s\n", strefresher2str(peer->stimer.st_ref));
16706       ast_cli(fd, "  Sess-Expires : %d secs\n", peer->stimer.st_max_se);
16707       ast_cli(fd, "  Min-Sess     : %d secs\n", peer->stimer.st_min_se);
16708       ast_cli(fd, "  RTP Engine   : %s\n", peer->engine);
16709       ast_cli(fd, "  Parkinglot   : %s\n", peer->parkinglot);
16710       ast_cli(fd, "  Use Reason   : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON)));
16711       ast_cli(fd, "  Encryption   : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP)));
16712       ast_cli(fd, "\n");
16713       peer = unref_peer(peer, "sip_show_peer: unref_peer: done with peer ptr");
16714    } else  if (peer && type == 1) { /* manager listing */
16715       char buffer[256];
16716       struct ast_str *mailbox_str = ast_str_alloca(512);
16717       astman_append(s, "Channeltype: SIP\r\n");
16718       astman_append(s, "ObjectName: %s\r\n", peer->name);
16719       astman_append(s, "ChanObjectType: peer\r\n");
16720       astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y");
16721       astman_append(s, "RemoteSecretExist: %s\r\n", ast_strlen_zero(peer->remotesecret)?"N":"Y");
16722       astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y");
16723       astman_append(s, "Context: %s\r\n", peer->context);
16724       astman_append(s, "Language: %s\r\n", peer->language);
16725       if (!ast_strlen_zero(peer->accountcode))
16726          astman_append(s, "Accountcode: %s\r\n", peer->accountcode);
16727       astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags));
16728       astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres));
16729       if (!ast_strlen_zero(peer->fromuser))
16730          astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser);
16731       if (!ast_strlen_zero(peer->fromdomain))
16732          astman_append(s, "SIP-FromDomain: %s\r\nSip-FromDomain-Port: %d\r\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT);
16733       astman_append(s, "Callgroup: ");
16734       astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->callgroup));
16735       astman_append(s, "Pickupgroup: ");
16736       astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->pickupgroup));
16737       astman_append(s, "MOHSuggest: %s\r\n", peer->mohsuggest);
16738       peer_mailboxes_to_str(&mailbox_str, peer);
16739       astman_append(s, "VoiceMailbox: %s\r\n", mailbox_str->str);
16740       astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
16741       astman_append(s, "Maxforwards: %d\r\n", peer->maxforwards);
16742       astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
16743       astman_append(s, "Maxforwards: %d\r\n", peer->maxforwards);
16744       astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
16745       astman_append(s, "Busy-level: %d\r\n", peer->busy_level);
16746       astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate);
16747       astman_append(s, "Dynamic: %s\r\n", peer->host_dynamic?"Y":"N");
16748       astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
16749       astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched, peer->expire));
16750       astman_append(s, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE)));
16751       astman_append(s, "SIP-Forcerport: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT)?"Y":"N"));
16752       astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N"));
16753       astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N"));
16754       astman_append(s, "SIP-DirectMedia: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_DIRECT_MEDIA)?"Y":"N"));
16755       astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N"));
16756       astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N"));
16757       astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N"));
16758       astman_append(s, "SIP-TextSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT)?"Y":"N"));
16759       astman_append(s, "SIP-T.38Support: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)?"Y":"N"));
16760       astman_append(s, "SIP-T.38EC: %s\r\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
16761       astman_append(s, "SIP-T.38MaxDtgrm: %d\r\n", peer->t38_maxdatagram);
16762       astman_append(s, "SIP-Sess-Timers: %s\r\n", stmode2str(peer->stimer.st_mode_oper));
16763       astman_append(s, "SIP-Sess-Refresh: %s\r\n", strefresher2str(peer->stimer.st_ref));
16764       astman_append(s, "SIP-Sess-Expires: %d\r\n", peer->stimer.st_max_se);
16765       astman_append(s, "SIP-Sess-Min: %d\r\n", peer->stimer.st_min_se);
16766       astman_append(s, "SIP-RTP-Engine: %s\r\n", peer->engine);
16767       astman_append(s, "SIP-Encryption: %s\r\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP) ? "Y" : "N");
16768 
16769       /* - is enumerated */
16770       astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
16771       astman_append(s, "ToHost: %s\r\n", peer->tohost);
16772       astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n", ast_sockaddr_stringify_addr(&peer->addr), ast_sockaddr_port(&peer->addr));
16773       astman_append(s, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_sockaddr_stringify_addr(&peer->defaddr), ast_sockaddr_port(&peer->defaddr));
16774       astman_append(s, "Default-Username: %s\r\n", peer->username);
16775       if (!ast_strlen_zero(sip_cfg.regcontext))
16776          astman_append(s, "RegExtension: %s\r\n", peer->regexten);
16777       astman_append(s, "Codecs: ");
16778       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
16779       astman_append(s, "%s\r\n", codec_buf);
16780       astman_append(s, "CodecOrder: ");
16781       pref = &peer->prefs;
16782       for(x = 0; x < 64 ; x++) {
16783          codec = ast_codec_pref_index(pref, x);
16784          if (!codec)
16785             break;
16786          astman_append(s, "%s", ast_getformatname(codec));
16787          if (x < 63 && ast_codec_pref_index(pref, x+1))
16788             astman_append(s, ",");
16789       }
16790 
16791       astman_append(s, "\r\n");
16792       astman_append(s, "Status: ");
16793       peer_status(peer, status, sizeof(status));
16794       astman_append(s, "%s\r\n", status);
16795       astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent);
16796       astman_append(s, "Reg-Contact: %s\r\n", peer->fullcontact);
16797       astman_append(s, "QualifyFreq: %d ms\r\n", peer->qualifyfreq);
16798       astman_append(s, "Parkinglot: %s\r\n", peer->parkinglot);
16799       if (peer->chanvars) {
16800          for (v = peer->chanvars ; v ; v = v->next) {
16801             astman_append(s, "ChanVariable: %s=%s\r\n", v->name, v->value);
16802          }
16803       }
16804       astman_append(s, "SIP-Use-Reason-Header : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON)) ? "Y" : "N");
16805 
16806       peer = unref_peer(peer, "sip_show_peer: unref_peer: done with peer");
16807 
16808    } else {
16809       ast_cli(fd, "Peer %s not found.\n", argv[3]);
16810       ast_cli(fd, "\n");
16811    }
16812 
16813    return CLI_SUCCESS;
16814 }

static char * _sip_show_peers ( int  fd,
int *  total,
struct mansession *  s,
const struct message *  m,
int  argc,
const char *  argv[] 
) [static]

Execute sip show peers command.

Definition at line 15877 of file chan_sip.c.

References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_calloc, ast_check_realtime(), ast_cli(), ast_copy_string(), ast_free, ast_sockaddr_isnull(), ast_sockaddr_port, AST_SOCKADDR_STR_HOST, ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_fmt(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), CLI_SHOWUSAGE, CLI_SUCCESS, FALSE, FORMAT, FORMAT2, id, name, peer_status(), peercomparefunc(), status, TRUE, and unref_peer().

Referenced by manager_sip_show_peers(), and sip_show_peers().

15878 {
15879    regex_t regexbuf;
15880    int havepattern = FALSE;
15881    struct sip_peer *peer;
15882    struct ao2_iterator i;
15883    
15884 /* the last argument is left-aligned, so we don't need a size anyways */
15885 #define FORMAT2 "%-25.25s  %-39.39s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n"
15886 #define FORMAT  "%-25.25s  %-39.39s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n"
15887 
15888    char name[256];
15889    int total_peers = 0;
15890    int peers_mon_online = 0;
15891    int peers_mon_offline = 0;
15892    int peers_unmon_offline = 0;
15893    int peers_unmon_online = 0;
15894    const char *id;
15895    char idtext[256] = "";
15896    int realtimepeers;
15897    int objcount = ao2_container_count(peers);
15898    struct sip_peer **peerarray;
15899    int k;
15900    
15901    
15902    realtimepeers = ast_check_realtime("sippeers");
15903    peerarray = ast_calloc(sizeof(struct sip_peer *), objcount);
15904 
15905    if (s) { /* Manager - get ActionID */
15906       id = astman_get_header(m, "ActionID");
15907       if (!ast_strlen_zero(id))
15908          snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
15909    }
15910 
15911    switch (argc) {
15912    case 5:
15913       if (!strcasecmp(argv[3], "like")) {
15914          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
15915             return CLI_SHOWUSAGE;
15916          havepattern = TRUE;
15917       } else
15918          return CLI_SHOWUSAGE;
15919    case 3:
15920       break;
15921    default:
15922       return CLI_SHOWUSAGE;
15923    }
15924 
15925    if (!s) /* Normal list */
15926       ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Forcerport", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""));
15927    
15928 
15929    i = ao2_iterator_init(peers, 0);
15930    while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {  
15931       ao2_lock(peer);
15932 
15933       if (!(peer->type & SIP_TYPE_PEER)) {
15934          ao2_unlock(peer);
15935          unref_peer(peer, "unref peer because it's actually a user");
15936          continue;
15937       }
15938 
15939       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0)) {
15940          objcount--;
15941          ao2_unlock(peer);
15942          unref_peer(peer, "toss iterator peer ptr before continue");
15943          continue;
15944       }
15945 
15946       peerarray[total_peers++] = peer;
15947       ao2_unlock(peer);
15948    }
15949    ao2_iterator_destroy(&i);
15950    
15951    qsort(peerarray, total_peers, sizeof(struct sip_peer *), peercomparefunc);
15952 
15953    for(k=0; k < total_peers; k++) {
15954       char status[20] = "";
15955       char srch[2000];
15956       char pstatus;
15957       peer = peerarray[k];
15958       
15959       ao2_lock(peer);
15960       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0)) {
15961          ao2_unlock(peer);
15962          unref_peer(peer, "toss iterator peer ptr before continue");
15963          continue;
15964       }
15965 
15966       if (!ast_strlen_zero(peer->username) && !s)
15967          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
15968       else
15969          ast_copy_string(name, peer->name, sizeof(name));
15970       
15971       pstatus = peer_status(peer, status, sizeof(status));
15972       if (pstatus == 1)
15973          peers_mon_online++;
15974       else if (pstatus == 0)
15975          peers_mon_offline++;
15976       else {
15977          if (ast_sockaddr_isnull(&peer->addr) ||
15978              !ast_sockaddr_port(&peer->addr)) {
15979             peers_unmon_offline++;
15980          } else {
15981             peers_unmon_online++;
15982          }
15983       }
15984 
15985       snprintf(srch, sizeof(srch), FORMAT, name,
15986          ast_sockaddr_isnull(&peer->addr) ? "(Unspecified)" : ast_sockaddr_stringify_addr(&peer->addr),
15987          peer->host_dynamic ? " D " : "   ",    /* Dynamic or not? */
15988          ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : "   ", /* NAT=yes? */
15989          peer->ha ? " A " : "   ",  /* permit/deny */
15990          ast_sockaddr_isnull(&peer->addr) ? 0 : ast_sockaddr_port(&peer->addr), status,
15991          realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "");
15992 
15993       if (!s)  {/* Normal CLI list */
15994          ast_cli(fd, FORMAT, name,
15995          ast_sockaddr_isnull(&peer->addr) ? "(Unspecified)" : ast_sockaddr_stringify_addr(&peer->addr),
15996          peer->host_dynamic ? " D " : "   ",    /* Dynamic or not? */
15997          ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : "   ", /* NAT=yes? */
15998          peer->ha ? " A " : "   ",       /* permit/deny */
15999          ast_sockaddr_isnull(&peer->addr) ? 0 : ast_sockaddr_port(&peer->addr), status,
16000          realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "");
16001       } else { /* Manager format */
16002          /* The names here need to be the same as other channels */
16003          astman_append(s,
16004          "Event: PeerEntry\r\n%s"
16005          "Channeltype: SIP\r\n"
16006          "ObjectName: %s\r\n"
16007          "ChanObjectType: peer\r\n" /* "peer" or "user" */
16008          "IPaddress: %s\r\n"
16009          "IPport: %d\r\n"
16010          "Dynamic: %s\r\n"
16011          "Forcerport: %s\r\n"
16012          "VideoSupport: %s\r\n"
16013          "TextSupport: %s\r\n"
16014          "ACL: %s\r\n"
16015          "Status: %s\r\n"
16016          "RealtimeDevice: %s\r\n\r\n",
16017          idtext,
16018          peer->name,
16019          ast_sockaddr_isnull(&peer->addr) ? "-none-" : ast_sockaddr_stringify_fmt(&peer->addr, AST_SOCKADDR_STR_HOST),
16020          ast_sockaddr_isnull(&peer->addr) ? 0 : ast_sockaddr_port(&peer->addr),
16021          peer->host_dynamic ? "yes" : "no",  /* Dynamic or not? */
16022          ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? "yes" : "no",  /* NAT=yes? */
16023          ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no",  /* VIDEOSUPPORT=yes? */
16024          ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "yes" : "no",   /* TEXTSUPPORT=yes? */
16025          peer->ha ? "yes" : "no",       /* permit/deny */
16026          status,
16027          realtimepeers ? (peer->is_realtime ? "yes":"no") : "no");
16028       }
16029       ao2_unlock(peer);
16030       unref_peer(peer, "toss iterator peer ptr");
16031    }
16032    
16033    if (!s)
16034       ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n",
16035               total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline);
16036 
16037    if (havepattern)
16038       regfree(&regexbuf);
16039 
16040    if (total)
16041       *total = total_peers;
16042    
16043    ast_free(peerarray);
16044    
16045    return CLI_SUCCESS;
16046 #undef FORMAT
16047 #undef FORMAT2
16048 }

static void * _sip_tcp_helper_thread ( struct sip_pvt *  pvt,
struct ast_tcptls_session_instance *  tcptls_session 
) [static]

SIP TCP thread management function This function reads from the socket, parses the packet into a request.

Todo:
XXX If there's no Content-Length or if the content-length and what we receive is not the same - we should generate an error

Definition at line 2473 of file chan_sip.c.

References ao2_t_find, ao2_t_ref, ast_atomic_fetchadd_int(), ast_debug, ast_log(), ast_str_create(), ast_tcptls_client_start(), authlimit, cleanup(), ast_tcptls_session_instance::client, errno, ast_tcptls_session_instance::fd, LOG_ERROR, OBJ_POINTER, ast_tcptls_session_instance::parent, sip_check_authtimeout(), sip_threadinfo_create(), ast_tcptls_session_instance::ssl, threadt, and unauth_sessions.

Referenced by sip_tcp_worker_fn().

02474 {
02475    int res, cl, timeout = -1, authenticated = 0, flags, after_poll = 0, need_poll = 1;
02476    time_t start;
02477    struct sip_request req = { 0, } , reqcpy = { 0, };
02478    struct sip_threadinfo *me = NULL;
02479    char buf[1024] = "";
02480    struct pollfd fds[2] = { { 0 }, { 0 }, };
02481    struct ast_tcptls_session_args *ca = NULL;
02482 
02483    /* If this is a server session, then the connection has already been
02484     * setup. Check if the authlimit has been reached and if not create the
02485     * threadinfo object so we can access this thread for writing.
02486     *
02487     * if this is a client connection more work must be done.
02488     * 1. We own the parent session args for a client connection.  This pointer needs
02489     *    to be held on to so we can decrement it's ref count on thread destruction.
02490     * 2. The threadinfo object was created before this thread was launched, however
02491     *    it must be found within the threadt table.
02492     * 3. Last, the tcptls_session must be started.
02493     */
02494    if (!tcptls_session->client) {
02495       if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) {
02496          /* unauth_sessions is decremented in the cleanup code */
02497          goto cleanup;
02498       }
02499 
02500       if ((flags = fcntl(tcptls_session->fd, F_GETFL)) == -1) {
02501          ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno));
02502          goto cleanup;
02503       }
02504 
02505       flags |= O_NONBLOCK;
02506       if (fcntl(tcptls_session->fd, F_SETFL, flags) == -1) {
02507          ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno));
02508          goto cleanup;
02509       }
02510 
02511       if (!(me = sip_threadinfo_create(tcptls_session, tcptls_session->ssl ? SIP_TRANSPORT_TLS : SIP_TRANSPORT_TCP))) {
02512          goto cleanup;
02513       }
02514       ao2_t_ref(me, +1, "Adding threadinfo ref for tcp_helper_thread");
02515    } else {
02516       struct sip_threadinfo tmp = {
02517          .tcptls_session = tcptls_session,
02518       };
02519 
02520       if ((!(ca = tcptls_session->parent)) ||
02521          (!(me = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread"))) ||
02522          (!(tcptls_session = ast_tcptls_client_start(tcptls_session)))) {
02523          goto cleanup;
02524       }
02525    }
02526 
02527    me->threadid = pthread_self();
02528    ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP");
02529 
02530    /* set up pollfd to watch for reads on both the socket and the alert_pipe */
02531    fds[0].fd = tcptls_session->fd;
02532    fds[1].fd = me->alert_pipe[0];
02533    fds[0].events = fds[1].events = POLLIN | POLLPRI;
02534 
02535    if (!(req.data = ast_str_create(SIP_MIN_PACKET))) {
02536       goto cleanup;
02537    }
02538    if (!(reqcpy.data = ast_str_create(SIP_MIN_PACKET))) {
02539       goto cleanup;
02540    }
02541 
02542    if(time(&start) == -1) {
02543       ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
02544       goto cleanup;
02545    }
02546 
02547    for (;;) {
02548       struct ast_str *str_save;
02549 
02550       if (!tcptls_session->client && req.authenticated && !authenticated) {
02551          authenticated = 1;
02552          ast_atomic_fetchadd_int(&unauth_sessions, -1);
02553       }
02554 
02555       /* calculate the timeout for unauthenticated server sessions */
02556       if (!tcptls_session->client && !authenticated ) {
02557          if ((timeout = sip_check_authtimeout(start)) < 0) {
02558             goto cleanup;
02559          }
02560 
02561          if (timeout == 0) {
02562             ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
02563             goto cleanup;
02564          }
02565       } else {
02566          timeout = -1;
02567       }
02568 
02569       res = ast_poll(fds, 2, timeout); /* polls for both socket and alert_pipe */
02570       if (res < 0) {
02571          ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res);
02572          goto cleanup;
02573       } else if (res == 0) {
02574          /* timeout */
02575          ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
02576          goto cleanup;
02577       }
02578 
02579       /* handle the socket event, check for both reads from the socket fd,
02580        * and writes from alert_pipe fd */
02581       if (fds[0].revents) { /* there is data on the socket to be read */
02582          after_poll = 1;
02583 
02584          fds[0].revents = 0;
02585 
02586          /* clear request structure */
02587          str_save = req.data;
02588          memset(&req, 0, sizeof(req));
02589          req.data = str_save;
02590          ast_str_reset(req.data);
02591 
02592          str_save = reqcpy.data;
02593          memset(&reqcpy, 0, sizeof(reqcpy));
02594          reqcpy.data = str_save;
02595          ast_str_reset(reqcpy.data);
02596 
02597          memset(buf, 0, sizeof(buf));
02598 
02599          if (tcptls_session->ssl) {
02600             set_socket_transport(&req.socket, SIP_TRANSPORT_TLS);
02601             req.socket.port = htons(ourport_tls);
02602          } else {
02603             set_socket_transport(&req.socket, SIP_TRANSPORT_TCP);
02604             req.socket.port = htons(ourport_tcp);
02605          }
02606          req.socket.fd = tcptls_session->fd;
02607 
02608          /* Read in headers one line at a time */
02609          while (req.len < 4 || strncmp(REQ_OFFSET_TO_STR(&req, len - 4), "\r\n\r\n", 4)) {
02610             if (!tcptls_session->client && !authenticated ) {
02611                if ((timeout = sip_check_authtimeout(start)) < 0) {
02612                   goto cleanup;
02613                }
02614 
02615                if (timeout == 0) {
02616                   ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
02617                   goto cleanup;
02618                }
02619             } else {
02620                timeout = -1;
02621             }
02622 
02623             /* special polling behavior is required for TLS
02624              * sockets because of the buffering done in the
02625              * TLS layer */
02626             if (!tcptls_session->ssl || need_poll) {
02627                need_poll = 0;
02628                after_poll = 1;
02629                res = ast_wait_for_input(tcptls_session->fd, timeout);
02630                if (res < 0) {
02631                   ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res);
02632                   goto cleanup;
02633                } else if (res == 0) {
02634                   /* timeout */
02635                   ast_debug(2, "SIP TCP server timed out\n");
02636                   goto cleanup;
02637                }
02638             }
02639 
02640             ast_mutex_lock(&tcptls_session->lock);
02641             if (!fgets(buf, sizeof(buf), tcptls_session->f)) {
02642                ast_mutex_unlock(&tcptls_session->lock);
02643                if (after_poll) {
02644                   goto cleanup;
02645                } else {
02646                   need_poll = 1;
02647                   continue;
02648                }
02649             }
02650             ast_mutex_unlock(&tcptls_session->lock);
02651             after_poll = 0;
02652             if (me->stop) {
02653                 goto cleanup;
02654             }
02655             ast_str_append(&req.data, 0, "%s", buf);
02656             req.len = req.data->used;
02657          }
02658          copy_request(&reqcpy, &req);
02659          parse_request(&reqcpy);
02660          /* In order to know how much to read, we need the content-length header */
02661          if (sscanf(get_header(&reqcpy, "Content-Length"), "%30d", &cl)) {
02662             while (cl > 0) {
02663                size_t bytes_read;
02664                if (!tcptls_session->client && !authenticated ) {
02665                   if ((timeout = sip_check_authtimeout(start)) < 0) {
02666                      goto cleanup;
02667                   }
02668 
02669                   if (timeout == 0) {
02670                      ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
02671                      goto cleanup;
02672                   }
02673                } else {
02674                   timeout = -1;
02675                }
02676 
02677                if (!tcptls_session->ssl || need_poll) {
02678                   need_poll = 0;
02679                   after_poll = 1;
02680                   res = ast_wait_for_input(tcptls_session->fd, timeout);
02681                   if (res < 0) {
02682                      ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res);
02683                      goto cleanup;
02684                   } else if (res == 0) {
02685                      /* timeout */
02686                      ast_debug(2, "SIP TCP server timed out\n");
02687                      goto cleanup;
02688                   }
02689                }
02690 
02691                ast_mutex_lock(&tcptls_session->lock);
02692                if (!(bytes_read = fread(buf, 1, MIN(sizeof(buf) - 1, cl), tcptls_session->f))) {
02693                   ast_mutex_unlock(&tcptls_session->lock);
02694                   if (after_poll) {
02695                      goto cleanup;
02696                   } else {
02697                      need_poll = 1;
02698                      continue;
02699                   }
02700                }
02701                buf[bytes_read] = '\0';
02702                ast_mutex_unlock(&tcptls_session->lock);
02703                after_poll = 0;
02704                if (me->stop) {
02705                   goto cleanup;
02706                }
02707                cl -= strlen(buf);
02708                ast_str_append(&req.data, 0, "%s", buf);
02709                req.len = req.data->used;
02710             }
02711          }
02712          /*! \todo XXX If there's no Content-Length or if the content-length and what
02713                we receive is not the same - we should generate an error */
02714 
02715          req.socket.tcptls_session = tcptls_session;
02716          handle_request_do(&req, &tcptls_session->remote_address);
02717       }
02718 
02719       if (fds[1].revents) { /* alert_pipe indicates there is data in the send queue to be sent */
02720          enum sip_tcptls_alert alert;
02721          struct tcptls_packet *packet;
02722 
02723          fds[1].revents = 0;
02724 
02725          if (read(me->alert_pipe[0], &alert, sizeof(alert)) == -1) {
02726             ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
02727             continue;
02728          }
02729 
02730          switch (alert) {
02731          case TCPTLS_ALERT_STOP:
02732             goto cleanup;
02733          case TCPTLS_ALERT_DATA:
02734             ao2_lock(me);
02735             if (!(packet = AST_LIST_REMOVE_HEAD(&me->packet_q, entry))) {
02736                ast_log(LOG_WARNING, "TCPTLS thread alert_pipe indicated packet should be sent, but frame_q is empty");
02737             } else if (ast_tcptls_server_write(tcptls_session, ast_str_buffer(packet->data), packet->len) == -1) {
02738                ast_log(LOG_WARNING, "Failure to write to tcp/tls socket\n");
02739             }
02740 
02741             if (packet) {
02742                ao2_t_ref(packet, -1, "tcptls packet sent, this is no longer needed");
02743             }
02744             ao2_unlock(me);
02745             break;
02746          default:
02747             ast_log(LOG_ERROR, "Unknown tcptls thread alert '%d'\n", alert);
02748          }
02749       }
02750    }
02751 
02752    ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP");
02753 
02754 cleanup:
02755    if (tcptls_session && !tcptls_session->client && !authenticated) {
02756       ast_atomic_fetchadd_int(&unauth_sessions, -1);
02757    }
02758 
02759    if (me) {
02760       ao2_t_unlink(threadt, me, "Removing tcptls helper thread, thread is closing");
02761       ao2_t_ref(me, -1, "Removing tcp_helper_threads threadinfo ref");
02762    }
02763    deinit_req(&reqcpy);
02764    deinit_req(&req);
02765 
02766    /* if client, we own the parent session arguments and must decrement ref */
02767    if (ca) {
02768       ao2_t_ref(ca, -1, "closing tcptls thread, getting rid of client tcptls_session arguments");
02769    }
02770 
02771    if (tcptls_session) {
02772       ast_mutex_lock(&tcptls_session->lock);
02773       if (tcptls_session->f) {
02774          fclose(tcptls_session->f);
02775          tcptls_session->f = NULL;
02776       }
02777       if (tcptls_session->fd != -1) {
02778          close(tcptls_session->fd);
02779          tcptls_session->fd = -1;
02780       }
02781       tcptls_session->parent = NULL;
02782       ast_mutex_unlock(&tcptls_session->lock);
02783 
02784       ao2_ref(tcptls_session, -1);
02785       tcptls_session = NULL;
02786    }
02787    return NULL;
02788 }

static void add_blank ( struct sip_request *  req  )  [static]

add a blank line if no body

Definition at line 4000 of file chan_sip.c.

References ast_str_append(), and ast_str_strlen().

Referenced by send_request(), and send_response().

04001 {
04002    if (!req->lines) {
04003       /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
04004       ast_str_append(&req->data, 0, "\r\n");
04005       req->len = ast_str_strlen(req->data);
04006    }
04007 }

static void add_cc_call_info_to_response ( struct sip_pvt *  p,
struct sip_request *  resp 
) [static]

Definition at line 11117 of file chan_sip.c.

References add_header(), ao2_ref, ast_copy_string(), ast_log(), ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_strlen_zero(), find_sip_cc_agent_by_original_callid(), generate_uri(), LOG_WARNING, and ast_cc_agent::private_data.

Referenced by __transmit_response(), and transmit_response_with_sdp().

11118 {
11119    char uri[SIPBUFSIZE];
11120    struct ast_str *header = ast_str_alloca(SIPBUFSIZE);
11121    struct ast_cc_agent *agent = find_sip_cc_agent_by_original_callid(p);
11122    struct sip_cc_agent_pvt *agent_pvt;
11123 
11124    if (!agent) {
11125       /* Um, what? How could the SIP_OFFER_CC flag be set but there not be an
11126        * agent? Oh well, we'll just warn and return without adding the header.
11127        */
11128       ast_log(LOG_WARNING, "Can't find SIP CC agent for call '%s' even though OFFER_CC flag was set?\n", p->callid);
11129       return;
11130    }
11131 
11132    agent_pvt = agent->private_data;
11133 
11134    if (!ast_strlen_zero(agent_pvt->subscribe_uri)) {
11135       ast_copy_string(uri, agent_pvt->subscribe_uri, sizeof(uri));
11136    } else {
11137       generate_uri(p, uri, sizeof(uri));
11138       ast_copy_string(agent_pvt->subscribe_uri, uri, sizeof(agent_pvt->subscribe_uri));
11139    }
11140    /* XXX Hardcode "NR" as the m reason for now. This should perhaps be changed
11141     * to be more accurate. This parameter has no bearing on the actual operation
11142     * of the feature; it's just there for informational purposes.
11143     */
11144    ast_str_set(&header, 0, "<%s>;purpose=call-completion;m=%s", uri, "NR");
11145    add_header(resp, "Call-Info", ast_str_buffer(header));
11146    ao2_ref(agent, -1);
11147 }

static void add_codec_to_sdp ( const struct sip_pvt *  p,
format_t  codec,
struct ast_str **  m_buf,
struct ast_str **  a_buf,
int  debug,
int *  min_packet_size 
) [static]

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

Definition at line 10417 of file chan_sip.c.

References ast_codec_pref_getsize(), AST_FORMAT_G719, AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_ILBC, AST_FORMAT_SIREN14, AST_FORMAT_SIREN7, ast_getformatname(), ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), AST_RTP_OPT_G726_NONSTANDARD, ast_str_append(), ast_test_flag, ast_verbose, ast_format_list::cur_ms, and ast_rtp_codecs::pref.

Referenced by add_sdp().

10420 {
10421    int rtp_code;
10422    struct ast_format_list fmt;
10423 
10424 
10425    if (debug)
10426       ast_verbose("Adding codec 0x%" PRIx64 " (%s) to SDP\n", codec, ast_getformatname(codec));
10427    if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 1, codec)) == -1)
10428       return;
10429 
10430    if (p->rtp) {
10431       struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref;
10432       fmt = ast_codec_pref_getsize(pref, codec);
10433    } else /* I don't see how you couldn't have p->rtp, but good to check for and error out if not there like earlier code */
10434       return;
10435    ast_str_append(m_buf, 0, " %d", rtp_code);
10436    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
10437              ast_rtp_lookup_mime_subtype2(1, codec,
10438                      ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
10439              ast_rtp_lookup_sample_rate2(1, codec));
10440 
10441    switch (codec) {
10442    case AST_FORMAT_G729A:
10443       /* Indicate that we don't support VAD (G.729 annex B) */
10444       ast_str_append(a_buf, 0, "a=fmtp:%d annexb=no\r\n", rtp_code);
10445       break;
10446    case AST_FORMAT_G723_1:
10447       /* Indicate that we don't support VAD (G.723.1 annex A) */
10448       ast_str_append(a_buf, 0, "a=fmtp:%d annexa=no\r\n", rtp_code);
10449       break;
10450    case AST_FORMAT_ILBC:
10451       /* Add information about us using only 20/30 ms packetization */
10452       ast_str_append(a_buf, 0, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
10453       break;
10454    case AST_FORMAT_SIREN7:
10455       /* Indicate that we only expect 32Kbps */
10456       ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=32000\r\n", rtp_code);
10457       break;
10458    case AST_FORMAT_SIREN14:
10459       /* Indicate that we only expect 48Kbps */
10460       ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=48000\r\n", rtp_code);
10461       break;
10462    case AST_FORMAT_G719:
10463       /* Indicate that we only expect 64Kbps */
10464       ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=64000\r\n", rtp_code);
10465       break;
10466    }
10467 
10468    if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))
10469       *min_packet_size = fmt.cur_ms;
10470 
10471    /* Our first codec packetization processed cannot be zero */
10472    if ((*min_packet_size)==0 && fmt.cur_ms)
10473       *min_packet_size = fmt.cur_ms;
10474 }

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

Add content (not header) to SIP message.

Definition at line 9371 of file chan_sip.c.

References ast_log(), ast_str_append(), and LOG_WARNING.

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

09372 {
09373    if (req->lines) {
09374       ast_log(LOG_WARNING, "Can't add more content when the content has been finalized\n");
09375       return -1;
09376    }
09377 
09378    ast_str_append(&req->content, 0, "%s", line);
09379    return 0;
09380 }

static int add_digit ( struct sip_request *  req,
char  digit,
unsigned int  duration,
int  mode 
) [static]

Add DTMF INFO tone to sip message Mode = 0 for application/dtmf-relay (Cisco) 1 for application/dtmf.

Definition at line 10281 of file chan_sip.c.

References add_content(), and add_header().

Referenced by transmit_info_with_digit().

10282 {
10283    char tmp[256];
10284    int event;
10285    if (mode) {
10286       /* Application/dtmf short version used by some implementations */
10287       if (digit == '*')
10288          event = 10;
10289       else if (digit == '#')
10290          event = 11;
10291       else if ((digit >= 'A') && (digit <= 'D'))
10292          event = 12 + digit - 'A';
10293       else
10294          event = atoi(&digit);
10295       snprintf(tmp, sizeof(tmp), "%d\r\n", event);
10296       add_header(req, "Content-Type", "application/dtmf");
10297       add_content(req, tmp);
10298    } else {
10299       /* Application/dtmf-relay as documented by Cisco */
10300       snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration);
10301       add_header(req, "Content-Type", "application/dtmf-relay");
10302       add_content(req, tmp);
10303    }
10304    return 0;
10305 }

static void add_diversion_header ( struct sip_request *  req,
struct sip_pvt *  pvt 
) [static]

Add "Diversion" header to outgoing message.

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

Parameters:
req The request/response to which we will add the header
pvt The sip_pvt which represents the call-leg

Definition at line 11502 of file chan_sip.c.

References add_header(), ast_sockaddr_stringify_host(), ast_strlen_zero(), and sip_reason_code_to_str().

Referenced by transmit_invite(), and update_redirecting().

11503 {
11504    const char *diverting_number;
11505    const char *diverting_name;
11506    const char *reason;
11507    char header_text[256];
11508 
11509    if (!pvt->owner) {
11510       return;
11511    }
11512 
11513    diverting_number = pvt->owner->redirecting.from.number.str;
11514    if (!pvt->owner->redirecting.from.number.valid
11515       || ast_strlen_zero(diverting_number)) {
11516       return;
11517    }
11518 
11519    reason = sip_reason_code_to_str(pvt->owner->redirecting.reason);
11520 
11521    /* We at least have a number to place in the Diversion header, which is enough */
11522    diverting_name = pvt->owner->redirecting.from.name.str;
11523    if (!pvt->owner->redirecting.from.name.valid
11524       || ast_strlen_zero(diverting_name)) {
11525       snprintf(header_text, sizeof(header_text), "<sip:%s@%s>;reason=%s", diverting_number,
11526             ast_sockaddr_stringify_host(&pvt->ourip), reason);
11527    } else {
11528       snprintf(header_text, sizeof(header_text), "\"%s\" <sip:%s@%s>;reason=%s",
11529             diverting_name, diverting_number,
11530             ast_sockaddr_stringify_host(&pvt->ourip), reason);
11531    }
11532 
11533    add_header(req, "Diversion", header_text);
11534 }

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

Add header to SIP message.

Definition at line 9311 of file chan_sip.c.

References ast_log(), ast_str_append(), ast_str_strlen(), find_alias(), LOG_WARNING, and sip_cfg.

09312 {
09313    if (req->headers == SIP_MAX_HEADERS) {
09314       ast_log(LOG_WARNING, "Out of SIP header space\n");
09315       return -1;
09316    }
09317 
09318    if (req->lines) {
09319       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
09320       return -1;
09321    }
09322 
09323    if (sip_cfg.compactheaders) {
09324       var = find_alias(var, var);
09325    }
09326 
09327    ast_str_append(&req->data, 0, "%s: %s\r\n", var, value);
09328    req->header[req->headers] = req->len;
09329 
09330    req->len = ast_str_strlen(req->data);
09331    req->headers++;
09332 
09333    return 0;   
09334 }

static int add_header_max_forwards ( struct sip_pvt *  dialog,
struct sip_request *  req 
) [static]

Add 'Max-Forwards' header to SIP message.

Precondition:
dialog is assumed to be locked while calling this function

Definition at line 9340 of file chan_sip.c.

References add_header().

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

09341 {
09342    char clen[10];
09343 
09344    snprintf(clen, sizeof(clen), "%d", dialog->maxforwards);
09345 
09346    return add_header(req, "Max-Forwards", clen);
09347 }

static void add_noncodec_to_sdp ( const struct sip_pvt *  p,
int  format,
struct ast_str **  m_buf,
struct ast_str **  a_buf,
int  debug 
) [static]

Add RFC 2833 DTMF offer to SDP.

Definition at line 10555 of file chan_sip.c.

References ast_rtp_codecs_payload_code(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_str_append(), and ast_verbose.

Referenced by add_sdp().

10558 {
10559    int rtp_code;
10560 
10561    if (debug)
10562       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype2(0, format, 0));
10563    if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 0, format)) == -1)
10564       return;
10565 
10566    ast_str_append(m_buf, 0, " %d", rtp_code);
10567    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
10568              ast_rtp_lookup_mime_subtype2(0, format, 0),
10569              ast_rtp_lookup_sample_rate2(0, format));
10570    if (format == AST_RTP_DTMF)   /* Indicate we support DTMF and FLASH... */
10571       ast_str_append(a_buf, 0, "a=fmtp:%d 0-16\r\n", rtp_code);
10572 }

static void add_peer_mailboxes ( struct sip_peer *  peer,
const char *  value 
) [static]

Todo:
document this function

Definition at line 25979 of file chan_sip.c.

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_strdupa, ast_strlen_zero(), context, mailbox, mbox(), S_OR, and strsep().

Referenced by build_peer().

25980 {
25981    char *next, *mbox, *context;
25982 
25983    next = ast_strdupa(value);
25984 
25985    while ((mbox = context = strsep(&next, ","))) {
25986       struct sip_mailbox *mailbox;
25987       int duplicate = 0;
25988 
25989       strsep(&context, "@");
25990 
25991       if (ast_strlen_zero(mbox)) {
25992          continue;
25993       }
25994 
25995       /* Check whether the mailbox is already in the list */
25996       AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
25997          if (!strcmp(mailbox->mailbox, mbox) && !strcmp(S_OR(mailbox->context, ""), S_OR(context, ""))) {
25998             duplicate = 1;
25999             mailbox->delme = 0;
26000             break;
26001          }
26002       }
26003       if (duplicate) {
26004          continue;
26005       }
26006 
26007       if (!(mailbox = ast_calloc(1, sizeof(*mailbox) + strlen(mbox) + strlen(S_OR(context, ""))))) {
26008          continue;
26009       }
26010 
26011       if (!ast_strlen_zero(context)) {
26012          mailbox->context = mailbox->mailbox + strlen(mbox) + 1;
26013          strcpy(mailbox->context, context); /* SAFE */
26014       }
26015       strcpy(mailbox->mailbox, mbox); /* SAFE */
26016 
26017       AST_LIST_INSERT_TAIL(&peer->mailboxes, mailbox, entry);
26018    }
26019 }

static void add_peer_mwi_subs ( struct sip_peer *  peer  )  [static]

Definition at line 23303 of file chan_sip.c.

References AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), AST_LIST_TRAVERSE, mailbox, mwi_event_cb(), and S_OR.

Referenced by build_peer(), and handle_request_subscribe().

23304 {
23305    struct sip_mailbox *mailbox;
23306 
23307    AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
23308       mailbox->event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "SIP mbox event", peer,
23309          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox,
23310          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"),
23311          AST_EVENT_IE_END);
23312    }
23313 }

static struct sip_auth * add_realm_authentication ( struct sip_auth *  authlist,
const char *  configuration,
int  lineno 
) [static]

Add realm authentication in list.

Definition at line 25787 of file chan_sip.c.

References ast_calloc, ast_copy_string(), ast_debug, ast_log(), ast_strlen_zero(), ast_verb, LOG_WARNING, and secret.

Referenced by build_peer().

25788 {
25789    char authcopy[256];
25790    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
25791    struct sip_auth *a, *b, *auth;
25792 
25793    if (ast_strlen_zero(configuration))
25794       return authlist;
25795 
25796    ast_debug(1, "Auth config ::  %s\n", configuration);
25797 
25798    ast_copy_string(authcopy, configuration, sizeof(authcopy));
25799    username = authcopy;
25800 
25801    /* split user[:secret] and relm */
25802    realm = strrchr(username, '@');
25803    if (realm)
25804       *realm++ = '\0';
25805    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
25806       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
25807       return authlist;
25808    }
25809 
25810    /* parse username at ':' for secret, or '#" for md5secret */
25811    if ((secret = strchr(username, ':'))) {
25812       *secret++ = '\0';
25813    } else if ((md5secret = strchr(username, '#'))) {
25814       *md5secret++ = '\0';
25815    }
25816 
25817    if (!(auth = ast_calloc(1, sizeof(*auth))))
25818       return authlist;
25819 
25820    ast_copy_string(auth->realm, realm, sizeof(auth->realm));
25821    ast_copy_string(auth->username, username, sizeof(auth->username));
25822    if (secret)
25823       ast_copy_string(auth->secret, secret, sizeof(auth->secret));
25824    if (md5secret)
25825       ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
25826 
25827    /* find the end of the list */
25828    for (b = NULL, a = authlist; a ; b = a, a = a->next)
25829       ;
25830    if (b)
25831       b->next = auth;   /* Add structure add end of list */
25832    else
25833       authlist = auth;
25834 
25835    ast_verb(3, "Added authentication for realm %s\n", realm);
25836 
25837    return authlist;
25838 
25839 }

static void add_route ( struct sip_request *  req,
struct sip_route *  route 
) [static]

Add route header into request per learned route.

Definition at line 9482 of file chan_sip.c.

References add_header(), and ast_copy_string().

Referenced by initreqprep(), and reqprep().

09483 {
09484    char r[SIPBUFSIZE*2], *p;
09485    int n, rem = sizeof(r);
09486 
09487    if (!route)
09488       return;
09489 
09490    p = r;
09491    for (;route ; route = route->next) {
09492       n = strlen(route->hop);
09493       if (rem < n+3) /* we need room for ",<route>" */
09494          break;
09495       if (p != r) {  /* add a separator after fist route */
09496          *p++ = ',';
09497          --rem;
09498       }
09499       *p++ = '<';
09500       ast_copy_string(p, route->hop, rem); /* cannot fail */
09501       p += n;
09502       *p++ = '>';
09503       rem -= (n+2);
09504    }
09505    *p = '\0';
09506    add_header(req, "Route", r);
09507 }

static int add_rpid ( struct sip_request *  req,
struct sip_pvt *  p 
) [static]

Add Remote-Party-ID header to SIP message.

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

Definition at line 10311 of file chan_sip.c.

References add_header(), ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_sockaddr_stringify_host(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_strlen_zero(), ast_test_flag, ast_uri_encode(), and S_OR.

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

10312 {
10313    struct ast_str *tmp = ast_str_alloca(256);
10314    char tmp2[256];
10315    char *lid_num = NULL;
10316    char *lid_name = NULL;
10317    int lid_pres;
10318    const char *fromdomain;
10319    const char *privacy = NULL;
10320    const char *screen = NULL;
10321    const char *anonymous_string = "\"Anonymous\" <sip:anonymous@anonymous.invalid>";
10322 
10323    if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) {
10324       return 0;
10325    }
10326 
10327    if (p->owner && p->owner->connected.id.number.valid
10328       && p->owner->connected.id.number.str) {
10329       lid_num = p->owner->connected.id.number.str;
10330    }
10331    if (p->owner && p->owner->connected.id.name.valid
10332       && p->owner->connected.id.name.str) {
10333       lid_name = p->owner->connected.id.name.str;
10334    }
10335    lid_pres = (p->owner) ? ast_party_id_presentation(&p->owner->connected.id) : AST_PRES_NUMBER_NOT_AVAILABLE;
10336 
10337    if (ast_strlen_zero(lid_num))
10338       return 0;
10339    if (ast_strlen_zero(lid_name))
10340       lid_name = lid_num;
10341    fromdomain = S_OR(p->fromdomain, ast_sockaddr_stringify_host(&p->ourip));
10342 
10343    lid_num = ast_uri_encode(lid_num, tmp2, sizeof(tmp2), 1);
10344 
10345    if (ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI)) {
10346       if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
10347          ast_str_set(&tmp, -1, "%s", anonymous_string);
10348       } else {
10349          ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>", lid_name, lid_num, fromdomain);
10350       }
10351       add_header(req, "P-Asserted-Identity", ast_str_buffer(tmp));
10352    } else {
10353       ast_str_set(&tmp, -1, "\"%s\" <sip:%s@%s>;party=%s", lid_name, lid_num, fromdomain, ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "calling" : "called");
10354 
10355       switch (lid_pres) {
10356       case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
10357       case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
10358          privacy = "off";
10359          screen = "no";
10360          break;
10361       case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
10362       case AST_PRES_ALLOWED_NETWORK_NUMBER:
10363          privacy = "off";
10364          screen = "yes";
10365          break;
10366       case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
10367       case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
10368          privacy = "full";
10369          screen = "no";
10370          break;
10371       case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
10372       case AST_PRES_PROHIB_NETWORK_NUMBER:
10373          privacy = "full";
10374          screen = "yes";
10375          break;
10376       case AST_PRES_NUMBER_NOT_AVAILABLE:
10377          break;
10378       default:
10379          if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
10380             privacy = "full";
10381          }
10382          else
10383             privacy = "off";
10384          screen = "no";
10385          break;
10386       }
10387 
10388       if (!ast_strlen_zero(privacy) && !ast_strlen_zero(screen)) {
10389          ast_str_append(&tmp, -1, ";privacy=%s;screen=%s", privacy, screen);
10390       }
10391 
10392       add_header(req, "Remote-Party-ID", ast_str_buffer(tmp));
10393    }
10394    return 0;
10395 }

static enum sip_result add_sdp ( struct sip_request *  resp,
struct sip_pvt *  p,
int  oldsdp,
int  add_audio,
int  add_t38 
) [static]

Add Session Description Protocol message.

If oldsdp is TRUE, then the SDP version number is not incremented. This mechanism is used in Session-Timers where RE-INVITEs are used for refreshing SIP sessions without modifying the media session in any way.

Definition at line 10693 of file chan_sip.c.

References add_codec_to_sdp(), add_content(), add_header(), add_noncodec_to_sdp(), add_tcodec_to_sdp(), add_vcodec_to_sdp(), ast_codec_pref_index(), ast_debug, AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_internal_timing_enabled(), ast_log(), ast_random(), AST_RTP_MAX, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_is_ipv4_mapped(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_str_alloca, ast_str_append(), ast_strlen_zero(), AST_T38_RATE_MANAGEMENT_LOCAL_TCF, AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), ast_verbose, capability, debug, FALSE, get_crypto_attrib(), get_our_media_address(), global_sdpowner, global_sdpsession, LOG_WARNING, sip_debug_test_pvt(), sipdebug_text, t38_get_rate(), TRUE, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, and version.

10694 {
10695    format_t alreadysent = 0;
10696    int doing_directmedia = FALSE;
10697 
10698    struct ast_sockaddr addr = { {0,} };
10699    struct ast_sockaddr vaddr = { {0,} };
10700    struct ast_sockaddr taddr = { {0,} };
10701    struct ast_sockaddr udptladdr = { {0,} };
10702    struct ast_sockaddr dest = { {0,} };
10703    struct ast_sockaddr vdest = { {0,} };
10704    struct ast_sockaddr tdest = { {0,} };
10705    struct ast_sockaddr udptldest = { {0,} };
10706 
10707    /* SDP fields */
10708    char *version =   "v=0\r\n";     /* Protocol version */
10709    char subject[256];            /* Subject of the session */
10710    char owner[256];           /* Session owner/creator */
10711    char connection[256];            /* Connection data */
10712    char *session_time = "t=0 0\r\n";         /* Time the session is active */
10713    char bandwidth[256] = "";        /* Max bitrate */
10714    char *hold = "";
10715    struct ast_str *m_audio = ast_str_alloca(256);  /* Media declaration line for audio */
10716    struct ast_str *m_video = ast_str_alloca(256);  /* Media declaration line for video */
10717    struct ast_str *m_text = ast_str_alloca(256);   /* Media declaration line for text */
10718    struct ast_str *m_modem = ast_str_alloca(256);  /* Media declaration line for modem */
10719    struct ast_str *a_audio = ast_str_alloca(1024); /* Attributes for audio */
10720    struct ast_str *a_video = ast_str_alloca(1024); /* Attributes for video */
10721    struct ast_str *a_text = ast_str_alloca(1024);  /* Attributes for text */
10722    struct ast_str *a_modem = ast_str_alloca(1024); /* Attributes for modem */
10723    const char *a_crypto = NULL;
10724    const char *v_a_crypto = NULL;
10725    const char *t_a_crypto = NULL;
10726 
10727    format_t x;
10728    format_t capability = 0;
10729    int needaudio = FALSE;
10730    int needvideo = FALSE;
10731    int needtext = FALSE;
10732    int debug = sip_debug_test_pvt(p);
10733    int min_audio_packet_size = 0;
10734    int min_video_packet_size = 0;
10735    int min_text_packet_size = 0;
10736 
10737    char codecbuf[SIPBUFSIZE];
10738    char buf[SIPBUFSIZE];
10739    char dummy_answer[256];
10740 
10741    /* Set the SDP session name */
10742    snprintf(subject, sizeof(subject), "s=%s\r\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession);
10743 
10744    if (!p->rtp) {
10745       ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
10746       return AST_FAILURE;
10747    }
10748    /* XXX We should not change properties in the SIP dialog until
10749       we have acceptance of the offer if this is a re-invite */
10750 
10751    /* Set RTP Session ID and version */
10752    if (!p->sessionid) {
10753       p->sessionid = (int)ast_random();
10754       p->sessionversion = p->sessionid;
10755    } else {
10756       if (oldsdp == FALSE)
10757          p->sessionversion++;
10758    }
10759 
10760    if (add_audio) {
10761       doing_directmedia = (!ast_sockaddr_isnull(&p->redirip) && p->redircodecs) ? TRUE : FALSE;
10762       /* Check if we need video in this call */
10763       if ((p->jointcapability & AST_FORMAT_VIDEO_MASK) && !p->novideo) {
10764          if (p->vrtp) {
10765             needvideo = TRUE;
10766             ast_debug(2, "This call needs video offers!\n");
10767          } else
10768             ast_debug(2, "This call needs video offers, but there's no video support enabled!\n");
10769       }
10770       /* Check if we need text in this call */
10771       if ((p->jointcapability & AST_FORMAT_TEXT_MASK) && !p->notext) {
10772          if (sipdebug_text)
10773             ast_verbose("We think we can do text\n");
10774          if (p->trtp) {
10775             if (sipdebug_text) {
10776                ast_verbose("And we have a text rtp object\n");
10777             }
10778             needtext = TRUE;
10779             ast_debug(2, "This call needs text offers! \n");
10780          } else {
10781             ast_debug(2, "This call needs text offers, but there's no text support enabled ! \n");
10782          }
10783       }
10784    }
10785 
10786    get_our_media_address(p, needvideo, needtext, &addr, &vaddr, &taddr, &dest, &vdest, &tdest);
10787 
10788    snprintf(owner, sizeof(owner), "o=%s %d %d IN %s %s\r\n",
10789        ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner,
10790        p->sessionid, p->sessionversion,
10791        (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ?
10792          "IP6" : "IP4",
10793        ast_sockaddr_stringify_addr(&dest));
10794 
10795    snprintf(connection, sizeof(connection), "c=IN %s %s\r\n",
10796        (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ?
10797          "IP6" : "IP4",
10798        ast_sockaddr_stringify_addr(&dest));
10799 
10800    if (add_audio) {
10801       if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) {
10802          hold = "a=recvonly\r\n";
10803          doing_directmedia = FALSE;
10804       } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) {
10805          hold = "a=inactive\r\n";
10806          doing_directmedia = FALSE;
10807       } else {
10808          hold = "a=sendrecv\r\n";
10809       }
10810 
10811       capability = p->jointcapability;
10812 
10813       /* XXX note, Video and Text are negated - 'true' means 'no' */
10814       ast_debug(1, "** Our capability: %s Video flag: %s Text flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability),
10815            p->novideo ? "True" : "False", p->notext ? "True" : "False");
10816       ast_debug(1, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec));
10817 
10818       if (doing_directmedia) {
10819          capability &= p->redircodecs;
10820          ast_debug(1, "** Our native-bridge filtered capablity: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability));
10821       }
10822 
10823       /* Check if we need audio */
10824       if (capability & AST_FORMAT_AUDIO_MASK)
10825          needaudio = TRUE;
10826 
10827       if (debug) {
10828          ast_verbose("Audio is at %s\n", ast_sockaddr_stringify_port(&p->ourip));
10829       }
10830 
10831       /* Ok, we need video. Let's add what we need for video and set codecs.
10832          Video is handled differently than audio since we can not transcode. */
10833       if (needvideo) {
10834          get_crypto_attrib(p->vsrtp, &v_a_crypto);
10835          ast_str_append(&m_video, 0, "m=video %d RTP/%s", ast_sockaddr_port(&vdest),
10836             v_a_crypto ? "SAVP" : "AVP");
10837 
10838          /* Build max bitrate string */
10839          if (p->maxcallbitrate)
10840             snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate);
10841          if (debug) {
10842             ast_verbose("Video is at %s\n", ast_sockaddr_stringify(&p->ourip));
10843          }
10844       }
10845 
10846       /* Ok, we need text. Let's add what we need for text and set codecs.
10847          Text is handled differently than audio since we can not transcode. */
10848       if (needtext) {
10849          if (sipdebug_text)
10850             ast_verbose("Lets set up the text sdp\n");
10851          get_crypto_attrib(p->tsrtp, &t_a_crypto);
10852          ast_str_append(&m_text, 0, "m=text %d RTP/%s", ast_sockaddr_port(&tdest),
10853             t_a_crypto ? "SAVP" : "AVP");
10854          if (debug) {  /* XXX should I use tdest below ? */
10855             ast_verbose("Text is at %s\n", ast_sockaddr_stringify(&p->ourip));
10856          }
10857       }
10858 
10859       /* Start building generic SDP headers */
10860 
10861       /* We break with the "recommendation" and send our IP, in order that our
10862          peer doesn't have to ast_gethostbyname() us */
10863 
10864       get_crypto_attrib(p->srtp, &a_crypto);
10865       ast_str_append(&m_audio, 0, "m=audio %d RTP/%s", ast_sockaddr_port(&dest),
10866          a_crypto ? "SAVP" : "AVP");
10867 
10868       /* Now, start adding audio codecs. These are added in this order:
10869          - First what was requested by the calling channel
10870          - Then preferences in order from sip.conf device config for this peer/user
10871          - Then other codecs in capabilities, including video
10872       */
10873 
10874       /* Prefer the audio codec we were requested to use, first, no matter what
10875          Note that p->prefcodec can include video codecs, so mask them out
10876       */
10877       if (capability & p->prefcodec) {
10878          format_t codec = p->prefcodec & AST_FORMAT_AUDIO_MASK;
10879 
10880          add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size);
10881          alreadysent |= codec;
10882       }
10883 
10884       /* Start by sending our preferred audio/video codecs */
10885       for (x = 0; x < 64; x++) {
10886          format_t codec;
10887 
10888          if (!(codec = ast_codec_pref_index(&p->prefs, x)))
10889             break;
10890 
10891          if (!(capability & codec))
10892             continue;
10893 
10894          if (alreadysent & codec)
10895             continue;
10896 
10897          add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size);
10898          alreadysent |= codec;
10899       }
10900 
10901       /* Now send any other common audio and video codecs, and non-codec formats: */
10902       for (x = 1ULL; x <= (needtext ? AST_FORMAT_TEXT_MASK : (needvideo ? AST_FORMAT_VIDEO_MASK : AST_FORMAT_AUDIO_MASK)); x <<= 1) {
10903          if (!(capability & x))  /* Codec not requested */
10904             continue;
10905 
10906          if (alreadysent & x) /* Already added to SDP */
10907             continue;
10908 
10909          if (x & AST_FORMAT_AUDIO_MASK)
10910             add_codec_to_sdp(p, x, &m_audio, &a_audio, debug, &min_audio_packet_size);
10911          else if (x & AST_FORMAT_VIDEO_MASK)
10912             add_vcodec_to_sdp(p, x, &m_video, &a_video, debug, &min_video_packet_size);
10913          else if (x & AST_FORMAT_TEXT_MASK)
10914             add_tcodec_to_sdp(p, x, &m_text, &a_text, debug, &min_text_packet_size);
10915       }
10916 
10917       /* Now add DTMF RFC2833 telephony-event as a codec */
10918       for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) {
10919          if (!(p->jointnoncodeccapability & x))
10920             continue;
10921 
10922          add_noncodec_to_sdp(p, x, &m_audio, &a_audio, debug);
10923       }
10924 
10925       ast_debug(3, "-- Done with adding codecs to SDP\n");
10926 
10927       if (!p->owner || !ast_internal_timing_enabled(p->owner))
10928          ast_str_append(&a_audio, 0, "a=silenceSupp:off - - - -\r\n");
10929 
10930       if (min_audio_packet_size)
10931          ast_str_append(&a_audio, 0, "a=ptime:%d\r\n", min_audio_packet_size);
10932 
10933       /* XXX don't think you can have ptime for video */
10934       if (min_video_packet_size)
10935          ast_str_append(&a_video, 0, "a=ptime:%d\r\n", min_video_packet_size);
10936 
10937       /* XXX don't think you can have ptime for text */
10938       if (min_text_packet_size)
10939          ast_str_append(&a_text, 0, "a=ptime:%d\r\n", min_text_packet_size);
10940 
10941       if (m_audio->len - m_audio->used < 2 || m_video->len - m_video->used < 2 ||
10942           m_text->len - m_text->used < 2 || a_text->len - a_text->used < 2 ||
10943           a_audio->len - a_audio->used < 2 || a_video->len - a_video->used < 2)
10944          ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n");
10945    }
10946 
10947    if (add_t38) {
10948       /* Our T.38 end is */
10949       ast_udptl_get_us(p->udptl, &udptladdr);
10950 
10951       /* Determine T.38 UDPTL destination */
10952       if (!ast_sockaddr_isnull(&p->udptlredirip)) {
10953          ast_sockaddr_copy(&udptldest, &p->udptlredirip);
10954       } else {
10955          ast_sockaddr_copy(&udptldest, &p->ourip);
10956          ast_sockaddr_set_port(&udptldest, ast_sockaddr_port(&udptladdr));
10957       }
10958 
10959       if (debug) {
10960          ast_debug(1, "T.38 UDPTL is at %s port %d\n", ast_sockaddr_stringify_addr(&p->ourip), ast_sockaddr_port(&udptladdr));
10961       }
10962 
10963       /* We break with the "recommendation" and send our IP, in order that our
10964          peer doesn't have to ast_gethostbyname() us */
10965 
10966       ast_str_append(&m_modem, 0, "m=image %d udptl t38\r\n", ast_sockaddr_port(&udptldest));
10967 
10968       if (!ast_sockaddr_cmp(&udptldest, &dest)) {
10969          ast_str_append(&m_modem, 0, "c=IN %s %s\r\n",
10970                (ast_sockaddr_is_ipv6(&dest) && !ast_sockaddr_is_ipv4_mapped(&dest)) ?
10971                "IP6" : "IP4", ast_sockaddr_stringify_addr(&udptldest));
10972       }
10973 
10974       ast_str_append(&a_modem, 0, "a=T38FaxVersion:%d\r\n", p->t38.our_parms.version);
10975       ast_str_append(&a_modem, 0, "a=T38MaxBitRate:%d\r\n", t38_get_rate(p->t38.our_parms.rate));
10976       if (p->t38.our_parms.fill_bit_removal) {
10977          ast_str_append(&a_modem, 0, "a=T38FaxFillBitRemoval\r\n");
10978       }
10979       if (p->t38.our_parms.transcoding_mmr) {
10980          ast_str_append(&a_modem, 0, "a=T38FaxTranscodingMMR\r\n");
10981       }
10982       if (p->t38.our_parms.transcoding_jbig) {
10983          ast_str_append(&a_modem, 0, "a=T38FaxTranscodingJBIG\r\n");
10984       }
10985       switch (p->t38.our_parms.rate_management) {
10986       case AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF:
10987          ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:transferredTCF\r\n");
10988          break;
10989       case AST_T38_RATE_MANAGEMENT_LOCAL_TCF:
10990          ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:localTCF\r\n");
10991          break;
10992       }
10993       ast_str_append(&a_modem, 0, "a=T38FaxMaxDatagram:%u\r\n", ast_udptl_get_local_max_datagram(p->udptl));
10994       switch (ast_udptl_get_error_correction_scheme(p->udptl)) {
10995       case UDPTL_ERROR_CORRECTION_NONE:
10996          break;
10997       case UDPTL_ERROR_CORRECTION_FEC:
10998          ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPFEC\r\n");
10999          break;
11000       case UDPTL_ERROR_CORRECTION_REDUNDANCY:
11001          ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPRedundancy\r\n");
11002          break;
11003       }
11004    }
11005 
11006    if (needaudio)
11007       ast_str_append(&m_audio, 0, "\r\n");
11008    if (needvideo)
11009       ast_str_append(&m_video, 0, "\r\n");
11010    if (needtext)
11011       ast_str_append(&m_text, 0, "\r\n");
11012 
11013    add_header(resp, "Content-Type", "application/sdp");
11014    add_content(resp, version);
11015    add_content(resp, owner);
11016    add_content(resp, subject);
11017    add_content(resp, connection);
11018    if (needvideo)    /* only if video response is appropriate */
11019       add_content(resp, bandwidth);
11020    add_content(resp, session_time);
11021    if (needaudio) {
11022       add_content(resp, m_audio->str);
11023       add_content(resp, a_audio->str);
11024       add_content(resp, hold);
11025       if (a_crypto) {
11026          add_content(resp, a_crypto);
11027       }
11028    } else if (p->offered_media[SDP_AUDIO].offered) {
11029       snprintf(dummy_answer, sizeof(dummy_answer), "m=audio 0 RTP/AVP %s\r\n", p->offered_media[SDP_AUDIO].codecs);
11030       add_content(resp, dummy_answer);
11031    }
11032    if (needvideo) { /* only if video response is appropriate */
11033       add_content(resp, m_video->str);
11034       add_content(resp, a_video->str);
11035       add_content(resp, hold);   /* Repeat hold for the video stream */
11036       if (v_a_crypto) {
11037          add_content(resp, v_a_crypto);
11038       }
11039    } else if (p->offered_media[SDP_VIDEO].offered) {
11040       snprintf(dummy_answer, sizeof(dummy_answer), "m=video 0 RTP/AVP %s\r\n", p->offered_media[SDP_VIDEO].codecs);
11041       add_content(resp, dummy_answer);
11042    }
11043    if (needtext) { /* only if text response is appropriate */
11044       add_content(resp, m_text->str);
11045       add_content(resp, a_text->str);
11046       add_content(resp, hold);   /* Repeat hold for the text stream */
11047       if (t_a_crypto) {
11048          add_content(resp, t_a_crypto);
11049       }
11050    } else if (p->offered_media[SDP_TEXT].offered) {
11051       snprintf(dummy_answer, sizeof(dummy_answer), "m=text 0 RTP/AVP %s\r\n", p->offered_media[SDP_TEXT].codecs);
11052       add_content(resp, dummy_answer);
11053    }
11054    if (add_t38) {
11055       add_content(resp, m_modem->str);
11056       add_content(resp, a_modem->str);
11057    } else if (p->offered_media[SDP_IMAGE].offered) {
11058       add_content(resp, "m=image 0 udptl t38\r\n");
11059    }
11060 
11061    /* Update lastrtprx when we send our SDP */
11062    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
11063 
11064    ast_debug(3, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability));
11065 
11066    return AST_SUCCESS;
11067 }

static int add_sip_domain ( const char *  domain,
const enum domain_mode  mode,
const char *  context 
) [static]

Add SIP domain to list of domains we are responsible for.

Definition at line 25723 of file chan_sip.c.

References ast_calloc, ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), and LOG_WARNING.

25724 {
25725    struct domain *d;
25726 
25727    if (ast_strlen_zero(domain)) {
25728       ast_log(LOG_WARNING, "Zero length domain.\n");
25729       return 1;
25730    }
25731 
25732    if (!(d = ast_calloc(1, sizeof(*d))))
25733       return 0;
25734 
25735    ast_copy_string(d->domain, domain, sizeof(d->domain));
25736 
25737    if (!ast_strlen_zero(context))
25738       ast_copy_string(d->context, context, sizeof(d->context));
25739 
25740    d->mode = mode;
25741 
25742    AST_LIST_LOCK(&domain_list);
25743    AST_LIST_INSERT_TAIL(&domain_list, d, list);
25744    AST_LIST_UNLOCK(&domain_list);
25745 
25746    if (sipdebug)  
25747       ast_debug(1, "Added local SIP domain '%s'\n", domain);
25748 
25749    return 1;
25750 }

static int add_supported_header ( struct sip_pvt *  pvt,
struct sip_request *  req 
) [static]

Add "Supported" header to sip message. Since some options may be disabled in the config, the sip_pvt must be inspected to determine what is supported for this dialog.

Definition at line 9299 of file chan_sip.c.

References add_header(), and st_get_mode().

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

09300 {
09301    int res;
09302    if (st_get_mode(pvt) != SESSION_TIMER_MODE_REFUSE) {
09303       res = add_header(req, "Supported", "replaces, timer");
09304    } else {
09305       res = add_header(req, "Supported", "replaces");
09306    }
09307    return res;
09308 }

static void add_tcodec_to_sdp ( const struct sip_pvt *  p,
int  codec,
struct ast_str **  m_buf,
struct ast_str **  a_buf,
int  debug,
int *  min_packet_size 
) [static]

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

Definition at line 10501 of file chan_sip.c.

References AST_FORMAT_T140, AST_FORMAT_T140RED, ast_getformatname(), ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_str_append(), and ast_verbose.

Referenced by add_sdp().

10504 {
10505    int rtp_code;
10506 
10507    if (!p->trtp)
10508       return;
10509 
10510    if (debug)
10511       ast_verbose("Adding text codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
10512 
10513    if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, codec)) == -1)
10514       return;
10515 
10516    ast_str_append(m_buf, 0, " %d", rtp_code);
10517    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
10518              ast_rtp_lookup_mime_subtype2(1, codec, 0),
10519              ast_rtp_lookup_sample_rate2(1, codec));
10520    /* Add fmtp code here */
10521 
10522    if (codec == AST_FORMAT_T140RED) {
10523       int t140code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, AST_FORMAT_T140);
10524       ast_str_append(a_buf, 0, "a=fmtp:%d %d/%d/%d\r\n", rtp_code,
10525           t140code,
10526           t140code,
10527           t140code);
10528 
10529    }
10530 }

static int add_text ( struct sip_request *  req,
const char *  text 
) [static]

Add text body to SIP message.

Definition at line 10269 of file chan_sip.c.

References add_content(), and add_header().

Referenced by transmit_message_with_text().

10270 {
10271    /* XXX Convert \n's to \r\n's XXX */
10272    add_header(req, "Content-Type", "text/plain;charset=UTF-8");
10273    add_content(req, text);
10274    return 0;
10275 }

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

implement the setvar config line

Definition at line 25872 of file chan_sip.c.

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

25873 {
25874    struct ast_variable *tmpvar = NULL;
25875    char *varname = ast_strdupa(buf), *varval = NULL;
25876    
25877    if ((varval = strchr(varname, '='))) {
25878       *varval++ = '\0';
25879       if ((tmpvar = ast_variable_new(varname, varval, ""))) {
25880          tmpvar->next = list;
25881          list = tmpvar;
25882       }
25883    }
25884    return list;
25885 }

static void add_vcodec_to_sdp ( const struct sip_pvt *  p,
format_t  codec,
struct ast_str **  m_buf,
struct ast_str **  a_buf,
int  debug,
int *  min_packet_size 
) [static]

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

Definition at line 10478 of file chan_sip.c.

References ast_getformatname(), ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_str_append(), and ast_verbose.

Referenced by add_sdp().

10481 {
10482    int rtp_code;
10483 
10484    if (!p->vrtp)
10485       return;
10486 
10487    if (debug)
10488       ast_verbose("Adding video codec 0x%" PRIx64 " (%s) to SDP\n", codec, ast_getformatname(codec));
10489 
10490    if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->vrtp), 1, codec)) == -1)
10491       return;
10492 
10493    ast_str_append(m_buf, 0, " %d", rtp_code);
10494    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
10495              ast_rtp_lookup_mime_subtype2(1, codec, 0),
10496              ast_rtp_lookup_sample_rate2(1, codec));
10497    /* Add fmtp code here */
10498 }

static int add_vidupdate ( struct sip_request *  req  )  [static]

add XML encoded media control with update

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

Definition at line 10399 of file chan_sip.c.

References add_content(), and add_header().

Referenced by transmit_info_with_vidupdate().

10400 {
10401    const char *xml_is_a_huge_waste_of_space =
10402       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
10403       " <media_control>\r\n"
10404       "  <vc_primitive>\r\n"
10405       "   <to_encoder>\r\n"
10406       "    <picture_fast_update>\r\n"
10407       "    </picture_fast_update>\r\n"
10408       "   </to_encoder>\r\n"
10409       "  </vc_primitive>\r\n"
10410       " </media_control>\r\n";
10411    add_header(req, "Content-Type", "application/media_control+xml");
10412    add_content(req, xml_is_a_huge_waste_of_space);
10413    return 0;
10414 }

static int addr_is_multicast ( const struct ast_sockaddr *  addr  )  [static]

Check if an ip is an multicast IP. addr the address to check.

This function checks if an address is in the 224.0.0.0/4 network block.

Returns:
non-zero if this is a multicast address

Definition at line 7395 of file chan_sip.c.

References ast_sockaddr_ipv4().

Referenced by process_via().

07396 {
07397    return ((ast_sockaddr_ipv4(addr) & 0xf0000000) == 0xe0000000);
07398 }

static void append_date ( struct sip_request *  req  )  [static]

Append date to SIP message.

Definition at line 10098 of file chan_sip.c.

References add_header().

10099 {
10100    char tmpdat[256];
10101    struct tm tm;
10102    time_t t = time(NULL);
10103 
10104    gmtime_r(&t, &tm);
10105    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
10106    add_header(req, "Date", tmpdat);
10107 }

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

Append to SIP dialog history with arg list.

Definition at line 3440 of file chan_sip.c.

References append_history_va(), dumphistory, and recordhistory.

03441 {
03442    va_list ap;
03443 
03444    if (!p) {
03445       return;
03446    }
03447 
03448    if (!p->do_history && !recordhistory && !dumphistory) {
03449       return;
03450    }
03451 
03452    va_start(ap, fmt);
03453    append_history_va(p, fmt, ap);
03454    va_end(ap);
03455 
03456    return;
03457 }

static void append_history_va ( struct sip_pvt *  p,
const char *  fmt,
va_list  ap 
) [static]

Append to SIP dialog history with arg list.

Definition at line 3412 of file chan_sip.c.

References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, and strsep().

Referenced by append_history_full().

03413 {
03414    char buf[80], *c = buf; /* max history length */
03415    struct sip_history *hist;
03416    int l;
03417 
03418    vsnprintf(buf, sizeof(buf), fmt, ap);
03419    strsep(&c, "\r\n"); /* Trim up everything after \r or \n */
03420    l = strlen(buf) + 1;
03421    if (!(hist = ast_calloc(1, sizeof(*hist) + l))) {
03422       return;
03423    }
03424    if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) {
03425       ast_free(hist);
03426       return;
03427    }
03428    memcpy(hist->event, buf, l);
03429    if (p->history_entries == MAX_HISTORY_ENTRIES) {
03430       struct sip_history *oldest;
03431       oldest = AST_LIST_REMOVE_HEAD(p->history, list);
03432       p->history_entries--;
03433       ast_free(oldest);
03434    }
03435    AST_LIST_INSERT_TAIL(p->history, hist, list);
03436    p->history_entries++;
03437 }

static int apply_directmedia_ha ( struct sip_pvt *  p,
const char *  op 
) [static]

Definition at line 27756 of file chan_sip.c.

References ast_apply_ha(), ast_debug, ast_rtp_instance_get_local_address(), ast_rtp_instance_get_remote_address(), AST_SENSE_ALLOW, AST_SENSE_DENY, ast_sockaddr_stringify(), and ast_strdupa.

Referenced by sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), and sip_get_vrtp_peer().

27757 {
27758    struct ast_sockaddr us = { { 0, }, }, them = { { 0, }, };
27759    int res = AST_SENSE_ALLOW;
27760 
27761    ast_rtp_instance_get_remote_address(p->rtp, &them);
27762    ast_rtp_instance_get_local_address(p->rtp, &us);
27763 
27764    if ((res = ast_apply_ha(p->directmediaha, &them)) == AST_SENSE_DENY) {
27765       const char *us_addr = ast_strdupa(ast_sockaddr_stringify(&us));
27766       const char *them_addr = ast_strdupa(ast_sockaddr_stringify(&them));
27767 
27768       ast_debug(3, "Reinvite %s to %s denied by directmedia ACL on %s\n",
27769          op, them_addr, us_addr);
27770    }
27771 
27772    return res;
27773 }

AST_DATA_STRUCTURE ( sip_peer  ,
DATA_EXPORT_SIP_PEER   
)

static void ast_quiet_chan ( struct ast_channel *  chan  )  [static]

Turn off generator data XXX Does this function belong in the SIP channel?

Definition at line 20507 of file chan_sip.c.

References ast_channel::_state, ast_deactivate_generator(), AST_FLAG_MOH, ast_moh_stop(), AST_STATE_UP, and ast_test_flag.

Referenced by attempt_transfer(), and handle_invite_replaces().

20508 {
20509    if (chan && chan->_state == AST_STATE_UP) {
20510       if (ast_test_flag(chan, AST_FLAG_MOH))
20511          ast_moh_stop(chan);
20512       else if (chan->generatordata)
20513          ast_deactivate_generator(chan);
20514    }
20515 }

static void ast_sip_ouraddrfor ( const struct ast_sockaddr *  them,
struct ast_sockaddr *  us,
struct sip_pvt *  p 
) [static]

NAT fix - decide which IP address to use for Asterisk server?

Using the localaddr structure built up with localnet statements in sip.conf apply it to their address to see if we need to substitute our externaddr or can get away with our internal bindaddr 'us' is always overwritten.

Definition at line 3306 of file chan_sip.c.

References ast_apply_ha(), ast_debug, ast_log(), ast_ouraddrfor(), AST_SENSE_ALLOW, ast_sockaddr_copy(), ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), bindaddr, externaddr, externexpire, externhost, externrefresh, externtcpport, externtlsport, get_transport(), internip, ast_tcptls_session_args::local_address, localaddr, LOG_NOTICE, LOG_WARNING, sip_cfg, sip_tcp_desc, and sip_tls_desc.

Referenced by __sip_subscribe_mwi_do(), sip_alloc(), sip_cc_monitor_request_cc(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_publish(), transmit_register(), and transmit_response_using_temp().

03307 {
03308    struct ast_sockaddr theirs;
03309 
03310    /* Set want_remap to non-zero if we want to remap 'us' to an externally
03311     * reachable IP address and port. This is done if:
03312     * 1. we have a localaddr list (containing 'internal' addresses marked
03313     *    as 'deny', so ast_apply_ha() will return AST_SENSE_DENY on them,
03314     *    and AST_SENSE_ALLOW on 'external' ones);
03315     * 2. externaddr is set, so we know what to use as the
03316     *    externally visible address;
03317     * 3. the remote address, 'them', is external;
03318     * 4. the address returned by ast_ouraddrfor() is 'internal' (AST_SENSE_DENY
03319     *    when passed to ast_apply_ha() so it does need to be remapped.
03320     *    This fourth condition is checked later.
03321     */
03322    int want_remap = 0;
03323 
03324    ast_sockaddr_copy(us, &internip); /* starting guess for the internal address */
03325    /* now ask the system what would it use to talk to 'them' */
03326    ast_ouraddrfor(them, us);
03327    ast_sockaddr_copy(&theirs, them);
03328 
03329    if (ast_sockaddr_is_ipv6(&theirs)) {
03330       if (localaddr && !ast_sockaddr_isnull(&externaddr)) {
03331          ast_log(LOG_WARNING, "Address remapping activated in sip.conf "
03332             "but we're using IPv6, which doesn't need it. Please "
03333             "remove \"localnet\" and/or \"externaddr\" settings.\n");
03334       }
03335    } else {
03336       want_remap = localaddr &&
03337          !ast_sockaddr_isnull(&externaddr) &&
03338          ast_apply_ha(localaddr, &theirs) == AST_SENSE_ALLOW ;
03339    }
03340 
03341    if (want_remap &&
03342        (!sip_cfg.matchexternaddrlocally || !ast_apply_ha(localaddr, us)) ) {
03343       /* if we used externhost, see if it is time to refresh the info */
03344       if (externexpire && time(NULL) >= externexpire) {
03345          if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) {
03346             ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
03347          }
03348          externexpire = time(NULL) + externrefresh;
03349       }
03350       if (!ast_sockaddr_isnull(&externaddr)) {
03351          ast_sockaddr_copy(us, &externaddr);
03352          switch (p->socket.type) {
03353          case SIP_TRANSPORT_TCP:
03354             if (!externtcpport && ast_sockaddr_port(&externaddr)) {
03355                /* for consistency, default to the externaddr port */
03356                externtcpport = ast_sockaddr_port(&externaddr);
03357             }
03358             ast_sockaddr_set_port(us, externtcpport);
03359             break;
03360          case SIP_TRANSPORT_TLS:
03361             ast_sockaddr_set_port(us, externtlsport);
03362             break;
03363          case SIP_TRANSPORT_UDP:
03364             if (!ast_sockaddr_port(&externaddr)) {
03365                ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr));
03366             }
03367             break;
03368          default:
03369             break;
03370          }
03371       }
03372       ast_debug(1, "Target address %s is not local, substituting externaddr\n",
03373            ast_sockaddr_stringify(them));
03374    } else if (p) {
03375       /* no remapping, but we bind to a specific address, so use it. */
03376       switch (p->socket.type) {
03377       case SIP_TRANSPORT_TCP:
03378          if (!ast_sockaddr_is_any(&sip_tcp_desc.local_address)) {
03379             ast_sockaddr_copy(us,
03380                     &sip_tcp_desc.local_address);
03381          } else {
03382             ast_sockaddr_set_port(us,
03383                         ast_sockaddr_port(&sip_tcp_desc.local_address));
03384          }
03385          break;
03386       case SIP_TRANSPORT_TLS:
03387          if (!ast_sockaddr_is_any(&sip_tls_desc.local_address)) {
03388             ast_sockaddr_copy(us,
03389                     &sip_tls_desc.local_address);
03390          } else {
03391             ast_sockaddr_set_port(us,
03392                         ast_sockaddr_port(&sip_tls_desc.local_address));
03393          }
03394          break;
03395       case SIP_TRANSPORT_UDP:
03396          /* fall through on purpose */
03397       default:
03398          if (!ast_sockaddr_is_any(&bindaddr)) {
03399             ast_sockaddr_copy(us, &bindaddr);
03400          }
03401          if (!ast_sockaddr_port(us)) {
03402             ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr));
03403          }
03404       }
03405    } else if (!ast_sockaddr_is_any(&bindaddr)) {
03406       ast_sockaddr_copy(us, &bindaddr);
03407    }
03408    ast_debug(3, "Setting SIP_TRANSPORT_%s with address %s\n", get_transport(p->socket.type), ast_sockaddr_stringify(us));
03409 }

static int ast_sockaddr_resolve_first ( struct ast_sockaddr *  addr,
const char *  name,
int  flag 
) [static]

Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr.

Using this function probably means you have a faulty design.

Definition at line 28452 of file chan_sip.c.

References ast_sockaddr_resolve_first_af(), and get_address_family_filter().

Referenced by __set_address_from_contact(), ast_sip_ouraddrfor(), check_via(), create_addr(), parse_register_contact(), process_via(), set_destination(), sip_do_debug_ip(), and sip_request_call().

28454 {
28455    return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(&bindaddr));
28456 }

static int ast_sockaddr_resolve_first_af ( struct ast_sockaddr *  addr,
const char *  name,
int  flag,
int  family 
) [static]

Return the first entry from ast_sockaddr_resolve filtered by address family.

Using this function probably means you have a faulty design.

Definition at line 28428 of file chan_sip.c.

References ast_debug, ast_free, ast_sockaddr_copy(), and ast_sockaddr_resolve().

Referenced by ast_sockaddr_resolve_first(), get_ip_and_port_from_sdp(), and process_sdp_c().

28430 {
28431    struct ast_sockaddr *addrs;
28432    int addrs_cnt;
28433 
28434    addrs_cnt = ast_sockaddr_resolve(&addrs, name, flag, family);
28435    if (addrs_cnt <= 0) {
28436       return 1;
28437    }
28438    if (addrs_cnt > 1) {
28439       ast_debug(1, "Multiple addresses, using the first one only\n");
28440    }
28441 
28442    ast_sockaddr_copy(addr, &addrs[0]);
28443 
28444    ast_free(addrs);
28445    return 0;
28446 }

static int attempt_transfer ( struct sip_dual *  transferer,
struct sip_dual *  target 
) [static]

Attempt transfer of SIP call This fix for attended transfers on a local PBX.

Definition at line 20519 of file chan_sip.c.

References ast_channel_masquerade(), ast_debug, ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_state2str(), LOG_NOTICE, and LOG_WARNING.

20520 {
20521    int res = 0;
20522    struct ast_channel *peera = NULL,   
20523       *peerb = NULL,
20524       *peerc = NULL,
20525       *peerd = NULL;
20526 
20527 
20528    /* We will try to connect the transferee with the target and hangup
20529       all channels to the transferer */   
20530    ast_debug(4, "Sip transfer:--------------------\n");
20531    if (transferer->chan1)
20532       ast_debug(4, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state));
20533    else
20534       ast_debug(4, "-- No transferer first channel - odd??? \n");
20535    if (target->chan1)
20536       ast_debug(4, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state));
20537    else
20538       ast_debug(4, "-- No target first channel ---\n");
20539    if (transferer->chan2)
20540       ast_debug(4, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state));
20541    else
20542       ast_debug(4, "-- No bridged call to transferee\n");
20543    if (target->chan2)
20544       ast_debug(4, "-- Bridged call to transfer target: %s State %s\n", target->chan2 ? target->chan2->name : "<none>", target->chan2 ? ast_state2str(target->chan2->_state) : "(none)");
20545    else
20546       ast_debug(4, "-- No target second channel ---\n");
20547    ast_debug(4, "-- END Sip transfer:--------------------\n");
20548    if (transferer->chan2) { /* We have a bridge on the transferer's channel */
20549       peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */
20550       peerb = target->chan1;     /* Transferer - PBX -> target channel - This will get lost in masq */
20551       peerc = transferer->chan2; /* Asterisk to Transferee */
20552       peerd = target->chan2;     /* Asterisk to Target */
20553       ast_debug(3, "SIP transfer: Four channels to handle\n");
20554    } else if (target->chan2) {   /* Transferer has no bridge (IVR), but transferee */
20555       peera = target->chan1;     /* Transferer to PBX -> target channel */
20556       peerb = transferer->chan1; /* Transferer to IVR*/
20557       peerc = target->chan2;     /* Asterisk to Target */
20558       peerd = transferer->chan2; /* Nothing */
20559       ast_debug(3, "SIP transfer: Three channels to handle\n");
20560    }
20561 
20562    if (peera && peerb && peerc && (peerb != peerc)) {
20563       ast_quiet_chan(peera);     /* Stop generators */
20564       ast_quiet_chan(peerb);  
20565       ast_quiet_chan(peerc);
20566       if (peerd)
20567          ast_quiet_chan(peerd);
20568 
20569       ast_debug(4, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name);
20570       if (ast_channel_masquerade(peerb, peerc)) {
20571          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
20572          res = -1;
20573       } else
20574          ast_debug(4, "SIP transfer: Succeeded to masquerade channels.\n");
20575       return res;
20576    } else {
20577       ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n");
20578       if (transferer->chan1)
20579          ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV);
20580       if (target->chan1)
20581          ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV);
20582       return -1;
20583    }
20584    return 0;
20585 }

static void auth_headers ( enum sip_auth_type  code,
char **  header,
char **  respheader 
) [static]

return the request and response heade for a 401 or 407 code

Definition at line 12917 of file chan_sip.c.

References ast_verbose.

Referenced by check_auth(), do_proxy_auth(), do_register_auth(), and transmit_request_with_auth().

12918 {
12919    if (code == WWW_AUTH) {       /* 401 */
12920       *header = "WWW-Authenticate";
12921       *respheader = "Authorization";
12922    } else if (code == PROXY_AUTH) { /* 407 */
12923       *header = "Proxy-Authenticate";
12924       *respheader = "Proxy-Authorization";
12925    } else {
12926       ast_verbose("-- wrong response code %d\n", code);
12927       *header = *respheader = "Invalid";
12928    }
12929 }

static int auto_congest ( const void *  arg  )  [static]

Scheduled congestion on a call. Only called by the scheduler, must return the reference when done.

Definition at line 5249 of file chan_sip.c.

References append_history, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_CONGESTION, ast_queue_control(), sip_pvt_lock, sip_pvt_unlock, and sip_scheddestroy().

05250 {
05251    struct sip_pvt *p = (struct sip_pvt *)arg;
05252 
05253    sip_pvt_lock(p);
05254    p->initid = -1;   /* event gone, will not be rescheduled */
05255    if (p->owner) {
05256       /* XXX fails on possible deadlock */
05257       if (!ast_channel_trylock(p->owner)) {
05258          append_history(p, "Cong", "Auto-congesting (timer)");
05259          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
05260          ast_channel_unlock(p->owner);
05261       }
05262 
05263       /* Give the channel a chance to act before we proceed with destruction */
05264       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
05265    }
05266    sip_pvt_unlock(p);
05267    dialog_unref(p, "unreffing arg passed into auto_congest callback (p->initid)");
05268    return 0;
05269 }

static void build_callid_pvt ( struct sip_pvt *  pvt  )  [static]

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

Definition at line 7192 of file chan_sip.c.

References ast_sockaddr_stringify(), ast_string_field_build, generate_random_string(), and S_OR.

Referenced by __sip_subscribe_mwi_do(), sip_alloc(), sip_poke_peer(), sip_request_call(), and sip_send_mwi_to_peer().

07193 {
07194    char buf[33];
07195 
07196    const char *host = S_OR(pvt->fromdomain, ast_sockaddr_stringify(&pvt->ourip));
07197    
07198    ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
07199 
07200 }

static void build_callid_registry ( struct sip_registry *  reg,
const struct ast_sockaddr *  ourip,
const char *  fromdomain 
) [static]

Build SIP Call-ID value for a REGISTER transaction.

Definition at line 7203 of file chan_sip.c.

References ast_sockaddr_stringify_host(), ast_string_field_build, generate_random_string(), and S_OR.

Referenced by transmit_register().

07204 {
07205    char buf[33];
07206 
07207    const char *host = S_OR(fromdomain, ast_sockaddr_stringify_host(ourip));
07208 
07209    ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
07210 }

static void build_contact ( struct sip_pvt *  p  )  [static]

Build contact header - the contact header we send out.

Definition at line 11311 of file chan_sip.c.

References ast_sockaddr_stringify(), ast_string_field_build, ast_strlen_zero(), ast_uri_encode(), and get_transport().

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

11312 {
11313    char tmp[SIPBUFSIZE];
11314    char *user = ast_uri_encode(p->exten, tmp, sizeof(tmp), 1);
11315 
11316    if (p->socket.type == SIP_TRANSPORT_UDP) {
11317       ast_string_field_build(p, our_contact, "<sip:%s%s%s>", user,
11318          ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify(&p->ourip));
11319    } else {
11320       ast_string_field_build(p, our_contact, "<sip:%s%s%s;transport=%s>", user,
11321          ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify(&p->ourip),
11322          get_transport(p->socket.type));
11323    }
11324 }

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

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

< The first transport listed should be default outbound

Definition at line 26022 of file chan_sip.c.

References __set_address_from_contact(), accountcode, add_peer_mailboxes(), add_peer_mwi_subs(), add_realm_authentication(), add_var(), ao2_alloc, ao2_t_alloc, ao2_t_find, ao2_t_ref, asprintf, ast_append_ha(), ast_atomic_fetchadd_int(), ast_callerid_split(), AST_CC_AGENT_NATIVE, AST_CC_AGENT_NEVER, ast_cc_config_params_init, ast_cc_is_config_param(), ast_cc_set_param(), ast_cdr_amaflags2int(), ast_copy_flags, ast_copy_string(), ast_debug, ast_dnsmgr_lookup(), ast_dnsmgr_refresh(), ast_free, ast_free_ha(), ast_get_cc_agent_policy(), ast_get_group(), ast_get_ip(), ast_get_time_t(), AST_LIST_EMPTY, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), AST_SCHED_DEL_UNREF, ast_set2_flag, ast_set_cc_agent_policy(), ast_set_flag, ast_skip_blanks(), ast_sockaddr_isnull(), ast_sockaddr_parse(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_setnull(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), ast_str_strlen(), ast_strdupa, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variables_destroy(), bindaddr, can_parse_xml, cid_name, cid_num, clear_realm_authentication(), config, context, default_maxcallbitrate, DEFAULT_MAXMS, default_primary_transport, default_qualify, default_transports, destroy_association(), destroy_mailbox(), errno, FALSE, ast_flags::flags, format, get_address_family_filter(), get_srv_protocol(), get_srv_service(), global_dynamic_exclude_static, global_flags, global_max_se, global_min_se, global_qualifyfreq, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_st_mode, global_st_refresher, global_t1min, global_timer_b, handle_common_options(), handle_t38_options(), language, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, mailbox, mark_parsed_methods(), MAXHOSTNAMELEN, mohinterpret, mohsuggest, ast_variable::name, ast_variable::next, OBJ_POINTER, OBJ_UNLINK, parkinglot, PARSE_PORT_FORBID, port_str2int(), proxy_update(), ref_peer(), reg_source_db(), rpeerobjs, secret, set_peer_defaults(), set_socket_transport(), sip_cfg, sip_destroy_peer_fn(), sip_poke_peer(), sip_register(), sip_send_mwi_to_peer(), speerobjs, srvlookup, str2stmode(), str2strefresher(), strsep(), TRUE, unref_peer(), and ast_variable::value.

26023 {
26024    struct sip_peer *peer = NULL;
26025    struct ast_ha *oldha = NULL;
26026    struct ast_ha *olddirectmediaha = NULL;
26027    int found = 0;
26028    int firstpass = 1;
26029    uint16_t port = 0;
26030    int format = 0;      /* Ama flags */
26031    int timerb_set = 0, timert1_set = 0;
26032    time_t regseconds = 0;
26033    struct ast_flags peerflags[3] = {{(0)}};
26034    struct ast_flags mask[3] = {{(0)}};
26035    char callback[256] = "";
26036    struct sip_peer tmp_peer;
26037    const char *srvlookup = NULL;
26038    static int deprecation_warning = 1;
26039    int alt_fullcontact = alt ? 1 : 0, headercount = 0;
26040    struct ast_str *fullcontact = ast_str_alloca(512);
26041 
26042    if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
26043       /* Note we do NOT use find_peer here, to avoid realtime recursion */
26044       /* We also use a case-sensitive comparison (unlike find_peer) so
26045          that case changes made to the peer name will be properly handled
26046          during reload
26047       */
26048       ast_copy_string(tmp_peer.name, name, sizeof(tmp_peer.name));
26049       peer = ao2_t_find(peers, &tmp_peer, OBJ_POINTER | OBJ_UNLINK, "find and unlink peer from peers table");
26050    }
26051 
26052    if (peer) {
26053       /* Already in the list, remove it and it will be added back (or FREE'd)  */
26054       found++;
26055       if (!(peer->the_mark))
26056          firstpass = 0;
26057    } else {
26058       if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct")))
26059          return NULL;
26060 
26061       if (ast_string_field_init(peer, 512)) {
26062          ao2_t_ref(peer, -1, "failed to string_field_init, drop peer");
26063          return NULL;
26064       }
26065 
26066       if (!(peer->cc_params = ast_cc_config_params_init())) {
26067          ao2_t_ref(peer, -1, "failed to allocate cc_params for peer");
26068          return NULL;
26069       }
26070 
26071       if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
26072          ast_atomic_fetchadd_int(&rpeerobjs, 1);
26073          ast_debug(3, "-REALTIME- peer built. Name: %s. Peer objects: %d\n", name, rpeerobjs);
26074       } else
26075          ast_atomic_fetchadd_int(&speerobjs, 1);
26076    }
26077 
26078    /* Note that our peer HAS had its reference count increased */
26079    if (firstpass) {
26080       peer->lastmsgssent = -1;
26081       oldha = peer->ha;
26082       peer->ha = NULL;
26083       olddirectmediaha = peer->directmediaha;
26084       peer->directmediaha = NULL;
26085       set_peer_defaults(peer);   /* Set peer defaults */
26086       peer->type = 0;
26087    }
26088    if (!found && name)
26089       ast_copy_string(peer->name, name, sizeof(peer->name));
26090 
26091    /* If we have channel variables, remove them (reload) */
26092    if (peer->chanvars) {
26093       ast_variables_destroy(peer->chanvars);
26094       peer->chanvars = NULL;
26095       /* XXX should unregister ? */
26096    }
26097 
26098    if (found)
26099       peer->portinuri = 0;
26100 
26101    /* If we have realm authentication information, remove them (reload) */
26102    clear_realm_authentication(peer->auth);
26103    peer->auth = NULL;
26104    /* clear the transport information.  We will detect if a default value is required after parsing the config */
26105    peer->default_outbound_transport = 0;
26106    peer->transports = 0;
26107 
26108    if (!devstate_only) {
26109       struct sip_mailbox *mailbox;
26110       AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
26111          mailbox->delme = 1;
26112       }
26113    }
26114 
26115    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
26116       if (!devstate_only) {
26117          if (handle_common_options(&peerflags[0], &mask[0], v)) {
26118             continue;
26119          }
26120          if (handle_t38_options(&peerflags[0], &mask[0], v, &peer->t38_maxdatagram)) {
26121             continue;
26122          }
26123          if (!strcasecmp(v->name, "transport") && !ast_strlen_zero(v->value)) {
26124             char *val = ast_strdupa(v->value);
26125             char *trans;
26126 
26127             while ((trans = strsep(&val, ","))) {
26128                trans = ast_skip_blanks(trans);
26129 
26130                if (!strncasecmp(trans, "udp", 3)) {
26131                   peer->transports |= SIP_TRANSPORT_UDP;
26132                } else if (!strncasecmp(trans, "tcp", 3)) {
26133                   peer->transports |= SIP_TRANSPORT_TCP;
26134                } else if (!strncasecmp(trans, "tls", 3)) {
26135                   peer->transports |= SIP_TRANSPORT_TLS;
26136                } else {
26137                   ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, udp will be used.\n", trans);
26138                }
26139 
26140                if (!peer->default_outbound_transport) { /*!< The first transport listed should be default outbound */
26141                   peer->default_outbound_transport = peer->transports;
26142                }
26143             }
26144          } else if (realtime && !strcasecmp(v->name, "regseconds")) {
26145             ast_get_time_t(v->value, &regseconds, 0, NULL);
26146          } else if (realtime && !strcasecmp(v->name, "name")) {
26147             ast_copy_string(peer->name, v->value, sizeof(peer->name));
26148          } else if (realtime && !strcasecmp(v->name, "useragent")) {
26149             ast_string_field_set(peer, useragent, v->value);
26150          } else if (!strcasecmp(v->name, "type")) {
26151             if (!strcasecmp(v->value, "peer")) {
26152                peer->type |= SIP_TYPE_PEER;
26153             } else if (!strcasecmp(v->value, "user")) {
26154                peer->type |= SIP_TYPE_USER;
26155             } else if (!strcasecmp(v->value, "friend")) {
26156                peer->type = SIP_TYPE_USER | SIP_TYPE_PEER;
26157             }
26158          } else if (!strcasecmp(v->name, "remotesecret")) {
26159             ast_string_field_set(peer, remotesecret, v->value);
26160          } else if (!strcasecmp(v->name, "secret")) {
26161             ast_string_field_set(peer, secret, v->value);
26162          } else if (!strcasecmp(v->name, "md5secret")) {
26163             ast_string_field_set(peer, md5secret, v->value);
26164          } else if (!strcasecmp(v->name, "auth")) {
26165             peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno);
26166          } else if (!strcasecmp(v->name, "callerid")) {
26167             char cid_name[80] = { '\0' }, cid_num[80] = { '\0' };
26168 
26169             ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
26170             ast_string_field_set(peer, cid_name, cid_name);
26171             ast_string_field_set(peer, cid_num, cid_num);
26172          } else if (!strcasecmp(v->name, "mwi_from")) {
26173             ast_string_field_set(peer, mwi_from, v->value);
26174          } else if (!strcasecmp(v->name, "fullname")) {
26175             ast_string_field_set(peer, cid_name, v->value);
26176          } else if (!strcasecmp(v->name, "trunkname")) {
26177             /* This is actually for a trunk, so we don't want to override callerid */
26178             ast_string_field_set(peer, cid_name, "");
26179          } else if (!strcasecmp(v->name, "cid_number")) {
26180             ast_string_field_set(peer, cid_num, v->value);
26181          } else if (!strcasecmp(v->name, "cid_tag")) {
26182             ast_string_field_set(peer, cid_tag, v->value);
26183          } else if (!strcasecmp(v->name, "context")) {
26184             ast_string_field_set(peer, context, v->value);
26185             ast_set_flag(&peer->flags[1], SIP_PAGE2_HAVEPEERCONTEXT);
26186          } else if (!strcasecmp(v->name, "subscribecontext")) {
26187             ast_string_field_set(peer, subscribecontext, v->value);
26188          } else if (!strcasecmp(v->name, "fromdomain")) {
26189             char *fromdomainport;
26190             ast_string_field_set(peer, fromdomain, v->value);
26191             if ((fromdomainport = strchr(peer->fromdomain, ':'))) {
26192                *fromdomainport++ = '\0';
26193                if (!(peer->fromdomainport = port_str2int(fromdomainport, 0))) {
26194                   ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport);
26195                }
26196             } else {
26197                peer->fromdomainport = STANDARD_SIP_PORT;
26198             }
26199          } else if (!strcasecmp(v->name, "usereqphone")) {
26200             ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE);
26201          } else if (!strcasecmp(v->name, "fromuser")) {
26202             ast_string_field_set(peer, fromuser, v->value);
26203          } else if (!strcasecmp(v->name, "outboundproxy")) {
26204             char *tok, *proxyname;
26205 
26206             if (ast_strlen_zero(v->value)) {
26207                ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf.", v->lineno);
26208                continue;
26209             }
26210 
26211             peer->outboundproxy =
26212                 ao2_alloc(sizeof(*peer->outboundproxy), NULL);
26213 
26214             tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ","));
26215 
26216             sip_parse_host(tok, v->lineno, &proxyname,
26217                       &peer->outboundproxy->port,
26218                       &peer->outboundproxy->transport);
26219 
26220             tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ","));
26221 
26222             if ((tok = strtok(NULL, ","))) {
26223                peer->outboundproxy->force = !strncasecmp(ast_skip_blanks(tok), "force", 5);
26224             } else {
26225                peer->outboundproxy->force = FALSE;
26226             }
26227 
26228             if (ast_strlen_zero(proxyname)) {
26229                ast_log(LOG_WARNING, "you must specify a name for the outboundproxy on line %d of sip.conf.", v->lineno);
26230                sip_cfg.outboundproxy.name[0] = '\0';
26231                continue;
26232             }
26233 
26234             ast_copy_string(peer->outboundproxy->name, proxyname, sizeof(peer->outboundproxy->name));
26235 
26236             proxy_update(peer->outboundproxy);
26237          } else if (!strcasecmp(v->name, "host")) {
26238             if (!strcasecmp(v->value, "dynamic")) {
26239                /* They'll register with us */
26240                if (!found || !peer->host_dynamic) {
26241                   /* Initialize stuff if this is a new peer, or if it used to
26242                    * not be dynamic before the reload. */
26243                   ast_sockaddr_setnull(&peer->addr);
26244                }
26245                peer->host_dynamic = TRUE;
26246             } else {
26247                /* Non-dynamic.  Make sure we become that way if we're not */
26248                AST_SCHED_DEL_UNREF(sched, peer->expire,
26249                      unref_peer(peer, "removing register expire ref"));
26250                peer->host_dynamic = FALSE;
26251                srvlookup = v->value;
26252             }
26253          } else if (!strcasecmp(v->name, "defaultip")) {
26254             if (!ast_strlen_zero(v->value) && ast_get_ip(&peer->defaddr, v->value)) {
26255                unref_peer(peer, "unref_peer: from build_peer defaultip");
26256                return NULL;
26257             }
26258          } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
26259             int ha_error = 0;
26260             if (!ast_strlen_zero(v->value)) {
26261                peer->ha = ast_append_ha(v->name, v->value, peer->ha, &ha_error);
26262             }
26263             if (ha_error) {
26264                ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
26265             }
26266          } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) {
26267             int ha_error = 0;
26268             if (!ast_strlen_zero(v->value)) {
26269                peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha, &ha_error);
26270             }
26271             if (ha_error) {
26272                ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
26273             }
26274          } else if (!strcasecmp(v->name, "directmediapermit") || !strcasecmp(v->name, "directmediadeny")) {
26275             int ha_error = 0;
26276             peer->directmediaha = ast_append_ha(v->name + 11, v->value, peer->directmediaha, &ha_error);
26277             if (ha_error) {
26278                ast_log(LOG_ERROR, "Bad directmedia ACL entry in configuration line %d : %s\n", v->lineno, v->value);
26279             }
26280          } else if (!strcasecmp(v->name, "port")) {
26281             peer->portinuri = 1;
26282             if (!(port = port_str2int(v->value, 0))) {
26283                if (realtime) {
26284                   /* If stored as integer, could be 0 for some DBs (notably MySQL) */
26285                   peer->portinuri = 0;
26286                } else {
26287                   ast_log(LOG_WARNING, "Invalid peer port configuration at line %d : %s\n", v->lineno, v->value);
26288                }
26289             }
26290          } else if (!strcasecmp(v->name, "callingpres")) {
26291             peer->callingpres = ast_parse_caller_presentation(v->value);
26292             if (peer->callingpres == -1) {
26293                peer->callingpres = atoi(v->value);
26294             }
26295          } else if (!strcasecmp(v->name, "username") || !strcmp(v->name, "defaultuser")) {   /* "username" is deprecated */
26296             ast_string_field_set(peer, username, v->value);
26297             if (!strcasecmp(v->name, "username")) {
26298                if (deprecation_warning) {
26299                   ast_log(LOG_NOTICE, "The 'username' field for sip peers has been deprecated in favor of the term 'defaultuser'\n");
26300                   deprecation_warning = 0;
26301                }
26302                peer->deprecated_username = 1;
26303             }
26304          } else if (!strcasecmp(v->name, "language")) {
26305             ast_string_field_set(peer, language, v->value);
26306          } else if (!strcasecmp(v->name, "regexten")) {
26307             ast_string_field_set(peer, regexten, v->value);
26308          } else if (!strcasecmp(v->name, "callbackextension")) {
26309             ast_copy_string(callback, v->value, sizeof(callback));
26310          } else if (!strcasecmp(v->name, "amaflags")) {
26311             format = ast_cdr_amaflags2int(v->value);
26312             if (format < 0) {
26313                ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
26314             } else {
26315                peer->amaflags = format;
26316             }
26317          } else if (!strcasecmp(v->name, "maxforwards")) {
26318             if ((sscanf(v->value, "%30d", &peer->maxforwards) != 1) || (peer->maxforwards < 1)) {
26319                ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d.  Using default.\n", v->value, v->lineno);
26320                peer->maxforwards = sip_cfg.default_max_forwards;
26321             }
26322          } else if (!strcasecmp(v->name, "accountcode")) {
26323             ast_string_field_set(peer, accountcode, v->value);
26324          } else if (!strcasecmp(v->name, "mohinterpret")) {
26325             ast_string_field_set(peer, mohinterpret, v->value);
26326          } else if (!strcasecmp(v->name, "mohsuggest")) {
26327             ast_string_field_set(peer, mohsuggest, v->value);
26328          } else if (!strcasecmp(v->name, "parkinglot")) {
26329             ast_string_field_set(peer, parkinglot, v->value);
26330          } else if (!strcasecmp(v->name, "rtp_engine")) {
26331             ast_string_field_set(peer, engine, v->value);
26332          } else if (!strcasecmp(v->name, "mailbox")) {
26333             add_peer_mailboxes(peer, v->value);
26334          } else if (!strcasecmp(v->name, "hasvoicemail")) {
26335             /* People expect that if 'hasvoicemail' is set, that the mailbox will
26336              * be also set, even if not explicitly specified. */
26337             if (ast_true(v->value) && AST_LIST_EMPTY(&peer->mailboxes)) {
26338                add_peer_mailboxes(peer, name);
26339             }
26340          } else if (!strcasecmp(v->name, "subscribemwi")) {
26341             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
26342          } else if (!strcasecmp(v->name, "vmexten")) {
26343             ast_string_field_set(peer, vmexten, v->value);
26344          } else if (!strcasecmp(v->name, "callgroup")) {
26345             peer->callgroup = ast_get_group(v->value);
26346          } else if (!strcasecmp(v->name, "allowtransfer")) {
26347             peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
26348          } else if (!strcasecmp(v->name, "pickupgroup")) {
26349             peer->pickupgroup = ast_get_group(v->value);
26350          } else if (!strcasecmp(v->name, "allow")) {
26351             int error =  ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, TRUE);
26352             if (error) {
26353                ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
26354             }
26355          } else if (!strcasecmp(v->name, "disallow")) {
26356             int error =  ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, FALSE);
26357             if (error) {
26358                ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
26359             }
26360          } else if (!strcasecmp(v->name, "preferred_codec_only")) {
26361             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC);
26362          } else if (!strcasecmp(v->name, "registertrying")) {
26363             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_REGISTERTRYING);
26364          } else if (!strcasecmp(v->name, "autoframing")) {
26365             peer->autoframing = ast_true(v->value);
26366          } else if (!strcasecmp(v->name, "rtptimeout")) {
26367             if ((sscanf(v->value, "%30d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
26368                ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
26369                peer->rtptimeout = global_rtptimeout;
26370             }
26371          } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
26372             if ((sscanf(v->value, "%30d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
26373                ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
26374                peer->rtpholdtimeout = global_rtpholdtimeout;
26375             }
26376          } else if (!strcasecmp(v->name, "rtpkeepalive")) {
26377             if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
26378                ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
26379                peer->rtpkeepalive = global_rtpkeepalive;
26380             }
26381          } else if (!strcasecmp(v->name, "timert1")) {
26382             if ((sscanf(v->value, "%30d", &peer->timer_t1) != 1) || (peer->timer_t1 < 200) || (peer->timer_t1 < global_t1min)) {
26383                ast_log(LOG_WARNING, "'%s' is not a valid T1 time at line %d.  Using default.\n", v->value, v->lineno);
26384                peer->timer_t1 = global_t1min;
26385             }
26386             timert1_set = 1;
26387          } else if (!strcasecmp(v->name, "timerb")) {
26388             if ((sscanf(v->value, "%30d", &peer->timer_b) != 1) || (peer->timer_b < 200)) {
26389                ast_log(LOG_WARNING, "'%s' is not a valid Timer B time at line %d.  Using default.\n", v->value, v->lineno);
26390                peer->timer_b = global_timer_b;
26391             }
26392             timerb_set = 1;
26393          } else if (!strcasecmp(v->name, "setvar")) {
26394             peer->chanvars = add_var(v->value, peer->chanvars);
26395          } else if (!strcasecmp(v->name, "header")) {
26396             char tmp[4096];
26397             snprintf(tmp, sizeof(tmp), "__SIPADDHEADERpre%2d=%s", ++headercount, v->value);
26398             peer->chanvars = add_var(tmp, peer->chanvars);
26399          } else if (!strcasecmp(v->name, "qualifyfreq")) {
26400             int i;
26401             if (sscanf(v->value, "%30d", &i) == 1) {
26402                peer->qualifyfreq = i * 1000;
26403             } else {
26404                ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config);
26405                peer->qualifyfreq = global_qualifyfreq;
26406             }
26407          } else if (!strcasecmp(v->name, "maxcallbitrate")) {
26408             peer->maxcallbitrate = atoi(v->value);
26409             if (peer->maxcallbitrate < 0) {
26410                peer->maxcallbitrate = default_maxcallbitrate;
26411             }
26412          } else if (!strcasecmp(v->name, "session-timers")) {
26413             int i = (int) str2stmode(v->value);
26414             if (i < 0) {
26415                ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config);
26416                peer->stimer.st_mode_oper = global_st_mode;
26417             } else {
26418                peer->stimer.st_mode_oper = i;
26419             }
26420          } else if (!strcasecmp(v->name, "session-expires")) {
26421             if (sscanf(v->value, "%30d", &peer->stimer.st_max_se) != 1) {
26422                ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config);
26423                peer->stimer.st_max_se = global_max_se;
26424             }
26425          } else if (!strcasecmp(v->name, "session-minse")) {
26426             if (sscanf(v->value, "%30d", &peer->stimer.st_min_se) != 1) {
26427                ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config);
26428                peer->stimer.st_min_se = global_min_se;
26429             }
26430             if (peer->stimer.st_min_se < 90) {
26431                ast_log(LOG_WARNING, "session-minse '%s' at line %d of %s is not allowed to be < 90 secs\n", v->value, v->lineno, config);
26432                peer->stimer.st_min_se = global_min_se;
26433             }
26434          } else if (!strcasecmp(v->name, "session-refresher")) {
26435             int i = (int) str2strefresher(v->value);
26436             if (i < 0) {
26437                ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config);
26438                peer->stimer.st_ref = global_st_refresher;
26439             } else {
26440                peer->stimer.st_ref = i;
26441             }
26442          } else if (!strcasecmp(v->name, "disallowed_methods")) {
26443             char *disallow = ast_strdupa(v->value);
26444             mark_parsed_methods(&peer->disallowed_methods, disallow);
26445          } else if (!strcasecmp(v->name, "unsolicited_mailbox")) {
26446             ast_string_field_set(peer, unsolicited_mailbox, v->value);
26447          } else if (!strcasecmp(v->name, "use_q850_reason")) {
26448             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON);
26449          } else if (!strcasecmp(v->name, "encryption")) {
26450             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_USE_SRTP);
26451          } else if (!strcasecmp(v->name, "snom_aoc_enabled")) {
26452             ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC);
26453          }
26454       }
26455 
26456       /* These apply to devstate lookups */
26457       if (realtime && !strcasecmp(v->name, "lastms")) {
26458          sscanf(v->value, "%30d", &peer->lastms);
26459       } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
26460          ast_sockaddr_parse(&peer->addr, v->value, PARSE_PORT_FORBID);
26461       } else if (realtime && !strcasecmp(v->name, "fullcontact")) {
26462          if (alt_fullcontact && !alt) {
26463             /* Reset, because the alternate also has a fullcontact and we
26464              * do NOT want the field value to be doubled. It might be
26465              * tempting to skip this, but the first table might not have
26466              * fullcontact and since we're here, we know that the alternate
26467              * absolutely does. */
26468             alt_fullcontact = 0;
26469             ast_str_reset(fullcontact);
26470          }
26471          /* Reconstruct field, because realtime separates our value at the ';' */
26472          if (fullcontact->used > 0) {
26473             ast_str_append(&fullcontact, 0, ";%s", v->value);
26474          } else {
26475             ast_str_set(&fullcontact, 0, "%s", v->value);
26476          }
26477       } else if (!strcasecmp(v->name, "qualify")) {
26478          if (!strcasecmp(v->value, "no")) {
26479             peer->maxms = 0;
26480          } else if (!strcasecmp(v->value, "yes")) {
26481             peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS;
26482          } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
26483             ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", peer->name, v->lineno);
26484             peer->maxms = 0;
26485          }
26486          if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) {
26487             /* This would otherwise cause a network storm, where the
26488              * qualify response refreshes the peer from the database,
26489              * which in turn causes another qualify to be sent, ad
26490              * infinitum. */
26491             ast_log(LOG_WARNING, "Qualify is incompatible with dynamic uncached realtime.  Please either turn rtcachefriends on or turn qualify off on peer '%s'\n", peer->name);
26492             peer->maxms = 0;
26493          }
26494       } else if (!strcasecmp(v->name, "callcounter")) {
26495          peer->call_limit = ast_true(v->value) ? INT_MAX : 0;
26496       } else if (!strcasecmp(v->name, "call-limit")) {
26497          peer->call_limit = atoi(v->value);
26498          if (peer->call_limit < 0) {
26499             peer->call_limit = 0;
26500          }
26501       } else if (!strcasecmp(v->name, "busylevel")) {
26502          peer->busy_level = atoi(v->value);
26503          if (peer->busy_level < 0) {
26504             peer->busy_level = 0;
26505          }
26506       } else if (ast_cc_is_config_param(v->name)) {
26507          ast_cc_set_param(peer->cc_params, v->name, v->value);
26508       }
26509    }
26510 
26511    if (!devstate_only) {
26512       struct sip_mailbox *mailbox;
26513       AST_LIST_TRAVERSE_SAFE_BEGIN(&peer->mailboxes, mailbox, entry) {
26514          if (mailbox->delme) {
26515             AST_LIST_REMOVE_CURRENT(entry);
26516             destroy_mailbox(mailbox);
26517          }
26518       }
26519       AST_LIST_TRAVERSE_SAFE_END;
26520    }
26521 
26522    if (!can_parse_xml && (ast_get_cc_agent_policy(peer->cc_params) == AST_CC_AGENT_NATIVE)) {
26523       ast_log(LOG_WARNING, "Peer %s has a cc_agent_policy of 'native' but required libxml2 dependency is not installed. Changing policy to 'never'\n", peer->name);
26524       ast_set_cc_agent_policy(peer->cc_params, AST_CC_AGENT_NEVER);
26525    }
26526 
26527    /* Note that Timer B is dependent upon T1 and MUST NOT be lower
26528     * than T1 * 64, according to RFC 3261, Section 17.1.1.2 */
26529    if (peer->timer_b < peer->timer_t1 * 64) {
26530       if (timerb_set && timert1_set) {
26531          ast_log(LOG_WARNING, "Timer B has been set lower than recommended for peer %s (%d < 64 * Timer-T1=%d)\n", peer->name, peer->timer_b, peer->timer_t1);
26532       } else if (timerb_set) {
26533          if ((peer->timer_t1 = peer->timer_b / 64) < global_t1min) {
26534             ast_log(LOG_WARNING, "Timer B has been set lower than recommended (%d < 64 * timert1=%d). (RFC 3261, 17.1.1.2)\n", peer->timer_b, peer->timer_t1);
26535             peer->timer_t1 = global_t1min;
26536             peer->timer_b = peer->timer_t1 * 64;
26537          }
26538          peer->timer_t1 = peer->timer_b / 64;
26539       } else {
26540          peer->timer_b = peer->timer_t1 * 64;
26541       }
26542    }
26543 
26544    if (!peer->default_outbound_transport) {
26545       /* Set default set of transports */
26546       peer->transports = default_transports;
26547       /* Set default primary transport */
26548       peer->default_outbound_transport = default_primary_transport;
26549    }
26550 
26551    /* The default transport type set during build_peer should only replace the socket.type when...
26552     * 1. Registration is not present and the socket.type and default transport types are different.
26553     * 2. The socket.type is not an acceptable transport type after rebuilding peer.
26554     * 3. The socket.type is not set yet. */
26555    if (((peer->socket.type != peer->default_outbound_transport) && (peer->expire == -1)) ||
26556       !(peer->socket.type & peer->transports) || !(peer->socket.type)) {
26557 
26558       set_socket_transport(&peer->socket, peer->default_outbound_transport);
26559    }
26560 
26561    if (ast_str_strlen(fullcontact)) {
26562       ast_string_field_set(peer, fullcontact, ast_str_buffer(fullcontact));
26563       peer->rt_fromcontact = TRUE;
26564       /* We have a hostname in the fullcontact, but if we don't have an
26565        * address listed on the entry (or if it's 'dynamic'), then we need to
26566        * parse the entry to obtain the IP address, so a dynamic host can be
26567        * contacted immediately after reload (as opposed to waiting for it to
26568        * register once again). But if we have an address for this peer and NAT was
26569        * specified, use that address instead. */
26570       /* XXX May need to revisit the final argument; does the realtime DB store whether
26571        * the original contact was over TLS or not? XXX */
26572       if (!ast_test_flag(&peer->flags[0], SIP_NAT_RPORT_PRESENT) || ast_sockaddr_isnull(&peer->addr)) {
26573          __set_address_from_contact(fullcontact->str, &peer->addr, 0);
26574       }
26575    }
26576 
26577    if (srvlookup && peer->dnsmgr == NULL) {
26578       char transport[MAXHOSTNAMELEN];
26579       char _srvlookup[MAXHOSTNAMELEN];
26580       char *params;
26581 
26582       ast_copy_string(_srvlookup, srvlookup, sizeof(_srvlookup));
26583       if ((params = strchr(_srvlookup, ';'))) {
26584          *params++ = '\0';
26585       }
26586 
26587       snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(peer->socket.type), get_srv_protocol(peer->socket.type));
26588 
26589       peer->addr.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */
26590       if (ast_dnsmgr_lookup(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup && !peer->portinuri ? transport : NULL)) {
26591          ast_log(LOG_ERROR, "srvlookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name);
26592          unref_peer(peer, "getting rid of a peer pointer");
26593          return NULL;
26594       }
26595 
26596       ast_string_field_set(peer, tohost, srvlookup);
26597 
26598       if (global_dynamic_exclude_static) {
26599          int err = 0;
26600          sip_cfg.contact_ha = ast_append_ha("deny", ast_sockaddr_stringify_addr(&peer->addr), 
26601                      sip_cfg.contact_ha, &err);
26602          if (err) {
26603             ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
26604          }
26605       }
26606    } else if (peer->dnsmgr && !peer->host_dynamic) {
26607       /* force a refresh here on reload if dnsmgr already exists and host is set. */
26608       ast_dnsmgr_refresh(peer->dnsmgr);
26609    }
26610 
26611    if (port && !realtime && peer->host_dynamic) {
26612       ast_sockaddr_set_port(&peer->defaddr, port);
26613    } else if (port) {
26614       ast_sockaddr_set_port(&peer->addr, port);
26615    }
26616 
26617    if (ast_sockaddr_port(&peer->addr) == 0) {
26618       ast_sockaddr_set_port(&peer->addr,
26619                   (peer->socket.type & SIP_TRANSPORT_TLS) ?
26620                   STANDARD_TLS_PORT : STANDARD_SIP_PORT);
26621    }
26622    if (ast_sockaddr_port(&peer->defaddr) == 0) {
26623       ast_sockaddr_set_port(&peer->defaddr,
26624                   (peer->socket.type & SIP_TRANSPORT_TLS) ?
26625                   STANDARD_TLS_PORT : STANDARD_SIP_PORT);
26626    }
26627    if (!peer->socket.port) {
26628       peer->socket.port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));
26629    }
26630 
26631    if (!sip_cfg.ignore_regexpire && peer->host_dynamic && realtime) {
26632       time_t nowtime = time(NULL);
26633 
26634       if ((nowtime - regseconds) > 0) {
26635          destroy_association(peer);
26636          memset(&peer->addr, 0, sizeof(peer->addr));
26637          peer->lastms = -1;
26638          ast_debug(1, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
26639       }
26640    }
26641 
26642    /* Startup regular pokes */
26643    if (!devstate_only && realtime && peer->lastms > 0) {
26644       ref_peer(peer, "schedule qualify");
26645       sip_poke_peer(peer, 0);
26646    }
26647 
26648    ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
26649    ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
26650    ast_copy_flags(&peer->flags[2], &peerflags[2], mask[2].flags);
26651    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
26652       sip_cfg.allowsubscribe = TRUE;   /* No global ban any more */
26653    }
26654    if (peer->host_dynamic && !peer->is_realtime) {
26655       reg_source_db(peer);
26656    }
26657 
26658    /* If they didn't request that MWI is sent *only* on subscribe, go ahead and
26659     * subscribe to it now. */
26660    if (!devstate_only && !ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
26661       !AST_LIST_EMPTY(&peer->mailboxes)) {
26662       add_peer_mwi_subs(peer);
26663       /* Send MWI from the event cache only.  This is so we can send initial
26664        * MWI if app_voicemail got loaded before chan_sip.  If it is the other
26665        * way, then we will get events when app_voicemail gets loaded. */
26666       sip_send_mwi_to_peer(peer, NULL, 1);
26667    }
26668 
26669    peer->the_mark = 0;
26670 
26671    ast_free_ha(oldha);
26672    ast_free_ha(olddirectmediaha);
26673    if (!ast_strlen_zero(callback)) { /* build string from peer info */
26674       char *reg_string;
26675       if (asprintf(&reg_string, "%s?%s:%s@%s/%s", peer->name, peer->username, !ast_strlen_zero(peer->remotesecret) ? peer->remotesecret : peer->secret, peer->tohost, callback) < 0) {
26676          ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
26677       } else if (reg_string) {
26678          sip_register(reg_string, 0); /* XXX TODO: count in registry_count */
26679          ast_free(reg_string);
26680       }
26681    }
26682    return peer;
26683 }

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

Build reply digest.

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

Definition at line 18352 of file chan_sip.c.

References append_history, ast_copy_string(), ast_debug, ast_md5_hash(), ast_random(), ast_sockaddr_stringify_host(), ast_strlen_zero(), authl, find_realm_authentication(), secret, and sip_methods.

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

18353 {
18354    char a1[256];
18355    char a2[256];
18356    char a1_hash[256];
18357    char a2_hash[256];
18358    char resp[256];
18359    char resp_hash[256];
18360    char uri[256];
18361    char opaque[256] = "";
18362    char cnonce[80];
18363    const char *username;
18364    const char *secret;
18365    const char *md5secret;
18366    struct sip_auth *auth = NULL; /* Realm authentication */
18367 
18368    if (!ast_strlen_zero(p->domain))
18369       ast_copy_string(uri, p->domain, sizeof(uri));
18370    else if (!ast_strlen_zero(p->uri))
18371       ast_copy_string(uri, p->uri, sizeof(uri));
18372    else
18373       snprintf(uri, sizeof(uri), "sip:%s@%s", p->username, ast_sockaddr_stringify_host(&p->sa));
18374 
18375    snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random());
18376 
18377    /* Check if we have separate auth credentials */
18378    if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */
18379       auth = find_realm_authentication(authl, p->realm); /* If not, global list */
18380 
18381    if (auth) {
18382       ast_debug(3, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username);
18383       username = auth->username;
18384       secret = auth->secret;
18385       md5secret = auth->md5secret;
18386       if (sipdebug)
18387          ast_debug(1, "Using realm %s authentication for call %s\n", p->realm, p->callid);
18388    } else {
18389       /* No authentication, use peer or register= config */
18390       username = p->authname;
18391       secret =  p->peersecret;
18392       md5secret = p->peermd5secret;
18393    }
18394    if (ast_strlen_zero(username))   /* We have no authentication */
18395       return -1;
18396 
18397    /* Calculate SIP digest response */
18398    snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret);
18399    snprintf(a2, sizeof(a2), "%s:%s", sip_methods[method].text, uri);
18400    if (!ast_strlen_zero(md5secret))
18401       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
18402    else
18403       ast_md5_hash(a1_hash, a1);
18404    ast_md5_hash(a2_hash, a2);
18405 
18406    p->noncecount++;
18407    if (!ast_strlen_zero(p->qop))
18408       snprintf(resp, sizeof(resp), "%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
18409    else
18410       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, p->nonce, a2_hash);
18411    ast_md5_hash(resp_hash, resp);
18412 
18413    /* only include the opaque string if it's set */
18414    if (!ast_strlen_zero(p->opaque)) {
18415      snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque);
18416    }
18417 
18418    /* XXX We hard code our qop to "auth" for now.  XXX */
18419    if (!ast_strlen_zero(p->qop))
18420       snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s, qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, opaque, cnonce, p->noncecount);
18421    else
18422       snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s", username, p->realm, uri, p->nonce, resp_hash, opaque);
18423 
18424    append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount);
18425 
18426    return 0;
18427 }

static void build_route ( struct sip_pvt *  p,
struct sip_request *  req,
int  backwards 
) [static]

Build route list from Record-Route header.

Definition at line 13463 of file chan_sip.c.

References __get_header(), ast_copy_string(), ast_debug, ast_malloc, ast_strlen_zero(), free_old_route(), get_header(), len(), list_route(), and sip_debug_test_pvt().

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

13464 {
13465    struct sip_route *thishop, *head, *tail;
13466    int start = 0;
13467    int len;
13468    const char *rr, *contact, *c;
13469 
13470    /* Once a persistent route is set, don't fool with it */
13471    if (p->route && p->route_persistent) {
13472       ast_debug(1, "build_route: Retaining previous route: <%s>\n", p->route->hop);
13473       return;
13474    }
13475 
13476    if (p->route) {
13477       free_old_route(p->route);
13478       p->route = NULL;
13479    }
13480 
13481    /* We only want to create the route set the first time this is called */
13482    p->route_persistent = 1;
13483    
13484    /* Build a tailq, then assign it to p->route when done.
13485     * If backwards, we add entries from the head so they end up
13486     * in reverse order. However, we do need to maintain a correct
13487     * tail pointer because the contact is always at the end.
13488     */
13489    head = NULL;
13490    tail = head;
13491    /* 1st we pass through all the hops in any Record-Route headers */
13492    for (;;) {
13493       /* Each Record-Route header */
13494       rr = __get_header(req, "Record-Route", &start);
13495       if (*rr == '\0') {
13496          break;
13497       }
13498       for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */
13499          ++rr;
13500          len = strcspn(rr, ">") + 1;
13501          /* Make a struct route */
13502          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
13503             /* ast_calloc is not needed because all fields are initialized in this block */
13504             ast_copy_string(thishop->hop, rr, len);
13505             ast_debug(2, "build_route: Record-Route hop: <%s>\n", thishop->hop);
13506             /* Link in */
13507             if (backwards) {
13508                /* Link in at head so they end up in reverse order */
13509                thishop->next = head;
13510                head = thishop;
13511                /* If this was the first then it'll be the tail */
13512                if (!tail) {
13513                   tail = thishop;
13514                }
13515             } else {
13516                thishop->next = NULL;
13517                /* Link in at the end */
13518                if (tail) {
13519                   tail->next = thishop;
13520                } else {
13521                   head = thishop;
13522                }
13523                tail = thishop;
13524             }
13525          }
13526       }
13527    }
13528 
13529    /* Only append the contact if we are dealing with a strict router */
13530    if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop, ";lr") == NULL) ) {
13531       /* 2nd append the Contact: if there is one */
13532       /* Can be multiple Contact headers, comma separated values - we just take the first */
13533       contact = get_header(req, "Contact");
13534       if (!ast_strlen_zero(contact)) {
13535          ast_debug(2, "build_route: Contact hop: %s\n", contact);
13536          /* Look for <: delimited address */
13537          c = strchr(contact, '<');
13538          if (c) {
13539             /* Take to > */
13540             ++c;
13541             len = strcspn(c, ">") + 1;
13542          } else {
13543             /* No <> - just take the lot */
13544             c = contact;
13545             len = strlen(contact) + 1;
13546          }
13547          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
13548             /* ast_calloc is not needed because all fields are initialized in this block */
13549             ast_copy_string(thishop->hop, c, len);
13550             thishop->next = NULL;
13551             /* Goes at the end */
13552             if (tail) {
13553                tail->next = thishop;
13554             } else {
13555                head = thishop;
13556             }
13557          }
13558       }
13559    }
13560 
13561    /* Store as new route */
13562    p->route = head;
13563 
13564    /* For debugging dump what we ended up with */
13565    if (sip_debug_test_pvt(p)) {
13566       list_route(p->route);
13567    }
13568 }

static void build_via ( struct sip_pvt *  p  )  [static]

Build a Via header for a request.

Definition at line 3287 of file chan_sip.c.

References ast_sockaddr_stringify(), ast_test_flag, and get_transport_pvt().

Referenced by __sip_subscribe_mwi_do(), reqprep(), sip_alloc(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), transmit_register(), and transmit_response_using_temp().

03288 {
03289    /* Work around buggy UNIDEN UIP200 firmware */
03290    const char *rport = (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)) ? ";rport" : "";
03291 
03292    /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
03293    snprintf(p->via, sizeof(p->via), "SIP/2.0/%s %s;branch=z9hG4bK%08x%s",
03294        get_transport_pvt(p),
03295        ast_sockaddr_stringify(&p->ourip),
03296        (int) p->branch, rport);
03297 }

static int cb_extensionstate ( char *  context,
char *  exten,
int  state,
void *  data 
) [static]

Callback for the devicestate notification (SUBSCRIBE) support subsystem.

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

Definition at line 13838 of file chan_sip.c.

References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_set_flag, ast_test_flag, ast_verb, FALSE, NONE, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), and transmit_state_notify().

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

13839 {
13840    struct sip_pvt *p = data;
13841 
13842    sip_pvt_lock(p);
13843 
13844    switch(state) {
13845    case AST_EXTENSION_DEACTIVATED:  /* Retry after a while */
13846    case AST_EXTENSION_REMOVED:   /* Extension is gone */
13847       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);  /* Delete subscription in 32 secs */
13848       ast_verb(2, "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username);
13849       p->stateid = -1;
13850       p->subscribed = NONE;
13851       append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
13852       break;
13853    default: /* Tell user */
13854       p->laststate = state;
13855       break;
13856    }
13857    if (p->subscribed != NONE) {  /* Only send state NOTIFY if we know the format */
13858       if (!p->pendinginvite) {
13859          transmit_state_notify(p, state, 1, FALSE);
13860       } else {
13861          /* We already have a NOTIFY sent that is not answered. Queue the state up.
13862             if many state changes happen meanwhile, we will only send a notification of the last one */
13863          ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
13864       }
13865    }
13866    ast_verb(2, "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username,
13867          ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : "");
13868 
13869    sip_pvt_unlock(p);
13870 
13871    return 0;
13872 }

static void cc_epa_destructor ( void *  data  )  [static]

Definition at line 876 of file chan_sip.c.

References ast_free.

00877 {
00878    struct sip_epa_entry *epa_entry = data;
00879    struct cc_epa_entry *cc_entry = epa_entry->instance_data;
00880    ast_free(cc_entry);
00881 }

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

Definition at line 23025 of file chan_sip.c.

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

23026 {
23027    const char *uri = REQ_OFFSET_TO_STR(req, rlPart2);
23028    struct ast_cc_agent *agent = find_sip_cc_agent_by_notify_uri(uri);
23029    struct sip_cc_agent_pvt *agent_pvt;
23030    struct ast_xml_doc *pidf_doc = NULL;
23031    const char *basic_status = NULL;
23032    struct ast_xml_node *presence_node;
23033    struct ast_xml_node *presence_children;
23034    struct ast_xml_node *tuple_node;
23035    struct ast_xml_node *tuple_children;
23036    struct ast_xml_node *status_node;
23037    struct ast_xml_node *status_children;
23038    struct ast_xml_node *basic_node;
23039    int res = 0;
23040 
23041    if (!agent) {
23042       ast_log(LOG_WARNING, "Could not find agent using uri '%s'\n", uri);
23043       transmit_response(pvt, "412 Conditional Request Failed", req);
23044       return -1;
23045    }
23046 
23047    agent_pvt = agent->private_data;
23048 
23049    if (sip_pidf_validate(req, &pidf_doc) == FALSE) {
23050       res = -1;
23051       goto cc_publish_cleanup;
23052    }
23053 
23054    /* It's important to note that the PIDF validation routine has no knowledge
23055     * of what we specifically want in this instance. A valid PIDF document could
23056     * have no tuples, or it could have tuples whose status element has no basic
23057     * element contained within. While not violating the PIDF spec, these are
23058     * insufficient for our needs in this situation
23059     */
23060    presence_node = ast_xml_get_root(pidf_doc);
23061    if (!(presence_children = ast_xml_node_get_children(presence_node))) {
23062       ast_log(LOG_WARNING, "No tuples within presence element.\n");
23063       res = -1;
23064       goto cc_publish_cleanup;
23065    }
23066 
23067    if (!(tuple_node = ast_xml_find_element(presence_children, "tuple", NULL, NULL))) {
23068       ast_log(LOG_NOTICE, "Couldn't find tuple node?\n");
23069       res = -1;
23070       goto cc_publish_cleanup;
23071    }
23072 
23073    /* We already made sure that the tuple has a status node when we validated the PIDF
23074     * document earlier. So there's no need to enclose this operation in an if statement.
23075     */
23076    tuple_children = ast_xml_node_get_children(tuple_node);
23077    status_node = ast_xml_find_element(tuple_children, "status", NULL, NULL);
23078 
23079    if (!(status_children = ast_xml_node_get_children(status_node))) {
23080       ast_log(LOG_WARNING, "No basic elements within status element.\n");
23081       res = -1;
23082       goto cc_publish_cleanup;
23083    }
23084 
23085    if (!(basic_node = ast_xml_find_element(status_children, "basic", NULL, NULL))) {
23086       ast_log(LOG_WARNING, "Couldn't find basic node?\n");
23087       res = -1;
23088       goto cc_publish_cleanup;
23089    }
23090 
23091    basic_status = ast_xml_get_text(basic_node);
23092 
23093    if (ast_strlen_zero(basic_status)) {
23094       ast_log(LOG_NOTICE, "NOthing in basic node?\n");
23095       res = -1;
23096       goto cc_publish_cleanup;
23097    }
23098 
23099    if (!strcmp(basic_status, "open")) {
23100       agent_pvt->is_available = TRUE;
23101       ast_cc_agent_caller_available(agent->core_id, "Received PUBLISH stating SIP caller %s is available",
23102             agent->device_name);
23103    } else if (!strcmp(basic_status, "closed")) {
23104       agent_pvt->is_available = FALSE;
23105       ast_cc_agent_caller_busy(agent->core_id, "Received PUBLISH stating SIP caller %s is busy",
23106             agent->device_name);
23107    } else {
23108       ast_log(LOG_NOTICE, "Invalid content in basic element: %s\n", basic_status);
23109    }
23110 
23111 cc_publish_cleanup:
23112    if (basic_status) {
23113       ast_xml_free_text(basic_status);
23114    }
23115    if (pidf_doc) {
23116       ast_xml_close(pidf_doc);
23117    }
23118    ao2_ref(agent, -1);
23119    if (res) {
23120       transmit_response(pvt, "400 Bad Request", req);
23121    }
23122    return res;
23123 }

static void cc_handle_publish_error ( struct sip_pvt *  pvt,
const int  resp,
struct sip_request *  req,
struct sip_epa_entry *  epa_entry 
) [static]

Definition at line 18938 of file chan_sip.c.

References ao2_callback, ao2_ref, ast_cc_monitor_failed(), ast_log(), ast_strlen_zero(), FALSE, find_sip_monitor_instance_by_suspension_entry(), get_header(), LOG_WARNING, sip_monitor_instances, and transmit_invite().

18939 {
18940    struct cc_epa_entry *cc_entry = epa_entry->instance_data;
18941    struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0,
18942          find_sip_monitor_instance_by_suspension_entry, epa_entry);
18943    const char *min_expires;
18944 
18945    if (!monitor_instance) {
18946       ast_log(LOG_WARNING, "Can't find monitor_instance corresponding to epa_entry %p.\n", epa_entry);
18947       return;
18948    }
18949 
18950    if (resp != 423) {
18951       ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name,
18952             "Received error response to our PUBLISH");
18953       ao2_ref(monitor_instance, -1);
18954       return;
18955    }
18956 
18957    /* Allrighty, the other end doesn't like our Expires value. They think it's
18958     * too small, so let's see if they've provided a more sensible value. If they
18959     * haven't, then we'll just double our Expires value and see if they like that
18960     * instead.
18961     *
18962     * XXX Ideally this logic could be placed into its own function so that SUBSCRIBE,
18963     * PUBLISH, and REGISTER could all benefit from the same shared code.
18964     */
18965    min_expires = get_header(req, "Min-Expires");
18966    if (ast_strlen_zero(min_expires)) {
18967       pvt->expiry *= 2;
18968       if (pvt->expiry < 0) {
18969          /* You dork! You overflowed! */
18970          ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name,
18971                "PUBLISH expiry overflowed");
18972          ao2_ref(monitor_instance, -1);
18973          return;
18974       }
18975    } else if (sscanf(min_expires, "%d", &pvt->expiry) != 1) {
18976       ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name,
18977             "Min-Expires has non-numeric value");
18978       ao2_ref(monitor_instance, -1);
18979       return;
18980    }
18981    /* At this point, we have most certainly changed pvt->expiry, so try transmitting
18982     * again
18983     */
18984    transmit_invite(pvt, SIP_PUBLISH, FALSE, 0, NULL);
18985    ao2_ref(monitor_instance, -1);
18986 }

static void change_hold_state ( struct sip_pvt *  dialog,
struct sip_request *  req,
int  holdstate,
int  sendonly 
) [static]

Change hold state for a call.

Definition at line 8210 of file chan_sip.c.

References append_history, ast_clear_flag, ast_set_flag, ast_test_flag, EVENT_FLAG_CALL, manager_event, sip_cfg, and sip_peer_hold().

Referenced by handle_request_invite(), and process_sdp().

08211 {
08212    if (sip_cfg.notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD)))
08213       sip_peer_hold(dialog, holdstate);
08214    if (sip_cfg.callevents)
08215       manager_event(EVENT_FLAG_CALL, "Hold",
08216                "Status: %s\r\n"
08217                "Channel: %s\r\n"
08218                "Uniqueid: %s\r\n",
08219                holdstate ? "On" : "Off",
08220                dialog->owner->name,
08221                dialog->owner->uniqueid);
08222    append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data->str);
08223    if (!holdstate) { /* Put off remote hold */
08224       ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD);   /* Clear both flags */
08225       return;
08226    }
08227    /* No address for RTP, we're on hold */
08228 
08229    if (sendonly == 1)   /* One directional hold (sendonly/recvonly) */
08230       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
08231    else if (sendonly == 2) /* Inactive stream */
08232       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
08233    else
08234       ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE);
08235    return;
08236 }

static void change_redirecting_information ( struct sip_pvt *  p,
struct sip_request *  req,
struct ast_party_redirecting *  redirecting,
struct ast_set_party_redirecting *  update_redirecting,
int  set_call_forward 
) [static]

update redirecting information for a channel based on headers

Definition at line 18675 of file chan_sip.c.

References ast_debug, ast_free, AST_REDIRECTING_REASON_UNCONDITIONAL, ast_strdup, ast_strlen_zero(), ast_party_redirecting::from, get_header(), get_rdnis(), ast_party_id::name, ast_party_id::number, parse_moved_contact(), ast_party_redirecting::reason, ast_party_name::str, ast_party_number::str, ast_party_id::tag, ast_party_redirecting::to, update_redirecting(), ast_party_name::valid, and ast_party_number::valid.

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

18678 {
18679    char *redirecting_from_name = NULL;
18680    char *redirecting_from_number = NULL;
18681    char *redirecting_to_name = NULL;
18682    char *redirecting_to_number = NULL;
18683    int reason = AST_REDIRECTING_REASON_UNCONDITIONAL;
18684    int is_response = req->method == SIP_RESPONSE;
18685    int res = 0;
18686 
18687    res = get_rdnis(p, req, &redirecting_from_name, &redirecting_from_number, &reason);
18688    if (res == -1) {
18689       if (is_response) {
18690          get_name_and_number(get_header(req, "TO"), &redirecting_from_name, &redirecting_from_number);
18691       } else {
18692          return;
18693       }
18694    }
18695 
18696    /* At this point, all redirecting "from" info should be filled in appropriately
18697     * on to the "to" info
18698     */
18699 
18700    if (is_response) {
18701       parse_moved_contact(p, req, &redirecting_to_name, &redirecting_to_number, set_call_forward);
18702    } else {
18703       get_name_and_number(get_header(req, "TO"), &redirecting_to_name, &redirecting_to_number);
18704    }
18705 
18706    if (!ast_strlen_zero(redirecting_from_number)) {
18707       ast_debug(3, "Got redirecting from number %s\n", redirecting_from_number);
18708       update_redirecting->from.number = 1;
18709       redirecting->from.number.valid = 1;
18710       ast_free(redirecting->from.number.str);
18711       redirecting->from.number.str = redirecting_from_number;
18712    }
18713    if (!ast_strlen_zero(redirecting_from_name)) {
18714       ast_debug(3, "Got redirecting from name %s\n", redirecting_from_name);
18715       update_redirecting->from.name = 1;
18716       redirecting->from.name.valid = 1;
18717       ast_free(redirecting->from.name.str);
18718       redirecting->from.name.str = redirecting_from_name;
18719    }
18720    if (!ast_strlen_zero(p->cid_tag)) {
18721       ast_free(redirecting->from.tag);
18722       redirecting->from.tag = ast_strdup(p->cid_tag);
18723       ast_free(redirecting->to.tag);
18724       redirecting->to.tag = ast_strdup(p->cid_tag);
18725    }
18726    if (!ast_strlen_zero(redirecting_to_number)) {
18727       ast_debug(3, "Got redirecting to number %s\n", redirecting_to_number);
18728       update_redirecting->to.number = 1;
18729       redirecting->to.number.valid = 1;
18730       ast_free(redirecting->to.number.str);
18731       redirecting->to.number.str = redirecting_to_number;
18732    }
18733    if (!ast_strlen_zero(redirecting_to_name)) {
18734       ast_debug(3, "Got redirecting to name %s\n", redirecting_from_number);
18735       update_redirecting->to.name = 1;
18736       redirecting->to.name.valid = 1;
18737       ast_free(redirecting->to.name.str);
18738       redirecting->to.name.str = redirecting_to_name;
18739    }
18740    redirecting->reason = reason;
18741 }

static void change_t38_state ( struct sip_pvt *  p,
int  state 
) [static]

Change the T38 state on a SIP dialog.

Definition at line 4867 of file chan_sip.c.

References AST_CONTROL_T38_PARAMETERS, ast_debug, ast_queue_control_data(), AST_T38_NEGOTIATED, AST_T38_REFUSED, AST_T38_REQUEST_NEGOTIATE, AST_T38_TERMINATED, ast_udptl_get_far_max_ifp(), ast_udptl_set_tag(), ast_control_t38_parameters::max_ifp, ast_channel::name, and ast_control_t38_parameters::request_response.

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

04868 {
04869    int old = p->t38.state;
04870    struct ast_channel *chan = p->owner;
04871    struct ast_control_t38_parameters parameters = { .request_response = 0 };
04872 
04873    /* Don't bother changing if we are already in the state wanted */
04874    if (old == state)
04875       return;
04876 
04877    p->t38.state = state;
04878    ast_debug(2, "T38 state changed to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>");
04879 
04880    /* If no channel was provided we can't send off a control frame */
04881    if (!chan)
04882       return;
04883 
04884    /* Given the state requested and old state determine what control frame we want to queue up */
04885    switch (state) {
04886    case T38_PEER_REINVITE:
04887       parameters = p->t38.their_parms;
04888       parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
04889       parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
04890       ast_udptl_set_tag(p->udptl, "SIP/%s", p->username);
04891       break;
04892    case T38_ENABLED:
04893       parameters = p->t38.their_parms;
04894       parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
04895       parameters.request_response = AST_T38_NEGOTIATED;
04896       ast_udptl_set_tag(p->udptl, "SIP/%s", p->username);
04897       break;
04898    case T38_DISABLED:
04899       if (old == T38_ENABLED) {
04900          parameters.request_response = AST_T38_TERMINATED;
04901       } else if (old == T38_LOCAL_REINVITE) {
04902          parameters.request_response = AST_T38_REFUSED;
04903       }
04904       break;
04905    case T38_LOCAL_REINVITE:
04906       /* wait until we get a peer response before responding to local reinvite */
04907       break;
04908    }
04909 
04910    /* Woot we got a message, create a control frame and send it on! */
04911    if (parameters.request_response)
04912       ast_queue_control_data(chan, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
04913 }

static enum check_auth_result check_auth ( struct sip_pvt *  p,
struct sip_request *  req,
const char *  username,
const char *  secret,
const char *  md5secret,
int  sipmethod,
const char *  uri,
enum xmittype  reliable,
int  ignore 
) [static]

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

Returns:
0 on success, non-zero on error

XXX

Todo:
need a better return code here

XXX

Todo:
need a better return code here

Definition at line 13592 of file chan_sip.c.

References AST_DYNSTR_BUILD_FAILED, ast_skip_blanks(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), auth_headers(), check_auth_buf, CHECK_AUTH_BUF_INITLEN, FALSE, get_header(), set_nonce_randdata(), sip_scheddestroy(), strsep(), and transmit_response_with_auth().

Referenced by check_peer_ok(), and register_verify().

13595 {
13596    const char *response;
13597    char *reqheader, *respheader;
13598    const char *authtoken;
13599    char a1_hash[256];
13600    char resp_hash[256]="";
13601    char *c;
13602    int  wrongnonce = FALSE;
13603    int  good_response;
13604    const char *usednonce = p->randdata;
13605    struct ast_str *buf;
13606    int res;
13607 
13608    /* table of recognised keywords, and their value in the digest */
13609    enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
13610    struct x {
13611       const char *key;
13612       const char *s;
13613    } *i, keys[] = {
13614       [K_RESP] = { "response=", "" },
13615       [K_URI] = { "uri=", "" },
13616       [K_USER] = { "username=", "" },
13617       [K_NONCE] = { "nonce=", "" },
13618       [K_LAST] = { NULL, NULL}
13619    };
13620 
13621    /* Always OK if no secret */
13622    if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret))
13623       return AUTH_SUCCESSFUL;
13624 
13625    /* Always auth with WWW-auth since we're NOT a proxy */
13626    /* Using proxy-auth in a B2BUA may block proxy authorization in the same transaction */
13627    response = "401 Unauthorized";
13628 
13629    /*
13630     * Note the apparent swap of arguments below, compared to other
13631     * usages of auth_headers().
13632     */
13633    auth_headers(WWW_AUTH, &respheader, &reqheader);
13634 
13635    authtoken =  get_header(req, reqheader);  
13636    if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
13637       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
13638          information */
13639       if (!reliable) {
13640          /* Resend message if this was NOT a reliable delivery.   Otherwise the
13641             retransmission should get it */
13642          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
13643          /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
13644          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13645       }
13646       return AUTH_CHALLENGE_SENT;
13647    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
13648       /* We have no auth, so issue challenge and request authentication */
13649       set_nonce_randdata(p, 1); /* Create nonce for challenge */
13650       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
13651       /* Schedule auto destroy in 32 seconds */
13652       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13653       return AUTH_CHALLENGE_SENT;
13654    }
13655 
13656    /* --- We have auth, so check it */
13657 
13658    /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
13659       an example in the spec of just what it is you're doing a hash on. */
13660 
13661    if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) {
13662       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
13663    }
13664 
13665    /* Make a copy of the response and parse it */
13666    res = ast_str_set(&buf, 0, "%s", authtoken);
13667 
13668    if (res == AST_DYNSTR_BUILD_FAILED) {
13669       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
13670    }
13671 
13672    c = buf->str;
13673 
13674    while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
13675       for (i = keys; i->key != NULL; i++) {
13676          const char *separator = ",";  /* default */
13677 
13678          if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
13679             continue;
13680          }
13681          /* Found. Skip keyword, take text in quotes or up to the separator. */
13682          c += strlen(i->key);
13683          if (*c == '"') { /* in quotes. Skip first and look for last */
13684             c++;
13685             separator = "\"";
13686          }
13687          i->s = c;
13688          strsep(&c, separator);
13689          break;
13690       }
13691       if (i->key == NULL) { /* not found, jump after space or comma */
13692          strsep(&c, " ,");
13693       }
13694    }
13695 
13696    /* Verify that digest username matches  the username we auth as */
13697    if (strcmp(username, keys[K_USER].s)) {
13698       ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
13699          username, keys[K_USER].s);
13700       /* Oops, we're trying something here */
13701       return AUTH_USERNAME_MISMATCH;
13702    }
13703 
13704    /* Verify nonce from request matches our nonce, and the nonce has not already been responded to.
13705     * If this check fails, send 401 with new nonce */
13706    if (strcasecmp(p->randdata, keys[K_NONCE].s) || p->stalenonce) { /* XXX it was 'n'casecmp ? */
13707       wrongnonce = TRUE;
13708       usednonce = keys[K_NONCE].s;
13709    } else {
13710       p->stalenonce = 1; /* now, since the nonce has a response, mark it as stale so it can't be sent or responded to again */
13711    }
13712 
13713    if (!ast_strlen_zero(md5secret)) {
13714       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
13715    } else {
13716       char a1[256];
13717 
13718       snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret);
13719       ast_md5_hash(a1_hash, a1);
13720    }
13721 
13722    /* compute the expected response to compare with what we received */
13723    {
13724       char a2[256];
13725       char a2_hash[256];
13726       char resp[256];
13727 
13728       snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text,
13729             S_OR(keys[K_URI].s, uri));
13730       ast_md5_hash(a2_hash, a2);
13731       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
13732       ast_md5_hash(resp_hash, resp);
13733    }
13734 
13735    good_response = keys[K_RESP].s &&
13736          !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
13737    if (wrongnonce) {
13738       if (good_response) {
13739          if (sipdebug)
13740             ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "From"));
13741          /* We got working auth token, based on stale nonce . */
13742          set_nonce_randdata(p, 0);
13743          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE);
13744       } else {
13745          /* Everything was wrong, so give the device one more try with a new challenge */
13746          if (!req->ignore) {
13747             if (sipdebug) {
13748                ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
13749             }
13750             set_nonce_randdata(p, 1);
13751          } else {
13752             if (sipdebug) {
13753                ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To"));
13754             }
13755          }
13756          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
13757       }
13758 
13759       /* Schedule auto destroy in 32 seconds */
13760       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13761       return AUTH_CHALLENGE_SENT;
13762    }
13763    if (good_response) {
13764       append_history(p, "AuthOK", "Auth challenge successful for %s", username);
13765       return AUTH_SUCCESSFUL;
13766    }
13767 
13768    /* Ok, we have a bad username/secret pair */
13769    /* Tell the UAS not to re-send this authentication data, because
13770       it will continue to fail
13771    */
13772 
13773    return AUTH_SECRET_FAILED;
13774 }

static enum check_auth_result check_peer_ok ( struct sip_pvt *  p,
char *  of,
struct sip_request *  req,
int  sipmethod,
struct ast_sockaddr *  addr,
struct sip_peer **  authpeer,
enum xmittype  reliable,
char *  calleridname,
char *  uri2 
) [static]

Validate device authentication.

Definition at line 15160 of file chan_sip.c.

References accountcode, ao2_t_ref, ast_apply_ha(), ast_cc_copy_config_params(), ast_copy_flags, ast_debug, ast_is_shrinkable_phonenumber(), ast_rtp_codecs_packetization_set(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_set_flag, ast_shrink_phone_number(), ast_sockaddr_stringify(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose, check_auth(), cid_name, cid_num, context, copy_vars(), debug, dialog_initialize_rtp(), do_setnat(), FALSE, find_peer(), get_rpid(), global_shrinkcallerid, global_t1min, language, mohinterpret, mohsuggest, parkinglot, set_pvt_allowed_methods(), set_t38_capabilities(), sip_debug_test_addr(), TRUE, and unref_peer().

Referenced by check_user_full().

15164 {
15165    enum check_auth_result res;
15166    int debug = sip_debug_test_addr(addr);
15167    struct sip_peer *peer;
15168 
15169    if (sipmethod == SIP_SUBSCRIBE) {
15170       /* For subscribes, match on device name only; for other methods,
15171       * match on IP address-port of the incoming request.
15172       */
15173       peer = find_peer(of, NULL, TRUE, FINDALLDEVICES, FALSE, 0);
15174    } else {
15175       /* First find devices based on username (avoid all type=peer's) */
15176       peer = find_peer(of, NULL, TRUE, FINDUSERS, FALSE, 0);
15177 
15178       /* Then find devices based on IP */
15179       if (!peer) {
15180          peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type);
15181       }
15182    }
15183 
15184    if (!peer) {
15185       if (debug) {
15186          ast_verbose("No matching peer for '%s' from '%s'\n",
15187             of, ast_sockaddr_stringify(&p->recv));
15188       }
15189       return AUTH_DONT_KNOW;
15190    }
15191 
15192    if (!ast_apply_ha(peer->ha, addr)) {
15193       ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of);
15194       unref_peer(peer, "unref_peer: check_peer_ok: from find_peer call, early return of AUTH_ACL_FAILED");
15195       return AUTH_ACL_FAILED;
15196    }
15197    if (debug)
15198       ast_verbose("Found peer '%s' for '%s' from %s\n",
15199          peer->name, of, ast_sockaddr_stringify(&p->recv));
15200 
15201    /* XXX what about p->prefs = peer->prefs; ? */
15202    /* Set Frame packetization */
15203    if (p->rtp) {
15204       ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs);
15205       p->autoframing = peer->autoframing;
15206    }
15207 
15208    /* Take the peer */
15209    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
15210    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
15211    ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
15212 
15213    if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->udptl) {
15214       p->t38_maxdatagram = peer->t38_maxdatagram;
15215       set_t38_capabilities(p);
15216    }
15217 
15218    /* Copy SIP extensions profile to peer */
15219    /* XXX is this correct before a successful auth ? */
15220    if (p->sipoptions)
15221       peer->sipoptions = p->sipoptions;
15222 
15223    do_setnat(p);
15224 
15225    ast_string_field_set(p, peersecret, peer->secret);
15226    ast_string_field_set(p, peermd5secret, peer->md5secret);
15227    ast_string_field_set(p, subscribecontext, peer->subscribecontext);
15228    ast_string_field_set(p, mohinterpret, peer->mohinterpret);
15229    ast_string_field_set(p, mohsuggest, peer->mohsuggest);
15230    if (!ast_strlen_zero(peer->parkinglot)) {
15231       ast_string_field_set(p, parkinglot, peer->parkinglot);
15232    }
15233    ast_string_field_set(p, engine, peer->engine);
15234    p->disallowed_methods = peer->disallowed_methods;
15235    set_pvt_allowed_methods(p, req);
15236    ast_cc_copy_config_params(p->cc_params, peer->cc_params);
15237    if (peer->callingpres)  /* Peer calling pres setting will override RPID */
15238       p->callingpres = peer->callingpres;
15239    if (peer->maxms && peer->lastms)
15240       p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
15241    else
15242       p->timer_t1 = peer->timer_t1;
15243 
15244    /* Set timer B to control transaction timeouts */
15245    if (peer->timer_b)
15246       p->timer_b = peer->timer_b;
15247    else
15248       p->timer_b = 64 * p->timer_t1;
15249 
15250    if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) {
15251       /* Pretend there is no required authentication */
15252       ast_string_field_set(p, peersecret, NULL);
15253       ast_string_field_set(p, peermd5secret, NULL);
15254    }
15255    if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, req->ignore))) {
15256       ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
15257       ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
15258       ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
15259       /* If we have a call limit, set flag */
15260       if (peer->call_limit)
15261          ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
15262       ast_string_field_set(p, peername, peer->name);
15263       ast_string_field_set(p, authname, peer->name);
15264 
15265       if (sipmethod == SIP_INVITE) {
15266          /* copy channel vars */
15267          p->chanvars = copy_vars(peer->chanvars);
15268       }
15269 
15270       if (authpeer) {
15271          ao2_t_ref(peer, 1, "copy pointer into (*authpeer)");
15272          (*authpeer) = peer;  /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
15273       }
15274 
15275       if (!ast_strlen_zero(peer->username)) {
15276          ast_string_field_set(p, username, peer->username);
15277          /* Use the default username for authentication on outbound calls */
15278          /* XXX this takes the name from the caller... can we override ? */
15279          ast_string_field_set(p, authname, peer->username);
15280       }
15281       if (!get_rpid(p, req)) {
15282          if (!ast_strlen_zero(peer->cid_num)) {
15283             char *tmp = ast_strdupa(peer->cid_num);
15284             if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp))
15285                ast_shrink_phone_number(tmp);
15286             ast_string_field_set(p, cid_num, tmp);
15287          }
15288          if (!ast_strlen_zero(peer->cid_name))
15289             ast_string_field_set(p, cid_name, peer->cid_name);
15290          if (!ast_strlen_zero(peer->cid_tag))
15291             ast_string_field_set(p, cid_tag, peer->cid_tag);
15292          if (peer->callingpres)
15293             p->callingpres = peer->callingpres;
15294       }
15295       ast_string_field_set(p, fullcontact, peer->fullcontact);
15296       if (!ast_strlen_zero(peer->context))
15297          ast_string_field_set(p, context, peer->context);
15298       ast_string_field_set(p, peersecret, peer->secret);
15299       ast_string_field_set(p, peermd5secret, peer->md5secret);
15300       ast_string_field_set(p, language, peer->language);
15301       ast_string_field_set(p, accountcode, peer->accountcode);
15302       p->amaflags = peer->amaflags;
15303       p->callgroup = peer->callgroup;
15304       p->pickupgroup = peer->pickupgroup;
15305       p->capability = peer->capability;
15306       p->prefs = peer->prefs;
15307       p->jointcapability = peer->capability;
15308       if (peer->maxforwards > 0) {
15309          p->maxforwards = peer->maxforwards;
15310       }
15311       if (p->peercapability)
15312          p->jointcapability &= p->peercapability;
15313       p->maxcallbitrate = peer->maxcallbitrate;
15314       if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
15315           (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
15316          p->noncodeccapability |= AST_RTP_DTMF;
15317       else
15318          p->noncodeccapability &= ~AST_RTP_DTMF;
15319       p->jointnoncodeccapability = p->noncodeccapability;
15320       if (!dialog_initialize_rtp(p)) {
15321          if (p->rtp) {
15322             ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &peer->prefs);
15323             p->autoframing = peer->autoframing;
15324          }
15325       } else {
15326          res = AUTH_RTP_FAILED;
15327       }
15328    }
15329    unref_peer(peer, "check_peer_ok: unref_peer: tossing temp ptr to peer from find_peer");
15330    return res;
15331 }

static void check_pendings ( struct sip_pvt *  p  )  [static]

Check pending actions on SIP call.

Note:
both sip_pvt and sip_pvt's owner channel (if present) must be locked for this function.

Definition at line 18861 of file chan_sip.c.

References ast_clear_flag, ast_debug, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_test_flag, FALSE, sip_scheddestroy(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), and TRUE.

Referenced by handle_incoming(), handle_response_invite(), and sip_reinvite_retry().

18862 {
18863    if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
18864       /* if we can't BYE, then this is really a pending CANCEL */
18865       if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) {
18866          p->invitestate = INV_CANCELLED;
18867          transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
18868          /* Actually don't destroy us yet, wait for the 487 on our original
18869             INVITE, but do set an autodestruct just in case we never get it. */
18870       } else {
18871          /* We have a pending outbound invite, don't send something
18872             new in-transaction */
18873          if (p->pendinginvite)
18874             return;
18875 
18876          if (p->owner) {
18877             ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
18878          }
18879          /* Perhaps there is an SD change INVITE outstanding */
18880          transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
18881       }
18882       ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);   
18883       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
18884    } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
18885       /* if we can't REINVITE, hold it for later */
18886       if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) {
18887          ast_debug(2, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid);
18888       } else {
18889          ast_debug(2, "Sending pending reinvite on '%s'\n", p->callid);
18890          /* Didn't get to reinvite yet, so do it now */
18891          transmit_reinvite_with_sdp(p, (p->t38.state == T38_LOCAL_REINVITE ? TRUE : FALSE), FALSE);
18892          ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
18893       }
18894    }
18895 }

static void check_rtp_timeout ( struct sip_pvt *  dialog,
time_t  t 
) [static]

helper function for the monitoring thread -- seems to be called with the assumption that the dialog is locked

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

Definition at line 24601 of file chan_sip.c.

References ast_channel_trylock, ast_channel_unlock, ast_log(), ast_rtp_instance_get_hold_timeout(), ast_rtp_instance_get_timeout(), ast_rtp_instance_set_hold_timeout(), ast_rtp_instance_set_timeout(), ast_sockaddr_isnull(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, LOG_NOTICE, sip_pvt_lock, and sip_pvt_unlock.

Referenced by dialog_needdestroy().

24602 {
24603    /* If we have no RTP or no active owner, no need to check timers */
24604    if (!dialog->rtp || !dialog->owner)
24605       return;
24606    /* If the call is not in UP state or redirected outside Asterisk, no need to check timers */
24607 
24608    if (dialog->owner->_state != AST_STATE_UP || !ast_sockaddr_isnull(&dialog->redirip))
24609       return;
24610 
24611    /* If the call is involved in a T38 fax session do not check RTP timeout */
24612    if (dialog->t38.state == T38_ENABLED)
24613       return;
24614 
24615    /* If we have no timers set, return now */
24616    if (!ast_rtp_instance_get_timeout(dialog->rtp) && !ast_rtp_instance_get_hold_timeout(dialog->rtp)) {
24617       return;
24618    }
24619 
24620    /*! \todo Check video RTP keepalives
24621 
24622       Do we need to move the lastrtptx to the RTP structure to have one for audio and one
24623       for video? It really does belong to the RTP structure.
24624    */
24625 
24626    /* Check AUDIO RTP timers */
24627    if (dialog->lastrtprx && (ast_rtp_instance_get_timeout(dialog->rtp) || ast_rtp_instance_get_hold_timeout(dialog->rtp)) && (t > dialog->lastrtprx + ast_rtp_instance_get_timeout(dialog->rtp))) {
24628       if (!ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD) || (ast_rtp_instance_get_hold_timeout(dialog->rtp) && (t > dialog->lastrtprx + ast_rtp_instance_get_hold_timeout(dialog->rtp)))) {
24629          /* Needs a hangup */
24630          if (ast_rtp_instance_get_timeout(dialog->rtp)) {
24631             while (dialog->owner && ast_channel_trylock(dialog->owner)) {
24632                sip_pvt_unlock(dialog);
24633                usleep(1);
24634                sip_pvt_lock(dialog);
24635             }
24636             if (!dialog->owner) {
24637                return; /* channel hangup can occur during deadlock avoidance. */
24638             }
24639             ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
24640                dialog->owner->name, (long) (t - dialog->lastrtprx));
24641             /* Issue a softhangup */
24642             ast_softhangup_nolock(dialog->owner, AST_SOFTHANGUP_DEV);
24643             ast_channel_unlock(dialog->owner);
24644             /* forget the timeouts for this call, since a hangup
24645                has already been requested and we don't want to
24646                repeatedly request hangups
24647             */
24648             ast_rtp_instance_set_timeout(dialog->rtp, 0);
24649             ast_rtp_instance_set_hold_timeout(dialog->rtp, 0);
24650             if (dialog->vrtp) {
24651                ast_rtp_instance_set_timeout(dialog->vrtp, 0);
24652                ast_rtp_instance_set_hold_timeout(dialog->vrtp, 0);
24653             }
24654          }
24655       }
24656    }
24657 }

static int check_sip_domain ( const char *  domain,
char *  context,
size_t  len 
) [static]

check_sip_domain: Check if domain part of uri is local to our server

Definition at line 25753 of file chan_sip.c.

References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strlen_zero().

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

25754 {
25755    struct domain *d;
25756    int result = 0;
25757 
25758    AST_LIST_LOCK(&domain_list);
25759    AST_LIST_TRAVERSE(&domain_list, d, list) {
25760       if (strcasecmp(d->domain, domain))
25761          continue;
25762 
25763       if (len && !ast_strlen_zero(d->context))
25764          ast_copy_string(context, d->context, len);
25765       
25766       result = 1;
25767       break;
25768    }
25769    AST_LIST_UNLOCK(&domain_list);
25770 
25771    return result;
25772 }

static int check_user ( struct sip_pvt *  p,
struct sip_request *  req,
int  sipmethod,
const char *  uri,
enum xmittype  reliable,
struct ast_sockaddr *  addr 
) [static]

Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced.

Definition at line 15462 of file chan_sip.c.

References check_user_full().

Referenced by handle_request_options(), and handle_request_publish().

15463 {
15464    return check_user_full(p, req, sipmethod, uri, reliable, addr, NULL);
15465 }

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

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

Returns:
0 on success, non-zero on failure

Definition at line 15339 of file chan_sip.c.

References ast_copy_string(), ast_is_shrinkable_phonenumber(), ast_log(), ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_contact(), check_peer_ok(), cid_name, cid_num, dialog_initialize_rtp(), dummy(), exten, get_header(), get_rpid(), global_match_auth_username, global_shrinkcallerid, LOG_ERROR, LOG_NOTICE, sip_cfg, SIP_PEDANTIC_DECODE, strsep(), and terminate_uri().

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

15342 {
15343    char from[256] = { 0, };
15344    char *dummy = NULL;  /* dummy return value for parse_uri */
15345    char *domain = NULL; /* dummy return value for parse_uri */
15346    char *of;
15347    enum check_auth_result res = AUTH_DONT_KNOW;
15348    char calleridname[50];
15349    char *uri2 = ast_strdupa(uri);
15350 
15351    terminate_uri(uri2); /* trim extra stuff */
15352 
15353    ast_copy_string(from, get_header(req, "From"), sizeof(from));
15354    /* XXX here tries to map the username for invite things */
15355    memset(calleridname, 0, sizeof(calleridname));
15356 
15357    /* strip the display-name portion off the beginning of the FROM header. */
15358    if (!(of = (char *) get_calleridname(from, calleridname, sizeof(calleridname)))) {
15359       ast_log(LOG_ERROR, "FROM header can not be parsed \n");
15360       return res;
15361    }
15362 
15363    if (calleridname[0])
15364       ast_string_field_set(p, cid_name, calleridname);
15365 
15366    if (ast_strlen_zero(p->exten)) {
15367       char *t = uri2;
15368       if (!strncasecmp(t, "sip:", 4))
15369          t+= 4;
15370       else if (!strncasecmp(t, "sips:", 5))
15371          t += 5;
15372       ast_string_field_set(p, exten, t);
15373       t = strchr(p->exten, '@');
15374       if (t)
15375          *t = '\0';
15376 
15377       if (ast_strlen_zero(p->our_contact))
15378          build_contact(p);
15379    }
15380 
15381    of = get_in_brackets(of);
15382 
15383    /* save the URI part of the From header */
15384    ast_string_field_set(p, from, of);
15385 
15386    /* ignore all fields but name */
15387    if (parse_uri(of, "sip:,sips:", &of, &dummy, &domain, NULL)) {
15388       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
15389    }
15390 
15391    SIP_PEDANTIC_DECODE(of);
15392    SIP_PEDANTIC_DECODE(domain);
15393 
15394    if (ast_strlen_zero(of)) {
15395       /* XXX note: the original code considered a missing @host
15396        * as a username-only URI. The SIP RFC (19.1.1) says that
15397        * this is wrong, and it should be considered as a domain-only URI.
15398        * For backward compatibility, we keep this block, but it is
15399        * really a mistake and should go away.
15400        */
15401       of = domain;
15402    } else {
15403       char *tmp = ast_strdupa(of);
15404       /* We need to be able to handle auth-headers looking like
15405          <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43>
15406       */
15407       tmp = strsep(&tmp, ";");
15408       if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp))
15409          ast_shrink_phone_number(tmp);
15410       ast_string_field_set(p, cid_num, tmp);
15411    }
15412 
15413    if (global_match_auth_username) {
15414       /*
15415        * XXX This is experimental code to grab the search key from the
15416        * Auth header's username instead of the 'From' name, if available.
15417        * Do not enable this block unless you understand the side effects (if any!)
15418        * Note, the search for "username" should be done in a more robust way.
15419        * Note2, at the moment we check both fields, though maybe we should
15420        * pick one or another depending on the request ? XXX
15421        */
15422       const char *hdr = get_header(req, "Authorization");
15423       if (ast_strlen_zero(hdr))
15424          hdr = get_header(req, "Proxy-Authorization");
15425 
15426       if ( !ast_strlen_zero(hdr) && (hdr = strstr(hdr, "username=\"")) ) {
15427          ast_copy_string(from, hdr + strlen("username=\""), sizeof(from));
15428          of = from;
15429          of = strsep(&of, "\"");
15430       }
15431    }
15432 
15433    res = check_peer_ok(p, of, req, sipmethod, addr,
15434          authpeer, reliable, calleridname, uri2);
15435    if (res != AUTH_DONT_KNOW)
15436       return res;
15437 
15438    /* Finally, apply the guest policy */
15439    if (sip_cfg.allowguest) {
15440       get_rpid(p, req);
15441       if (!dialog_initialize_rtp(p)) {
15442          res = AUTH_SUCCESSFUL;
15443       } else {
15444          res = AUTH_RTP_FAILED;
15445       }
15446    } else if (sip_cfg.alwaysauthreject)
15447       res = AUTH_FAKE_AUTH; /* reject with fake authorization request */
15448    else
15449       res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */
15450 
15451 
15452    if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT)) {
15453       ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT);
15454    }
15455 
15456    return res;
15457 }

static void check_via ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

check Via: header for hostname, port and rport request/answer

Definition at line 15099 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_set_flag, ast_skip_blanks(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_verbose, get_header(), LOG_WARNING, sip_debug_test_pvt(), sip_nat_mode(), and sip_real_dst().

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

15100 {
15101    char via[512];
15102    char *c, *maddr;
15103    struct ast_sockaddr tmp;
15104    uint16_t port;
15105 
15106    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
15107 
15108    /* Work on the leftmost value of the topmost Via header */
15109    c = strchr(via, ',');
15110    if (c)
15111       *c = '\0';
15112 
15113    /* Check for rport */
15114    c = strstr(via, ";rport");
15115    if (c && (c[6] != '=')) { /* rport query, not answer */
15116       ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT);
15117       ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT);
15118    }
15119 
15120    /* Check for maddr */
15121    maddr = strstr(via, "maddr=");
15122    if (maddr) {
15123       maddr += 6;
15124       c = maddr + strspn(maddr, "abcdefghijklmnopqrstuvwxyz"
15125                       "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.:[]");
15126       *c = '\0';
15127    }
15128 
15129    c = strchr(via, ';');
15130    if (c)
15131       *c = '\0';
15132 
15133    c = strchr(via, ' ');
15134    if (c) {
15135       *c = '\0';
15136       c = ast_skip_blanks(c+1);
15137       if (strcasecmp(via, "SIP/2.0/UDP") && strcasecmp(via, "SIP/2.0/TCP") && strcasecmp(via, "SIP/2.0/TLS")) {
15138          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
15139          return;
15140       }
15141 
15142       if (maddr && ast_sockaddr_resolve_first(&p->sa, maddr, 0)) {
15143          p->sa = p->recv;
15144       }
15145 
15146       ast_sockaddr_resolve_first(&tmp, c, 0);
15147       port = ast_sockaddr_port(&tmp);
15148       ast_sockaddr_set_port(&p->sa,
15149                   port != 0 ? port : STANDARD_SIP_PORT);
15150 
15151       if (sip_debug_test_pvt(p)) {
15152          ast_verbose("Sending to %s (%s)\n",
15153                 ast_sockaddr_stringify(sip_real_dst(p)),
15154                 sip_nat_mode(p));
15155       }
15156    }
15157 }

static attribute_unused void check_via_response ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

check received= and rport= in a SIP response. If we get a response with received= and/or rport= in the Via: line, use them as 'p->ourip' (see RFC 3581 for rport, and RFC 3261 for received). Using these two fields SIP can produce the correct address and port in the SIP headers without the need for STUN. The address part is also reused for the media sessions. Note that ast_sip_ouraddrfor() still rewrites p->ourip if you specify externaddr/seternaddr/.

Definition at line 15069 of file chan_sip.c.

References ast_copy_string(), ast_parse_arg(), ast_sockaddr_set_port, get_header(), PARSE_ADDR, and strsep().

15070 {
15071    char via[256];
15072    char *cur, *opts;
15073 
15074    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
15075 
15076    /* Work on the leftmost value of the topmost Via header */
15077    opts = strchr(via, ',');
15078    if (opts)
15079       *opts = '\0';
15080 
15081    /* parse all relevant options */
15082    opts = strchr(via, ';');
15083    if (!opts)
15084       return;  /* no options to parse */
15085    *opts++ = '\0';
15086    while ( (cur = strsep(&opts, ";")) ) {
15087       if (!strncmp(cur, "rport=", 6)) {
15088          int port = strtol(cur+6, NULL, 10);
15089          /* XXX add error checking */
15090          ast_sockaddr_set_port(&p->ourip, port);
15091       } else if (!strncmp(cur, "received=", 9)) {
15092          if (ast_parse_arg(cur + 9, PARSE_ADDR, &p->ourip))
15093             ;  /* XXX add error checking */
15094       }
15095    }
15096 }

static void cleanup_stale_contexts ( char *  new,
char *  old 
) [static]

Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly.

Definition at line 16145 of file chan_sip.c.

References ast_context_destroy(), ast_context_find(), ast_copy_string(), AST_MAX_CONTEXT, and strsep().

Referenced by config_parse_variables().

16146 {
16147    char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
16148 
16149    while ((oldcontext = strsep(&old, "&"))) {
16150       stalecontext = '\0';
16151       ast_copy_string(newlist, new, sizeof(newlist));
16152       stringp = newlist;
16153       while ((newcontext = strsep(&stringp, "&"))) {
16154          if (!strcmp(newcontext, oldcontext)) {
16155             /* This is not the context you're looking for */
16156             stalecontext = '\0';
16157             break;
16158          } else if (strcmp(newcontext, oldcontext)) {
16159             stalecontext = oldcontext;
16160          }
16161          
16162       }
16163       if (stalecontext)
16164          ast_context_destroy(ast_context_find(stalecontext), "SIP");
16165    }
16166 }

static void clear_peer_mailboxes ( struct sip_peer *  peer  )  [static]

Destroy all peer-related mailbox subscriptions

Definition at line 4457 of file chan_sip.c.

References AST_LIST_REMOVE_HEAD, destroy_mailbox(), and mailbox.

Referenced by set_peer_defaults(), and sip_destroy_peer().

04458 {
04459    struct sip_mailbox *mailbox;
04460 
04461    while ((mailbox = AST_LIST_REMOVE_HEAD(&peer->mailboxes, entry)))
04462       destroy_mailbox(mailbox);
04463 }

static int clear_realm_authentication ( struct sip_auth *  authlist  )  [static]

Clear realm authentication list (at reload).

Definition at line 25842 of file chan_sip.c.

References ast_free.

Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().

25843 {
25844    struct sip_auth *a = authlist;
25845    struct sip_auth *b;
25846 
25847    while (a) {
25848       b = a;
25849       a = a->next;
25850       ast_free(b);
25851    }
25852 
25853    return 1;
25854 }

static void clear_sip_domains ( void   )  [static]

Clear our domain list (at reload).

Definition at line 25775 of file chan_sip.c.

References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.

Referenced by reload_config(), and unload_module().

25776 {
25777    struct domain *d;
25778 
25779    AST_LIST_LOCK(&domain_list);
25780    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
25781       ast_free(d);
25782    AST_LIST_UNLOCK(&domain_list);
25783 }

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

Do completion on peer name.

Definition at line 17543 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, ast_test_flag, and unref_peer().

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

17544 {
17545    char *result = NULL;
17546    int wordlen = strlen(word);
17547    int which = 0;
17548    struct ao2_iterator i = ao2_iterator_init(peers, 0);
17549    struct sip_peer *peer;
17550 
17551    while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
17552       /* locking of the object is not required because only the name and flags are being compared */
17553       if (!strncasecmp(word, peer->name, wordlen) &&
17554             (!flags2 || ast_test_flag(&peer->flags[1], flags2)) &&
17555             ++which > state)
17556          result = ast_strdup(peer->name);
17557       unref_peer(peer, "toss iterator peer ptr before break");
17558       if (result) {
17559          break;
17560       }
17561    }
17562    ao2_iterator_destroy(&i);
17563    return result;
17564 }

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

Do completion on registered peer name.

Definition at line 17567 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, ast_test_flag, and unref_peer().

Referenced by complete_sip_unregister().

17568 {
17569        char *result = NULL;
17570        int wordlen = strlen(word);
17571        int which = 0;
17572        struct ao2_iterator i;
17573        struct sip_peer *peer;
17574        
17575        i = ao2_iterator_init(peers, 0);
17576        while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
17577           if (!strncasecmp(word, peer->name, wordlen) &&
17578          (!flags2 || ast_test_flag(&peer->flags[1], flags2)) &&
17579          ++which > state && peer->expire > 0)
17580              result = ast_strdup(peer->name);
17581           if (result) {
17582              unref_peer(peer, "toss iterator peer ptr before break");
17583              break;
17584           }
17585           unref_peer(peer, "toss iterator peer ptr");
17586        }
17587        ao2_iterator_destroy(&i);
17588        return result;
17589 }

static char * complete_sip_show_history ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip show history' CLI.

Definition at line 17592 of file chan_sip.c.

References complete_sipch().

Referenced by sip_show_history().

17593 {
17594    if (pos == 3)
17595       return complete_sipch(line, word, pos, state);
17596 
17597    return NULL;
17598 }

static char * complete_sip_show_peer ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip show peer' CLI.

Definition at line 17601 of file chan_sip.c.

References complete_sip_peer().

Referenced by sip_qualify_peer(), and sip_show_peer().

17602 {
17603    if (pos == 3) {
17604       return complete_sip_peer(word, state, 0);
17605    }
17606 
17607    return NULL;
17608 }

static char* complete_sip_show_user ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip show user' CLI.

Definition at line 16847 of file chan_sip.c.

References complete_sip_user().

Referenced by sip_show_user().

16848 {
16849    if (pos == 3)
16850       return complete_sip_user(word, state);
16851 
16852    return NULL;
16853 }

static char * complete_sip_unregister ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip unregister' CLI.

Definition at line 17611 of file chan_sip.c.

References complete_sip_registered_peer().

Referenced by sip_unregister().

17612 {
17613        if (pos == 2)
17614                return complete_sip_registered_peer(word, state, 0);
17615 
17616        return NULL;
17617 }

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

Do completion on user name.

Definition at line 16817 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_unlock, ast_strdup, and unref_peer().

Referenced by complete_sip_show_user().

16818 {
16819    char *result = NULL;
16820    int wordlen = strlen(word);
16821    int which = 0;
16822    struct ao2_iterator user_iter;
16823    struct sip_peer *user;
16824 
16825    user_iter = ao2_iterator_init(peers, 0);
16826    while ((user = ao2_iterator_next(&user_iter))) {
16827       ao2_lock(user);
16828       if (!(user->type & SIP_TYPE_USER)) {
16829          ao2_unlock(user);
16830          unref_peer(user, "complete sip user");
16831          continue;
16832       }
16833       /* locking of the object is not required because only the name and flags are being compared */
16834       if (!strncasecmp(word, user->name, wordlen) && ++which > state) {
16835          result = ast_strdup(user->name);
16836       }
16837       ao2_unlock(user);
16838       unref_peer(user, "complete sip user");
16839       if (result) {
16840          break;
16841       }
16842    }
16843    ao2_iterator_destroy(&user_iter);
16844    return result;
16845 }

static char* complete_sipch ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip show channel' and 'sip show history' CLI This is in charge of generating all strings that match a prefix in the given position. As many functions of this kind, each invokation has O(state) time complexity so be careful in using it.

Definition at line 17513 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, dialogs, sip_pvt_lock, and sip_pvt_unlock.

Referenced by complete_sip_show_history(), and sip_show_channel().

17514 {
17515    int which=0;
17516    struct sip_pvt *cur;
17517    char *c = NULL;
17518    int wordlen = strlen(word);
17519    struct ao2_iterator i;
17520 
17521    if (pos != 3) {
17522       return NULL;
17523    }
17524 
17525    i = ao2_iterator_init(dialogs, 0);
17526    while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
17527       sip_pvt_lock(cur);
17528       if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
17529          c = ast_strdup(cur->callid);
17530          sip_pvt_unlock(cur);
17531          dialog_unref(cur, "drop ref in iterator loop break");
17532          break;
17533       }
17534       sip_pvt_unlock(cur);
17535       dialog_unref(cur, "drop ref in iterator loop");
17536    }
17537    ao2_iterator_destroy(&i);
17538    return c;
17539 }

static char * complete_sipnotify ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip notify' CLI.

Definition at line 17620 of file chan_sip.c.

References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.

Referenced by sip_cli_notify().

17621 {
17622    char *c = NULL;
17623 
17624    if (pos == 2) {
17625       int which = 0;
17626       char *cat = NULL;
17627       int wordlen = strlen(word);
17628 
17629       /* do completion for notify type */
17630 
17631       if (!notify_types)
17632          return NULL;
17633       
17634       while ( (cat = ast_category_browse(notify_types, cat)) ) {
17635          if (!strncasecmp(word, cat, wordlen) && ++which > state) {
17636             c = ast_strdup(cat);
17637             break;
17638          }
17639       }
17640       return c;
17641    }
17642 
17643    if (pos > 2)
17644       return complete_sip_peer(word, state, 0);
17645 
17646    return NULL;
17647 }

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

Definition at line 1921 of file chan_sip.c.

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

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

01922 {
01923    struct ast_str *body = ast_str_alloca(size);
01924    char tuple_id[32];
01925 
01926    generate_random_string(tuple_id, sizeof(tuple_id));
01927 
01928    /* We'll make this a bare-bones pidf body. In state_notify_build_xml, the PIDF
01929     * body gets a lot more extra junk that isn't necessary, so we'll leave it out here.
01930     */
01931    ast_str_append(&body, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
01932    /* XXX The entity attribute is currently set to the peer name associated with the
01933     * dialog. This is because we currently only call this function for call-completion
01934     * PUBLISH bodies. In such cases, the entity is completely disregarded. For other
01935     * event packages, it may be crucial to have a proper URI as the presentity so this
01936     * should be revisited as support is expanded.
01937     */
01938    ast_str_append(&body, 0, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"%s\">\n", presentity);
01939    ast_str_append(&body, 0, "<tuple id=\"%s\">\n", tuple_id);
01940    ast_str_append(&body, 0, "<status><basic>%s</basic></status>\n", state == CC_OPEN ? "open" : "closed");
01941    ast_str_append(&body, 0, "</tuple>\n");
01942    ast_str_append(&body, 0, "</presence>\n");
01943    ast_copy_string(pidf_body, ast_str_buffer(body), size);
01944    return 0;
01945 }

static int copy_all_header ( struct sip_request *  req,
const struct sip_request *  orig,
const char *  field 
) [static]

Copy all headers from one request to another.

Definition at line 9394 of file chan_sip.c.

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

Referenced by respprep().

09395 {
09396    int start = 0;
09397    int copied = 0;
09398    for (;;) {
09399       const char *tmp = __get_header(orig, field, &start);
09400 
09401       if (ast_strlen_zero(tmp))
09402          break;
09403       /* Add what we're responding to */
09404       add_header(req, field, tmp);
09405       copied++;
09406    }
09407    return copied ? 0 : -1;
09408 }

static int copy_header ( struct sip_request *  req,
const struct sip_request *  orig,
const char *  field 
) [static]

Copy one header field from one request to another.

Definition at line 9383 of file chan_sip.c.

References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.

Referenced by reqprep(), and respprep().

09384 {
09385    const char *tmp = get_header(orig, field);
09386 
09387    if (!ast_strlen_zero(tmp)) /* Add what we're responding to */
09388       return add_header(req, field, tmp);
09389    ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
09390    return -1;
09391 }

static void copy_request ( struct sip_request *  dst,
const struct sip_request *  src 
) [static]

copy SIP request (mostly used to save request for responses)

Definition at line 11090 of file chan_sip.c.

References ast_str_copy_string(), ast_str_create(), and ast_str_strlen().

Referenced by handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), parse_copy(), queue_request(), sip_park(), and sip_park_thread().

11091 {
11092    /* XXX this function can encounter memory allocation errors, perhaps it
11093     * should return a value */
11094 
11095    struct ast_str *duplicate = dst->data;
11096    struct ast_str *duplicate_content = dst->content;
11097 
11098    /* copy the entire request then restore the original data and content
11099     * members from the dst request */
11100    memcpy(dst, src, sizeof(*dst));
11101    dst->data = duplicate;
11102    dst->content = duplicate_content;
11103 
11104    /* copy the data into the dst request */
11105    if (!dst->data && !(dst->data = ast_str_create(ast_str_strlen(src->data) + 1)))
11106       return;
11107    ast_str_copy_string(&dst->data, src->data);
11108 
11109    /* copy the content into the dst request (if it exists) */
11110    if (src->content) {
11111       if (!dst->content && !(dst->content = ast_str_create(ast_str_strlen(src->content) + 1)))
11112          return;
11113       ast_str_copy_string(&dst->content, src->content);
11114    }
11115 }

static void copy_socket_data ( struct sip_socket *  to_sock,
const struct sip_socket *  from_sock 
) [static]

Definition at line 4929 of file chan_sip.c.

References ao2_ref.

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

04930 {
04931    if (to_sock->tcptls_session) {
04932       ao2_ref(to_sock->tcptls_session, -1);
04933       to_sock->tcptls_session = NULL;
04934    }
04935 
04936    if (from_sock->tcptls_session) {
04937       ao2_ref(from_sock->tcptls_session, +1);
04938    }
04939 
04940    *to_sock = *from_sock;
04941 }

static struct ast_variable * copy_vars ( struct ast_variable *  src  )  [static]

duplicate a list of channel variables,

Returns:
the copy.

Definition at line 2300 of file chan_sip.c.

References ast_variable_new(), and ast_variable::next.

02301 {
02302    struct ast_variable *res = NULL, *tmp, *v = NULL;
02303 
02304    for (v = src ; v ; v = v->next) {
02305       if ((tmp = ast_variable_new(v->name, v->value, v->file))) {
02306          tmp->next = res;
02307          res = tmp;
02308       }
02309    }
02310    return res;
02311 }

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

Copy SIP VIA Headers from the request to the response.

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

Definition at line 9418 of file chan_sip.c.

References __get_header(), add_header(), ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_strlen_zero(), ast_test_flag, and LOG_NOTICE.

Referenced by respprep().

09419 {
09420    int copied = 0;
09421    int start = 0;
09422 
09423    for (;;) {
09424       char new[512];
09425       const char *oh = __get_header(orig, field, &start);
09426 
09427       if (ast_strlen_zero(oh))
09428          break;
09429 
09430       if (!copied) { /* Only check for empty rport in topmost via header */
09431          char leftmost[512], *others, *rport;
09432 
09433          /* Only work on leftmost value */
09434          ast_copy_string(leftmost, oh, sizeof(leftmost));
09435          others = strchr(leftmost, ',');
09436          if (others)
09437              *others++ = '\0';
09438 
09439          /* Find ;rport;  (empty request) */
09440          rport = strstr(leftmost, ";rport");
09441          if (rport && *(rport+6) == '=')
09442             rport = NULL;     /* We already have a parameter to rport */
09443 
09444          if (((ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) || (rport && ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)))) {
09445             /* We need to add received port - rport */
09446             char *end;
09447 
09448             rport = strstr(leftmost, ";rport");
09449 
09450             if (rport) {
09451                end = strchr(rport + 1, ';');
09452                if (end)
09453                   memmove(rport, end, strlen(end) + 1);
09454                else
09455                   *rport = '\0';
09456             }
09457 
09458             /* Add rport to first VIA header if requested */
09459             snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s",
09460                leftmost, ast_sockaddr_stringify_addr(&p->recv),
09461                ast_sockaddr_port(&p->recv),
09462                others ? "," : "", others ? others : "");
09463          } else {
09464             /* We should *always* add a received to the topmost via */
09465             snprintf(new, sizeof(new), "%s;received=%s%s%s",
09466                leftmost, ast_sockaddr_stringify_addr(&p->recv),
09467                others ? "," : "", others ? others : "");
09468          }
09469          oh = new;   /* the header to copy */
09470       }  /* else add the following via headers untouched */
09471       add_header(req, field, oh);
09472       copied++;
09473    }
09474    if (!copied) {
09475       ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
09476       return -1;
09477    }
09478    return 0;
09479 }

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

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

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

Definition at line 5149 of file chan_sip.c.

References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_srv(), ast_log(), AST_NONSTANDARD_RAW_ARGS, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_strdupa, ast_string_field_set, bindaddr, create_addr_from_peer(), dialog_initialize_rtp(), FALSE, find_peer(), get_srv_protocol(), get_srv_service(), global_t1, global_timer_b, LOG_WARNING, MAXHOSTNAMELEN, obproxy_get(), ref_peer(), ref_proxy(), service, set_socket_transport(), sip_cfg, TRUE, and unref_peer().

05150 {
05151    struct sip_peer *peer;
05152    char *peername, *peername2, *hostn;
05153    char host[MAXHOSTNAMELEN];
05154    char service[MAXHOSTNAMELEN];
05155    int srv_ret = 0;
05156    int tportno;
05157 
05158    AST_DECLARE_APP_ARGS(hostport,
05159       AST_APP_ARG(host);
05160       AST_APP_ARG(port);
05161    );
05162 
05163    peername = ast_strdupa(opeer);
05164    peername2 = ast_strdupa(opeer);
05165    AST_NONSTANDARD_RAW_ARGS(hostport, peername2, ':');
05166 
05167    if (hostport.port)
05168       dialog->portinuri = 1;
05169 
05170    dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
05171    dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
05172    peer = find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0);
05173 
05174    if (peer) {
05175       int res;
05176       if (newdialog) {
05177          set_socket_transport(&dialog->socket, 0);
05178       }
05179       res = create_addr_from_peer(dialog, peer);
05180       if (!ast_sockaddr_isnull(remote_address)) {
05181          ast_sockaddr_copy(&dialog->sa, remote_address);
05182       }
05183       dialog->relatedpeer = ref_peer(peer, "create_addr: setting dialog's relatedpeer pointer");
05184       unref_peer(peer, "create_addr: unref peer from find_peer hashtab lookup");
05185       return res;
05186    }
05187 
05188    if (dialog_initialize_rtp(dialog)) {
05189       return -1;
05190    }
05191 
05192    ast_string_field_set(dialog, tohost, hostport.host);
05193    dialog->allowed_methods &= ~sip_cfg.disallowed_methods;
05194 
05195    /* Get the outbound proxy information */
05196    ref_proxy(dialog, obproxy_get(dialog, NULL));
05197 
05198    if (addr) {
05199       /* This address should be updated using dnsmgr */
05200       ast_sockaddr_copy(&dialog->sa, addr);
05201    } else {
05202 
05203       /* Let's see if we can find the host in DNS. First try DNS SRV records,
05204          then hostname lookup */
05205       /*! \todo Fix this function. When we ask for SRV, we should check all transports
05206            In the future, we should first check NAPTR to find out transport preference
05207        */
05208       hostn = peername;
05209       /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then
05210        * an A record lookup should be used instead of SRV.
05211        */
05212       if (!hostport.port && sip_cfg.srvlookup) {
05213          snprintf(service, sizeof(service), "_%s._%s.%s", 
05214              get_srv_service(dialog->socket.type),
05215              get_srv_protocol(dialog->socket.type), peername);
05216          if ((srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno,
05217                      service)) > 0) {
05218             hostn = host;
05219          }
05220       }
05221 
05222       if (ast_sockaddr_resolve_first(&dialog->sa, hostn, 0)) {
05223          ast_log(LOG_WARNING, "No such host: %s\n", peername);
05224       }
05225 
05226       if (srv_ret > 0) {
05227          ast_sockaddr_set_port(&dialog->sa, tportno);
05228       }
05229    }
05230 
05231    if (!dialog->socket.type)
05232       set_socket_transport(&dialog->socket, SIP_TRANSPORT_UDP);
05233    if (!dialog->socket.port) {
05234       dialog->socket.port = htons(ast_sockaddr_port(&bindaddr));
05235    }
05236 
05237    if (!ast_sockaddr_port(&dialog->sa)) {
05238       ast_sockaddr_set_port(&dialog->sa,
05239                   (dialog->socket.type == SIP_TRANSPORT_TLS) ?
05240                   STANDARD_TLS_PORT : STANDARD_SIP_PORT);
05241    }
05242    ast_sockaddr_copy(&dialog->recv, &dialog->sa);
05243    return 0;
05244 }

static int create_addr_from_peer ( struct sip_pvt *  dialog,
struct sip_peer *  peer 
) [static]

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

Returns:
-1 on error, 0 on success.

Definition at line 5001 of file chan_sip.c.

References accountcode, ao2_t_link, ao2_t_unlink, ast_cc_copy_config_params(), ast_clear_flag, ast_copy_flags, ast_debug, ast_duplicate_ha_list(), ast_rtp_codecs_packetization_set(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_instance_set_hold_timeout(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_timeout(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify_host(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_destroy(), ast_udptl_new_with_bindaddr(), bindaddr, check_request_transport, cid_name, cid_num, context, copy_socket_data(), copy_vars(), dialog_initialize_rtp(), dialogs, global_t1min, io, language, mohinterpret, mohsuggest, obproxy_get(), parkinglot, ref_proxy(), and set_t38_capabilities().

Referenced by create_addr(), and sip_send_mwi_to_peer().

05002 {
05003    /* this checks that the dialog is contacting the peer on a valid
05004     * transport type based on the peers transport configuration,
05005     * otherwise, this function bails out */
05006    if (dialog->socket.type && check_request_transport(peer, dialog))
05007       return -1;
05008    copy_socket_data(&dialog->socket, &peer->socket);
05009 
05010    if (!(ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) &&
05011        (!peer->maxms || ((peer->lastms >= 0)  && (peer->lastms <= peer->maxms)))) {
05012       dialog->sa = ast_sockaddr_isnull(&peer->addr) ? peer->defaddr : peer->addr;
05013       dialog->recv = dialog->sa;
05014    } else
05015       return -1;
05016 
05017    /* XXX TODO: get flags directly from peer only as they are needed using dialog->relatedpeer */
05018    ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
05019    ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
05020    ast_copy_flags(&dialog->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
05021    dialog->capability = peer->capability;
05022    dialog->prefs = peer->prefs;
05023    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) {
05024       /* t38pt_udptl was enabled in the peer and not in [general] */
05025       if (dialog->udptl || (!dialog->udptl && (dialog->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &bindaddr)))) {
05026          dialog->t38_maxdatagram = peer->t38_maxdatagram;
05027          set_t38_capabilities(dialog);
05028       } else {
05029          /* It is impossible to support T38 without udptl */
05030          ast_debug(1, "UDPTL creation failed on dialog.\n");
05031          ast_clear_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT);
05032       }
05033    } else if (dialog->udptl) {
05034       ast_udptl_destroy(dialog->udptl);
05035       dialog->udptl = NULL;
05036    }
05037 
05038    ast_string_field_set(dialog, engine, peer->engine);
05039 
05040    if (dialog_initialize_rtp(dialog)) {
05041       return -1;
05042    }
05043 
05044    if (dialog->rtp) { /* Audio */
05045       ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
05046       ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
05047       ast_rtp_instance_set_timeout(dialog->rtp, peer->rtptimeout);
05048       ast_rtp_instance_set_hold_timeout(dialog->rtp, peer->rtpholdtimeout);
05049       /* Set Frame packetization */
05050       ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(dialog->rtp), dialog->rtp, &dialog->prefs);
05051       dialog->autoframing = peer->autoframing;
05052    }
05053    if (dialog->vrtp) { /* Video */
05054       ast_rtp_instance_set_timeout(dialog->vrtp, peer->rtptimeout);
05055       ast_rtp_instance_set_hold_timeout(dialog->vrtp, peer->rtpholdtimeout);
05056    }
05057    if (dialog->trtp) { /* Realtime text */
05058       ast_rtp_instance_set_timeout(dialog->trtp, peer->rtptimeout);
05059       ast_rtp_instance_set_hold_timeout(dialog->trtp, peer->rtpholdtimeout);
05060    }
05061 
05062    /* XXX TODO: get fields directly from peer only as they are needed using dialog->relatedpeer */
05063    ast_string_field_set(dialog, peername, peer->name);
05064    ast_string_field_set(dialog, authname, peer->username);
05065    ast_string_field_set(dialog, username, peer->username);
05066    ast_string_field_set(dialog, peersecret, peer->secret);
05067    ast_string_field_set(dialog, peermd5secret, peer->md5secret);
05068    ast_string_field_set(dialog, mohsuggest, peer->mohsuggest);
05069    ast_string_field_set(dialog, mohinterpret, peer->mohinterpret);
05070    ast_string_field_set(dialog, tohost, peer->tohost);
05071    ast_string_field_set(dialog, fullcontact, peer->fullcontact);
05072    ast_string_field_set(dialog, accountcode, peer->accountcode);
05073    ast_string_field_set(dialog, context, peer->context);
05074    ast_string_field_set(dialog, cid_num, peer->cid_num);
05075    ast_string_field_set(dialog, cid_name, peer->cid_name);
05076    ast_string_field_set(dialog, cid_tag, peer->cid_tag);
05077    ast_string_field_set(dialog, mwi_from, peer->mwi_from);
05078    if (!ast_strlen_zero(peer->parkinglot)) {
05079       ast_string_field_set(dialog, parkinglot, peer->parkinglot);
05080    }
05081    ast_string_field_set(dialog, engine, peer->engine);
05082    ref_proxy(dialog, obproxy_get(dialog, peer));
05083    dialog->callgroup = peer->callgroup;
05084    dialog->pickupgroup = peer->pickupgroup;
05085    dialog->allowtransfer = peer->allowtransfer;
05086    dialog->jointnoncodeccapability = dialog->noncodeccapability;
05087    dialog->rtptimeout = peer->rtptimeout;
05088    dialog->peerauth = peer->auth;
05089    dialog->maxcallbitrate = peer->maxcallbitrate;
05090    dialog->disallowed_methods = peer->disallowed_methods;
05091    ast_cc_copy_config_params(dialog->cc_params, peer->cc_params);
05092    if (ast_strlen_zero(dialog->tohost))
05093       ast_string_field_set(dialog, tohost, ast_sockaddr_stringify_host(&dialog->sa));
05094    if (!ast_strlen_zero(peer->fromdomain)) {
05095       ast_string_field_set(dialog, fromdomain, peer->fromdomain);
05096       if (!dialog->initreq.headers) {
05097          char *c;
05098          char *tmpcall = ast_strdupa(dialog->callid);
05099          /* this sure looks to me like we are going to change the callid on this dialog!! */
05100          c = strchr(tmpcall, '@');
05101          if (c) {
05102             *c = '\0';
05103             ao2_t_unlink(dialogs, dialog, "About to change the callid -- remove the old name");
05104             ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain);
05105             ao2_t_link(dialogs, dialog, "New dialog callid -- inserted back into table");
05106          }
05107       }
05108    }
05109    if (!ast_strlen_zero(peer->fromuser))
05110       ast_string_field_set(dialog, fromuser, peer->fromuser);
05111    if (!ast_strlen_zero(peer->language))
05112       ast_string_field_set(dialog, language, peer->language);
05113    /* Set timer T1 to RTT for this peer (if known by qualify=) */
05114    /* Minimum is settable or default to 100 ms */
05115    /* If there is a maxms and lastms from a qualify use that over a manual T1
05116       value. Otherwise, use the peer's T1 value. */
05117    if (peer->maxms && peer->lastms)
05118       dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
05119    else
05120       dialog->timer_t1 = peer->timer_t1;
05121 
05122    /* Set timer B to control transaction timeouts, the peer setting is the default and overrides
05123       the known timer */
05124    if (peer->timer_b)
05125       dialog->timer_b = peer->timer_b;
05126    else
05127       dialog->timer_b = 64 * dialog->timer_t1;
05128 
05129    if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
05130        (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
05131       dialog->noncodeccapability |= AST_RTP_DTMF;
05132    else
05133       dialog->noncodeccapability &= ~AST_RTP_DTMF;
05134    dialog->directmediaha = ast_duplicate_ha_list(peer->directmediaha);
05135    if (peer->call_limit)
05136       ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
05137    if (!dialog->portinuri)
05138       dialog->portinuri = peer->portinuri;
05139    dialog->chanvars = copy_vars(peer->chanvars);
05140    if (peer->fromdomainport)
05141       dialog->fromdomainport = peer->fromdomainport;
05142 
05143    return 0;
05144 }

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

Definition at line 904 of file chan_sip.c.

References ao2_t_alloc, ast_copy_string(), and find_static_data().

Referenced by sip_cc_monitor_suspend().

00905 {
00906    struct sip_epa_entry *epa_entry;
00907    const struct epa_static_data *static_data;
00908 
00909    if (!(static_data = find_static_data(event_package))) {
00910       return NULL;
00911    }
00912 
00913    if (!(epa_entry = ao2_t_alloc(sizeof(*epa_entry), static_data->destructor, "Allocate new EPA entry"))) {
00914       return NULL;
00915    }
00916 
00917    epa_entry->static_data = static_data;
00918    ast_copy_string(epa_entry->destination, destination, sizeof(epa_entry->destination));
00919    return epa_entry;
00920 }

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

Definition at line 1030 of file chan_sip.c.

References ao2_alloc, ao2_ref, ast_sched_add(), create_new_sip_etag(), esc_entry_destructor(), event_state_compositor::name, publish_expire(), and sched.

Referenced by handle_sip_publish_initial().

01031 {
01032    struct sip_esc_entry *esc_entry;
01033    int expires_ms;
01034 
01035    if (!(esc_entry = ao2_alloc(sizeof(*esc_entry), esc_entry_destructor))) {
01036       return NULL;
01037    }
01038 
01039    esc_entry->event = esc->name;
01040 
01041    expires_ms = expires * 1000;
01042    /* Bump refcount for scheduler */
01043    ao2_ref(esc_entry, +1);
01044    esc_entry->sched_id = ast_sched_add(sched, expires_ms, publish_expire, esc_entry);
01045 
01046    /* Note: This links the esc_entry into the ESC properly */
01047    create_new_sip_etag(esc_entry, 0);
01048 
01049    return esc_entry;
01050 }

static void create_new_sip_etag ( struct sip_esc_entry *  esc_entry,
int  is_linked 
) [static]

Definition at line 1017 of file chan_sip.c.

References ao2_link, ao2_unlink, ast_assert, ast_atomic_fetchadd_int(), event_state_compositor::compositor, and get_esc().

Referenced by create_esc_entry(), and transmit_response_with_sip_etag().

01018 {
01019    int new_etag = ast_atomic_fetchadd_int(&esc_etag_counter, +1);
01020    struct event_state_compositor *esc = get_esc(esc_entry->event);
01021 
01022    ast_assert(esc != NULL);
01023    if (is_linked) {
01024       ao2_unlink(esc->compositor, esc_entry);
01025    }
01026    snprintf(esc_entry->entity_tag, sizeof(esc_entry->entity_tag), "%d", new_etag);
01027    ao2_link(esc->compositor, esc_entry);
01028 }

static void deinit_req ( struct sip_request *  req  )  [static]

Deinitialize SIP response/request.

Definition at line 9637 of file chan_sip.c.

References ast_free.

Referenced by __sip_destroy(), send_request(), send_response(), sip_park(), sip_park_thread(), and sipsock_read().

09638 {
09639    if (req->data) {
09640       ast_free(req->data);
09641       req->data = NULL;
09642    }
09643    if (req->content) {
09644       ast_free(req->content);
09645       req->content = NULL;
09646    }
09647 }

static void destroy_association ( struct sip_peer *  peer  )  [static]

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

Definition at line 12969 of file chan_sip.c.

References ast_check_realtime(), ast_db_del(), ast_update_realtime(), SENTINEL, and sip_cfg.

Referenced by build_peer(), expire_register(), and parse_register_contact().

12970 {
12971    int realtimeregs = ast_check_realtime("sipregs");
12972    char *tablename = (realtimeregs) ? "sipregs" : "sippeers";
12973 
12974    if (!sip_cfg.ignore_regexpire) {
12975       if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) {
12976          ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "regserver", "", "useragent", "", "lastms", "", SENTINEL);
12977       } else {
12978          ast_db_del("SIP/Registry", peer->name);
12979          ast_db_del("SIP/PeerMethods", peer->name);
12980       }
12981    }
12982 }

static void destroy_escs ( void   )  [static]

Definition at line 1064 of file chan_sip.c.

References ao2_ref, ARRAY_LEN, and event_state_compositors.

Referenced by unload_module().

01065 {
01066    int i;
01067    for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
01068       ao2_ref(event_state_compositors[i].compositor, -1);
01069    }
01070 }

static void destroy_mailbox ( struct sip_mailbox *  mailbox  )  [static]

Destroy mailbox subscriptions

Definition at line 4449 of file chan_sip.c.

References ast_event_unsubscribe(), and ast_free.

Referenced by build_peer(), and clear_peer_mailboxes().

04450 {
04451    if (mailbox->event_sub)
04452       ast_event_unsubscribe(mailbox->event_sub);
04453    ast_free(mailbox);
04454 }

static int determine_firstline_parts ( struct sip_request *  req  )  [static]

Parse first line of incoming SIP request.

Definition at line 11187 of file chan_sip.c.

References ast_debug, ast_skip_blanks(), ast_skip_nonblanks(), and ast_trim_blanks().

11188 {
11189    char *e = ast_skip_blanks(req->data->str);   /* there shouldn't be any */
11190    char *local_rlPart1;
11191 
11192    if (!*e)
11193       return -1;
11194    req->rlPart1 = e - req->data->str;  /* method or protocol */
11195    local_rlPart1 = e;
11196    e = ast_skip_nonblanks(e);
11197    if (*e)
11198       *e++ = '\0';
11199    /* Get URI or status code */
11200    e = ast_skip_blanks(e);
11201    if ( !*e )
11202       return -1;
11203    ast_trim_blanks(e);
11204 
11205    if (!strcasecmp(local_rlPart1, "SIP/2.0") ) { /* We have a response */
11206       if (strlen(e) < 3)   /* status code is 3 digits */
11207          return -1;
11208       req->rlPart2 = e - req->data->str;
11209    } else { /* We have a request */
11210       if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */
11211          ast_debug(3, "Oops. Bogus uri in <> %s\n", e);
11212          e++;
11213          if (!*e)
11214             return -1;
11215       }
11216       req->rlPart2 = e - req->data->str;  /* URI */
11217       e = ast_skip_nonblanks(e);
11218       if (*e)
11219          *e++ = '\0';
11220       e = ast_skip_blanks(e);
11221       if (strcasecmp(e, "SIP/2.0") ) {
11222          ast_debug(3, "Skipping packet - Bad request protocol %s\n", e);
11223          return -1;
11224       }
11225    }
11226    return 1;
11227 }

static enum sip_publish_type determine_sip_publish_type ( struct sip_request *  req,
const char *const   event,
const char *const   etag,
const char *const   expires,
int *  expires_int 
) [static]

Definition at line 22813 of file chan_sip.c.

References ast_assert, ast_strlen_zero(), and DEFAULT_PUBLISH_EXPIRES.

Referenced by handle_request_publish().

22814 {
22815    int etag_present = !ast_strlen_zero(etag);
22816    int body_present = req->lines > 0;
22817 
22818    ast_assert(expires_int != NULL);
22819 
22820    if (ast_strlen_zero(expires)) {
22821       /* Section 6, item 4, second bullet point of RFC 3903 says to
22822        * use a locally-configured default expiration if none is provided
22823        * in the request
22824        */
22825       *expires_int = DEFAULT_PUBLISH_EXPIRES;
22826    } else if (sscanf(expires, "%30d", expires_int) != 1) {
22827       return SIP_PUBLISH_UNKNOWN;
22828    }
22829 
22830    if (*expires_int == 0) {
22831       return SIP_PUBLISH_REMOVE;
22832    } else if (!etag_present && body_present) {
22833       return SIP_PUBLISH_INITIAL;
22834    } else if (etag_present && !body_present) {
22835       return SIP_PUBLISH_REFRESH;
22836    } else if (etag_present && body_present) {
22837       return SIP_PUBLISH_MODIFY;
22838    }
22839 
22840    return SIP_PUBLISH_UNKNOWN;
22841 }

static int dialog_cmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Note:
The only member of the dialog used here callid string

Definition at line 28582 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by load_module().

28583 {
28584    struct sip_pvt *pvt = obj, *pvt2 = arg;
28585 
28586    return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH | CMP_STOP : 0;
28587 }

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

Definition at line 16061 of file chan_sip.c.

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

Referenced by sip_show_objects().

16062 {
16063    struct sip_pvt *pvt = userobj;
16064    int refc = ao2_t_ref(userobj, 0, "");
16065    struct ast_cli_args *a = (struct ast_cli_args *) arg;
16066    
16067    ast_cli(a->fd, "name: %s\ntype: dialog\nobjflags: %d\nrefcount: %d\n\n",
16068       pvt->callid, 0, refc);
16069    return 0;
16070 }

static int dialog_find_multiple ( void *  obj,
void *  arg,
int  flags 
) [static]

Note:
Same as dialog_cmp_cb, except without the CMP_STOP on match

Definition at line 28572 of file chan_sip.c.

References CMP_MATCH.

Referenced by find_call().

28573 {
28574    struct sip_pvt *pvt = obj, *pvt2 = arg;
28575 
28576    return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH : 0;
28577 }

static int dialog_hash_cb ( const void *  obj,
const int  flags 
) [static]

Note:
The only member of the dialog used here callid string

Definition at line 28562 of file chan_sip.c.

References ast_str_case_hash().

Referenced by load_module().

28563 {
28564    const struct sip_pvt *pvt = obj;
28565 
28566    return ast_str_case_hash(pvt->callid);
28567 }

static int dialog_initialize_rtp ( struct sip_pvt *  dialog  )  [static]

Initialize RTP portion of a dialog.

Returns:
-1 on failure, 0 on success

Definition at line 4946 of file chan_sip.c.

References AST_FORMAT_VIDEO_MASK, ast_rtp_instance_new(), ast_rtp_instance_set_hold_timeout(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_qos(), ast_rtp_instance_set_timeout(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, AST_RTP_PROPERTY_RTCP, ast_sockaddr_copy(), ast_test_flag, bindaddr, do_setnat(), global_cos_audio, global_rtpholdtimeout, global_rtptimeout, global_tos_audio, cfsip_methods::need_rtp, and sip_methods.

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

04947 {
04948    struct ast_sockaddr bindaddr_tmp;
04949 
04950    if (!sip_methods[dialog->method].need_rtp) {
04951       return 0;
04952    }
04953 
04954    ast_sockaddr_copy(&bindaddr_tmp, &bindaddr);
04955    if (!(dialog->rtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
04956       return -1;
04957    }
04958 
04959    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) ||
04960          (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (dialog->capability & AST_FORMAT_VIDEO_MASK))) {
04961       if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
04962          return -1;
04963       }
04964       ast_rtp_instance_set_timeout(dialog->vrtp, global_rtptimeout);
04965       ast_rtp_instance_set_hold_timeout(dialog->vrtp, global_rtpholdtimeout);
04966 
04967       ast_rtp_instance_set_prop(dialog->vrtp, AST_RTP_PROPERTY_RTCP, 1);
04968    }
04969 
04970    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_TEXTSUPPORT)) {
04971       if (!(dialog->trtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
04972          return -1;
04973       }
04974       ast_rtp_instance_set_timeout(dialog->trtp, global_rtptimeout);
04975       ast_rtp_instance_set_hold_timeout(dialog->trtp, global_rtpholdtimeout);
04976 
04977       ast_rtp_instance_set_prop(dialog->trtp, AST_RTP_PROPERTY_RTCP, 1);
04978    }
04979 
04980    ast_rtp_instance_set_timeout(dialog->rtp, global_rtptimeout);
04981    ast_rtp_instance_set_hold_timeout(dialog->rtp, global_rtpholdtimeout);
04982 
04983    ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_RTCP, 1);
04984    ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
04985    ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
04986 
04987    ast_rtp_instance_set_qos(dialog->rtp, global_tos_audio, global_cos_audio, "SIP RTP");
04988 
04989    do_setnat(dialog);
04990 
04991    return 0;
04992 }

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

Match dialogs that need to be destroyed.

This is used with ao2_callback to unlink/delete all dialogs that are marked needdestroy. It will return CMP_MATCH for candidates, and they will be unlinked.

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

Definition at line 16180 of file chan_sip.c.

References ast_debug, ast_rtp_instance_get_bridged(), check_rtp_timeout(), dialog_unlink_all(), FALSE, sip_methods, sip_pvt_trylock, sip_pvt_unlock, cfsip_methods::text, and TRUE.

Referenced by do_monitor().

16181 {
16182    struct sip_pvt *dialog = dialogobj;
16183    time_t *t = arg;
16184 
16185    if (sip_pvt_trylock(dialog)) {
16186       /* Don't block the monitor thread.  This function is called often enough
16187        * that we can wait for the next time around. */
16188       return 0;
16189    }
16190 
16191    /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */
16192    if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) {
16193       ast_debug(2, "Bridge still active.  Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
16194       sip_pvt_unlock(dialog);
16195       return 0;
16196    }
16197 
16198    if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) {
16199       ast_debug(2, "Bridge still active.  Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
16200       sip_pvt_unlock(dialog);
16201       return 0;
16202    }
16203 
16204    /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
16205    check_rtp_timeout(dialog, *t);
16206 
16207    /* If we have sessions that needs to be destroyed, do it now */
16208    /* Check if we have outstanding requests not responsed to or an active call
16209       - if that's the case, wait with destruction */
16210    if (dialog->needdestroy && !dialog->packets && !dialog->owner) {
16211       /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */
16212       if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) {
16213          ast_debug(2, "Bridge still active.  Delaying destruction of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
16214          sip_pvt_unlock(dialog);
16215          return 0;
16216       }
16217       
16218       if (dialog->vrtp && ast_rtp_instance_get_bridged(dialog->vrtp)) {
16219          ast_debug(2, "Bridge still active.  Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
16220          sip_pvt_unlock(dialog);
16221          return 0;
16222       }
16223 
16224       sip_pvt_unlock(dialog);
16225       /* no, the unlink should handle this: dialog_unref(dialog, "needdestroy: one more refcount decrement to allow dialog to be destroyed"); */
16226       /* the CMP_MATCH will unlink this dialog from the dialog hash table */
16227       dialog_unlink_all(dialog, TRUE, FALSE);
16228       return 0; /* the unlink_all should unlink this from the table, so.... no need to return a match */
16229    }
16230 
16231    sip_pvt_unlock(dialog);
16232 
16233    return 0;
16234 }

struct sip_pvt* dialog_ref_debug ( struct sip_pvt *  p,
char *  tag,
char *  file,
int  line,
const char *  func 
)

Definition at line 2192 of file chan_sip.c.

References __ao2_ref_debug(), ao2_ref, ast_log(), and LOG_ERROR.

02193 {
02194    if (p)
02195 #ifdef REF_DEBUG
02196       __ao2_ref_debug(p, 1, tag, file, line, func);
02197 #else
02198       ao2_ref(p, 1);
02199 #endif
02200    else
02201       ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n");
02202    return p;
02203 }

void* dialog_unlink_all ( struct sip_pvt *  dialog,
int  lockowner,
int  lockdialoglist 
)

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

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

Definition at line 2870 of file chan_sip.c.

References ao2_t_unlink, ast_channel_lock, ast_channel_unlock, ast_debug, ast_extension_state_del(), ast_free, AST_SCHED_DEL, AST_SCHED_DEL_UNREF, dialogs, and registry_unref().

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

02871 {
02872    struct sip_pkt *cp;
02873 
02874    dialog_ref(dialog, "Let's bump the count in the unlink so it doesn't accidentally become dead before we are done");
02875 
02876    ao2_t_unlink(dialogs, dialog, "unlinking dialog via ao2_unlink");
02877 
02878    /* Unlink us from the owner (channel) if we have one */
02879    if (dialog->owner) {
02880       if (lockowner)
02881          ast_channel_lock(dialog->owner);
02882       ast_debug(1, "Detaching from channel %s\n", dialog->owner->name);
02883       dialog->owner->tech_pvt = dialog_unref(dialog->owner->tech_pvt, "resetting channel dialog ptr in unlink_all");
02884       if (lockowner) {
02885          ast_channel_unlock(dialog->owner);
02886       }
02887    }
02888    if (dialog->registry) {
02889       if (dialog->registry->call == dialog) {
02890          dialog->registry->call = dialog_unref(dialog->registry->call, "nulling out the registry's call dialog field in unlink_all");
02891       }
02892       dialog->registry = registry_unref(dialog->registry, "delete dialog->registry");
02893    }
02894    if (dialog->stateid > -1) {
02895       ast_extension_state_del(dialog->stateid, NULL);
02896       dialog_unref(dialog, "removing extension_state, should unref the associated dialog ptr that was stored there.");
02897       dialog->stateid = -1; /* shouldn't we 'zero' this out? */
02898    }
02899    /* Remove link from peer to subscription of MWI */
02900    if (dialog->relatedpeer && dialog->relatedpeer->mwipvt == dialog) {
02901       dialog->relatedpeer->mwipvt = dialog_unref(dialog->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt");
02902    }
02903    if (dialog->relatedpeer && dialog->relatedpeer->call == dialog) {
02904       dialog->relatedpeer->call = dialog_unref(dialog->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself");
02905    }
02906 
02907    /* remove all current packets in this dialog */
02908    while((cp = dialog->packets)) {
02909       dialog->packets = dialog->packets->next;
02910       AST_SCHED_DEL(sched, cp->retransid);
02911       dialog_unref(cp->owner, "remove all current packets in this dialog, and the pointer to the dialog too as part of __sip_destroy");
02912       if (cp->data) {
02913          ast_free(cp->data);
02914       }
02915       ast_free(cp);
02916    }
02917 
02918    AST_SCHED_DEL_UNREF(sched, dialog->waitid, dialog_unref(dialog, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr"));
02919 
02920    AST_SCHED_DEL_UNREF(sched, dialog->initid, dialog_unref(dialog, "when you delete the initid sched, you should dec the refcount for the stored dialog ptr"));
02921    
02922    if (dialog->autokillid > -1) {
02923       AST_SCHED_DEL_UNREF(sched, dialog->autokillid, dialog_unref(dialog, "when you delete the autokillid sched, you should dec the refcount for the stored dialog ptr"));
02924    }
02925 
02926    if (dialog->request_queue_sched_id > -1) {
02927       AST_SCHED_DEL_UNREF(sched, dialog->request_queue_sched_id, dialog_unref(dialog, "when you delete the request_queue_sched_id sched, you should dec the refcount for the stored dialog ptr"));
02928    }
02929 
02930    AST_SCHED_DEL_UNREF(sched, dialog->provisional_keepalive_sched_id, dialog_unref(dialog, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr"));
02931 
02932    if (dialog->t38id > -1) {
02933       AST_SCHED_DEL_UNREF(sched, dialog->t38id, dialog_unref(dialog, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr"));
02934    }
02935 
02936    dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time");
02937    return NULL;
02938 }

struct sip_pvt* dialog_unref_debug ( struct sip_pvt *  p,
char *  tag,
char *  file,
int  line,
const char *  func 
)

Definition at line 2205 of file chan_sip.c.

References __ao2_ref_debug(), and ao2_ref.

02206 {
02207    if (p)
02208 #ifdef REF_DEBUG
02209       __ao2_ref_debug(p, -1, tag, file, line, func);
02210 #else
02211       ao2_ref(p, -1);
02212 #endif
02213    return NULL;
02214 }

static void disable_dsp_detect ( struct sip_pvt *  p  )  [static]

Definition at line 4156 of file chan_sip.c.

References ast_dsp_free().

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

04157 {
04158    if (p->dsp) {
04159       ast_dsp_free(p->dsp);
04160       p->dsp = NULL;
04161    }
04162 }

static int do_magic_pickup ( struct ast_channel *  channel,
const char *  extension,
const char *  context 
) [static]

Note:
No channel or pvt locks should be held while calling this function.

Definition at line 21038 of file chan_sip.c.

References ast_debug, ast_log(), AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_str_alloca, ast_str_set(), LOG_ERROR, pbx_exec(), pbx_findapp(), sip_cfg, and str.

Referenced by handle_request_invite().

21039 {
21040    struct ast_str *str = ast_str_alloca(AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2);
21041    struct ast_app *pickup = pbx_findapp("Pickup");
21042 
21043    if (!pickup) {
21044       ast_log(LOG_ERROR, "Unable to perform pickup: Application 'Pickup' not loaded (app_directed_pickup.so).\n");
21045       return -1;
21046    }
21047 
21048    ast_str_set(&str, 0, "%s@%s", extension, sip_cfg.notifycid == IGNORE_CONTEXT ? "PICKUPMARK" : context);
21049 
21050    ast_debug(2, "About to call Pickup(%s)\n", str->str);
21051 
21052    /* There is no point in capturing the return value since pickup_exec
21053       doesn't return anything meaningful unless the passed data is an empty
21054       string (which in our case it will not be) */
21055    pbx_exec(channel, pickup, str->str);
21056 
21057    return 0;
21058 }

static void * do_monitor ( void *  data  )  [static]

The SIP monitoring thread.

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

Definition at line 24663 of file chan_sip.c.

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

24664 {
24665    int res;
24666    time_t t;
24667    int reloading;
24668 
24669    /* Add an I/O event to our SIP UDP socket */
24670    if (sipsock > -1)
24671       sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
24672 
24673    /* From here on out, we die whenever asked */
24674    for(;;) {
24675       /* Check for a reload request */
24676       ast_mutex_lock(&sip_reload_lock);
24677       reloading = sip_reloading;
24678       sip_reloading = FALSE;
24679       ast_mutex_unlock(&sip_reload_lock);
24680       if (reloading) {
24681          ast_verb(1, "Reloading SIP\n");
24682          sip_do_reload(sip_reloadreason);
24683 
24684          /* Change the I/O fd of our UDP socket */
24685          if (sipsock > -1) {
24686             if (sipsock_read_id)
24687                sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL);
24688             else
24689                sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
24690          } else if (sipsock_read_id) {
24691             ast_io_remove(io, sipsock_read_id);
24692             sipsock_read_id = NULL;
24693          }
24694       }
24695 
24696       /* Check for dialogs needing to be killed */
24697       t = time(NULL);
24698       /* don't scan the dialogs list if it hasn't been a reasonable period
24699          of time since the last time we did it (when MWI is being sent, we can
24700          get back to this point every millisecond or less)
24701       */
24702       ao2_t_callback(dialogs, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, dialog_needdestroy, &t,
24703             "callback to remove dialogs w/needdestroy");
24704 
24705       /* the old methodology would be to restart the search for dialogs to delete with every
24706          dialog that was found and destroyed, probably because the list contents would change,
24707          so we'd need to restart. This isn't the best thing to do with callbacks. */
24708 
24709       /* XXX TODO The scheduler usage in this module does not have sufficient
24710        * synchronization being done between running the scheduler and places
24711        * scheduling tasks.  As it is written, any scheduled item may not run
24712        * any sooner than about  1 second, regardless of whether a sooner time
24713        * was asked for. */
24714 
24715       pthread_testcancel();
24716       /* Wait for sched or io */
24717       res = ast_sched_wait(sched);
24718       if ((res < 0) || (res > 1000))
24719          res = 1000;
24720       res = ast_io_wait(io, res);
24721       if (res > 20)
24722          ast_debug(1, "chan_sip: ast_io_wait ran %d all at once\n", res);
24723       ast_mutex_lock(&monlock);
24724       res = ast_sched_runq(sched);
24725       if (res >= 20)
24726          ast_debug(1, "chan_sip: ast_sched_runq ran %d all at once\n", res);
24727       ast_mutex_unlock(&monlock);
24728    }
24729 
24730    /* Never reached */
24731    return NULL;
24732 }

static int do_proxy_auth ( struct sip_pvt *  p,
struct sip_request *  req,
enum sip_auth_type  code,
int  sipmethod,
int  init 
) [static]

Add authentication on outbound SIP packet.

Definition at line 18252 of file chan_sip.c.

References ast_calloc, ast_debug, auth_headers(), reply_digest(), sip_methods, cfsip_methods::text, and transmit_invite().

Referenced by handle_response(), handle_response_invite(), handle_response_notify(), handle_response_publish(), handle_response_refer(), handle_response_subscribe(), and handle_response_update().

18253 {
18254    char *header, *respheader;
18255    char digest[1024];
18256 
18257    if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options))))
18258       return -2;
18259 
18260    p->authtries++;
18261    auth_headers(code, &header, &respheader);
18262    ast_debug(2, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
18263    memset(digest, 0, sizeof(digest));
18264    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
18265       /* No way to authenticate */
18266       return -1;
18267    }
18268    /* Now we have a reply digest */
18269    p->options->auth = digest;
18270    p->options->authheader = respheader;
18271    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init, NULL);
18272 }

static int do_register_auth ( struct sip_pvt *  p,
struct sip_request *  req,
enum sip_auth_type  code 
) [static]

Authenticate for outbound registration.

Definition at line 18228 of file chan_sip.c.

References append_history, ast_verbose, auth_headers(), reply_digest(), sip_debug_test_pvt(), and transmit_register().

Referenced by handle_response_register().

18229 {
18230    char *header, *respheader;
18231    char digest[1024];
18232 
18233    p->authtries++;
18234    auth_headers(code, &header, &respheader);
18235    memset(digest, 0, sizeof(digest));
18236    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
18237       /* There's nothing to use for authentication */
18238       /* No digest challenge in request */
18239       if (sip_debug_test_pvt(p) && p->registry)
18240          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
18241          /* No old challenge */
18242       return -1;
18243    }
18244    if (p->do_history)
18245       append_history(p, "RegistryAuth", "Try: %d", p->authtries);
18246    if (sip_debug_test_pvt(p) && p->registry)
18247       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
18248    return transmit_register(p->registry, SIP_REGISTER, digest, respheader);
18249 }

static void do_setnat ( struct sip_pvt *  p  )  [static]

Set nat mode on the various data sockets.

Definition at line 4840 of file chan_sip.c.

References ast_debug, ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_NAT, ast_test_flag, and ast_udptl_setnat().

Referenced by check_peer_ok(), dialog_initialize_rtp(), sip_alloc(), and transmit_response_using_temp().

04841 {
04842    const char *mode;
04843    int natflags;
04844 
04845    natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP);
04846    mode = natflags ? "On" : "Off";
04847 
04848    if (p->rtp) {
04849       ast_debug(1, "Setting NAT on RTP to %s\n", mode);
04850       ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_NAT, natflags);
04851    }
04852    if (p->vrtp) {
04853       ast_debug(1, "Setting NAT on VRTP to %s\n", mode);
04854       ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_NAT, natflags);
04855    }
04856    if (p->udptl) {
04857       ast_debug(1, "Setting NAT on UDPTL to %s\n", mode);
04858       ast_udptl_setnat(p->udptl, natflags);
04859    }
04860    if (p->trtp) {
04861       ast_debug(1, "Setting NAT on TRTP to %s\n", mode);
04862       ast_rtp_instance_set_prop(p->trtp, AST_RTP_PROPERTY_NAT, natflags);
04863    }
04864 }

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

Print domain mode to cli.

Definition at line 16389 of file chan_sip.c.

Referenced by sip_show_domains().

16390 {
16391    switch (mode) {
16392    case SIP_DOMAIN_AUTO:
16393       return "[Automatic]";
16394    case SIP_DOMAIN_CONFIG:
16395       return "[Configured]";
16396    }
16397 
16398    return "";
16399 }

static const char * dtmfmode2str ( int  mode  )  const [static]

Convert DTMF mode to printable string.

Definition at line 16117 of file chan_sip.c.

References dtmfstr, and map_x_s().

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

16118 {
16119    return map_x_s(dtmfstr, mode, "<error>");
16120 }

static void enable_dsp_detect ( struct sip_pvt *  p  )  [static]

Definition at line 4123 of file chan_sip.c.

References ast_dsp_new(), ast_dsp_set_digitmode(), ast_dsp_set_features(), AST_RTP_DTMF_MODE_INBAND, ast_rtp_instance_dtmf_mode_set(), ast_test_flag, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, and global_relaxdtmf.

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

04124 {
04125    int features = 0;
04126 
04127    if (p->dsp) {
04128       return;
04129    }
04130 
04131    if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) ||
04132             (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
04133       if (!p->rtp || ast_rtp_instance_dtmf_mode_set(p->rtp, AST_RTP_DTMF_MODE_INBAND)) {
04134          features |= DSP_FEATURE_DIGIT_DETECT;
04135                 }
04136    }
04137 
04138    if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) {
04139       features |= DSP_FEATURE_FAX_DETECT;
04140    }
04141 
04142    if (!features) {
04143       return;
04144    }
04145 
04146    if (!(p->dsp = ast_dsp_new())) {
04147       return;
04148    }
04149 
04150    ast_dsp_set_features(p->dsp, features);
04151    if (global_relaxdtmf) {
04152       ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
04153    }
04154 }

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

Definition at line 976 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by initialize_escs().

00977 {
00978    struct sip_esc_entry *entry1 = obj;
00979    struct sip_esc_entry *entry2 = arg;
00980 
00981    return (!strcmp(entry1->entity_tag, entry2->entity_tag)) ? (CMP_MATCH | CMP_STOP) : 0;
00982 }

static void esc_entry_destructor ( void *  obj  )  [static]

Definition at line 962 of file chan_sip.c.

References AST_SCHED_DEL, and sched.

Referenced by create_esc_entry().

00963 {
00964    struct sip_esc_entry *esc_entry = obj;
00965    if (esc_entry->sched_id > -1) {
00966       AST_SCHED_DEL(sched, esc_entry->sched_id);
00967    }
00968 }

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

Definition at line 970 of file chan_sip.c.

References ast_str_hash().

Referenced by initialize_escs().

00971 {
00972    const struct sip_esc_entry *entry = obj;
00973    return ast_str_hash(entry->entity_tag);
00974 }

static int expire_register ( const void *  data  )  [static]

Expire registration of SIP peer.

Definition at line 12998 of file chan_sip.c.

References ao2_ref, ast_debug, AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_test_flag, destroy_association(), EVENT_FLAG_SYSTEM, FALSE, manager_event, register_peer_exten(), rpeerobjs, set_socket_transport(), unlink_peer_from_tables(), and unref_peer().

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

12999 {
13000    struct sip_peer *peer = (struct sip_peer *)data;
13001 
13002    if (!peer) {      /* Hmmm. We have no peer. Weird. */
13003       return 0;
13004    }
13005 
13006    peer->expire = -1;
13007    peer->portinuri = 0;
13008 
13009    destroy_association(peer); /* remove registration data from storage */
13010    set_socket_transport(&peer->socket, peer->default_outbound_transport);
13011 
13012    if (peer->socket.tcptls_session) {
13013       ao2_ref(peer->socket.tcptls_session, -1);
13014       peer->socket.tcptls_session = NULL;
13015    }
13016 
13017    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
13018    register_peer_exten(peer, FALSE);   /* Remove regexten */
13019    ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
13020 
13021    /* Do we need to release this peer from memory?
13022       Only for realtime peers and autocreated peers
13023    */
13024    if (peer->is_realtime) {
13025       ast_debug(3, "-REALTIME- peer expired registration. Name: %s. Realtime peer objects now %d\n", peer->name, rpeerobjs);
13026    }
13027 
13028    if (peer->selfdestruct ||
13029        ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
13030       unlink_peer_from_tables(peer);
13031    }
13032 
13033    /* Only clear the addr after we check for destruction.  The addr must remain
13034     * in order to unlink from the peers_by_ip container correctly */
13035    memset(&peer->addr, 0, sizeof(peer->addr));
13036 
13037    unref_peer(peer, "removing peer ref for expire_register");
13038 
13039    return 0;
13040 }

static void extract_uri ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

Check Contact: URI of SIP message.

Definition at line 11295 of file chan_sip.c.

References ast_copy_string(), ast_string_field_set, ast_strlen_zero(), get_header(), and remove_uri_parameters().

Referenced by handle_incoming(), and handle_request_invite().

11296 {
11297    char stripped[SIPBUFSIZE];
11298    char *c;
11299 
11300    ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
11301    c = get_in_brackets(stripped);
11302    /* Cut the URI at the at sign after the @, not in the username part */
11303    c = remove_uri_parameters(c);
11304    if (!ast_strlen_zero(c)) {
11305       ast_string_field_set(p, uri, c);
11306    }
11307 
11308 }

static const char* faxec2str ( int  faxec  )  [static]

Definition at line 16553 of file chan_sip.c.

References faxecmodes, and map_x_s().

Referenced by _sip_show_peer(), and sip_show_settings().

16554 {
16555    return map_x_s(faxecmodes, faxec, "Unknown");
16556 }

static int finalize_content ( struct sip_request *  req  )  [static]

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

Definition at line 9350 of file chan_sip.c.

References add_header(), ast_log(), ast_str_append(), ast_str_buffer(), ast_str_strlen(), and LOG_WARNING.

Referenced by send_request(), and send_response().

09351 {
09352    char clen[10];
09353 
09354    if (req->lines) {
09355       ast_log(LOG_WARNING, "finalize_content() called on a message that has already been finalized\n");
09356       return -1;
09357    }
09358 
09359    snprintf(clen, sizeof(clen), "%zd", ast_str_strlen(req->content));
09360    add_header(req, "Content-Length", clen);
09361 
09362    if (ast_str_strlen(req->content)) {
09363       ast_str_append(&req->data, 0, "\r\n%s", ast_str_buffer(req->content));
09364       req->len = ast_str_strlen(req->data);
09365    }
09366    req->lines = ast_str_strlen(req->content) ? 1 : 0;
09367    return 0;
09368 }

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

Find compressed SIP alias.

Structure for conversion between compressed SIP and "normal" SIP

Definition at line 6949 of file chan_sip.c.

References aliases, and ARRAY_LEN.

06950 {
06951    /*! \brief Structure for conversion between compressed SIP and "normal" SIP */
06952    static const struct cfalias {
06953       char * const fullname;
06954       char * const shortname;
06955    } aliases[] = {
06956       { "Content-Type",  "c" },
06957       { "Content-Encoding",    "e" },
06958       { "From",       "f" },
06959       { "Call-ID",       "i" },
06960       { "Contact",       "m" },
06961       { "Content-Length",   "l" },
06962       { "Subject",       "s" },
06963       { "To",         "t" },
06964       { "Supported",     "k" },
06965       { "Refer-To",      "r" },
06966       { "Referred-By",   "b" },
06967       { "Allow-Events",  "u" },
06968       { "Event",      "o" },
06969       { "Via",     "v" },
06970       { "Accept-Contact",      "a" },
06971       { "Reject-Contact",      "j" },
06972       { "Request-Disposition", "d" },
06973       { "Session-Expires",     "x" },
06974       { "Identity",            "y" },
06975       { "Identity-Info",       "n" },
06976    };
06977    int x;
06978 
06979    for (x = 0; x < ARRAY_LEN(aliases); x++) {
06980       if (!strcasecmp(aliases[x].fullname, name))
06981          return aliases[x].shortname;
06982    }
06983 
06984    return _default;
06985 }

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

Definition at line 1656 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, and ast_cc_agent::private_data.

Referenced by find_sip_cc_agent_by_original_callid().

01657 {
01658    struct ast_cc_agent *agent = obj;
01659    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01660    struct sip_pvt *call_pvt = arg;
01661 
01662    return !strcmp(agent_pvt->original_callid, call_pvt->callid) ? CMP_MATCH | CMP_STOP : 0;
01663 }

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

Definition at line 4751 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, and match().

Referenced by ast_setlocale(), find_peer(), and store_by_locale().

04752 {
04753    struct sip_peer *search = obj, *match = arg;
04754    int *which_objects = data;
04755 
04756    /* Usernames in SIP uri's are case sensitive. Domains are not */
04757    if (strcmp(search->name, match->name)) {
04758       return 0;
04759    }
04760 
04761    switch (*which_objects) {
04762    case FINDUSERS:
04763       if (!(search->type & SIP_TYPE_USER)) {
04764          return 0;
04765       }
04766       break;
04767    case FINDPEERS:
04768       if (!(search->type & SIP_TYPE_PEER)) {
04769          return 0;
04770       }
04771       break;
04772    case FINDALLDEVICES:
04773       break;
04774    }
04775 
04776    return CMP_MATCH | CMP_STOP;
04777 }

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

Definition at line 1626 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, and ast_cc_agent::private_data.

Referenced by find_sip_cc_agent_by_notify_uri().

01627 {
01628    struct ast_cc_agent *agent = obj;
01629    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01630    const char *uri = arg;
01631 
01632    return !sip_uri_cmp(agent_pvt->notify_uri, uri) ? CMP_MATCH | CMP_STOP : 0;
01633 }

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

Definition at line 1641 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, and ast_cc_agent::private_data.

Referenced by find_sip_cc_agent_by_subscribe_uri().

01642 {
01643    struct ast_cc_agent *agent = obj;
01644    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01645    const char *uri = arg;
01646 
01647    return !sip_uri_cmp(agent_pvt->subscribe_uri, uri) ? CMP_MATCH | CMP_STOP : 0;
01648 }

static struct sip_pvt * find_call ( struct sip_request *  req,
struct ast_sockaddr *  addr,
const int  intended_method 
) [static]

find or create a dialog structure for an incoming SIP message. Connect incoming SIP message to current dialog or create new dialog structure Returns a reference to the sip_pvt object, remember to give it back once done. Called by handle_incoming(), sipsock_read

Definition at line 7603 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_next, ao2_t_callback, ao2_t_find, args, ast_debug, ast_strlen_zero(), dialog_find_multiple(), dialogs, get_header(), gettag(), match_req_to_dialog(), OBJ_MULTIPLE, OBJ_POINTER, sip_alloc(), sip_cfg, sip_methods, sip_pvt_lock, SIP_REQ_LOOP_DETECTED, SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, cfsip_methods::text, and transmit_response_using_temp().

Referenced by handle_request_do().

07604 {
07605    char totag[128];
07606    char fromtag[128];
07607    const char *callid = get_header(req, "Call-ID");
07608    const char *from = get_header(req, "From");
07609    const char *to = get_header(req, "To");
07610    const char *cseq = get_header(req, "Cseq");
07611    struct sip_pvt *sip_pvt_ptr;
07612    unsigned int seqno;
07613    /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */
07614    /* get_header always returns non-NULL so we must use ast_strlen_zero() */
07615    if (ast_strlen_zero(callid) || ast_strlen_zero(to) ||
07616          ast_strlen_zero(from) || ast_strlen_zero(cseq) ||
07617          (sscanf(cseq, "%30u", &seqno) != 1)) {
07618 
07619       /* RFC 3261 section 24.4.1.   Send a 400 Bad Request if the request is malformed. */
07620       if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
07621          transmit_response_using_temp(callid, addr, 1, intended_method,
07622                        req, "400 Bad Request");
07623       }
07624       return NULL;   /* Invalid packet */
07625    }
07626 
07627    if (sip_cfg.pedanticsipchecking) {
07628       /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
07629          we need more to identify a branch - so we have to check branch, from
07630          and to tags to identify a call leg.
07631          For Asterisk to behave correctly, you need to turn on pedanticsipchecking
07632          in sip.conf
07633          */
07634       if (gettag(req, "To", totag, sizeof(totag)))
07635          req->has_to_tag = 1; /* Used in handle_request/response */
07636       gettag(req, "From", fromtag, sizeof(fromtag));
07637 
07638       ast_debug(5, "= Looking for  Call ID: %s (Checking %s) --From tag %s --To-tag %s  \n", callid, req->method==SIP_RESPONSE ? "To" : "From", fromtag, totag);
07639 
07640       /* All messages must always have From: tag */
07641       if (ast_strlen_zero(fromtag)) {
07642          ast_debug(5, "%s request has no from tag, dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from );
07643          return NULL;
07644       }
07645       /* reject requests that must always have a To: tag */
07646       if (ast_strlen_zero(totag) && (req->method == SIP_ACK || req->method == SIP_BYE || req->method == SIP_INFO )) {
07647          ast_debug(5, "%s must have a to tag. dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from );
07648          return NULL;
07649       }
07650    }
07651 
07652    if (!sip_cfg.pedanticsipchecking) {
07653       struct sip_pvt tmp_dialog = {
07654          .callid = callid,
07655       };
07656       sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find in dialogs");
07657       if (sip_pvt_ptr) {  /* well, if we don't find it-- what IS in there? */
07658          /* Found the call */
07659          sip_pvt_lock(sip_pvt_ptr);
07660          return sip_pvt_ptr;
07661       }
07662    } else { /* in pedantic mode! -- do the fancy search */
07663       struct sip_pvt tmp_dialog = {
07664          .callid = callid,
07665       };
07666       struct match_req_args args = { 0, };
07667       int found;
07668       struct ao2_iterator *iterator = ao2_t_callback(dialogs,
07669          OBJ_POINTER | OBJ_MULTIPLE,
07670          dialog_find_multiple,
07671          &tmp_dialog,
07672          "pedantic ao2_find in dialogs");
07673       struct sip_via *via = NULL;
07674 
07675       args.method = req->method;
07676       args.callid = NULL; /* we already matched this. */
07677       args.totag = totag;
07678       args.fromtag = fromtag;
07679       args.seqno = seqno;
07680 
07681       /* If this is a Request, set the Via and Authorization header arguments */
07682       if (req->method != SIP_RESPONSE) {
07683          args.ruri = REQ_OFFSET_TO_STR(req, rlPart2);
07684          via = parse_via(get_header(req, "Via"));
07685          if (via) {
07686             args.viasentby = via->sent_by;
07687             args.viabranch = via->branch;
07688          }
07689          if (!ast_strlen_zero(get_header(req, "Authorization")) ||
07690             !ast_strlen_zero(get_header(req, "Proxy-Authorization"))) {
07691             args.authentication_present = 1;
07692          }
07693       }
07694 
07695       /* Iterate a list of dialogs already matched by Call-id */
07696       while (iterator && (sip_pvt_ptr = ao2_iterator_next(iterator))) {
07697          found = match_req_to_dialog(sip_pvt_ptr, &args);
07698 
07699          switch (found) {
07700          case SIP_REQ_MATCH:
07701             sip_pvt_lock(sip_pvt_ptr);
07702             ao2_iterator_destroy(iterator);
07703             free_via(via);
07704             return sip_pvt_ptr; /* return pvt with ref */
07705          case SIP_REQ_LOOP_DETECTED:
07706             /* This is likely a forked Request that somehow resulted in us receiving multiple parts of the fork.
07707             * RFC 3261 section 8.2.2.2, Indicate that we want to merge requests by sending a 482 response. */
07708             transmit_response_using_temp(callid, addr, 1, intended_method, req, "482 (Loop Detected)");
07709             dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search.");
07710             ao2_iterator_destroy(iterator);
07711             free_via(via);
07712             return NULL;
07713          case SIP_REQ_NOT_MATCH:
07714          default:
07715             dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search");
07716          }
07717       }
07718       if (iterator) {
07719          ao2_iterator_destroy(iterator);
07720       }
07721 
07722       free_via(via);
07723    } /* end of pedantic mode Request/Reponse to Dialog matching */
07724 
07725    /* See if the method is capable of creating a dialog */
07726    if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) {
07727       struct sip_pvt *p = NULL;
07728 
07729       if (intended_method == SIP_REFER) {
07730          /* We do support REFER, but not outside of a dialog yet */
07731          transmit_response_using_temp(callid, addr, 1, intended_method, req, "603 Declined (no dialog)");
07732       } else {
07733          /* Ok, time to create a new SIP dialog object, a pvt */
07734          if ((p = sip_alloc(callid, addr, 1, intended_method, req)))  {
07735             /* Ok, we've created a dialog, let's go and process it */
07736             sip_pvt_lock(p);
07737          } else {
07738             /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
07739                getting a dialog from sip_alloc.
07740    
07741                Without a dialog we can't retransmit and handle ACKs and all that, but at least
07742                send an error message.
07743    
07744                Sorry, we apologize for the inconvienience
07745             */
07746             transmit_response_using_temp(callid, addr, 1, intended_method, req, "500 Server internal error");
07747             ast_debug(4, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
07748          }
07749       }
07750       return p; /* can be NULL */
07751    } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
07752       /* A method we do not support, let's take it on the volley */
07753       transmit_response_using_temp(callid, addr, 1, intended_method, req, "501 Method Not Implemented");
07754       ast_debug(2, "Got a request with unsupported SIP method.\n");
07755    } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
07756       /* This is a request outside of a dialog that we don't know about */
07757       transmit_response_using_temp(callid, addr, 1, intended_method, req, "481 Call leg/transaction does not exist");
07758       ast_debug(2, "That's odd...  Got a request in unknown dialog. Callid %s\n", callid ? callid : "<unknown>");
07759    }
07760    /* We do not respond to responses for dialogs that we don't know about, we just drop
07761       the session quickly */
07762    if (intended_method == SIP_RESPONSE)
07763       ast_debug(2, "That's odd...  Got a response on a call we don't know about. Callid %s\n", callid ? callid : "<unknown>");
07764 
07765    return NULL;
07766 }

static int find_calling_channel ( void *  obj,
void *  arg,
void *  data,
int  flags 
) [static]

Find the channel that is causing the RINGING update.

Definition at line 11841 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, CMP_MATCH, CMP_STOP, ast_channel::context, ast_channel::exten, ast_channel::macroexten, ast_channel::pbx, and sip_cfg.

Referenced by state_notify_build_xml().

11842 {
11843    struct ast_channel *c = obj;
11844    struct sip_pvt *p = data;
11845    int res;
11846 
11847    ast_channel_lock(c);
11848 
11849    res = (c->pbx &&
11850          (!strcasecmp(c->macroexten, p->exten) || !strcasecmp(c->exten, p->exten)) &&
11851          (sip_cfg.notifycid == IGNORE_CONTEXT || !strcasecmp(c->context, p->context)));
11852 
11853    ast_channel_unlock(c);
11854 
11855    return res ? CMP_MATCH | CMP_STOP : 0;
11856 }

const char* find_closing_quote ( const char *  start,
const char *  lim 
)

Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote.

Definition at line 4282 of file chan_sip.c.

Referenced by parse_moved_contact().

04283 {
04284    char last_char = '\0';
04285    const char *s;
04286    for (s = start; *s && s != lim; last_char = *s++) {
04287       if (*s == '"' && last_char != '\\')
04288          break;
04289    }
04290    return s;
04291 }

static struct sip_peer * find_peer ( const char *  peer,
struct ast_sockaddr *  addr,
int  realtime,
int  which_objects,
int  devstate_only,
int  transport 
) [static]

Locate device by name or ip address.

Parameters:
peer,sin,realtime,devstate_only,transport 
which_objects Define which objects should be matched when doing a lookup by name. Valid options are FINDUSERS, FINDPEERS, or FINDALLDEVICES. Note that this option is not used at all when doing a lookup by IP.
This is used on find matching device on name or ip/port. If the device was declared as type=peer, we don't match on peer name on incoming INVITEs.

Note:
Avoid using this function in new functions if there is a way to avoid it, since it might cause a database lookup.

Definition at line 4792 of file chan_sip.c.

References ao2_t_callback_data, ao2_t_find, ast_copy_string(), ast_set_flag, ast_sockaddr_copy(), find_by_name(), OBJ_POINTER, peers_by_ip, realtime_peer(), and unref_peer().

04793 {
04794    struct sip_peer *p = NULL;
04795    struct sip_peer tmp_peer;
04796 
04797    if (peer) {
04798       ast_copy_string(tmp_peer.name, peer, sizeof(tmp_peer.name));
04799       p = ao2_t_callback_data(peers, OBJ_POINTER, find_by_name, &tmp_peer, &which_objects, "ao2_find in peers table");
04800    } else if (addr) { /* search by addr? */
04801       ast_sockaddr_copy(&tmp_peer.addr, addr);
04802       tmp_peer.flags[0].flags = 0;
04803       tmp_peer.transports = transport;
04804       p = ao2_t_find(peers_by_ip, &tmp_peer, OBJ_POINTER, "ao2_find in peers_by_ip table"); /* WAS:  p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); */
04805       if (!p) {
04806          ast_set_flag(&tmp_peer.flags[0], SIP_INSECURE_PORT);
04807          p = ao2_t_find(peers_by_ip, &tmp_peer, OBJ_POINTER, "ao2_find in peers_by_ip table 2"); /* WAS:  p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); */
04808          if (p) {
04809             return p;
04810          }
04811       }
04812    }
04813 
04814    if (!p && (realtime || devstate_only)) {
04815       p = realtime_peer(peer, addr, devstate_only, which_objects);
04816       if (p) {
04817          switch (which_objects) {
04818          case FINDUSERS:
04819             if (!(p->type & SIP_TYPE_USER)) {
04820                unref_peer(p, "Wrong type of realtime SIP endpoint");
04821                return NULL;
04822             }
04823             break;
04824          case FINDPEERS:
04825             if (!(p->type & SIP_TYPE_PEER)) {
04826                unref_peer(p, "Wrong type of realtime SIP endpoint");
04827                return NULL;
04828             }
04829             break;
04830          case FINDALLDEVICES:
04831             break;
04832          }
04833       }
04834    }
04835 
04836    return p;
04837 }

static struct sip_auth * find_realm_authentication ( struct sip_auth *  authlist,
const char *  realm 
) [static]

Find authentication for a specific realm.

Definition at line 25857 of file chan_sip.c.

Referenced by build_reply_digest().

25858 {
25859    struct sip_auth *a;
25860 
25861    for (a = authlist; a; a = a->next) {
25862       if (!strcasecmp(a->realm, realm))
25863          break;
25864    }
25865 
25866    return a;
25867 }

static int find_sdp ( struct sip_request *  req  )  [static]

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

Parameters:
req the SIP request to process
Returns:
1 if SDP found, 0 if not found
Also updates req->sdp_start and req->sdp_count to indicate where the SDP lives in the message body.

Definition at line 8117 of file chan_sip.c.

References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, get_header(), LOG_WARNING, strcasestr(), and TRUE.

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

08118 {
08119    const char *content_type;
08120    const char *content_length;
08121    const char *search;
08122    char *boundary;
08123    unsigned int x;
08124    int boundaryisquoted = FALSE;
08125    int found_application_sdp = FALSE;
08126    int found_end_of_headers = FALSE;
08127 
08128    content_length = get_header(req, "Content-Length");
08129 
08130    if (!ast_strlen_zero(content_length)) {
08131       if (sscanf(content_length, "%30u", &x) != 1) {
08132          ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length);
08133          return 0;
08134       }
08135 
08136       /* Content-Length of zero means there can't possibly be an
08137          SDP here, even if the Content-Type says there is */
08138       if (x == 0)
08139          return 0;
08140    }
08141 
08142    content_type = get_header(req, "Content-Type");
08143 
08144    /* if the body contains only SDP, this is easy */
08145    if (!strncasecmp(content_type, "application/sdp", 15)) {
08146       req->sdp_start = 0;
08147       req->sdp_count = req->lines;
08148       return req->lines ? 1 : 0;
08149    }
08150 
08151    /* if it's not multipart/mixed, there cannot be an SDP */
08152    if (strncasecmp(content_type, "multipart/mixed", 15))
08153       return 0;
08154 
08155    /* if there is no boundary marker, it's invalid */
08156    if ((search = strcasestr(content_type, ";boundary=")))
08157       search += 10;
08158    else if ((search = strcasestr(content_type, "; boundary=")))
08159       search += 11;
08160    else
08161       return 0;
08162 
08163    if (ast_strlen_zero(search))
08164       return 0;
08165 
08166    /* If the boundary is quoted with ", remove quote */
08167    if (*search == '\"')  {
08168       search++;
08169       boundaryisquoted = TRUE;
08170    }
08171 
08172    /* make a duplicate of the string, with two extra characters
08173       at the beginning */
08174    boundary = ast_strdupa(search - 2);
08175    boundary[0] = boundary[1] = '-';
08176    /* Remove final quote */
08177    if (boundaryisquoted)
08178       boundary[strlen(boundary) - 1] = '\0';
08179 
08180    /* search for the boundary marker, the empty line delimiting headers from
08181       sdp part and the end boundry if it exists */
08182 
08183    for (x = 0; x < (req->lines); x++) {
08184       const char *line = REQ_OFFSET_TO_STR(req, line[x]);
08185       if (!strncasecmp(line, boundary, strlen(boundary))){
08186          if (found_application_sdp && found_end_of_headers) {
08187             req->sdp_count = (x - 1) - req->sdp_start;
08188             return 1;
08189          }
08190          found_application_sdp = FALSE;
08191       }
08192       if (!strcasecmp(line, "Content-Type: application/sdp"))
08193          found_application_sdp = TRUE;
08194       
08195       if (ast_strlen_zero(line)) {
08196          if (found_application_sdp && !found_end_of_headers){
08197             req->sdp_start = x;
08198             found_end_of_headers = TRUE;
08199          }
08200       }
08201    }
08202    if (found_application_sdp && found_end_of_headers) {
08203       req->sdp_count = x - req->sdp_start;
08204       return TRUE;
08205    }
08206    return FALSE;
08207 }

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

Definition at line 1635 of file chan_sip.c.

References ast_cc_agent_callback(), and find_by_notify_uri_helper().

Referenced by cc_esc_publish_handler(), and get_destination().

01636 {
01637    struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_notify_uri_helper, (char *)uri, "SIP");
01638    return agent;
01639 }

static struct ast_cc_agent* find_sip_cc_agent_by_original_callid ( struct sip_pvt *  pvt  )  [static]

Definition at line 1665 of file chan_sip.c.

References ast_cc_agent_callback(), and find_by_callid_helper().

Referenced by add_cc_call_info_to_response().

01666 {
01667    struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_callid_helper, pvt, "SIP");
01668    return agent;
01669 }

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

Definition at line 1650 of file chan_sip.c.

References ast_cc_agent_callback(), and find_by_subscribe_uri_helper().

Referenced by handle_cc_subscribe().

01651 {
01652    struct ast_cc_agent *agent = ast_cc_agent_callback(0, find_by_subscribe_uri_helper, (char *)uri, "SIP");
01653    return agent;
01654 }

static int find_sip_method ( const char *  msg  )  [static]

find_sip_method: Find SIP method from header

Definition at line 3080 of file chan_sip.c.

References ARRAY_LEN, ast_strlen_zero(), cfsip_methods::id, method_match(), and sip_methods.

Referenced by __sip_pretend_ack(), handle_request_do(), handle_response(), mark_parsed_methods(), and sip_hangup().

03081 {
03082    int i, res = 0;
03083    
03084    if (ast_strlen_zero(msg)) {
03085       return 0;
03086    }
03087    for (i = 1; i < ARRAY_LEN(sip_methods) && !res; i++) {
03088       if (method_match(i, msg)) {
03089          res = sip_methods[i].id;
03090       }
03091    }
03092    return res;
03093 }

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

Definition at line 1863 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by handle_cc_notify(), and handle_response().

01864 {
01865    struct sip_monitor_instance *monitor_instance = obj;
01866    return monitor_instance->subscription_pvt == arg ? CMP_MATCH | CMP_STOP : 0;
01867 }

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

Definition at line 1869 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by cc_handle_publish_error().

01870 {
01871    struct sip_monitor_instance *monitor_instance = obj;
01872    return monitor_instance->suspension_entry == arg ? CMP_MATCH | CMP_STOP : 0;
01873 }

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

Definition at line 890 of file chan_sip.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.

Referenced by create_epa_entry().

00891 {
00892    const struct epa_backend *backend = NULL;
00893 
00894    AST_LIST_LOCK(&epa_static_data_list);
00895    AST_LIST_TRAVERSE(&epa_static_data_list, backend, next) {
00896       if (!strcmp(backend->static_data->name, event_package)) {
00897          break;
00898       }
00899    }
00900    AST_LIST_UNLOCK(&epa_static_data_list);
00901    return backend ? backend->static_data : NULL;
00902 }

static struct cfsubscription_types * find_subscription_type ( enum subscriptiontype  subtype  )  [static]

Find subscription type in array.

Definition at line 17398 of file chan_sip.c.

References ARRAY_LEN, subscription_types, and type.

Referenced by transmit_state_notify().

17399 {
17400    int i;
17401 
17402    for (i = 1; i < ARRAY_LEN(subscription_types); i++) {
17403       if (subscription_types[i].type == subtype) {
17404          return &subscription_types[i];
17405       }
17406    }
17407    return &subscription_types[0];
17408 }

static void free_old_route ( struct sip_route *  route  )  [static]

Remove route from route list.

Definition at line 13440 of file chan_sip.c.

References ast_free.

Referenced by __sip_destroy(), and build_route().

13441 {
13442    struct sip_route *next;
13443 
13444    while (route) {
13445       next = route->next;
13446       ast_free(route);
13447       route = next;
13448    }
13449 }

static int func_check_sipdomain ( struct ast_channel *  chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

Dial plan function to check if domain is local.

Definition at line 18489 of file chan_sip.c.

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

18490 {
18491    if (ast_strlen_zero(data)) {
18492       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
18493       return -1;
18494    }
18495    if (check_sip_domain(data, NULL, 0))
18496       ast_copy_string(buf, data, len);
18497    else
18498       buf[0] = '\0';
18499    return 0;
18500 }

static int func_header_read ( struct ast_channel *  chan,
const char *  function,
char *  data,
char *  buf,
size_t  len 
) [static]

Read SIP header (dialplan function).

Definition at line 18430 of file chan_sip.c.

References __get_header(), args, AST_APP_ARG, ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), LOG_WARNING, ast_channel::tech, and ast_channel::tech_pvt.

18431 {
18432    struct sip_pvt *p;
18433    const char *content = NULL;
18434    AST_DECLARE_APP_ARGS(args,
18435       AST_APP_ARG(header);
18436       AST_APP_ARG(number);
18437    );
18438    int i, number, start = 0;
18439 
18440    if (ast_strlen_zero(data)) {
18441       ast_log(LOG_WARNING, "This function requires a header name.\n");
18442       return -1;
18443    }
18444 
18445    ast_channel_lock(chan);
18446    if (!IS_SIP_TECH(chan->tech)) {
18447       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
18448       ast_channel_unlock(chan);
18449       return -1;
18450    }
18451 
18452    AST_STANDARD_APP_ARGS(args, data);
18453    if (!args.number) {
18454       number = 1;
18455    } else {
18456       sscanf(args.number, "%30d", &number);
18457       if (number < 1)
18458          number = 1;
18459    }
18460 
18461    p = chan->tech_pvt;
18462 
18463    /* If there is no private structure, this channel is no longer alive */
18464    if (!p) {
18465       ast_channel_unlock(chan);
18466       return -1;
18467    }
18468 
18469    for (i = 0; i < number; i++)
18470       content = __get_header(&p->initreq, args.header, &start);
18471 
18472    if (ast_strlen_zero(content)) {
18473       ast_channel_unlock(chan);
18474       return -1;
18475    }
18476 
18477    ast_copy_string(buf, content, len);
18478    ast_channel_unlock(chan);
18479 
18480    return 0;
18481 }

static int function_sipchaninfo_read ( struct ast_channel *  chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

${SIPCHANINFO()} Dialplan function - reads sip channel data

Definition at line 18607 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log(), ast_sockaddr_stringify_addr(), LOG_WARNING, ast_channel::tech, and ast_channel::tech_pvt.

18608 {
18609    struct sip_pvt *p;
18610    static int deprecated = 0;
18611 
18612    *buf = 0;
18613    
18614    if (!data) {
18615       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
18616       return -1;
18617    }
18618 
18619    ast_channel_lock(chan);
18620    if (!IS_SIP_TECH(chan->tech)) {
18621       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
18622       ast_channel_unlock(chan);
18623       return -1;
18624    }
18625 
18626    if (deprecated++ % 20 == 0) {
18627       /* Deprecated in 1.6.1 */
18628       ast_log(LOG_WARNING, "SIPCHANINFO() is deprecated.  Please transition to using CHANNEL().\n");
18629    }
18630 
18631    p = chan->tech_pvt;
18632 
18633    /* If there is no private structure, this channel is no longer alive */
18634    if (!p) {
18635       ast_channel_unlock(chan);
18636       return -1;
18637    }
18638 
18639    if (!strcasecmp(data, "peerip")) {
18640       ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->sa), len);
18641    } else  if (!strcasecmp(data, "recvip")) {
18642       ast_copy_string(buf, ast_sockaddr_stringify_addr(&p->recv), len);
18643    } else  if (!strcasecmp(data, "from")) {
18644       ast_copy_string(buf, p->from, len);
18645    } else  if (!strcasecmp(data, "uri")) {
18646       ast_copy_string(buf, p->uri, len);
18647    } else  if (!strcasecmp(data, "useragent")) {
18648       ast_copy_string(buf, p->useragent, len);
18649    } else  if (!strcasecmp(data, "peername")) {
18650       ast_copy_string(buf, p->peername, len);
18651    } else if (!strcasecmp(data, "t38passthrough")) {
18652       if (p->t38.state == T38_DISABLED) {
18653          ast_copy_string(buf, "0", len);
18654       } else { /* T38 is offered or enabled in this call */
18655          ast_copy_string(buf, "1", len);
18656       }
18657    } else {
18658       ast_channel_unlock(chan);
18659       return -1;
18660    }
18661    ast_channel_unlock(chan);
18662 
18663    return 0;
18664 }

static int function_sippeer ( struct ast_channel *  chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

${SIPPEER()} Dialplan function - reads peer data

Todo:
Will be deprecated after 1.4

Definition at line 18508 of file chan_sip.c.

References ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_print_group(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_str_alloca, ast_test_flag, chanvar, FALSE, find_peer(), LOG_WARNING, ast_variable::name, ast_variable::next, peer_mailboxes_to_str(), peer_status(), strsep(), TRUE, unref_peer(), and ast_variable::value.

18509 {
18510    struct sip_peer *peer;
18511    char *colname;
18512 
18513    if ((colname = strchr(data, ':'))) {   /*! \todo Will be deprecated after 1.4 */
18514       static int deprecation_warning = 0;
18515       *colname++ = '\0';
18516       if (deprecation_warning++ % 10 == 0)
18517          ast_log(LOG_WARNING, "SIPPEER(): usage of ':' to separate arguments is deprecated.  Please use ',' instead.\n");
18518    } else if ((colname = strchr(data, ',')))
18519       *colname++ = '\0';
18520    else
18521       colname = "ip";
18522 
18523    if (!(peer = find_peer(data, NULL, TRUE, FINDPEERS, FALSE, 0)))
18524       return -1;
18525 
18526    if (!strcasecmp(colname, "ip")) {
18527       ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
18528    } else  if (!strcasecmp(colname, "port")) {
18529       snprintf(buf, len, "%d", ast_sockaddr_port(&peer->addr));
18530    } else  if (!strcasecmp(colname, "status")) {
18531       peer_status(peer, buf, len);
18532    } else  if (!strcasecmp(colname, "language")) {
18533       ast_copy_string(buf, peer->language, len);
18534    } else  if (!strcasecmp(colname, "regexten")) {
18535       ast_copy_string(buf, peer->regexten, len);
18536    } else  if (!strcasecmp(colname, "limit")) {
18537       snprintf(buf, len, "%d", peer->call_limit);
18538    } else  if (!strcasecmp(colname, "busylevel")) {
18539       snprintf(buf, len, "%d", peer->busy_level);
18540    } else  if (!strcasecmp(colname, "curcalls")) {
18541       snprintf(buf, len, "%d", peer->inUse);
18542    } else if (!strcasecmp(colname, "maxforwards")) {
18543       snprintf(buf, len, "%d", peer->maxforwards);
18544    } else  if (!strcasecmp(colname, "accountcode")) {
18545       ast_copy_string(buf, peer->accountcode, len);
18546    } else  if (!strcasecmp(colname, "callgroup")) {
18547       ast_print_group(buf, len, peer->callgroup);
18548    } else  if (!strcasecmp(colname, "pickupgroup")) {
18549       ast_print_group(buf, len, peer->pickupgroup);
18550    } else  if (!strcasecmp(colname, "useragent")) {
18551       ast_copy_string(buf, peer->useragent, len);
18552    } else  if (!strcasecmp(colname, "mailbox")) {
18553       struct ast_str *mailbox_str = ast_str_alloca(512);
18554       peer_mailboxes_to_str(&mailbox_str, peer);
18555       ast_copy_string(buf, mailbox_str->str, len);
18556    } else  if (!strcasecmp(colname, "context")) {
18557       ast_copy_string(buf, peer->context, len);
18558    } else  if (!strcasecmp(colname, "expire")) {
18559       snprintf(buf, len, "%d", peer->expire);
18560    } else  if (!strcasecmp(colname, "dynamic")) {
18561       ast_copy_string(buf, peer->host_dynamic ? "yes" : "no", len);
18562    } else  if (!strcasecmp(colname, "callerid_name")) {
18563       ast_copy_string(buf, peer->cid_name, len);
18564    } else  if (!strcasecmp(colname, "callerid_num")) {
18565       ast_copy_string(buf, peer->cid_num, len);
18566    } else  if (!strcasecmp(colname, "codecs")) {
18567       ast_getformatname_multiple(buf, len -1, peer->capability);
18568    } else if (!strcasecmp(colname, "encryption")) {
18569       snprintf(buf, len, "%d", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP));
18570    } else  if (!strncasecmp(colname, "chanvar[", 8)) {
18571       char *chanvar=colname + 8;
18572       struct ast_variable *v;
18573    
18574       chanvar = strsep(&chanvar, "]");
18575       for (v = peer->chanvars ; v ; v = v->next) {
18576          if (!strcasecmp(v->name, chanvar)) {
18577             ast_copy_string(buf, v->value, len);
18578          }
18579       }
18580    } else  if (!strncasecmp(colname, "codec[", 6)) {
18581       char *codecnum;
18582       format_t codec = 0;
18583       
18584       codecnum = colname + 6; /* move past the '[' */
18585       codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
18586       if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
18587          ast_copy_string(buf, ast_getformatname(codec), len);
18588       } else {
18589          buf[0] = '\0';
18590       }
18591    } else {
18592       buf[0] = '\0';
18593    }
18594 
18595    unref_peer(peer, "unref_peer from function_sippeer, just before return");
18596 
18597    return 0;
18598 }

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

Generate 32 byte random string for callid's etc.

Definition at line 7166 of file chan_sip.c.

References ast_random().

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

07167 {
07168    long val[4];
07169    int x;
07170 
07171    for (x=0; x<4; x++)
07172       val[x] = ast_random();
07173    snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
07174 
07175    return buf;
07176 }

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

Definition at line 7178 of file chan_sip.c.

References ast_copy_string(), ast_sockaddr_stringify(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), and generate_random_string().

Referenced by add_cc_call_info_to_response(), and transmit_cc_notify().

07179 {
07180    struct ast_str *uri = ast_str_alloca(size);
07181    ast_str_set(&uri, 0, "%s", pvt->socket.type == SIP_TRANSPORT_TLS ? "sips:" : "sip:");
07182    /* Here would be a great place to generate a UUID, but for now we'll
07183     * use the handy random string generation function we already have
07184     */
07185    ast_str_append(&uri, 0, "%s", generate_random_string(buf, size));
07186    ast_str_append(&uri, 0, "@%s", ast_sockaddr_stringify(&pvt->ourip));
07187    ast_copy_string(buf, ast_str_buffer(uri), size);
07188    return buf;
07189 }

int get_address_family_filter ( const struct ast_sockaddr *  addr  )  [static]

Helper for dns resolution to filter by address family.

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

Definition at line 24370 of file chan_sip.c.

References ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), and ast_sockaddr::ss.

Referenced by __sip_subscribe_mwi_do(), ast_sockaddr_resolve_first(), build_peer(), proxy_update(), realtime_peer(), and transmit_register().

24371 {
24372    if (ast_sockaddr_is_ipv6(addr) && ast_sockaddr_is_any(addr)) {
24373       return 0;
24374    }
24375 
24376    return addr->ss.ss_family;
24377 }

static int get_also_info ( struct sip_pvt *  p,
struct sip_request *  oreq 
) [static]

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

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

Definition at line 15004 of file chan_sip.c.

References ast_canmatch_extension(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_verbose, context, get_header(), LOG_WARNING, pbx_builtin_getvar_helper(), S_OR, sip_cfg, sip_debug_test_pvt(), SIP_PEDANTIC_DECODE, and sip_refer_allocate().

Referenced by handle_request_bye().

15005 {
15006    char tmp[256] = "", *c, *a;
15007    struct sip_request *req = oreq ? oreq : &p->initreq;
15008    struct sip_refer *referdata = NULL;
15009    const char *transfer_context = NULL;
15010    
15011    if (!p->refer && !sip_refer_allocate(p))
15012       return -1;
15013 
15014    referdata = p->refer;
15015 
15016    ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
15017    c = get_in_brackets(tmp);
15018 
15019    if (parse_uri(c, "sip:,sips:", &c, NULL, &a, NULL)) {
15020       ast_log(LOG_WARNING, "Huh?  Not a SIP header in Also: transfer (%s)?\n", c);
15021       return -1;
15022    }
15023    
15024    SIP_PEDANTIC_DECODE(c);
15025    SIP_PEDANTIC_DECODE(a);
15026 
15027    if (!ast_strlen_zero(a)) {
15028       ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain));
15029    }
15030 
15031    if (sip_debug_test_pvt(p))
15032       ast_verbose("Looking for %s in %s\n", c, p->context);
15033 
15034    if (p->owner)  /* Mimic behaviour in res_features.c */
15035       transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT");
15036 
15037    /* By default, use the context in the channel sending the REFER */
15038    if (ast_strlen_zero(transfer_context)) {
15039       transfer_context = S_OR(p->owner->macrocontext,
15040                S_OR(p->context, sip_cfg.default_context));
15041    }
15042    if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
15043       /* This is a blind transfer */
15044       ast_debug(1, "SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
15045       ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to));
15046       ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by));
15047       ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact));
15048       referdata->refer_call = dialog_unref(referdata->refer_call, "unreffing referdata->refer_call");
15049       /* Set new context */
15050       ast_string_field_set(p, context, transfer_context);
15051       return 0;
15052    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
15053       return 1;
15054    }
15055 
15056    return -1;
15057 }

static char* get_body ( struct sip_request *  req,
char *  name,
char  delimiter 
) [static]

Get a specific line from the message body.

Definition at line 6933 of file chan_sip.c.

References get_body_by_line(), and len().

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

06934 {
06935    int x;
06936    int len = strlen(name);
06937    char *r;
06938 
06939    for (x = 0; x < req->lines; x++) {
06940       r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[x]), name, len, delimiter);
06941       if (r[0] != '\0')
06942          return r;
06943    }
06944 
06945    return "";
06946 }

static char* get_body_by_line ( const char *  line,
const char *  name,
int  nameLen,
char  delimiter 
) [static]

Reads one line of SIP message body.

Definition at line 6878 of file chan_sip.c.

References ast_skip_blanks().

Referenced by get_body(), and get_sdp_iterate().

06879 {
06880    if (!strncasecmp(line, name, nameLen) && line[nameLen] == delimiter)
06881       return ast_skip_blanks(line + nameLen + 1);
06882 
06883    return "";
06884 }

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

Get cached MWI info.

Return values:
0 At least one message is waiting
1 no messages waiting

Definition at line 24513 of file chan_sip.c.

References ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, AST_LIST_TRAVERSE, mailbox, and S_OR.

Referenced by sip_send_mwi_to_peer().

24514 {
24515    struct sip_mailbox *mailbox;
24516 
24517    AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
24518       struct ast_event *event;
24519       event = ast_event_get_cached(AST_EVENT_MWI,
24520          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox,
24521          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"),
24522          AST_EVENT_IE_END);
24523       if (!event)
24524          continue;
24525       *new += ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
24526       *old += ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
24527       ast_event_destroy(event);
24528    }
24529 
24530    return (*new || *old) ? 0 : 1;
24531 }

static void get_crypto_attrib ( struct sip_srtp *  srtp,
const char **  a_crypto 
) [static]

Definition at line 10670 of file chan_sip.c.

References ast_log(), and LOG_WARNING.

Referenced by add_sdp().

10671 {
10672    /* Set encryption properties */
10673    if (srtp) {
10674       if (!srtp->crypto) {
10675          srtp->crypto = sdp_crypto_setup();
10676       }
10677       if (srtp->crypto && (sdp_crypto_offer(srtp->crypto) >= 0)) {
10678          *a_crypto = sdp_crypto_attrib(srtp->crypto);
10679       }
10680 
10681       if (!*a_crypto) {
10682          ast_log(LOG_WARNING, "No SRTP key management enabled\n");
10683       }
10684    }
10685 }

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

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

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

Definition at line 14573 of file chan_sip.c.

References ao2_ref, ast_canmatch_extension(), ast_cc_agent_recalling(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_get_hint(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose, check_sip_domain(), context, ast_cc_agent::core_id, ast_cc_agent::device_name, dummy(), exten, find_sip_cc_agent_by_notify_uri(), get_header(), global_flags, LOG_WARNING, ast_cc_agent::private_data, S_OR, sip_cfg, sip_debug_test_pvt(), sip_methods, SIP_PEDANTIC_DECODE, and cfsip_methods::text.

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

14574 {
14575    char tmp[256] = "", *uri, *domain, *dummy = NULL;
14576    char tmpf[256] = "", *from = NULL;
14577    struct sip_request *req;
14578    char *decoded_uri;
14579 
14580    req = oreq;
14581    if (!req) {
14582       req = &p->initreq;
14583    }
14584 
14585    /* Find the request URI */
14586    if (req->rlPart2)
14587       ast_copy_string(tmp, REQ_OFFSET_TO_STR(req, rlPart2), sizeof(tmp));
14588    
14589    uri = ast_strdupa(get_in_brackets(tmp));
14590 
14591    if (parse_uri(uri, "sip:,sips:", &uri, &dummy, &domain, NULL)) {
14592       ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", uri);
14593       return SIP_GET_DEST_INVALID_URI;
14594    }
14595 
14596    SIP_PEDANTIC_DECODE(domain);
14597    SIP_PEDANTIC_DECODE(uri);
14598 
14599    ast_string_field_set(p, domain, domain);
14600 
14601    /* Now find the From: caller ID and name */
14602    /* XXX Why is this done in get_destination? Isn't it already done?
14603       Needs to be checked
14604         */
14605    ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
14606    if (!ast_strlen_zero(tmpf)) {
14607       from = get_in_brackets(tmpf);
14608       if (parse_uri(from, "sip:,sips:", &from, NULL, &domain, NULL)) {
14609          ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", from);
14610          return SIP_GET_DEST_INVALID_URI;
14611       }
14612 
14613       SIP_PEDANTIC_DECODE(from);
14614       SIP_PEDANTIC_DECODE(domain);
14615 
14616       ast_string_field_set(p, fromdomain, domain);
14617    }
14618 
14619    if (!AST_LIST_EMPTY(&domain_list)) {
14620       char domain_context[AST_MAX_EXTENSION];
14621 
14622       domain_context[0] = '\0';
14623       if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
14624          if (!sip_cfg.allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
14625             ast_debug(1, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
14626             return SIP_GET_DEST_REFUSED;
14627          }
14628       }
14629       /* If we don't have a peer (i.e. we're a guest call),
14630        * overwrite the original context */
14631       if (!ast_test_flag(&p->flags[1], SIP_PAGE2_HAVEPEERCONTEXT) && !ast_strlen_zero(domain_context)) {
14632          ast_string_field_set(p, context, domain_context);
14633       }
14634    }
14635 
14636    /* If the request coming in is a subscription and subscribecontext has been specified use it */
14637    if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) {
14638       ast_string_field_set(p, context, p->subscribecontext);
14639    }
14640 
14641    if (sip_debug_test_pvt(p)) {
14642       ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
14643    }
14644 
14645    /* Since extensions.conf can have unescaped characters, try matching a
14646     * decoded uri in addition to the non-decoded uri. */
14647    decoded_uri = ast_strdupa(uri);
14648    ast_uri_decode(decoded_uri);
14649 
14650    /* If this is a subscription we actually just need to see if a hint exists for the extension */
14651    if (req->method == SIP_SUBSCRIBE) {
14652       char hint[AST_MAX_EXTENSION];
14653       int which = 0;
14654       if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, uri) ||
14655           (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, decoded_uri) && (which = 1))) {
14656          if (!oreq) {
14657             ast_string_field_set(p, exten, which ? decoded_uri : uri);
14658          }
14659          return SIP_GET_DEST_EXTEN_FOUND;
14660       } else {
14661          return SIP_GET_DEST_EXTEN_NOT_FOUND;
14662       }
14663    } else {
14664       struct ast_cc_agent *agent;
14665       int which = 0;
14666       /* Check the dialplan for the username part of the request URI,
14667          the domain will be stored in the SIPDOMAIN variable
14668          Return 0 if we have a matching extension */
14669       if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) ||
14670           (ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) && (which = 1)) ||
14671           !strcmp(decoded_uri, ast_pickup_ext())) {
14672          if (!oreq) {
14673             ast_string_field_set(p, exten, which ? decoded_uri : uri);
14674          }
14675          return SIP_GET_DEST_EXTEN_FOUND;
14676       } else if ((agent = find_sip_cc_agent_by_notify_uri(tmp))) {
14677          struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
14678          /* This is a CC recall. We can set p's extension to the exten from
14679           * the original INVITE
14680           */
14681          ast_string_field_set(p, exten, agent_pvt->original_exten);
14682          /* And we need to let the CC core know that the caller is attempting
14683           * his recall
14684           */
14685          ast_cc_agent_recalling(agent->core_id, "SIP caller %s is attempting recall",
14686                agent->device_name);
14687          if (cc_recall_core_id) {
14688             *cc_recall_core_id = agent->core_id;
14689          }
14690          ao2_ref(agent, -1);
14691          return SIP_GET_DEST_EXTEN_FOUND;
14692       }
14693    }
14694 
14695    /* Return 1 for pickup extension or overlap dialling support (if we support it) */
14696    if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) &&
14697        ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))) ||
14698        !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri))) {
14699       return SIP_GET_DEST_PICKUP_EXTEN_FOUND;
14700    }
14701 
14702    return SIP_GET_DEST_EXTEN_NOT_FOUND;
14703 }

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

Extract domain from SIP To/From header.

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

Definition at line 10177 of file chan_sip.c.

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

Referenced by get_realm().

10178 {
10179    char tmpf[256];
10180    char *a, *from;
10181 
10182    *domain = '\0';
10183    ast_copy_string(tmpf, str, sizeof(tmpf));
10184    from = get_in_brackets(tmpf);
10185    if (!ast_strlen_zero(from)) {
10186       if (strncasecmp(from, "sip:", 4)) {
10187          ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
10188          return -1;
10189       }
10190       from += 4;
10191    } else
10192       from = NULL;
10193 
10194    if (from) {
10195       int bracket = 0;
10196 
10197       /* Strip any params or options from user */
10198       if ((a = strchr(from, ';')))
10199          *a = '\0';
10200       /* Strip port from domain if present */
10201       for (a = from; *a != '\0'; ++a) {
10202          if (*a == ':' && bracket == 0) {
10203             *a = '\0';
10204             break;
10205          } else if (*a == '[') {
10206             ++bracket;
10207          } else if (*a == ']') {
10208             --bracket;
10209          }
10210       }
10211       if ((a = strchr(from, '@'))) {
10212          *a = '\0';
10213          ast_copy_string(domain, a + 1, len);
10214       } else
10215          ast_copy_string(domain, from, len);
10216    }
10217 
10218    return ast_strlen_zero(domain);
10219 }

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

Definition at line 984 of file chan_sip.c.

References ARRAY_LEN, event_state_compositors, and name.

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

00984                                                                                 {
00985    int i;
00986    for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
00987       if (!strcasecmp(event_package, event_state_compositors[i].name)) {
00988          return &event_state_compositors[i];
00989       }
00990    }
00991    return NULL;
00992 }

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

Definition at line 994 of file chan_sip.c.

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

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

00994                                                                                                         {
00995    struct sip_esc_entry *entry;
00996    struct sip_esc_entry finder;
00997 
00998    ast_copy_string(finder.entity_tag, entity_tag, sizeof(finder.entity_tag));
00999 
01000    entry = ao2_find(esc->compositor, &finder, OBJ_POINTER);
01001 
01002    return entry;
01003 }

static const char * get_header ( const struct sip_request *  req,
const char *  name 
) [static]

Get header from SIP request.

Returns:
Always return something, so don't check for NULL because it won't happen :-)

Definition at line 7026 of file chan_sip.c.

References __get_header().

07027 {
07028    int start = 0;
07029    return __get_header(req, name, &start);
07030 }

static struct ast_variable * get_insecure_variable_from_config ( struct ast_config *  config  )  [static]

Definition at line 4531 of file chan_sip.c.

References ast_category_browse(), ast_category_root(), ast_test_flag, ast_variable_retrieve(), ast_flags::flags, set_insecure_flags(), and var.

04532 {
04533    struct ast_variable *var = NULL;
04534    struct ast_flags flags = {0};
04535    char *cat = NULL;
04536    const char *insecure;
04537    while ((cat = ast_category_browse(cfg, cat))) {
04538       insecure = ast_variable_retrieve(cfg, cat, "insecure");
04539       set_insecure_flags(&flags, insecure, -1);
04540       if (ast_test_flag(&flags, SIP_INSECURE_PORT)) {
04541          var = ast_category_root(cfg, cat);
04542          break;
04543       }
04544    }
04545    return var;
04546 }

static int get_ip_and_port_from_sdp ( struct sip_request *  req,
const enum media_type  media,
struct ast_sockaddr *  addr 
) [static]

Definition at line 8239 of file chan_sip.c.

References ast_log(), ast_sockaddr_resolve_first_af(), ast_strlen_zero(), get_sdp_iterate(), len(), and LOG_WARNING.

Referenced by handle_request_invite().

08240 {
08241    const char *m;
08242    const char *c;
08243    int miterator = req->sdp_start;
08244    int citerator = req->sdp_start;
08245    int x = 0;
08246    int numberofports;
08247    int len;
08248    int af;
08249    char proto[4], host[258] = ""; /*Initialize to empty so we will know if we have any input */
08250 
08251    c = get_sdp_iterate(&citerator, req, "c");
08252    if (sscanf(c, "IN %3s %256s", proto, host) != 2) {
08253          ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
08254          /* Continue since there may be a valid host in a c= line specific to the audio stream */
08255    }
08256    /* We only want the m and c lines for audio */
08257    for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) {
08258       if ((media == SDP_AUDIO && ((sscanf(m, "audio %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
08259           (sscanf(m, "audio %30u RTP/AVP %n", &x, &len) == 1 && len > 0))) ||
08260          (media == SDP_VIDEO && ((sscanf(m, "video %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
08261           (sscanf(m, "video %30u RTP/AVP %n", &x, &len) == 1 && len > 0)))) {
08262          /* See if there's a c= line for this media stream.
08263           * XXX There is no guarantee that we'll be grabbing the c= line for this
08264           * particular media stream here. However, this is the same logic used in process_sdp.
08265           */
08266          c = get_sdp_iterate(&citerator, req, "c");
08267          if (!ast_strlen_zero(c)) {
08268             sscanf(c, "IN %3s %256s", proto, host);
08269          }
08270          break;
08271       }
08272    }
08273 
08274    if (!strcmp("IP4", proto)) {
08275       af = AF_INET;
08276    } else if (!strcmp("IP6", proto)) {
08277       af = AF_INET6;
08278    } else {
08279       ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto);
08280       return -1;
08281    }
08282 
08283    if (ast_strlen_zero(host) || x == 0) {
08284       ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video");
08285       return -1;
08286    }
08287 
08288    if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) {
08289       ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video");
08290       return -1;
08291    }
08292 
08293    return 0;
08294 }

static int get_msg_text ( char *  buf,
int  len,
struct sip_request *  req,
int  addnewline 
) [static]

Get text out of a SIP MESSAGE packet.

Definition at line 15468 of file chan_sip.c.

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

15469 {
15470    int x;
15471    int y;
15472 
15473    buf[0] = '\0';
15474    /*XXX isn't strlen(buf) going to always be 0? */
15475    y = len - strlen(buf) - 5;
15476    if (y < 0)
15477       y = 0;
15478    for (x = 0; x < req->lines; x++) {
15479       const char *line = REQ_OFFSET_TO_STR(req, line[x]);
15480       strncat(buf, line, y); /* safe */
15481       y -= strlen(line) + 1;
15482       if (y < 0)
15483          y = 0;
15484       if (y != 0 && addnewline)
15485          strcat(buf, "\n"); /* safe */
15486    }
15487    return 0;
15488 }

static const char * get_name_from_variable ( struct ast_variable *  var,
const char *  newpeername 
) [static]

Definition at line 4548 of file chan_sip.c.

References ast_variable::name, ast_variable::next, ast_variable::value, and var.

04549 {
04550    struct ast_variable *tmp;
04551    for (tmp = var; tmp; tmp = tmp->next) {
04552       if (!newpeername && !strcasecmp(tmp->name, "name"))
04553          newpeername = tmp->value;
04554    }
04555    return newpeername;
04556 }

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

Set all IP media addresses for this call.

Note:
called from add_sdp()

Definition at line 10577 of file chan_sip.c.

References ast_rtp_instance_get_local_address(), ast_sockaddr_cmp_addr(), ast_sockaddr_copy(), ast_sockaddr_is_any(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, and media_address.

Referenced by add_sdp().

10581 {
10582    int use_externip = 0;
10583 
10584    /* First, get our address */
10585    ast_rtp_instance_get_local_address(p->rtp, addr);
10586    if (p->vrtp) {
10587       ast_rtp_instance_get_local_address(p->vrtp, vaddr);
10588    }
10589    if (p->trtp) {
10590       ast_rtp_instance_get_local_address(p->trtp, taddr);
10591    }
10592 
10593    /* If our real IP differs from the local address returned by the RTP engine, use it. */
10594    /* The premise is that if we are already using that IP to communicate with the client, */
10595    /* we should be using it for RTP too. */
10596         use_externip = ast_sockaddr_cmp_addr(&p->ourip, addr);
10597 
10598    /* Now, try to figure out where we want them to send data */
10599    /* Is this a re-invite to move the media out, then use the original offer from caller  */
10600    if (!ast_sockaddr_isnull(&p->redirip)) {  /* If we have a redirection IP, use it */
10601       ast_sockaddr_copy(dest, &p->redirip);
10602    } else {
10603       /*
10604        * Audio Destination IP:
10605        *
10606        * 1. Specifically configured media address.
10607        * 2. Local address as specified by the RTP engine.
10608        * 3. The local IP as defined by chan_sip.
10609        *
10610        * Audio Destination Port:
10611        *
10612        * 1. Provided by the RTP engine.
10613        */
10614       ast_sockaddr_copy(dest,
10615               !ast_sockaddr_isnull(&media_address) ? &media_address :
10616               !ast_sockaddr_is_any(addr) && !use_externip ? addr    :
10617               &p->ourip);
10618       ast_sockaddr_set_port(dest, ast_sockaddr_port(addr));
10619    }
10620 
10621    if (needvideo) {
10622       /* Determine video destination */
10623       if (!ast_sockaddr_isnull(&p->vredirip)) {
10624          ast_sockaddr_copy(vdest, &p->vredirip);
10625       } else {
10626          /*
10627           * Video Destination IP:
10628           *
10629           * 1. Specifically configured media address.
10630           * 2. Local address as specified by the RTP engine.
10631           * 3. The local IP as defined by chan_sip.
10632           *
10633           * Video Destination Port:
10634           *
10635           * 1. Provided by the RTP engine.
10636           */
10637          ast_sockaddr_copy(vdest,
10638                  !ast_sockaddr_isnull(&media_address) ? &media_address :
10639                  !ast_sockaddr_is_any(vaddr) && !use_externip ? vaddr  :
10640                  &p->ourip);
10641          ast_sockaddr_set_port(vdest, ast_sockaddr_port(vaddr));
10642       }
10643    }
10644 
10645    if (needtext) {
10646       /* Determine text destination */
10647       if (!ast_sockaddr_isnull(&p->tredirip)) {
10648          ast_sockaddr_copy(tdest, &p->tredirip);
10649       } else {
10650          /*
10651           * Text Destination IP:
10652           *
10653           * 1. Specifically configured media address.
10654           * 2. Local address as specified by the RTP engine.
10655           * 3. The local IP as defined by chan_sip.
10656           *
10657           * Text Destination Port:
10658           *
10659           * 1. Provided by the RTP engine.
10660           */
10661          ast_sockaddr_copy(tdest,
10662                  !ast_sockaddr_isnull(&media_address) ? &media_address  :
10663                  !ast_sockaddr_is_any(taddr) && !use_externip ? taddr   :
10664                  &p->ourip);
10665          ast_sockaddr_set_port(tdest, ast_sockaddr_port(taddr));
10666       }
10667    }
10668 }

static int get_pai ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

Parse the parts of the P-Asserted-Identity header on an incoming packet. Returns 1 if a valid header is found and it is different from the current caller id.

Definition at line 14294 of file chan_sip.c.

References ast_copy_string(), ast_is_shrinkable_phonenumber(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, ast_set_callerid(), ast_shrink_phone_number(), ast_skip_blanks(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), cid_name, cid_num, get_header(), and global_shrinkcallerid.

Referenced by get_rpid().

14295 {
14296    char pai[256];
14297    char privacy[64];
14298    char *cid_num = "";
14299    char *cid_name = "";
14300    int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
14301    char *start = NULL, *end = NULL, *uri = NULL;
14302 
14303    ast_copy_string(pai, get_header(req, "P-Asserted-Identity"), sizeof(pai));
14304 
14305    if (ast_strlen_zero(pai)) {
14306       return 0;
14307    }
14308 
14309    start = pai;
14310    if (*start == '"') {
14311       *start++ = '\0';
14312       end = strchr(start, '"');
14313       if (!end) {
14314          return 0;
14315       }
14316       *end++ = '\0';
14317       cid_name = start;
14318       start = ast_skip_blanks(end);
14319    }
14320 
14321    if (*start != '<')
14322       return 0;
14323    /* At this point, 'start' points to the URI in brackets.
14324     * We need a copy so that our comparison to the anonymous
14325     * URI is valid.
14326     */
14327    uri = ast_strdupa(start);
14328    *start++ = '\0';
14329    end = strchr(start, '@');
14330    if (!end) {
14331       return 0;
14332    }
14333    *end++ = '\0';
14334    if (!strncasecmp(uri, "sip:anonymous@anonymous.invalid", 31)) {
14335       callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
14336       /*XXX Assume no change in cid_num. Perhaps it should be
14337        * blanked?
14338        */
14339       cid_num = (char *)p->cid_num;
14340    } else if (!strncasecmp(start, "sip:", 4)) {
14341       cid_num = start + 4;
14342       if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num))
14343          ast_shrink_phone_number(cid_num);
14344       start = end;
14345 
14346       end = strchr(start, '>');
14347       if (!end) {
14348          return 0;
14349       }
14350       *end = '\0';
14351    } else {
14352       return 0;
14353    }
14354 
14355    ast_copy_string(privacy, get_header(req, "Privacy"), sizeof(privacy));
14356    if (!ast_strlen_zero(privacy) && strncmp(privacy, "id", 2)) {
14357       callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
14358    }
14359 
14360    /* Only return true if the supplied caller id is different */
14361    if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres) {
14362       return 0;
14363    }
14364 
14365    ast_string_field_set(p, cid_num, cid_num);
14366    ast_string_field_set(p, cid_name, cid_name);
14367    p->callingpres = callingpres;
14368 
14369    if (p->owner) {
14370       ast_set_callerid(p->owner, cid_num, cid_name, NULL);
14371       p->owner->caller.id.name.presentation = callingpres;
14372       p->owner->caller.id.number.presentation = callingpres;
14373    }
14374 
14375    return 1;
14376 }

static void get_pidf_body ( struct sip_request *  req,
char *  pidf_body,
size_t  size 
) [static]

Definition at line 22844 of file chan_sip.c.

References ast_copy_string(), ast_str_alloca, ast_str_append(), ast_str_buffer(), and str.

Referenced by sip_pidf_validate().

22845 {
22846    int i;
22847    struct ast_str *str = ast_str_alloca(size);
22848    for (i = 0; i < req->lines; ++i) {
22849       ast_str_append(&str, 0, "%s", REQ_OFFSET_TO_STR(req, line[i]));
22850    }
22851    ast_copy_string(pidf_body, ast_str_buffer(str), size);
22852 }

static int get_rdnis ( struct sip_pvt *  p,
struct sip_request *  oreq,
char **  name,
char **  number,
int *  reason 
) [static]

Get referring dnis.

Definition at line 14479 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_strdup, ast_strip_quoted(), ast_strlen_zero(), ast_verbose, exten, get_header(), LOG_WARNING, pbx_builtin_setvar_helper(), sip_debug_test_pvt(), sip_reason_str_to_code(), sip_set_redirstr(), strcasestr(), and strsep().

Referenced by change_redirecting_information().

14480 {
14481    char tmp[256], *exten, *rexten, *rdomain, *rname = NULL;
14482    char *params, *reason_param = NULL;
14483    struct sip_request *req;
14484 
14485    req = oreq ? oreq : &p->initreq;
14486 
14487    ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
14488    if (ast_strlen_zero(tmp))
14489       return -1;
14490 
14491    if ((params = strchr(tmp, '>'))) {
14492       params = strchr(params, ';');
14493    }
14494 
14495    exten = get_in_brackets(tmp);
14496    if (!strncasecmp(exten, "sip:", 4)) {
14497       exten += 4;
14498    } else if (!strncasecmp(exten, "sips:", 5)) {
14499       exten += 5;
14500    } else {
14501       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", exten);
14502       return -1;
14503    }
14504 
14505    /* Get diversion-reason param if present */
14506    if (params) {
14507       *params = '\0';   /* Cut off parameters  */
14508       params++;
14509       while (*params == ';' || *params == ' ')
14510          params++;
14511       /* Check if we have a reason parameter */
14512       if ((reason_param = strcasestr(params, "reason="))) {
14513          char *end;
14514          reason_param+=7;
14515          if ((end = strchr(reason_param, ';'))) {
14516             *end = '\0';
14517          }
14518          /* Remove enclosing double-quotes */
14519          if (*reason_param == '"')
14520             ast_strip_quoted(reason_param, "\"", "\"");
14521          if (!ast_strlen_zero(reason_param)) {
14522             sip_set_redirstr(p, reason_param);
14523             if (p->owner) {
14524                pbx_builtin_setvar_helper(p->owner, "__PRIREDIRECTREASON", p->redircause);
14525                pbx_builtin_setvar_helper(p->owner, "__SIPREDIRECTREASON", reason_param);
14526             }
14527          }
14528       }
14529    }
14530 
14531    rdomain = exten;
14532    rexten = strsep(&rdomain, "@");  /* trim anything after @ */
14533    if (p->owner)
14534       pbx_builtin_setvar_helper(p->owner, "__SIPRDNISDOMAIN", rdomain);
14535 
14536    if (sip_debug_test_pvt(p))
14537       ast_verbose("RDNIS for this call is %s (reason %s)\n", exten, reason ? reason_param : "");
14538 
14539    /*ast_string_field_set(p, rdnis, rexten);*/
14540 
14541    if (*tmp == '\"') {
14542       char *end_quote;
14543       rname = tmp + 1;
14544       end_quote = strchr(rname, '\"');
14545       *end_quote = '\0';
14546    }
14547 
14548    if (number) {
14549       *number = ast_strdup(rexten);
14550    }
14551 
14552    if (name && rname) {
14553       *name = ast_strdup(rname);
14554    }
14555 
14556    if (reason && !ast_strlen_zero(reason_param)) {
14557       *reason = sip_reason_str_to_code(reason_param);
14558    }
14559 
14560    return 0;
14561 }

static void get_realm ( struct sip_pvt *  p,
const struct sip_request *  req 
) [static]

Choose realm based on From header and then To header or use globaly configured realm. Realm from From/To header should be listed among served domains in config file: domain=...

Definition at line 10225 of file chan_sip.c.

References AST_LIST_EMPTY, ast_string_field_set, ast_strlen_zero(), check_sip_domain(), get_domain(), get_header(), MAXHOSTNAMELEN, and sip_cfg.

Referenced by transmit_response_with_auth().

10226 {
10227    char domain[MAXHOSTNAMELEN];
10228 
10229    if (!ast_strlen_zero(p->realm))
10230       return;
10231 
10232    if (sip_cfg.domainsasrealm &&
10233        !AST_LIST_EMPTY(&domain_list))
10234    {
10235       /* Check From header first */
10236       if (!get_domain(get_header(req, "From"), domain, sizeof(domain))) {
10237          if (check_sip_domain(domain, NULL, 0)) {
10238             ast_string_field_set(p, realm, domain);
10239             return;
10240          }
10241       }
10242       /* Check To header */
10243       if (!get_domain(get_header(req, "To"), domain, sizeof(domain))) {
10244          if (check_sip_domain(domain, NULL, 0)) {
10245             ast_string_field_set(p, realm, domain);
10246             return;
10247          }
10248       }
10249    }
10250    
10251    /* Use default realm from config file */
10252    ast_string_field_set(p, realm, sip_cfg.realm);
10253 }

static int get_refer_info ( struct sip_pvt *  transferer,
struct sip_request *  outgoing_req 
) [static]

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

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

Definition at line 14797 of file chan_sip.c.

References ast_bridged_channel(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose, ast_channel::context, get_header(), LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), S_OR, sip_cfg, sip_debug_test_pvt(), SIP_PEDANTIC_DECODE, and strcasestr().

Referenced by handle_request_refer().

14798 {
14799 
14800    const char *p_referred_by = NULL;
14801    char *h_refer_to = NULL;
14802    char *h_referred_by = NULL;
14803    char *refer_to;
14804    const char *p_refer_to;
14805    char *referred_by_uri = NULL;
14806    char *ptr;
14807    struct sip_request *req = NULL;
14808    const char *transfer_context = NULL;
14809    struct sip_refer *referdata;
14810 
14811 
14812    req = outgoing_req;
14813    referdata = transferer->refer;
14814 
14815    if (!req) {
14816       req = &transferer->initreq;
14817    }
14818 
14819    p_refer_to = get_header(req, "Refer-To");
14820    if (ast_strlen_zero(p_refer_to)) {
14821       ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n");
14822       return -2;  /* Syntax error */
14823    }
14824    h_refer_to = ast_strdupa(p_refer_to);
14825    refer_to = get_in_brackets(h_refer_to);
14826    if (!strncasecmp(refer_to, "sip:", 4)) {
14827       refer_to += 4;       /* Skip sip: */
14828    } else if (!strncasecmp(refer_to, "sips:", 5)) {
14829       refer_to += 5;
14830    } else {
14831       ast_log(LOG_WARNING, "Can't transfer to non-sip: URI.  (Refer-to: %s)?\n", refer_to);
14832       return -3;
14833    }
14834 
14835    /* Get referred by header if it exists */
14836    p_referred_by = get_header(req, "Referred-By");
14837 
14838    /* Give useful transfer information to the dialplan */
14839    if (transferer->owner) {
14840       struct ast_channel *peer = ast_bridged_channel(transferer->owner);
14841       if (peer) {
14842          pbx_builtin_setvar_helper(peer, "SIPREFERRINGCONTEXT", transferer->context);
14843          pbx_builtin_setvar_helper(peer, "SIPREFERREDBYHDR", p_referred_by);
14844       }
14845    }
14846 
14847    if (!ast_strlen_zero(p_referred_by)) {
14848       char *lessthan;
14849       h_referred_by = ast_strdupa(p_referred_by);
14850 
14851       /* Store referrer's caller ID name */
14852       ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name));
14853       if ((lessthan = strchr(referdata->referred_by_name, '<'))) {
14854          *(lessthan - 1) = '\0'; /* Space */
14855       }
14856 
14857       referred_by_uri = get_in_brackets(h_referred_by);
14858 
14859       if (!strncasecmp(referred_by_uri, "sip:", 4)) {
14860          referred_by_uri += 4;      /* Skip sip: */
14861       } else if (!strncasecmp(referred_by_uri, "sips:", 5)) {
14862          referred_by_uri += 5;      /* Skip sips: */
14863       } else {
14864          ast_log(LOG_WARNING, "Huh?  Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
14865          referred_by_uri = NULL;
14866       }
14867    }
14868 
14869    /* Check for arguments in the refer_to header */
14870    if ((ptr = strcasestr(refer_to, "replaces="))) {
14871       char *to = NULL, *from = NULL;
14872       
14873       /* This is an attended transfer */
14874       referdata->attendedtransfer = 1;
14875       ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid));
14876       ast_uri_decode(referdata->replaces_callid);
14877       if ((ptr = strchr(referdata->replaces_callid, ';')))  /* Find options */ {
14878          *ptr++ = '\0';
14879       }
14880       
14881       if (ptr) {
14882          /* Find the different tags before we destroy the string */
14883          to = strcasestr(ptr, "to-tag=");
14884          from = strcasestr(ptr, "from-tag=");
14885       }
14886       
14887       /* Grab the to header */
14888       if (to) {
14889          ptr = to + 7;
14890          if ((to = strchr(ptr, '&'))) {
14891             *to = '\0';
14892          }
14893          if ((to = strchr(ptr, ';'))) {
14894             *to = '\0';
14895          }
14896          ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag));
14897       }
14898       
14899       if (from) {
14900          ptr = from + 9;
14901          if ((to = strchr(ptr, '&'))) {
14902             *to = '\0';
14903          }
14904          if ((to = strchr(ptr, ';'))) {
14905             *to = '\0';
14906          }
14907          ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag));
14908       }
14909 
14910       if (!strcmp(referdata->replaces_callid, transferer->callid) &&
14911          (!sip_cfg.pedanticsipchecking ||
14912          (!strcmp(referdata->replaces_callid_fromtag, transferer->theirtag) &&
14913          !strcmp(referdata->replaces_callid_totag, transferer->tag)))) {
14914             ast_log(LOG_WARNING, "Got an attempt to replace own Call-ID on %s\n", transferer->callid);
14915             return -4;
14916       }
14917 
14918       if (!sip_cfg.pedanticsipchecking) {
14919          ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid );
14920       } else {
14921          ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s F-tag: %s T-tag: %s\n", referdata->replaces_callid, referdata->replaces_callid_fromtag ? referdata->replaces_callid_fromtag : "<none>", referdata->replaces_callid_totag ? referdata->replaces_callid_totag : "<none>" );
14922       }
14923    }
14924    
14925    if ((ptr = strchr(refer_to, '@'))) {   /* Separate domain */
14926       char *urioption = NULL, *domain;
14927       int bracket = 0;
14928       *ptr++ = '\0';
14929 
14930       if ((urioption = strchr(ptr, ';'))) { /* Separate urioptions */
14931          *urioption++ = '\0';
14932       }
14933 
14934       domain = ptr;
14935 
14936       /* Remove :port */
14937       for (; *ptr != '\0'; ++ptr) {
14938          if (*ptr == ':' && bracket == 0) {
14939             *ptr = '\0';
14940             break;
14941          } else if (*ptr == '[') {
14942             ++bracket;
14943          } else if (*ptr == ']') {
14944             --bracket;
14945          }
14946       }
14947 
14948       SIP_PEDANTIC_DECODE(domain);
14949       SIP_PEDANTIC_DECODE(urioption);
14950 
14951       /* Save the domain for the dial plan */
14952       ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain));
14953       if (urioption) {
14954          ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption));
14955       }
14956    }
14957 
14958    if ((ptr = strchr(refer_to, ';')))  /* Remove options */
14959       *ptr = '\0';
14960 
14961    SIP_PEDANTIC_DECODE(refer_to);
14962    ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to));
14963    
14964    if (referred_by_uri) {
14965       if ((ptr = strchr(referred_by_uri, ';')))    /* Remove options */
14966          *ptr = '\0';
14967       SIP_PEDANTIC_DECODE(referred_by_uri);
14968       ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by));
14969    } else {
14970       referdata->referred_by[0] = '\0';
14971    }
14972 
14973    /* Determine transfer context */
14974    if (transferer->owner)  /* Mimic behaviour in res_features.c */
14975       transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT");
14976 
14977    /* By default, use the context in the channel sending the REFER */
14978    if (ast_strlen_zero(transfer_context)) {
14979       transfer_context = S_OR(transferer->owner->macrocontext,
14980                S_OR(transferer->context, sip_cfg.default_context));
14981    }
14982 
14983    ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context));
14984    
14985    /* Either an existing extension or the parking extension */
14986    if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) {
14987       if (sip_debug_test_pvt(transferer)) {
14988          ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri);
14989       }
14990       /* We are ready to transfer to the extension */
14991       return 0;
14992    }
14993    if (sip_debug_test_pvt(transferer))
14994       ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context);
14995 
14996    /* Failure, we can't find this extension */
14997    return -1;
14998 }

static int get_rpid ( struct sip_pvt *  p,
struct sip_request *  oreq 
) [static]

Get name, number and presentation from remote party id header, returns true if a valid header was found and it was different from the current caller id.

Definition at line 14382 of file chan_sip.c.

References ast_copy_string(), ast_is_shrinkable_phonenumber(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, ast_set_callerid(), ast_shrink_phone_number(), ast_skip_blanks(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, cid_name, cid_num, get_header(), get_pai(), and global_shrinkcallerid.

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

14383 {
14384    char tmp[256];
14385    struct sip_request *req;
14386    char *cid_num = "";
14387    char *cid_name = "";
14388    int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
14389    char *privacy = "";
14390    char *screen = "";
14391    char *start, *end;
14392 
14393    if (!ast_test_flag(&p->flags[0], SIP_TRUSTRPID))
14394       return 0;
14395    req = oreq;
14396    if (!req)
14397       req = &p->initreq;
14398    ast_copy_string(tmp, get_header(req, "Remote-Party-ID"), sizeof(tmp));
14399    if (ast_strlen_zero(tmp)) {
14400       return get_pai(p, req);
14401    }
14402 
14403    start = tmp;
14404    if (*start == '"') {
14405       *start++ = '\0';
14406       end = strchr(start, '"');
14407       if (!end)
14408          return 0;
14409       *end++ = '\0';
14410       cid_name = start;
14411       start = ast_skip_blanks(end);
14412    }
14413 
14414    if (*start != '<')
14415       return 0;
14416    *start++ = '\0';
14417    end = strchr(start, '@');
14418    if (!end)
14419       return 0;
14420    *end++ = '\0';
14421    if (strncasecmp(start, "sip:", 4))
14422       return 0;
14423    cid_num = start + 4;
14424    if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num))
14425       ast_shrink_phone_number(cid_num);
14426    start = end;
14427 
14428    end = strchr(start, '>');
14429    if (!end)
14430       return 0;
14431    *end++ = '\0';
14432    if (*end) {
14433       start = end;
14434       if (*start != ';')
14435          return 0;
14436       *start++ = '\0';
14437       while (!ast_strlen_zero(start)) {
14438          end = strchr(start, ';');
14439          if (end)
14440             *end++ = '\0';
14441          if (!strncasecmp(start, "privacy=", 8))
14442             privacy = start + 8;
14443          else if (!strncasecmp(start, "screen=", 7))
14444             screen = start + 7;
14445          start = end;
14446       }
14447 
14448       if (!strcasecmp(privacy, "full")) {
14449          if (!strcasecmp(screen, "yes"))
14450             callingpres = AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN;
14451          else if (!strcasecmp(screen, "no"))
14452             callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
14453       } else {
14454          if (!strcasecmp(screen, "yes"))
14455             callingpres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
14456          else if (!strcasecmp(screen, "no"))
14457             callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
14458       }
14459    }
14460 
14461    /* Only return true if the supplied caller id is different */
14462    if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres)
14463       return 0;
14464 
14465    ast_string_field_set(p, cid_num, cid_num);
14466    ast_string_field_set(p, cid_name, cid_name);
14467    p->callingpres = callingpres;
14468 
14469    if (p->owner) {
14470       ast_set_callerid(p->owner, cid_num, cid_name, NULL);
14471       p->owner->caller.id.name.presentation = callingpres;
14472       p->owner->caller.id.number.presentation = callingpres;
14473    }
14474 
14475    return 1;
14476 }

static const char * get_sdp_iterate ( int *  start,
struct sip_request *  req,
const char *  name 
) [static]

Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number.

Definition at line 6890 of file chan_sip.c.

References get_body_by_line(), and len().

06891 {
06892    int len = strlen(name);
06893 
06894    while (*start < (req->sdp_start + req->sdp_count)) {
06895       const char *r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[(*start)++]), name, len, '=');
06896       if (r[0] != '\0')
06897          return r;
06898    }
06899 
06900    /* if the line was not found, ensure that *start points past the SDP */
06901    (*start)++;
06902 
06903    return "";
06904 }

static char get_sdp_line ( int *  start,
int  stop,
struct sip_request *  req,
const char **  value 
) [static]

Fetches the next valid SDP line between the 'start' line (inclusive) and the 'stop' line (exclusive). Returns the type ('a', 'c', ...) and matching line in reference 'start' is updated with the next line number.

Definition at line 6911 of file chan_sip.c.

References ast_skip_blanks(), and type.

Referenced by process_sdp().

06912 {
06913    char type = '\0';
06914    const char *line = NULL;
06915 
06916    if (stop > (req->sdp_start + req->sdp_count)) {
06917       stop = req->sdp_start + req->sdp_count;
06918    }
06919 
06920    while (*start < stop) {
06921       line = REQ_OFFSET_TO_STR(req, line[(*start)++]);
06922       if (line[1] == '=') {
06923          type = line[0];
06924          *value = ast_skip_blanks(line + 2);
06925          break;
06926       }
06927    }
06928 
06929    return type;
06930 }

static struct sip_pvt * get_sip_pvt_byid_locked ( const char *  callid,
const char *  totag,
const char *  fromtag 
) [static]

Lock dialog lock and find matching pvt lock.

Returns:
a reference, remember to release it when done

Definition at line 14708 of file chan_sip.c.

References ao2_t_find, ast_channel_trylock, ast_debug, ast_strlen_zero(), dialogs, OBJ_POINTER, sip_cfg, sip_pvt_lock, sip_pvt_unlock, and TRUE.

Referenced by handle_request_invite(), and local_attended_transfer().

14709 {
14710    struct sip_pvt *sip_pvt_ptr;
14711    struct sip_pvt tmp_dialog = {
14712       .callid = callid,
14713    };
14714 
14715    if (totag) {
14716       ast_debug(4, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
14717    }
14718 
14719    /* Search dialogs and find the match */
14720    
14721    sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find of dialog in dialogs table");
14722    if (sip_pvt_ptr) {
14723       /* Go ahead and lock it (and its owner) before returning */
14724       sip_pvt_lock(sip_pvt_ptr);
14725       if (sip_cfg.pedanticsipchecking) {
14726          unsigned char frommismatch = 0, tomismatch = 0;
14727 
14728          if (ast_strlen_zero(fromtag)) {
14729             sip_pvt_unlock(sip_pvt_ptr);
14730             ast_debug(4, "Matched %s call for callid=%s - no from tag specified, pedantic check fails\n",
14731                  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid);
14732             return NULL;
14733          }
14734 
14735          if (ast_strlen_zero(totag)) {
14736             sip_pvt_unlock(sip_pvt_ptr);
14737             ast_debug(4, "Matched %s call for callid=%s - no to tag specified, pedantic check fails\n",
14738                  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid);
14739             return NULL;
14740          }
14741          /* RFC 3891
14742           * > 3.  User Agent Server Behavior: Receiving a Replaces Header
14743           * > The Replaces header contains information used to match an existing
14744           * > SIP dialog (call-id, to-tag, and from-tag).  Upon receiving an INVITE
14745           * > with a Replaces header, the User Agent (UA) attempts to match this
14746           * > information with a confirmed or early dialog.  The User Agent Server
14747           * > (UAS) matches the to-tag and from-tag parameters as if they were tags
14748           * > present in an incoming request.  In other words, the to-tag parameter
14749           * > is compared to the local tag, and the from-tag parameter is compared
14750           * > to the remote tag.
14751           *
14752           * Thus, the totag is always compared to the local tag, regardless if
14753           * this our call is an incoming or outgoing call.
14754           */
14755          frommismatch = !!strcmp(fromtag, sip_pvt_ptr->theirtag);
14756          tomismatch = !!strcmp(totag, sip_pvt_ptr->tag);
14757 
14758          if (frommismatch || tomismatch) {
14759             sip_pvt_unlock(sip_pvt_ptr);
14760             if (frommismatch) {
14761                ast_debug(4, "Matched %s call for callid=%s - pedantic from tag check fails; their tag is %s our tag is %s\n",
14762                     sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid,
14763                     fromtag, sip_pvt_ptr->theirtag);
14764             }
14765             if (tomismatch) {
14766                ast_debug(4, "Matched %s call for callid=%s - pedantic to tag check fails; their tag is %s our tag is %s\n",
14767                     sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid,
14768                     totag, sip_pvt_ptr->tag);
14769             }
14770             return NULL;
14771          }
14772       }
14773       
14774       if (totag)
14775          ast_debug(4, "Matched %s call - their tag is %s Our tag is %s\n",
14776                  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING",
14777                  sip_pvt_ptr->theirtag, sip_pvt_ptr->tag);
14778 
14779       /* deadlock avoidance... */
14780       while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) {
14781          sip_pvt_unlock(sip_pvt_ptr);
14782          usleep(1);
14783          sip_pvt_lock(sip_pvt_ptr);
14784       }
14785    }
14786    
14787    return sip_pvt_ptr;
14788 }

static const char* get_srv_protocol ( enum sip_transport  t  )  [inline, static]

Return protocol string for srv dns query.

Definition at line 3202 of file chan_sip.c.

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

03203 {
03204    switch (t) {
03205    case SIP_TRANSPORT_UDP:
03206       return "udp";
03207    case SIP_TRANSPORT_TLS:
03208    case SIP_TRANSPORT_TCP:
03209       return "tcp";
03210    }
03211 
03212    return "udp";
03213 }

static const char* get_srv_service ( enum sip_transport  t  )  [inline, static]

Return service string for srv dns query.

Definition at line 3216 of file chan_sip.c.

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

03217 {
03218    switch (t) {
03219    case SIP_TRANSPORT_TCP:
03220    case SIP_TRANSPORT_UDP:
03221       return "sip";
03222    case SIP_TRANSPORT_TLS:
03223       return "sips";
03224    }
03225    return "sip";
03226 }

static const char* get_transport ( enum sip_transport  t  )  [inline, static]

Return transport as string.

Definition at line 3187 of file chan_sip.c.

Referenced by _sip_show_peer(), ast_sip_ouraddrfor(), build_contact(), get_transport_pvt(), handle_request_do(), parse_moved_contact(), sip_show_settings(), sip_show_tcp(), and transmit_notify_with_mwi().

03188 {
03189    switch (t) {
03190    case SIP_TRANSPORT_UDP:
03191       return "UDP";
03192    case SIP_TRANSPORT_TCP:
03193       return "TCP";
03194    case SIP_TRANSPORT_TLS:
03195       return "TLS";
03196    }
03197 
03198    return "UNKNOWN";
03199 }

static const char* get_transport_list ( unsigned int  transports  )  [inline, static]

Return configuration of transports for a device.

Definition at line 3166 of file chan_sip.c.

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

03166                                                                       {
03167    switch (transports) {
03168       case SIP_TRANSPORT_UDP:
03169          return "UDP";
03170       case SIP_TRANSPORT_TCP:
03171          return "TCP";
03172       case SIP_TRANSPORT_TLS:
03173          return "TLS";
03174       case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TCP:
03175          return "TCP,UDP";
03176       case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TLS:
03177          return "TLS,UDP";
03178       case SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS:
03179          return "TLS,TCP";
03180       default:
03181          return transports ?
03182             "TLS,TCP,UDP" : "UNKNOWN"; 
03183    }
03184 }

static const char* get_transport_pvt ( struct sip_pvt *  p  )  [inline, static]

Return transport of dialog.

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

Definition at line 3234 of file chan_sip.c.

References get_transport(), and set_socket_transport().

Referenced by __sip_xmit(), and build_via().

03235 {
03236    if (p->outboundproxy && p->outboundproxy->transport) {
03237       set_socket_transport(&p->socket, p->outboundproxy->transport);
03238    }
03239 
03240    return get_transport(p->socket.type);
03241 }

static int get_transport_str2enum ( const char *  transport  )  [static]

Return int representing a bit field of transport types found in const char *transport.

Definition at line 3144 of file chan_sip.c.

References ast_strlen_zero().

Referenced by __set_address_from_contact(), and parse_register_contact().

03145 {
03146    int res = 0;
03147 
03148    if (ast_strlen_zero(transport)) {
03149       return res;
03150    }
03151 
03152    if (!strcasecmp(transport, "udp")) {
03153       res |= SIP_TRANSPORT_UDP;
03154    }
03155    if (!strcasecmp(transport, "tcp")) {
03156       res |= SIP_TRANSPORT_TCP;
03157    }
03158    if (!strcasecmp(transport, "tls")) {
03159       res |= SIP_TRANSPORT_TLS;
03160    }
03161 
03162    return res;
03163 }

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

Get tag from packet.

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

Definition at line 20592 of file chan_sip.c.

References ast_copy_string(), get_header(), strcasestr(), and strsep().

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

20593 {
20594    const char *thetag;
20595 
20596    if (!tagbuf)
20597       return NULL;
20598    tagbuf[0] = '\0';    /* reset the buffer */
20599    thetag = get_header(req, header);
20600    thetag = strcasestr(thetag, ";tag=");
20601    if (thetag) {
20602       thetag += 5;
20603       ast_copy_string(tagbuf, thetag, tagbufsize);
20604       return strsep(&tagbuf, ";");
20605    }
20606    return NULL;
20607 }

static int handle_cc_notify ( struct sip_pvt *  pvt,
struct sip_request *  req 
) [static]

Definition at line 20609 of file chan_sip.c.

References ao2_callback, ao2_ref, ast_cc_monitor_callee_available(), ast_cc_monitor_request_acked(), ast_string_field_set, ast_strlen_zero(), construct_pidf_body(), find_sip_monitor_instance_by_subscription_pvt(), get_body(), get_header(), sip_monitor_instances, status, transmit_publish(), and transmit_response().

Referenced by handle_request_notify().

20610 {
20611    struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0,
20612          find_sip_monitor_instance_by_subscription_pvt, pvt);
20613    const char *status = get_body(req, "cc-state", ':');
20614    struct cc_epa_entry *cc_entry;
20615    char *uri;
20616 
20617    if (!monitor_instance) {
20618       transmit_response(pvt, "400 Bad Request", req);
20619       return -1;
20620    }
20621 
20622    if (ast_strlen_zero(status)) {
20623       ao2_ref(monitor_instance, -1);
20624       transmit_response(pvt, "400 Bad Request", req);
20625       return -1;
20626    }
20627 
20628    if (!strcmp(status, "queued")) {
20629       /* We've been told that we're queued. This is the endpoint's way of telling
20630        * us that it has accepted our CC request. We need to alert the core of this
20631        * development
20632        */
20633       ast_cc_monitor_request_acked(monitor_instance->core_id, "SIP endpoint %s accepted request", monitor_instance->device_name);
20634       transmit_response(pvt, "200 OK", req);
20635       ao2_ref(monitor_instance, -1);
20636       return 0;
20637    }
20638 
20639    /* It's open! Yay! */
20640    uri = get_body(req, "cc-URI", ':');
20641    if (ast_strlen_zero(uri)) {
20642       uri = get_in_brackets((char *)get_header(req, "From"));
20643    }
20644 
20645    ast_string_field_set(monitor_instance, notify_uri, uri);
20646    if (monitor_instance->suspension_entry) {
20647       cc_entry = monitor_instance->suspension_entry->instance_data;
20648       if (cc_entry->current_state == CC_CLOSED) {
20649          /* If we've created a suspension entry and the current state is closed, then that means
20650           * we got a notice from the CC core earlier to suspend monitoring, but because this particular
20651           * call leg had not yet notified us that it was ready for recall, it meant that we
20652           * could not yet send a PUBLISH. Now, however, we can.
20653           */
20654          construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body,
20655                sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername);
20656          transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_INITIAL, monitor_instance->notify_uri);
20657       } else {
20658          ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available");
20659       }
20660    } else {
20661       ast_cc_monitor_callee_available(monitor_instance->core_id, "SIP monitored callee has become available");
20662    }
20663    ao2_ref(monitor_instance, -1);
20664    transmit_response(pvt, "200 OK", req);
20665 
20666    return 0;
20667 }

static int handle_cc_subscribe ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

Definition at line 23315 of file chan_sip.c.

References ao2_ref, ast_cc_agent_accept_request(), ast_cc_failed(), ast_log(), ast_strlen_zero(), ast_cc_agent::core_id, ast_cc_agent::device_name, find_sip_cc_agent_by_subscribe_uri(), get_header(), LOG_WARNING, ast_cc_agent::private_data, and transmit_response().

Referenced by handle_request_subscribe().

23316 {
23317    const char *uri = REQ_OFFSET_TO_STR(req, rlPart2);
23318    char *param_separator;
23319    struct ast_cc_agent *agent;
23320    struct sip_cc_agent_pvt *agent_pvt;
23321    const char *expires_str = get_header(req, "Expires");
23322    int expires = -1; /* Just need it to be non-zero */
23323 
23324    if (!ast_strlen_zero(expires_str)) {
23325       sscanf(expires_str, "%d", &expires);
23326    }
23327 
23328    if ((param_separator = strchr(uri, ';'))) {
23329       *param_separator = '\0';
23330    }
23331 
23332    if (!(agent = find_sip_cc_agent_by_subscribe_uri(uri))) {
23333       if (!expires) {
23334          /* Typically, if a 0 Expires reaches us and we can't find
23335           * the corresponding agent, it means that the CC transaction
23336           * has completed and so the calling side is just trying to
23337           * clean up its subscription. We'll just respond with a
23338           * 200 OK and be done with it
23339           */
23340          transmit_response(p, "200 OK", req);
23341          return 0;
23342       }
23343       ast_log(LOG_WARNING, "Invalid URI '%s' in CC subscribe\n", uri);
23344       transmit_response(p, "404 Not Found", req);
23345       return -1;
23346    }
23347 
23348    agent_pvt = agent->private_data;
23349 
23350    if (!expires) {
23351       /* We got sent a SUBSCRIBE and found an agent. This means that CC
23352        * is being canceled.
23353        */
23354       ast_cc_failed(agent->core_id, "CC is being canceled by %s", agent->device_name);
23355       transmit_response(p, "200 OK", req);
23356       ao2_ref(agent, -1);
23357       return 0;
23358    }
23359 
23360    agent_pvt->subscribe_pvt = dialog_ref(p, "SIP CC agent gains reference to subscription dialog");
23361    ast_cc_agent_accept_request(agent->core_id, "SIP caller %s has requested CC via SUBSCRIBE",
23362          agent->device_name);
23363    p->subscribed = CALL_COMPLETION;
23364 
23365    /* We don't send a response here. That is done in the agent's ack callback or in the
23366     * agent destructor, should a failure occur before we have responded
23367     */
23368    ao2_ref(agent, -1);
23369    return 0;
23370 }

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

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

Parameters:
flags array of two struct ast_flags
mask array of two struct ast_flags
v linked list of config variables to process
Returns:
non-zero if any config options were handled, zero otherwise

Definition at line 25574 of file chan_sip.c.

References ast_clear_flag, ast_copy_string(), ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_true(), ast_variable::lineno, LOG_WARNING, ast_variable::name, set_insecure_flags(), strsep(), ast_variable::value, and word.

Referenced by build_peer().

25575 {
25576    int res = 1;
25577 
25578    if (!strcasecmp(v->name, "trustrpid")) {
25579       ast_set_flag(&mask[0], SIP_TRUSTRPID);
25580       ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
25581    } else if (!strcasecmp(v->name, "sendrpid")) {
25582       ast_set_flag(&mask[0], SIP_SENDRPID);
25583       if (!strcasecmp(v->value, "pai")) {
25584          ast_set_flag(&flags[0], SIP_SENDRPID_PAI);
25585       } else if (!strcasecmp(v->value, "rpid")) {
25586          ast_set_flag(&flags[0], SIP_SENDRPID_RPID);
25587       } else if (ast_true(v->value)) {
25588          ast_set_flag(&flags[0], SIP_SENDRPID_RPID);
25589       }
25590    } else if (!strcasecmp(v->name, "rpid_update")) {
25591       ast_set_flag(&mask[1], SIP_PAGE2_RPID_UPDATE);
25592       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_UPDATE);
25593    } else if (!strcasecmp(v->name, "rpid_immediate")) {
25594       ast_set_flag(&mask[1], SIP_PAGE2_RPID_IMMEDIATE);
25595       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_IMMEDIATE);
25596    } else if (!strcasecmp(v->name, "g726nonstandard")) {
25597       ast_set_flag(&mask[0], SIP_G726_NONSTANDARD);
25598       ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD);
25599    } else if (!strcasecmp(v->name, "useclientcode")) {
25600       ast_set_flag(&mask[0], SIP_USECLIENTCODE);
25601       ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
25602    } else if (!strcasecmp(v->name, "dtmfmode")) {
25603       ast_set_flag(&mask[0], SIP_DTMF);
25604       ast_clear_flag(&flags[0], SIP_DTMF);
25605       if (!strcasecmp(v->value, "inband"))
25606          ast_set_flag(&flags[0], SIP_DTMF_INBAND);
25607       else if (!strcasecmp(v->value, "rfc2833"))
25608          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
25609       else if (!strcasecmp(v->value, "info"))
25610          ast_set_flag(&flags[0], SIP_DTMF_INFO);
25611       else if (!strcasecmp(v->value, "shortinfo"))
25612          ast_set_flag(&flags[0], SIP_DTMF_SHORTINFO);
25613       else if (!strcasecmp(v->value, "auto"))
25614          ast_set_flag(&flags[0], SIP_DTMF_AUTO);
25615       else {
25616          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
25617          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
25618       }
25619    } else if (!strcasecmp(v->name, "nat")) {
25620       ast_set_flag(&mask[0], SIP_NAT_FORCE_RPORT);
25621       if (!strcasecmp(v->value, "no")) {
25622          ast_clear_flag(&flags[0], SIP_NAT_FORCE_RPORT);
25623       } else if (!strcasecmp(v->value, "force_rport")) {
25624          ast_set_flag(&flags[0], SIP_NAT_FORCE_RPORT);
25625       } else if (!strcasecmp(v->value, "yes")) {
25626          ast_set_flag(&flags[0], SIP_NAT_FORCE_RPORT);
25627          ast_set_flag(&mask[1], SIP_PAGE2_SYMMETRICRTP);
25628          ast_set_flag(&flags[1], SIP_PAGE2_SYMMETRICRTP);
25629       } else if (!strcasecmp(v->value, "comedia")) {
25630          ast_clear_flag(&flags[0], SIP_NAT_FORCE_RPORT);
25631          ast_set_flag(&mask[1], SIP_PAGE2_SYMMETRICRTP);
25632          ast_set_flag(&flags[1], SIP_PAGE2_SYMMETRICRTP);
25633       }
25634    } else if (!strcasecmp(v->name, "directmedia") || !strcasecmp(v->name, "canreinvite")) {
25635       ast_set_flag(&mask[0], SIP_REINVITE);
25636       ast_clear_flag(&flags[0], SIP_REINVITE);
25637       if (ast_true(v->value)) {
25638          ast_set_flag(&flags[0], SIP_DIRECT_MEDIA | SIP_DIRECT_MEDIA_NAT);
25639       } else if (!ast_false(v->value)) {
25640          char buf[64];
25641          char *word, *next = buf;
25642 
25643          ast_copy_string(buf, v->value, sizeof(buf));
25644          while ((word = strsep(&next, ","))) {
25645             if (!strcasecmp(word, "update")) {
25646                ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_DIRECT_MEDIA);
25647             } else if (!strcasecmp(word, "nonat")) {
25648                ast_set_flag(&flags[0], SIP_DIRECT_MEDIA);
25649                ast_clear_flag(&flags[0], SIP_DIRECT_MEDIA_NAT);
25650             } else {
25651                ast_log(LOG_WARNING, "Unknown directmedia mode '%s' on line %d\n", v->value, v->lineno);
25652             }
25653          }
25654       }
25655    } else if (!strcasecmp(v->name, "insecure")) {
25656       ast_set_flag(&mask[0], SIP_INSECURE);
25657       ast_clear_flag(&flags[0], SIP_INSECURE);
25658       set_insecure_flags(&flags[0], v->value, v->lineno);   
25659    } else if (!strcasecmp(v->name, "progressinband")) {
25660       ast_set_flag(&mask[0], SIP_PROG_INBAND);
25661       ast_clear_flag(&flags[0], SIP_PROG_INBAND);
25662       if (ast_true(v->value))
25663          ast_set_flag(&flags[0], SIP_PROG_INBAND_YES);
25664       else if (strcasecmp(v->value, "never"))
25665          ast_set_flag(&flags[0], SIP_PROG_INBAND_NO);
25666    } else if (!strcasecmp(v->name, "promiscredir")) {
25667       ast_set_flag(&mask[0], SIP_PROMISCREDIR);
25668       ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR);
25669    } else if (!strcasecmp(v->name, "videosupport")) {
25670       if (!strcasecmp(v->value, "always")) {
25671          ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS);
25672          ast_set_flag(&flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS);
25673       } else {
25674          ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT);
25675          ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT);
25676       }
25677    } else if (!strcasecmp(v->name, "textsupport")) {
25678       ast_set_flag(&mask[1], SIP_PAGE2_TEXTSUPPORT);
25679       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_TEXTSUPPORT);
25680       res = 1;
25681    } else if (!strcasecmp(v->name, "allowoverlap")) {
25682       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP);
25683       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP);
25684    } else if (!strcasecmp(v->name, "allowsubscribe")) {
25685       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE);
25686       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE);
25687    } else if (!strcasecmp(v->name, "ignoresdpversion")) {
25688       ast_set_flag(&mask[1], SIP_PAGE2_IGNORESDPVERSION);
25689       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_IGNORESDPVERSION);
25690    } else if (!strcasecmp(v->name, "faxdetect")) {
25691       ast_set_flag(&mask[1], SIP_PAGE2_FAX_DETECT);
25692       if (ast_true(v->value)) {
25693          ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH);
25694       } else if (ast_false(v->value)) {
25695          ast_clear_flag(&flags[1], SIP_PAGE2_FAX_DETECT_BOTH);
25696       } else {
25697          char *buf = ast_strdupa(v->value);
25698          char *word, *next = buf;
25699 
25700          while ((word = strsep(&next, ","))) {
25701             if (!strcasecmp(word, "cng")) {
25702                ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_CNG);
25703             } else if (!strcasecmp(word, "t38")) {
25704                ast_set_flag(&flags[1], SIP_PAGE2_FAX_DETECT_T38);
25705             } else {
25706                ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
25707             }
25708          }
25709       }
25710    } else if (!strcasecmp(v->name, "rfc2833compensate")) {
25711       ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE);
25712       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE);
25713    } else if (!strcasecmp(v->name, "buggymwi")) {
25714       ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
25715       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
25716    } else
25717       res = 0;
25718 
25719    return res;
25720 }

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

Handle incoming SIP requests (methods).

Note:
This is where all incoming requests go first.

called with p and p->owner locked

Definition at line 23796 of file chan_sip.c.

References __get_header(), __sip_ack(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_debug, ast_log(), ast_random(), ast_skip_blanks(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_verbose, check_pendings(), debug, extract_uri(), find_sdp(), get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_publish(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_request_update(), handle_response(), cfsip_methods::id, len(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::name, pbx_builtin_setvar_helper(), process_sdp(), pvt_set_needdestroy(), sip_cfg, sip_debug_test_pvt(), sip_methods, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), cfsip_methods::text, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and transmit_response_with_retry_after().

Referenced by handle_request_do(), and process_request_queue().

23797 {
23798    /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
23799       relatively static */
23800    const char *cmd;
23801    const char *cseq;
23802    const char *useragent;
23803    const char *via;
23804    const char *callid;
23805    int via_pos = 0;
23806    int seqno;
23807    int len;
23808    int respid;
23809    int res = 0;
23810    int debug = sip_debug_test_pvt(p);
23811    const char *e;
23812    int error = 0;
23813    int oldmethod = p->method;
23814    int acked = 0;
23815 
23816    /* RFC 3261 - 8.1.1 A valid SIP request must contain To, From, CSeq, Call-ID and Via.
23817     * 8.2.6.2 Response must have To, From, Call-ID CSeq, and Via related to the request,
23818     * so we can check to make sure these fields exist for all requests and responses */
23819    cseq = get_header(req, "Cseq");
23820    cmd = REQ_OFFSET_TO_STR(req, header[0]);
23821    /* Save the via_pos so we can check later that responses only have 1 Via header */
23822    via = __get_header(req, "Via", &via_pos);
23823    /* This must exist already because we've called find_call by now */
23824    callid = get_header(req, "Call-ID");
23825 
23826    /* Must have Cseq */
23827    if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq) || ast_strlen_zero(via)) {
23828       ast_log(LOG_ERROR, "Dropping this SIP message with Call-ID '%s', it's incomplete.\n", callid);
23829       error = 1;
23830    }
23831    if (!error && sscanf(cseq, "%30d%n", &seqno, &len) != 1) {
23832       ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd);
23833       error = 1;
23834    }
23835    if (error) {
23836       if (!p->initreq.headers) { /* New call */
23837          pvt_set_needdestroy(p, "no headers");
23838       }
23839       return -1;
23840    }
23841    /* Get the command XXX */
23842 
23843    cmd = REQ_OFFSET_TO_STR(req, rlPart1);
23844    e = ast_skip_blanks(REQ_OFFSET_TO_STR(req, rlPart2));
23845 
23846    /* Save useragent of the client */
23847    useragent = get_header(req, "User-Agent");
23848    if (!ast_strlen_zero(useragent))
23849       ast_string_field_set(p, useragent, useragent);
23850 
23851    /* Find out SIP method for incoming request */
23852    if (req->method == SIP_RESPONSE) {  /* Response to our request */
23853       /* ignore means "don't do anything with it" but still have to
23854        * respond appropriately.
23855        * But in this case this is a response already, so we really
23856        * have nothing to do with this message, and even setting the
23857        * ignore flag is pointless.
23858        */
23859       if (ast_strlen_zero(e)) {
23860          return 0;
23861       }
23862       if (sscanf(e, "%30d %n", &respid, &len) != 1) {
23863          ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
23864          return 0;
23865       }
23866       if (respid <= 0) {
23867          ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid);
23868          return 0;
23869       }
23870       /* RFC 3261 - 8.1.3.3 If more than one Via header field value is present in a reponse
23871        * the UAC SHOULD discard the message. This is not perfect, as it will not catch multiple
23872        * headers joined with a comma. Fixing that would pretty much involve writing a new parser */
23873       if (!ast_strlen_zero(__get_header(req, "via", &via_pos))) {
23874          ast_log(LOG_WARNING, "Misrouted SIP response '%s' with Call-ID '%s', too many vias\n", e, callid);
23875          return 0;
23876       }
23877       if (p->ocseq && (p->ocseq < seqno)) {
23878          ast_debug(1, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq);
23879          return -1;
23880       } else {
23881          char causevar[256], causeval[256];
23882 
23883          if ((respid == 200) || ((respid >= 300) && (respid <= 399))) {
23884             extract_uri(p, req);
23885          }
23886 
23887          handle_response(p, respid, e + len, req, seqno);
23888 
23889          if (p->owner) {
23890             struct ast_channel *owner = p->owner;
23891 
23892             snprintf(causevar, sizeof(causevar), "MASTER_CHANNEL(HASH(SIP_CAUSE,%s))", owner->name);
23893             snprintf(causeval, sizeof(causeval), "SIP %s", REQ_OFFSET_TO_STR(req, rlPart2));
23894 
23895             ast_channel_ref(owner);
23896             sip_pvt_unlock(p);
23897             ast_channel_unlock(owner);
23898             *nounlock = 1;
23899             pbx_builtin_setvar_helper(owner, causevar, causeval);
23900             ast_channel_unref(owner);
23901             sip_pvt_lock(p);
23902          }
23903       }
23904       return 0;
23905    }
23906 
23907    /* New SIP request coming in
23908       (could be new request in existing SIP dialog as well...)
23909     */         
23910    
23911    p->method = req->method;   /* Find out which SIP method they are using */
23912    ast_debug(4, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd);
23913 
23914    if (p->icseq && (p->icseq > seqno) ) {
23915       if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) {
23916          ast_debug(2, "Got CANCEL or ACK on INVITE with transactions in between.\n");
23917       } else {
23918          ast_debug(1, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq);
23919          if (req->method == SIP_INVITE) {
23920             unsigned int ran = (ast_random() % 10) + 1;
23921             char seconds[4];
23922             snprintf(seconds, sizeof(seconds), "%u", ran);
23923             transmit_response_with_retry_after(p, "500 Server error", req, seconds);   /* respond according to RFC 3261 14.2 with Retry-After betwewn 0 and 10 */
23924          } else if (req->method != SIP_ACK) {
23925             transmit_response(p, "500 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
23926          }
23927          return -1;
23928       }
23929    } else if (p->icseq &&
23930          p->icseq == seqno &&
23931          req->method != SIP_ACK &&
23932          (p->method != SIP_CANCEL || p->alreadygone)) {
23933       /* ignore means "don't do anything with it" but still have to
23934          respond appropriately.  We do this if we receive a repeat of
23935          the last sequence number  */
23936       req->ignore = 1;
23937       ast_debug(3, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno);
23938    }
23939 
23940    /* RFC 3261 section 9. "CANCEL has no effect on a request to which a UAS has
23941     * already given a final response." */
23942    if (!p->pendinginvite && (req->method == SIP_CANCEL)) {
23943       transmit_response(p, "481 Call/Transaction Does Not Exist", req);
23944       return res;
23945    }
23946 
23947    if (seqno >= p->icseq)
23948       /* Next should follow monotonically (but not necessarily
23949          incrementally -- thanks again to the genius authors of SIP --
23950          increasing */
23951       p->icseq = seqno;
23952 
23953    /* Find their tag if we haven't got it */
23954    if (ast_strlen_zero(p->theirtag)) {
23955       char tag[128];
23956 
23957       gettag(req, "From", tag, sizeof(tag));
23958       ast_string_field_set(p, theirtag, tag);
23959    }
23960    snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd);
23961 
23962    if (sip_cfg.pedanticsipchecking) {
23963       /* If this is a request packet without a from tag, it's not
23964          correct according to RFC 3261  */
23965       /* Check if this a new request in a new dialog with a totag already attached to it,
23966          RFC 3261 - section 12.2 - and we don't want to mess with recovery  */
23967       if (!p->initreq.headers && req->has_to_tag) {
23968          /* If this is a first request and it got a to-tag, it is not for us */
23969          if (!req->ignore && req->method == SIP_INVITE) {
23970             transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req);
23971             /* Will cease to exist after ACK */
23972          } else if (req->method != SIP_ACK) {
23973             transmit_response(p, "481 Call/Transaction Does Not Exist", req);
23974             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23975          } else {
23976             ast_debug(1, "Got ACK for unknown dialog... strange.\n");
23977          }
23978          return res;
23979       }
23980    }
23981 
23982    if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY || p->method == SIP_PUBLISH)) {
23983       transmit_response(p, "400 Bad request", req);
23984       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23985       return -1;
23986    }
23987 
23988    /* Handle various incoming SIP methods in requests */
23989    switch (p->method) {
23990    case SIP_OPTIONS:
23991       res = handle_request_options(p, req, addr, e);
23992       break;
23993    case SIP_INVITE:
23994       res = handle_request_invite(p, req, debug, seqno, addr, recount, e, nounlock);
23995       break;
23996    case SIP_REFER:
23997       res = handle_request_refer(p, req, debug, seqno, nounlock);
23998       break;
23999    case SIP_CANCEL:
24000       res = handle_request_cancel(p, req);
24001       break;
24002    case SIP_BYE:
24003       res = handle_request_bye(p, req);
24004       break;
24005    case SIP_MESSAGE:
24006       res = handle_request_message(p, req);
24007       break;
24008    case SIP_PUBLISH:
24009       res = handle_request_publish(p, req, addr, seqno, e);
24010       break;
24011    case SIP_SUBSCRIBE:
24012       res = handle_request_subscribe(p, req, addr, seqno, e);
24013       break;
24014    case SIP_REGISTER:
24015       res = handle_request_register(p, req, addr, e);
24016       break;
24017    case SIP_INFO:
24018       if (req->debug)
24019          ast_verbose("Receiving INFO!\n");
24020       if (!req->ignore)
24021          handle_request_info(p, req);
24022       else  /* if ignoring, transmit response */
24023          transmit_response(p, "200 OK", req);
24024       break;
24025    case SIP_NOTIFY:
24026       res = handle_request_notify(p, req, addr, seqno, e);
24027       break;
24028    case SIP_UPDATE:
24029       res = handle_request_update(p, req);
24030       break;
24031    case SIP_ACK:
24032       /* Make sure we don't ignore this */
24033       if (seqno == p->pendinginvite) {
24034          p->invitestate = INV_TERMINATED;
24035          p->pendinginvite = 0;
24036          acked = __sip_ack(p, seqno, 1 /* response */, 0);
24037          if (find_sdp(req)) {
24038             if (process_sdp(p, req, SDP_T38_NONE))
24039                return -1;
24040          }
24041          check_pendings(p);
24042       } else if (p->glareinvite == seqno) {
24043          /* handle ack for the 491 pending sent for glareinvite */
24044          p->glareinvite = 0;
24045          acked = __sip_ack(p, seqno, 1, 0);
24046       }
24047       if (!acked) {
24048          /* Got an ACK that did not match anything. Ignore
24049           * silently and restore previous method */
24050          p->method = oldmethod;
24051       }
24052       if (!p->lastinvite && ast_strlen_zero(p->randdata)) {
24053          pvt_set_needdestroy(p, "unmatched ACK");
24054       }
24055       break;
24056    default:
24057       transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
24058       ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n",
24059          cmd, ast_sockaddr_stringify(&p->sa));
24060       /* If this is some new method, and we don't have a call, destroy it now */
24061       if (!p->initreq.headers) {
24062          pvt_set_needdestroy(p, "unimplemented method");
24063       }
24064       break;
24065    }
24066    return res;
24067 }

static int handle_invite_replaces ( struct sip_pvt *  p,
struct sip_request *  req,
int  debug,
int  seqno,
struct ast_sockaddr *  addr,
int *  nounlock 
) [static]

Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. Used only once. XXX 'ignore' is unused.

Note:
this function is called by handle_request_invite(). Four locks held at the beginning of this function, p, p->owner, p->refer->refer_call and p->refere->refer_call->owner. only p's lock should remain at the end of this function. p's lock as well as the channel p->owner's lock are held by handle_request_do(), we unlock p->owner before the masq. By setting nounlock we are indicating to handle_request_do() that we have already unlocked the owner.

Definition at line 20914 of file chan_sip.c.

References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_lock, ast_channel_masquerade(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_debug, ast_do_masquerade(), ast_hangup(), ast_log(), ast_quiet_chan(), ast_set_flag, ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, FALSE, ast_channel::hangupcause, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::name, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), ast_channel::tech_pvt, transmit_response(), transmit_response_reliable(), and transmit_response_with_sdp().

Referenced by handle_request_invite().

20915 {
20916    int earlyreplace = 0;
20917    int oneleggedreplace = 0;     /* Call with no bridge, propably IVR or voice message */
20918    struct ast_channel *c = p->owner;   /* Our incoming call */
20919    struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */
20920    struct ast_channel *targetcall;     /* The bridge to the take-over target */
20921 
20922    /* Check if we're in ring state */
20923    if (replacecall->_state == AST_STATE_RING)
20924       earlyreplace = 1;
20925 
20926    /* Check if we have a bridge */
20927    if (!(targetcall = ast_bridged_channel(replacecall))) {
20928       /* We have no bridge */
20929       if (!earlyreplace) {
20930          ast_debug(2, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name);
20931          oneleggedreplace = 1;
20932       }
20933    }
20934    if (targetcall && targetcall->_state == AST_STATE_RINGING)
20935       ast_debug(4, "SIP transfer: Target channel is in ringing state\n");
20936 
20937    if (targetcall)
20938       ast_debug(4, "SIP transfer: Invite Replace incoming channel should bridge to channel %s while hanging up channel %s\n", targetcall->name, replacecall->name);
20939    else
20940       ast_debug(4, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name);
20941 
20942    if (req->ignore) {
20943       ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n");
20944       /* We should answer something here. If we are here, the
20945          call we are replacing exists, so an accepted
20946          can't harm */
20947       transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE);
20948       /* Do something more clever here */
20949       if (c) {
20950          *nounlock = 1;
20951          ast_channel_unlock(c);
20952       }
20953       ast_channel_unlock(replacecall);
20954       sip_pvt_unlock(p->refer->refer_call);
20955       return 1;
20956    }
20957    if (!c) {
20958       /* What to do if no channel ??? */
20959       ast_log(LOG_ERROR, "Unable to create new channel.  Invite/replace failed.\n");
20960       transmit_response_reliable(p, "503 Service Unavailable", req);
20961       append_history(p, "Xfer", "INVITE/Replace Failed. No new channel.");
20962       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20963       ast_channel_unlock(replacecall);
20964       sip_pvt_unlock(p->refer->refer_call);
20965       return 1;
20966    }
20967    append_history(p, "Xfer", "INVITE/Replace received");
20968    /* We have three channels to play with
20969       channel c: New incoming call
20970       targetcall: Call from PBX to target
20971       p->refer->refer_call: SIP pvt dialog from transferer to pbx.
20972       replacecall: The owner of the previous
20973       We need to masq C into refer_call to connect to
20974       targetcall;
20975       If we are talking to internal audio stream, target call is null.
20976    */
20977 
20978    /* Fake call progress */
20979    transmit_response(p, "100 Trying", req);
20980    ast_setstate(c, AST_STATE_RING);
20981 
20982    /* Masquerade the new call into the referred call to connect to target call
20983       Targetcall is not touched by the masq */
20984 
20985    /* Answer the incoming call and set channel to UP state */
20986    transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE);
20987 
20988    ast_setstate(c, AST_STATE_UP);
20989 
20990    /* Stop music on hold and other generators */
20991    ast_quiet_chan(replacecall);
20992    ast_quiet_chan(targetcall);
20993    ast_debug(4, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name);
20994 
20995    /* Make sure that the masq does not free our PVT for the old call */
20996    if (! earlyreplace && ! oneleggedreplace )
20997       ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER);  /* Delay hangup */
20998 
20999    /* Prepare the masquerade - if this does not happen, we will be gone */
21000    if(ast_channel_masquerade(replacecall, c))
21001       ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n");
21002    else
21003       ast_debug(4, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name);
21004 
21005    /* C should now be in place of replacecall. all channel locks and pvt locks should be removed
21006     * before issuing the masq.  Since we are unlocking both the pvt (p) and its owner channel (c)
21007     * it is possible for channel c to be destroyed on us.  To prevent this, we must give c a reference
21008     * before any unlocking takes place and remove it only once we are completely done with it */
21009    ast_channel_ref(c);
21010    ast_channel_unlock(replacecall);
21011    ast_channel_unlock(c);
21012    sip_pvt_unlock(p->refer->refer_call);
21013    sip_pvt_unlock(p);
21014    if (ast_do_masquerade(replacecall)) {
21015       ast_log(LOG_WARNING, "Failed to perform masquerade with INVITE replaces\n");
21016    }
21017    ast_channel_lock(c);
21018    if (earlyreplace || oneleggedreplace ) {
21019       c->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
21020    }
21021    ast_setstate(c, AST_STATE_DOWN);
21022    ast_channel_unlock(c);
21023 
21024    /* The call should be down with no ast_channel, so hang it up */
21025    c->tech_pvt = dialog_unref(c->tech_pvt, "unref dialog c->tech_pvt");
21026 
21027    /* c and c's tech pvt must be unlocked at this point for ast_hangup */
21028    ast_hangup(c);
21029    /* this indicates to handle_request_do that the owner channel has already been unlocked */
21030    *nounlock = 1;
21031    /* lock PVT structure again after hangup */
21032    sip_pvt_lock(p);
21033    ast_channel_unref(c);
21034    return 0;
21035 }

static int handle_request_bye ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

Handle incoming BYE request.

Definition at line 22653 of file chan_sip.c.

References __sip_pretend_ack(), append_history, ARRAY_LEN, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_PROTOCOL_ERROR, ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_clear_flag, AST_CONTROL_UNHOLD, ast_debug, ast_log(), AST_MAX_USER_FIELD, ast_queue_control(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_rtp_instance_get_quality(), ast_rtp_instance_set_stats_vars(), AST_RTP_INSTANCE_STAT_FIELD_QUALITY, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, ast_set_hangupsource(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_channel::bridge, check_via(), ast_channel::context, context, copy_request(), get_also_info(), get_header(), LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar_helper(), quality, sip_alreadygone(), sip_cfg, sip_methods, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy_final(), stop_media_flows(), stop_session_timer(), ast_channel::tech, ast_channel::tech_pvt, cfsip_methods::text, transmit_response(), transmit_response_reliable(), and transmit_response_with_unsupported().

Referenced by handle_incoming().

22654 {
22655    struct ast_channel *c=NULL;
22656    int res;
22657    struct ast_channel *bridged_to;
22658    const char *required;
22659 
22660    /* If we have an INCOMING invite that we haven't answered, terminate that transaction */
22661    if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !req->ignore) {
22662       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
22663    }
22664 
22665    __sip_pretend_ack(p);
22666 
22667    p->invitestate = INV_TERMINATED;
22668 
22669    copy_request(&p->initreq, req);
22670    if (sipdebug)
22671       ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
22672    check_via(p, req);
22673    sip_alreadygone(p);
22674 
22675    /* Get RTCP quality before end of call */
22676    if (p->do_history || p->owner) {
22677       char quality_buf[AST_MAX_USER_FIELD], *quality;
22678       struct ast_channel *bridge = p->owner ? ast_bridged_channel(p->owner) : NULL;
22679 
22680       /* We need to get the lock on bridge because ast_rtp_instance_set_stats_vars will attempt
22681        * to lock the bridge. This may get hairy...
22682        */
22683       while (bridge && ast_channel_trylock(bridge)) {
22684          ast_channel_unlock(p->owner);
22685          do {
22686             /* Can't use DEADLOCK_AVOIDANCE since p is an ao2 object */
22687             sip_pvt_unlock(p);
22688             usleep(1);
22689             sip_pvt_lock(p);
22690          } while (p->owner && ast_channel_trylock(p->owner));
22691          bridge = p->owner ? ast_bridged_channel(p->owner) : NULL;
22692       }
22693 
22694 
22695       if (p->rtp && (quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
22696          if (p->do_history) {
22697             append_history(p, "RTCPaudio", "Quality:%s", quality);
22698 
22699             if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, quality_buf, sizeof(quality_buf)))) {
22700                append_history(p, "RTCPaudioJitter", "Quality:%s", quality);
22701             }
22702             if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, quality_buf, sizeof(quality_buf)))) {
22703                append_history(p, "RTCPaudioLoss", "Quality:%s", quality);
22704             }
22705             if ((quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, quality_buf, sizeof(quality_buf)))) {
22706                append_history(p, "RTCPaudioRTT", "Quality:%s", quality);
22707             }
22708          }
22709 
22710          if (p->owner) {
22711             ast_rtp_instance_set_stats_vars(p->owner, p->rtp);
22712          }
22713 
22714       }
22715 
22716       if (bridge) {
22717          struct sip_pvt *q = bridge->tech_pvt;
22718 
22719          if (IS_SIP_TECH(bridge->tech) && q && q->rtp) {
22720             ast_rtp_instance_set_stats_vars(bridge, q->rtp);
22721          }
22722          ast_channel_unlock(bridge);
22723       }
22724 
22725       if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
22726          if (p->do_history) {
22727             append_history(p, "RTCPvideo", "Quality:%s", quality);
22728          }
22729          if (p->owner) {
22730             pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", quality);
22731          }
22732       }
22733       if (p->trtp && (quality = ast_rtp_instance_get_quality(p->trtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
22734          if (p->do_history) {
22735             append_history(p, "RTCPtext", "Quality:%s", quality);
22736          }
22737          if (p->owner) {
22738             pbx_builtin_setvar_helper(p->owner, "RTPTEXTQOS", quality);
22739          }
22740       }
22741    }
22742 
22743    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
22744    stop_session_timer(p); /* Stop Session-Timer */
22745 
22746    if (!ast_strlen_zero(get_header(req, "Also"))) {
22747       ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
22748          ast_sockaddr_stringify(&p->recv));
22749       if (ast_strlen_zero(p->context))
22750          ast_string_field_set(p, context, sip_cfg.default_context);
22751       res = get_also_info(p, req);
22752       if (!res) {
22753          c = p->owner;
22754          if (c) {
22755             bridged_to = ast_bridged_channel(c);
22756             if (bridged_to) {
22757                /* Don't actually hangup here... */
22758                ast_queue_control(c, AST_CONTROL_UNHOLD);
22759                ast_channel_unlock(c);  /* async_goto can do a masquerade, no locks can be held during a masq */
22760                ast_async_goto(bridged_to, p->context, p->refer->refer_to, 1);
22761                ast_channel_lock(c);
22762             } else
22763                ast_queue_hangup(p->owner);
22764          }
22765       } else {
22766          ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_sockaddr_stringify(&p->recv));
22767          if (p->owner)
22768             ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR);
22769       }
22770    } else if (p->owner) {
22771       ast_set_hangupsource(p->owner, p->owner->name, 0);
22772       ast_queue_hangup(p->owner);
22773       sip_scheddestroy_final(p, DEFAULT_TRANS_TIMEOUT);
22774       ast_debug(3, "Received bye, issuing owner hangup\n");
22775    } else {
22776       sip_scheddestroy_final(p, DEFAULT_TRANS_TIMEOUT);
22777       ast_debug(3, "Received bye, no owner, selfdestruct soon.\n");
22778    }
22779    ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
22780 
22781    /* Find out what they require */
22782    required = get_header(req, "Require");
22783    if (!ast_strlen_zero(required)) {
22784       char unsupported[256] = { 0, };
22785       parse_sip_options(required, unsupported, ARRAY_LEN(unsupported));
22786       /* If there are any options required that we do not support,
22787        * then send a 420 with only those unsupported options listed */
22788       if (!ast_strlen_zero(unsupported)) {
22789          transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported);
22790          ast_log(LOG_WARNING, "Received SIP BYE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported);
22791       } else {
22792          transmit_response(p, "200 OK", req);
22793       }
22794    } else {
22795       transmit_response(p, "200 OK", req);
22796    }
22797 
22798    return 1;
22799 }

static int handle_request_cancel ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

Handle incoming CANCEL request.

Definition at line 22588 of file chan_sip.c.

References __sip_pretend_ack(), ast_debug, ast_free, ast_queue_hangup(), AST_SCHED_DEL, ast_set_hangupsource(), AST_STATE_UP, ast_test_flag, check_via(), sip_alreadygone(), sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), UNLINK, and update_call_counter().

Referenced by handle_incoming().

22589 {
22590 
22591    check_via(p, req);
22592    sip_alreadygone(p);
22593 
22594    if (p->owner && p->owner->_state == AST_STATE_UP) {
22595       /* This call is up, cancel is ignored, we need a bye */
22596       transmit_response(p, "200 OK", req);
22597       ast_debug(1, "Got CANCEL on an answered call. Ignoring... \n");
22598       return 0;
22599    }
22600 
22601    /* At this point, we could have cancelled the invite at the same time
22602       as the other side sends a CANCEL. Our final reply with error code
22603       might not have been received by the other side before the CANCEL
22604       was sent, so let's just give up retransmissions and waiting for
22605       ACK on our error code. The call is hanging up any way. */
22606    if (p->invitestate == INV_TERMINATED || p->invitestate == INV_COMPLETED) {
22607       __sip_pretend_ack(p);
22608    }
22609    if (p->invitestate != INV_TERMINATED)
22610       p->invitestate = INV_CANCELLED;
22611 
22612    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD))
22613       update_call_counter(p, DEC_CALL_LIMIT);
22614 
22615    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
22616    if (p->owner) {
22617       ast_set_hangupsource(p->owner, p->owner->name, 0);
22618       ast_queue_hangup(p->owner);
22619    }
22620    else
22621       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
22622    if (p->initreq.len > 0) {
22623       struct sip_pkt *pkt, *prev_pkt;
22624       /* If the CANCEL we are receiving is a retransmission, and we already have scheduled
22625        * a reliable 487, then we don't want to schedule another one on top of the previous
22626        * one.
22627        *
22628        * As odd as this may sound, we can't rely on the previously-transmitted "reliable"
22629        * response in this situation. What if we've sent all of our reliable responses
22630        * already and now all of a sudden, we get this second CANCEL?
22631        *
22632        * The only way to do this correctly is to cancel our previously-scheduled reliably-
22633        * transmitted response and send a new one in its place.
22634        */
22635       for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->next) {
22636          if (pkt->seqno == p->lastinvite && pkt->response_code == 487) {
22637             AST_SCHED_DEL(sched, pkt->retransid);
22638             UNLINK(pkt, p->packets, prev_pkt);
22639             ast_free(pkt);
22640             break;
22641          }
22642       }
22643       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
22644       transmit_response(p, "200 OK", req);
22645       return 1;
22646    } else {
22647       transmit_response(p, "481 Call Leg Does Not Exist", req);
22648       return 0;
22649    }
22650 }

static int handle_request_do ( struct sip_request *  req,
struct ast_sockaddr *  addr 
) [static]

Handle incoming SIP message - request or response.

This is used for all transports (udp, tcp and tcp/tls)

Definition at line 24208 of file chan_sip.c.

References ao2_t_ref, append_history, ast_channel_trylock, ast_channel_unlock, ast_debug, AST_LIST_EMPTY, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_SCHED_DEL_UNREF, ast_sockaddr_copy(), ast_sockaddr_stringify(), ast_str_reset(), ast_update_use_count(), ast_verbose, copy_socket_data(), find_call(), find_sip_method(), get_header(), get_transport(), handle_incoming(), LOG_ERROR, lws2sws(), netlock, parse_request(), process_request_queue(), queue_request(), S_OR, sip_cfg, sip_debug_test_addr(), sip_pvt_unlock, and transmit_response().

Referenced by sipsock_read().

24209 {
24210    struct sip_pvt *p;
24211    int recount = 0;
24212    int nounlock = 0;
24213    int lockretry;
24214 
24215    if (sip_debug_test_addr(addr))   /* Set the debug flag early on packet level */
24216       req->debug = 1;
24217    if (sip_cfg.pedanticsipchecking)
24218       req->len = lws2sws(req->data->str, req->len);   /* Fix multiline headers */
24219    if (req->debug) {
24220       ast_verbose("\n<--- SIP read from %s:%s --->\n%s\n<------------->\n",
24221          get_transport(req->socket.type), ast_sockaddr_stringify(addr), req->data->str);
24222    }
24223 
24224    if (parse_request(req) == -1) { /* Bad packet, can't parse */
24225       ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */
24226       return 1;
24227    }
24228    req->method = find_sip_method(REQ_OFFSET_TO_STR(req, rlPart1));
24229 
24230    if (req->debug)
24231       ast_verbose("--- (%d headers %d lines)%s ---\n", req->headers, req->lines, (req->headers + req->lines == 0) ? " Nat keepalive" : "");
24232 
24233    if (req->headers < 2) { /* Must have at least two headers */
24234       ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */
24235       return 1;
24236    }
24237 
24238    /* Process request, with netlock held, and with usual deadlock avoidance */
24239    for (lockretry = 10; lockretry > 0; lockretry--) {
24240       ast_mutex_lock(&netlock);
24241 
24242       /* Find the active SIP dialog or create a new one */
24243       p = find_call(req, addr, req->method); /* returns p locked */
24244       if (p == NULL) {
24245          ast_debug(1, "Invalid SIP message - rejected , no callid, len %d\n", req->len);
24246          ast_mutex_unlock(&netlock);
24247          return 1;
24248       }
24249 
24250       copy_socket_data(&p->socket, &req->socket);
24251 
24252       /* Go ahead and lock the owner if it has one -- we may need it */
24253       /* becaues this is deadlock-prone, we need to try and unlock if failed */
24254       if (!p->owner || !ast_channel_trylock(p->owner))
24255          break;   /* locking succeeded */
24256 
24257       if (lockretry != 1) {
24258          sip_pvt_unlock(p);
24259          ao2_t_ref(p, -1, "release p (from find_call) inside lockretry loop"); /* we'll look for it again, but p is dead now */
24260          ast_mutex_unlock(&netlock);
24261          /* Sleep for a very short amount of time */
24262          usleep(1);
24263       }
24264    }
24265    ast_sockaddr_copy(&p->recv, addr);
24266 
24267    /* if we have an owner, then this request has been authenticated */
24268    if (p->owner) {
24269       req->authenticated = 1;
24270    }
24271 
24272    if (p->do_history) /* This is a request or response, note what it was for */
24273       append_history(p, "Rx", "%s / %s / %s", req->data->str, get_header(req, "CSeq"), REQ_OFFSET_TO_STR(req, rlPart2));
24274 
24275    if (!lockretry) {
24276       if (!queue_request(p, req)) {
24277          /* the request has been queued for later handling */
24278          sip_pvt_unlock(p);
24279          ao2_t_ref(p, -1, "release p (from find_call) after queueing request");
24280          ast_mutex_unlock(&netlock);
24281          return 1;
24282       }
24283 
24284       if (p->owner)
24285          ast_log(LOG_ERROR, "Channel lock for %s could not be obtained, and request was unable to be queued.\n", S_OR(p->owner->name, "- no channel name ??? - "));
24286       ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid);
24287       if (req->method != SIP_ACK)
24288          transmit_response(p, "503 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
24289       /* XXX We could add retry-after to make sure they come back */
24290       append_history(p, "LockFail", "Owner lock failed, transaction failed.");
24291       sip_pvt_unlock(p);
24292       ao2_t_ref(p, -1, "release p (from find_call) at end of lockretry"); /* p is gone after the return */
24293       ast_mutex_unlock(&netlock);
24294       return 1;
24295    }
24296 
24297    /* if there are queued requests on this sip_pvt, process them first, so that everything is
24298       handled in order
24299    */
24300    if (!AST_LIST_EMPTY(&p->request_queue)) {
24301       AST_SCHED_DEL_UNREF(sched, p->request_queue_sched_id, dialog_unref(p, "when you delete the request_queue_sched_id sched, you should dec the refcount for the stored dialog ptr"));
24302       process_request_queue(p, &recount, &nounlock);
24303    }
24304 
24305    if (handle_incoming(p, req, addr, &recount, &nounlock) == -1) {
24306       /* Request failed */
24307       ast_debug(1, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
24308    }
24309       
24310    if (recount)
24311       ast_update_use_count();
24312 
24313    if (p->owner && !nounlock)
24314       ast_channel_unlock(p->owner);
24315    sip_pvt_unlock(p);
24316    ao2_t_ref(p, -1, "throw away dialog ptr from find_call at end of routine"); /* p is gone after the return */
24317    ast_mutex_unlock(&netlock);
24318    return 1;
24319 }

static void handle_request_info ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

Receive SIP INFO Message.

Todo:
Note: Doesn't read the duration of the DTMF. Should be fixed.

Definition at line 17858 of file chan_sip.c.

References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, ast_copy_string(), ast_debug, ast_find_call_feature(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), ast_queue_control(), ast_queue_frame(), ast_rdlock_call_features(), ast_strlen_zero(), ast_test_flag, ast_unlock_call_features(), ast_verbose, ast_channel::cdr, ast_call_feature::exten, f, get_body(), get_header(), get_msg_text(), LOG_WARNING, sip_scheddestroy(), transmit_response(), and TRUE.

Referenced by handle_incoming().

17859 {
17860    char buf[1024];
17861    unsigned int event;
17862    const char *c = get_header(req, "Content-Type");
17863 
17864    /* Need to check the media/type */
17865    if (!strcasecmp(c, "application/dtmf-relay") ||
17866        !strcasecmp(c, "application/vnd.nortelnetworks.digits")) {
17867       unsigned int duration = 0;
17868 
17869       if (!p->owner) {  /* not a PBX call */
17870          transmit_response(p, "481 Call leg/transaction does not exist", req);
17871          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
17872          return;
17873       }
17874 
17875       /* Try getting the "signal=" part */
17876       if (ast_strlen_zero(c = get_body(req, "Signal", '=')) && ast_strlen_zero(c = get_body(req, "d", '='))) {
17877          ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
17878          transmit_response(p, "200 OK", req); /* Should return error */
17879          return;
17880       } else {
17881          ast_copy_string(buf, c, sizeof(buf));
17882       }
17883 
17884       if (!ast_strlen_zero((c = get_body(req, "Duration", '='))))
17885          duration = atoi(c);
17886       if (!duration)
17887          duration = 100; /* 100 ms */
17888 
17889 
17890       if (ast_strlen_zero(buf)) {
17891          transmit_response(p, "200 OK", req);
17892          return;
17893       }
17894 
17895       if (buf[0] == '*')
17896          event = 10;
17897       else if (buf[0] == '#')
17898          event = 11;
17899       else if ((buf[0] >= 'A') && (buf[0] <= 'D'))
17900          event = 12 + buf[0] - 'A';
17901       else if (buf[0] == '!')
17902          event = 16;
17903       else
17904          event = atoi(buf);
17905       if (event == 16) {
17906          /* send a FLASH event */
17907          struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH, } };
17908          ast_queue_frame(p->owner, &f);
17909          if (sipdebug)
17910             ast_verbose("* DTMF-relay event received: FLASH\n");
17911       } else {
17912          /* send a DTMF event */
17913          struct ast_frame f = { AST_FRAME_DTMF, };
17914          if (event < 10) {
17915             f.subclass.integer = '0' + event;
17916          } else if (event == 10) {
17917             f.subclass.integer = '*';
17918          } else if (event == 11) {
17919             f.subclass.integer = '#';
17920          } else if (event < 16) {
17921             f.subclass.integer = 'A' + (event - 12);
17922          }
17923          f.len = duration;
17924          ast_queue_frame(p->owner, &f);
17925          if (sipdebug)
17926             ast_verbose("* DTMF-relay event received: %c\n", (int) f.subclass.integer);
17927       }
17928       transmit_response(p, "200 OK", req);
17929       return;
17930    } else if (!strcasecmp(c, "application/dtmf")) {
17931       /*! \todo Note: Doesn't read the duration of the DTMF. Should be fixed. */
17932       unsigned int duration = 0;
17933 
17934       if (!p->owner) {  /* not a PBX call */
17935          transmit_response(p, "481 Call leg/transaction does not exist", req);
17936          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
17937          return;
17938       }
17939 
17940       get_msg_text(buf, sizeof(buf), req, TRUE);
17941       duration = 100; /* 100 ms */
17942 
17943       if (ast_strlen_zero(buf)) {
17944          transmit_response(p, "200 OK", req);
17945          return;
17946       }
17947       event = atoi(buf);
17948       if (event == 16) {
17949          /* send a FLASH event */
17950          struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH }, };
17951          ast_queue_frame(p->owner, &f);
17952          if (sipdebug)
17953             ast_verbose("* DTMF-relay event received: FLASH\n");
17954       } else {
17955          /* send a DTMF event */
17956          struct ast_frame f = { AST_FRAME_DTMF, };
17957          if (event < 10) {
17958             f.subclass.integer = '0' + event;
17959          } else if (event == 10) {
17960             f.subclass.integer = '*';
17961          } else if (event == 11) {
17962             f.subclass.integer = '#';
17963          } else if (event < 16) {
17964             f.subclass.integer = 'A' + (event - 12);
17965          }
17966          f.len = duration;
17967          ast_queue_frame(p->owner, &f);
17968          if (sipdebug)
17969             ast_verbose("* DTMF-relay event received: %c\n", (int) f.subclass.integer);
17970       }
17971       transmit_response(p, "200 OK", req);
17972       return;
17973 
17974    } else if (!strcasecmp(c, "application/media_control+xml")) {
17975       /* Eh, we'll just assume it's a fast picture update for now */
17976       if (p->owner)
17977          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
17978       transmit_response(p, "200 OK", req);
17979       return;
17980    } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) {
17981       /* Client code (from SNOM phone) */
17982       if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) {
17983          if (p->owner && p->owner->cdr)
17984             ast_cdr_setuserfield(p->owner, c);
17985          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
17986             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
17987          transmit_response(p, "200 OK", req);
17988       } else {
17989          transmit_response(p, "403 Forbidden", req);
17990       }
17991       return;
17992    } else if (!ast_strlen_zero(c = get_header(req, "Record"))) {
17993       /* INFO messages generated by some phones to start/stop recording
17994          on phone calls.
17995          OEJ: I think this should be something that is enabled/disabled
17996          per device. I don't want incoming callers to record calls in my
17997          pbx.
17998       */
17999       /* first, get the feature string, if it exists */
18000       struct ast_call_feature *feat;
18001       int j;
18002       struct ast_frame f = { AST_FRAME_DTMF, };
18003 
18004       ast_rdlock_call_features();
18005       feat = ast_find_call_feature("automon");
18006       if (!feat || ast_strlen_zero(feat->exten)) {
18007          ast_log(LOG_WARNING, "Recording requested, but no One Touch Monitor registered. (See features.conf)\n");
18008          /* 403 means that we don't support this feature, so don't request it again */
18009          transmit_response(p, "403 Forbidden", req);
18010          ast_unlock_call_features();
18011          return;
18012       }
18013       /* Send the feature code to the PBX as DTMF, just like the handset had sent it */
18014       f.len = 100;
18015       for (j=0; j < strlen(feat->exten); j++) {
18016          f.subclass.integer = feat->exten[j];
18017          ast_queue_frame(p->owner, &f);
18018          if (sipdebug)
18019             ast_verbose("* DTMF-relay event faked: %c\n", f.subclass.integer);
18020       }
18021       ast_unlock_call_features();
18022 
18023       ast_debug(1, "Got a Request to Record the channel, state %s\n", c);
18024       transmit_response(p, "200 OK", req);
18025       return;
18026    } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) {
18027       /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */
18028       transmit_response(p, "200 OK", req);
18029       return;
18030    }
18031 
18032    /* Other type of INFO message, not really understood by Asterisk */
18033    /* if (get_msg_text(buf, sizeof(buf), req)) { */
18034 
18035    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
18036    transmit_response(p, "415 Unsupported media type", req);
18037    return;
18038 }

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

Handle incoming INVITE request.

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

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

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

Definition at line 21130 of file chan_sip.c.

References __sip_ack(), ast_channel::_state, append_history, ARRAY_LEN, AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_cc_agent_set_interfaces_chanvar(), ast_channel_lock, ast_channel_queue_connected_line_update(), ast_channel_set_redirecting(), ast_channel_unlock, ast_clear_flag, AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, AST_CONTROL_BUSY, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_hangup(), ast_log(), AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_null_frame, ast_party_connected_line_init(), ast_party_redirecting_free(), ast_party_redirecting_init(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_queue_frame(), ast_rtp_instance_set_alt_remote_address(), ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_sched_add(), ast_set_flag, ast_setstate(), ast_setup_cc_recall_datastore(), ast_skip_blanks(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_new_with_bindaddr(), ast_uri_decode(), ast_verbose, bindaddr, build_contact(), build_route(), change_hold_state(), change_redirecting_information(), check_user_full(), check_via(), connected, context, copy_request(), do_magic_pickup(), ast_channel::exten, exten, extract_uri(), FALSE, find_sdp(), get_destination(), get_header(), get_ip_and_port_from_sdp(), get_rpid(), get_sip_pvt_byid_locked(), global_max_se, global_t38_maxdatagram, handle_invite_replaces(), ast_channel::hangupcause, io, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_our_tag(), ast_channel::name, parse_minse(), parse_ok_contact(), parse_session_expires(), process_sdp(), ref_peer(), restart_session_timer(), S_OR, set_pvt_allowed_methods(), set_t38_capabilities(), sip_alreadygone(), sip_cancel_destroy(), sip_cfg, sip_methods, sip_new(), sip_pvt_lock, sip_pvt_unlock, sip_refer_allocate(), sip_scheddestroy(), sip_st_alloc(), sip_t38_abort(), st_get_mode(), st_get_refresher(), st_get_se(), start_session_timer(), strcasestr(), strsep(), cfsip_methods::text, transmit_fake_auth_response(), transmit_provisional_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_minse(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, unref_peer(), update_call_counter(), and update_redirecting().

Referenced by handle_incoming().

21131 {
21132    int res = 1;
21133    int gotdest;
21134    const char *p_replaces;
21135    char *replace_id = NULL;
21136    int refer_locked = 0;
21137    const char *required;
21138    unsigned int required_profile = 0;
21139    struct ast_channel *c = NULL;    /* New channel */
21140    struct sip_peer *authpeer = NULL;   /* Matching Peer */
21141    int reinvite = 0;
21142    int rtn;
21143    struct ast_party_redirecting redirecting;
21144    struct ast_set_party_redirecting update_redirecting;
21145 
21146    const char *p_uac_se_hdr;       /* UAC's Session-Expires header string                      */
21147    const char *p_uac_min_se;       /* UAC's requested Min-SE interval (char string)            */
21148    int uac_max_se = -1;            /* UAC's Session-Expires in integer format                  */
21149    int uac_min_se = -1;            /* UAC's Min-SE in integer format                           */
21150    int st_active = FALSE;          /* Session-Timer on/off boolean                             */
21151    int st_interval = 0;            /* Session-Timer negotiated refresh interval                */
21152    enum st_refresher st_ref;       /* Session-Timer session refresher                          */
21153    int dlg_min_se = -1;
21154    struct {
21155       char exten[AST_MAX_EXTENSION];
21156       char context[AST_MAX_CONTEXT];
21157    } pickup = {
21158          .exten = "",
21159    };
21160    st_ref = SESSION_TIMER_REFRESHER_AUTO;
21161 
21162    /* Find out what they support */
21163    if (!p->sipoptions) {
21164       const char *supported = get_header(req, "Supported");
21165       if (!ast_strlen_zero(supported)) {
21166          p->sipoptions = parse_sip_options(supported, NULL, 0);
21167       }
21168    }
21169 
21170    /* Find out what they require */
21171    required = get_header(req, "Require");
21172    if (!ast_strlen_zero(required)) {
21173       char unsupported[256] = { 0, };
21174       required_profile = parse_sip_options(required, unsupported, ARRAY_LEN(unsupported));
21175 
21176       /* If there are any options required that we do not support,
21177        * then send a 420 with only those unsupported options listed */
21178       if (!ast_strlen_zero(unsupported)) {
21179          transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, unsupported);
21180          ast_log(LOG_WARNING, "Received SIP INVITE with unsupported required extension: required:%s unsupported:%s\n", required, unsupported);
21181          p->invitestate = INV_COMPLETED;
21182          if (!p->lastinvite)
21183             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21184          res = -1;
21185          goto request_invite_cleanup;
21186       }
21187    }
21188 
21189    /* The option tags may be present in Supported: or Require: headers.
21190    Include the Require: option tags for further processing as well */
21191    p->sipoptions |= required_profile;
21192    p->reqsipoptions = required_profile;
21193 
21194    /* Check if this is a loop */
21195    if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->invitestate != INV_TERMINATED && p->invitestate != INV_CONFIRMED) && p->owner->_state != AST_STATE_UP) {
21196       /* This is a call to ourself.  Send ourselves an error code and stop
21197          processing immediately, as SIP really has no good mechanism for
21198          being able to call yourself */
21199       /* If pedantic is on, we need to check the tags. If they're different, this is
21200          in fact a forked call through a SIP proxy somewhere. */
21201       int different;
21202       const char *initial_rlPart2 = REQ_OFFSET_TO_STR(&p->initreq, rlPart2);
21203       const char *this_rlPart2 = REQ_OFFSET_TO_STR(req, rlPart2);
21204       if (sip_cfg.pedanticsipchecking)
21205          different = sip_uri_cmp(initial_rlPart2, this_rlPart2);
21206       else
21207          different = strcmp(initial_rlPart2, this_rlPart2);
21208       if (!different) {
21209          transmit_response(p, "482 Loop Detected", req);
21210          p->invitestate = INV_COMPLETED;
21211          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21212          res = 0;
21213          goto request_invite_cleanup;
21214       } else {
21215          /*! This is a spiral. What we need to do is to just change the outgoing INVITE
21216           * so that it now routes to the new Request URI. Since we created the INVITE ourselves
21217           * that should be all we need to do.
21218           *
21219           * \todo XXX This needs to be reviewed.  YOu don't change the request URI really, you route the packet
21220           * correctly instead...
21221           */
21222          char *uri = ast_strdupa(this_rlPart2);
21223          char *at = strchr(uri, '@');
21224          char *peerorhost;
21225          ast_debug(2, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", initial_rlPart2, this_rlPart2);
21226          transmit_response(p, "100 Trying", req);
21227          if (at) {
21228             *at = '\0';
21229          }
21230          /* Parse out "sip:" */
21231          if ((peerorhost = strchr(uri, ':'))) {
21232             *peerorhost++ = '\0';
21233          }
21234          ast_string_field_set(p, theirtag, NULL);
21235          /* Treat this as if there were a call forward instead...
21236           */
21237          ast_string_field_set(p->owner, call_forward, peerorhost);
21238          ast_queue_control(p->owner, AST_CONTROL_BUSY);
21239          res = 0;
21240          goto request_invite_cleanup;
21241       }
21242    }
21243 
21244    if (!req->ignore && p->pendinginvite) {
21245       if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && (p->invitestate == INV_COMPLETED || p->invitestate == INV_TERMINATED)) {
21246          /* What do these circumstances mean? We have received an INVITE for an "incoming" dialog for which we
21247           * have sent a final response. We have not yet received an ACK, though (which is why p->pendinginvite is non-zero).
21248           * We also know that the INVITE is not a retransmission, because otherwise the "ignore" flag would be set.
21249           * This means that either we are receiving a reinvite for a terminated dialog, or we are receiving an INVITE with
21250           * credentials based on one we challenged earlier.
21251           *
21252           * The action to take in either case is to treat the INVITE as though it contains an implicit ACK for the previous
21253           * transaction. Calling __sip_ack will take care of this by clearing the p->pendinginvite and removing the response
21254           * from the previous transaction from the list of outstanding packets.
21255           */
21256          __sip_ack(p, p->pendinginvite, 1, 0);
21257       } else {
21258          /* We already have a pending invite. Sorry. You are on hold. */
21259          p->glareinvite = seqno;
21260          if (p->rtp && find_sdp(req)) {
21261             struct ast_sockaddr addr;
21262             if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &addr)) {
21263                ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Audio may not work properly on this call.\n");
21264             } else {
21265                ast_rtp_instance_set_alt_remote_address(p->rtp, &addr);
21266             }
21267             if (p->vrtp) {
21268                if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &addr)) {
21269                   ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Video may not work properly on this call.\n");
21270                } else {
21271                   ast_rtp_instance_set_alt_remote_address(p->vrtp, &addr);
21272                }
21273             }
21274          }
21275          transmit_response_reliable(p, "491 Request Pending", req);
21276          ast_debug(1, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid);
21277          /* Don't destroy dialog here */
21278          res = 0;
21279          goto request_invite_cleanup;
21280       }
21281    }
21282 
21283    p_replaces = get_header(req, "Replaces");
21284    if (!ast_strlen_zero(p_replaces)) {
21285       /* We have a replaces header */
21286       char *ptr;
21287       char *fromtag = NULL;
21288       char *totag = NULL;
21289       char *start, *to;
21290       int error = 0;
21291 
21292       if (p->owner) {
21293          ast_debug(3, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid);
21294          transmit_response_reliable(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
21295          /* Do not destroy existing call */
21296          res = -1;
21297          goto request_invite_cleanup;
21298       }
21299 
21300       if (sipdebug)
21301          ast_debug(3, "INVITE part of call transfer. Replaces [%s]\n", p_replaces);
21302       /* Create a buffer we can manipulate */
21303       replace_id = ast_strdupa(p_replaces);
21304       ast_uri_decode(replace_id);
21305 
21306       if (!p->refer && !sip_refer_allocate(p)) {
21307          transmit_response_reliable(p, "500 Server Internal Error", req);
21308          append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory.");
21309          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21310          p->invitestate = INV_COMPLETED;
21311          res = -1;
21312          goto request_invite_cleanup;
21313       }
21314 
21315       /*  Todo: (When we find phones that support this)
21316          if the replaces header contains ";early-only"
21317          we can only replace the call in early
21318          stage, not after it's up.
21319 
21320          If it's not in early mode, 486 Busy.
21321       */
21322 
21323       /* Skip leading whitespace */
21324       replace_id = ast_skip_blanks(replace_id);
21325 
21326       start = replace_id;
21327       while ( (ptr = strsep(&start, ";")) ) {
21328          ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */
21329          if ( (to = strcasestr(ptr, "to-tag=") ) )
21330             totag = to + 7;   /* skip the keyword */
21331          else if ( (to = strcasestr(ptr, "from-tag=") ) ) {
21332             fromtag = to + 9; /* skip the keyword */
21333             fromtag = strsep(&fromtag, "&"); /* trim what ? */
21334          }
21335       }
21336 
21337       if (sipdebug)
21338          ast_debug(4, "Invite/replaces: Will use Replace-Call-ID : %s Fromtag: %s Totag: %s\n",
21339                  replace_id,
21340                  fromtag ? fromtag : "<no from tag>",
21341                  totag ? totag : "<no to tag>");
21342 
21343       /* Try to find call that we are replacing.
21344          If we have a Replaces header, we need to cancel that call if we succeed with this call.
21345          First we cheat a little and look for a magic call-id from phones that support
21346          dialog-info+xml so we can do technology independent pickup... */
21347       if (strncmp(replace_id, "pickup-", 7) == 0) {
21348          struct sip_pvt *subscription = NULL;
21349          replace_id += 7; /* Worst case we are looking at \0 */
21350 
21351          if ((subscription = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) {
21352             ast_log(LOG_NOTICE, "Unable to find subscription with call-id: %s\n", replace_id);
21353             transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req);
21354             error = 1;
21355          } else {
21356             ast_log(LOG_NOTICE, "Trying to pick up %s@%s\n", subscription->exten, subscription->context);
21357             ast_copy_string(pickup.exten, subscription->exten, sizeof(pickup.exten));
21358             ast_copy_string(pickup.context, subscription->context, sizeof(pickup.context));
21359             sip_pvt_unlock(subscription);
21360             if (subscription->owner) {
21361                ast_channel_unlock(subscription->owner);
21362             }
21363          }
21364       }
21365 
21366       /* This locks both refer_call pvt and refer_call pvt's owner!!!*/
21367       if (!error && ast_strlen_zero(pickup.exten) && (p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) {
21368          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id);
21369          transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req);
21370          error = 1;
21371       } else {
21372          refer_locked = 1;
21373       }
21374 
21375       /* The matched call is the call from the transferer to Asterisk .
21376          We want to bridge the bridged part of the call to the
21377          incoming invite, thus taking over the refered call */
21378 
21379       if (p->refer->refer_call == p) {
21380          ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid);
21381          p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call");
21382          transmit_response_reliable(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
21383          error = 1;
21384       }
21385 
21386       if (!error && ast_strlen_zero(pickup.exten) && !p->refer->refer_call->owner) {
21387          /* Oops, someting wrong anyway, no owner, no call */
21388          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id);
21389          /* Check for better return code */
21390          transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req);
21391          error = 1;
21392       }
21393 
21394       if (!error && ast_strlen_zero(pickup.exten) && p->refer->refer_call->owner->_state != AST_STATE_RINGING && p->refer->refer_call->owner->_state != AST_STATE_RING && p->refer->refer_call->owner->_state != AST_STATE_UP) {
21395          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id);
21396          transmit_response_reliable(p, "603 Declined (Replaces)", req);
21397          error = 1;
21398       }
21399 
21400       if (error) {   /* Give up this dialog */
21401          append_history(p, "Xfer", "INVITE/Replace Failed.");
21402          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21403          sip_pvt_unlock(p);
21404          if (p->refer->refer_call) {
21405             sip_pvt_unlock(p->refer->refer_call);
21406             if (p->refer->refer_call->owner) {
21407                ast_channel_unlock(p->refer->refer_call->owner);
21408             }
21409          }
21410          refer_locked = 0;
21411          p->invitestate = INV_COMPLETED;
21412          res = -1;
21413          goto request_invite_cleanup;
21414       }
21415    }
21416 
21417    /* Check if this is an INVITE that sets up a new dialog or
21418       a re-invite in an existing dialog */
21419 
21420    if (!req->ignore) {
21421       int newcall = (p->initreq.headers ? TRUE : FALSE);
21422 
21423       if (sip_cancel_destroy(p))
21424          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
21425       /* This also counts as a pending invite */
21426       p->pendinginvite = seqno;
21427       check_via(p, req);
21428 
21429       copy_request(&p->initreq, req);     /* Save this INVITE as the transaction basis */
21430       if (sipdebug)
21431          ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
21432       if (!p->owner) {  /* Not a re-invite */
21433          if (debug)
21434             ast_verbose("Using INVITE request as basis request - %s\n", p->callid);
21435          if (newcall)
21436             append_history(p, "Invite", "New call: %s", p->callid);
21437          parse_ok_contact(p, req);
21438       } else { /* Re-invite on existing call */
21439          ast_clear_flag(&p->flags[0], SIP_OUTGOING);  /* This is now an inbound dialog */
21440          if (get_rpid(p, req)) {
21441             struct ast_party_connected_line connected;
21442             struct ast_set_party_connected_line update_connected;
21443 
21444             ast_party_connected_line_init(&connected);
21445             memset(&update_connected, 0, sizeof(update_connected));
21446             if (p->cid_num) {
21447                update_connected.id.number = 1;
21448                connected.id.number.valid = 1;
21449                connected.id.number.str = (char *) p->cid_num;
21450                connected.id.number.presentation = p->callingpres;
21451             }
21452             if (p->cid_name) {
21453                update_connected.id.name = 1;
21454                connected.id.name.valid = 1;
21455                connected.id.name.str = (char *) p->cid_name;
21456                connected.id.name.presentation = p->callingpres;
21457             }
21458             connected.id.tag = (char *) p->cid_tag;
21459             connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
21460             ast_channel_queue_connected_line_update(p->owner, &connected,
21461                &update_connected);
21462          }
21463          /* Handle SDP here if we already have an owner */
21464          if (find_sdp(req)) {
21465             if (process_sdp(p, req, SDP_T38_INITIATE)) {
21466                if (!ast_strlen_zero(get_header(req, "Content-Encoding"))) {
21467                   /* Asterisk does not yet support any Content-Encoding methods.  Always
21468                    * attempt to process the sdp, but return a 415 if a Content-Encoding header
21469                    * was present after processing failed.  */
21470                   transmit_response_reliable(p, "415 Unsupported Media type", req);
21471                } else {
21472                   transmit_response_reliable(p, "488 Not acceptable here", req);
21473                }
21474                if (!p->lastinvite)
21475                   sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21476                res = -1;
21477                goto request_invite_cleanup;
21478             }
21479             ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE);
21480          } else {
21481             p->jointcapability = p->capability;
21482             ast_debug(1, "Hm....  No sdp for the moment\n");
21483             /* Some devices signal they want to be put off hold by sending a re-invite
21484                *without* an SDP, which is supposed to mean "Go back to your state"
21485                and since they put os on remote hold, we go back to off hold */
21486             if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
21487                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
21488                /* Activate a re-invite */
21489                ast_queue_frame(p->owner, &ast_null_frame);
21490                change_hold_state(p, req, FALSE, 0);
21491             }
21492          }
21493          if (p->do_history) /* This is a response, note what it was for */
21494             append_history(p, "ReInv", "Re-invite received");
21495       }
21496    } else if (debug)
21497       ast_verbose("Ignoring this INVITE request\n");
21498 
21499    if (!p->lastinvite && !req->ignore && !p->owner) {
21500       /* This is a new invite */
21501       /* Handle authentication if this is our first invite */
21502       int cc_recall_core_id = -1;
21503       set_pvt_allowed_methods(p, req);
21504       res = check_user_full(p, req, SIP_INVITE, e, XMIT_RELIABLE, addr, &authpeer);
21505       if (res == AUTH_CHALLENGE_SENT) {
21506          p->invitestate = INV_COMPLETED;     /* Needs to restart in another INVITE transaction */
21507          res = 0;
21508          goto request_invite_cleanup;
21509       }
21510       if (res < 0) { /* Something failed in authentication */
21511          if (res == AUTH_FAKE_AUTH) {
21512             ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From"));
21513             transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE);
21514          } else {
21515             ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
21516             transmit_response_reliable(p, "403 Forbidden", req);
21517          }
21518          p->invitestate = INV_COMPLETED;
21519          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21520          ast_string_field_set(p, theirtag, NULL);
21521          res = 0;
21522          goto request_invite_cleanup;
21523       }
21524 
21525       /* Successful authentication and peer matching so record the peer related to this pvt (for easy access to peer settings) */
21526       if (p->relatedpeer) {
21527          p->relatedpeer = unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else.");
21528       }
21529       if (authpeer) {
21530          p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer");
21531       }
21532       /* If T38 is needed but not present, then make it magically appear */
21533       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && !p->udptl) {
21534          if ((p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &bindaddr))) {
21535             p->t38_maxdatagram = global_t38_maxdatagram;
21536             set_t38_capabilities(p);
21537          } else {
21538             /* udptl creation failed, T38 can not be supported on this dialog */
21539             ast_debug(1, "UDPTL creation failed on dialog.\n");
21540             ast_clear_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT);
21541          }
21542       }
21543 
21544       req->authenticated = 1;
21545 
21546       /* We have a successful authentication, process the SDP portion if there is one */
21547       if (find_sdp(req)) {
21548          if (process_sdp(p, req, SDP_T38_INITIATE)) {
21549             /* Asterisk does not yet support any Content-Encoding methods.  Always
21550              * attempt to process the sdp, but return a 415 if a Content-Encoding header
21551              * was present after processing fails. */
21552             if (!ast_strlen_zero(get_header(req, "Content-Encoding"))) {
21553                transmit_response_reliable(p, "415 Unsupported Media type", req);
21554             } else {
21555                /* Unacceptable codecs */
21556                transmit_response_reliable(p, "488 Not acceptable here", req);
21557             }
21558             p->invitestate = INV_COMPLETED;
21559             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21560             ast_debug(1, "No compatible codecs for this SIP call.\n");
21561             res = -1;
21562             goto request_invite_cleanup;
21563          }
21564       } else { /* No SDP in invite, call control session */
21565          p->jointcapability = p->capability;
21566          ast_debug(2, "No SDP in Invite, third party call control\n");
21567       }
21568 
21569       /* Queue NULL frame to prod ast_rtp_bridge if appropriate */
21570       /* This seems redundant ... see !p-owner above */
21571       if (p->owner)
21572          ast_queue_frame(p->owner, &ast_null_frame);
21573 
21574 
21575       /* Initialize the context if it hasn't been already */
21576       if (ast_strlen_zero(p->context))
21577          ast_string_field_set(p, context, sip_cfg.default_context);
21578 
21579 
21580       /* Check number of concurrent calls -vs- incoming limit HERE */
21581       ast_debug(1, "Checking SIP call limits for device %s\n", p->username);
21582       if ((res = update_call_counter(p, INC_CALL_LIMIT))) {
21583          if (res < 0) {
21584             ast_log(LOG_NOTICE, "Failed to place call for device %s, too many calls\n", p->username);
21585             transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req);
21586             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21587             p->invitestate = INV_COMPLETED;
21588          }
21589          res = 0;
21590          goto request_invite_cleanup;
21591       }
21592       gotdest = get_destination(p, NULL, &cc_recall_core_id);  /* Get destination right away */
21593       extract_uri(p, req);       /* Get the Contact URI */
21594       build_contact(p);       /* Build our contact header */
21595 
21596       if (p->rtp) {
21597          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
21598          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
21599       }
21600 
21601       if (!replace_id && (gotdest != SIP_GET_DEST_EXTEN_FOUND)) { /* No matching extension found */
21602          switch(gotdest) {
21603          case SIP_GET_DEST_INVALID_URI:
21604             transmit_response_reliable(p, "416 Unsupported URI scheme", req);
21605             break;
21606          case SIP_GET_DEST_PICKUP_EXTEN_FOUND:
21607             if (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) {
21608                transmit_response_reliable(p, "484 Address Incomplete", req);
21609                break;
21610             }
21611          /* INTENTIONAL FALL THROUGH */
21612          case SIP_GET_DEST_EXTEN_NOT_FOUND:
21613          case SIP_GET_DEST_REFUSED:
21614          default:
21615             {
21616                char *decoded_exten = ast_strdupa(p->exten);
21617                transmit_response_reliable(p, "404 Not Found", req);
21618                ast_uri_decode(decoded_exten);
21619                ast_log(LOG_NOTICE, "Call from '%s' to extension"
21620                   " '%s' rejected because extension not found in context '%s'.\n",
21621                   S_OR(p->username, p->peername), decoded_exten, p->context);
21622             }
21623          } /* end switch */
21624 
21625          p->invitestate = INV_COMPLETED;
21626          update_call_counter(p, DEC_CALL_LIMIT);
21627          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21628          res = 0;
21629          goto request_invite_cleanup;
21630       } else {
21631 
21632          /* If no extension was specified, use the s one */
21633          /* Basically for calling to IP/Host name only */
21634          if (ast_strlen_zero(p->exten))
21635             ast_string_field_set(p, exten, "s");
21636          /* Initialize our tag */
21637 
21638          make_our_tag(p->tag, sizeof(p->tag));
21639          /* First invitation - create the channel.  Allocation
21640           * failures are handled below. */
21641          c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL), NULL);
21642          if (cc_recall_core_id != -1) {
21643             ast_setup_cc_recall_datastore(c, cc_recall_core_id);
21644             ast_cc_agent_set_interfaces_chanvar(c);
21645          }
21646          *recount = 1;
21647 
21648          /* Save Record-Route for any later requests we make on this dialogue */
21649          build_route(p, req, 0);
21650 
21651          if (c) {
21652             ast_party_redirecting_init(&redirecting);
21653             memset(&update_redirecting, 0, sizeof(update_redirecting));
21654             /* Pre-lock the call */
21655             ast_channel_lock(c);
21656             change_redirecting_information(p, req, &redirecting, &update_redirecting,
21657                FALSE); /*Will return immediately if no Diversion header is present */
21658             ast_channel_set_redirecting(c, &redirecting, &update_redirecting);
21659             ast_party_redirecting_free(&redirecting);
21660          }
21661       }
21662    } else {
21663       ast_party_redirecting_init(&redirecting);
21664       memset(&update_redirecting, 0, sizeof(update_redirecting));
21665       if (sipdebug) {
21666          if (!req->ignore)
21667             ast_debug(2, "Got a SIP re-invite for call %s\n", p->callid);
21668          else
21669             ast_debug(2, "Got a SIP re-transmit of INVITE for call %s\n", p->callid);
21670       }
21671       if (!req->ignore)
21672          reinvite = 1;
21673       c = p->owner;
21674       change_redirecting_information(p, req, &redirecting, &update_redirecting, FALSE); /*Will return immediately if no Diversion header is present */
21675       if (c) {
21676          ast_channel_set_redirecting(c, &redirecting, &update_redirecting);
21677       }
21678       ast_party_redirecting_free(&redirecting);
21679    }
21680 
21681    /* Session-Timers */
21682    if ((p->sipoptions & SIP_OPT_TIMER) && !ast_strlen_zero(get_header(req, "Session-Expires"))) {
21683       /* The UAC has requested session-timers for this session. Negotiate
21684       the session refresh interval and who will be the refresher */
21685       ast_debug(2, "Incoming INVITE with 'timer' option supported and \"Session-Expires\" header.\n");
21686 
21687       /* Allocate Session-Timers struct w/in the dialog */
21688       if (!p->stimer)
21689          sip_st_alloc(p);
21690 
21691       /* Parse the Session-Expires header */
21692       p_uac_se_hdr = get_header(req, "Session-Expires");
21693       rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref);
21694       if (rtn != 0) {
21695          transmit_response_reliable(p, "400 Session-Expires Invalid Syntax", req);
21696          p->invitestate = INV_COMPLETED;
21697          if (!p->lastinvite) {
21698             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21699          }
21700          res = -1;
21701          goto request_invite_cleanup;
21702       }
21703 
21704       /* Parse the Min-SE header */
21705       p_uac_min_se = get_header(req, "Min-SE");
21706       if (!ast_strlen_zero(p_uac_min_se)) {
21707          rtn = parse_minse(p_uac_min_se, &uac_min_se);
21708          if (rtn != 0) {
21709             transmit_response_reliable(p, "400 Min-SE Invalid Syntax", req);
21710             p->invitestate = INV_COMPLETED;
21711             if (!p->lastinvite) {
21712                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21713             }
21714             res = -1;
21715             goto request_invite_cleanup;
21716          }
21717       }
21718 
21719       dlg_min_se = st_get_se(p, FALSE);
21720       switch (st_get_mode(p)) {
21721       case SESSION_TIMER_MODE_ACCEPT:
21722       case SESSION_TIMER_MODE_ORIGINATE:
21723          if (uac_max_se > 0 && uac_max_se < dlg_min_se) {
21724             transmit_response_with_minse(p, "422 Session Interval Too Small", req, dlg_min_se);
21725             p->invitestate = INV_COMPLETED;
21726             if (!p->lastinvite) {
21727                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21728             }
21729             res = -1;
21730             goto request_invite_cleanup;
21731          }
21732 
21733          p->stimer->st_active_peer_ua = TRUE;
21734          st_active = TRUE;
21735          if (st_ref == SESSION_TIMER_REFRESHER_AUTO) {
21736             st_ref = st_get_refresher(p);
21737          }
21738 
21739          if (uac_max_se > 0) {
21740             int dlg_max_se = st_get_se(p, TRUE);
21741             if (dlg_max_se >= uac_min_se) {
21742                st_interval = (uac_max_se < dlg_max_se) ? uac_max_se : dlg_max_se;
21743             } else {
21744                st_interval = uac_max_se;
21745             }
21746          } else {
21747             /* Set to default max value */
21748             st_interval = global_max_se;
21749          }
21750          break;
21751 
21752       case SESSION_TIMER_MODE_REFUSE:
21753          if (p->reqsipoptions & SIP_OPT_TIMER) {
21754             transmit_response_with_unsupported(p, "420 Option Disabled", req, required);
21755             ast_log(LOG_WARNING, "Received SIP INVITE with supported but disabled option: %s\n", required);
21756             p->invitestate = INV_COMPLETED;
21757             if (!p->lastinvite) {
21758                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21759             }
21760             res = -1;
21761             goto request_invite_cleanup;
21762          }
21763          break;
21764 
21765       default:
21766          ast_log(LOG_ERROR, "Internal Error %d at %s:%d\n", st_get_mode(p), __FILE__, __LINE__);
21767          break;
21768       }
21769    } else {
21770       /* The UAC did not request session-timers.  Asterisk (UAS), will now decide
21771       (based on session-timer-mode in sip.conf) whether to run session-timers for
21772       this session or not. */
21773       switch (st_get_mode(p)) {
21774       case SESSION_TIMER_MODE_ORIGINATE:
21775          st_active = TRUE;
21776          st_interval = st_get_se(p, TRUE);
21777          st_ref = SESSION_TIMER_REFRESHER_UAS;
21778          p->stimer->st_active_peer_ua = FALSE;
21779          break;
21780 
21781       default:
21782          break;
21783       }
21784    }
21785 
21786    if (reinvite == 0) {
21787       /* Session-Timers: Start session refresh timer based on negotiation/config */
21788       if (st_active == TRUE) {
21789          p->stimer->st_active   = TRUE;
21790          p->stimer->st_interval = st_interval;
21791          p->stimer->st_ref      = st_ref;
21792          start_session_timer(p);
21793       }
21794    } else {
21795       if (p->stimer->st_active == TRUE) {
21796          /* Session-Timers:  A re-invite request sent within a dialog will serve as
21797          a refresh request, no matter whether the re-invite was sent for refreshing
21798          the session or modifying it.*/
21799          ast_debug (2, "Restarting session-timers on a refresh - %s\n", p->callid);
21800 
21801          /* The UAC may be adjusting the session-timers mid-session */
21802          if (st_interval > 0) {
21803             p->stimer->st_interval = st_interval;
21804             p->stimer->st_ref      = st_ref;
21805          }
21806 
21807          restart_session_timer(p);
21808          if (p->stimer->st_expirys > 0) {
21809             p->stimer->st_expirys--;
21810          }
21811       }
21812    }
21813 
21814    if (!req->ignore && p)
21815       p->lastinvite = seqno;
21816 
21817    if (c && replace_id) {  /* Attended transfer or call pickup - we're the target */
21818       if (!ast_strlen_zero(pickup.exten)) {
21819          append_history(p, "Xfer", "INVITE/Replace received");
21820 
21821          /* Let the caller know we're giving it a shot */
21822          transmit_response(p, "100 Trying", req);
21823          p->invitestate = INV_PROCEEDING;
21824          ast_setstate(c, AST_STATE_RING);
21825 
21826          /* Do the pickup itself */
21827          ast_channel_unlock(c);
21828          *nounlock = 1;
21829 
21830          /* since p->owner (c) is unlocked, we need to go ahead and unlock pvt for both
21831           * magic pickup and ast_hangup.  Both of these functions will attempt to lock
21832           * p->owner again, which can cause a deadlock if we already hold a lock on p.
21833           * Locking order is, channel then pvt.  Dead lock avoidance must be used if
21834           * called the other way around. */
21835          sip_pvt_unlock(p);
21836          do_magic_pickup(c, pickup.exten, pickup.context);
21837          /* Now we're either masqueraded or we failed to pickup, in either case we... */
21838          ast_hangup(c);
21839          sip_pvt_lock(p); /* pvt is expected to remain locked on return, so re-lock it */
21840 
21841          res = 0;
21842          goto request_invite_cleanup;
21843       } else {
21844          /* Go and take over the target call */
21845          if (sipdebug)
21846             ast_debug(4, "Sending this call to the invite/replcaes handler %s\n", p->callid);
21847          res = handle_invite_replaces(p, req, debug, seqno, addr, nounlock);
21848          refer_locked = 0;
21849          goto request_invite_cleanup;
21850       }
21851    }
21852 
21853 
21854    if (c) { /* We have a call  -either a new call or an old one (RE-INVITE) */
21855       enum ast_channel_state c_state = c->_state;
21856 
21857       if (c_state != AST_STATE_UP && reinvite &&
21858          (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) {
21859          /* If these conditions are true, and the channel is still in the 'ringing'
21860           * state, then this likely means that we have a situation where the initial
21861           * INVITE transaction has completed *but* the channel's state has not yet been
21862           * changed to UP. The reason this could happen is if the reinvite is received
21863           * on the SIP socket prior to an application calling ast_read on this channel
21864           * to read the answer frame we earlier queued on it. In this case, the reinvite
21865           * is completely legitimate so we need to handle this the same as if the channel
21866           * were already UP. Thus we are purposely falling through to the AST_STATE_UP case.
21867           */
21868          c_state = AST_STATE_UP;
21869       }
21870 
21871       switch(c_state) {
21872       case AST_STATE_DOWN:
21873          ast_debug(2, "%s: New call is still down.... Trying... \n", c->name);
21874          transmit_provisional_response(p, "100 Trying", req, 0);
21875          p->invitestate = INV_PROCEEDING;
21876          ast_setstate(c, AST_STATE_RING);
21877          if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */
21878             enum ast_pbx_result result;
21879 
21880             result = ast_pbx_start(c);
21881 
21882             switch(result) {
21883             case AST_PBX_FAILED:
21884                ast_log(LOG_WARNING, "Failed to start PBX :(\n");
21885                p->invitestate = INV_COMPLETED;
21886                transmit_response_reliable(p, "503 Unavailable", req);
21887                break;
21888             case AST_PBX_CALL_LIMIT:
21889                ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
21890                p->invitestate = INV_COMPLETED;
21891                transmit_response_reliable(p, "480 Temporarily Unavailable", req);
21892                break;
21893             case AST_PBX_SUCCESS:
21894                /* nothing to do */
21895                break;
21896             }
21897 
21898             if (result) {
21899 
21900                /* Unlock locks so ast_hangup can do its magic */
21901                ast_channel_unlock(c);
21902                sip_pvt_unlock(p);
21903                ast_hangup(c);
21904                sip_pvt_lock(p);
21905                c = NULL;
21906             }
21907          } else { /* Pickup call in call group */
21908             ast_channel_unlock(c);
21909             *nounlock = 1;
21910             if (ast_pickup_call(c)) {
21911                ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid);
21912                transmit_response_reliable(p, "503 Unavailable", req);
21913                sip_alreadygone(p);
21914                /* Unlock locks so ast_hangup can do its magic */
21915                sip_pvt_unlock(p);
21916                c->hangupcause = AST_CAUSE_CALL_REJECTED;
21917             } else {
21918                sip_pvt_unlock(p);
21919                c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
21920             }
21921             p->invitestate = INV_COMPLETED;
21922             ast_hangup(c);
21923             sip_pvt_lock(p);
21924             c = NULL;
21925          }
21926          break;
21927       case AST_STATE_RING:
21928          transmit_provisional_response(p, "100 Trying", req, 0);
21929          p->invitestate = INV_PROCEEDING;
21930          break;
21931       case AST_STATE_RINGING:
21932          transmit_provisional_response(p, "180 Ringing", req, 0);
21933          p->invitestate = INV_PROCEEDING;
21934          break;
21935       case AST_STATE_UP:
21936          ast_debug(2, "%s: This call is UP.... \n", c->name);
21937 
21938          transmit_response(p, "100 Trying", req);
21939 
21940          if (p->t38.state == T38_PEER_REINVITE) {
21941             p->t38id = ast_sched_add(sched, 5000, sip_t38_abort, dialog_ref(p, "passing dialog ptr into sched structure based on t38id for sip_t38_abort."));
21942          } else if (p->t38.state == T38_ENABLED) {
21943             ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
21944             transmit_response_with_t38_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ?  XMIT_UNRELIABLE : XMIT_CRITICAL)));
21945          } else if (p->t38.state == T38_DISABLED) {
21946             /* If this is not a re-invite or something to ignore - it's critical */
21947             if (p->srtp && !ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)) {
21948                ast_log(LOG_WARNING, "Target does not support required crypto\n");
21949                transmit_response_reliable(p, "488 Not Acceptable Here (crypto)", req);
21950             } else {
21951                ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
21952                transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ?  XMIT_UNRELIABLE : XMIT_CRITICAL)), p->session_modify == TRUE ? FALSE : TRUE, FALSE);
21953             }
21954          }
21955 
21956          p->invitestate = INV_TERMINATED;
21957          break;
21958       default:
21959          ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state);
21960          transmit_response(p, "100 Trying", req);
21961          break;
21962       }
21963    } else {
21964       if (p && (p->autokillid == -1)) {
21965          const char *msg;
21966 
21967          if (!p->jointcapability)
21968             msg = "488 Not Acceptable Here (codec error)";
21969          else {
21970             ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n");
21971             msg = "503 Unavailable";
21972          }
21973          transmit_response_reliable(p, msg, req);
21974          p->invitestate = INV_COMPLETED;
21975          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21976       }
21977    }
21978 
21979 request_invite_cleanup:
21980 
21981    if (refer_locked && p->refer && p->refer->refer_call) {
21982       sip_pvt_unlock(p->refer->refer_call);
21983       if (p->refer->refer_call->owner) {
21984          ast_channel_unlock(p->refer->refer_call->owner);
21985       }
21986    }
21987    if (authpeer) {
21988       authpeer = unref_peer(authpeer, "unref_peer, from handle_request_invite authpeer");
21989    }
21990 
21991    return res;
21992 }

static int handle_request_message ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

Handle incoming MESSAGE request.

Definition at line 22802 of file chan_sip.c.

References ast_verbose, receive_message(), and transmit_response().

Referenced by handle_incoming().

22803 {
22804    if (!req->ignore) {
22805       if (req->debug)
22806          ast_verbose("Receiving message!\n");
22807       receive_message(p, req);
22808    } else
22809       transmit_response(p, "202 Accepted", req);
22810    return 1;
22811 }

static int handle_request_notify ( struct sip_pvt *  p,
struct sip_request *  req,
struct ast_sockaddr *  addr,
int  seqno,
const char *  e 
) [static]

Handle incoming notifications.

Definition at line 20670 of file chan_sip.c.

References AST_CONTROL_TRANSFER, ast_debug, AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_new(), ast_event_queue_and_cache(), ast_log(), ast_queue_control_data(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), AST_TRANSFER_FAILED, AST_TRANSFER_SUCCESS, FALSE, find_peer(), get_body(), get_header(), get_msg_text(), handle_cc_notify(), LOG_NOTICE, LOG_WARNING, mailbox, sip_scheddestroy(), strsep(), transmit_response(), TRUE, and unref_peer().

Referenced by handle_incoming().

20671 {
20672    /* This is mostly a skeleton for future improvements */
20673    /* Mostly created to return proper answers on notifications on outbound REFER's */
20674    int res = 0;
20675    const char *event = get_header(req, "Event");
20676    char *eventid = NULL;
20677    char *sep;
20678 
20679    if( (sep = strchr(event, ';')) ) {  /* XXX bug here - overwriting string ? */
20680       *sep++ = '\0';
20681       eventid = sep;
20682    }
20683    
20684    if (sipdebug)
20685       ast_debug(2, "Got NOTIFY Event: %s\n", event);
20686 
20687    if (!strcmp(event, "refer")) {
20688       /* Save nesting depth for now, since there might be other events we will
20689          support in the future */
20690 
20691       /* Handle REFER notifications */
20692 
20693       char buf[1024];
20694       char *cmd, *code;
20695       int respcode;
20696       int success = TRUE;
20697 
20698       /* EventID for each transfer... EventID is basically the REFER cseq
20699 
20700        We are getting notifications on a call that we transfered
20701        We should hangup when we are getting a 200 OK in a sipfrag
20702        Check if we have an owner of this event */
20703       
20704       /* Check the content type */
20705       if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) {
20706          /* We need a sipfrag */
20707          transmit_response(p, "400 Bad request", req);
20708          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20709          return -1;
20710       }
20711 
20712       /* Get the text of the attachment */
20713       if (get_msg_text(buf, sizeof(buf), req, TRUE)) {
20714          ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid);
20715          transmit_response(p, "400 Bad request", req);
20716          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20717          return -1;
20718       }
20719 
20720       /*
20721       From the RFC...
20722       A minimal, but complete, implementation can respond with a single
20723       NOTIFY containing either the body:
20724          SIP/2.0 100 Trying
20725       
20726       if the subscription is pending, the body:
20727          SIP/2.0 200 OK
20728       if the reference was successful, the body:
20729          SIP/2.0 503 Service Unavailable
20730       if the reference failed, or the body:
20731          SIP/2.0 603 Declined
20732 
20733       if the REFER request was accepted before approval to follow the
20734       reference could be obtained and that approval was subsequently denied
20735       (see Section 2.4.7).
20736       
20737       If there are several REFERs in the same dialog, we need to
20738       match the ID of the event header...
20739       */
20740       ast_debug(3, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf);
20741       cmd = ast_skip_blanks(buf);
20742       code = cmd;
20743       /* We are at SIP/2.0 */
20744       while(*code && (*code > 32)) {   /* Search white space */
20745          code++;
20746       }
20747       *code++ = '\0';
20748       code = ast_skip_blanks(code);
20749       sep = code;
20750       sep++;
20751       while(*sep && (*sep > 32)) {  /* Search white space */
20752          sep++;
20753       }
20754       *sep++ = '\0';       /* Response string */
20755       respcode = atoi(code);
20756       switch (respcode) {
20757       case 200:   /* OK: The new call is up, hangup this call */
20758          /* Hangup the call that we are replacing */
20759          break;
20760       case 301: /* Moved permenantly */
20761       case 302: /* Moved temporarily */
20762          /* Do we get the header in the packet in this case? */
20763          success = FALSE;
20764          break;
20765       case 503:   /* Service Unavailable: The new call failed */
20766       case 603:   /* Declined: Not accepted */
20767             /* Cancel transfer, continue the current call */
20768          success = FALSE;
20769          break;
20770       case 0:     /* Parse error */
20771             /* Cancel transfer, continue the current call */
20772          ast_log(LOG_NOTICE, "Error parsing sipfrag in NOTIFY in response to REFER.\n");
20773          success = FALSE;
20774          break;
20775       default:
20776          if (respcode < 200) {
20777             /* ignore provisional responses */
20778             success = -1;
20779          } else {
20780             ast_log(LOG_NOTICE, "Got unknown code '%d' in NOTIFY in response to REFER.\n", respcode);
20781             success = FALSE;
20782          }
20783          break;
20784       }
20785       if (success == FALSE) {
20786          ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n");
20787       }
20788 
20789       if (p->owner && success != -1) {
20790          enum ast_control_transfer message = success ? AST_TRANSFER_SUCCESS : AST_TRANSFER_FAILED;
20791          ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
20792       }
20793       /* Confirm that we received this packet */
20794       transmit_response(p, "200 OK", req);
20795    } else if (!strcmp(event, "message-summary")) {
20796       const char *mailbox = NULL;
20797       char *c = ast_strdupa(get_body(req, "Voice-Message", ':'));
20798 
20799       if (!p->mwi) {
20800          struct sip_peer *peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type);
20801 
20802          if (peer) {
20803             mailbox = ast_strdupa(peer->unsolicited_mailbox);
20804             unref_peer(peer, "removing unsolicited mwi ref");
20805          }
20806       } else {
20807          mailbox = p->mwi->mailbox;
20808       }
20809 
20810       if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(c)) {
20811          char *old = strsep(&c, " ");
20812          char *new = strsep(&old, "/");
20813          struct ast_event *event;
20814 
20815          if ((event = ast_event_new(AST_EVENT_MWI,
20816                      AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
20817                      AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, "SIP_Remote",
20818                      AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, atoi(new),
20819                      AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, atoi(old),
20820                      AST_EVENT_IE_END))) {
20821             ast_event_queue_and_cache(event);
20822          }
20823          transmit_response(p, "200 OK", req);
20824       } else {
20825          transmit_response(p, "489 Bad event", req);
20826          res = -1;
20827       }
20828    } else if (!strcmp(event, "keep-alive")) {
20829        /* Used by Sipura/Linksys for NAT pinhole,
20830         * just confirm that we received the packet. */
20831       transmit_response(p, "200 OK", req);
20832    } else if (!strcmp(event, "call-completion")) {
20833       res = handle_cc_notify(p, req);
20834    } else {
20835       /* We don't understand this event. */
20836       transmit_response(p, "489 Bad event", req);
20837       res = -1;
20838    }
20839 
20840    if (!p->lastinvite)
20841       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20842 
20843    return res;
20844 }

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

Handle incoming OPTIONS request An OPTIONS request should be answered like an INVITE from the same UA, including SDP.

Definition at line 20849 of file chan_sip.c.

References ast_log(), ast_shutting_down(), ast_string_field_set, ast_strlen_zero(), build_contact(), check_user(), context, copy_request(), get_destination(), get_header(), LOG_NOTICE, set_pvt_allowed_methods(), sip_cfg, sip_scheddestroy(), transmit_fake_auth_response(), transmit_response(), and transmit_response_with_allow().

Referenced by handle_incoming().

20850 {
20851    int res;
20852 
20853    if (p->lastinvite) {
20854       /* if this is a request in an active dialog, just confirm that the dialog exists. */
20855       transmit_response_with_allow(p, "200 OK", req, 0);
20856       return 0;
20857    }
20858 
20859    if (sip_cfg.auth_options_requests) {
20860       /* Do authentication if this OPTIONS request began the dialog */
20861       copy_request(&p->initreq, req);
20862       set_pvt_allowed_methods(p, req);
20863       res = check_user(p, req, SIP_OPTIONS, e, XMIT_UNRELIABLE, addr);
20864       if (res == AUTH_CHALLENGE_SENT) {
20865          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20866          return 0;
20867       }
20868       if (res < 0) { /* Something failed in authentication */
20869          if (res == AUTH_FAKE_AUTH) {
20870             ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From"));
20871             transmit_fake_auth_response(p, SIP_OPTIONS, req, XMIT_UNRELIABLE);
20872          } else {
20873             ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
20874             transmit_response(p, "403 Forbidden", req);
20875          }
20876          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20877          return 0;
20878       }
20879    }
20880 
20881    /* must go through authentication before getting here */
20882    res = (get_destination(p, req, NULL) == SIP_GET_DEST_EXTEN_FOUND ? 0 : -1);
20883    build_contact(p);
20884 
20885    if (ast_strlen_zero(p->context))
20886       ast_string_field_set(p, context, sip_cfg.default_context);
20887 
20888    if (ast_shutting_down())
20889       transmit_response_with_allow(p, "503 Unavailable", req, 0);
20890    else if (res < 0)
20891       transmit_response_with_allow(p, "404 Not Found", req, 0);
20892    else
20893       transmit_response_with_allow(p, "200 OK", req, 0);
20894 
20895    /* Destroy if this OPTIONS was the opening request, but not if
20896       it's in the middle of a normal call flow. */
20897    sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20898 
20899    return res;
20900 }

static int handle_request_publish ( struct sip_pvt *  p,
struct sip_request *  req,
struct ast_sockaddr *  addr,
const int  seqno,
const char *  uri 
) [static]

Definition at line 23233 of file chan_sip.c.

References __sip_ack(), ast_log(), ast_string_field_set, ast_strlen_zero(), check_user(), determine_sip_publish_type(), get_esc(), get_header(), handle_sip_publish_initial(), handle_sip_publish_modify(), handle_sip_publish_refresh(), handle_sip_publish_remove(), LOG_NOTICE, sip_scheddestroy(), transmit_fake_auth_response(), transmit_response(), and transmit_response_reliable().

Referenced by handle_incoming().

23234 {
23235    const char *etag = get_header(req, "SIP-If-Match");
23236    const char *event = get_header(req, "Event");
23237    struct event_state_compositor *esc;
23238    enum sip_publish_type publish_type;
23239    const char *expires_str = get_header(req, "Expires");
23240    int expires_int;
23241    int auth_result;
23242    int handler_result = -1;
23243 
23244    if (ast_strlen_zero(event)) {
23245       transmit_response(p, "489 Bad Event", req);
23246       return -1;
23247    }
23248 
23249    if (!(esc = get_esc(event))) {
23250       transmit_response(p, "489 Bad Event", req);
23251       return -1;
23252    }
23253 
23254    auth_result = check_user(p, req, SIP_PUBLISH, uri, XMIT_RELIABLE, addr);
23255    if (auth_result == AUTH_CHALLENGE_SENT) {
23256       p->lastinvite = seqno;
23257       return 0;
23258    } else if (auth_result < 0) {
23259       if (auth_result == AUTH_FAKE_AUTH) {
23260          ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From"));
23261          transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE);
23262       } else {
23263          ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
23264          transmit_response_reliable(p, "403 Forbidden", req);
23265       }
23266       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23267       ast_string_field_set(p, theirtag, NULL);
23268       return 0;
23269    } else if (auth_result == AUTH_SUCCESSFUL && p->lastinvite) {
23270       /* We need to stop retransmitting the 401 */
23271       __sip_ack(p, p->lastinvite, 1, 0);
23272    }
23273 
23274    publish_type = determine_sip_publish_type(req, event, etag, expires_str, &expires_int);
23275 
23276    /* It is the responsibility of these handlers to formulate any response
23277     * sent for a PUBLISH
23278     */
23279    switch (publish_type) {
23280    case SIP_PUBLISH_UNKNOWN:
23281       transmit_response(p, "400 Bad Request", req);
23282       break;
23283    case SIP_PUBLISH_INITIAL:
23284       handler_result = handle_sip_publish_initial(p, req, esc, expires_int);
23285       break;
23286    case SIP_PUBLISH_REFRESH:
23287       handler_result = handle_sip_publish_refresh(p, req, esc, etag, expires_int);
23288       break;
23289    case SIP_PUBLISH_MODIFY:
23290       handler_result = handle_sip_publish_modify(p, req, esc, etag, expires_int);
23291       break;
23292    case SIP_PUBLISH_REMOVE:
23293       handler_result = handle_sip_publish_remove(p, req, esc, etag);
23294       break;
23295    default:
23296       transmit_response(p, "400 Impossible Condition", req);
23297       break;
23298    }
23299 
23300    return handler_result;
23301 }

static int handle_request_refer ( struct sip_pvt *  p,
struct sip_request *  req,
int  debug,
int  seqno,
int *  nounlock 
) [static]

Definition at line 22257 of file chan_sip.c.

References append_history, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_NORMAL_CLEARING, AST_CEL_ATTENDEDTRANSFER, AST_CEL_BLINDTRANSFER, ast_cel_report_event(), ast_channel_ref, ast_channel_trylock, ast_channel_unlock, ast_channel_unref, ast_clear_flag, AST_CONTROL_UNHOLD, ast_debug, ast_indicate(), AST_LIST_EMPTY, ast_manager_event_multichan, ast_parking_ext_valid(), ast_queue_control(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose, check_sip_domain(), context, copy_request(), EVENT_FLAG_CALL, FALSE, get_refer_info(), local_attended_transfer(), ast_channel::name, pbx_builtin_setvar_helper(), pvt_set_needdestroy(), sip_alreadygone(), sip_cfg, sip_park(), sip_pvt_lock, sip_pvt_unlock, sip_refer_allocate(), transmit_notify_with_sipfrag(), transmit_response(), and TRUE.

Referenced by handle_incoming().

22258 {
22259    struct sip_dual current;   /* Chan1: Call between asterisk and transferer */
22260                /* Chan2: Call between asterisk and transferee */
22261 
22262    int res = 0;
22263    struct ast_channel *chans[2];
22264    current.req.data = NULL;
22265 
22266    if (req->debug)
22267       ast_verbose("Call %s got a SIP call transfer from %s: (REFER)!\n", p->callid, ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "callee" : "caller");
22268 
22269    if (!p->owner) {
22270       /* This is a REFER outside of an existing SIP dialog */
22271       /* We can't handle that, so decline it */
22272       ast_debug(3, "Call %s: Declined REFER, outside of dialog...\n", p->callid);
22273       transmit_response(p, "603 Declined (No dialog)", req);
22274       if (!req->ignore) {
22275          append_history(p, "Xfer", "Refer failed. Outside of dialog.");
22276          sip_alreadygone(p);
22277          pvt_set_needdestroy(p, "outside of dialog");
22278       }
22279       return 0;
22280    }
22281 
22282 
22283    /* Check if transfer is allowed from this device */
22284    if (p->allowtransfer == TRANSFER_CLOSED ) {
22285       /* Transfer not allowed, decline */
22286       transmit_response(p, "603 Declined (policy)", req);
22287       append_history(p, "Xfer", "Refer failed. Allowtransfer == closed.");
22288       /* Do not destroy SIP session */
22289       return 0;
22290    }
22291 
22292    if (!req->ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
22293       /* Already have a pending REFER */
22294       transmit_response(p, "491 Request pending", req);
22295       append_history(p, "Xfer", "Refer failed. Request pending.");
22296       return 0;
22297    }
22298 
22299    /* Allocate memory for call transfer data */
22300    if (!p->refer && !sip_refer_allocate(p)) {
22301       transmit_response(p, "500 Internal Server Error", req);
22302       append_history(p, "Xfer", "Refer failed. Memory allocation error.");
22303       return -3;
22304    }
22305 
22306    res = get_refer_info(p, req); /* Extract headers */
22307 
22308    p->refer->status = REFER_SENT;
22309 
22310    if (res != 0) {
22311       switch (res) {
22312       case -2: /* Syntax error */
22313          transmit_response(p, "400 Bad Request (Refer-to missing)", req);
22314          append_history(p, "Xfer", "Refer failed. Refer-to missing.");
22315          if (req->debug)
22316             ast_debug(1, "SIP transfer to black hole can't be handled (no refer-to: )\n");
22317          break;
22318       case -3:
22319          transmit_response(p, "603 Declined (Non sip: uri)", req);
22320          append_history(p, "Xfer", "Refer failed. Non SIP uri");
22321          if (req->debug)
22322             ast_debug(1, "SIP transfer to non-SIP uri denied\n");
22323          break;
22324       default:
22325          /* Refer-to extension not found, fake a failed transfer */
22326          transmit_response(p, "202 Accepted", req);
22327          append_history(p, "Xfer", "Refer failed. Bad extension.");
22328          transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE);
22329          ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
22330          if (req->debug)
22331             ast_debug(1, "SIP transfer to bad extension: %s\n", p->refer->refer_to);
22332          break;
22333       }
22334       return 0;
22335    }
22336    if (ast_strlen_zero(p->context))
22337       ast_string_field_set(p, context, sip_cfg.default_context);
22338 
22339    /* If we do not support SIP domains, all transfers are local */
22340    if (sip_cfg.allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
22341       p->refer->localtransfer = 1;
22342       if (sipdebug)
22343          ast_debug(3, "This SIP transfer is local : %s\n", p->refer->refer_to_domain);
22344    } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
22345       /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */
22346       p->refer->localtransfer = 1;
22347    } else if (sipdebug)
22348          ast_debug(3, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain);
22349 
22350    /* Is this a repeat of a current request? Ignore it */
22351    /* Don't know what else to do right now. */
22352    if (req->ignore)
22353       return res;
22354 
22355    /* If this is a blind transfer, we have the following
22356    channels to work with:
22357    - chan1, chan2: The current call between transferer and transferee (2 channels)
22358    - target_channel: A new call from the transferee to the target (1 channel)
22359    We need to stay tuned to what happens in order to be able
22360    to bring back the call to the transferer */
22361 
22362    /* If this is a attended transfer, we should have all call legs within reach:
22363    - chan1, chan2: The call between the transferer and transferee (2 channels)
22364    - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels)
22365    We want to bridge chan2 with targetcall_pvt!
22366    
22367    The replaces call id in the refer message points
22368    to the call leg between Asterisk and the transferer.
22369    So we need to connect the target and the transferee channel
22370    and hangup the two other channels silently
22371    
22372    If the target is non-local, the call ID could be on a remote
22373    machine and we need to send an INVITE with replaces to the
22374    target. We basically handle this as a blind transfer
22375    and let the sip_call function catch that we need replaces
22376    header in the INVITE.
22377    */
22378 
22379 
22380    /* Get the transferer's channel */
22381    chans[0] = current.chan1 = p->owner;
22382 
22383    /* Find the other part of the bridge (2) - transferee */
22384    chans[1] = current.chan2 = ast_bridged_channel(current.chan1);
22385 
22386    if (sipdebug)
22387       ast_debug(3, "SIP %s transfer: Transferer channel %s, transferee channel %s\n", p->refer->attendedtransfer ? "attended" : "blind", current.chan1->name, current.chan2 ? current.chan2->name : "<none>");
22388 
22389    if (!current.chan2 && !p->refer->attendedtransfer) {
22390       /* No bridged channel, propably IVR or echo or similar... */
22391       /* Guess we should masquerade or something here */
22392       /* Until we figure it out, refuse transfer of such calls */
22393       if (sipdebug)
22394          ast_debug(3, "Refused SIP transfer on non-bridged channel.\n");
22395       p->refer->status = REFER_FAILED;
22396       append_history(p, "Xfer", "Refer failed. Non-bridged channel.");
22397       transmit_response(p, "603 Declined", req);
22398       return -1;
22399    }
22400 
22401    if (current.chan2) {
22402       if (sipdebug)
22403          ast_debug(4, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name);
22404 
22405       ast_queue_control(current.chan1, AST_CONTROL_UNHOLD);
22406    }
22407 
22408    ast_set_flag(&p->flags[0], SIP_GOTREFER);
22409 
22410    /* From here on failures will be indicated with NOTIFY requests */
22411    transmit_response(p, "202 Accepted", req);
22412 
22413    /* Attended transfer: Find all call legs and bridge transferee with target*/
22414    if (p->refer->attendedtransfer) {
22415       if ((res = local_attended_transfer(p, &current, req, seqno, nounlock)))
22416          return res; /* We're done with the transfer */
22417       /* Fall through for remote transfers that we did not find locally */
22418       if (sipdebug)
22419          ast_debug(4, "SIP attended transfer: Still not our call - generating INVITE with replaces\n");
22420       /* Fallthrough if we can't find the call leg internally */
22421    }
22422 
22423    /* Must release lock now, because it will not longer
22424       be accessible after the transfer! */
22425    *nounlock = 1;
22426    /*
22427     * Increase ref count so that we can delay channel destruction until after
22428     * we get a chance to fire off some events.
22429     */
22430    ast_channel_ref(current.chan1);
22431    sip_pvt_unlock(p);
22432    ast_channel_unlock(current.chan1);
22433 
22434    /* Parking a call */
22435    if (p->refer->localtransfer && ast_parking_ext_valid(p->refer->refer_to, p->owner, p->owner->context)) {
22436       sip_pvt_lock(p);
22437       copy_request(&current.req, req);
22438       ast_clear_flag(&p->flags[0], SIP_GOTREFER);
22439       p->refer->status = REFER_200OK;
22440       append_history(p, "Xfer", "REFER to call parking.");
22441       ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans,
22442          "TransferMethod: SIP\r\n"
22443          "TransferType: Blind\r\n"
22444          "Channel: %s\r\n"
22445          "Uniqueid: %s\r\n"
22446          "SIP-Callid: %s\r\n"
22447          "TargetChannel: %s\r\n"
22448          "TargetUniqueid: %s\r\n"
22449          "TransferExten: %s\r\n"
22450          "Transfer2Parking: Yes\r\n",
22451          current.chan1->name,
22452          current.chan1->uniqueid,
22453          p->callid,
22454          current.chan2->name,
22455          current.chan2->uniqueid,
22456          p->refer->refer_to);
22457       if (sipdebug)
22458          ast_debug(4, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name);
22459       if (sip_park(current.chan2, current.chan1, req, seqno, p->refer->refer_to)) {
22460          transmit_notify_with_sipfrag(p, seqno, "500 Internal Server Error", TRUE);
22461       }
22462       ast_channel_unref(current.chan1);
22463       return res;
22464    }
22465 
22466    /* Blind transfers and remote attended xfers */
22467    if (current.chan1 && current.chan2) {
22468       ast_debug(3, "chan1->name: %s\n", current.chan1->name);
22469       pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name);
22470    }
22471 
22472    sip_pvt_lock(p);
22473 
22474    if (current.chan2) {
22475       pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name);
22476       pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain);
22477       pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes");
22478       /* One for the new channel */
22479       pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes");
22480       /* Attended transfer to remote host, prepare headers for the INVITE */
22481       if (p->refer->referred_by)
22482          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by);
22483    }
22484    /* Generate a Replaces string to be used in the INVITE during attended transfer */
22485    if (!ast_strlen_zero(p->refer->replaces_callid)) {
22486       char tempheader[SIPBUFSIZE];
22487       snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid,
22488             p->refer->replaces_callid_totag ? ";to-tag=" : "",
22489             p->refer->replaces_callid_totag,
22490             p->refer->replaces_callid_fromtag ? ";from-tag=" : "",
22491             p->refer->replaces_callid_fromtag);
22492       if (current.chan2)
22493          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader);
22494    }
22495 
22496    /* Connect the call */
22497 
22498    /* FAKE ringing if not attended transfer */
22499    if (!p->refer->attendedtransfer)
22500       transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE);
22501 
22502    /* For blind transfer, this will lead to a new call */
22503    /* For attended transfer to remote host, this will lead to
22504       a new SIP call with a replaces header, if the dial plan allows it
22505    */
22506    if (!current.chan2) {
22507       /* We have no bridge, so we're talking with Asterisk somehow */
22508       /* We need to masquerade this call */
22509       /* What to do to fix this situation:
22510          * Set up the new call in a new channel
22511          * Let the new channel masq into this channel
22512          Please add that code here :-)
22513       */
22514       p->refer->status = REFER_FAILED;
22515       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE);
22516       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
22517       append_history(p, "Xfer", "Refer failed (only bridged calls).");
22518       ast_channel_unref(current.chan1);
22519       return -1;
22520    }
22521    ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
22522 
22523 
22524    /* For blind transfers, move the call to the new extensions. For attended transfers on multiple
22525       servers - generate an INVITE with Replaces. Either way, let the dial plan decided  */
22526    /* indicate before masquerade so the indication actually makes it to the real channel
22527       when using local channels with MOH passthru */
22528    ast_indicate(current.chan2, AST_CONTROL_UNHOLD);
22529    res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1);
22530 
22531    if (!res) {
22532       ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans,
22533          "TransferMethod: SIP\r\n"
22534          "TransferType: Blind\r\n"
22535          "Channel: %s\r\n"
22536          "Uniqueid: %s\r\n"
22537          "SIP-Callid: %s\r\n"
22538          "TargetChannel: %s\r\n"
22539          "TargetUniqueid: %s\r\n"
22540          "TransferExten: %s\r\n"
22541          "TransferContext: %s\r\n",
22542          current.chan1->name,
22543          current.chan1->uniqueid,
22544          p->callid,
22545          current.chan2->name,
22546          current.chan2->uniqueid,
22547          p->refer->refer_to, p->refer->refer_to_context);
22548       /* Success  - we have a new channel */
22549       ast_debug(3, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind");
22550 
22551       while (ast_channel_trylock(current.chan1)) {
22552          sip_pvt_unlock(p);
22553          sched_yield();
22554          sip_pvt_lock(p);
22555       }
22556 
22557       /* XXX - what to we put in CEL 'extra' for attended transfers to external systems? NULL for now */
22558       ast_cel_report_event(current.chan1, p->refer->attendedtransfer? AST_CEL_ATTENDEDTRANSFER : AST_CEL_BLINDTRANSFER, NULL, p->refer->attendedtransfer ? NULL : p->refer->refer_to, current.chan2);
22559       ast_channel_unlock(current.chan1);
22560 
22561       transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE);
22562       if (p->refer->localtransfer)
22563          p->refer->status = REFER_200OK;
22564       if (p->owner)
22565          p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING;
22566       append_history(p, "Xfer", "Refer succeeded.");
22567       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
22568       /* Do not hangup call, the other side do that when we say 200 OK */
22569       /* We could possibly implement a timer here, auto congestion */
22570       res = 0;
22571    } else {
22572       ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */
22573       ast_debug(3, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind");
22574       append_history(p, "Xfer", "Refer failed.");
22575       /* Failure of some kind */
22576       p->refer->status = REFER_FAILED;
22577       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE);
22578       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
22579       res = -1;
22580    }
22581 
22582    ast_channel_unref(current.chan1);
22583 
22584    return res;
22585 }

static int handle_request_register ( struct sip_pvt *  p,
struct sip_request *  req,
struct ast_sockaddr *  sin,
const char *  e 
) [static]

Handle incoming REGISTER request.

Definition at line 23727 of file chan_sip.c.

References append_history, ast_debug, ast_log(), ast_sockaddr_stringify(), check_via(), copy_request(), get_header(), LOG_NOTICE, LOG_WARNING, register_verify(), sip_methods, sip_scheddestroy(), and cfsip_methods::text.

Referenced by handle_incoming().

23728 {
23729    enum check_auth_result res;
23730 
23731    /* If this is not the intial request, and the initial request isn't
23732     * a register, something screwy happened, so bail */
23733    if (p->initreq.headers && p->initreq.method != SIP_REGISTER) {
23734       ast_log(LOG_WARNING, "Ignoring spurious REGISTER with Call-ID: %s\n", p->callid);
23735       return -1;
23736    }
23737 
23738    /* Use this as the basis */
23739    copy_request(&p->initreq, req);
23740    if (sipdebug)
23741       ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
23742    check_via(p, req);
23743    if ((res = register_verify(p, addr, req, e)) < 0) {
23744       const char *reason;
23745 
23746       switch (res) {
23747       case AUTH_SECRET_FAILED:
23748          reason = "Wrong password";
23749          break;
23750       case AUTH_USERNAME_MISMATCH:
23751          reason = "Username/auth name mismatch";
23752          break;
23753       case AUTH_NOT_FOUND:
23754          reason = "No matching peer found";
23755          break;
23756       case AUTH_UNKNOWN_DOMAIN:
23757          reason = "Not a local domain";
23758          break;
23759       case AUTH_PEER_NOT_DYNAMIC:
23760          reason = "Peer is not supposed to register";
23761          break;
23762       case AUTH_ACL_FAILED:
23763          reason = "Device does not match ACL";
23764          break;
23765       case AUTH_BAD_TRANSPORT:
23766          reason = "Device not configured to use this transport type";
23767          break;
23768       default:
23769          reason = "Unknown failure";
23770          break;
23771       }
23772       ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
23773          get_header(req, "To"), ast_sockaddr_stringify(addr),
23774          reason);
23775       append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason);
23776    } else {
23777       req->authenticated = 1;
23778       append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To"));
23779    }
23780 
23781    if (res < 1) {
23782       /* Destroy the session, but keep us around for just a bit in case they don't
23783          get our 200 OK */
23784       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
23785    }
23786    return res;
23787 }

static int handle_request_subscribe ( struct sip_pvt *  p,
struct sip_request *  req,
struct ast_sockaddr *  addr,
int  seqno,
const char *  e 
) [static]

Handle incoming SUBSCRIBE request.

Definition at line 23373 of file chan_sip.c.

References __get_header(), add_peer_mwi_subs(), ao2_lock, ao2_unlock, append_history, ast_debug, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_extension_state_del(), AST_LIST_EMPTY, ast_log(), ast_set_flag, ast_sockaddr_stringify(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose, build_contact(), build_route(), cb_extensionstate(), check_user_full(), check_via(), copy_request(), dialog_unlink_all(), FALSE, get_destination(), get_header(), gettag(), handle_cc_subscribe(), LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), max_expiry, min_expiry, NONE, option_debug, parse_ok_contact(), pvt_set_needdestroy(), ref_peer(), set_pvt_allowed_methods(), sip_cancel_destroy(), sip_cfg, sip_methods, sip_scheddestroy(), sip_send_mwi_to_peer(), cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_minexpires(), transmit_state_notify(), TRUE, and unref_peer().

Referenced by handle_incoming().

23374 {
23375    int gotdest = 0;
23376    int res = 0;
23377    int firststate = AST_EXTENSION_REMOVED;
23378    struct sip_peer *authpeer = NULL;
23379    const char *eventheader = get_header(req, "Event");   /* Get Event package name */
23380    int resubscribe = (p->subscribed != NONE) && !req->ignore;
23381    char *temp, *event;
23382 
23383    if (p->initreq.headers) {  
23384       /* We already have a dialog */
23385       if (p->initreq.method != SIP_SUBSCRIBE) {
23386          /* This is a SUBSCRIBE within another SIP dialog, which we do not support */
23387          /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */
23388          transmit_response(p, "403 Forbidden (within dialog)", req);
23389          /* Do not destroy session, since we will break the call if we do */
23390          ast_debug(1, "Got a subscription within the context of another call, can't handle that - %s (Method %s)\n", p->callid, sip_methods[p->initreq.method].text);
23391          return 0;
23392       } else if (req->debug) {
23393          if (resubscribe)
23394             ast_debug(1, "Got a re-subscribe on existing subscription %s\n", p->callid);
23395          else
23396             ast_debug(1, "Got a new subscription %s (possibly with auth) or retransmission\n", p->callid);
23397       }
23398    }
23399 
23400    /* Check if we have a global disallow setting on subscriptions.
23401       if so, we don't have to check peer settings after auth, which saves a lot of processing
23402    */
23403    if (!sip_cfg.allowsubscribe) {
23404       transmit_response(p, "403 Forbidden (policy)", req);
23405       pvt_set_needdestroy(p, "forbidden");
23406       return 0;
23407    }
23408 
23409    if (!req->ignore && !resubscribe) { /* Set up dialog, new subscription */
23410       const char *to = get_header(req, "To");
23411       char totag[128];
23412       set_pvt_allowed_methods(p, req);
23413 
23414       /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */
23415       if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) {
23416          if (req->debug)
23417             ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n");
23418          transmit_response(p, "481 Subscription does not exist", req);
23419          pvt_set_needdestroy(p, "subscription does not exist");
23420          return 0;
23421       }
23422 
23423       /* Use this as the basis */
23424       if (req->debug)
23425          ast_verbose("Creating new subscription\n");
23426 
23427       copy_request(&p->initreq, req);
23428       if (sipdebug)
23429          ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
23430       check_via(p, req);
23431       build_route(p, req, 0);
23432    } else if (req->debug && req->ignore)
23433       ast_verbose("Ignoring this SUBSCRIBE request\n");
23434 
23435    /* Find parameters to Event: header value and remove them for now */
23436    if (ast_strlen_zero(eventheader)) {
23437       transmit_response(p, "489 Bad Event", req);
23438       ast_debug(2, "Received SIP subscribe for unknown event package: <none>\n");
23439       pvt_set_needdestroy(p, "unknown event package in subscribe");
23440       return 0;
23441    }
23442 
23443    if ( (strchr(eventheader, ';'))) {
23444       event = ast_strdupa(eventheader);   /* Since eventheader is a const, we can't change it */
23445       temp = strchr(event, ';');       
23446       *temp = '\0';           /* Remove any options for now */
23447                      /* We might need to use them later :-) */
23448    } else
23449       event = (char *) eventheader;    /* XXX is this legal ? */
23450 
23451    /* Handle authentication if we're new and not a retransmission. We can't just
23452     * use if !req->ignore, because then we'll end up sending
23453     * a 200 OK if someone retransmits without sending auth */
23454    if (p->subscribed == NONE || resubscribe) {
23455       res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, addr, &authpeer);
23456 
23457       /* if an authentication response was sent, we are done here */
23458       if (res == AUTH_CHALLENGE_SENT)  /* authpeer = NULL here */
23459          return 0;
23460       if (res < 0) {
23461          if (res == AUTH_FAKE_AUTH) {
23462             ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From"));
23463             transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE);
23464          } else {
23465             ast_log(LOG_NOTICE, "Failed to authenticate device %s for SUBSCRIBE\n", get_header(req, "From"));
23466             transmit_response_reliable(p, "403 Forbidden", req);
23467          }
23468 
23469          pvt_set_needdestroy(p, "authentication failed");
23470          return 0;
23471       }
23472    }
23473 
23474    /* At this point, authpeer cannot be NULL. Remember we hold a reference,
23475     * so we must release it when done.
23476     * XXX must remove all the checks for authpeer == NULL.
23477     */
23478 
23479    /* Check if this device  is allowed to subscribe at all */
23480    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
23481       transmit_response(p, "403 Forbidden (policy)", req);
23482       pvt_set_needdestroy(p, "subscription not allowed");
23483       if (authpeer)
23484          unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 1)");
23485       return 0;
23486    }
23487 
23488    if (strcmp(event, "message-summary") && strcmp(event, "call-completion")) {
23489       /* Get destination right away */
23490       gotdest = get_destination(p, NULL, NULL);
23491    }
23492 
23493    /* Get full contact header - this needs to be used as a request URI in NOTIFY's */
23494    parse_ok_contact(p, req);
23495 
23496    build_contact(p);
23497    if (gotdest != SIP_GET_DEST_EXTEN_FOUND) {
23498       if (gotdest == SIP_GET_DEST_INVALID_URI) {
23499          transmit_response(p, "416 Unsupported URI scheme", req);
23500       } else {
23501          transmit_response(p, "404 Not Found", req);
23502       }
23503       pvt_set_needdestroy(p, "subscription target not found");
23504       if (authpeer)
23505          unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)");
23506       return 0;
23507    }
23508 
23509    /* Initialize tag for new subscriptions */   
23510    if (ast_strlen_zero(p->tag))
23511       make_our_tag(p->tag, sizeof(p->tag));
23512 
23513    if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
23514       unsigned int pidf_xml;
23515       const char *accept;
23516       int start = 0;
23517       enum subscriptiontype subscribed = NONE;
23518       const char *unknown_acceptheader = NULL;
23519 
23520       if (authpeer)  /* We do not need the authpeer any more */
23521          unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)");
23522 
23523       /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
23524       accept = __get_header(req, "Accept", &start);
23525       while ((subscribed == NONE) && !ast_strlen_zero(accept)) {
23526          pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0;
23527 
23528          /* Older versions of Polycom firmware will claim pidf+xml, but really
23529           * they only support xpidf+xml. */
23530          if (pidf_xml && strstr(p->useragent, "Polycom")) {
23531             subscribed = XPIDF_XML;
23532          } else if (pidf_xml) {
23533             subscribed = PIDF_XML;         /* RFC 3863 format */
23534          } else if (strstr(accept, "application/dialog-info+xml")) {
23535             subscribed = DIALOG_INFO_XML;
23536             /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
23537          } else if (strstr(accept, "application/cpim-pidf+xml")) {
23538             subscribed = CPIM_PIDF_XML;    /* RFC 3863 format */
23539          } else if (strstr(accept, "application/xpidf+xml")) {
23540             subscribed = XPIDF_XML;        /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
23541          } else {
23542             unknown_acceptheader = accept;
23543          }
23544          /* check to see if there is another Accept header present */
23545          accept = __get_header(req, "Accept", &start);
23546       }
23547 
23548       if (!start) {
23549          if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
23550             transmit_response(p, "489 Bad Event", req);
23551             ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: "
23552                "stateid: %d, laststate: %d, dialogver: %d, subscribecont: "
23553                "'%s', subscribeuri: '%s'\n",
23554                p->stateid,
23555                p->laststate,
23556                p->dialogver,
23557                p->subscribecontext,
23558                p->subscribeuri);
23559             pvt_set_needdestroy(p, "no Accept header");
23560             return 0;
23561          }
23562          /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
23563             so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */
23564       } else if (subscribed == NONE) {
23565          /* Can't find a format for events that we know about */
23566          char mybuf[200];
23567          if (!ast_strlen_zero(unknown_acceptheader)) {
23568             snprintf(mybuf, sizeof(mybuf), "489 Bad Event (format %s)", unknown_acceptheader);
23569          } else {
23570             snprintf(mybuf, sizeof(mybuf), "489 Bad Event");
23571          }
23572          transmit_response(p, mybuf, req);
23573          ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format:"
23574             "'%s' pvt: subscribed: %d, stateid: %d, laststate: %d,"
23575             "dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
23576             unknown_acceptheader,
23577             (int)p->subscribed,
23578             p->stateid,
23579             p->laststate,
23580             p->dialogver,
23581             p->subscribecontext,
23582             p->subscribeuri);
23583          pvt_set_needdestroy(p, "unrecognized format");
23584          return 0;
23585       } else {
23586          p->subscribed = subscribed;
23587       }
23588    } else if (!strcmp(event, "message-summary")) {
23589       int start = 0;
23590       int found_supported = 0;
23591       const char *acceptheader;
23592 
23593       acceptheader = __get_header(req, "Accept", &start);
23594       while (!found_supported && !ast_strlen_zero(acceptheader)) {
23595          found_supported = strcmp(acceptheader, "application/simple-message-summary") ? 0 : 1;
23596          if (!found_supported && (option_debug > 2)) {
23597             ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader);
23598          }
23599          acceptheader = __get_header(req, "Accept", &start);
23600       }
23601       if (start && !found_supported) {
23602          /* Format requested that we do not support */
23603          transmit_response(p, "406 Not Acceptable", req);
23604          ast_debug(2, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader);
23605          pvt_set_needdestroy(p, "unknown format");
23606          if (authpeer)
23607             unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)");
23608          return 0;
23609       }
23610       /* Looks like they actually want a mailbox status
23611         This version of Asterisk supports mailbox subscriptions
23612         The subscribed URI needs to exist in the dial plan
23613         In most devices, this is configurable to the voicemailmain extension you use
23614       */
23615       if (!authpeer || AST_LIST_EMPTY(&authpeer->mailboxes)) {
23616          transmit_response(p, "404 Not found (no mailbox)", req);
23617          pvt_set_needdestroy(p, "received 404 response");
23618          ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name);
23619          if (authpeer)
23620             unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 4)");
23621          return 0;
23622       }
23623 
23624       p->subscribed = MWI_NOTIFICATION;
23625       if (ast_test_flag(&authpeer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY)) {
23626          add_peer_mwi_subs(authpeer);
23627       }
23628       if (authpeer->mwipvt && authpeer->mwipvt != p) {   /* Destroy old PVT if this is a new one */
23629          /* We only allow one subscription per peer */
23630          dialog_unlink_all(authpeer->mwipvt, TRUE, TRUE);
23631          authpeer->mwipvt = dialog_unref(authpeer->mwipvt, "unref dialog authpeer->mwipvt");
23632          /* sip_destroy(authpeer->mwipvt); */
23633       }
23634       if (authpeer->mwipvt)
23635          dialog_unref(authpeer->mwipvt, "Unref previously stored mwipvt dialog pointer");
23636       authpeer->mwipvt = dialog_ref(p, "setting peers' mwipvt to p");      /* Link from peer to pvt UH- should this be dialog_ref()? */
23637       if (p->relatedpeer)
23638          unref_peer(p->relatedpeer, "Unref previously stored relatedpeer ptr");
23639       p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer");  /* already refcounted...Link from pvt to peer UH- should this be dialog_ref()? */
23640       /* Do not release authpeer here */
23641    } else if (!strcmp(event, "call-completion")) {
23642       handle_cc_subscribe(p, req);
23643    } else { /* At this point, Asterisk does not understand the specified event */
23644       transmit_response(p, "489 Bad Event", req);
23645       ast_debug(2, "Received SIP subscribe for unknown event package: %s\n", event);
23646       pvt_set_needdestroy(p, "unknown event package");
23647       if (authpeer)
23648          unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 5)");
23649       return 0;
23650    }
23651 
23652    /* Add subscription for extension state from the PBX core */
23653    if (p->subscribed != MWI_NOTIFICATION  && p->subscribed != CALL_COMPLETION && !resubscribe) {
23654       if (p->stateid > -1) {
23655          ast_extension_state_del(p->stateid, cb_extensionstate);
23656          /* we need to dec the refcount, now that the extensionstate is removed */
23657          dialog_unref(p, "the extensionstate containing this dialog ptr was deleted");
23658       }
23659       p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, dialog_ref(p,"copying dialog ptr into extension state struct"));
23660    }
23661 
23662    if (!req->ignore && p)
23663       p->lastinvite = seqno;
23664    if (p && !p->needdestroy) {
23665       p->expiry = atoi(get_header(req, "Expires"));
23666 
23667       /* check if the requested expiry-time is within the approved limits from sip.conf */
23668       if (p->expiry > max_expiry) {
23669          p->expiry = max_expiry;
23670       } else if (p->expiry < min_expiry && p->expiry > 0) {
23671          transmit_response_with_minexpires(p, "423 Interval too small", req);
23672          ast_log(LOG_WARNING, "Received subscription for extension \"%s\" context \"%s\" "
23673             "with Expire header less that 'minexpire' limit. Received \"Expire: %d\" min is %d\n",
23674             p->exten, p->context, p->expiry, min_expiry);
23675          p->expiry = min_expiry;
23676          pvt_set_needdestroy(p, "Expires is less that the min expires allowed. ");
23677          return 0;
23678       }
23679 
23680       if (sipdebug) {
23681          if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) {
23682             ast_debug(2, "Adding subscription for mailbox notification - peer %s\n", p->relatedpeer->name);
23683          } else if (p->subscribed == CALL_COMPLETION) {
23684             ast_debug(2, "Adding CC subscription for peer %s\n", p->username);
23685          } else {
23686             ast_debug(2, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
23687          }
23688       }
23689       if (p->autokillid > -1 && sip_cancel_destroy(p))   /* Remove subscription expiry for renewals */
23690          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
23691       if (p->expiry > 0)
23692          sip_scheddestroy(p, (p->expiry + 10) * 1000);   /* Set timer for destruction of call at expiration */
23693 
23694       if (p->subscribed == MWI_NOTIFICATION) {
23695          ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
23696          transmit_response(p, "200 OK", req);
23697          if (p->relatedpeer) {   /* Send first notification */
23698             ao2_lock(p->relatedpeer); /* was WRLOCK */
23699             sip_send_mwi_to_peer(p->relatedpeer, NULL, 0);
23700             ao2_unlock(p->relatedpeer);
23701          }
23702       } else if (p->subscribed != CALL_COMPLETION) {
23703          if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
23704 
23705             ast_log(LOG_NOTICE, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension.\n", p->exten, p->context, ast_sockaddr_stringify(&p->sa));
23706             transmit_response(p, "404 Not found", req);
23707             pvt_set_needdestroy(p, "no extension for SUBSCRIBE");
23708             return 0;
23709          }
23710          ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
23711          transmit_response(p, "200 OK", req);
23712          transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */
23713          append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate));
23714          /* hide the 'complete' exten/context in the refer_to field for later display */
23715          ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context);
23716          /* Deleted the slow iteration of all sip dialogs to find old subscribes from this peer for exten@context */
23717 
23718       }
23719       if (!p->expiry) {
23720          pvt_set_needdestroy(p, "forcing expiration");
23721       }
23722    }
23723    return 1;
23724 }

static int handle_request_update ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

bare-bones support for SIP UPDATE

XXX This is not even close to being RFC 3311-compliant. We don't advertise that we support the UPDATE method, so no one should ever try sending us an UPDATE anyway. However, Asterisk can send an UPDATE to change connected line information, so we need to be prepared to handle this. The way we distinguish such an UPDATE is through the X-Asterisk-rpid-update header.

Actually updating the media session may be some future work.

Definition at line 21092 of file chan_sip.c.

References ast_channel_queue_connected_line_update(), AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, ast_party_connected_line_init(), ast_strlen_zero(), connected, get_header(), get_rpid(), and transmit_response().

Referenced by handle_incoming().

21093 {
21094    if (ast_strlen_zero(get_header(req, "X-Asterisk-rpid-update"))) {
21095       transmit_response(p, "501 Method Not Implemented", req);
21096       return 0;
21097    }
21098    if (get_rpid(p, req)) {
21099       struct ast_party_connected_line connected;
21100       struct ast_set_party_connected_line update_connected;
21101       ast_party_connected_line_init(&connected);
21102       memset(&update_connected, 0, sizeof(update_connected));
21103       if (p->cid_num) {
21104          update_connected.id.number = 1;
21105          connected.id.number.valid = 1;
21106          connected.id.number.str = (char *) p->cid_num;
21107          connected.id.number.presentation = p->callingpres;
21108       }
21109       if (p->cid_name) {
21110          update_connected.id.name = 1;
21111          connected.id.name.valid = 1;
21112          connected.id.name.str = (char *) p->cid_name;
21113          connected.id.name.presentation = p->callingpres;
21114       }
21115       connected.id.tag = (char *) p->cid_tag;
21116       connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
21117       ast_channel_queue_connected_line_update(p->owner, &connected, &update_connected);
21118    }
21119    transmit_response(p, "200 OK", req);
21120    return 0;
21121 }

static void handle_response ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
int  seqno 
) [static]

Handle SIP response in dialogue.

Note:
only called by handle_incoming

Definition at line 19882 of file chan_sip.c.

References __sip_ack(), __sip_semi_ack(), ao2_callback, append_history, AST_CAUSE_PROTOCOL_ERROR, AST_CC_CCBS, ast_cc_monitor_failed(), ast_channel_set_redirecting(), ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_debug, ast_log(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_queue_control(), ast_queue_hangup_with_cause(), ast_set_flag, ast_skip_blanks(), ast_skip_nonblanks(), ast_sockaddr_stringify(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose, cb_extensionstate(), change_redirecting_information(), do_proxy_auth(), FALSE, find_sdp(), find_sip_method(), find_sip_monitor_instance_by_subscription_pvt(), get_header(), gettag(), handle_response_invite(), handle_response_notify(), handle_response_peerpoke(), handle_response_publish(), handle_response_refer(), handle_response_register(), handle_response_subscribe(), handle_response_update(), hangup_sip2cause(), ast_channel::hangupcause, LOG_NOTICE, LOG_WARNING, mark_method_allowed(), mark_method_unallowed(), process_sdp(), pvt_set_needdestroy(), rh, sip_alreadygone(), sip_cancel_destroy(), sip_handle_cc(), sip_methods, sip_monitor_instances, stop_media_flows(), transmit_request(), TRUE, and update_redirecting().

19883 {
19884    struct ast_channel *owner;
19885    int sipmethod;
19886    int res = 1;
19887    const char *c = get_header(req, "Cseq");
19888    /* GCC 4.2 complains if I try to cast c as a char * when passing it to ast_skip_nonblanks, so make a copy of it */
19889    char *c_copy = ast_strdupa(c);
19890    /* Skip the Cseq and its subsequent spaces */
19891    const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy));
19892 
19893    if (!msg)
19894       msg = "";
19895 
19896    sipmethod = find_sip_method(msg);
19897 
19898    owner = p->owner;
19899    if (owner) {
19900       const char *rp = NULL, *rh = NULL;
19901 
19902       owner->hangupcause = 0;
19903       if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON) && (rh = get_header(req, "Reason"))) {
19904          rh = ast_skip_blanks(rh);
19905          if (!strncasecmp(rh, "Q.850", 5)) {
19906             rp = strstr(rh, "cause=");
19907             if (rp && sscanf(rp + 6, "%30d", &owner->hangupcause) == 1) {
19908                owner->hangupcause &= 0x7f;
19909                if (req->debug)
19910                   ast_verbose("Using Reason header for cause code: %d\n", owner->hangupcause);
19911             }
19912          }
19913       }
19914 
19915       if (!owner->hangupcause)
19916          owner->hangupcause = hangup_sip2cause(resp);
19917    }
19918 
19919    if (p->socket.type == SIP_TRANSPORT_UDP) {
19920       int ack_res = FALSE;
19921 
19922       /* Acknowledge whatever it is destined for */
19923       if ((resp >= 100) && (resp <= 199)) {
19924          /* NON-INVITE messages do not ack a 1XX response. RFC 3261 section 17.1.2.2 */
19925          if (sipmethod == SIP_INVITE) {
19926             ack_res = __sip_semi_ack(p, seqno, 0, sipmethod);
19927          }
19928       } else {
19929          ack_res = __sip_ack(p, seqno, 0, sipmethod);
19930       }
19931 
19932       if (ack_res == FALSE) {
19933          /* RFC 3261 13.2.2.4 and 17.1.1.2 - We must re-send ACKs to re-transmitted final responses */
19934          if (sipmethod == SIP_INVITE && resp >= 200) {
19935             transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, resp < 300 ? TRUE: FALSE);
19936          }
19937 
19938          append_history(p, "Ignore", "Ignoring this retransmit\n");
19939          return;
19940       }
19941    }
19942 
19943    /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */
19944    if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite)
19945       p->pendinginvite = 0;
19946 
19947    /* Get their tag if we haven't already */
19948    if (ast_strlen_zero(p->theirtag) || (resp >= 200)) {
19949       char tag[128];
19950 
19951       gettag(req, "To", tag, sizeof(tag));
19952       ast_string_field_set(p, theirtag, tag);
19953    }
19954    /* This needs to be configurable on a channel/peer level,
19955       not mandatory for all communication. Sadly enough, NAT implementations
19956       are not so stable so we can always rely on these headers.
19957       Temporarily disabled, while waiting for fix.
19958       Fix assigned to Rizzo :-)
19959    */
19960    /* check_via_response(p, req); */
19961 
19962    /* RFC 3261 Section 15 specifies that if we receive a 408 or 481
19963     * in response to a BYE, then we should end the current dialog
19964     * and session.  It is known that at least one phone manufacturer
19965     * potentially will send a 404 in response to a BYE, so we'll be
19966     * liberal in what we accept and end the dialog and session if we
19967     * receive any of those responses to a BYE.
19968     */
19969    if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) {
19970       pvt_set_needdestroy(p, "received 4XX response to a BYE");
19971       return;
19972    }
19973 
19974    if (p->relatedpeer && p->method == SIP_OPTIONS) {
19975       /* We don't really care what the response is, just that it replied back.
19976          Well, as long as it's not a 100 response...  since we might
19977          need to hang around for something more "definitive" */
19978       if (resp != 100)
19979          handle_response_peerpoke(p, resp, req);
19980    } else if (sipmethod == SIP_REFER && resp >= 200) {
19981       handle_response_refer(p, resp, rest, req, seqno);
19982    } else if (sipmethod == SIP_PUBLISH) {
19983       /* SIP PUBLISH transcends this morass of doodoo and instead
19984        * we just always call the response handler. Good gravy!
19985        */
19986       handle_response_publish(p, resp, rest, req, seqno);
19987    } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
19988       switch(resp) {
19989       case 100:   /* 100 Trying */
19990       case 101:   /* 101 Dialog establishment */
19991       case 183:   /* 183 Session Progress */
19992       case 180:   /* 180 Ringing */
19993       case 182:   /* 182 Queued */
19994       case 181:   /* 181 Call Is Being Forwarded */
19995          if (sipmethod == SIP_INVITE)
19996             handle_response_invite(p, resp, rest, req, seqno);
19997          break;
19998       case 200:   /* 200 OK */
19999          p->authtries = 0; /* Reset authentication counter */
20000          if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) {
20001             /* We successfully transmitted a message
20002                or a video update request in INFO */
20003             /* Nothing happens here - the message is inside a dialog */
20004          } else if (sipmethod == SIP_INVITE) {
20005             handle_response_invite(p, resp, rest, req, seqno);
20006          } else if (sipmethod == SIP_NOTIFY) {
20007             handle_response_notify(p, resp, rest, req, seqno);
20008          } else if (sipmethod == SIP_REGISTER) {
20009             res = handle_response_register(p, resp, rest, req, seqno);
20010          } else if (sipmethod == SIP_SUBSCRIBE) {
20011             ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
20012             handle_response_subscribe(p, resp, rest, req, seqno);
20013          } else if (sipmethod == SIP_BYE) {     /* Ok, we're ready to go */
20014             pvt_set_needdestroy(p, "received 200 response");
20015             ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
20016          }
20017          break;
20018       case 401: /* Not www-authorized on SIP method */
20019       case 407: /* Proxy auth required */
20020          if (sipmethod == SIP_INVITE)
20021             handle_response_invite(p, resp, rest, req, seqno);
20022          else if (sipmethod == SIP_NOTIFY)
20023             handle_response_notify(p, resp, rest, req, seqno);
20024          else if (sipmethod == SIP_SUBSCRIBE)
20025             handle_response_subscribe(p, resp, rest, req, seqno);
20026          else if (p->registry && sipmethod == SIP_REGISTER)
20027             res = handle_response_register(p, resp, rest, req, seqno);
20028          else if (sipmethod == SIP_UPDATE) {
20029             handle_response_update(p, resp, rest, req, seqno);
20030          } else if (sipmethod == SIP_BYE) {
20031             if (p->options)
20032                p->options->auth_type = resp;
20033             if (ast_strlen_zero(p->authname)) {
20034                ast_log(LOG_WARNING, "Asked to authenticate %s, to %s but we have no matching peer!\n",
20035                      msg, ast_sockaddr_stringify(&p->recv));
20036                pvt_set_needdestroy(p, "unable to authenticate BYE");
20037             } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp,  sipmethod, 0)) {
20038                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
20039                pvt_set_needdestroy(p, "failed to authenticate BYE");
20040             }
20041          } else {
20042             ast_log(LOG_WARNING, "Got authentication request (%d) on %s to '%s'\n", resp, sip_methods[sipmethod].text, get_header(req, "To"));
20043             pvt_set_needdestroy(p, "received 407 response");
20044          }
20045          break;
20046       case 403: /* Forbidden - we failed authentication */
20047          if (sipmethod == SIP_INVITE)
20048             handle_response_invite(p, resp, rest, req, seqno);
20049          else if (sipmethod == SIP_SUBSCRIBE)
20050             handle_response_subscribe(p, resp, rest, req, seqno);
20051          else if (p->registry && sipmethod == SIP_REGISTER)
20052             res = handle_response_register(p, resp, rest, req, seqno);
20053          else {
20054             ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg);
20055             pvt_set_needdestroy(p, "received 403 response");
20056          }
20057          break;
20058       case 404: /* Not found */
20059          if (p->registry && sipmethod == SIP_REGISTER)
20060             res = handle_response_register(p, resp, rest, req, seqno);
20061          else if (sipmethod == SIP_INVITE)
20062             handle_response_invite(p, resp, rest, req, seqno);
20063          else if (sipmethod == SIP_SUBSCRIBE)
20064             handle_response_subscribe(p, resp, rest, req, seqno);
20065          else if (owner)
20066             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
20067          break;
20068       case 423: /* Interval too brief */
20069          if (sipmethod == SIP_REGISTER)
20070             res = handle_response_register(p, resp, rest, req, seqno);
20071          break;
20072       case 408: /* Request timeout - terminate dialog */
20073          if (sipmethod == SIP_INVITE)
20074             handle_response_invite(p, resp, rest, req, seqno);
20075          else if (sipmethod == SIP_REGISTER)
20076             res = handle_response_register(p, resp, rest, req, seqno);
20077          else if (sipmethod == SIP_BYE) {
20078             pvt_set_needdestroy(p, "received 408 response");
20079             ast_debug(4, "Got timeout on bye. Thanks for the answer. Now, kill this call\n");
20080          } else {
20081             if (owner)
20082                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
20083             pvt_set_needdestroy(p, "received 408 response");
20084          }
20085          break;
20086 
20087       case 422: /* Session-Timers: Session Interval Too Small */
20088          if (sipmethod == SIP_INVITE) {
20089             handle_response_invite(p, resp, rest, req, seqno);
20090          }
20091          break;
20092 
20093       case 481: /* Call leg does not exist */
20094          if (sipmethod == SIP_INVITE) {
20095             handle_response_invite(p, resp, rest, req, seqno);
20096          } else if (sipmethod == SIP_SUBSCRIBE) {
20097             handle_response_subscribe(p, resp, rest, req, seqno);
20098          } else if (sipmethod == SIP_NOTIFY) {
20099             pvt_set_needdestroy(p, "received 481 response");
20100          } else if (sipmethod == SIP_BYE) {
20101             /* The other side has no transaction to bye,
20102             just assume it's all right then */
20103             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
20104          } else if (sipmethod == SIP_CANCEL) {
20105             /* The other side has no transaction to cancel,
20106             just assume it's all right then */
20107             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
20108          } else {
20109             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
20110             /* Guessing that this is not an important request */
20111          }
20112          break;
20113       case 487:
20114          if (sipmethod == SIP_INVITE)
20115             handle_response_invite(p, resp, rest, req, seqno);
20116          break;
20117       case 415: /* Unsupported media type */
20118       case 488: /* Not acceptable here - codec error */
20119       case 606: /* Not Acceptable */
20120          if (sipmethod == SIP_INVITE)
20121             handle_response_invite(p, resp, rest, req, seqno);
20122          break;
20123       case 491: /* Pending */
20124          if (sipmethod == SIP_INVITE)
20125             handle_response_invite(p, resp, rest, req, seqno);
20126          else {
20127             ast_debug(1, "Got 491 on %s, unsupported. Call ID %s\n", sip_methods[sipmethod].text, p->callid);
20128             pvt_set_needdestroy(p, "received 491 response");
20129          }
20130          break;
20131       case 405:
20132       case 501: /* Not Implemented */
20133          mark_method_unallowed(&p->allowed_methods, sipmethod);
20134          if (p->relatedpeer) {
20135             mark_method_allowed(&p->relatedpeer->disallowed_methods, sipmethod);
20136          }
20137          if (sipmethod == SIP_INVITE)
20138             handle_response_invite(p, resp, rest, req, seqno);
20139          else
20140             ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_sockaddr_stringify(&p->sa), msg);
20141          break;
20142          /* Fallthrough */
20143       default:
20144          if ((resp >= 300) && (resp < 700)) {
20145             /* Fatal response */
20146             if ((resp != 487))
20147                ast_verb(3, "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa));
20148    
20149             if (sipmethod == SIP_INVITE)
20150                stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
20151 
20152             /* XXX Locking issues?? XXX */
20153             switch(resp) {
20154             case 300: /* Multiple Choices */
20155             case 301: /* Moved permanently */
20156             case 302: /* Moved temporarily */
20157             case 305: /* Use Proxy */
20158             if (p->owner) {
20159                struct ast_party_redirecting redirecting;
20160                struct ast_set_party_redirecting update_redirecting;
20161 
20162                ast_party_redirecting_init(&redirecting);
20163                change_redirecting_information(p, req, &redirecting,
20164                   &update_redirecting, TRUE);
20165                ast_channel_set_redirecting(p->owner, &redirecting,
20166                   &update_redirecting);
20167                ast_party_redirecting_free(&redirecting);
20168             }
20169                /* Fall through */
20170             case 486: /* Busy here */
20171             case 600: /* Busy everywhere */
20172             case 603: /* Decline */
20173                if (p->owner) {
20174                   sip_handle_cc(p, req, AST_CC_CCBS);
20175                   ast_queue_control(p->owner, AST_CONTROL_BUSY);
20176                }
20177                break;
20178             case 482: /* Loop Detected */
20179             case 480: /* Temporarily Unavailable */
20180             case 404: /* Not Found */
20181             case 410: /* Gone */
20182             case 400: /* Bad Request */
20183             case 500: /* Server error */
20184                if (sipmethod == SIP_SUBSCRIBE) {
20185                   handle_response_subscribe(p, resp, rest, req, seqno);
20186                   break;
20187                }
20188                /* Fall through */
20189             case 502: /* Bad gateway */
20190             case 503: /* Service Unavailable */
20191             case 504: /* Server Timeout */
20192                if (owner)
20193                   ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
20194                break;
20195             default:
20196                /* Send hangup */ 
20197                if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE)
20198                   ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR);
20199                break;
20200             }
20201             /* ACK on invite */
20202             if (sipmethod == SIP_INVITE)
20203                transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
20204             if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO)
20205                sip_alreadygone(p);
20206             if (!p->owner) {
20207                pvt_set_needdestroy(p, "transaction completed");
20208             }
20209          } else if ((resp >= 100) && (resp < 200)) {
20210             if (sipmethod == SIP_INVITE) {
20211                if (!req->ignore && sip_cancel_destroy(p))
20212                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
20213                if (find_sdp(req))
20214                   process_sdp(p, req, SDP_T38_NONE);
20215                if (p->owner) {
20216                   /* Queue a progress frame */
20217                   ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
20218                }
20219             }
20220          } else
20221             ast_log(LOG_NOTICE, "Don't know how to handle a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : ast_sockaddr_stringify(&p->sa));
20222       }
20223    } else { 
20224       /* Responses to OUTGOING SIP requests on INCOMING calls
20225          get handled here. As well as out-of-call message responses */
20226       if (req->debug)
20227          ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg);
20228 
20229       if (sipmethod == SIP_INVITE && resp == 200) {
20230          /* Tags in early session is replaced by the tag in 200 OK, which is
20231          the final reply to our INVITE */
20232          char tag[128];
20233 
20234          gettag(req, "To", tag, sizeof(tag));
20235          ast_string_field_set(p, theirtag, tag);
20236       }
20237 
20238       if (sipmethod == SIP_SUBSCRIBE && resp >= 400) {
20239          struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances,
20240                0, find_sip_monitor_instance_by_subscription_pvt, p);
20241          if (monitor_instance) {
20242             ast_cc_monitor_failed(monitor_instance->core_id, monitor_instance->device_name,
20243                   "Received error response to our SUBSCRIBE");
20244             return;
20245          }
20246       }
20247 
20248       switch(resp) {
20249       case 200:
20250          if (sipmethod == SIP_INVITE) {
20251             handle_response_invite(p, resp, rest, req, seqno);
20252          } else if (sipmethod == SIP_CANCEL) {
20253             ast_debug(1, "Got 200 OK on CANCEL\n");
20254 
20255             /* Wait for 487, then destroy */
20256          } else if (sipmethod == SIP_NOTIFY) {
20257             /* They got the notify, this is the end */
20258             if (p->owner) {
20259                if (p->refer) {
20260                   ast_debug(1, "Got 200 OK on NOTIFY for transfer\n");
20261                } else
20262                   ast_log(LOG_WARNING, "Notify answer on an owned channel?\n");
20263                /* ast_queue_hangup(p->owner); Disabled */
20264             } else {
20265                if (!p->subscribed && !p->refer) {
20266                   pvt_set_needdestroy(p, "transaction completed");
20267                }
20268                if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
20269                   /* Ready to send the next state we have on queue */
20270                   ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
20271                   cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p);
20272                }
20273             }
20274          } else if (sipmethod == SIP_BYE) {
20275             pvt_set_needdestroy(p, "transaction completed");
20276          } else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) {
20277             /* We successfully transmitted a message or
20278                a video update request in INFO */
20279             ;
20280          }
20281          break;
20282       case 401:   /* www-auth */
20283       case 407:
20284          if (sipmethod == SIP_INVITE)
20285             handle_response_invite(p, resp, rest, req, seqno);
20286          else if (sipmethod == SIP_BYE) {
20287             if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, sipmethod, 0)) {
20288                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
20289                pvt_set_needdestroy(p, "failed to authenticate BYE");
20290             }
20291          }
20292          break;
20293       case 481:   /* Call leg does not exist */
20294          if (sipmethod == SIP_INVITE) {
20295             /* Re-invite failed */
20296             handle_response_invite(p, resp, rest, req, seqno);
20297          } else if (sipmethod == SIP_BYE) {
20298             pvt_set_needdestroy(p, "received 481 response");
20299          } else if (sipmethod == SIP_NOTIFY) {
20300             pvt_set_needdestroy(p, "received 481 response");
20301          } else if (sipdebug) {
20302             ast_debug(1, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid);
20303          }
20304          break;
20305       case 501: /* Not Implemented */
20306          if (sipmethod == SIP_INVITE)
20307             handle_response_invite(p, resp, rest, req, seqno);
20308          break;
20309       default: /* Errors without handlers */
20310          if ((resp >= 100) && (resp < 200)) {
20311             if (sipmethod == SIP_INVITE) {   /* re-invite */
20312                if (!req->ignore && sip_cancel_destroy(p))
20313                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
20314             }
20315          }
20316          if ((resp >= 300) && (resp < 700)) {
20317             if ((resp != 487))
20318                ast_verb(3, "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_sockaddr_stringify(&p->sa));
20319             switch(resp) {
20320             case 415: /* Unsupported media type */
20321             case 488: /* Not acceptable here - codec error */
20322             case 603: /* Decline */
20323             case 500: /* Server error */
20324             case 502: /* Bad gateway */
20325             case 503: /* Service Unavailable */
20326             case 504: /* Server timeout */
20327 
20328                /* re-invite failed */
20329                if (sipmethod == SIP_INVITE && sip_cancel_destroy(p))
20330                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
20331                break;
20332             }
20333          }
20334          break;
20335       }
20336    }
20337 }

static void handle_response_invite ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
int  seqno 
) [static]

Handle SIP response to INVITE dialogue.

Definition at line 19039 of file chan_sip.c.

References append_history, AST_CAUSE_NORMAL_CLEARING, AST_CC_CCNR, ast_channel_queue_connected_line_update(), ast_channel_queue_redirecting_update(), AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_debug, ast_log(), ast_null_frame, ast_party_connected_line_init(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_queue_control(), ast_queue_frame(), ast_queue_hangup_with_cause(), ast_random(), ast_rtp_instance_activate(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_set_hangupsource(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_route(), change_redirecting_information(), change_t38_state(), check_pendings(), connected, do_proxy_auth(), EVENT_FLAG_SYSTEM, FALSE, find_sdp(), get_header(), get_rpid(), LOG_NOTICE, LOG_WARNING, manager_event, parse_ok_contact(), parse_session_expires(), proc_422_rsp(), process_sdp(), pvt_set_needdestroy(), set_address_from_contact(), set_pvt_allowed_methods(), sip_alreadygone(), sip_cancel_destroy(), sip_cfg, sip_handle_cc(), sip_reinvite_retry(), sip_scheddestroy(), st_get_mode(), start_session_timer(), transmit_reinvite_with_sdp(), transmit_request(), TRUE, update_call_counter(), and update_redirecting().

Referenced by handle_response().

19040 {
19041    int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING);
19042    int res = 0;
19043    int xmitres = 0;
19044    int reinvite = (p->owner && p->owner->_state == AST_STATE_UP);
19045    char *p_hdrval;
19046    int rtn;
19047    struct ast_party_connected_line connected;
19048    struct ast_set_party_connected_line update_connected;
19049 
19050    if (reinvite)
19051       ast_debug(4, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid);
19052    else
19053       ast_debug(4, "SIP response %d to standard invite\n", resp);
19054 
19055    if (p->alreadygone) { /* This call is already gone */
19056       ast_debug(1, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
19057       return;
19058    }
19059 
19060    /* Acknowledge sequence number - This only happens on INVITE from SIP-call */
19061    /* Don't auto congest anymore since we've gotten something useful back */
19062    AST_SCHED_DEL_UNREF(sched, p->initid, dialog_unref(p, "when you delete the initid sched, you should dec the refcount for the stored dialog ptr"));
19063 
19064    /* RFC3261 says we must treat every 1xx response (but not 100)
19065       that we don't recognize as if it was 183.
19066    */
19067    if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 181 && resp != 182 && resp != 183)
19068       resp = 183;
19069 
19070    /* Any response between 100 and 199 is PROCEEDING */
19071    if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING)
19072       p->invitestate = INV_PROCEEDING;
19073 
19074    /* Final response, not 200 ? */
19075    if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA ))
19076       p->invitestate = INV_COMPLETED;
19077    
19078    /* Final response, clear out pending invite */
19079    if ((resp == 200 || resp >= 300) && p->pendinginvite && seqno == p->pendinginvite)
19080       p->pendinginvite = 0;
19081 
19082    /* If this is a response to our initial INVITE, we need to set what we can use
19083     * for this peer.
19084     */
19085    if (!reinvite) {
19086       set_pvt_allowed_methods(p, req);
19087    }     
19088 
19089    switch (resp) {
19090    case 100:   /* Trying */
19091    case 101:   /* Dialog establishment */
19092       if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p))
19093          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
19094       check_pendings(p);
19095       break;
19096 
19097    case 180:   /* 180 Ringing */
19098    case 182:       /* 182 Queued */
19099       if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p))
19100          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
19101       if (!req->ignore && p->owner) {
19102          if (get_rpid(p, req)) {
19103             ast_party_connected_line_init(&connected);
19104             memset(&update_connected, 0, sizeof(update_connected));
19105             if (p->cid_num) {
19106                update_connected.id.number = 1;
19107                connected.id.number.valid = 1;
19108                connected.id.number.str = (char *) p->cid_num;
19109                connected.id.number.presentation = p->callingpres;
19110             }
19111             if (p->cid_name) {
19112                update_connected.id.name = 1;
19113                connected.id.name.valid = 1;
19114                connected.id.name.str = (char *) p->cid_name;
19115                connected.id.name.presentation = p->callingpres;
19116             }
19117             connected.id.tag = (char *) p->cid_tag;
19118             connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
19119             ast_channel_queue_connected_line_update(p->owner, &connected,
19120                &update_connected);
19121          }
19122          sip_handle_cc(p, req, AST_CC_CCNR);
19123          ast_queue_control(p->owner, AST_CONTROL_RINGING);
19124          if (p->owner->_state != AST_STATE_UP) {
19125             ast_setstate(p->owner, AST_STATE_RINGING);
19126          }
19127       }
19128       if (find_sdp(req)) {
19129          if (p->invitestate != INV_CANCELLED)
19130             p->invitestate = INV_EARLY_MEDIA;
19131          res = process_sdp(p, req, SDP_T38_NONE);
19132          if (!req->ignore && p->owner) {
19133             /* Queue a progress frame only if we have SDP in 180 or 182 */
19134             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
19135          }
19136          ast_rtp_instance_activate(p->rtp);
19137       }
19138       check_pendings(p);
19139       break;
19140 
19141    case 181:   /* Call Is Being Forwarded */
19142       if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
19143          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
19144       if (!req->ignore && p->owner) {
19145          struct ast_party_redirecting redirecting;
19146          struct ast_set_party_redirecting update_redirecting;
19147 
19148          ast_party_redirecting_init(&redirecting);
19149          memset(&update_redirecting, 0, sizeof(update_redirecting));
19150          change_redirecting_information(p, req, &redirecting, &update_redirecting,
19151             FALSE);
19152          ast_channel_queue_redirecting_update(p->owner, &redirecting,
19153             &update_redirecting);
19154          ast_party_redirecting_free(&redirecting);
19155          sip_handle_cc(p, req, AST_CC_CCNR);
19156       }
19157       check_pendings(p);
19158       break;
19159 
19160    case 183:   /* Session progress */
19161       if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
19162          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
19163       if (!req->ignore && p->owner) {
19164          if (get_rpid(p, req)) {
19165             /* Queue a connected line update */
19166             ast_party_connected_line_init(&connected);
19167             memset(&update_connected, 0, sizeof(update_connected));
19168             if (p->cid_num) {
19169                update_connected.id.number = 1;
19170                connected.id.number.valid = 1;
19171                connected.id.number.str = (char *) p->cid_num;
19172                connected.id.number.presentation = p->callingpres;
19173             }
19174             if (p->cid_name) {
19175                update_connected.id.name = 1;
19176                connected.id.name.valid = 1;
19177                connected.id.name.str = (char *) p->cid_name;
19178                connected.id.name.presentation = p->callingpres;
19179             }
19180             connected.id.tag = (char *) p->cid_tag;
19181             connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
19182             ast_channel_queue_connected_line_update(p->owner, &connected,
19183                &update_connected);
19184          }
19185          sip_handle_cc(p, req, AST_CC_CCNR);
19186       }
19187       if (find_sdp(req)) {
19188          if (p->invitestate != INV_CANCELLED)
19189             p->invitestate = INV_EARLY_MEDIA;
19190          res = process_sdp(p, req, SDP_T38_NONE);
19191          if (!req->ignore && p->owner) {
19192             /* Queue a progress frame */
19193             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
19194          }
19195          ast_rtp_instance_activate(p->rtp);
19196       } else {
19197          /* Alcatel PBXs are known to send 183s with no SDP after sending
19198           * a 100 Trying response. We're just going to treat this sort of thing
19199           * the same as we would treat a 180 Ringing
19200           */
19201          if (!req->ignore && p->owner) {
19202             ast_queue_control(p->owner, AST_CONTROL_RINGING);
19203          }
19204       }
19205       check_pendings(p);
19206       break;
19207 
19208    case 200:   /* 200 OK on invite - someone's answering our call */
19209       if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
19210          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
19211       p->authtries = 0;
19212       if (find_sdp(req)) {
19213          if ((res = process_sdp(p, req, SDP_T38_ACCEPT)) && !req->ignore)
19214             if (!reinvite)
19215                /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */
19216                /* For re-invites, we try to recover */
19217                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
19218          ast_rtp_instance_activate(p->rtp);
19219       }
19220 
19221       if (!req->ignore && p->owner && (get_rpid(p, req) || !reinvite)) {
19222          /* Queue a connected line update */
19223          ast_party_connected_line_init(&connected);
19224          memset(&update_connected, 0, sizeof(update_connected));
19225          if (p->cid_num) {
19226             update_connected.id.number = 1;
19227             connected.id.number.valid = 1;
19228             connected.id.number.str = (char *) p->cid_num;
19229             connected.id.number.presentation = p->callingpres;
19230          }
19231          if (p->cid_name) {
19232             update_connected.id.name = 1;
19233             connected.id.name.valid = 1;
19234             connected.id.name.str = (char *) p->cid_name;
19235             connected.id.name.presentation = p->callingpres;
19236          }
19237          connected.id.tag = (char *) p->cid_tag;
19238          connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
19239          ast_channel_queue_connected_line_update(p->owner, &connected,
19240             &update_connected);
19241       }
19242 
19243       /* Parse contact header for continued conversation */
19244       /* When we get 200 OK, we know which device (and IP) to contact for this call */
19245       /* This is important when we have a SIP proxy between us and the phone */
19246       if (outgoing) {
19247          update_call_counter(p, DEC_CALL_RINGING);
19248          parse_ok_contact(p, req);
19249          /* Save Record-Route for any later requests we make on this dialogue */
19250          if (!reinvite)
19251             build_route(p, req, 1);
19252 
19253          if(set_address_from_contact(p)) {
19254             /* Bad contact - we don't know how to reach this device */
19255             /* We need to ACK, but then send a bye */
19256             if (!p->route && !req->ignore)
19257                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
19258          }
19259 
19260       }
19261 
19262       if (!req->ignore && p->owner) {
19263          if (!reinvite) {
19264             ast_queue_control(p->owner, AST_CONTROL_ANSWER);
19265             if (sip_cfg.callevents)
19266                manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
19267                   "Channel: %s\r\nChanneltype: %s\r\nUniqueid: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n",
19268                   p->owner->name, "SIP", p->owner->uniqueid, p->callid, p->fullcontact, p->peername);
19269          } else { /* RE-invite */
19270             ast_queue_frame(p->owner, &ast_null_frame);
19271          }
19272       } else {
19273           /* It's possible we're getting an 200 OK after we've tried to disconnect
19274               by sending CANCEL */
19275          /* First send ACK, then send bye */
19276          if (!req->ignore)
19277             ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
19278       }
19279 
19280       /* Check for Session-Timers related headers */
19281       if (st_get_mode(p) != SESSION_TIMER_MODE_REFUSE && p->outgoing_call == TRUE && !reinvite) {
19282          p_hdrval = (char*)get_header(req, "Session-Expires");
19283          if (!ast_strlen_zero(p_hdrval)) {
19284             /* UAS supports Session-Timers */
19285             enum st_refresher tmp_st_ref = SESSION_TIMER_REFRESHER_AUTO;
19286             int tmp_st_interval = 0;
19287             rtn = parse_session_expires(p_hdrval, &tmp_st_interval, &tmp_st_ref);
19288             if (rtn != 0) {
19289                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
19290             }
19291             if (tmp_st_ref == SESSION_TIMER_REFRESHER_UAC ||
19292                tmp_st_ref == SESSION_TIMER_REFRESHER_UAS) {
19293                p->stimer->st_ref = tmp_st_ref;
19294             }
19295             if (tmp_st_interval) {
19296                p->stimer->st_interval = tmp_st_interval;
19297             }
19298             p->stimer->st_active = TRUE;
19299             p->stimer->st_active_peer_ua = TRUE;
19300             start_session_timer(p);
19301          } else {
19302             /* UAS doesn't support Session-Timers */
19303             if (st_get_mode(p) == SESSION_TIMER_MODE_ORIGINATE) {
19304                p->stimer->st_ref = SESSION_TIMER_REFRESHER_UAC;
19305                p->stimer->st_active_peer_ua = FALSE;
19306                start_session_timer(p);
19307             }
19308          }
19309       }
19310 
19311 
19312       /* If I understand this right, the branch is different for a non-200 ACK only */
19313       p->invitestate = INV_TERMINATED;
19314       ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
19315       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE);
19316       check_pendings(p);
19317       break;
19318 
19319    case 407: /* Proxy authentication */
19320    case 401: /* Www auth */
19321       /* First we ACK */
19322       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19323       if (p->options)
19324          p->options->auth_type = resp;
19325 
19326       /* Then we AUTH */
19327       ast_string_field_set(p, theirtag, NULL);  /* forget their old tag, so we don't match tags when getting response */
19328       if (!req->ignore) {
19329          if (p->authtries < MAX_AUTHTRIES)
19330             p->invitestate = INV_CALLING;
19331          if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, SIP_INVITE, 1)) {
19332             ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From"));
19333             pvt_set_needdestroy(p, "failed to authenticate on INVITE");
19334             sip_alreadygone(p);
19335             if (p->owner)
19336                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19337          }
19338       }
19339       break;
19340 
19341    case 403: /* Forbidden */
19342       /* First we ACK */
19343       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19344       ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From"));
19345       if (!req->ignore && p->owner) {
19346          ast_set_hangupsource(p->owner, p->owner->name, 0);
19347          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19348       }
19349       pvt_set_needdestroy(p, "received 403 response");
19350       sip_alreadygone(p);
19351       break;
19352 
19353    case 404: /* Not found */
19354       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19355       if (p->owner && !req->ignore) {
19356          ast_set_hangupsource(p->owner, p->owner->name, 0);
19357          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19358       }
19359       sip_alreadygone(p);
19360       break;
19361 
19362    case 408: /* Request timeout */
19363    case 481: /* Call leg does not exist */
19364       /* Could be REFER caused INVITE with replaces */
19365       ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
19366       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19367       if (p->owner)
19368          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19369       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19370       break;
19371 
19372    case 422: /* Session-Timers: Session interval too small */
19373       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19374       ast_string_field_set(p, theirtag, NULL);
19375       proc_422_rsp(p, req);
19376       break;
19377 
19378    case 428: /* Use identity header - rfc 4474 - not supported by Asterisk yet */
19379       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19380       append_history(p, "Identity", "SIP identity is required. Not supported by Asterisk.");
19381       ast_log(LOG_WARNING, "SIP identity required by proxy. SIP dialog '%s'. Giving up.\n", p->callid);
19382       if (p->owner)
19383          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19384       break;
19385 
19386       
19387 
19388    case 487: /* Cancelled transaction */
19389       /* We have sent CANCEL on an outbound INVITE
19390          This transaction is already scheduled to be killed by sip_hangup().
19391       */
19392       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19393       if (p->owner && !req->ignore) {
19394          ast_queue_hangup_with_cause(p->owner, AST_CAUSE_NORMAL_CLEARING);
19395          append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request");
19396       } else if (!req->ignore) {
19397          update_call_counter(p, DEC_CALL_LIMIT);
19398          append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog.");
19399          pvt_set_needdestroy(p, "received 487 response");
19400          sip_alreadygone(p);
19401       }
19402       break;
19403    case 415: /* Unsupported media type */
19404    case 488: /* Not acceptable here */
19405    case 606: /* Not Acceptable */
19406       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19407       if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) {
19408          change_t38_state(p, T38_DISABLED);
19409          /* Try to reset RTP timers */
19410          //ast_rtp_set_rtptimers_onhold(p->rtp);
19411 
19412          /* Trigger a reinvite back to audio */
19413          transmit_reinvite_with_sdp(p, FALSE, FALSE);
19414       } else {
19415          /* We can't set up this call, so give up */
19416          if (p->owner && !req->ignore)
19417             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19418          pvt_set_needdestroy(p, "received 488 response");
19419          /* If there's no dialog to end, then mark p as already gone */
19420          if (!reinvite)
19421             sip_alreadygone(p);
19422       }
19423       break;
19424    case 491: /* Pending */
19425       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19426       if (p->owner && !req->ignore) {
19427          if (p->owner->_state != AST_STATE_UP) {
19428             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19429             pvt_set_needdestroy(p, "received 491 response");
19430          } else {
19431             /* This is a re-invite that failed. */
19432             /* Reset the flag after a while
19433              */
19434             int wait;
19435             /* RFC 3261, if owner of call, wait between 2.1 to 4 seconds,
19436              * if not owner of call, wait 0 to 2 seconds */
19437             if (p->outgoing_call) {
19438                wait = 2100 + ast_random() % 2000;
19439             } else {
19440                wait = ast_random() % 2000;
19441             }
19442             p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, dialog_ref(p, "passing dialog ptr into sched structure based on waitid for sip_reinvite_retry."));
19443             ast_log(LOG_WARNING, "just did sched_add waitid(%d) for sip_reinvite_retry for dialog %s in handle_response_invite\n", p->waitid, p->callid);
19444             ast_debug(2, "Reinvite race. Waiting %d secs before retry\n", wait);
19445          }
19446       }
19447       break;
19448 
19449    case 405: /* Not allowed */
19450    case 501: /* Not implemented */
19451       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
19452       if (p->owner)
19453          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19454       break;
19455    }
19456    if (xmitres == XMIT_ERROR)
19457       ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid);
19458 }

static void handle_response_notify ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
int  seqno 
) [static]

Definition at line 19463 of file chan_sip.c.

References AST_CAUSE_NORMAL_UNSPECIFIED, ast_clear_flag, ast_debug, ast_log(), ast_queue_hangup_with_cause(), ast_sockaddr_stringify(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, cb_extensionstate(), do_proxy_auth(), get_header(), LOG_NOTICE, LOG_WARNING, NONE, and pvt_set_needdestroy().

Referenced by handle_response().

19464 {
19465    switch (resp) {
19466    case 200:   /* Notify accepted */
19467       /* They got the notify, this is the end */
19468       if (p->owner) {
19469          if (!p->refer) {
19470             ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name);
19471             ast_queue_hangup_with_cause(p->owner, AST_CAUSE_NORMAL_UNSPECIFIED);
19472          } else {
19473             ast_debug(4, "Got OK on REFER Notify message\n");
19474          }
19475       } else {
19476          if (p->subscribed == NONE) {
19477             ast_debug(4, "Got 200 accepted on NOTIFY\n");
19478             pvt_set_needdestroy(p, "received 200 response");
19479          }
19480          if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
19481             /* Ready to send the next state we have on queue */
19482             ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
19483             cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p);
19484          }
19485       }
19486       break;
19487    case 401:   /* Not www-authorized on SIP method */
19488    case 407:   /* Proxy auth */
19489       if (!p->notify) {
19490          break; /* Only device notify can use NOTIFY auth */
19491       }
19492       ast_string_field_set(p, theirtag, NULL);
19493       if (ast_strlen_zero(p->authname)) {
19494          ast_log(LOG_WARNING, "Asked to authenticate NOTIFY to %s but we have no matching peer or realm auth!\n", ast_sockaddr_stringify(&p->recv));
19495          pvt_set_needdestroy(p, "unable to authenticate NOTIFY");
19496       }
19497       if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_NOTIFY, 0)) {
19498          ast_log(LOG_NOTICE, "Failed to authenticate on NOTIFY to '%s'\n", get_header(&p->initreq, "From"));
19499          pvt_set_needdestroy(p, "failed to authenticate NOTIFY");
19500       }
19501       break;
19502    }
19503 }

static void handle_response_peerpoke ( struct sip_pvt *  p,
int  resp,
struct sip_request *  req 
) [static]

Handle qualification responses (OPTIONS).

Definition at line 19812 of file chan_sip.c.

References ast_check_realtime(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_log(), AST_SCHED_REPLACE_UNREF, ast_tvdiff_ms(), ast_tvnow(), ast_update_realtime(), DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, LOG_NOTICE, manager_event, pvt_set_needdestroy(), ref_peer(), register_peer_exten(), SENTINEL, sip_cfg, sip_poke_peer_s(), TRUE, and unref_peer().

Referenced by handle_response().

19813 {
19814    struct sip_peer *peer = /* ref_peer( */ p->relatedpeer /* , "bump refcount on p, as it is being used in this function(handle_response_peerpoke)")*/ ; /* hope this is already refcounted! */
19815    int statechanged, is_reachable, was_reachable;
19816    int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
19817 
19818    /*
19819     * Compute the response time to a ping (goes in peer->lastms.)
19820     * -1 means did not respond, 0 means unknown,
19821     * 1..maxms is a valid response, >maxms means late response.
19822     */
19823    if (pingtime < 1) /* zero = unknown, so round up to 1 */
19824       pingtime = 1;
19825 
19826    /* Now determine new state and whether it has changed.
19827     * Use some helper variables to simplify the writing
19828     * of the expressions.
19829     */
19830    was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms;
19831    is_reachable = pingtime <= peer->maxms;
19832    statechanged = peer->lastms == 0 /* yes, unknown before */
19833       || was_reachable != is_reachable;
19834 
19835    peer->lastms = pingtime;
19836    peer->call = dialog_unref(peer->call, "unref dialog peer->call");
19837    if (statechanged) {
19838       const char *s = is_reachable ? "Reachable" : "Lagged";
19839       char str_lastms[20];
19840       snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime);
19841 
19842       ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
19843          peer->name, s, pingtime, peer->maxms);
19844       ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
19845       if (sip_cfg.peer_rtupdate) {
19846          ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", str_lastms, SENTINEL);
19847       }
19848       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
19849          "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
19850          peer->name, s, pingtime);
19851       if (is_reachable && sip_cfg.regextenonqualify)
19852          register_peer_exten(peer, TRUE);
19853    }
19854 
19855    pvt_set_needdestroy(p, "got OPTIONS response");
19856 
19857    /* Try again eventually */
19858    AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched,
19859          is_reachable ? peer->qualifyfreq : DEFAULT_FREQ_NOTOK,
19860          sip_poke_peer_s, peer,
19861          unref_peer(_data, "removing poke peer ref"),
19862          unref_peer(peer, "removing poke peer ref"),
19863          ref_peer(peer, "adding poke peer ref"));
19864 }

static void handle_response_publish ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
int  seqno 
) [static]

Definition at line 18988 of file chan_sip.c.

References ast_assert, ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), do_proxy_auth(), get_header(), LOG_NOTICE, mark_method_unallowed(), pvt_set_needdestroy(), and sip_alreadygone().

Referenced by handle_response().

18989 {
18990    struct sip_epa_entry *epa_entry = p->epa_entry;
18991    const char *etag = get_header(req, "Sip-ETag");
18992 
18993    ast_assert(epa_entry != NULL);
18994 
18995    if (resp == 401 || resp == 407) {
18996       ast_string_field_set(p, theirtag, NULL);
18997       if (p->options) {
18998          p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
18999       }
19000       if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_PUBLISH, 0)) {
19001          ast_log(LOG_NOTICE, "Failed to authenticate on PUBLISH to '%s'\n", get_header(&p->initreq, "From"));
19002          pvt_set_needdestroy(p, "Failed to authenticate on PUBLISH");
19003          sip_alreadygone(p);
19004       }
19005       return;
19006    }
19007 
19008    if (resp == 501 || resp == 405) {
19009       mark_method_unallowed(&p->allowed_methods, SIP_PUBLISH);
19010    }
19011 
19012    if (resp == 200) {
19013       p->authtries = 0;
19014       /* If I've read section 6, item 6 of RFC 3903 correctly,
19015        * an ESC will only generate a new etag when it sends a 200 OK
19016        */
19017       if (!ast_strlen_zero(etag)) {
19018          ast_copy_string(epa_entry->entity_tag, etag, sizeof(epa_entry->entity_tag));
19019       }
19020       /* The nominal case. Everything went well. Everybody is happy.
19021        * Each EPA will have a specific action to take as a result of this
19022        * development, so ... callbacks!
19023        */
19024       if (epa_entry->static_data->handle_ok) {
19025          epa_entry->static_data->handle_ok(p, req, epa_entry);
19026       }
19027    } else {
19028       /* Rather than try to make individual callbacks for each error
19029        * type, there is just a single error callback. The callback
19030        * can distinguish between error messages and do what it needs to
19031        */
19032       if (epa_entry->static_data->handle_error) {
19033          epa_entry->static_data->handle_error(p, resp, req, epa_entry);
19034       }
19035    }
19036 }

static void handle_response_refer ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
int  seqno 
) [static]

Definition at line 19568 of file chan_sip.c.

References AST_CONTROL_CONGESTION, AST_CONTROL_TRANSFER, ast_debug, ast_log(), ast_queue_control(), ast_queue_control_data(), ast_sockaddr_stringify(), ast_strlen_zero(), AST_TRANSFER_FAILED, do_proxy_auth(), get_header(), LOG_NOTICE, LOG_WARNING, and pvt_set_needdestroy().

Referenced by handle_response().

19569 {
19570    enum ast_control_transfer message = AST_TRANSFER_FAILED;
19571 
19572    /* If no refer structure exists, then do nothing */
19573    if (!p->refer)
19574       return;
19575 
19576    switch (resp) {
19577    case 202:   /* Transfer accepted */
19578       /* We need  to do something here */
19579       /* The transferee is now sending INVITE to target */
19580       p->refer->status = REFER_ACCEPTED;
19581       /* Now wait for next message */
19582       ast_debug(3, "Got 202 accepted on transfer\n");
19583       /* We should hang along, waiting for NOTIFY's here */
19584       break;
19585 
19586    case 401:   /* Not www-authorized on SIP method */
19587    case 407:   /* Proxy auth */
19588       if (ast_strlen_zero(p->authname)) {
19589          ast_log(LOG_WARNING, "Asked to authenticate REFER to %s but we have no matching peer or realm auth!\n",
19590             ast_sockaddr_stringify(&p->recv));
19591          if (p->owner) {
19592             ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
19593          }
19594          pvt_set_needdestroy(p, "unable to authenticate REFER");
19595       }
19596       if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_REFER, 0)) {
19597          ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From"));
19598          p->refer->status = REFER_NOAUTH;
19599          if (p->owner) {
19600             ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
19601          }
19602          pvt_set_needdestroy(p, "failed to authenticate REFER");
19603       }
19604       break;
19605    
19606    case 405:   /* Method not allowed */
19607       /* Return to the current call onhold */
19608       /* Status flag needed to be reset */
19609       ast_log(LOG_NOTICE, "SIP transfer to %s failed, REFER not allowed. \n", p->refer->refer_to);
19610       pvt_set_needdestroy(p, "received 405 response");
19611       p->refer->status = REFER_FAILED;
19612       if (p->owner) {
19613          ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
19614       }
19615       break;
19616 
19617    case 481: /* Call leg does not exist */
19618 
19619       /* A transfer with Replaces did not work */
19620       /* OEJ: We should Set flag, cancel the REFER, go back
19621       to original call - but right now we can't */
19622       ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid);
19623       if (p->owner)
19624          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
19625       pvt_set_needdestroy(p, "received 481 response");
19626       break;
19627 
19628    case 500:   /* Server error */
19629    case 501:   /* Method not implemented */
19630       /* Return to the current call onhold */
19631       /* Status flag needed to be reset */
19632       ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to);
19633       pvt_set_needdestroy(p, "received 500/501 response");
19634       p->refer->status = REFER_FAILED;
19635       if (p->owner) {
19636          ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
19637       }
19638       break;
19639    case 603:   /* Transfer declined */
19640       ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to);
19641       p->refer->status = REFER_FAILED;
19642       pvt_set_needdestroy(p, "received 603 response");
19643       if (p->owner) {
19644          ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
19645       }
19646       break;
19647    default:
19648       /* We should treat unrecognized 9xx as 900.  400 is actually
19649          specified as a possible response, but any 4-6xx is 
19650          theoretically possible. */
19651 
19652       if (resp < 299) { /* 1xx cases don't get here */
19653          ast_log(LOG_WARNING, "SIP transfer to %s had unxpected 2xx response (%d), confusion is possible. \n", p->refer->refer_to, resp);
19654       } else {
19655          ast_log(LOG_WARNING, "SIP transfer to %s with response (%d). \n", p->refer->refer_to, resp);
19656       }
19657 
19658       p->refer->status = REFER_FAILED;
19659       pvt_set_needdestroy(p, "received failure response");
19660       if (p->owner) {
19661          ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
19662       }
19663       break;
19664    }
19665 }

static int handle_response_register ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
int  seqno 
) [static]

Handle responses on REGISTER to services.

Definition at line 19668 of file chan_sip.c.

References __get_header(), ast_debug, ast_log(), AST_SCHED_DEL_UNREF, AST_SCHED_REPLACE_UNREF, ast_strlen_zero(), ast_tvnow(), default_expiry, do_register_auth(), EVENT_FLAG_SYSTEM, get_header(), LOG_NOTICE, LOG_WARNING, manager_event, MAX, max_expiry, pvt_set_needdestroy(), REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_UNREGISTERED, registry_addref(), registry_unref(), regstate2str(), S_OR, sip_reregister(), sip_scheddestroy(), strcasestr(), and transmit_register().

Referenced by handle_response().

19669 {
19670    int expires, expires_ms;
19671    struct sip_registry *r;
19672    r=p->registry;
19673    
19674    switch (resp) {
19675    case 401:   /* Unauthorized */
19676       if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) {
19677          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries);
19678          pvt_set_needdestroy(p, "failed to authenticate REGISTER");
19679       }
19680       break;
19681    case 403:   /* Forbidden */
19682       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname);
19683       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 403"));
19684       r->regstate = REG_STATE_NOAUTH;
19685       pvt_set_needdestroy(p, "received 403 response");
19686       break;
19687    case 404:   /* Not found */
19688       ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username, p->registry->hostname);
19689       pvt_set_needdestroy(p, "received 404 response");
19690       if (r->call)
19691          r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 404");
19692       r->regstate = REG_STATE_REJECTED;
19693       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 404"));
19694       break;
19695    case 407:   /* Proxy auth */
19696       if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) {
19697          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries);
19698          pvt_set_needdestroy(p, "failed to authenticate REGISTER");
19699       }
19700       break;
19701    case 408:   /* Request timeout */
19702       /* Got a timeout response, so reset the counter of failed responses */
19703       if (r) {
19704          r->regattempts = 0;
19705       } else {
19706          ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid);
19707       }
19708       break;
19709    case 423:   /* Interval too brief */
19710       r->expiry = atoi(get_header(req, "Min-Expires"));
19711       ast_log(LOG_WARNING, "Got 423 Interval too brief for service %s@%s, minimum is %d seconds\n", p->registry->username, p->registry->hostname, r->expiry);
19712       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 423"));
19713       if (r->call) {
19714          r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 423");
19715          pvt_set_needdestroy(p, "received 423 response");
19716       }
19717       if (r->expiry > max_expiry) {
19718          ast_log(LOG_WARNING, "Required expiration time from %s@%s is too high, giving up\n", p->registry->username, p->registry->hostname);
19719          r->expiry = r->configured_expiry;
19720          r->regstate = REG_STATE_REJECTED;
19721       } else {
19722          r->regstate = REG_STATE_UNREGISTERED;
19723          transmit_register(r, SIP_REGISTER, NULL, NULL);
19724       }
19725       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate));
19726       break;
19727    case 479:   /* SER: Not able to process the URI - address is wrong in register*/
19728       ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username, p->registry->hostname);
19729       pvt_set_needdestroy(p, "received 479 response");
19730       if (r->call)
19731          r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 479");
19732       r->regstate = REG_STATE_REJECTED;
19733       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 479"));
19734       break;
19735    case 200:   /* 200 OK */
19736       if (!r) {
19737          ast_log(LOG_WARNING, "Got 200 OK on REGISTER, but there isn't a registry entry for '%s' (we probably already got the OK)\n", S_OR(p->peername, p->username));
19738          pvt_set_needdestroy(p, "received erroneous 200 response");
19739          return 0;
19740       }
19741       
19742       r->regstate = REG_STATE_REGISTERED;
19743       r->regtime = ast_tvnow();     /* Reset time of last successful registration */
19744       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate));
19745       r->regattempts = 0;
19746       ast_debug(1, "Registration successful\n");
19747       if (r->timeout > -1) {
19748          ast_debug(1, "Cancelling timeout %d\n", r->timeout);
19749       }
19750       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 200"));
19751       if (r->call)
19752          r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 200");
19753       p->registry = registry_unref(p->registry, "unref registry entry p->registry");
19754       /* Let this one hang around until we have all the responses */
19755       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19756       /* p->needdestroy = 1; */
19757       
19758       /* set us up for re-registering
19759        * figure out how long we got registered for
19760        * according to section 6.13 of RFC, contact headers override
19761        * expires headers, so check those first */
19762       expires = 0;
19763 
19764       /* XXX todo: try to save the extra call */
19765       if (!ast_strlen_zero(get_header(req, "Contact"))) {
19766          const char *contact = NULL;
19767          const char *tmptmp = NULL;
19768          int start = 0;
19769          for(;;) {
19770             contact = __get_header(req, "Contact", &start);
19771             /* this loop ensures we get a contact header about our register request */
19772             if(!ast_strlen_zero(contact)) {
19773                if( (tmptmp=strstr(contact, p->our_contact))) {
19774                   contact=tmptmp;
19775                   break;
19776                }
19777             } else
19778                break;
19779          }
19780          tmptmp = strcasestr(contact, "expires=");
19781          if (tmptmp) {
19782             if (sscanf(tmptmp + 8, "%30d;", &expires) != 1)
19783                expires = 0;
19784          }
19785          
19786       }
19787       if (!expires)
19788          expires=atoi(get_header(req, "expires"));
19789       if (!expires)
19790          expires=default_expiry;
19791       
19792       expires_ms = expires * 1000;
19793       if (expires <= EXPIRY_GUARD_LIMIT)
19794          expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT), EXPIRY_GUARD_MIN);
19795       else
19796          expires_ms -= EXPIRY_GUARD_SECS * 1000;
19797       if (sipdebug)
19798          ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000);
19799       
19800       r->refresh= (int) expires_ms / 1000;
19801       
19802       /* Schedule re-registration before we expire */
19803       AST_SCHED_REPLACE_UNREF(r->expire, sched, expires_ms, sip_reregister, r,
19804                         registry_unref(_data,"unref in REPLACE del fail"),
19805                         registry_unref(r,"unref in REPLACE add fail"),
19806                         registry_addref(r,"The Addition side of REPLACE"));
19807    }
19808    return 1;
19809 }

static void handle_response_subscribe ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
int  seqno 
) [static]

Definition at line 19506 of file chan_sip.c.

References ast_debug, ast_free, ast_log(), ast_sched_add(), ast_string_field_set, ASTOBJ_REF, ASTOBJ_UNREF, do_proxy_auth(), get_header(), LOG_NOTICE, LOG_WARNING, mwi_expiry, pvt_set_needdestroy(), set_pvt_allowed_methods(), sip_alreadygone(), sip_subscribe_mwi_destroy(), sip_subscribe_mwi_do(), and transmit_response_with_date().

Referenced by handle_response().

19507 {
19508    if (!p->mwi) {
19509       return;
19510    }
19511 
19512    switch (resp) {
19513    case 200: /* Subscription accepted */
19514       ast_debug(3, "Got 200 OK on subscription for MWI\n");
19515       set_pvt_allowed_methods(p, req);
19516       if (p->options) {
19517          ast_free(p->options);
19518          p->options = NULL;
19519       }
19520       p->mwi->subscribed = 1;
19521       if ((p->mwi->resub = ast_sched_add(sched, mwi_expiry * 1000, sip_subscribe_mwi_do, ASTOBJ_REF(p->mwi))) < 0) {
19522          ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
19523       }
19524       break;
19525    case 401:
19526    case 407:
19527       ast_string_field_set(p, theirtag, NULL);
19528       if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_SUBSCRIBE, 0)) {
19529          ast_log(LOG_NOTICE, "Failed to authenticate on SUBSCRIBE to '%s'\n", get_header(&p->initreq, "From"));
19530          p->mwi->call = NULL;
19531          ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
19532          pvt_set_needdestroy(p, "failed to authenticate SUBSCRIBE");
19533       }
19534       break;
19535    case 403:
19536       transmit_response_with_date(p, "200 OK", req);
19537       ast_log(LOG_WARNING, "Authentication failed while trying to subscribe for MWI.\n");
19538       p->mwi->call = NULL;
19539       ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
19540       pvt_set_needdestroy(p, "received 403 response");
19541       sip_alreadygone(p);
19542       break;
19543    case 404:
19544       ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that a mailbox may not have been configured.\n");
19545       p->mwi->call = NULL;
19546       ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
19547       pvt_set_needdestroy(p, "received 404 response");
19548       break;
19549    case 481:
19550       ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that our dialog did not exist.\n");
19551       p->mwi->call = NULL;
19552       ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
19553       pvt_set_needdestroy(p, "received 481 response");
19554       break;
19555    case 500:
19556    case 501:
19557       ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side may have suffered a heart attack.\n");
19558       p->mwi->call = NULL;
19559       ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy);
19560       pvt_set_needdestroy(p, "received 500/501 response");
19561       break;
19562    }
19563 }

static void handle_response_update ( struct sip_pvt *  p,
int  resp,
const char *  rest,
struct sip_request *  req,
int  seqno 
) [static]

Handle authentication challenge for SIP UPDATE.

This function is only called upon the receipt of a 401/407 response to an UPDATE.

Definition at line 18928 of file chan_sip.c.

References ast_log(), do_proxy_auth(), get_header(), and LOG_NOTICE.

Referenced by handle_response().

18929 {
18930    if (p->options) {
18931       p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
18932    }
18933    if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_UPDATE, 1)) {
18934       ast_log(LOG_NOTICE, "Failed to authenticate on UPDATE to '%s'\n", get_header(&p->initreq, "From"));
18935    }
18936 }

static int handle_sip_publish_initial ( struct sip_pvt *  p,
struct sip_request *  req,
struct event_state_compositor *  esc,
const int  expires 
) [static]

Definition at line 23127 of file chan_sip.c.

References ao2_ref, event_state_compositor::callbacks, create_esc_entry(), transmit_response(), and transmit_response_with_sip_etag().

Referenced by handle_request_publish().

23128 {
23129    struct sip_esc_entry *esc_entry = create_esc_entry(esc, req, expires);
23130    int res = 0;
23131 
23132    if (!esc_entry) {
23133       transmit_response(p, "503 Internal Server Failure", req);
23134       return -1;
23135    }
23136 
23137    if (esc->callbacks->initial_handler) {
23138       res = esc->callbacks->initial_handler(p, req, esc, esc_entry);
23139    }
23140 
23141    if (!res) {
23142       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 0);
23143    }
23144 
23145    ao2_ref(esc_entry, -1);
23146    return res;
23147 }

static int handle_sip_publish_modify ( struct sip_pvt *  p,
struct sip_request *  req,
struct event_state_compositor *  esc,
const char *const   etag,
const int  expires 
) [static]

Definition at line 23177 of file chan_sip.c.

References ao2_ref, AST_SCHED_REPLACE_UNREF, event_state_compositor::callbacks, get_esc_entry(), publish_expire(), transmit_response(), and transmit_response_with_sip_etag().

Referenced by handle_request_publish().

23178 {
23179    struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc);
23180    int expires_ms = expires * 1000;
23181    int res = 0;
23182 
23183    if (!esc_entry) {
23184       transmit_response(p, "412 Conditional Request Failed", req);
23185       return -1;
23186    }
23187 
23188    AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry,
23189          ao2_ref(_data, -1),
23190          ao2_ref(esc_entry, -1),
23191          ao2_ref(esc_entry, +1));
23192 
23193    if (esc->callbacks->modify_handler) {
23194       res = esc->callbacks->modify_handler(p, req, esc, esc_entry);
23195    }
23196 
23197    if (!res) {
23198       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1);
23199    }
23200 
23201    ao2_ref(esc_entry, -1);
23202    return res;
23203 }

static int handle_sip_publish_refresh ( struct sip_pvt *  p,
struct sip_request *  req,
struct event_state_compositor *  esc,
const char *const   etag,
const int  expires 
) [static]

Definition at line 23149 of file chan_sip.c.

References ao2_ref, AST_SCHED_REPLACE_UNREF, event_state_compositor::callbacks, get_esc_entry(), publish_expire(), transmit_response(), and transmit_response_with_sip_etag().

Referenced by handle_request_publish().

23150 {
23151    struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc);
23152    int expires_ms = expires * 1000;
23153    int res = 0;
23154 
23155    if (!esc_entry) {
23156       transmit_response(p, "412 Conditional Request Failed", req);
23157       return -1;
23158    }
23159 
23160    AST_SCHED_REPLACE_UNREF(esc_entry->sched_id, sched, expires_ms, publish_expire, esc_entry,
23161          ao2_ref(_data, -1),
23162          ao2_ref(esc_entry, -1),
23163          ao2_ref(esc_entry, +1));
23164 
23165    if (esc->callbacks->refresh_handler) {
23166       res = esc->callbacks->refresh_handler(p, req, esc, esc_entry);
23167    }
23168 
23169    if (!res) {
23170       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1);
23171    }
23172 
23173    ao2_ref(esc_entry, -1);
23174    return res;
23175 }

static int handle_sip_publish_remove ( struct sip_pvt *  p,
struct sip_request *  req,
struct event_state_compositor *  esc,
const char *const   etag 
) [static]

Definition at line 23205 of file chan_sip.c.

References ao2_ref, ao2_unlink, AST_SCHED_DEL, event_state_compositor::callbacks, event_state_compositor::compositor, get_esc_entry(), transmit_response(), and transmit_response_with_sip_etag().

Referenced by handle_request_publish().

23206 {
23207    struct sip_esc_entry *esc_entry = get_esc_entry(etag, esc);
23208    int res = 0;
23209 
23210    if (!esc_entry) {
23211       transmit_response(p, "412 Conditional Request Failed", req);
23212       return -1;
23213    }
23214 
23215    AST_SCHED_DEL(sched, esc_entry->sched_id);
23216    /* Scheduler's ref of the esc_entry */
23217    ao2_ref(esc_entry, -1);
23218 
23219    if (esc->callbacks->remove_handler) {
23220       res = esc->callbacks->remove_handler(p, req, esc, esc_entry);
23221    }
23222 
23223    if (!res) {
23224       transmit_response_with_sip_etag(p, "200 OK", req, esc_entry, 1);
23225    }
23226 
23227    /* Ref from finding the esc_entry earlier in function */
23228    ao2_unlink(esc->compositor, esc_entry);
23229    ao2_ref(esc_entry, -1);
23230    return res;
23231 }

static int handle_t38_options ( struct ast_flags *  flags,
struct ast_flags *  mask,
struct ast_variable *  v,
int *  maxdatagram 
) [static]

Handle T.38 configuration options common to users and peers.

Returns:
non-zero if any config options were handled, zero otherwise

Definition at line 25529 of file chan_sip.c.

References ast_clear_flag, ast_log(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_true(), config, global_t38_maxdatagram, ast_variable::lineno, LOG_WARNING, ast_variable::name, strsep(), ast_variable::value, and word.

Referenced by build_peer().

25531 {
25532    int res = 1;
25533 
25534    if (!strcasecmp(v->name, "t38pt_udptl")) {
25535       char *buf = ast_strdupa(v->value);
25536       char *word, *next = buf;
25537 
25538       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT);
25539 
25540       while ((word = strsep(&next, ","))) {
25541          if (ast_true(word) || !strcasecmp(word, "fec")) {
25542             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
25543             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_FEC);
25544          } else if (!strcasecmp(word, "redundancy")) {
25545             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
25546             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY);
25547          } else if (!strcasecmp(word, "none")) {
25548             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
25549             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL);
25550          } else if (!strncasecmp(word, "maxdatagram=", 12)) {
25551             if (sscanf(&word[12], "%30u", maxdatagram) != 1) {
25552                ast_log(LOG_WARNING, "Invalid maxdatagram '%s' at line %d of %s\n", v->value, v->lineno, config);
25553                *maxdatagram = global_t38_maxdatagram;
25554             }
25555          }
25556       }
25557    } else if (!strcasecmp(v->name, "t38pt_usertpsource")) {
25558       ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION);
25559       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION);
25560    } else {
25561       res = 0;
25562    }
25563 
25564    return res;
25565 }

const char* hangup_cause2sip ( int  cause  ) 

Convert Asterisk hangup causes to SIP codes.

 Possible values from causes.h
        AST_CAUSE_NOTDEFINED    AST_CAUSE_NORMAL        AST_CAUSE_BUSY
        AST_CAUSE_FAILURE       AST_CAUSE_CONGESTION    AST_CAUSE_UNALLOCATED

	In addition to these, a lot of PRI codes is defined in causes.h
	...should we take care of them too ?

	Quote RFC 3398

   ISUP Cause value                        SIP response
   ----------------                        ------------
   1  unallocated number                   404 Not Found
   2  no route to network                  404 Not found
   3  no route to destination              404 Not found
   16 normal call clearing                 --- (*)
   17 user busy                            486 Busy here
   18 no user responding                   408 Request Timeout
   19 no answer from the user              480 Temporarily unavailable
   20 subscriber absent                    480 Temporarily unavailable
   21 call rejected                        403 Forbidden (+)
   22 number changed (w/o diagnostic)      410 Gone
   22 number changed (w/ diagnostic)       301 Moved Permanently
   23 redirection to new destination       410 Gone
   26 non-selected user clearing           404 Not Found (=)
   27 destination out of order             502 Bad Gateway
   28 address incomplete                   484 Address incomplete
   29 facility rejected                    501 Not implemented
   31 normal unspecified                   480 Temporarily unavailable

Definition at line 5896 of file chan_sip.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CHAN_NOT_IMPLEMENTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_ROUTE_TRANSIT_NET, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL_UNSPECIFIED, AST_CAUSE_NOTDEFINED, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNALLOCATED, AST_CAUSE_UNREGISTERED, AST_CAUSE_USER_BUSY, and ast_debug.

Referenced by sip_hangup().

05897 {
05898    switch (cause) {
05899       case AST_CAUSE_UNALLOCATED:      /* 1 */
05900       case AST_CAUSE_NO_ROUTE_DESTINATION:   /* 3 IAX2: Can't find extension in context */
05901       case AST_CAUSE_NO_ROUTE_TRANSIT_NET:   /* 2 */
05902          return "404 Not Found";
05903       case AST_CAUSE_CONGESTION:    /* 34 */
05904       case AST_CAUSE_SWITCH_CONGESTION:   /* 42 */
05905          return "503 Service Unavailable";
05906       case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
05907          return "408 Request Timeout";
05908       case AST_CAUSE_NO_ANSWER:     /* 19 */
05909       case AST_CAUSE_UNREGISTERED:        /* 20 */
05910          return "480 Temporarily unavailable";
05911       case AST_CAUSE_CALL_REJECTED:    /* 21 */
05912          return "403 Forbidden";
05913       case AST_CAUSE_NUMBER_CHANGED:      /* 22 */
05914          return "410 Gone";
05915       case AST_CAUSE_NORMAL_UNSPECIFIED:  /* 31 */
05916          return "480 Temporarily unavailable";
05917       case AST_CAUSE_INVALID_NUMBER_FORMAT:
05918          return "484 Address incomplete";
05919       case AST_CAUSE_USER_BUSY:
05920          return "486 Busy here";
05921       case AST_CAUSE_FAILURE:
05922          return "500 Server internal failure";
05923       case AST_CAUSE_FACILITY_REJECTED:   /* 29 */
05924          return "501 Not Implemented";
05925       case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
05926          return "503 Service Unavailable";
05927       /* Used in chan_iax2 */
05928       case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
05929          return "502 Bad Gateway";
05930       case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
05931          return "488 Not Acceptable Here";
05932          
05933       case AST_CAUSE_NOTDEFINED:
05934       default:
05935          ast_debug(1, "AST hangup cause %d (no match found in SIP)\n", cause);
05936          return NULL;
05937    }
05938 
05939    /* Never reached */
05940    return 0;
05941 }

int hangup_sip2cause ( int  cause  ) 

Convert SIP hangup causes to Asterisk hangup causes.

Definition at line 5774 of file chan_sip.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, AST_CAUSE_UNALLOCATED, and AST_CAUSE_USER_BUSY.

Referenced by __transmit_response(), and handle_response().

05775 {
05776    /* Possible values taken from causes.h */
05777 
05778    switch(cause) {
05779       case 401:   /* Unauthorized */
05780          return AST_CAUSE_CALL_REJECTED;
05781       case 403:   /* Not found */
05782          return AST_CAUSE_CALL_REJECTED;
05783       case 404:   /* Not found */
05784          return AST_CAUSE_UNALLOCATED;
05785       case 405:   /* Method not allowed */
05786          return AST_CAUSE_INTERWORKING;
05787       case 407:   /* Proxy authentication required */
05788          return AST_CAUSE_CALL_REJECTED;
05789       case 408:   /* No reaction */
05790          return AST_CAUSE_NO_USER_RESPONSE;
05791       case 409:   /* Conflict */
05792          return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
05793       case 410:   /* Gone */
05794          return AST_CAUSE_NUMBER_CHANGED;
05795       case 411:   /* Length required */
05796          return AST_CAUSE_INTERWORKING;
05797       case 413:   /* Request entity too large */
05798          return AST_CAUSE_INTERWORKING;
05799       case 414:   /* Request URI too large */
05800          return AST_CAUSE_INTERWORKING;
05801       case 415:   /* Unsupported media type */
05802          return AST_CAUSE_INTERWORKING;
05803       case 420:   /* Bad extension */
05804          return AST_CAUSE_NO_ROUTE_DESTINATION;
05805       case 480:   /* No answer */
05806          return AST_CAUSE_NO_ANSWER;
05807       case 481:   /* No answer */
05808          return AST_CAUSE_INTERWORKING;
05809       case 482:   /* Loop detected */
05810          return AST_CAUSE_INTERWORKING;
05811       case 483:   /* Too many hops */
05812          return AST_CAUSE_NO_ANSWER;
05813       case 484:   /* Address incomplete */
05814          return AST_CAUSE_INVALID_NUMBER_FORMAT;
05815       case 485:   /* Ambiguous */
05816          return AST_CAUSE_UNALLOCATED;
05817       case 486:   /* Busy everywhere */
05818          return AST_CAUSE_BUSY;
05819       case 487:   /* Request terminated */
05820          return AST_CAUSE_INTERWORKING;
05821       case 488:   /* No codecs approved */
05822          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05823       case 491:   /* Request pending */
05824          return AST_CAUSE_INTERWORKING;
05825       case 493:   /* Undecipherable */
05826          return AST_CAUSE_INTERWORKING;
05827       case 500:   /* Server internal failure */
05828          return AST_CAUSE_FAILURE;
05829       case 501:   /* Call rejected */
05830          return AST_CAUSE_FACILITY_REJECTED;
05831       case 502:
05832          return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
05833       case 503:   /* Service unavailable */
05834          return AST_CAUSE_CONGESTION;
05835       case 504:   /* Gateway timeout */
05836          return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
05837       case 505:   /* SIP version not supported */
05838          return AST_CAUSE_INTERWORKING;
05839       case 600:   /* Busy everywhere */
05840          return AST_CAUSE_USER_BUSY;
05841       case 603:   /* Decline */
05842          return AST_CAUSE_CALL_REJECTED;
05843       case 604:   /* Does not exist anywhere */
05844          return AST_CAUSE_UNALLOCATED;
05845       case 606:   /* Not acceptable */
05846          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05847       default:
05848          if (cause < 500 && cause >= 400) {
05849             /* 4xx class error that is unknown - someting wrong with our request */
05850             return AST_CAUSE_INTERWORKING;
05851          } else if (cause < 600 && cause >= 500) {
05852             /* 5xx class error - problem in the remote end */
05853             return AST_CAUSE_CONGESTION;
05854          } else if (cause < 700 && cause >= 600) {
05855             /* 6xx - global errors in the 4xx class */
05856             return AST_CAUSE_INTERWORKING;
05857          }
05858          return AST_CAUSE_NORMAL;
05859    }
05860    /* Never reached */
05861    return 0;
05862 }

static int init_req ( struct sip_request *  req,
int  sipmethod,
const char *  recip 
) [static]

Initialize SIP request.

Definition at line 9614 of file chan_sip.c.

References ast_free, ast_str_create(), ast_str_set(), ast_str_strlen(), sip_methods, and cfsip_methods::text.

09615 {
09616    /* Initialize a request */
09617    memset(req, 0, sizeof(*req));
09618    if (!(req->data = ast_str_create(SIP_MIN_PACKET)))
09619       goto e_return;
09620    if (!(req->content = ast_str_create(SIP_MIN_PACKET)))
09621       goto e_free_data;
09622    req->method = sipmethod;
09623    req->header[0] = 0;
09624    ast_str_set(&req->data, 0, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
09625    req->len = ast_str_strlen(req->data);
09626    req->headers++;
09627    return 0;
09628 
09629 e_free_data:
09630    ast_free(req->data);
09631    req->data = NULL;
09632 e_return:
09633    return -1;
09634 }

static int init_resp ( struct sip_request *  resp,
const char *  msg 
) [static]

Initialize SIP response, based on SIP request.

Definition at line 9591 of file chan_sip.c.

References ast_free, ast_str_create(), and ast_str_set().

09592 {
09593    /* Initialize a response */
09594    memset(resp, 0, sizeof(*resp));
09595    resp->method = SIP_RESPONSE;
09596    if (!(resp->data = ast_str_create(SIP_MIN_PACKET)))
09597       goto e_return;
09598    if (!(resp->content = ast_str_create(SIP_MIN_PACKET)))
09599       goto e_free_data;
09600    resp->header[0] = 0;
09601    ast_str_set(&resp->data, 0, "SIP/2.0 %s\r\n", msg);
09602    resp->len = resp->data->used;
09603    resp->headers++;
09604    return 0;
09605 
09606 e_free_data:
09607    ast_free(resp->data);
09608    resp->data = NULL;
09609 e_return:
09610    return -1;
09611 }

static int initialize_escs ( void   )  [static]

Definition at line 1052 of file chan_sip.c.

References ao2_container_alloc, ARRAY_LEN, esc_cmp_fn(), esc_hash_fn(), and event_state_compositors.

Referenced by load_module().

01053 {
01054    int i, res = 0;
01055    for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
01056       if (!((event_state_compositors[i].compositor) =
01057                ao2_container_alloc(ESC_MAX_BUCKETS, esc_hash_fn, esc_cmp_fn))) {
01058          res = -1;
01059       }
01060    }
01061    return res;
01062 }

static void initialize_initreq ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog.

Definition at line 2983 of file chan_sip.c.

References ast_debug, ast_verbose, copy_request(), parse_request(), sip_methods, and cfsip_methods::text.

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

02984 {
02985    if (p->initreq.headers) {
02986       ast_debug(1, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid);
02987    } else {
02988       ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
02989    }
02990    /* Use this as the basis */
02991    copy_request(&p->initreq, req);
02992    parse_request(&p->initreq);
02993    if (req->debug) {
02994       ast_verbose("Initreq: %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
02995    }
02996 }

static void initreqprep ( struct sip_request *  req,
struct sip_pvt *  p,
int  sipmethod,
const char *const   explicit_uri 
) [static]

Initiate new SIP request to peer/user.

Todo:
Need to add back the VXML URL here at some point, possibly use build_string for all this junk

Definition at line 11327 of file chan_sip.c.

References add_header(), add_header_max_forwards(), add_route(), AST_DIGIT_ANYNUM, ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_sockaddr_port, ast_sockaddr_stringify_host(), ast_str_alloca, ast_str_append(), ast_str_set(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), default_callerid, exten, global_useragent, init_req(), ourport, S_OR, sip_cfg, sip_methods, sip_standard_port(), and cfsip_methods::text.

Referenced by transmit_invite(), and transmit_notify_with_mwi().

11328 {
11329    struct ast_str *invite = ast_str_alloca(256);
11330    char from[256];
11331    char to[256];
11332    char tmp_n[SIPBUFSIZE/2];  /* build a local copy of 'n' if needed */
11333    char tmp_l[SIPBUFSIZE/2];  /* build a local copy of 'l' if needed */
11334    const char *l = NULL;   /* XXX what is this, exactly ? */
11335    const char *n = NULL;   /* XXX what is this, exactly ? */
11336    const char *d = NULL;   /* domain in from header */
11337    const char *urioptions = "";
11338    int ourport;
11339 
11340    if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
11341       const char *s = p->username;  /* being a string field, cannot be NULL */
11342 
11343       /* Test p->username against allowed characters in AST_DIGIT_ANY
11344          If it matches the allowed characters list, then sipuser = ";user=phone"
11345          If not, then sipuser = ""
11346       */
11347       /* + is allowed in first position in a tel: uri */
11348       if (*s == '+')
11349          s++;
11350       for (; *s; s++) {
11351          if (!strchr(AST_DIGIT_ANYNUM, *s) )
11352             break;
11353       }
11354       /* If we have only digits, add ;user=phone to the uri */
11355       if (!*s)
11356          urioptions = ";user=phone";
11357    }
11358 
11359 
11360    snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
11361 
11362    d = S_OR(p->fromdomain, ast_sockaddr_stringify_host(&p->ourip));
11363    if (p->owner) {
11364       if ((ast_party_id_presentation(&p->owner->connected.id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
11365          l = p->owner->connected.id.number.valid ? p->owner->connected.id.number.str : NULL;
11366          n = p->owner->connected.id.name.valid ? p->owner->connected.id.name.str : NULL;
11367       } else if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) {
11368          /* if we are not sending RPID and user wants his callerid restricted */    
11369          l = CALLERID_UNKNOWN;
11370          n = l;
11371          d = FROMDOMAIN_INVALID;
11372       }
11373    }
11374 
11375    /* Hey, it's a NOTIFY! See if they've configured a mwi_from.
11376     * XXX Right now, this logic works because the only place that mwi_from
11377     * is set on the sip_pvt is in sip_send_mwi_to_peer. If things changed, then
11378     * we might end up putting the mwi_from setting into other types of NOTIFY
11379     * messages as well.
11380     */
11381    if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->mwi_from)) {
11382       l = p->mwi_from;
11383    }
11384 
11385    if (ast_strlen_zero(l))
11386       l = default_callerid;
11387    if (ast_strlen_zero(n))
11388       n = l;
11389    /* Allow user to be overridden */
11390    if (!ast_strlen_zero(p->fromuser))
11391       l = p->fromuser;
11392    else /* Save for any further attempts */
11393       ast_string_field_set(p, fromuser, l);
11394 
11395    /* Allow user to be overridden */
11396    if (!ast_strlen_zero(p->fromname))
11397       n = p->fromname;
11398    else /* Save for any further attempts */
11399       ast_string_field_set(p, fromname, n);
11400 
11401    if (sip_cfg.pedanticsipchecking) {
11402       ast_uri_encode(n, tmp_n, sizeof(tmp_n), 0);
11403       n = tmp_n;
11404       ast_uri_encode(l, tmp_l, sizeof(tmp_l), 0);
11405       l = tmp_l;
11406    }
11407 
11408    ourport = (p->fromdomainport) ? p->fromdomainport : ast_sockaddr_port(&p->ourip);
11409    if (!sip_standard_port(p->socket.type, ourport)) {
11410       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, d, ourport, p->tag);
11411    } else {
11412       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, d, p->tag);
11413    }
11414 
11415    if (!ast_strlen_zero(explicit_uri)) {
11416       ast_str_set(&invite, 0, "%s", explicit_uri);
11417    } else {
11418       /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
11419       if (!ast_strlen_zero(p->fullcontact)) {
11420          /* If we have full contact, trust it */
11421          ast_str_append(&invite, 0, "%s", p->fullcontact);
11422       } else {
11423          /* Otherwise, use the username while waiting for registration */
11424          ast_str_append(&invite, 0, "sip:");
11425          if (!ast_strlen_zero(p->username)) {
11426             n = p->username;
11427             if (sip_cfg.pedanticsipchecking) {
11428                ast_uri_encode(n, tmp_n, sizeof(tmp_n), 0);
11429                n = tmp_n;
11430             }
11431             ast_str_append(&invite, 0, "%s@", n);
11432          }
11433          ast_str_append(&invite, 0, "%s", p->tohost);
11434          if (p->portinuri) {
11435             ast_str_append(&invite, 0, ":%d", ast_sockaddr_port(&p->sa));
11436          }
11437          ast_str_append(&invite, 0, "%s", urioptions);
11438       }
11439    }
11440 
11441    /* If custom URI options have been provided, append them */
11442    if (p->options && !ast_strlen_zero(p->options->uri_options))
11443       ast_str_append(&invite, 0, ";%s", p->options->uri_options);
11444    
11445    /* This is the request URI, which is the next hop of the call
11446       which may or may not be the destination of the call
11447    */
11448    ast_string_field_set(p, uri, invite->str);
11449 
11450    if (!ast_strlen_zero(p->todnid)) {
11451       /*! \todo Need to add back the VXML URL here at some point, possibly use build_string for all this junk */
11452       if (!strchr(p->todnid, '@')) {
11453          /* We have no domain in the dnid */
11454          snprintf(to, sizeof(to), "<sip:%s@%s>%s%s", p->todnid, p->tohost, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag);
11455       } else {
11456          snprintf(to, sizeof(to), "<sip:%s>%s%s", p->todnid, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag);
11457       }
11458    } else {
11459       if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) {
11460          /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
11461          snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "sip:" : ""), p->uri, p->theirtag);
11462       } else if (p->options && p->options->vxml_url) {
11463          /* If there is a VXML URL append it to the SIP URL */
11464          snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
11465       } else {
11466          snprintf(to, sizeof(to), "<%s>", p->uri);
11467       }
11468    }
11469 
11470    init_req(req, sipmethod, p->uri);
11471    /* now tmp_n is available so reuse it to build the CSeq */
11472    snprintf(tmp_n, sizeof(tmp_n), "%d %s", ++p->ocseq, sip_methods[sipmethod].text);
11473 
11474    add_header(req, "Via", p->via);
11475    add_header_max_forwards(p, req);
11476    /* This will be a no-op most of the time. However, under certain circumstances,
11477     * NOTIFY messages will use this function for preparing the request and should
11478     * have Route headers present.
11479     */
11480    add_route(req, p->route);
11481 
11482    add_header(req, "From", from);
11483    add_header(req, "To", to);
11484    ast_string_field_set(p, exten, l);
11485    build_contact(p);
11486    add_header(req, "Contact", p->our_contact);
11487    add_header(req, "Call-ID", p->callid);
11488    add_header(req, "CSeq", tmp_n);
11489    if (!ast_strlen_zero(global_useragent)) {
11490       add_header(req, "User-Agent", global_useragent);
11491    }
11492 }

static const char * insecure2str ( int  mode  )  const [static]

Convert Insecure setting to printable string.

Definition at line 16137 of file chan_sip.c.

References insecurestr, and map_x_s().

Referenced by _sip_show_peer().

16138 {
16139    return map_x_s(insecurestr, mode, "<error>");
16140 }

static int interpret_t38_parameters ( struct sip_pvt *  p,
const struct ast_control_t38_parameters *  parameters 
) [static]

Helper function which updates T.38 capability information and triggers a reinvite.

Definition at line 6426 of file chan_sip.c.

References AST_CONTROL_T38_PARAMETERS, ast_queue_control_data(), AST_SCHED_DEL, AST_SCHED_DEL_UNREF, ast_set_flag, AST_T38_NEGOTIATED, AST_T38_REFUSED, AST_T38_REQUEST_NEGOTIATE, AST_T38_REQUEST_PARMS, AST_T38_REQUEST_TERMINATE, AST_T38_TERMINATED, ast_test_flag, ast_udptl_get_far_max_ifp(), ast_udptl_set_local_max_ifp(), change_t38_state(), FALSE, ast_control_t38_parameters::fill_bit_removal, ast_control_t38_parameters::max_ifp, MIN, ast_control_t38_parameters::request_response, transmit_reinvite_with_sdp(), transmit_response_reliable(), transmit_response_with_t38_sdp(), and TRUE.

Referenced by sip_indicate().

06427 {
06428    int res = 0;
06429 
06430    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) || !p->udptl) {
06431       return -1;
06432    }
06433    switch (parameters->request_response) {
06434    case AST_T38_NEGOTIATED:
06435    case AST_T38_REQUEST_NEGOTIATE:         /* Request T38 */
06436       /* Negotiation can not take place without a valid max_ifp value. */
06437       if (!parameters->max_ifp) {
06438          change_t38_state(p, T38_DISABLED);
06439          if (p->t38.state == T38_PEER_REINVITE) {
06440             AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr"));
06441             transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
06442          }
06443          break;
06444       } else if (p->t38.state == T38_PEER_REINVITE) {
06445          AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr"));
06446          p->t38.our_parms = *parameters;
06447          /* modify our parameters to conform to the peer's parameters,
06448           * based on the rules in the ITU T.38 recommendation
06449           */
06450          if (!p->t38.their_parms.fill_bit_removal) {
06451             p->t38.our_parms.fill_bit_removal = FALSE;
06452          }
06453          if (!p->t38.their_parms.transcoding_mmr) {
06454             p->t38.our_parms.transcoding_mmr = FALSE;
06455          }
06456          if (!p->t38.their_parms.transcoding_jbig) {
06457             p->t38.our_parms.transcoding_jbig = FALSE;
06458          }
06459          p->t38.our_parms.version = MIN(p->t38.our_parms.version, p->t38.their_parms.version);
06460          p->t38.our_parms.rate_management = p->t38.their_parms.rate_management;
06461          ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp);
06462          change_t38_state(p, T38_ENABLED);
06463          transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
06464       } else if (p->t38.state != T38_ENABLED) {
06465          p->t38.our_parms = *parameters;
06466          ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp);
06467          change_t38_state(p, T38_LOCAL_REINVITE);
06468          if (!p->pendinginvite) {
06469             transmit_reinvite_with_sdp(p, TRUE, FALSE);
06470          } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
06471             ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
06472          }
06473       }
06474       break;
06475    case AST_T38_TERMINATED:
06476    case AST_T38_REFUSED:
06477    case AST_T38_REQUEST_TERMINATE:         /* Shutdown T38 */
06478       if (p->t38.state == T38_PEER_REINVITE) {
06479          AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr"));
06480          change_t38_state(p, T38_DISABLED);
06481          transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
06482       } else if (p->t38.state == T38_ENABLED)
06483          transmit_reinvite_with_sdp(p, FALSE, FALSE);
06484       break;
06485    case AST_T38_REQUEST_PARMS: {    /* Application wants remote's parameters re-sent */
06486       struct ast_control_t38_parameters parameters = p->t38.their_parms;
06487 
06488       if (p->t38.state == T38_PEER_REINVITE) {
06489          AST_SCHED_DEL(sched, p->t38id);
06490          parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
06491          parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
06492          ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
06493          /* we need to return a positive value here, so that applications that
06494           * send this request can determine conclusively whether it was accepted or not...
06495           * older versions of chan_sip would just silently accept it and return zero.
06496           */
06497          res = AST_T38_REQUEST_PARMS;
06498       }
06499       break;
06500    }
06501    default:
06502       res = -1;
06503       break;
06504    }
06505 
06506    return res;
06507 }

static int is_method_allowed ( unsigned int *  allowed_methods,
enum sipmethod  method 
) [static]

Check if method is allowed for a device or a dialog.

Definition at line 7883 of file chan_sip.c.

Referenced by sip_sendtext(), and update_connectedline().

07884 {
07885    return ((*allowed_methods) >> method) & 1;
07886 }

static void list_route ( struct sip_route *  route  )  [static]

List all routes - mostly for debugging.

Definition at line 13452 of file chan_sip.c.

References ast_verbose.

Referenced by build_route().

13453 {
13454    if (!route) {
13455       ast_verbose("list_route: no route\n");
13456    } else {
13457       for (;route; route = route->next)
13458          ast_verbose("list_route: hop: <%s>\n", route->hop);
13459    }
13460 }

static int load_module ( void   )  [static]

PBX load module - initialization.

Definition at line 29012 of file chan_sip.c.

References ao2_container_alloc, ao2_t_container_alloc, ARRAY_LEN, ast_cc_agent_register(), ast_cc_monitor_register(), ast_channel_register(), ast_check_realtime(), ast_cli_register_multiple(), ast_custom_function_register, ast_data_register_multiple, ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_realtime_require_field(), ast_register_application_xml, ast_rtp_glue_register, AST_TEST_REGISTER, ast_udptl_proto_register(), ast_verbose, ASTOBJ_CONTAINER_INIT, can_parse_xml, cc_epa_static_data, CHANNEL_MODULE_LOAD, checksipdomain_function, cli_sip, dialog_cmp_cb(), dialog_hash_cb(), dialogs, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, HASH_DIALOG_SIZE, HASH_PEER_SIZE, initialize_escs(), io, io_context_create(), io_context_destroy(), LOG_ERROR, manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_sipnotify(), network_change_event_subscribe(), peer_cmp_cb(), peer_hash_cb(), peer_ipcmp_cb(), peer_iphash_cb(), peers_by_ip, regl, reload_config(), restart_monitor(), RQ_CHAR, RQ_INTEGER4, RQ_UINTEGER2, sched_context_create(), sched_context_destroy(), ast_channel_tech::send_digit_begin, SENTINEL, sip_addheader(), sip_cc_agent_callbacks, sip_cc_monitor_callbacks, sip_data_providers, sip_dtmfmode(), sip_epa_register(), sip_header_function, sip_is_xml_parsable(), sip_monitor_instance_cmp_fn(), sip_monitor_instance_hash_fn(), sip_monitor_instances, sip_poke_all_peers(), sip_register_tests(), sip_reloadreason, sip_removeheader(), sip_rtp_glue, sip_send_all_mwi_subscriptions(), sip_send_all_registers(), sip_tech, sip_tech_info, sip_udptl, sipchaninfo_function, sippeer_function, submwil, threadt, threadt_cmp_cb(), and threadt_hash_cb().

29013 {
29014    ast_verbose("SIP channel loading...\n");
29015    /* the fact that ao2_containers can't resize automatically is a major worry! */
29016    /* if the number of objects gets above MAX_XXX_BUCKETS, things will slow down */
29017    peers = ao2_t_container_alloc(HASH_PEER_SIZE, peer_hash_cb, peer_cmp_cb, "allocate peers");
29018    peers_by_ip = ao2_t_container_alloc(HASH_PEER_SIZE, peer_iphash_cb, peer_ipcmp_cb, "allocate peers_by_ip");
29019    dialogs = ao2_t_container_alloc(HASH_DIALOG_SIZE, dialog_hash_cb, dialog_cmp_cb, "allocate dialogs");
29020    threadt = ao2_t_container_alloc(HASH_DIALOG_SIZE, threadt_hash_cb, threadt_cmp_cb, "allocate threadt table");
29021    
29022    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list -- not searched for anything */
29023    ASTOBJ_CONTAINER_INIT(&submwil); /* MWI subscription object list */
29024 
29025    if (!(sched = sched_context_create())) {
29026       ast_log(LOG_ERROR, "Unable to create scheduler context\n");
29027       return AST_MODULE_LOAD_FAILURE;
29028    }
29029 
29030    if (!(io = io_context_create())) {
29031       ast_log(LOG_ERROR, "Unable to create I/O context\n");
29032       sched_context_destroy(sched);
29033       return AST_MODULE_LOAD_FAILURE;
29034    }
29035 
29036    sip_reloadreason = CHANNEL_MODULE_LOAD;
29037 
29038    can_parse_xml = sip_is_xml_parsable();
29039    if(reload_config(sip_reloadreason)) {  /* Load the configuration from sip.conf */
29040       return AST_MODULE_LOAD_DECLINE;
29041    }
29042 
29043    /* Prepare the version that does not require DTMF BEGIN frames.
29044     * We need to use tricks such as memcpy and casts because the variable
29045     * has const fields.
29046     */
29047    memcpy(&sip_tech_info, &sip_tech, sizeof(sip_tech));
29048    memset((void *) &sip_tech_info.send_digit_begin, 0, sizeof(sip_tech_info.send_digit_begin));
29049 
29050    /* Make sure we can register our sip channel type */
29051    if (ast_channel_register(&sip_tech)) {
29052       ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
29053       io_context_destroy(io);
29054       sched_context_destroy(sched);
29055       return AST_MODULE_LOAD_FAILURE;
29056    }
29057 
29058 #ifdef TEST_FRAMEWORK
29059    AST_TEST_REGISTER(test_sip_peers_get);
29060    AST_TEST_REGISTER(test_sip_mwi_subscribe_parse);
29061 #endif
29062 
29063    /* Register AstData providers */
29064    ast_data_register_multiple(sip_data_providers, ARRAY_LEN(sip_data_providers));
29065 
29066    /* Register all CLI functions for SIP */
29067    ast_cli_register_multiple(cli_sip, ARRAY_LEN(cli_sip));
29068 
29069    /* Tell the UDPTL subdriver that we're here */
29070    ast_udptl_proto_register(&sip_udptl);
29071 
29072    /* Tell the RTP engine about our RTP glue */
29073    ast_rtp_glue_register(&sip_rtp_glue);
29074 
29075    /* Register dialplan applications */
29076    ast_register_application_xml(app_dtmfmode, sip_dtmfmode);
29077    ast_register_application_xml(app_sipaddheader, sip_addheader);
29078    ast_register_application_xml(app_sipremoveheader, sip_removeheader);
29079 
29080    /* Register dialplan functions */
29081    ast_custom_function_register(&sip_header_function);
29082    ast_custom_function_register(&sippeer_function);
29083    ast_custom_function_register(&sipchaninfo_function);
29084    ast_custom_function_register(&checksipdomain_function);
29085 
29086    /* Register manager commands */
29087    ast_manager_register_xml("SIPpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peers);
29088    ast_manager_register_xml("SIPshowpeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peer);
29089    ast_manager_register_xml("SIPqualifypeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_qualify_peer);
29090    ast_manager_register_xml("SIPshowregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_show_registry);
29091    ast_manager_register_xml("SIPnotify", EVENT_FLAG_SYSTEM, manager_sipnotify);
29092    sip_poke_all_peers();   
29093    sip_send_all_registers();
29094    sip_send_all_mwi_subscriptions();
29095    initialize_escs();
29096 
29097    if (sip_epa_register(&cc_epa_static_data)) {
29098       return AST_MODULE_LOAD_DECLINE;
29099    }
29100 
29101    if (sip_reqresp_parser_init() == -1) {
29102       ast_log(LOG_ERROR, "Unable to initialize the SIP request and response parser\n");
29103       return AST_MODULE_LOAD_DECLINE;
29104    }
29105 
29106    if (can_parse_xml) {
29107       /* SIP CC agents require the ability to parse XML PIDF bodies
29108        * in incoming PUBLISH requests
29109        */
29110       if (ast_cc_agent_register(&sip_cc_agent_callbacks)) {
29111          return AST_MODULE_LOAD_DECLINE;
29112       }
29113    }
29114    if (ast_cc_monitor_register(&sip_cc_monitor_callbacks)) {
29115       return AST_MODULE_LOAD_DECLINE;
29116    }
29117    if (!(sip_monitor_instances = ao2_container_alloc(37, sip_monitor_instance_hash_fn, sip_monitor_instance_cmp_fn))) {
29118       return AST_MODULE_LOAD_DECLINE;
29119    }
29120 
29121    /* And start the monitor for the first time */
29122    restart_monitor();
29123 
29124    ast_realtime_require_field(ast_check_realtime("sipregs") ? "sipregs" : "sippeers",
29125       "name", RQ_CHAR, 10,
29126       "ipaddr", RQ_CHAR, INET6_ADDRSTRLEN - 1,
29127       "port", RQ_UINTEGER2, 5,
29128       "regseconds", RQ_INTEGER4, 11,
29129       "defaultuser", RQ_CHAR, 10,
29130       "fullcontact", RQ_CHAR, 35,
29131       "regserver", RQ_CHAR, 20,
29132       "useragent", RQ_CHAR, 20,
29133       "lastms", RQ_INTEGER4, 11,
29134       SENTINEL);
29135 
29136 
29137    sip_register_tests();
29138    network_change_event_subscribe();
29139 
29140    return AST_MODULE_LOAD_SUCCESS;
29141 }

static int local_attended_transfer ( struct sip_pvt *  transferer,
struct sip_dual *  current,
struct sip_request *  req,
int  seqno,
int *  nounlock 
) [static]

Find all call legs and bridge transferee with target called from handle_request_refer.

Note:
this function assumes two locks to begin with, sip_pvt transferer and current.chan1 (the pvt's owner)... 2 additional locks are held at the beginning of the function, targetcall_pvt, and targetcall_pvt's owner channel (which is stored in target.chan1). These 2 locks _MUST_ be let go by the end of the function. Do not be confused into thinking a pvt's owner is the same thing as the channels locked at the beginning of this function, after the masquerade this may not be true. Be consistent and unlock only the exact same pointers that were locked to begin with.
If this function is successful, only the transferer pvt lock will remain on return. Setting nounlock indicates to handle_request_do() that the pvt's owner it locked does not require an unlock.

Definition at line 22007 of file chan_sip.c.

References ao2_t_ref, append_history, ast_bridged_channel(), AST_CEL_ATTENDEDTRANSFER, ast_cel_report_event(), ast_channel_queue_connected_line_update(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_clear_flag, ast_connected_line_build_data(), AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, AST_CONTROL_READ_ACTION, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_do_masquerade(), AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO, ast_indicate(), ast_manager_event_multichan, ast_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_queue_control_data(), ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_streamfile(), ast_strlen_zero(), ast_waitstream(), attempt_transfer(), EVENT_FLAG_CALL, frame_size, get_sip_pvt_byid_locked(), ast_channel::name, ast_control_read_action_payload::payload_size, pbx_builtin_getvar_helper(), sip_pvt_lock, sip_pvt_unlock, ast_party_connected_line::source, transmit_notify_with_sipfrag(), TRUE, and xfersound.

Referenced by handle_request_refer().

22008 {
22009    struct sip_dual target;    /* Chan 1: Call from tranferer to Asterisk */
22010                /* Chan 2: Call from Asterisk to target */
22011    int res = 0;
22012    struct sip_pvt *targetcall_pvt;
22013    struct ast_party_connected_line connected_to_transferee;
22014    struct ast_party_connected_line connected_to_target;
22015    char transferer_linkedid[32];
22016    struct ast_channel *chans[2];
22017 
22018    /* Check if the call ID of the replaces header does exist locally */
22019    if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag,
22020       transferer->refer->replaces_callid_fromtag))) {
22021       if (transferer->refer->localtransfer) {
22022          /* We did not find the refered call. Sorry, can't accept then */
22023          /* Let's fake a response from someone else in order
22024             to follow the standard */
22025          transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE);
22026          append_history(transferer, "Xfer", "Refer failed");
22027          ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
22028          transferer->refer->status = REFER_FAILED;
22029          return -1;
22030       }
22031       /* Fall through for remote transfers that we did not find locally */
22032       ast_debug(3, "SIP attended transfer: Not our call - generating INVITE with replaces\n");
22033       return 0;
22034    }
22035 
22036    /* Ok, we can accept this transfer */
22037    append_history(transferer, "Xfer", "Refer accepted");
22038    if (!targetcall_pvt->owner) { /* No active channel */
22039       ast_debug(4, "SIP attended transfer: Error: No owner of target call\n");
22040       /* Cancel transfer */
22041       transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE);
22042       append_history(transferer, "Xfer", "Refer failed");
22043       ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
22044       transferer->refer->status = REFER_FAILED;
22045       sip_pvt_unlock(targetcall_pvt);
22046       if (targetcall_pvt)
22047          ao2_t_ref(targetcall_pvt, -1, "Drop targetcall_pvt pointer");
22048       return -1;
22049    }
22050 
22051    /* We have a channel, find the bridge */
22052    target.chan1 = targetcall_pvt->owner;           /* Transferer to Asterisk */
22053    target.chan2 = ast_bridged_channel(targetcall_pvt->owner);  /* Asterisk to target */
22054 
22055    if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) {
22056       /* Wrong state of new channel */
22057       if (target.chan2)
22058          ast_debug(4, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state));
22059       else if (target.chan1->_state != AST_STATE_RING)
22060          ast_debug(4, "SIP attended transfer: Error: No target channel\n");
22061       else
22062          ast_debug(4, "SIP attended transfer: Attempting transfer in ringing state\n");
22063    }
22064 
22065    /* Transfer */
22066    if (sipdebug) {
22067       if (current->chan2)  /* We have two bridges */
22068          ast_debug(4, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name);
22069       else        /* One bridge, propably transfer of IVR/voicemail etc */
22070          ast_debug(4, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name);
22071    }
22072 
22073    ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
22074 
22075    ast_copy_string(transferer_linkedid, transferer->owner->linkedid, sizeof(transferer_linkedid));
22076 
22077    /* Perform the transfer */
22078    chans[0] = transferer->owner;
22079    chans[1] = target.chan1;
22080    ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans,
22081       "TransferMethod: SIP\r\n"
22082       "TransferType: Attended\r\n"
22083       "Channel: %s\r\n"
22084       "Uniqueid: %s\r\n"
22085       "SIP-Callid: %s\r\n"
22086       "TargetChannel: %s\r\n"
22087       "TargetUniqueid: %s\r\n",
22088       transferer->owner->name,
22089       transferer->owner->uniqueid,
22090       transferer->callid,
22091       target.chan1->name,
22092       target.chan1->uniqueid);
22093    ast_party_connected_line_init(&connected_to_transferee);
22094    ast_party_connected_line_init(&connected_to_target);
22095    /* No need to lock current->chan1 here since it was locked in sipsock_read */
22096    ast_party_connected_line_copy(&connected_to_transferee, &current->chan1->connected);
22097    /* No need to lock target.chan1 here since it was locked in get_sip_pvt_byid_locked */
22098    ast_party_connected_line_copy(&connected_to_target, &target.chan1->connected);
22099    connected_to_target.source = connected_to_transferee.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
22100    res = attempt_transfer(current, &target);
22101    if (res) {
22102       /* Failed transfer */
22103       transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE);
22104       append_history(transferer, "Xfer", "Refer failed");
22105       ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
22106       /* if transfer failed, go ahead and unlock targetcall_pvt and it's owner channel */
22107       sip_pvt_unlock(targetcall_pvt);
22108       ast_channel_unlock(target.chan1);
22109    } else {
22110       /* Transfer succeeded! */
22111       const char *xfersound = pbx_builtin_getvar_helper(target.chan1, "ATTENDED_TRANSFER_COMPLETE_SOUND");
22112 
22113       /* target.chan1 was locked in get_sip_pvt_byid_locked, do not unlock target.chan1 before this */
22114       ast_cel_report_event(target.chan1, AST_CEL_ATTENDEDTRANSFER, NULL, transferer_linkedid, target.chan2);
22115 
22116       /* Tell transferer that we're done. */
22117       transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE);
22118       append_history(transferer, "Xfer", "Refer succeeded");
22119       transferer->refer->status = REFER_200OK;
22120       if (target.chan2 && !ast_strlen_zero(xfersound) && ast_streamfile(target.chan2, xfersound, target.chan2->language) >= 0) {
22121          ast_waitstream(target.chan2, "");
22122       }
22123 
22124       /* By forcing the masquerade, we know that target.chan1 and target.chan2 are bridged. We then
22125        * can queue connected line updates where they need to go.
22126        *
22127        * before a masquerade, all channel and pvt locks must be unlocked.  Any recursive
22128        * channel locks held before this function invalidates channel container locking order.
22129        * Since we are unlocking both the pvt (transferer) and its owner channel (current.chan1)
22130        * it is possible for current.chan1 to be destroyed in the pbx thread.  To prevent this
22131        * we must give c a reference before any unlocking takes place.
22132        */
22133 
22134       ast_channel_ref(current->chan1);
22135       ast_channel_unlock(current->chan1); /* current.chan1 is p->owner before the masq, it was locked by socket_read()*/
22136       ast_channel_unlock(target.chan1);
22137       *nounlock = 1;  /* we just unlocked the dialog's channel and have no plans of locking it again. */
22138       sip_pvt_unlock(targetcall_pvt);
22139       sip_pvt_unlock(transferer);
22140 
22141       ast_do_masquerade(target.chan1);
22142 
22143       sip_pvt_lock(transferer); /* the transferer pvt is expected to remain locked on return */
22144 
22145       ast_indicate(target.chan1, AST_CONTROL_UNHOLD);
22146 
22147       if (current->chan2 && current->chan2->_state == AST_STATE_RING) {
22148          ast_indicate(target.chan1, AST_CONTROL_RINGING);
22149       }
22150 
22151       if (target.chan2) {
22152          ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL);
22153          ast_channel_queue_connected_line_update(target.chan2, &connected_to_target, NULL);
22154       } else {
22155          /* Since target.chan1 isn't actually connected to another channel, there is no way for us
22156           * to queue a frame so that its connected line status will be updated.
22157           *
22158           * Instead, we use the somewhat hackish approach of using a special control frame type that
22159           * instructs ast_read to perform a specific action. In this case, the frame we queue tells
22160           * ast_read to call the connected line interception macro configured for target.chan1.
22161           */
22162          struct ast_control_read_action_payload *frame_payload;
22163          int payload_size;
22164          int frame_size;
22165          unsigned char connected_line_data[1024];
22166          payload_size = ast_connected_line_build_data(connected_line_data,
22167             sizeof(connected_line_data), &connected_to_target, NULL);
22168          frame_size = payload_size + sizeof(*frame_payload);
22169          if (payload_size != -1 && (frame_payload = alloca(frame_size))) {
22170             frame_payload->payload_size = payload_size;
22171             memcpy(frame_payload->payload, connected_line_data, payload_size);
22172             frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO;
22173             ast_queue_control_data(target.chan1, AST_CONTROL_READ_ACTION, frame_payload, frame_size);
22174          }
22175          /* In addition to queueing the read action frame so that target.chan1's connected line info
22176           * will be updated, we also are going to queue a plain old connected line update on target.chan1. This
22177           * way, either Dial or Queue can apply this connected line update to the outgoing ringing channel.
22178           */
22179          ast_channel_queue_connected_line_update(target.chan1, &connected_to_transferee, NULL);
22180 
22181       }
22182       ast_channel_unref(current->chan1);
22183    }
22184 
22185    /* at this point if the transfer is successful only the transferer pvt should be locked. */
22186    ast_party_connected_line_free(&connected_to_target);
22187    ast_party_connected_line_free(&connected_to_transferee);
22188    if (targetcall_pvt)
22189       ao2_t_ref(targetcall_pvt, -1, "drop targetcall_pvt");
22190    return 1;
22191 }

static int lws2sws ( char *  msgbuf,
int  len 
) [static]

Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.

Definition at line 7971 of file chan_sip.c.

Referenced by handle_request_do().

07972 {
07973    int h = 0, t = 0;
07974    int lws = 0;
07975 
07976    for (; h < len;) {
07977       /* Eliminate all CRs */
07978       if (msgbuf[h] == '\r') {
07979          h++;
07980          continue;
07981       }
07982       /* Check for end-of-line */
07983       if (msgbuf[h] == '\n') {
07984          /* Check for end-of-message */
07985          if (h + 1 == len)
07986             break;
07987          /* Check for a continuation line */
07988          if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') {
07989             /* Merge continuation line */
07990             h++;
07991             continue;
07992          }
07993          /* Propagate LF and start new line */
07994          msgbuf[t++] = msgbuf[h++];
07995          lws = 0;
07996          continue;
07997       }
07998       if (msgbuf[h] == ' ' || msgbuf[h] == '\t') {
07999          if (lws) {
08000             h++;
08001             continue;
08002          }
08003          msgbuf[t++] = msgbuf[h++];
08004          lws = 1;
08005          continue;
08006       }
08007       msgbuf[t++] = msgbuf[h++];
08008       if (lws)
08009          lws = 0;
08010    }
08011    msgbuf[t] = '\0';
08012    return t;
08013 }

static void make_our_tag ( char *  tagbuf,
size_t  len 
) [static]

Make our SIP dialog tag.

Definition at line 7213 of file chan_sip.c.

References ast_random().

Referenced by handle_request_invite(), handle_request_subscribe(), sip_alloc(), transmit_register(), and transmit_response_using_temp().

07214 {
07215    snprintf(tagbuf, len, "as%08lx", ast_random());
07216 }

static int manager_show_registry ( struct mansession *  s,
const struct message *  m 
) [static]

Show SIP registrations in the manager API.

Definition at line 15775 of file chan_sip.c.

References ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, regl, regstate2str(), S_OR, and total.

Referenced by load_module().

15776 {
15777    const char *id = astman_get_header(m, "ActionID");
15778    char idtext[256] = "";
15779    int total = 0;
15780 
15781    if (!ast_strlen_zero(id))
15782       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
15783 
15784    astman_send_listack(s, m, "Registrations will follow", "start");
15785 
15786    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
15787       ASTOBJ_RDLOCK(iterator);
15788       astman_append(s,
15789          "Event: RegistryEntry\r\n"
15790          "%s"
15791          "Host: %s\r\n"
15792          "Port: %d\r\n"
15793          "Username: %s\r\n"
15794          "Domain: %s\r\n"
15795          "DomainPort: %d\r\n"
15796          "Refresh: %d\r\n"
15797          "State: %s\r\n"
15798          "RegistrationTime: %ld\r\n"
15799          "\r\n",
15800          idtext,
15801          iterator->hostname,
15802          iterator->portno ? iterator->portno : STANDARD_SIP_PORT,
15803          iterator->username,
15804          S_OR(iterator->regdomain,iterator->hostname),
15805          iterator->regdomainport ? iterator->regdomainport : STANDARD_SIP_PORT,
15806          iterator->refresh,
15807          regstate2str(iterator->regstate),
15808          (long) iterator->regtime.tv_sec);
15809       ASTOBJ_UNLOCK(iterator);
15810       total++;
15811    } while(0));
15812 
15813    astman_append(s,
15814       "Event: RegistrationsComplete\r\n"
15815       "EventList: Complete\r\n"
15816       "ListItems: %d\r\n"
15817       "%s"
15818       "\r\n", total, idtext);
15819    
15820    return 0;
15821 }

static int manager_sip_qualify_peer ( struct mansession *  s,
const struct message *  m 
) [static]

Qualify SIP peers in the manager API.

Definition at line 16495 of file chan_sip.c.

References _sip_qualify_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), and astman_send_error().

Referenced by load_module().

16496 {
16497    const char *a[4];
16498    const char *peer;
16499 
16500    peer = astman_get_header(m, "Peer");
16501    if (ast_strlen_zero(peer)) {
16502       astman_send_error(s, m, "Peer: <name> missing.");
16503       return 0;
16504    }
16505    a[0] = "sip";
16506    a[1] = "qualify";
16507    a[2] = "peer";
16508    a[3] = peer;
16509 
16510    _sip_qualify_peer(1, -1, s, m, 4, a);
16511    astman_append(s, "\r\n\r\n" );
16512    return 0;
16513 }

static int manager_sip_show_peer ( struct mansession *  s,
const struct message *  m 
) [static]

Show SIP peers in the manager API.

Definition at line 16436 of file chan_sip.c.

References _sip_show_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), and astman_send_error().

Referenced by load_module().

16437 {
16438    const char *a[4];
16439    const char *peer;
16440 
16441    peer = astman_get_header(m, "Peer");
16442    if (ast_strlen_zero(peer)) {
16443       astman_send_error(s, m, "Peer: <name> missing.");
16444       return 0;
16445    }
16446    a[0] = "sip";
16447    a[1] = "show";
16448    a[2] = "peer";
16449    a[3] = peer;
16450 
16451    _sip_show_peer(1, -1, s, m, 4, a);
16452    astman_append(s, "\r\n\r\n" );
16453    return 0;
16454 }

static int manager_sip_show_peers ( struct mansession *  s,
const struct message *  m 
) [static]

Show SIP peers in the manager API.

Definition at line 15825 of file chan_sip.c.

References _sip_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), and total.

Referenced by load_module().

15826 {
15827    const char *id = astman_get_header(m, "ActionID");
15828    const char *a[] = {"sip", "show", "peers"};
15829    char idtext[256] = "";
15830    int total = 0;
15831 
15832    if (!ast_strlen_zero(id))
15833       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
15834 
15835    astman_send_listack(s, m, "Peer status list will follow", "start");
15836    /* List the peers in separate manager events */
15837    _sip_show_peers(-1, &total, s, m, 3, a);
15838    /* Send final confirmation */
15839    astman_append(s,
15840    "Event: PeerlistComplete\r\n"
15841    "EventList: Complete\r\n"
15842    "ListItems: %d\r\n"
15843    "%s"
15844    "\r\n", total, idtext);
15845    return 0;
15846 }

static int manager_sipnotify ( struct mansession *  s,
const struct message *  m 
) [static]

Definition at line 12225 of file chan_sip.c.

References ast_log(), ast_set_flag, ast_str_append(), ast_str_strlen(), ast_strlen_zero(), ast_variable_new(), astman_get_header(), astman_get_variables(), astman_send_error(), create_addr(), dialog_unlink_all(), LOG_WARNING, sip_alloc(), sip_notify_allocate(), TRUE, and var.

Referenced by load_module().

12226 {
12227    const char *channame = astman_get_header(m, "Channel");
12228    struct ast_variable *vars = astman_get_variables(m);
12229    struct sip_pvt *p;
12230    struct ast_variable *header, *var;
12231 
12232    if (ast_strlen_zero(channame)) {
12233       astman_send_error(s, m, "SIPNotify requires a channel name");
12234       return 0;
12235    }
12236 
12237    if (!strncasecmp(channame, "sip/", 4)) {
12238       channame += 4;
12239    }
12240 
12241    if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) {
12242       astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)");
12243       return 0;
12244    }
12245 
12246    if (create_addr(p, channame, NULL, 0, NULL)) {
12247       /* Maybe they're not registered, etc. */
12248       dialog_unlink_all(p, TRUE, TRUE);
12249       dialog_unref(p, "unref dialog inside for loop" );
12250       /* sip_destroy(p); */
12251       astman_send_error(s, m, "Could not create address");
12252       return 0;
12253    }
12254 
12255    /* Notify is outgoing call */
12256    ast_set_flag(&p->flags[0], SIP_OUTGOING);
12257    sip_notify_allocate(p);
12258 
12259    p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", "");
12260 
12261    for (var = vars; var; var = var->next) {
12262       if (!strcasecmp(var->name, "Content")) {
12263          if (ast_str_strlen(p->notify->content))
12264             ast_str_append(&p->notify->content, 0, "\r\n");
12265          ast_str_append(&p->notify->content, 0, "%s", var->value);
12266       } else if (!strcasecmp(var->name, "Content-Length")) {
12267          ast_log(LOG_WARNING, "it is not necessary to specify Content-Length, ignoring");
12268       } else {
12269          header->next = ast_variable_new(var->name, var->value, "");
12270          header = header->next;
12271       }
12272    }
12273 
12274    dialog_ref(p, "bump the count of p, which transmit_sip_request will decrement.");
12275    sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
12276    transmit_invite(p, SIP_NOTIFY, 0, 2, NULL);
12277 
12278    astman_send_ack(s, m, "Notify Sent");
12279    ast_variables_destroy(vars);
12280    return 0;
12281 }

static int map_s_x ( const struct _map_x_s *  table,
const char *  s,
int  errorvalue 
) [static]

map from a string to an integer value, case insensitive. If no match is found, return errorvalue.

Definition at line 2232 of file chan_sip.c.

References table.

Referenced by str2dtmfmode(), str2stmode(), and str2strefresher().

02233 {
02234    const struct _map_x_s *cur;
02235 
02236    for (cur = table; cur->s; cur++)
02237       if (!strcasecmp(cur->s, s))
02238          return cur->x;
02239    return errorvalue;
02240 }

static const char* map_x_s ( const struct _map_x_s *  table,
int  x,
const char *  errorstring 
) [static]

map from an integer value to a string. If no match is found, return errorstring

Definition at line 2219 of file chan_sip.c.

References table.

Referenced by dtmfmode2str(), faxec2str(), insecure2str(), referstatus2str(), regstate2str(), stmode2str(), and strefresher2str().

02220 {
02221    const struct _map_x_s *cur;
02222 
02223    for (cur = table; cur->s; cur++)
02224       if (cur->x == x)
02225          return cur->s;
02226    return errorstring;
02227 }

static void mark_method_allowed ( unsigned int *  allowed_methods,
enum sipmethod  method 
) [static]

Definition at line 7872 of file chan_sip.c.

Referenced by handle_response(), mark_parsed_methods(), and set_pvt_allowed_methods().

07873 {
07874    (*allowed_methods) |= (1 << method);
07875 }

static void mark_method_unallowed ( unsigned int *  allowed_methods,
enum sipmethod  method 
) [static]

Definition at line 7877 of file chan_sip.c.

Referenced by handle_response(), and handle_response_publish().

07878 {
07879    (*allowed_methods) &= ~(1 << method);
07880 }

static void mark_parsed_methods ( unsigned int *  methods,
char *  methods_str 
) [static]

Definition at line 7888 of file chan_sip.c.

References ast_skip_blanks(), ast_strlen_zero(), find_sip_method(), mark_method_allowed(), and strsep().

Referenced by build_peer(), and parse_allowed_methods().

07889 {
07890    char *method;
07891    for (method = strsep(&methods_str, ","); !ast_strlen_zero(method); method = strsep(&methods_str, ",")) {
07892       int id = find_sip_method(ast_skip_blanks(method));
07893       if (id == SIP_UNKNOWN) {
07894          continue;
07895       }
07896       mark_method_allowed(methods, id);
07897    }
07898 }

static enum match_req_res match_req_to_dialog ( struct sip_pvt *  sip_pvt_ptr,
struct match_req_args *  arg 
) [static]

Definition at line 7471 of file chan_sip.c.

References ast_strlen_zero(), ast_test_flag, match_req_args::authentication_present, match_req_args::callid, match_req_args::fromtag, match_req_args::method, match_req_args::ruri, match_req_args::seqno, SIP_REQ_LOOP_DETECTED, SIP_REQ_MATCH, SIP_REQ_NOT_MATCH, match_req_args::totag, match_req_args::viabranch, and match_req_args::viasentby.

Referenced by find_call().

07472 {
07473    const char *init_ruri = NULL;
07474    if (sip_pvt_ptr->initreq.headers) {
07475       init_ruri = REQ_OFFSET_TO_STR(&sip_pvt_ptr->initreq, rlPart2);
07476    }
07477 
07478    /*
07479     * Match Tags and call-id to Dialog
07480     */
07481    if (!ast_strlen_zero(arg->callid) && strcmp(sip_pvt_ptr->callid, arg->callid)) {
07482       /* call-id does not match. */
07483       return SIP_REQ_NOT_MATCH;
07484    }
07485    if (arg->method == SIP_RESPONSE) {
07486       /* Verify totag if we have one stored for this dialog, but never be strict about this for
07487        * a response until the dialog is established */
07488       if (!ast_strlen_zero(sip_pvt_ptr->theirtag) && ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
07489          if (ast_strlen_zero(arg->totag)) {
07490             /* missing totag when they already gave us one earlier */
07491             return SIP_REQ_NOT_MATCH;
07492          }
07493          if (strcmp(arg->totag, sip_pvt_ptr->theirtag)) {
07494             /* The totag of the response does not match the one we have stored */
07495             return SIP_REQ_NOT_MATCH;
07496          }
07497       }
07498       /* Verify fromtag of response matches the tag we gave them. */
07499       if (strcmp(arg->fromtag, sip_pvt_ptr->tag)) {
07500          /* fromtag from response does not match our tag */
07501          return SIP_REQ_NOT_MATCH;
07502       }
07503    } else {
07504       /* Verify the fromtag of Request matches the tag they provided earlier.
07505        * If this is a Request with authentication credentials, forget their old
07506        * tag as it is not valid after the 401 or 407 response. */
07507       if (!arg->authentication_present && strcmp(arg->fromtag, sip_pvt_ptr->theirtag)) {
07508          /* their tag does not match the one was have stored for them */
07509          return SIP_REQ_NOT_MATCH;
07510       }
07511       /* Verify if totag is present in Request, that it matches what we gave them as our tag earlier */
07512       if (!ast_strlen_zero(arg->totag) && (strcmp(arg->totag, sip_pvt_ptr->tag))) {
07513          /* totag from Request does not match our tag */
07514          return SIP_REQ_NOT_MATCH;
07515       }
07516    }
07517 
07518    /*
07519     * Compare incoming request against initial transaction.
07520     * 
07521     * This is a best effort attempt at distinguishing forked requests from
07522     * our initial transaction.  If all the elements are NOT in place to evaluate
07523     * this, this block is ignored and the dialog match is made regardless.
07524     * Once the totag is established after the dialog is confirmed, this is not necessary.
07525     *
07526     * CRITERIA required for initial transaction matching.
07527     * 
07528     * 1. Is a Request
07529     * 2. Callid and theirtag match (this is done in the dialog matching block)
07530     * 3. totag is NOT present
07531     * 4. CSeq matchs our initial transaction's cseq number
07532     * 5. pvt has init via branch parameter stored
07533     */
07534    if ((arg->method != SIP_RESPONSE) &&                 /* must be a Request */
07535       ast_strlen_zero(arg->totag) &&                   /* must not have a totag */
07536       (sip_pvt_ptr->init_icseq == arg->seqno) &&       /* the cseq must be the same as this dialogs initial cseq */
07537       !ast_strlen_zero(sip_pvt_ptr->initviabranch) &&  /* The dialog must have started with a RFC3261 compliant branch tag */
07538       init_ruri) {                                     /* the dialog must have an initial request uri associated with it */
07539       /* This Request matches all the criteria required for Loop/Merge detection.
07540        * Now we must go down the path of comparing VIA's and RURIs. */
07541       if (ast_strlen_zero(arg->viabranch) ||
07542          strcmp(arg->viabranch, sip_pvt_ptr->initviabranch) ||
07543          ast_strlen_zero(arg->viasentby) ||
07544          strcmp(arg->viasentby, sip_pvt_ptr->initviasentby)) {
07545          /* At this point, this request does not match this Dialog.*/
07546 
07547          /* if methods are different this is just a mismatch */
07548          if ((sip_pvt_ptr->method != arg->method)) {
07549             return SIP_REQ_NOT_MATCH;
07550          }
07551 
07552          /* If RUIs are different, this is a forked request to a separate URI.
07553           * Returning a mismatch allows this Request to be processed separately. */
07554          if (sip_uri_cmp(init_ruri, arg->ruri)) {
07555             /* not a match, request uris are different */
07556             return SIP_REQ_NOT_MATCH;
07557          }
07558 
07559          /* Loop/Merge Detected
07560           *
07561           * ---Current Matches to Initial Request---
07562           * request uri
07563           * Call-id
07564           * their-tag
07565           * no totag present
07566           * method
07567           * cseq
07568           *
07569           * --- Does not Match Initial Request ---
07570           * Top Via
07571           *
07572           * Without the same Via, this can not match our initial transaction for this dialog,
07573           * but given that this Request matches everything else associated with that initial
07574           * Request this is most certainly a Forked request in which we have already received
07575           * part of the fork.
07576           */
07577          return SIP_REQ_LOOP_DETECTED;
07578       }
07579    } /* end of Request Via check */
07580 
07581    /* Match Authentication Request.
07582     *
07583     * A Request with an Authentication header must come back with the
07584     * same Request URI.  Otherwise it is not a match.
07585     */
07586    if ((arg->method != SIP_RESPONSE) &&      /* Must be a Request type to even begin checking this */
07587       ast_strlen_zero(arg->totag) &&        /* no totag is present to match */
07588       arg->authentication_present &&        /* Authentication header is present in Request */
07589       sip_uri_cmp(init_ruri, arg->ruri)) {  /* Compare the Request URI of both the last Request and this new one */
07590 
07591       /* Authentication was provided, but the Request URI did not match the last one on this dialog. */
07592       return SIP_REQ_NOT_MATCH;
07593    }
07594 
07595    return SIP_REQ_MATCH;
07596 }

static int method_match ( enum sipmethod  id,
const char *  name 
) [static]

returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send

Definition at line 3070 of file chan_sip.c.

References len(), sip_methods, and text.

Referenced by __sip_autodestruct(), __sip_semi_ack(), and find_sip_method().

03071 {
03072    int len = strlen(sip_methods[id].text);
03073    int l_name = name ? strlen(name) : 0;
03074    /* true if the string is long enough, and ends with whitespace, and matches */
03075    return (l_name >= len && name[len] < 33 &&
03076       !strncasecmp(sip_methods[id].text, name, len));
03077 }

static void mwi_event_cb ( const struct ast_event *  ,
void *   
) [static]

Receive MWI events that we have subscribed to.

Definition at line 13793 of file chan_sip.c.

References ao2_lock, ao2_unlock, and sip_send_mwi_to_peer().

13794 {
13795    struct sip_peer *peer = userdata;
13796 
13797    ao2_lock(peer);
13798    sip_send_mwi_to_peer(peer, event, 0);
13799    ao2_unlock(peer);
13800 }

static void network_change_event_cb ( const struct ast_event *  ,
void *   
) [static]

Definition at line 13827 of file chan_sip.c.

References ast_debug, ast_sched_add(), network_change_event_sched_cb(), and network_change_event_sched_id.

13828 {
13829    ast_debug(1, "SIP, got a network change event, renewing all SIP registrations.\n");
13830    if (network_change_event_sched_id == -1) {
13831       network_change_event_sched_id = ast_sched_add(sched, 1000, network_change_event_sched_cb, NULL);
13832    }
13833 }

static int network_change_event_sched_cb ( const void *  data  )  [static]

Definition at line 13819 of file chan_sip.c.

References network_change_event_sched_id, sip_send_all_mwi_subscriptions(), and sip_send_all_registers().

13820 {
13821    network_change_event_sched_id = -1;
13822    sip_send_all_registers();
13823    sip_send_all_mwi_subscriptions();
13824    return 0;
13825 }

static void network_change_event_subscribe ( void   )  [static]

Definition at line 13802 of file chan_sip.c.

References AST_EVENT_IE_END, AST_EVENT_NETWORK_CHANGE, ast_event_subscribe(), network_change_event_cb(), and network_change_event_subscription.

13803 {
13804    if (!network_change_event_subscription) {
13805       network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE,
13806          network_change_event_cb,
13807          "SIP Network Change ",
13808          NULL, AST_EVENT_IE_END);
13809    }
13810 }

static void network_change_event_unsubscribe ( void   )  [static]

Definition at line 13812 of file chan_sip.c.

References ast_event_unsubscribe(), and network_change_event_subscription.

13813 {
13814    if (network_change_event_subscription) {
13815       network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription);
13816    }
13817 }

static struct sip_proxy* obproxy_get ( struct sip_pvt *  dialog,
struct sip_peer *  peer 
) [static]

Get default outbound proxy or global proxy.

Definition at line 3042 of file chan_sip.c.

References append_history, ast_debug, sip_cfg, and sipdebug.

Referenced by __sip_subscribe_mwi_do(), create_addr(), and create_addr_from_peer().

03043 {
03044    if (peer && peer->outboundproxy) {
03045       if (sipdebug) {
03046          ast_debug(1, "OBPROXY: Applying peer OBproxy to this call\n");
03047       }
03048       append_history(dialog, "OBproxy", "Using peer obproxy %s", peer->outboundproxy->name);
03049       return peer->outboundproxy;
03050    }
03051    if (sip_cfg.outboundproxy.name[0]) {
03052       if (sipdebug) {
03053          ast_debug(1, "OBPROXY: Applying global OBproxy to this call\n");
03054       }
03055       append_history(dialog, "OBproxy", "Using global obproxy %s", sip_cfg.outboundproxy.name);
03056       return &sip_cfg.outboundproxy;
03057    }
03058    if (sipdebug) {
03059       ast_debug(1, "OBPROXY: Not applying OBproxy to this call\n");
03060    }
03061    return NULL;
03062 }

static unsigned int parse_allowed_methods ( struct sip_request *  req  )  [static]

parse the Allow header to see what methods the endpoint we are communicating with allows.

We parse the allow header on incoming Registrations and save the result to the SIP peer that is registering. When the registration expires, we clear what we know about the peer's allowed methods. When the peer re-registers, we once again parse to see if the list of allowed methods has changed.

For peers that do not register, we parse the first message we receive during a call to see what is allowed, and save the information for the duration of the call.

Parameters:
req The SIP request we are parsing
Return values:
The methods allowed

Definition at line 7915 of file chan_sip.c.

References ast_strdupa, ast_strip_quoted(), ast_strlen_zero(), get_header(), and mark_parsed_methods().

Referenced by set_pvt_allowed_methods().

07916 {
07917    char *allow = ast_strdupa(get_header(req, "Allow"));
07918    unsigned int allowed_methods = SIP_UNKNOWN;
07919 
07920    if (ast_strlen_zero(allow)) {
07921       /* I have witnessed that REGISTER requests from Polycom phones do not
07922        * place the phone's allowed methods in an Allow header. Instead, they place the
07923        * allowed methods in a methods= parameter in the Contact header.
07924        */
07925       char *contact = ast_strdupa(get_header(req, "Contact"));
07926       char *methods = strstr(contact, ";methods=");
07927 
07928       if (ast_strlen_zero(methods)) {
07929          /* RFC 3261 states:
07930           *
07931           * "The absence of an Allow header field MUST NOT be
07932           * interpreted to mean that the UA sending the message supports no
07933           * methods.   Rather, it implies that the UA is not providing any
07934           * information on what methods it supports."
07935           *
07936           * For simplicity, we'll assume that the peer allows all known
07937           * SIP methods if they have no Allow header. We can then clear out the necessary
07938           * bits if the peer lets us know that we have sent an unsupported method.
07939           */
07940          return UINT_MAX;
07941       }
07942       allow = ast_strip_quoted(methods + 9, "\"", "\"");
07943    }
07944    mark_parsed_methods(&allowed_methods, allow);
07945    return allowed_methods;
07946 }

static void parse_copy ( struct sip_request *  dst,
const struct sip_request *  src 
) [static]

Copy SIP request, parse it.

Definition at line 3993 of file chan_sip.c.

References copy_request(), and parse_request().

Referenced by send_request(), and send_response().

03994 {
03995    copy_request(dst, src);
03996    parse_request(dst);
03997 }

int parse_minse ( const char *  p_hdrval,
int *const   p_interval 
) [static]

Session-Timers: Function for parsing Min-SE header.

Definition at line 24896 of file chan_sip.c.

References ast_debug, ast_log(), ast_skip_blanks(), ast_strlen_zero(), and LOG_WARNING.

Referenced by handle_request_invite(), and proc_422_rsp().

24897 {
24898    if (ast_strlen_zero(p_hdrval)) {
24899       ast_log(LOG_WARNING, "Null Min-SE header\n");
24900       return -1;
24901    }
24902 
24903    *p_interval = 0;
24904    p_hdrval = ast_skip_blanks(p_hdrval);
24905    if (!sscanf(p_hdrval, "%30d", p_interval)) {
24906       ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval);
24907       return -1;
24908    }
24909 
24910    ast_debug(2, "Received Min-SE: %d\n", *p_interval);
24911    return 0;
24912 }

static void parse_moved_contact ( struct sip_pvt *  p,
struct sip_request *  req,
char **  name,
char **  number,
int  set_call_forward 
) [static]

Parse 302 Moved temporalily response.

Todo:
XXX Doesn't redirect over TLS on sips: uri's. If we get a redirect to a SIPS: uri, this needs to be going back to the dialplan (this is a request for a secure signalling path). Note that transport=tls is deprecated, but we need to support it on incoming requests.

Definition at line 18749 of file chan_sip.c.

References ao2_ref, ast_copy_string(), ast_debug, ast_log(), ast_strdup, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), find_closing_quote(), get_header(), get_transport(), LOG_NOTICE, pbx_builtin_setvar_helper(), remove_uri_parameters(), set_socket_transport(), and strcasestr().

Referenced by change_redirecting_information().

18750 {
18751    char contact[SIPBUFSIZE];
18752    char *contact_name = NULL;
18753    char *contact_number = NULL;
18754    char *separator, *trans;
18755    char *domain;
18756    enum sip_transport transport = SIP_TRANSPORT_UDP;
18757 
18758    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
18759    if ((separator = strchr(contact, ',')))
18760       *separator = '\0';
18761 
18762    contact_number = get_in_brackets(contact);
18763    if ((trans = strcasestr(contact_number, ";transport="))) {
18764       trans += 11;
18765 
18766       if ((separator = strchr(trans, ';')))
18767          *separator = '\0';
18768 
18769       if (!strncasecmp(trans, "tcp", 3))
18770          transport = SIP_TRANSPORT_TCP;
18771       else if (!strncasecmp(trans, "tls", 3))
18772          transport = SIP_TRANSPORT_TLS;
18773       else {
18774          if (strncasecmp(trans, "udp", 3))
18775             ast_debug(1, "received contact with an invalid transport, '%s'\n", contact_number);
18776          /* This will assume UDP for all unknown transports */
18777          transport = SIP_TRANSPORT_UDP;
18778       }
18779    }
18780    contact_number = remove_uri_parameters(contact_number);
18781 
18782    if (p->socket.tcptls_session) {
18783       ao2_ref(p->socket.tcptls_session, -1);
18784       p->socket.tcptls_session = NULL;
18785    }
18786 
18787    set_socket_transport(&p->socket, transport);
18788 
18789    if (set_call_forward && ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
18790       char *host = NULL;
18791       if (!strncasecmp(contact_number, "sip:", 4))
18792          contact_number += 4;
18793       else if (!strncasecmp(contact_number, "sips:", 5))
18794          contact_number += 5;
18795       separator = strchr(contact_number, '/');
18796       if (separator)
18797          *separator = '\0';
18798       if ((host = strchr(contact_number, '@'))) {
18799          *host++ = '\0';
18800          ast_debug(2, "Found promiscuous redirection to 'SIP/%s::::%s@%s'\n", contact_number, get_transport(transport), host);
18801          if (p->owner)
18802             ast_string_field_build(p->owner, call_forward, "SIP/%s::::%s@%s", contact_number, get_transport(transport), host);
18803       } else {
18804          ast_debug(2, "Found promiscuous redirection to 'SIP/::::%s@%s'\n", get_transport(transport), contact_number);
18805          if (p->owner)
18806             ast_string_field_build(p->owner, call_forward, "SIP/::::%s@%s", get_transport(transport), contact_number);
18807       }
18808    } else {
18809       separator = strchr(contact, '@');
18810       if (separator) {
18811          *separator++ = '\0';
18812          domain = separator;
18813       } else {
18814          /* No username part */
18815          domain = contact;
18816       }
18817       separator = strchr(contact, '/');   /* WHEN do we hae a forward slash in the URI? */
18818       if (separator)
18819          *separator = '\0';
18820 
18821       if (!strncasecmp(contact_number, "sip:", 4))
18822          contact_number += 4;
18823       else if (!strncasecmp(contact_number, "sips:", 5))
18824          contact_number += 5;
18825       separator = strchr(contact_number, ';');  /* And username ; parameters? */
18826       if (separator)
18827          *separator = '\0';
18828       ast_uri_decode(contact_number);
18829       if (set_call_forward) {
18830          ast_debug(2, "Received 302 Redirect to extension '%s' (domain %s)\n", contact_number, domain);
18831          if (p->owner) {
18832             pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
18833             ast_string_field_set(p->owner, call_forward, contact_number);
18834          }
18835       }
18836    }
18837 
18838    /* We've gotten the number for the contact, now get the name */
18839 
18840    if (*contact == '\"') {
18841       contact_name = contact + 1;
18842       if (!(separator = (char *)find_closing_quote(contact_name, NULL))) {
18843          ast_log(LOG_NOTICE, "No closing quote on name in Contact header? %s\n", contact);
18844       }
18845       *separator = '\0';
18846    }
18847 
18848    if (name && !ast_strlen_zero(contact_name)) {
18849       *name = ast_strdup(contact_name);
18850    }
18851    if (number) {
18852       *number = ast_strdup(contact_number);
18853    }
18854 }

static int parse_ok_contact ( struct sip_pvt *  pvt,
struct sip_request *  req 
) [static]

Save contact header for 200 OK on INVITE.

Definition at line 13131 of file chan_sip.c.

References ast_copy_string(), ast_string_field_set, get_header(), and TRUE.

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

13132 {
13133    char contact[SIPBUFSIZE];
13134    char *c;
13135 
13136    /* Look for brackets */
13137    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
13138    c = get_in_brackets(contact);
13139 
13140    /* Save full contact to call pvt for later bye or re-invite */
13141    ast_string_field_set(pvt, fullcontact, c);
13142 
13143    /* Save URI for later ACKs, BYE or RE-invites */
13144    ast_string_field_set(pvt, okcontacturi, c);
13145 
13146    /* We should return false for URI:s we can't handle,
13147       like tel:, mailto:,ldap: etc */
13148    return TRUE;      
13149 }

static enum parse_register_result parse_register_contact ( struct sip_pvt *  pvt,
struct sip_peer *  p,
struct sip_request *  req 
) [static]

Parse contact header and save registration (peer registration).

Todo:
Check NAPTR/SRV if we have not got a port in the URI

Definition at line 13213 of file chan_sip.c.

References __get_header(), ao2_t_link, ao2_t_unlink, ast_apply_ha(), ast_copy_string(), ast_db_put(), ast_debug, ast_log(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_sched_when(), AST_SENSE_ALLOW, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose, copy_socket_data(), default_expiry, destroy_association(), EVENT_FLAG_SYSTEM, expire_register(), FALSE, get_header(), get_transport_str2enum(), LOG_NOTICE, LOG_WARNING, manager_event, max_expiry, min_expiry, peers_by_ip, ref_peer(), register_peer_exten(), set_socket_transport(), sip_cfg, sip_poke_peer(), strcasestr(), strsep(), TRUE, unref_peer(), VERBOSE_PREFIX_3, and VERBOSITY_ATLEAST.

Referenced by register_verify().

13214 {
13215    char contact[SIPBUFSIZE];
13216    char data[SIPBUFSIZE];
13217    const char *expires = get_header(req, "Expires");
13218    int expire = atoi(expires);
13219    char *curi, *domain, *transport;
13220    int transport_type;
13221    const char *useragent;
13222    struct ast_sockaddr oldsin, testsa;
13223    char *firstcuri = NULL;
13224    int start = 0;
13225    int wildcard_found = 0;
13226    int single_binding_found = 0;
13227 
13228    ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact));
13229 
13230    if (ast_strlen_zero(expires)) {  /* No expires header, try look in Contact: */
13231       char *s = strcasestr(contact, ";expires=");
13232       if (s) {
13233          expires = strsep(&s, ";"); /* trim ; and beyond */
13234          if (sscanf(expires + 9, "%30d", &expire) != 1) {
13235             expire = default_expiry;
13236          }
13237       } else {
13238          /* Nothing has been specified */
13239          expire = default_expiry;
13240       }
13241    }
13242 
13243    copy_socket_data(&pvt->socket, &req->socket);
13244 
13245    do {
13246       /* Look for brackets */
13247       curi = contact;
13248       if (strchr(contact, '<') == NULL)   /* No <, check for ; and strip it */
13249          strsep(&curi, ";");  /* This is Header options, not URI options */
13250       curi = get_in_brackets(contact);
13251       if (!firstcuri) {
13252          firstcuri = ast_strdupa(curi);
13253       }
13254 
13255       if (!strcasecmp(curi, "*")) {
13256          wildcard_found = 1;
13257       } else {
13258          single_binding_found = 1;
13259       }
13260 
13261       if (wildcard_found && (ast_strlen_zero(expires) || expire != 0 || single_binding_found)) {
13262          /* Contact header parameter "*" detected, so punt if: Expires header is missing,
13263           * Expires value is not zero, or another Contact header is present. */
13264          return PARSE_REGISTER_FAILED;
13265       }
13266 
13267       ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact));
13268    } while (!ast_strlen_zero(contact));
13269    curi = firstcuri;
13270 
13271    /* if they did not specify Contact: or Expires:, they are querying
13272       what we currently have stored as their contact address, so return
13273       it
13274    */
13275    if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) {
13276       /* If we have an active registration, tell them when the registration is going to expire */
13277       if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) {
13278          pvt->expiry = ast_sched_when(sched, peer->expire);
13279       }
13280       return PARSE_REGISTER_QUERY;
13281    } else if (!strcasecmp(curi, "*") || !expire) { /* Unregister this peer */
13282       /* This means remove all registrations and return OK */
13283       memset(&peer->addr, 0, sizeof(peer->addr));
13284       set_socket_transport(&peer->socket, peer->default_outbound_transport);
13285 
13286       AST_SCHED_DEL_UNREF(sched, peer->expire,
13287             unref_peer(peer, "remove register expire ref"));
13288 
13289       destroy_association(peer);
13290 
13291       register_peer_exten(peer, FALSE);   /* Remove extension from regexten= setting in sip.conf */
13292       ast_string_field_set(peer, fullcontact, "");
13293       ast_string_field_set(peer, useragent, "");
13294       peer->sipoptions = 0;
13295       peer->lastms = 0;
13296       peer->portinuri = 0;
13297       pvt->expiry = 0;
13298 
13299       ast_verb(3, "Unregistered SIP '%s'\n", peer->name);
13300 
13301       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name);
13302       return PARSE_REGISTER_UPDATE;
13303    }
13304 
13305    /* Store whatever we got as a contact from the client */
13306    ast_string_field_set(peer, fullcontact, curi);
13307 
13308    /* For the 200 OK, we should use the received contact */
13309    ast_string_field_build(pvt, our_contact, "<%s>", curi);
13310 
13311    /* Make sure it's a SIP URL */
13312    if (parse_uri(curi, "sip:,sips:", &curi, NULL, &domain, &transport)) {
13313       ast_log(LOG_NOTICE, "Not a valid SIP contact (missing sip:/sips:) trying to use anyway\n");
13314    }
13315 
13316    /* handle the transport type specified in Contact header. */
13317    if (!(transport_type = get_transport_str2enum(transport))) {
13318       transport_type = pvt->socket.type;
13319    }
13320 
13321    /* if the peer's socket type is different than the Registration
13322     * transport type, change it.  If it got this far, it is a
13323     * supported type, but check just in case */
13324    if ((peer->socket.type != transport_type) && (peer->transports & transport_type)) {
13325       set_socket_transport(&peer->socket, transport_type);
13326    }
13327 
13328    oldsin = peer->addr;
13329 
13330    /* If we were already linked into the peers_by_ip container unlink ourselves so nobody can find us */
13331    if (!ast_sockaddr_isnull(&peer->addr)) {
13332       ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
13333    }
13334 
13335    if (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) && !ast_test_flag(&peer->flags[0], SIP_NAT_RPORT_PRESENT)) {
13336        /* use the data provided in the Contact header for call routing */
13337       ast_debug(1, "Store REGISTER's Contact header for call routing.\n");
13338       /* XXX This could block for a long time XXX */
13339       /*! \todo Check NAPTR/SRV if we have not got a port in the URI */
13340       if (ast_sockaddr_resolve_first(&testsa, domain, 0)) {
13341          ast_log(LOG_WARNING, "Invalid domain '%s'\n", domain);
13342          ast_string_field_set(peer, fullcontact, "");
13343          ast_string_field_set(pvt, our_contact, "");
13344          return PARSE_REGISTER_FAILED;
13345       }
13346 
13347       /* If we have a port number in the given URI, make sure we do remember to not check for NAPTR/SRV records.
13348          The domain part is actually a host. */
13349       peer->portinuri = ast_sockaddr_port(&testsa) ? TRUE : FALSE;
13350 
13351       if (!ast_sockaddr_port(&testsa)) {
13352          ast_sockaddr_set_port(&testsa,
13353                     transport_type == SIP_TRANSPORT_TLS ?
13354                     STANDARD_TLS_PORT : STANDARD_SIP_PORT);
13355       }
13356 
13357       ast_sockaddr_copy(&peer->addr, &testsa);
13358    } else {
13359       /* Don't trust the contact field.  Just use what they came to us
13360          with */
13361       ast_debug(1, "Store REGISTER's src-IP:port for call routing.\n");
13362       peer->addr = pvt->recv;
13363    }
13364 
13365    /* Check that they're allowed to register at this IP */
13366    if (ast_apply_ha(sip_cfg.contact_ha, &peer->addr) != AST_SENSE_ALLOW ||
13367          ast_apply_ha(peer->contactha, &peer->addr) != AST_SENSE_ALLOW) {
13368       ast_log(LOG_WARNING, "Domain '%s' disallowed by contact ACL (violating IP %s)\n", domain,
13369          ast_sockaddr_stringify_addr(&testsa));
13370       ast_string_field_set(peer, fullcontact, "");
13371       ast_string_field_set(pvt, our_contact, "");
13372       return PARSE_REGISTER_DENIED;
13373    }
13374 
13375    /* if the Contact header information copied into peer->addr matches the
13376     * received address, and the transport types are the same, then copy socket
13377     * data into the peer struct */
13378    if ((peer->socket.type == pvt->socket.type) &&
13379       !ast_sockaddr_cmp(&peer->addr, &pvt->recv)) {
13380       copy_socket_data(&peer->socket, &pvt->socket);
13381    }
13382 
13383    /* Now that our address has been updated put ourselves back into the container for lookups */
13384    ao2_t_link(peers_by_ip, peer, "ao2_link into peers_by_ip table");
13385 
13386    /* Save SIP options profile */
13387    peer->sipoptions = pvt->sipoptions;
13388 
13389    if (!ast_strlen_zero(curi) && ast_strlen_zero(peer->username)) {
13390       ast_string_field_set(peer, username, curi);
13391    }
13392 
13393    AST_SCHED_DEL_UNREF(sched, peer->expire,
13394          unref_peer(peer, "remove register expire ref"));
13395 
13396    if (expire > max_expiry) {
13397       expire = max_expiry;
13398    }
13399    if (expire < min_expiry) {
13400       expire = min_expiry;
13401    }
13402    if (peer->is_realtime && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
13403       peer->expire = -1;
13404    } else {
13405       peer->expire = ast_sched_add(sched, (expire + 10) * 1000, expire_register,
13406             ref_peer(peer, "add registration ref"));
13407       if (peer->expire == -1) {
13408          unref_peer(peer, "remote registration ref");
13409       }
13410    }
13411    pvt->expiry = expire;
13412    snprintf(data, sizeof(data), "%s:%d:%s:%s", ast_sockaddr_stringify(&peer->addr),
13413        expire, peer->username, peer->fullcontact);
13414    /* Saving TCP connections is useless, we won't be able to reconnect
13415       XXX WHY???? XXX
13416       \todo Fix this immediately.
13417    */
13418    if (!peer->rt_fromcontact && (peer->socket.type & SIP_TRANSPORT_UDP))
13419       ast_db_put("SIP/Registry", peer->name, data);
13420    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\n", peer->name,  ast_sockaddr_stringify(&peer->addr));
13421 
13422    /* Is this a new IP address for us? */
13423    if (VERBOSITY_ATLEAST(2) && ast_sockaddr_cmp(&peer->addr, &oldsin)) {
13424       ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s\n", peer->name,
13425             ast_sockaddr_stringify(&peer->addr));
13426    }
13427    sip_poke_peer(peer, 0);
13428    register_peer_exten(peer, 1);
13429    
13430    /* Save User agent */
13431    useragent = get_header(req, "User-Agent");
13432    if (strcasecmp(useragent, peer->useragent)) {
13433       ast_string_field_set(peer, useragent, useragent);
13434       ast_verb(4, "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name);
13435    }
13436    return PARSE_REGISTER_UPDATE;
13437 }

static int parse_request ( struct sip_request *  req  )  [static]

Parse a SIP message.

Note:
this function is used both on incoming and outgoing packets

Definition at line 8018 of file chan_sip.c.

References ast_debug, ast_strlen_zero(), and sipdebug.

Referenced by handle_request_do(), initialize_initreq(), and parse_copy().

08019 {
08020    char *c = req->data->str;
08021    ptrdiff_t *dst = req->header;
08022    int i = 0, lim = SIP_MAX_HEADERS - 1;
08023    unsigned int skipping_headers = 0;
08024    ptrdiff_t current_header_offset = 0;
08025    char *previous_header = "";
08026 
08027    req->header[0] = 0;
08028    req->headers = -1;   /* mark that we are working on the header */
08029    for (; *c; c++) {
08030       if (*c == '\r') {    /* remove \r */
08031          *c = '\0';
08032       } else if (*c == '\n') {   /* end of this line */
08033          *c = '\0';
08034          current_header_offset = (c + 1) - req->data->str;
08035          previous_header = req->data->str + dst[i];
08036          if (skipping_headers) {
08037             /* check to see if this line is blank; if so, turn off
08038                the skipping flag, so the next line will be processed
08039                as a body line */
08040             if (ast_strlen_zero(previous_header)) {
08041                skipping_headers = 0;
08042             }
08043             dst[i] = current_header_offset; /* record start of next line */
08044             continue;
08045          }
08046          if (sipdebug) {
08047             ast_debug(4, "%7s %2d [%3d]: %s\n",
08048                  req->headers < 0 ? "Header" : "Body",
08049                  i, (int) strlen(previous_header), previous_header);
08050          }
08051          if (ast_strlen_zero(previous_header) && req->headers < 0) {
08052             req->headers = i; /* record number of header lines */
08053             dst = req->line;  /* start working on the body */
08054             i = 0;
08055             lim = SIP_MAX_LINES - 1;
08056          } else { /* move to next line, check for overflows */
08057             if (i++ == lim) {
08058                /* if we're processing headers, then skip any remaining
08059                   headers and move on to processing the body, otherwise
08060                   we're done */
08061                if (req->headers != -1) {
08062                   break;
08063                } else {
08064                   req->headers = i;
08065                   dst = req->line;
08066                   i = 0;
08067                   lim = SIP_MAX_LINES - 1;
08068                   skipping_headers = 1;
08069                }
08070             }
08071          }
08072          dst[i] = current_header_offset; /* record start of next line */
08073       }
08074    }
08075 
08076    /* Check for last header or body line without CRLF. The RFC for SDP requires CRLF,
08077       but since some devices send without, we'll be generous in what we accept. However,
08078       if we've already reached the maximum number of lines for portion of the message
08079       we were parsing, we can't accept any more, so just ignore it.
08080    */
08081    previous_header = req->data->str + dst[i];
08082    if ((i < lim) && !ast_strlen_zero(previous_header)) {
08083       if (sipdebug) {
08084          ast_debug(4, "%7s %2d [%3d]: %s\n",
08085               req->headers < 0 ? "Header" : "Body",
08086               i, (int) strlen(previous_header), previous_header );
08087       }
08088       i++;
08089    }
08090 
08091    /* update count of header or body lines */
08092    if (req->headers >= 0) {   /* we are in the body */
08093       req->lines = i;
08094    } else {       /* no body */
08095       req->headers = i;
08096       req->lines = 0;
08097       /* req->data->used will be a NULL byte */
08098       req->line[0] = ast_str_strlen(req->data);
08099    }
08100 
08101    if (*c) {
08102       ast_log(LOG_WARNING, "Too many lines, skipping <%s>\n", c);
08103    }
08104 
08105    /* Split up the first line parts */
08106    return determine_firstline_parts(req);
08107 }

int parse_session_expires ( const char *  p_hdrval,
int *const   p_interval,
enum st_refresher *const   p_ref 
) [static]

Session-Timers: Function for parsing Session-Expires header.

Definition at line 24916 of file chan_sip.c.

References ast_debug, ast_log(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, and strsep().

Referenced by handle_request_invite(), and handle_response_invite().

24917 {
24918    char *p_token;
24919    int  ref_idx;
24920    char *p_se_hdr;
24921 
24922    if (ast_strlen_zero(p_hdrval)) {
24923       ast_log(LOG_WARNING, "Null Session-Expires header\n");
24924       return -1;
24925    }
24926 
24927    *p_ref = SESSION_TIMER_REFRESHER_AUTO;
24928    *p_interval = 0;
24929 
24930    p_se_hdr = ast_strdupa(p_hdrval);
24931    p_se_hdr = ast_skip_blanks(p_se_hdr);
24932 
24933    while ((p_token = strsep(&p_se_hdr, ";"))) {
24934       p_token = ast_skip_blanks(p_token);
24935       if (!sscanf(p_token, "%30d", p_interval)) {
24936          ast_log(LOG_WARNING, "Parsing of Session-Expires failed\n");
24937          return -1;
24938       }
24939 
24940       ast_debug(2, "Session-Expires: %d\n", *p_interval);
24941 
24942       if (!p_se_hdr)
24943          continue;
24944 
24945       p_se_hdr = ast_skip_blanks(p_se_hdr);
24946       ref_idx = strlen("refresher=");
24947       if (!strncasecmp(p_se_hdr, "refresher=", ref_idx)) {
24948          p_se_hdr += ref_idx;
24949          p_se_hdr = ast_skip_blanks(p_se_hdr);
24950 
24951          if (!strncasecmp(p_se_hdr, "uac", strlen("uac"))) {
24952             *p_ref = SESSION_TIMER_REFRESHER_UAC;
24953             ast_debug(2, "Refresher: UAC\n");
24954          } else if (!strncasecmp(p_se_hdr, "uas", strlen("uas"))) {
24955             *p_ref = SESSION_TIMER_REFRESHER_UAS;
24956             ast_debug(2, "Refresher: UAS\n");
24957          } else {
24958             ast_log(LOG_WARNING, "Invalid refresher value %s\n", p_se_hdr);
24959             return -1;
24960          }
24961          break;
24962       }
24963    }
24964    return 0;
24965 }

static int peer_cmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Note:
The only member of the peer used here is the name field

Definition at line 28471 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

28472 {
28473    struct sip_peer *peer = obj, *peer2 = arg;
28474 
28475    return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
28476 }

static int peer_dump_func ( void *  userobj,
void *  arg,
int  flags 
) [static]

Definition at line 16050 of file chan_sip.c.

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

Referenced by sip_show_objects().

16051 {
16052    struct sip_peer *peer = userobj;
16053    int refc = ao2_t_ref(userobj, 0, "");
16054    struct ast_cli_args *a = (struct ast_cli_args *) arg;
16055    
16056    ast_cli(a->fd, "name: %s\ntype: peer\nobjflags: %d\nrefcount: %d\n\n",
16057       peer->name, 0, refc);
16058    return 0;
16059 }

static int peer_hash_cb ( const void *  obj,
const int  flags 
) [static]

Note:
The only member of the peer used here is the name field

Definition at line 28461 of file chan_sip.c.

References ast_str_case_hash().

28462 {
28463    const struct sip_peer *peer = obj;
28464 
28465    return ast_str_case_hash(peer->name);
28466 }

static int peer_ipcmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Match Peers by IP and Port number.

This function has two modes.

This callback will be used twice when doing peer matching. There is a first pass for full IP+port matching, and a second pass in case there is a match that meets the insecure=port criteria.

Note:
Connections coming in over TCP or TLS should never be matched by port.

the peer's addr struct provides to fields combined to make a key: the sin_addr.s_addr and sin_port fields.

Definition at line 28519 of file chan_sip.c.

References ast_sockaddr_cmp_addr(), ast_sockaddr_port, ast_test_flag, CMP_MATCH, and CMP_STOP.

Referenced by load_module().

28520 {
28521    struct sip_peer *peer = obj, *peer2 = arg;
28522 
28523    if (ast_sockaddr_cmp_addr(&peer->addr, &peer2->addr)) {
28524       /* IP doesn't match */
28525       return 0;
28526    }
28527 
28528    /* We matched the IP, check to see if we need to match by port as well. */
28529    if ((peer->transports & peer2->transports) & (SIP_TRANSPORT_TLS | SIP_TRANSPORT_TCP)) {
28530       /* peer matching on port is not possible with TCP/TLS */
28531       return CMP_MATCH | CMP_STOP;
28532    } else if (ast_test_flag(&peer2->flags[0], SIP_INSECURE_PORT)) {
28533       /* We are allowing match without port for peers configured that
28534        * way in this pass through the peers. */
28535       return ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT) ?
28536             (CMP_MATCH | CMP_STOP) : 0;
28537    }
28538 
28539    /* Now only return a match if the port matches, as well. */
28540    return ast_sockaddr_port(&peer->addr) == ast_sockaddr_port(&peer2->addr) ?
28541          (CMP_MATCH | CMP_STOP) : 0;
28542 }

static int peer_iphash_cb ( const void *  obj,
const int  flags 
) [static]

Hash function based on the the peer's ip address. For IPv6, we use the end of the address.

Todo:
Find a better hashing function

Definition at line 28483 of file chan_sip.c.

References ast_log(), ast_sockaddr_hash(), ast_sockaddr_isnull(), and LOG_ERROR.

Referenced by load_module().

28484 {
28485    const struct sip_peer *peer = obj;
28486    int ret = 0;
28487 
28488    if (ast_sockaddr_isnull(&peer->addr)) {
28489       ast_log(LOG_ERROR, "Empty address\n");
28490    }
28491 
28492    ret = ast_sockaddr_hash(&peer->addr);
28493 
28494    if (ret < 0) {
28495       ret = -ret;
28496    }
28497 
28498    return ret;
28499 }

static int peer_is_marked ( void *  peerobj,
void *  arg,
int  flags 
) [static]

Definition at line 2792 of file chan_sip.c.

References AST_SCHED_DEL, and CMP_MATCH.

Referenced by unlink_marked_peers_from_tables().

02793 {
02794    struct sip_peer *peer = peerobj;
02795    if (peer->the_mark && peer->pokeexpire != -1) {
02796       AST_SCHED_DEL(sched, peer->pokeexpire);
02797    }
02798    return peer->the_mark ? CMP_MATCH : 0;
02799 }

static void peer_mailboxes_to_str ( struct ast_str **  mailbox_str,
struct sip_peer *  peer 
) [static]

list peer mailboxes to CLI

Definition at line 16533 of file chan_sip.c.

References AST_LIST_NEXT, AST_LIST_TRAVERSE, ast_str_append(), ast_strlen_zero(), mailbox, and S_OR.

Referenced by _sip_show_peer(), function_sippeer(), show_channels_cb(), and sip_send_mwi_to_peer().

16534 {
16535    struct sip_mailbox *mailbox;
16536 
16537    AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
16538       ast_str_append(mailbox_str, 0, "%s%s%s%s",
16539          mailbox->mailbox,
16540          ast_strlen_zero(mailbox->context) ? "" : "@",
16541          S_OR(mailbox->context, ""),
16542          AST_LIST_NEXT(mailbox, entry) ? "," : "");
16543    }
16544 }

static int peer_markall_func ( void *  device,
void *  arg,
int  flags 
) [static]

Definition at line 26685 of file chan_sip.c.

26686 {
26687    struct sip_peer *peer = device;
26688    peer->the_mark = 1;
26689    return 0;
26690 }

static int peer_status ( struct sip_peer *  peer,
char *  status,
int  statuslen 
) [static]

Definition at line 15640 of file chan_sip.c.

References ast_copy_string().

15641 {
15642    int res = 0;
15643    if (peer->maxms) {
15644       if (peer->lastms < 0) {
15645          ast_copy_string(status, "UNREACHABLE", statuslen);
15646       } else if (peer->lastms > peer->maxms) {
15647          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
15648          res = 1;
15649       } else if (peer->lastms) {
15650          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
15651          res = 1;
15652       } else {
15653          ast_copy_string(status, "UNKNOWN", statuslen);
15654       }
15655    } else {
15656       ast_copy_string(status, "Unmonitored", statuslen);
15657       /* Checking if port is 0 */
15658       res = -1;
15659    }
15660    return res;
15661 }

int peercomparefunc ( const void *  a,
const void *  b 
)

Definition at line 15868 of file chan_sip.c.

Referenced by _sip_show_peers().

15869 {
15870    struct sip_peer **ap = (struct sip_peer **)a;
15871    struct sip_peer **bp = (struct sip_peer **)b;
15872    return strcmp((*ap)->name, (*bp)->name);
15873 }

static int peers_data_provider_get ( const struct ast_data_search *  search,
struct ast_data *  data_root 
) [static]

Definition at line 28900 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ARRAY_LEN, ast_cdr_flags2str(), ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_describe_caller_presentation(), AST_LIST_TRAVERSE, get_transport_list(), mailbox, and transfermode2str().

28902 {
28903    struct sip_peer *peer;
28904    struct ao2_iterator i;
28905    struct ast_data *data_peer, *data_peer_mailboxes = NULL, *data_peer_mailbox, *enum_node;
28906    struct ast_data *data_sip_options;
28907    int total_mailboxes, x;
28908    struct sip_mailbox *mailbox;
28909 
28910    i = ao2_iterator_init(peers, 0);
28911    while ((peer = ao2_iterator_next(&i))) {
28912       ao2_lock(peer);
28913 
28914       data_peer = ast_data_add_node(data_root, "peer");
28915       if (!data_peer) {
28916          ao2_unlock(peer);
28917          ao2_ref(peer, -1);
28918          continue;
28919       }
28920 
28921       ast_data_add_structure(sip_peer, data_peer, peer);
28922 
28923       /* transfer mode */
28924       enum_node = ast_data_add_node(data_peer, "allowtransfer");
28925       if (!enum_node) {
28926          continue;
28927       }
28928       ast_data_add_str(enum_node, "text", transfermode2str(peer->allowtransfer));
28929       ast_data_add_int(enum_node, "value", peer->allowtransfer);
28930 
28931       /* transports */
28932       ast_data_add_str(data_peer, "transports", get_transport_list(peer->transports));
28933 
28934       /* peer type */
28935       if ((peer->type & SIP_TYPE_USER) && (peer->type & SIP_TYPE_PEER)) {
28936          ast_data_add_str(data_peer, "type", "friend");
28937       } else if (peer->type & SIP_TYPE_PEER) {
28938          ast_data_add_str(data_peer, "type", "peer");
28939       } else if (peer->type & SIP_TYPE_USER) {
28940          ast_data_add_str(data_peer, "type", "user");
28941       }
28942 
28943       /* mailboxes */
28944       total_mailboxes = 0;
28945       AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
28946          if (!total_mailboxes) {
28947             data_peer_mailboxes = ast_data_add_node(data_peer, "mailboxes");
28948             if (!data_peer_mailboxes) {
28949                break;
28950             }
28951             total_mailboxes++;
28952          }
28953 
28954          data_peer_mailbox = ast_data_add_node(data_peer_mailboxes, "mailbox");
28955          if (!data_peer_mailbox) {
28956             continue;
28957          }
28958          ast_data_add_str(data_peer_mailbox, "mailbox", mailbox->mailbox);
28959          ast_data_add_str(data_peer_mailbox, "context", mailbox->context);
28960       }
28961 
28962       /* amaflags */
28963       enum_node = ast_data_add_node(data_peer, "amaflags");
28964       if (!enum_node) {
28965          continue;
28966       }
28967       ast_data_add_int(enum_node, "value", peer->amaflags);
28968       ast_data_add_str(enum_node, "text", ast_cdr_flags2str(peer->amaflags));
28969 
28970       /* sip options */
28971       data_sip_options = ast_data_add_node(data_peer, "sipoptions");
28972       if (!data_sip_options) {
28973          continue;
28974       }
28975       for (x = 0 ; x < ARRAY_LEN(sip_options); x++) {
28976          ast_data_add_bool(data_sip_options, sip_options[x].text, peer->sipoptions & sip_options[x].id);
28977       }
28978 
28979       /* callingpres */
28980       enum_node = ast_data_add_node(data_peer, "callingpres");
28981       if (!enum_node) {
28982          continue;
28983       }
28984       ast_data_add_int(enum_node, "value", peer->callingpres);
28985       ast_data_add_str(enum_node, "text", ast_describe_caller_presentation(peer->callingpres));
28986 
28987       /* codecs */
28988       ast_data_add_codecs(data_peer, "codecs", peer->capability);
28989 
28990       if (!ast_data_search_match(search, data_peer)) {
28991          ast_data_remove_node(data_root, data_peer);
28992       }
28993 
28994       ao2_unlock(peer);
28995       ao2_ref(peer, -1);
28996    }
28997    ao2_iterator_destroy(&i);
28998 
28999    return 0;
29000 }

static int pidf_validate_presence ( struct ast_xml_doc *  doc  )  [static]

Definition at line 22894 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), ast_xml_find_namespace(), ast_xml_free_attr(), ast_xml_get_attribute(), ast_xml_get_ns_href(), ast_xml_get_root(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), entity, FALSE, LOG_WARNING, pidf_validate_tuple(), and TRUE.

Referenced by sip_pidf_validate().

22895 {
22896    struct ast_xml_node *presence_node = ast_xml_get_root(doc);
22897    struct ast_xml_node *child_nodes;
22898    struct ast_xml_node *node_iterator;
22899    struct ast_xml_ns *ns;
22900    const char *entity;
22901    const char *namespace;
22902    const char presence_namespace[] = "urn:ietf:params:xml:ns:pidf";
22903 
22904    if (!presence_node) {
22905       ast_log(LOG_WARNING, "Unable to retrieve root node of the XML document\n");
22906       return FALSE;
22907    }
22908    /* Okay, we managed to open the document! YAY! Now, let's start making sure it's all PIDF-ified
22909     * correctly.
22910     */
22911    if (strcmp(ast_xml_node_get_name(presence_node), "presence")) {
22912       ast_log(LOG_WARNING, "Root node of PIDF document is not 'presence'. Invalid\n");
22913       return FALSE;
22914    }
22915 
22916    /* The presence element must have an entity attribute and an xmlns attribute. Furthermore
22917     * the xmlns attribute must be "urn:ietf:params:xml:ns:pidf"
22918     */
22919    if (!(entity = ast_xml_get_attribute(presence_node, "entity"))) {
22920       ast_log(LOG_WARNING, "Presence element of PIDF document has no 'entity' attribute\n");
22921       return FALSE;
22922    }
22923    /* We're not interested in what the entity is, just that it exists */
22924    ast_xml_free_attr(entity);
22925 
22926    if (!(ns = ast_xml_find_namespace(doc, presence_node, NULL))) {
22927       ast_log(LOG_WARNING, "Couldn't find default namespace...\n");
22928       return FALSE;
22929    }
22930 
22931    namespace = ast_xml_get_ns_href(ns);
22932    if (ast_strlen_zero(namespace) || strcmp(namespace, presence_namespace)) {
22933       ast_log(LOG_WARNING, "PIDF document has invalid namespace value %s\n", namespace);
22934       return FALSE;
22935    }
22936 
22937    if (!(child_nodes = ast_xml_node_get_children(presence_node))) {
22938       ast_log(LOG_WARNING, "PIDF document has no elements as children of 'presence'. Invalid\n");
22939       return FALSE;
22940    }
22941 
22942    /* Check for tuple elements. RFC 3863 says that PIDF documents can have any number of
22943     * tuples, including 0. The big thing here is that if there are tuple elements present,
22944     * they have to have a single status element within.
22945     *
22946     * The RFC is worded such that tuples should appear as the first elements as children of
22947     * the presence element. However, we'll be accepting of documents which may place other elements
22948     * before the tuple(s).
22949     */
22950    for (node_iterator = child_nodes; node_iterator;
22951          node_iterator = ast_xml_node_get_next(node_iterator)) {
22952       if (strcmp(ast_xml_node_get_name(node_iterator), "tuple")) {
22953          /* Not a tuple. We don't give a rat's hind quarters */
22954          continue;
22955       }
22956       if (pidf_validate_tuple(node_iterator) == FALSE) {
22957          ast_log(LOG_WARNING, "Unable to validate tuple\n");
22958          return FALSE;
22959       }
22960    }
22961 
22962    return TRUE;
22963 }

static int pidf_validate_tuple ( struct ast_xml_node *  tuple_node  )  [static]

Definition at line 22854 of file chan_sip.c.

References ast_log(), ast_xml_free_attr(), ast_xml_get_attribute(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), FALSE, id, LOG_WARNING, and TRUE.

Referenced by pidf_validate_presence().

22855 {
22856    const char *id;
22857    int status_found = FALSE;
22858    struct ast_xml_node *tuple_children;
22859    struct ast_xml_node *tuple_children_iterator;
22860    /* Tuples have to have an id attribute or they're invalid */
22861    if (!(id = ast_xml_get_attribute(tuple_node, "id"))) {
22862       ast_log(LOG_WARNING, "Tuple XML element has no attribute 'id'\n");
22863       return FALSE;
22864    }
22865    /* We don't care what it actually is, just that it's there */
22866    ast_xml_free_attr(id);
22867    /* This is a tuple. It must have a status element */
22868    if (!(tuple_children = ast_xml_node_get_children(tuple_node))) {
22869       /* The tuple has no children. It sucks */
22870       ast_log(LOG_WARNING, "Tuple XML element has no child elements\n");
22871       return FALSE;
22872    }
22873    for (tuple_children_iterator = tuple_children; tuple_children_iterator;
22874          tuple_children_iterator = ast_xml_node_get_next(tuple_children_iterator)) {
22875       /* Similar to the wording used regarding tuples, the status element should appear
22876        * first. However, we will once again relax things and accept the status at any
22877        * position. We will enforce that only a single status element can be present.
22878        */
22879       if (strcmp(ast_xml_node_get_name(tuple_children_iterator), "status")) {
22880          /* Not the status, we don't care */
22881          continue;
22882       }
22883       if (status_found == TRUE) {
22884          /* THERE CAN BE ONLY ONE!!! */
22885          ast_log(LOG_WARNING, "Multiple status elements found in tuple. Only one allowed\n");
22886          return FALSE;
22887       }
22888       status_found = TRUE;
22889    }
22890    return status_found;
22891 }

unsigned int port_str2int ( const char *  pt,
unsigned int  standard 
)

converts ascii port to int representation. If no pt buffer is provided or the pt has errors when being converted to an int value, the port provided as the standard is used.

Definition at line 3031 of file chan_sip.c.

References ast_strlen_zero().

Referenced by build_peer().

03032 {
03033    int port = standard;
03034    if (ast_strlen_zero(pt) || (sscanf(pt, "%30d", &port) != 1) || (port < 1) || (port > 65535)) {
03035       port = standard;
03036    }
03037 
03038    return port;
03039 }

static void print_codec_to_cli ( int  fd,
struct ast_codec_pref *  pref 
) [static]

Print codec list from preference to CLI/manager.

Definition at line 16370 of file chan_sip.c.

References ast_cli(), ast_codec_pref_index(), ast_getformatname(), and ast_codec_pref::framing.

Referenced by _sip_show_peer(), _skinny_show_line(), sip_show_settings(), and sip_show_user().

16371 {
16372    int x;
16373    format_t codec;
16374 
16375    for(x = 0; x < 64 ; x++) {
16376       codec = ast_codec_pref_index(pref, x);
16377       if (!codec)
16378          break;
16379       ast_cli(fd, "%s", ast_getformatname(codec));
16380       ast_cli(fd, ":%d", pref->framing[x]);
16381       if (x < 31 && ast_codec_pref_index(pref, x + 1))
16382          ast_cli(fd, ",");
16383    }
16384    if (!x)
16385       ast_cli(fd, "none");
16386 }

static void print_group ( int  fd,
ast_group_t  group,
int  crlf 
) [static]

Print call group and pickup group.

Definition at line 16100 of file chan_sip.c.

References ast_cli(), and ast_print_group().

Referenced by _sip_show_peer(), and sip_show_user().

16101 {
16102    char buf[256];
16103    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
16104 }

static void proc_422_rsp ( struct sip_pvt *  p,
struct sip_request *  rsp 
) [static]

Handle 422 response to INVITE with session-timer requested.

Session-Timers: An INVITE originated by Asterisk that asks for session-timers support from the UAS can result into a 422 response. This is how a UAS or an intermediary proxy server tells Asterisk that the session refresh interval offered by Asterisk is too low for them. The proc_422_rsp() function handles a 422 response. It extracts the Min-SE header that comes back in 422 and sends a new INVITE accordingly.

Definition at line 24975 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), get_header(), LOG_WARNING, parse_minse(), and transmit_invite().

Referenced by handle_response_invite().

24976 {
24977    int rtn;
24978    const char *p_hdrval;
24979    int minse;
24980 
24981    p_hdrval = get_header(rsp, "Min-SE");
24982    if (ast_strlen_zero(p_hdrval)) {
24983       ast_log(LOG_WARNING, "422 response without a Min-SE header %s\n", p_hdrval);
24984       return;
24985    }
24986    rtn = parse_minse(p_hdrval, &minse);
24987    if (rtn != 0) {
24988       ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval);
24989       return;
24990    }
24991    p->stimer->st_interval = minse;
24992    transmit_invite(p, SIP_INVITE, 1, 2, NULL);
24993 }

static int proc_session_timer ( const void *  vp  )  [static]

Session-Timers: Process session refresh timeout event.

Definition at line 24815 of file chan_sip.c.

References ast_channel_trylock, ast_channel_unlock, ast_debug, ast_log(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, FALSE, LOG_ERROR, LOG_WARNING, sip_pvt_lock, sip_pvt_unlock, stop_session_timer(), transmit_reinvite_with_sdp(), and TRUE.

Referenced by start_session_timer().

24816 {
24817    struct sip_pvt *p = (struct sip_pvt *) vp;
24818    int sendreinv = FALSE;
24819    int res = 0;
24820 
24821    if (!p->stimer) {
24822       ast_log(LOG_WARNING, "Null stimer in proc_session_timer - %s\n", p->callid);
24823       goto return_unref;
24824    }
24825 
24826    ast_debug(2, "Session timer expired: %d - %s\n", p->stimer->st_schedid, p->callid);
24827 
24828    if (!p->owner) {
24829       goto return_unref;
24830    }
24831 
24832    if ((p->stimer->st_active != TRUE) || (p->owner->_state != AST_STATE_UP)) {
24833       goto return_unref;
24834    }
24835 
24836    switch (p->stimer->st_ref) {
24837    case SESSION_TIMER_REFRESHER_UAC:
24838       if (p->outgoing_call == TRUE) {
24839          sendreinv = TRUE;
24840       }
24841       break;
24842    case SESSION_TIMER_REFRESHER_UAS:
24843       if (p->outgoing_call != TRUE) {
24844          sendreinv = TRUE;
24845       }
24846       break;
24847    default:
24848       ast_log(LOG_ERROR, "Unknown session refresher %d\n", p->stimer->st_ref);
24849       goto return_unref;
24850    }
24851 
24852    if (sendreinv == TRUE) {
24853       res = 1;
24854       transmit_reinvite_with_sdp(p, FALSE, TRUE);
24855    } else {
24856       p->stimer->st_expirys++;
24857       if (p->stimer->st_expirys >= 2) {
24858          if (p->stimer->quit_flag) {
24859             goto return_unref;
24860          }
24861          ast_log(LOG_WARNING, "Session-Timer expired - %s\n", p->callid);
24862          sip_pvt_lock(p);
24863          while (p->owner && ast_channel_trylock(p->owner)) {
24864             sip_pvt_unlock(p);
24865             usleep(1);
24866             if (p->stimer && p->stimer->quit_flag) {
24867                goto return_unref;
24868             }
24869             sip_pvt_lock(p);
24870          }
24871 
24872          ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
24873          ast_channel_unlock(p->owner);
24874          sip_pvt_unlock(p);
24875       }
24876    }
24877 
24878 return_unref:
24879    if (!res) {
24880       /* An error occurred.  Stop session timer processing */
24881       if (p->stimer) {
24882          p->stimer->st_schedid = -1;
24883          stop_session_timer(p);
24884       }
24885 
24886       /* If we are not asking to be rescheduled, then we need to release our
24887        * reference to the dialog. */
24888       dialog_unref(p, "removing session timer ref");
24889    }
24890 
24891    return res;
24892 }

static int process_crypto ( struct sip_pvt *  p,
struct ast_rtp_instance *  rtp,
struct sip_srtp **  srtp,
const char *  a 
) [static]

Definition at line 28322 of file chan_sip.c.

References ast_debug, ast_log(), ast_set_flag, ast_test_flag, FALSE, LOG_WARNING, setup_srtp(), and TRUE.

Referenced by process_sdp().

28323 {
28324    if (strncasecmp(a, "crypto:", 7)) {
28325       return FALSE;
28326    }
28327    if (!*srtp) {
28328       if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
28329          ast_log(LOG_WARNING, "Ignoring unexpected crypto attribute in SDP answer\n");
28330          return FALSE;
28331       }
28332 
28333       if (setup_srtp(srtp) < 0) {
28334          return FALSE;
28335       }
28336    }
28337 
28338    /* For now, when we receive an INVITE just take the first successful crypto line */
28339    if ((*srtp)->crypto && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
28340       ast_debug(3, "We've already processed a crypto attribute, skipping '%s'\n", a);
28341       return FALSE;
28342    }
28343 
28344    if (!(*srtp)->crypto && !((*srtp)->crypto = sdp_crypto_setup())) {
28345       return FALSE;
28346    }
28347 
28348    if (sdp_crypto_process((*srtp)->crypto, a, rtp) < 0) {
28349       return FALSE;
28350    }
28351 
28352    ast_set_flag(*srtp, SRTP_CRYPTO_OFFER_OK);
28353 
28354    return TRUE;
28355 }

static void process_request_queue ( struct sip_pvt *  p,
int *  recount,
int *  nounlock 
) [static]

Definition at line 24069 of file chan_sip.c.

References ast_debug, ast_free, AST_LIST_REMOVE_HEAD, and handle_incoming().

Referenced by handle_request_do().

24070 {
24071    struct sip_request *req;
24072 
24073    while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) {
24074       if (handle_incoming(p, req, &p->recv, recount, nounlock) == -1) {
24075          /* Request failed */
24076          ast_debug(1, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
24077       }
24078       ast_free(req);
24079    }
24080 }

static int process_sdp ( struct sip_pvt *  p,
struct sip_request *  req,
int  t38action 
) [static]

Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp().

< RTP Audio host IP

< RTP video host IP

< RTP text host IP

< UDPTL host ip

< RTP Audio port number

< RTP Video port number

< RTP Text port number

< UDPTL Image port number

Definition at line 8301 of file chan_sip.c.

References ast_async_goto(), ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_codec_choose(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_exists_extension(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_T140RED, ast_getformatname_multiple(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_codecs_payload_formats(), ast_rtp_codecs_payloads_clear(), ast_rtp_codecs_payloads_copy(), ast_rtp_codecs_payloads_set_m_type(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_instance_get_remote_address(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_remote_address(), ast_rtp_instance_stop(), ast_rtp_lookup_mime_multiple2(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_rtp_red_init(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_skip_blanks(), ast_sockaddr_isnull(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_str_alloca, ast_strlen_zero(), ast_test_flag, ast_udptl_get_far_max_datagram(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_peer(), ast_udptl_stop(), ast_verbose, change_hold_state(), change_t38_state(), debug, FALSE, get_sdp_iterate(), get_sdp_line(), len(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar_helper(), process_crypto(), process_sdp_a_audio(), process_sdp_a_image(), process_sdp_a_sendonly(), process_sdp_a_text(), process_sdp_a_video(), process_sdp_c(), process_sdp_o(), S_COR, S_OR, sip_debug_test_pvt(), text, TRUE, type, UDPTL_ERROR_CORRECTION_NONE, value, and VERBOSE_PREFIX_2.

08302 {
08303    /* Iterators for SDP parsing */
08304    int start = req->sdp_start;
08305    int next = start;
08306    int iterator = start;
08307 
08308    /* Temporary vars for SDP parsing */
08309    char type = '\0';
08310    const char *value = NULL;
08311    const char *m = NULL;           /* SDP media offer */
08312    const char *nextm = NULL;
08313    int len = -1;
08314 
08315    /* Host information */
08316    struct ast_sockaddr sessionsa;
08317    struct ast_sockaddr audiosa;
08318    struct ast_sockaddr videosa;
08319    struct ast_sockaddr textsa;
08320    struct ast_sockaddr imagesa;
08321    struct ast_sockaddr *sa = NULL;  /*!< RTP Audio host IP */
08322    struct ast_sockaddr *vsa = NULL; /*!< RTP video host IP */
08323    struct ast_sockaddr *tsa = NULL; /*!< RTP text host IP */
08324    struct ast_sockaddr *isa = NULL;     /*!< UDPTL host ip */
08325    int portno = -1;     /*!< RTP Audio port number */
08326    int vportno = -1;    /*!< RTP Video port number */
08327    int tportno = -1;    /*!< RTP Text port number */
08328    int udptlportno = -1;      /*!< UDPTL Image port number */
08329 
08330    /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 
08331    format_t peercapability = 0, vpeercapability = 0, tpeercapability = 0;
08332    int peernoncodeccapability = 0, vpeernoncodeccapability = 0, tpeernoncodeccapability = 0;
08333 
08334    struct ast_rtp_codecs newaudiortp, newvideortp, newtextrtp;
08335    format_t newjointcapability;           /* Negotiated capability */
08336    format_t newpeercapability;
08337    int newnoncodeccapability;
08338 
08339    const char *codecs;
08340    int codec;
08341 
08342    /* SRTP */
08343    int secure_audio = FALSE;
08344    int secure_video = FALSE;
08345 
08346    /* Others */
08347    int sendonly = -1;
08348    int vsendonly = -1;
08349    int numberofports;
08350    int numberofmediastreams = 0;
08351    int last_rtpmap_codec = 0;
08352    int red_data_pt[10];    /* For T.140 red */
08353    int red_num_gen = 0;    /* For T.140 red */
08354    char red_fmtp[100] = "empty"; /* For T.140 red */
08355    int debug = sip_debug_test_pvt(p);
08356 
08357    /* START UNKNOWN */
08358    char buf[SIPBUFSIZE];
08359    /* END UNKNOWN */
08360 
08361    /* Initial check */
08362    if (!p->rtp) {
08363       ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n");
08364       return -1;
08365    }
08366 
08367    /* Make sure that the codec structures are all cleared out */
08368    ast_rtp_codecs_payloads_clear(&newaudiortp, NULL);
08369    ast_rtp_codecs_payloads_clear(&newvideortp, NULL);
08370    ast_rtp_codecs_payloads_clear(&newtextrtp, NULL);
08371 
08372    /* Update our last rtprx when we receive an SDP, too */
08373    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
08374 
08375    memset(p->offered_media, 0, sizeof(p->offered_media));
08376 
08377 
08378    /* default: novideo and notext set */
08379    p->novideo = TRUE;
08380    p->notext = TRUE;
08381 
08382    if (p->vrtp) {
08383       ast_rtp_codecs_payloads_clear(&newvideortp, NULL);
08384    }
08385 
08386    if (p->trtp) {
08387       ast_rtp_codecs_payloads_clear(&newtextrtp, NULL);
08388    }
08389 
08390    /* Scan for the first media stream (m=) line to limit scanning of globals */
08391    nextm = get_sdp_iterate(&next, req, "m");
08392    if (ast_strlen_zero(nextm)) {
08393       ast_log(LOG_WARNING, "Insufficient information for SDP (m= not found)\n");
08394       return -1;
08395    }
08396 
08397    /* Scan session level SDP parameters (lines before first media stream) */
08398    while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') {
08399       int processed = FALSE;
08400       switch (type) {
08401       case 'o':
08402          /* If we end up receiving SDP that doesn't actually modify the session we don't want to treat this as a fatal
08403           * error. We just want to ignore the SDP and let the rest of the packet be handled as normal.
08404           */
08405          if (!process_sdp_o(value, p))
08406             return (p->session_modify == FALSE) ? 0 : -1;
08407          break;
08408       case 'c':
08409          if (process_sdp_c(value, &sessionsa)) {
08410             processed = TRUE;
08411             sa = &sessionsa;
08412             vsa = sa;
08413             tsa = sa;
08414             isa = sa;
08415          }
08416          break;
08417       case 'a':
08418          if (process_sdp_a_sendonly(value, &sendonly)) {
08419             processed = TRUE;
08420             vsendonly = sendonly;
08421          }
08422          else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec))
08423             processed = TRUE;
08424          else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec))
08425             processed = TRUE;
08426          else if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec))
08427             processed = TRUE;
08428          else if (process_sdp_a_image(value, p))
08429             processed = TRUE;
08430          break;
08431       }
08432 
08433       ast_debug(3, "Processing session-level SDP %c=%s... %s\n", type, value, (processed == TRUE)? "OK." : "UNSUPPORTED.");
08434    }
08435 
08436 
08437 
08438    /* Scan media stream (m=) specific parameters loop */
08439    while (!ast_strlen_zero(nextm)) {
08440       int audio = FALSE;
08441       int video = FALSE;
08442       int image = FALSE;
08443       int text = FALSE;
08444       char protocol[5] = {0,};
08445       int x;
08446 
08447       numberofports = 1;
08448       len = -1;
08449       start = next;
08450       m = nextm;
08451       iterator = next;
08452       nextm = get_sdp_iterate(&next, req, "m");
08453 
08454       /* Search for audio media definition */
08455       if ((sscanf(m, "audio %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) ||
08456           (sscanf(m, "audio %30u RTP/%4s %n", &x, protocol, &len) == 2 && len > 0)) {
08457          if (!strcmp(protocol, "SAVP")) {
08458             secure_audio = 1;
08459          } else if (strcmp(protocol, "AVP")) {
08460             ast_log(LOG_WARNING, "unknown SDP media protocol in offer: %s\n", protocol);
08461             continue;
08462          }
08463          audio = TRUE;
08464          p->offered_media[SDP_AUDIO].offered = TRUE;
08465          numberofmediastreams++;
08466          portno = x;
08467 
08468          /* Scan through the RTP payload types specified in a "m=" line: */
08469          codecs = m + len;
08470          ast_copy_string(p->offered_media[SDP_AUDIO].codecs, codecs, sizeof(p->offered_media[SDP_AUDIO].codecs));
08471          for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
08472             if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
08473                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
08474                return -1;
08475             }
08476             if (debug)
08477                ast_verbose("Found RTP audio format %d\n", codec);
08478             
08479             ast_rtp_codecs_payloads_set_m_type(&newaudiortp, NULL, codec);
08480          }
08481       /* Search for video media definition */
08482       } else if ((sscanf(m, "video %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) ||
08483             (sscanf(m, "video %30u RTP/%4s %n", &x, protocol, &len) == 2 && len >= 0)) {
08484          if (!strcmp(protocol, "SAVP")) {
08485             secure_video = 1;
08486          } else if (strcmp(protocol, "AVP")) {
08487             ast_log(LOG_WARNING, "unknown SDP media protocol in offer: %s\n", protocol);
08488             continue;
08489          }
08490          video = TRUE;
08491          p->novideo = FALSE;
08492          p->offered_media[SDP_VIDEO].offered = TRUE;
08493          numberofmediastreams++;
08494          vportno = x;
08495 
08496          /* Scan through the RTP payload types specified in a "m=" line: */
08497          codecs = m + len;
08498          ast_copy_string(p->offered_media[SDP_VIDEO].codecs, codecs, sizeof(p->offered_media[SDP_VIDEO].codecs));
08499          for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
08500             if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
08501                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
08502                return -1;
08503             }
08504             if (debug)
08505                ast_verbose("Found RTP video format %d\n", codec);
08506             ast_rtp_codecs_payloads_set_m_type(&newvideortp, NULL, codec);
08507          }
08508       /* Search for text media definition */
08509       } else if ((sscanf(m, "text %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
08510             (sscanf(m, "text %30u RTP/AVP %n", &x, &len) == 1 && len > 0)) {
08511          text = TRUE;
08512          p->notext = FALSE;
08513          p->offered_media[SDP_TEXT].offered = TRUE;
08514          numberofmediastreams++;
08515          tportno = x;
08516 
08517          /* Scan through the RTP payload types specified in a "m=" line: */
08518          codecs = m + len;
08519          ast_copy_string(p->offered_media[SDP_TEXT].codecs, codecs, sizeof(p->offered_media[SDP_TEXT].codecs));
08520          for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
08521             if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
08522                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
08523                return -1;
08524             }
08525             if (debug)
08526                ast_verbose("Found RTP text format %d\n", codec);
08527             ast_rtp_codecs_payloads_set_m_type(&newtextrtp, NULL, codec);
08528          }
08529       /* Search for image media definition */
08530       } else if (p->udptl && ((sscanf(m, "image %30u udptl t38%n", &x, &len) == 1 && len > 0) ||
08531                (sscanf(m, "image %30u UDPTL t38%n", &x, &len) == 1 && len > 0) )) {
08532          image = TRUE;
08533          if (debug)
08534             ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid);
08535          p->offered_media[SDP_IMAGE].offered = TRUE;
08536          udptlportno = x;
08537          numberofmediastreams++;
08538 
08539          if (p->t38.state != T38_ENABLED) {
08540             memset(&p->t38.their_parms, 0, sizeof(p->t38.their_parms));
08541 
08542             /* default EC to none, the remote end should
08543              * respond with the EC they want to use */
08544             ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE);
08545          }
08546       } else {
08547          ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m);
08548          continue;
08549       }
08550 
08551       /* Check for number of ports */
08552       if (numberofports > 1)
08553          ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports);
08554       
08555       /* Media stream specific parameters */
08556       while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') {
08557          int processed = FALSE;
08558 
08559          switch (type) {
08560          case 'c':
08561             if (audio) {
08562                if (process_sdp_c(value, &audiosa)) {
08563                   processed = TRUE;
08564                   sa = &audiosa;
08565                }
08566             } else if (video) {
08567                if (process_sdp_c(value, &videosa)) {
08568                   processed = TRUE;
08569                   vsa = &videosa;
08570                }
08571             } else if (text) {
08572                if (process_sdp_c(value, &textsa)) {
08573                   processed = TRUE;
08574                   tsa = &textsa;
08575                }
08576             } else if (image) {
08577                if (process_sdp_c(value, &imagesa)) {
08578                   processed = TRUE;
08579                   isa = &imagesa;
08580                }
08581             }
08582             break;
08583          case 'a':
08584             /* Audio specific scanning */
08585             if (audio) {
08586                if (process_sdp_a_sendonly(value, &sendonly))
08587                   processed = TRUE;
08588                else if (process_crypto(p, p->rtp, &p->srtp, value))
08589                   processed = TRUE;
08590                else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec))
08591                   processed = TRUE;
08592             }
08593             /* Video specific scanning */
08594             else if (video) {
08595                if (process_sdp_a_sendonly(value, &vsendonly))
08596                   processed = TRUE;
08597                else if (process_crypto(p, p->vrtp, &p->vsrtp, value))
08598                   processed = TRUE;
08599                else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec))
08600                   processed = TRUE;
08601             }
08602             /* Text (T.140) specific scanning */
08603             else if (text) {
08604                if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec))
08605                   processed = TRUE;
08606                else if (process_crypto(p, p->trtp, &p->tsrtp, value))
08607                   processed = TRUE;
08608             }
08609             /* Image (T.38 FAX) specific scanning */
08610             else if (image) {
08611                if (process_sdp_a_image(value, p))
08612                   processed = TRUE;
08613             }
08614             break;
08615          }
08616 
08617          ast_debug(3, "Processing media-level (%s) SDP %c=%s... %s\n",
08618                (audio == TRUE)? "audio" : (video == TRUE)? "video" : "image",
08619                type, value,
08620                (processed == TRUE)? "OK." : "UNSUPPORTED.");
08621       }
08622    }
08623 
08624 
08625    /* Sanity checks */
08626    if (!sa && !vsa && !tsa && !isa) {
08627       ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n");
08628       return -1;
08629    }
08630 
08631    if (portno == -1 && vportno == -1 && udptlportno == -1  && tportno == -1) {
08632       /* No acceptable offer found in SDP  - we have no ports */
08633       /* Do not change RTP or VRTP if this is a re-invite */
08634       ast_log(LOG_WARNING, "Failing due to no acceptable offer found\n");
08635       return -2;
08636    }
08637 
08638    if (numberofmediastreams > 3) {
08639       /* We have too many fax, audio and/or video and/or text media streams, fail this offer */
08640       ast_log(LOG_WARNING, "Faling due to too many media streams\n");
08641       return -3;
08642    }
08643 
08644    if (secure_audio && !(p->srtp && (ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)))) {
08645       ast_log(LOG_WARNING, "Can't provide secure audio requested in SDP offer\n");
08646       return -4;
08647    }
08648 
08649    if (!secure_audio && p->srtp) {
08650       ast_log(LOG_WARNING, "We are requesting SRTP, but they responded without it!\n");
08651       return -4;
08652    }
08653 
08654    if (secure_video && !(p->vsrtp && (ast_test_flag(p->vsrtp, SRTP_CRYPTO_OFFER_OK)))) {
08655       ast_log(LOG_WARNING, "Can't provide secure video requested in SDP offer\n");
08656       return -4;
08657    }
08658 
08659    if (!p->novideo && !secure_video && p->vsrtp) {
08660       ast_log(LOG_WARNING, "We are requesting SRTP, but they responded without it!\n");
08661       return -4;
08662    }
08663 
08664    if (!(secure_audio || secure_video) && ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) {
08665       ast_log(LOG_WARNING, "Matched device setup to use SRTP, but request was not!\n");
08666       return -4;
08667    }
08668 
08669    if (udptlportno == -1) {
08670       change_t38_state(p, T38_DISABLED);
08671    }
08672 
08673    /* Now gather all of the codecs that we are asked for: */
08674    ast_rtp_codecs_payload_formats(&newaudiortp, &peercapability, &peernoncodeccapability);
08675    ast_rtp_codecs_payload_formats(&newvideortp, &vpeercapability, &vpeernoncodeccapability);
08676    ast_rtp_codecs_payload_formats(&newtextrtp, &tpeercapability, &tpeernoncodeccapability);
08677 
08678    newjointcapability = p->capability & (peercapability | vpeercapability | tpeercapability);
08679    newpeercapability = (peercapability | vpeercapability | tpeercapability);
08680    newnoncodeccapability = p->noncodeccapability & peernoncodeccapability;
08681 
08682    if (debug) {
08683       /* shame on whoever coded this.... */
08684       char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE], s5[SIPBUFSIZE];
08685 
08686       ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s/text=%s, combined - %s\n",
08687              ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability),
08688              ast_getformatname_multiple(s2, SIPBUFSIZE, peercapability),
08689              ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability),
08690              ast_getformatname_multiple(s4, SIPBUFSIZE, tpeercapability),
08691              ast_getformatname_multiple(s5, SIPBUFSIZE, newjointcapability));
08692    }
08693    if (debug) {
08694       struct ast_str *s1 = ast_str_alloca(SIPBUFSIZE);
08695       struct ast_str *s2 = ast_str_alloca(SIPBUFSIZE);
08696       struct ast_str *s3 = ast_str_alloca(SIPBUFSIZE);
08697 
08698       ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n",
08699              ast_rtp_lookup_mime_multiple2(s1, p->noncodeccapability, 0, 0),
08700              ast_rtp_lookup_mime_multiple2(s2, peernoncodeccapability, 0, 0),
08701              ast_rtp_lookup_mime_multiple2(s3, newnoncodeccapability, 0, 0));
08702    }
08703    if (!newjointcapability && (portno != -1)) {
08704       ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n");
08705       /* Do NOT Change current setting */
08706       return -1;
08707    }
08708 
08709    /* Setup audio address and port */
08710    if (p->rtp) {
08711       if (portno > 0) {
08712          ast_sockaddr_set_port(sa, portno);
08713          ast_rtp_instance_set_remote_address(p->rtp, sa);
08714          if (debug) {
08715             ast_verbose("Peer audio RTP is at port %s\n",
08716                    ast_sockaddr_stringify(sa));
08717          }
08718          /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since
08719             they are acceptable */
08720          p->jointcapability = newjointcapability;                /* Our joint codec profile for this call */
08721          p->peercapability = newpeercapability;                  /* The other sides capability in latest offer */
08722          p->jointnoncodeccapability = newnoncodeccapability;     /* DTMF capabilities */
08723 
08724          if (ast_test_flag(&p->flags[1], SIP_PAGE2_PREFERRED_CODEC)) { /* respond with single most preferred joint codec, limiting the other side's choice */
08725             p->jointcapability = ast_codec_choose(&p->prefs, p->jointcapability, 1);
08726          }
08727 
08728          ast_rtp_codecs_payloads_copy(&newaudiortp, ast_rtp_instance_get_codecs(p->rtp), p->rtp);
08729 
08730          if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) {
08731             ast_clear_flag(&p->flags[0], SIP_DTMF);
08732             if (newnoncodeccapability & AST_RTP_DTMF) {
08733                /* XXX Would it be reasonable to drop the DSP at this point? XXX */
08734                ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
08735                /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */
08736                ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, 1);
08737                ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
08738             } else {
08739                ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
08740             }
08741          }
08742       } else if (udptlportno > 0) {
08743          if (debug)
08744             ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n");
08745       } else {
08746          ast_rtp_instance_stop(p->rtp);
08747          if (debug)
08748             ast_verbose("Peer doesn't provide audio\n");
08749       }
08750    }
08751 
08752    /* Setup video address and port */
08753    if (p->vrtp) {
08754       if (vportno > 0) {
08755          ast_sockaddr_set_port(vsa, vportno);
08756          ast_rtp_instance_set_remote_address(p->vrtp, vsa);
08757          if (debug) {
08758             ast_verbose("Peer video RTP is at port %s\n",
08759                    ast_sockaddr_stringify(vsa));
08760          }
08761          ast_rtp_codecs_payloads_copy(&newvideortp, ast_rtp_instance_get_codecs(p->vrtp), p->vrtp);
08762       } else {
08763          ast_rtp_instance_stop(p->vrtp);
08764          if (debug)
08765             ast_verbose("Peer doesn't provide video\n");
08766       }
08767    }
08768 
08769    /* Setup text address and port */
08770    if (p->trtp) {
08771       if (tportno > 0) {
08772          ast_sockaddr_set_port(tsa, tportno);
08773          ast_rtp_instance_set_remote_address(p->trtp, tsa);
08774          if (debug) {
08775             ast_verbose("Peer T.140 RTP is at port %s\n",
08776                    ast_sockaddr_stringify(tsa));
08777          }
08778          if ((p->jointcapability & AST_FORMAT_T140RED)) {
08779             p->red = 1;
08780             ast_rtp_red_init(p->trtp, 300, red_data_pt, 2);
08781          } else {
08782             p->red = 0;
08783          }
08784          ast_rtp_codecs_payloads_copy(&newtextrtp, ast_rtp_instance_get_codecs(p->trtp), p->trtp);
08785       } else {
08786          ast_rtp_instance_stop(p->trtp);
08787          if (debug)
08788             ast_verbose("Peer doesn't provide T.140\n");
08789       }
08790    }
08791    /* Setup image address and port */
08792    if (p->udptl) {
08793       if (udptlportno > 0) {
08794          if (ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) {
08795             ast_rtp_instance_get_remote_address(p->rtp, isa);
08796             if (!ast_sockaddr_isnull(isa) && debug) {
08797                ast_debug(1, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_sockaddr_stringify(isa));
08798             }
08799          }
08800          ast_sockaddr_set_port(isa, udptlportno);
08801          ast_udptl_set_peer(p->udptl, isa);
08802          if (debug)
08803             ast_debug(1,"Peer T.38 UDPTL is at port %s\n", ast_sockaddr_stringify(isa));
08804 
08805          /* verify the far max ifp can be calculated. this requires far max datagram to be set. */
08806          if (!ast_udptl_get_far_max_datagram(p->udptl)) {
08807             /* setting to zero will force a default if none was provided by the SDP */
08808             ast_udptl_set_far_max_datagram(p->udptl, 0);
08809          }
08810 
08811          /* Remote party offers T38, we need to update state */
08812          if ((t38action == SDP_T38_ACCEPT) &&
08813              (p->t38.state == T38_LOCAL_REINVITE)) {
08814             change_t38_state(p, T38_ENABLED);
08815          } else if ((t38action == SDP_T38_INITIATE) &&
08816                p->owner && p->lastinvite) {
08817             change_t38_state(p, T38_PEER_REINVITE); /* T38 Offered in re-invite from remote party */
08818             /* If fax detection is enabled then send us off to the fax extension */
08819             if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_T38)) {
08820                ast_channel_lock(p->owner);
08821                if (strcmp(p->owner->exten, "fax")) {
08822                   const char *target_context = S_OR(p->owner->macrocontext, p->owner->context);
08823                   ast_channel_unlock(p->owner);
08824                   if (ast_exists_extension(p->owner, target_context, "fax", 1,
08825                      S_COR(p->owner->caller.id.number.valid, p->owner->caller.id.number.str, NULL))) {
08826                      ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to peer T.38 re-INVITE\n", p->owner->name);
08827                      pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", p->owner->exten);
08828                      if (ast_async_goto(p->owner, target_context, "fax", 1)) {
08829                         ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", p->owner->name, target_context);
08830                      }
08831                   } else {
08832                      ast_log(LOG_NOTICE, "T.38 re-INVITE detected but no fax extension\n");
08833                   }
08834                } else {
08835                   ast_channel_unlock(p->owner);
08836                }
08837             }
08838          }
08839       } else {
08840          ast_udptl_stop(p->udptl);
08841          if (debug)
08842             ast_debug(1, "Peer doesn't provide T.38 UDPTL\n");
08843       }
08844    }
08845 
08846    if ((portno == -1) && (p->t38.state != T38_DISABLED)) {
08847       ast_debug(3, "Have T.38 but no audio, accepting offer anyway\n");
08848       return 0;
08849         }
08850 
08851    /* Ok, we're going with this offer */
08852    ast_debug(2, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability));
08853 
08854    if (!p->owner)    /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */
08855       return 0;
08856 
08857    ast_debug(4, "We have an owner, now see if we need to change this call\n");
08858 
08859    if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
08860       if (debug) {
08861          char s1[SIPBUFSIZE], s2[SIPBUFSIZE];
08862          ast_debug(1, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n",
08863             ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability),
08864             ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats));
08865       }
08866       p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability) | (p->capability & tpeercapability);
08867       ast_set_read_format(p->owner, p->owner->readformat);
08868       ast_set_write_format(p->owner, p->owner->writeformat);
08869    }
08870    
08871    if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && (!ast_sockaddr_isnull(sa) || !ast_sockaddr_isnull(vsa) || !ast_sockaddr_isnull(tsa) || !ast_sockaddr_isnull(isa)) && (!sendonly || sendonly == -1)) {
08872       ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
08873       /* Activate a re-invite */
08874       ast_queue_frame(p->owner, &ast_null_frame);
08875       change_hold_state(p, req, FALSE, sendonly);
08876    } else if ((ast_sockaddr_isnull(sa) && ast_sockaddr_isnull(vsa) && ast_sockaddr_isnull(tsa) && ast_sockaddr_isnull(isa)) || (sendonly && sendonly != -1)) {
08877       ast_queue_control_data(p->owner, AST_CONTROL_HOLD,
08878                    S_OR(p->mohsuggest, NULL),
08879                    !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
08880       if (sendonly)
08881          ast_rtp_instance_stop(p->rtp);
08882       /* RTCP needs to go ahead, even if we're on hold!!! */
08883       /* Activate a re-invite */
08884       ast_queue_frame(p->owner, &ast_null_frame);
08885       change_hold_state(p, req, TRUE, sendonly);
08886    }
08887    
08888    return 0;
08889 }

static int process_sdp_a_audio ( const char *  a,
struct sip_pvt *  p,
struct ast_rtp_codecs *  newaudiortp,
int *  last_rtpmap_codec 
) [static]

Definition at line 9017 of file chan_sip.c.

References ast_codec_pref_setsize(), ast_debug, AST_FORMAT_G719, AST_FORMAT_SIREN14, AST_FORMAT_SIREN7, ast_getformatname(), ast_log(), ast_rtp_codecs_packetization_set(), ast_rtp_codecs_payload_lookup(), ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_rtp_codecs_payloads_unset(), ast_rtp_instance_get_codecs(), AST_RTP_MAX_PT, AST_RTP_OPT_G726_NONSTANDARD, ast_test_flag, ast_verbose, debug, FALSE, format, LOG_WARNING, ast_rtp_codecs::pref, sip_debug_test_pvt(), and TRUE.

Referenced by process_sdp().

09018 {
09019    int found = FALSE;
09020    int codec;
09021    char mimeSubtype[128];
09022    char fmtp_string[64];
09023    unsigned int sample_rate;
09024    int debug = sip_debug_test_pvt(p);
09025 
09026    if (!strncasecmp(a, "ptime", 5)) {
09027       char *tmp = strrchr(a, ':');
09028       long int framing = 0;
09029       if (tmp) {
09030          tmp++;
09031          framing = strtol(tmp, NULL, 10);
09032          if (framing == LONG_MIN || framing == LONG_MAX) {
09033             framing = 0;
09034             ast_debug(1, "Can't read framing from SDP: %s\n", a);
09035          }
09036       }
09037       if (framing && p->autoframing) {
09038          struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref;
09039          int codec_n;
09040          for (codec_n = 0; codec_n < AST_RTP_MAX_PT; codec_n++) {
09041             struct ast_rtp_payload_type format = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(p->rtp), codec_n);
09042             if (!format.asterisk_format || !format.code) /* non-codec or not found */
09043                continue;
09044             ast_debug(1, "Setting framing for %s to %ld\n", ast_getformatname(format.code), framing);
09045             ast_codec_pref_setsize(pref, format.code, framing);
09046          }
09047          ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, pref);
09048       }
09049       found = TRUE;
09050    } else if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) {
09051       /* We have a rtpmap to handle */
09052       if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
09053          if (ast_rtp_codecs_payloads_set_rtpmap_type_rate(newaudiortp, NULL, codec, "audio", mimeSubtype,
09054              ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0, sample_rate) != -1) {
09055             if (debug)
09056                ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec);
09057             //found_rtpmap_codecs[last_rtpmap_codec] = codec;
09058             (*last_rtpmap_codec)++;
09059             found = TRUE;
09060          } else {
09061             ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
09062             if (debug)
09063                ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec);
09064          }
09065       } else {
09066          if (debug)
09067             ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec);
09068       }
09069    } else if (sscanf(a, "fmtp: %30u %63s", &codec, fmtp_string) == 2) {
09070       struct ast_rtp_payload_type payload;
09071 
09072       payload = ast_rtp_codecs_payload_lookup(newaudiortp, codec);
09073       if (payload.code && payload.asterisk_format) {
09074          unsigned int bit_rate;
09075 
09076          switch (payload.code) {
09077          case AST_FORMAT_SIREN7:
09078             if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
09079                if (bit_rate != 32000) {
09080                   ast_log(LOG_WARNING, "Got Siren7 offer at %d bps, but only 32000 bps supported; ignoring.\n", bit_rate);
09081                   ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
09082                } else {
09083                   found = TRUE;
09084                }
09085             }
09086             break;
09087          case AST_FORMAT_SIREN14:
09088             if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
09089                if (bit_rate != 48000) {
09090                   ast_log(LOG_WARNING, "Got Siren14 offer at %d bps, but only 48000 bps supported; ignoring.\n", bit_rate);
09091                   ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
09092                } else {
09093                   found = TRUE;
09094                }
09095             }
09096             break;
09097          case AST_FORMAT_G719:
09098             if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
09099                if (bit_rate != 64000) {
09100                   ast_log(LOG_WARNING, "Got G.719 offer at %d bps, but only 64000 bps supported; ignoring.\n", bit_rate);
09101                   ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
09102                } else {
09103                   found = TRUE;
09104                }
09105             }
09106          }
09107       }
09108    }
09109 
09110    return found;
09111 }

static int process_sdp_a_image ( const char *  a,
struct sip_pvt *  p 
) [static]

Definition at line 9196 of file chan_sip.c.

References ast_debug, AST_T38_RATE_12000, AST_T38_RATE_14400, AST_T38_RATE_2400, AST_T38_RATE_4800, AST_T38_RATE_7200, AST_T38_RATE_9600, AST_T38_RATE_MANAGEMENT_LOCAL_TCF, AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF, ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), FALSE, TRUE, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.

Referenced by process_sdp().

09197 {
09198    int found = FALSE;
09199    char s[256];
09200    unsigned int x;
09201 
09202    if ((sscanf(a, "T38FaxMaxBuffer:%30u", &x) == 1)) {
09203       ast_debug(3, "MaxBufferSize:%d\n", x);
09204       found = TRUE;
09205    } else if ((sscanf(a, "T38MaxBitRate:%30u", &x) == 1) || (sscanf(a, "T38FaxMaxRate:%30u", &x) == 1)) {
09206       ast_debug(3, "T38MaxBitRate: %d\n", x);
09207       switch (x) {
09208       case 14400:
09209          p->t38.their_parms.rate = AST_T38_RATE_14400;
09210          break;
09211       case 12000:
09212          p->t38.their_parms.rate = AST_T38_RATE_12000;
09213          break;
09214       case 9600:
09215          p->t38.their_parms.rate = AST_T38_RATE_9600;
09216          break;
09217       case 7200:
09218          p->t38.their_parms.rate = AST_T38_RATE_7200;
09219          break;
09220       case 4800:
09221          p->t38.their_parms.rate = AST_T38_RATE_4800;
09222          break;
09223       case 2400:
09224          p->t38.their_parms.rate = AST_T38_RATE_2400;
09225          break;
09226       }
09227       found = TRUE;
09228    } else if ((sscanf(a, "T38FaxVersion:%30u", &x) == 1)) {
09229       ast_debug(3, "FaxVersion: %u\n", x);
09230       p->t38.their_parms.version = x;
09231       found = TRUE;
09232    } else if ((sscanf(a, "T38FaxMaxDatagram:%30u", &x) == 1) || (sscanf(a, "T38MaxDatagram:%30u", &x) == 1)) {
09233       /* override the supplied value if the configuration requests it */
09234       if (((signed int) p->t38_maxdatagram >= 0) && ((unsigned int) p->t38_maxdatagram > x)) {
09235          ast_debug(1, "Overriding T38FaxMaxDatagram '%d' with '%d'\n", x, p->t38_maxdatagram);
09236          x = p->t38_maxdatagram;
09237       }
09238       ast_debug(3, "FaxMaxDatagram: %u\n", x);
09239       ast_udptl_set_far_max_datagram(p->udptl, x);
09240       found = TRUE;
09241    } else if ((strncmp(a, "T38FaxFillBitRemoval", 20) == 0)) {
09242       if (sscanf(a, "T38FaxFillBitRemoval:%30u", &x) == 1) {
09243          ast_debug(3, "FillBitRemoval: %d\n", x);
09244          if (x == 1) {
09245             p->t38.their_parms.fill_bit_removal = TRUE;
09246          }
09247       } else {
09248          ast_debug(3, "FillBitRemoval\n");
09249          p->t38.their_parms.fill_bit_removal = TRUE;
09250       }
09251       found = TRUE;
09252    } else if ((strncmp(a, "T38FaxTranscodingMMR", 20) == 0)) {
09253       if (sscanf(a, "T38FaxTranscodingMMR:%30u", &x) == 1) {
09254          ast_debug(3, "Transcoding MMR: %d\n", x);
09255          if (x == 1) {
09256             p->t38.their_parms.transcoding_mmr = TRUE;
09257          }
09258       } else {
09259          ast_debug(3, "Transcoding MMR\n");
09260          p->t38.their_parms.transcoding_mmr = TRUE;
09261       }
09262       found = TRUE;
09263    } else if ((strncmp(a, "T38FaxTranscodingJBIG", 21) == 0)) {
09264       if (sscanf(a, "T38FaxTranscodingJBIG:%30u", &x) == 1) {
09265          ast_debug(3, "Transcoding JBIG: %d\n", x);
09266          if (x == 1) {
09267             p->t38.their_parms.transcoding_jbig = TRUE;
09268          }
09269       } else {
09270          ast_debug(3, "Transcoding JBIG\n");
09271          p->t38.their_parms.transcoding_jbig = TRUE;
09272       }
09273       found = TRUE;
09274    } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) {
09275       ast_debug(3, "RateManagement: %s\n", s);
09276       if (!strcasecmp(s, "localTCF"))
09277          p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_LOCAL_TCF;
09278       else if (!strcasecmp(s, "transferredTCF"))
09279          p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF;
09280       found = TRUE;
09281    } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) {
09282       ast_debug(3, "UDP EC: %s\n", s);
09283       if (!strcasecmp(s, "t38UDPRedundancy")) {
09284          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY);
09285       } else if (!strcasecmp(s, "t38UDPFEC")) {
09286          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC);
09287       } else {
09288          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE);
09289       }
09290       found = TRUE;
09291    }
09292 
09293    return found;
09294 }

static int process_sdp_a_sendonly ( const char *  a,
int *  sendonly 
) [static]

Definition at line 8997 of file chan_sip.c.

References FALSE, and TRUE.

Referenced by process_sdp().

08998 {
08999    int found = FALSE;
09000 
09001    if (!strcasecmp(a, "sendonly")) {
09002       if (*sendonly == -1)
09003          *sendonly = 1;
09004       found = TRUE;
09005    } else if (!strcasecmp(a, "inactive")) {
09006       if (*sendonly == -1)
09007          *sendonly = 2;
09008       found = TRUE;
09009    }  else if (!strcasecmp(a, "sendrecv")) {
09010       if (*sendonly == -1)
09011          *sendonly = 0;
09012       found = TRUE;
09013    }
09014    return found;
09015 }

static int process_sdp_a_text ( const char *  a,
struct sip_pvt *  p,
struct ast_rtp_codecs *  newtextrtp,
char *  red_fmtp,
int *  red_num_gen,
int *  red_data_pt,
int *  last_rtpmap_codec 
) [static]

Definition at line 9147 of file chan_sip.c.

References AST_RED_MAX_GENERATION, ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_verbose, debug, FALSE, sip_debug_test_pvt(), and TRUE.

Referenced by process_sdp().

09148 {
09149    int found = FALSE;
09150    int codec;
09151    char mimeSubtype[128];
09152    unsigned int sample_rate;
09153    char *red_cp;
09154    int debug = sip_debug_test_pvt(p);
09155 
09156    if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) {
09157       /* We have a rtpmap to handle */
09158       if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
09159          if (!strncasecmp(mimeSubtype, "T140", 4)) { /* Text */
09160             if (p->trtp) {
09161                /* ast_verbose("Adding t140 mimeSubtype to textrtp struct\n"); */
09162                ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate);
09163                found = TRUE;
09164             }
09165          } else if (!strncasecmp(mimeSubtype, "RED", 3)) { /* Text with Redudancy */
09166             if (p->trtp) {
09167                ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate);
09168                sprintf(red_fmtp, "fmtp:%d ", codec);
09169                if (debug)
09170                   ast_verbose("RED submimetype has payload type: %d\n", codec);
09171                found = TRUE;
09172             }
09173          }
09174       } else {
09175          if (debug)
09176             ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec);
09177       }
09178    } else if (!strncmp(a, red_fmtp, strlen(red_fmtp))) {
09179       /* count numbers of generations in fmtp */
09180       red_cp = &red_fmtp[strlen(red_fmtp)];
09181       strncpy(red_fmtp, a, 100);
09182 
09183       sscanf(red_cp, "%30u", &red_data_pt[*red_num_gen]);
09184       red_cp = strtok(red_cp, "/");
09185       while (red_cp && (*red_num_gen)++ < AST_RED_MAX_GENERATION) {
09186          sscanf(red_cp, "%30u", &red_data_pt[*red_num_gen]);
09187          red_cp = strtok(NULL, "/");
09188       }
09189       red_cp = red_fmtp;
09190       found = TRUE;
09191    }
09192 
09193    return found;
09194 }

static int process_sdp_a_video ( const char *  a,
struct sip_pvt *  p,
struct ast_rtp_codecs *  newvideortp,
int *  last_rtpmap_codec 
) [static]

Definition at line 9113 of file chan_sip.c.

References ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_rtp_codecs_payloads_unset(), ast_verbose, debug, FALSE, sip_debug_test_pvt(), and TRUE.

Referenced by process_sdp().

09114 {
09115    int found = FALSE;
09116    int codec;
09117    char mimeSubtype[128];
09118    unsigned int sample_rate;
09119    int debug = sip_debug_test_pvt(p);
09120 
09121    if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) {
09122       /* We have a rtpmap to handle */
09123       if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
09124          /* Note: should really look at the '#chans' params too */
09125          if (!strncasecmp(mimeSubtype, "H26", 3) || !strncasecmp(mimeSubtype, "MP4", 3)) {
09126             if (ast_rtp_codecs_payloads_set_rtpmap_type_rate(newvideortp, NULL, codec, "video", mimeSubtype, 0, sample_rate) != -1) {
09127                if (debug)
09128                   ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec);
09129                //found_rtpmap_codecs[last_rtpmap_codec] = codec;
09130                (*last_rtpmap_codec)++;
09131                found = TRUE;
09132             } else {
09133                ast_rtp_codecs_payloads_unset(newvideortp, NULL, codec);
09134                if (debug)
09135                   ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec);
09136             }
09137          }
09138       } else {
09139          if (debug)
09140             ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec);
09141       }
09142    }
09143 
09144    return found;
09145 }

static int process_sdp_c ( const char *  c,
struct ast_sockaddr *  addr 
) [static]

Definition at line 8970 of file chan_sip.c.

References ast_log(), ast_sockaddr_resolve_first_af(), FALSE, LOG_WARNING, and TRUE.

Referenced by process_sdp().

08971 {
08972    char proto[4], host[258];
08973    int af;
08974 
08975    /* Check for Media-description-level-address */
08976    if (sscanf(c, "IN %3s %255s", proto, host) == 2) {
08977       if (!strcmp("IP4", proto)) {
08978          af = AF_INET;
08979       } else if (!strcmp("IP6", proto)) {
08980          af = AF_INET6;
08981       } else {
08982          ast_log(LOG_WARNING, "Unknown protocol '%s'.\n", proto);
08983          return FALSE;
08984       }
08985       if (ast_sockaddr_resolve_first_af(addr, host, 0, af)) {
08986          ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in c= line, '%s'\n", c);
08987          return FALSE;
08988       }
08989       return TRUE;
08990    } else {
08991       ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
08992       return FALSE;
08993    }
08994    return FALSE;
08995 }

static int process_sdp_o ( const char *  o,
struct sip_pvt *  p 
) [static]

Definition at line 8891 of file chan_sip.c.

References ast_debug, ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, FALSE, LOG_WARNING, strsep(), and TRUE.

Referenced by process_sdp().

08892 {
08893    char *o_copy;
08894    char *token;
08895    int64_t rua_version;
08896 
08897    /* Store the SDP version number of remote UA. This will allow us to
08898    distinguish between session modifications and session refreshes. If
08899    the remote UA does not send an incremented SDP version number in a
08900    subsequent RE-INVITE then that means its not changing media session.
08901    The RE-INVITE may have been sent to update connected party, remote
08902    target or to refresh the session (Session-Timers).  Asterisk must not
08903    change media session and increment its own version number in answer
08904    SDP in this case. */
08905 
08906    p->session_modify = TRUE;
08907 
08908    if (ast_strlen_zero(o)) {
08909       ast_log(LOG_WARNING, "SDP syntax error. SDP without an o= line\n");
08910       return FALSE;
08911    }
08912 
08913    o_copy = ast_strdupa(o);
08914    token = strsep(&o_copy, " ");  /* Skip username   */
08915    if (!o_copy) {
08916       ast_log(LOG_WARNING, "SDP syntax error in o= line username\n");
08917       return FALSE;
08918    }
08919    token = strsep(&o_copy, " ");  /* Skip session-id */
08920    if (!o_copy) {
08921       ast_log(LOG_WARNING, "SDP syntax error in o= line session-id\n");
08922       return FALSE;
08923    }
08924    token = strsep(&o_copy, " ");  /* Version         */
08925    if (!o_copy) {
08926       ast_log(LOG_WARNING, "SDP syntax error in o= line\n");
08927       return FALSE;
08928    }
08929    if (!sscanf(token, "%30" SCNd64, &rua_version)) {
08930       ast_log(LOG_WARNING, "SDP syntax error in o= line version\n");
08931       return FALSE;
08932    }
08933 
08934    /* we need to check the SDP version number the other end sent us;
08935     * our rules for deciding what to accept are a bit complex.
08936     *
08937     * 1) if 'ignoresdpversion' has been set for this dialog, then
08938     *    we will just accept whatever they sent and assume it is
08939     *    a modification of the session, even if it is not
08940     * 2) otherwise, if this is the first SDP we've seen from them
08941     *    we accept it
08942     * 3) otherwise, if the new SDP version number is higher than the
08943     *    old one, we accept it
08944     * 4) otherwise, if this SDP is in response to us requesting a switch
08945     *    to T.38, we accept the SDP, but also generate a warning message
08946     *    that this peer should have the 'ignoresdpversion' option set,
08947     *    because it is not following the SDP offer/answer RFC; if we did
08948     *    not request a switch to T.38, then we stop parsing the SDP, as it
08949     *    has not changed from the previous version
08950     */
08951 
08952    if (ast_test_flag(&p->flags[1], SIP_PAGE2_IGNORESDPVERSION) ||
08953        (p->sessionversion_remote < 0) ||
08954        (p->sessionversion_remote < rua_version)) {
08955       p->sessionversion_remote = rua_version;
08956    } else {
08957       if (p->t38.state == T38_LOCAL_REINVITE) {
08958          p->sessionversion_remote = rua_version;
08959          ast_log(LOG_WARNING, "Call %s responded to our T.38 reinvite without changing SDP version; 'ignoresdpversion' should be set for this peer.\n", p->callid);
08960       } else {
08961          p->session_modify = FALSE;
08962          ast_debug(2, "Call %s responded to our reinvite without changing SDP version; ignoring SDP.\n", p->callid);
08963          return FALSE;
08964       }
08965    }
08966 
08967    return TRUE;
08968 }

static int process_via ( struct sip_pvt *  p,
const struct sip_request *  req 
) [static]

Process the Via header according to RFC 3261 section 18.2.2.

Parameters:
p a sip_pvt structure that will be modified according to the received header
req a sip request with a Via header to process
This function will update the destination of the response according to the Via header in the request and RFC 3261 section 18.2.2. We do not have a transport layer so we ignore certain values like the 'received' param (we set the destination address to the addres the request came from in the respprep() function).

Return values:
-1 error
0 success

Definition at line 7415 of file chan_sip.c.

References addr_is_multicast(), ast_log(), ast_sockaddr_resolve_first(), ast_sockaddr_set_port, get_header(), LOG_ERROR, LOG_WARNING, PARSE_PORT_FORBID, and sipsock.

Referenced by respprep().

07416 {
07417    struct sip_via *via = parse_via(get_header(req, "Via"));
07418 
07419    if (!via) {
07420       ast_log(LOG_ERROR, "error processing via header\n");
07421       return -1;
07422    }
07423 
07424    if (via->maddr) {
07425       if (ast_sockaddr_resolve_first(&p->sa, via->maddr, PARSE_PORT_FORBID)) {
07426          ast_log(LOG_WARNING, "Can't find address for maddr '%s'\n", via->maddr);
07427          ast_log(LOG_ERROR, "error processing via header\n");
07428          free_via(via);
07429          return -1;
07430       }
07431 
07432       if (addr_is_multicast(&p->sa)) {
07433          setsockopt(sipsock, IPPROTO_IP, IP_MULTICAST_TTL, &via->ttl, sizeof(via->ttl));
07434       }
07435    }
07436 
07437    ast_sockaddr_set_port(&p->sa, via->port ? via->port : STANDARD_SIP_PORT);
07438 
07439    free_via(via);
07440    return 0;
07441 }

static int proxy_update ( struct sip_proxy *  proxy  )  [static]

Resolve DNS srv name or host name in a sip_proxy structure

Definition at line 3006 of file chan_sip.c.

References ast_get_ip_or_srv(), ast_log(), ast_sockaddr_parse(), ast_sockaddr_set_port, bindaddr, FALSE, get_address_family_filter(), LOG_WARNING, sip_cfg, and TRUE.

Referenced by build_peer().

03007 {
03008    /* if it's actually an IP address and not a name,
03009            there's no need for a managed lookup */
03010    if (!ast_sockaddr_parse(&proxy->ip, proxy->name, 0)) {
03011       /* Ok, not an IP address, then let's check if it's a domain or host */
03012       /* XXX Todo - if we have proxy port, don't do SRV */
03013       proxy->ip.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */
03014       if (ast_get_ip_or_srv(&proxy->ip, proxy->name, sip_cfg.srvlookup ? "_sip._udp" : NULL) < 0) {
03015             ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name);
03016             return FALSE;
03017       }
03018 
03019    }
03020 
03021    ast_sockaddr_set_port(&proxy->ip, proxy->port);
03022 
03023    proxy->last_dnsupdate = time(NULL);
03024    return TRUE;
03025 }

static int publish_expire ( const void *  data  )  [static]

Definition at line 1005 of file chan_sip.c.

References ao2_ref, ao2_unlink, ast_assert, event_state_compositor::compositor, and get_esc().

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

01006 {
01007    struct sip_esc_entry *esc_entry = (struct sip_esc_entry *) data;
01008    struct event_state_compositor *esc = get_esc(esc_entry->event);
01009 
01010    ast_assert(esc != NULL);
01011 
01012    ao2_unlink(esc->compositor, esc_entry);
01013    ao2_ref(esc_entry, -1);
01014    return 0;
01015 }

static void pvt_set_needdestroy ( struct sip_pvt *  pvt,
const char *  reason 
) [inline, static]

Definition at line 2971 of file chan_sip.c.

References append_history.

Referenced by __sip_autodestruct(), handle_incoming(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_notify(), handle_response_peerpoke(), handle_response_publish(), handle_response_refer(), handle_response_register(), handle_response_subscribe(), retrans_pkt(), sip_hangup(), and sip_reg_timeout().

02972 {
02973    if (pvt->final_destruction_scheduled) {
02974       return; /* This is already scheduled for final destruction, let the scheduler take care of it. */
02975    }
02976    append_history(pvt, "NeedDestroy", "Setting needdestroy because %s", reason);
02977    pvt->needdestroy = 1;
02978 }

static int queue_request ( struct sip_pvt *  p,
const struct sip_request *  req 
) [static]

Definition at line 24137 of file chan_sip.c.

References ast_calloc, AST_LIST_INSERT_TAIL, ast_sched_add(), copy_request(), and scheduler_process_request_queue().

Referenced by handle_request_do().

24138 {
24139    struct sip_request *newreq;
24140 
24141    if (!(newreq = ast_calloc(1, sizeof(*newreq)))) {
24142       return -1;
24143    }
24144 
24145    copy_request(newreq, req);
24146    AST_LIST_INSERT_TAIL(&p->request_queue, newreq, next);
24147    if (p->request_queue_sched_id == -1) {
24148       if ((p->request_queue_sched_id = ast_sched_add(sched, 10, scheduler_process_request_queue, dialog_ref(p, "Increment refcount to pass dialog pointer to sched callback"))) == -1) {
24149          dialog_unref(p, "Decrement refcount due to sched_add failure");
24150       }
24151    }
24152 
24153    return 0;
24154 }

static struct sip_peer * realtime_peer ( const char *  peername,
struct ast_sockaddr *  sin,
int  devstate_only,
int  which_objects 
) [static]

realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf Checks the "sipregs" realtime family from extconfig.conf if it's configured. This returns a pointer to a peer and because we use build_peer, we can rest assured that the refcount is bumped.

Note:
If this one loaded something, then we need to ensure that the host field matched. The only reason why we can't have this as a criteria is because we only have the IP address and the host field might be set as a name (and the reverse PTR might not match).

Definition at line 4564 of file chan_sip.c.

References ast_check_realtime(), ast_free, ast_load_realtime(), ast_sockaddr_cmp(), ast_sockaddr_resolve(), ast_sockaddr_stringify_addr(), ast_variables_destroy(), bindaddr, get_address_family_filter(), ipaddr, ast_variable::name, ast_variable::next, PARSE_PORT_FORBID, SENTINEL, ast_variable::value, and var.

04565 {
04566    struct sip_peer *peer;
04567    struct ast_variable *var = NULL;
04568    struct ast_variable *varregs = NULL;
04569    struct ast_variable *tmp;
04570    struct ast_config *peerlist = NULL;
04571    char ipaddr[INET6_ADDRSTRLEN];
04572    char portstring[6]; /*up to 5 digits plus null terminator*/
04573    char *cat = NULL;
04574    int realtimeregs = ast_check_realtime("sipregs");
04575 
04576    /* First check on peer name */
04577    if (newpeername) {
04578       if (realtimeregs)
04579          varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL);
04580 
04581       var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", SENTINEL);
04582       if (!var && addr) {
04583          var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_sockaddr_stringify_addr(addr), SENTINEL);
04584       }
04585       if (!var) {
04586          var = ast_load_realtime("sippeers", "name", newpeername, SENTINEL);
04587          /*!\note
04588           * If this one loaded something, then we need to ensure that the host
04589           * field matched.  The only reason why we can't have this as a criteria
04590           * is because we only have the IP address and the host field might be
04591           * set as a name (and the reverse PTR might not match).
04592           */
04593          if (var && addr) {
04594             for (tmp = var; tmp; tmp = tmp->next) {
04595                if (!strcasecmp(tmp->name, "host")) {
04596                   struct ast_sockaddr *addrs = NULL;
04597 
04598                   if (ast_sockaddr_resolve(&addrs,
04599                             tmp->value,
04600                             PARSE_PORT_FORBID,
04601                             get_address_family_filter(&bindaddr)) <= 0 ||
04602                       ast_sockaddr_cmp(&addrs[0], addr)) {
04603                      /* No match */
04604                      ast_variables_destroy(var);
04605                      var = NULL;
04606                   }
04607                   ast_free(addrs);
04608                   break;
04609                }
04610             }
04611          }
04612       }
04613    }
04614 
04615    if (!var && addr) {  /* Then check on IP address for dynamic peers */
04616       ast_copy_string(ipaddr, ast_sockaddr_stringify_addr(addr), sizeof(ipaddr));
04617       ast_copy_string(portstring, ast_sockaddr_stringify_port(addr), sizeof(portstring));
04618       var = ast_load_realtime("sippeers", "host", ipaddr, "port", portstring, SENTINEL);  /* First check for fixed IP hosts */
04619       if (var) {
04620          if (realtimeregs) {
04621             newpeername = get_name_from_variable(var, newpeername);
04622             varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL);
04623          }
04624       } else {
04625          if (realtimeregs)
04626             varregs = ast_load_realtime("sipregs", "ipaddr", ipaddr, "port", portstring, SENTINEL); /* Then check for registered hosts */
04627          else
04628             var = ast_load_realtime("sippeers", "ipaddr", ipaddr, "port", portstring, SENTINEL); /* Then check for registered hosts */
04629          if (varregs) {
04630             newpeername = get_name_from_variable(varregs, newpeername);
04631             var = ast_load_realtime("sippeers", "name", newpeername, SENTINEL);
04632          }
04633       }
04634       if (!var) { /*We couldn't match on ipaddress and port, so we need to check if port is insecure*/
04635          peerlist = ast_load_realtime_multientry("sippeers", "host", ipaddr, SENTINEL);
04636          if (peerlist) {
04637             var = get_insecure_variable_from_config(peerlist);
04638             if(var) {
04639                if (realtimeregs) {
04640                   newpeername = get_name_from_variable(var, newpeername);
04641                   varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL);
04642                }
04643             } else { /*var wasn't found in the list of "hosts", so try "ipaddr"*/
04644                peerlist = NULL;
04645                cat = NULL;
04646                peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", ipaddr, SENTINEL);
04647                if(peerlist) {
04648                   var = get_insecure_variable_from_config(peerlist);
04649                   if(var) {
04650                      if (realtimeregs) {
04651                         newpeername = get_name_from_variable(var, newpeername);
04652                         varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL);
04653                      }
04654                   }
04655                }
04656             }
04657          } else {
04658             if (realtimeregs) {
04659                peerlist = ast_load_realtime_multientry("sipregs", "ipaddr", ipaddr, SENTINEL);
04660                if (peerlist) {
04661                   varregs = get_insecure_variable_from_config(peerlist);
04662                   if (varregs) {
04663                      newpeername = get_name_from_variable(varregs, newpeername);
04664                      var = ast_load_realtime("sippeers", "name", newpeername, SENTINEL);
04665                   }
04666                }
04667             } else {
04668                peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", ipaddr, SENTINEL);
04669                if (peerlist) {
04670                   var = get_insecure_variable_from_config(peerlist);
04671                   if (var) {
04672                      newpeername = get_name_from_variable(var, newpeername);
04673                      varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL);
04674                   }
04675                }
04676             }
04677          }
04678       }
04679    }
04680 
04681    if (!var) {
04682       if (peerlist)
04683          ast_config_destroy(peerlist);
04684       return NULL;
04685    }
04686 
04687    for (tmp = var; tmp; tmp = tmp->next) {
04688       if (!strcasecmp(tmp->name, "type") && (!strcasecmp(tmp->value, "peer") && which_objects == FINDUSERS)) {
04689          if (peerlist) {
04690             ast_config_destroy(peerlist);
04691          } else {
04692             ast_variables_destroy(var);
04693             ast_variables_destroy(varregs);
04694          }
04695          return NULL;
04696       } else if (!newpeername && !strcasecmp(tmp->name, "name")) {
04697          newpeername = tmp->value;
04698       }
04699    }
04700 
04701    if (!newpeername) {  /* Did not find peer in realtime */
04702       ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", ipaddr);
04703       if(peerlist)
04704          ast_config_destroy(peerlist);
04705       else
04706          ast_variables_destroy(var);
04707       return NULL;
04708    }
04709 
04710 
04711    /* Peer found in realtime, now build it in memory */
04712    peer = build_peer(newpeername, var, varregs, TRUE, devstate_only);
04713    if (!peer) {
04714       if(peerlist)
04715          ast_config_destroy(peerlist);
04716       else {
04717          ast_variables_destroy(var);
04718          ast_variables_destroy(varregs);
04719       }
04720       return NULL;
04721    }
04722 
04723    ast_debug(3, "-REALTIME- loading peer from database to memory. Name: %s. Peer objects: %d\n", peer->name, rpeerobjs);
04724 
04725    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) {
04726       /* Cache peer */
04727       ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS);
04728       if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
04729          AST_SCHED_REPLACE_UNREF(peer->expire, sched, sip_cfg.rtautoclear * 1000, expire_register, peer,
04730                unref_peer(_data, "remove registration ref"),
04731                unref_peer(peer, "remove registration ref"),
04732                ref_peer(peer, "add registration ref"));
04733       }
04734       ao2_t_link(peers, peer, "link peer into peers table");
04735       if (!ast_sockaddr_isnull(&peer->addr)) {
04736          ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
04737       }
04738    }
04739    peer->is_realtime = 1;
04740    if (peerlist)
04741       ast_config_destroy(peerlist);
04742    else {
04743       ast_variables_destroy(var);
04744       ast_variables_destroy(varregs);
04745    }
04746 
04747    return peer;
04748 }

static void realtime_update_peer ( const char *  peername,
struct ast_sockaddr *  addr,
const char *  username,
const char *  fullcontact,
const char *  useragent,
int  expirey,
unsigned short  deprecated_username,
int  lastms 
) [static]

Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.

Definition at line 4361 of file chan_sip.c.

References ast_check_realtime(), ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strlen_zero(), ast_update_realtime(), ipaddr, SENTINEL, and sip_cfg.

04362 {
04363    char port[10];
04364    char ipaddr[INET6_ADDRSTRLEN];
04365    char regseconds[20];
04366    char *tablename = NULL;
04367    char str_lastms[20];
04368 
04369    const char *sysname = ast_config_AST_SYSTEM_NAME;
04370    char *syslabel = NULL;
04371 
04372    time_t nowtime = time(NULL) + expirey;
04373    const char *fc = fullcontact ? "fullcontact" : NULL;
04374 
04375    int realtimeregs = ast_check_realtime("sipregs");
04376 
04377    tablename = realtimeregs ? "sipregs" : "sippeers";
04378    
04379 
04380    snprintf(str_lastms, sizeof(str_lastms), "%d", lastms);
04381    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);  /* Expiration time */
04382    ast_copy_string(ipaddr, ast_sockaddr_stringify_addr(addr), sizeof(ipaddr));
04383    ast_copy_string(port, ast_sockaddr_stringify_port(addr), sizeof(port));
04384 
04385    if (ast_strlen_zero(sysname)) /* No system name, disable this */
04386       sysname = NULL;
04387    else if (sip_cfg.rtsave_sysname)
04388       syslabel = "regserver";
04389 
04390    /* XXX IMPORTANT: Anytime you add a new parameter to be updated, you
04391          *  must also add it to contrib/scripts/asterisk.ldap-schema,
04392          *  contrib/scripts/asterisk.ldif,
04393          *  and to configs/res_ldap.conf.sample as described in
04394          *  bugs 15156 and 15895 
04395          */
04396    if (fc) {
04397       ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
04398          "port", port, "regseconds", regseconds,
04399          deprecated_username ? "username" : "defaultuser", defaultuser,
04400          "useragent", useragent, "lastms", str_lastms,
04401          fc, fullcontact, syslabel, sysname, SENTINEL); /* note fc and syslabel _can_ be NULL */
04402    } else {
04403       ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
04404          "port", port, "regseconds", regseconds,
04405          "useragent", useragent, "lastms", str_lastms,
04406          deprecated_username ? "username" : "defaultuser", defaultuser,
04407          syslabel, sysname, SENTINEL); /* note syslabel _can_ be NULL */
04408    }
04409 }

static void receive_message ( struct sip_pvt *  p,
struct sip_request *  req 
) [static]

Receive SIP MESSAGE method messages.

Note:
We only handle messages within current calls currently Reference: RFC 3428

Definition at line 15494 of file chan_sip.c.

References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose, f, FALSE, get_header(), get_msg_text(), LOG_WARNING, sip_debug_test_pvt(), sip_scheddestroy(), and transmit_response().

Referenced by handle_request_message().

15495 {
15496    char buf[1400];   
15497    struct ast_frame f;
15498    const char *content_type = get_header(req, "Content-Type");
15499 
15500    if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */
15501       transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
15502       if (!p->owner)
15503          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15504       return;
15505    }
15506 
15507    if (get_msg_text(buf, sizeof(buf), req, FALSE)) {
15508       ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
15509       transmit_response(p, "202 Accepted", req);
15510       if (!p->owner)
15511          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15512       return;
15513    }
15514 
15515    if (p->owner) {
15516       if (sip_debug_test_pvt(p))
15517          ast_verbose("SIP Text message received: '%s'\n", buf);
15518       memset(&f, 0, sizeof(f));
15519       f.frametype = AST_FRAME_TEXT;
15520       f.subclass.integer = 0;
15521       f.offset = 0;
15522       f.data.ptr = buf;
15523       f.datalen = strlen(buf) + 1;
15524       ast_queue_frame(p->owner, &f);
15525       transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
15526       return;
15527    }
15528 
15529    /* Message outside of a call, we do not support that */
15530    ast_log(LOG_WARNING, "Received message to %s from %s, dropped it...\n  Content-Type:%s\n  Message: %s\n", get_header(req, "To"), get_header(req, "From"), content_type, buf);
15531    transmit_response(p, "405 Method Not Allowed", req);
15532    sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15533    return;
15534 }

static struct sip_peer* ref_peer ( struct sip_peer *  peer,
char *  tag 
) [static]

Definition at line 2831 of file chan_sip.c.

References ao2_t_ref.

Referenced by build_peer(), create_addr(), handle_request_invite(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), reg_source_db(), sip_poke_all_peers(), sip_poke_noanswer(), sip_poke_peer(), sip_unregister(), and update_call_counter().

02832 {
02833    ao2_t_ref(peer, 1, tag);
02834    return peer;
02835 }

static void ref_proxy ( struct sip_pvt *  pvt,
struct sip_proxy *  proxy 
) [static]

maintain proper refcounts for a sip_pvt's outboundproxy

This function sets pvt's outboundproxy pointer to the one referenced by the proxy parameter. Because proxy may be a refcounted object, and because pvt's old outboundproxy may also be a refcounted object, we need to maintain the proper refcounts.

Parameters:
pvt The sip_pvt for which we wish to set the outboundproxy
proxy The sip_proxy which we will point pvt towards.
Returns:
Returns void

Definition at line 2848 of file chan_sip.c.

References ao2_ref, and sip_cfg.

Referenced by __sip_ack(), __sip_subscribe_mwi_do(), create_addr(), and create_addr_from_peer().

02849 {
02850    struct sip_proxy *old_obproxy = pvt->outboundproxy;
02851    /* The sip_cfg.outboundproxy is statically allocated, and so
02852     * we don't ever need to adjust refcounts for it
02853     */
02854    if (proxy && proxy != &sip_cfg.outboundproxy) {
02855       ao2_ref(proxy, +1);
02856    }
02857    pvt->outboundproxy = proxy;
02858    if (old_obproxy && old_obproxy != &sip_cfg.outboundproxy) {
02859       ao2_ref(old_obproxy, -1);
02860    }
02861 }

static const char * referstatus2str ( enum referstatus  rstatus  )  [static]

Convert transfer status to string.

Definition at line 2966 of file chan_sip.c.

References map_x_s(), and referstatusstrings.

Referenced by show_channels_cb().

02967 {
02968    return map_x_s(referstatusstrings, rstatus, "");
02969 }

static void reg_source_db ( struct sip_peer *  peer  )  [static]

Get registration details from Asterisk DB.

Definition at line 13068 of file chan_sip.c.

References args, AST_APP_ARG, ast_db_get(), ast_debug, AST_DECLARE_APP_ARGS, AST_NONSTANDARD_RAW_ARGS, ast_random(), AST_SCHED_REPLACE_UNREF, ast_sockaddr_copy(), ast_sockaddr_parse(), ast_sockaddr_stringify_host(), ast_string_field_set, expire_register(), ref_peer(), register_peer_exten(), sip_poke_peer(), sip_poke_peer_s(), sipsock, TRUE, and unref_peer().

13069 {
13070    char data[256];
13071    struct ast_sockaddr sa;
13072    int expire;
13073    char full_addr[128];
13074    AST_DECLARE_APP_ARGS(args,
13075       AST_APP_ARG(addr);
13076       AST_APP_ARG(port);
13077       AST_APP_ARG(expiry_str);
13078       AST_APP_ARG(username);
13079       AST_APP_ARG(contact);
13080    );
13081 
13082    if (peer->rt_fromcontact) {
13083       return;
13084    }
13085    if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) {
13086       return;
13087    }
13088 
13089    AST_NONSTANDARD_RAW_ARGS(args, data, ':');
13090 
13091    snprintf(full_addr, sizeof(full_addr), "%s:%s", args.addr, args.port);
13092 
13093    if (!ast_sockaddr_parse(&sa, full_addr, 0)) {
13094       return;
13095    }
13096 
13097    if (args.expiry_str) {
13098       expire = atoi(args.expiry_str);
13099    } else {
13100       return;
13101    }
13102 
13103    if (args.username) {
13104       ast_string_field_set(peer, username, args.username);
13105    }
13106    if (args.contact) {
13107       ast_string_field_set(peer, fullcontact, args.contact);
13108    }
13109 
13110    ast_debug(2, "SIP Seeding peer from astdb: '%s' at %s@%s for %d\n",
13111        peer->name, peer->username, ast_sockaddr_stringify_host(&sa), expire);
13112 
13113    ast_sockaddr_copy(&peer->addr, &sa);
13114    if (sipsock < 0) {
13115       /* SIP isn't up yet, so schedule a poke only, pretty soon */
13116       AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer,
13117             unref_peer(_data, "removing poke peer ref"),
13118             unref_peer(peer, "removing poke peer ref"),
13119             ref_peer(peer, "adding poke peer ref"));
13120    } else {
13121       sip_poke_peer(peer, 0);
13122    }
13123    AST_SCHED_REPLACE_UNREF(peer->expire, sched, (expire + 10) * 1000, expire_register, peer,
13124          unref_peer(_data, "remove registration ref"),
13125          unref_peer(peer, "remove registration ref"),
13126          ref_peer(peer, "add registration ref"));
13127    register_peer_exten(peer, TRUE);
13128 }

static void register_peer_exten ( struct sip_peer *  peer,
int  onoff 
) [static]

Automatically add peer extension to dial plan.

Definition at line 4412 of file chan_sip.c.

References ast_add_extension(), ast_context_find(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr, ast_log(), ast_strdup, ast_strlen_zero(), context, E_MATCH, ext, LOG_WARNING, pbx_find_extension(), S_OR, sip_cfg, pbx_find_info::stacklen, and strsep().

04413 {
04414    char multi[256];
04415    char *stringp, *ext, *context;
04416    struct pbx_find_info q = { .stacklen = 0 };
04417 
04418    /* XXX note that sip_cfg.regcontext is both a global 'enable' flag and
04419     * the name of the global regexten context, if not specified
04420     * individually.
04421     */
04422    if (ast_strlen_zero(sip_cfg.regcontext))
04423       return;
04424 
04425    ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
04426    stringp = multi;
04427    while ((ext = strsep(&stringp, "&"))) {
04428       if ((context = strchr(ext, '@'))) {
04429          *context++ = '\0';   /* split ext@context */
04430          if (!ast_context_find(context)) {
04431             ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context);
04432             continue;
04433          }
04434       } else {
04435          context = sip_cfg.regcontext;
04436       }
04437       if (onoff) {
04438          if (!ast_exists_extension(NULL, context, ext, 1, NULL)) {
04439             ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
04440                 ast_strdup(peer->name), ast_free_ptr, "SIP");
04441          }
04442       } else if (pbx_find_extension(NULL, NULL, &q, context, ext, 1, NULL, "", E_MATCH)) {
04443          ast_context_remove_extension(context, ext, 1, NULL);
04444       }
04445    }
04446 }

static enum check_auth_result register_verify ( struct sip_pvt *  p,
struct ast_sockaddr *  addr,
struct sip_request *  req,
const char *  uri 
) [static]

Verify registration of user

Todo:
XXX here too we interpret a missing as a name-only URI, whereas the RFC says this is a domain-only uri.

Definition at line 13998 of file chan_sip.c.

References ao2_lock, ao2_t_link, ao2_unlock, ast_apply_ha(), ast_copy_flags, ast_copy_string(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), AST_LIST_EMPTY, ast_log(), ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_contact(), check_auth(), check_request_transport, check_sip_domain(), dummy(), EVENT_FLAG_SYSTEM, exten, FALSE, find_peer(), get_header(), global_authfailureevents, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, name, parse_register_contact(), peers_by_ip, remove_uri_parameters(), sip_cancel_destroy(), sip_cfg, SIP_PEDANTIC_DECODE, strcasestr(), temp_peer(), terminate_uri(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), TRUE, unref_peer(), and update_peer().

14000 {
14001    enum check_auth_result res = AUTH_NOT_FOUND;
14002    struct sip_peer *peer;
14003    char tmp[256];
14004    char *name = NULL, *c, *domain = NULL, *dummy = NULL;
14005    char *uri2 = ast_strdupa(uri);
14006 
14007    terminate_uri(uri2);
14008 
14009    ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp));
14010 
14011    c = get_in_brackets(tmp);
14012    c = remove_uri_parameters(c);
14013 
14014    if (parse_uri(c, "sip:,sips:", &name, &dummy, &domain, NULL)) {
14015       ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_sockaddr_stringify_addr(addr));
14016       return -1;
14017    }
14018 
14019    SIP_PEDANTIC_DECODE(name);
14020    SIP_PEDANTIC_DECODE(domain);
14021 
14022    /*! \todo XXX here too we interpret a missing @domain as a name-only
14023     * URI, whereas the RFC says this is a domain-only uri.
14024     */
14025    if (!ast_strlen_zero(domain) && !AST_LIST_EMPTY(&domain_list)) {
14026       if (!check_sip_domain(domain, NULL, 0)) {
14027          transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
14028          return AUTH_UNKNOWN_DOMAIN;
14029       }
14030    }
14031 
14032    ast_string_field_set(p, exten, name);
14033    build_contact(p);
14034    if (req->ignore) {
14035       /* Expires is a special case, where we only want to load the peer if this isn't a deregistration attempt */
14036       const char *expires = get_header(req, "Expires");
14037       int expire = atoi(expires);
14038 
14039       if (ast_strlen_zero(expires)) { /* No expires header; look in Contact */
14040          if ((expires = strcasestr(get_header(req, "Contact"), ";expires="))) {
14041             expire = atoi(expires + 9);
14042          }
14043       }
14044       if (!ast_strlen_zero(expires) && expire == 0) {
14045          transmit_response_with_date(p, "200 OK", req);
14046          return 0;
14047       }
14048    }
14049    peer = find_peer(name, NULL, TRUE, FINDPEERS, FALSE, 0);
14050 
14051    if (!(peer && ast_apply_ha(peer->ha, addr))) {
14052       /* Peer fails ACL check */
14053       if (peer) {
14054          unref_peer(peer, "register_verify: unref_peer: from find_peer operation");
14055          peer = NULL;
14056          res = AUTH_ACL_FAILED;
14057       } else {
14058          res = AUTH_NOT_FOUND;
14059       }
14060    }
14061 
14062    if (peer) {
14063       ao2_lock(peer);
14064       if (!peer->host_dynamic) {
14065          ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
14066          res = AUTH_PEER_NOT_DYNAMIC;
14067       } else {
14068          ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT_FORCE_RPORT);
14069          if (ast_test_flag(&p->flags[1], SIP_PAGE2_REGISTERTRYING))
14070             transmit_response(p, "100 Trying", req);
14071          if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri2, XMIT_UNRELIABLE, req->ignore))) {
14072             if (sip_cancel_destroy(p))
14073                ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
14074 
14075             if (check_request_transport(peer, req)) {
14076                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
14077                transmit_response_with_date(p, "403 Forbidden", req);
14078                res = AUTH_BAD_TRANSPORT;
14079             } else {
14080 
14081                /* We have a successful registration attempt with proper authentication,
14082                   now, update the peer */
14083                switch (parse_register_contact(p, peer, req)) {
14084                case PARSE_REGISTER_DENIED:
14085                   ast_log(LOG_WARNING, "Registration denied because of contact ACL\n");
14086                   transmit_response_with_date(p, "603 Denied", req);
14087                   peer->lastmsgssent = -1;
14088                   res = 0;
14089                   break;
14090                case PARSE_REGISTER_FAILED:
14091                   ast_log(LOG_WARNING, "Failed to parse contact info\n");
14092                   transmit_response_with_date(p, "400 Bad Request", req);
14093                   peer->lastmsgssent = -1;
14094                   res = 0;
14095                   break;
14096                case PARSE_REGISTER_QUERY:
14097                   ast_string_field_set(p, fullcontact, peer->fullcontact);
14098                   transmit_response_with_date(p, "200 OK", req);
14099                   peer->lastmsgssent = -1;
14100                   res = 0;
14101                   break;
14102                case PARSE_REGISTER_UPDATE:
14103                   ast_string_field_set(p, fullcontact, peer->fullcontact);
14104                   update_peer(peer, p->expiry);
14105                   /* Say OK and ask subsystem to retransmit msg counter */
14106                   transmit_response_with_date(p, "200 OK", req);
14107                   if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY))
14108                      peer->lastmsgssent = -1;
14109                   res = 0;
14110                   break;
14111                }
14112             }
14113 
14114          }
14115       }
14116       ao2_unlock(peer);
14117    }
14118    if (!peer && sip_cfg.autocreatepeer) {
14119       /* Create peer if we have autocreate mode enabled */
14120       peer = temp_peer(name);
14121       if (peer) {
14122          ao2_t_link(peers, peer, "link peer into peer table");
14123          if (!ast_sockaddr_isnull(&peer->addr)) {
14124             ao2_t_link(peers_by_ip, peer, "link peer into peers-by-ip table");
14125          }
14126          ao2_lock(peer);
14127          if (sip_cancel_destroy(p))
14128             ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
14129          switch (parse_register_contact(p, peer, req)) {
14130          case PARSE_REGISTER_DENIED:
14131             ast_log(LOG_WARNING, "Registration denied because of contact ACL\n");
14132             transmit_response_with_date(p, "403 Forbidden (ACL)", req);
14133             peer->lastmsgssent = -1;
14134             res = 0;
14135             break;
14136          case PARSE_REGISTER_FAILED:
14137             ast_log(LOG_WARNING, "Failed to parse contact info\n");
14138             transmit_response_with_date(p, "400 Bad Request", req);
14139             peer->lastmsgssent = -1;
14140             res = 0;
14141             break;
14142          case PARSE_REGISTER_QUERY:
14143             ast_string_field_set(p, fullcontact, peer->fullcontact);
14144             transmit_response_with_date(p, "200 OK", req);
14145             peer->lastmsgssent = -1;
14146             res = 0;
14147             break;
14148          case PARSE_REGISTER_UPDATE:
14149             ast_string_field_set(p, fullcontact, peer->fullcontact);
14150             /* Say OK and ask subsystem to retransmit msg counter */
14151             transmit_response_with_date(p, "200 OK", req);
14152             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\n", peer->name, ast_sockaddr_stringify(addr));
14153             peer->lastmsgssent = -1;
14154             res = 0;
14155             break;
14156          }
14157          ao2_unlock(peer);
14158       }
14159    }
14160    if (!peer && sip_cfg.alwaysauthreject) {
14161       /* If we found a peer, we transmit a 100 Trying.  Therefore, if we're
14162        * trying to avoid leaking information, we MUST also transmit the same
14163        * response when we DON'T find a peer. */
14164       transmit_response(p, "100 Trying", req);
14165       /* Insert a fake delay between the 100 and the subsequent failure. */
14166       sched_yield();
14167    }
14168    if (!res) {
14169       ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
14170    }
14171    if (res < 0) {
14172       switch (res) {
14173       case AUTH_SECRET_FAILED:
14174          /* Wrong password in authentication. Go away, don't try again until you fixed it */
14175          transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
14176          if (global_authfailureevents) {
14177             const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
14178             const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
14179             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
14180                      "ChannelType: SIP\r\n"
14181                      "Peer: SIP/%s\r\n"
14182                      "PeerStatus: Rejected\r\n"
14183                      "Cause: AUTH_SECRET_FAILED\r\n"
14184                      "Address: %s\r\n"
14185                      "Port: %s\r\n",
14186                      name, peer_addr, peer_port);
14187          }
14188          break;
14189       case AUTH_USERNAME_MISMATCH:
14190          /* Username and digest username does not match.
14191             Asterisk uses the From: username for authentication. We need the
14192             devices to use the same authentication user name until we support
14193             proper authentication by digest auth name */
14194       case AUTH_NOT_FOUND:
14195       case AUTH_PEER_NOT_DYNAMIC:
14196       case AUTH_ACL_FAILED:
14197          if (sip_cfg.alwaysauthreject) {
14198             transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE);
14199             if (global_authfailureevents) {
14200                const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
14201                const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
14202                manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
14203                         "ChannelType: SIP\r\n"
14204                         "Peer: SIP/%s\r\n"
14205                         "PeerStatus: Rejected\r\n"
14206                         "Cause: %s\r\n"
14207                         "Address: %s\r\n"
14208                         "Port: %s\r\n",
14209                         name,
14210                         res == AUTH_PEER_NOT_DYNAMIC ? "AUTH_PEER_NOT_DYNAMIC" : "URI_NOT_FOUND",
14211                         peer_addr, peer_port);
14212             }
14213          } else {
14214             /* URI not found */
14215             if (res == AUTH_PEER_NOT_DYNAMIC) {
14216                transmit_response(p, "403 Forbidden", &p->initreq);
14217                if (global_authfailureevents) {
14218                   const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
14219                   const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
14220                   manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
14221                      "ChannelType: SIP\r\n"
14222                      "Peer: SIP/%s\r\n"
14223                      "PeerStatus: Rejected\r\n"
14224                      "Cause: AUTH_PEER_NOT_DYNAMIC\r\n"
14225                      "Address: %s\r\n"
14226                      "Port: %s\r\n",
14227                      name, peer_addr, peer_port);
14228                }
14229             } else {
14230                transmit_response(p, "404 Not found", &p->initreq);
14231                if (global_authfailureevents) {
14232                   const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
14233                   const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
14234                   manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
14235                      "ChannelType: SIP\r\n"
14236                      "Peer: SIP/%s\r\n"
14237                      "PeerStatus: Rejected\r\n"
14238                      "Cause: %s\r\n"
14239                      "Address: %s\r\n"
14240                      "Port: %s\r\n",
14241                      name,
14242                      (res == AUTH_USERNAME_MISMATCH) ? "AUTH_USERNAME_MISMATCH" : "URI_NOT_FOUND",
14243                      peer_addr, peer_port);
14244                }
14245             }
14246          }
14247          break;
14248       case AUTH_BAD_TRANSPORT:
14249       default:
14250          break;
14251       }
14252    }
14253    if (peer) {
14254       unref_peer(peer, "register_verify: unref_peer: tossing stack peer pointer at end of func");
14255    }
14256 
14257    return res;
14258 }

static struct sip_registry* registry_addref ( struct sip_registry *  reg,
char *  tag 
) [static]

Add object reference to SIP registry.

Definition at line 2948 of file chan_sip.c.

References ast_debug, and ASTOBJ_REF.

Referenced by handle_response_register(), sip_send_all_registers(), and transmit_register().

02949 {
02950    ast_debug(3, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount + 1);
02951    return ASTOBJ_REF(reg); /* Add pointer to registry in packet */
02952 }

void * registry_unref ( struct sip_registry *  reg,
char *  tag 
) [static]

Definition at line 2940 of file chan_sip.c.

References ast_debug, ASTOBJ_UNREF, and sip_registry_destroy().

Referenced by __sip_destroy(), dialog_unlink_all(), handle_response_register(), reload_config(), sip_reg_timeout(), sip_register(), sip_registry_destroy(), sip_reregister(), sip_send_all_registers(), and transmit_register().

02941 {
02942    ast_debug(3, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount - 1);
02943    ASTOBJ_UNREF(reg, sip_registry_destroy);
02944    return NULL;
02945 }

static const char * regstate2str ( enum sipregistrystate  regstate  )  const [static]

Convert registration state status to string.

Definition at line 12376 of file chan_sip.c.

References map_x_s(), and regstatestrings.

12377 {
12378    return map_x_s(regstatestrings, regstate, "Unknown");
12379 }

static int reload ( void   )  [static]

Part of Asterisk module interface.

Definition at line 28417 of file chan_sip.c.

References sip_reload().

28418 {
28419    if (sip_reload(0, 0, NULL))
28420       return 0;
28421    return 1;
28422 }

static int reload_config ( enum channelreloadreason  reason  )  [static]

Re-read SIP.conf config file.

Note:
This function reloads all config data, except for active peers (with registrations). They will only change configuration data at restart, not at reload. SIP debug and recordhistory state will not change

< Don't force proxy usage, use route: headers

< Reset default transport to zero here, default value later on

< Reset default primary transport to zero here, default value later on

< Keep track of hold status for a peer

< Match auth username if available instead of From: Default off.

< Default DTMF setting: RFC2833

< Allow re-invites

Definition at line 26698 of file chan_sip.c.

References ast_clear_flag, ast_config_destroy(), ast_config_load, ast_debug, ast_free_ha(), ast_log(), AST_MAX_CONTEXT, AST_SCHED_DEL_UNREF, ast_test_flag, ast_unload_realtime(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, authl, bindaddr, CHANNEL_MODULE_LOAD, clear_realm_authentication(), clear_sip_domains(), config, CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, context, default_tls_cfg, dialog_unlink_all(), dummy(), ast_tls_config::enabled, FALSE, global_flags, LOG_ERROR, LOG_NOTICE, registry_unref(), regl, sip_cfg, and TRUE.

26699 {
26700    struct ast_config *cfg, *ucfg;
26701    struct ast_variable *v;
26702    struct sip_peer *peer;
26703    char *cat, *stringp, *context, *oldregcontext;
26704    char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT];
26705    struct ast_flags dummy[2];
26706    struct ast_flags config_flags = { reason == CHANNEL_MODULE_LOAD ? 0 : ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? 0 : CONFIG_FLAG_FILEUNCHANGED };
26707    int auto_sip_domains = FALSE;
26708    struct ast_sockaddr old_bindaddr = bindaddr;
26709    int registry_count = 0, peer_count = 0, timerb_set = 0, timert1_set = 0;
26710    int subscribe_network_change = 1;
26711    time_t run_start, run_end;
26712    int bindport = 0;
26713 
26714    run_start = time(0);
26715    ast_unload_realtime("sipregs");
26716    ast_unload_realtime("sippeers");
26717    cfg = ast_config_load(config, config_flags);
26718 
26719    /* We *must* have a config file otherwise stop immediately */
26720    if (!cfg) {
26721       ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
26722       return -1;
26723    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
26724       ucfg = ast_config_load("users.conf", config_flags);
26725       if (ucfg == CONFIG_STATUS_FILEUNCHANGED) {
26726          return 1;
26727       } else if (ucfg == CONFIG_STATUS_FILEINVALID) {
26728          ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n");
26729          return 1;
26730       }
26731       /* Must reread both files, because one changed */
26732       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
26733       if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
26734          ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config);
26735          ast_config_destroy(ucfg);
26736          return 1;
26737       }
26738    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
26739       ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config);
26740       return 1;
26741    } else {
26742       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
26743       if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
26744          ast_log(LOG_ERROR, "Contents of users.conf are invalid and cannot be parsed\n");
26745          ast_config_destroy(cfg);
26746          return 1;
26747       }
26748    }
26749 
26750    ast_free_ha(sip_cfg.contact_ha);
26751    sip_cfg.contact_ha = NULL;
26752 
26753    default_tls_cfg.enabled = FALSE;    /* Default: Disable TLS */
26754 
26755    if (reason != CHANNEL_MODULE_LOAD) {
26756       ast_debug(4, "--------------- SIP reload started\n");
26757 
26758       clear_realm_authentication(authl);
26759       clear_sip_domains();
26760       authl = NULL;
26761 
26762       /* First, destroy all outstanding registry calls */
26763       /* This is needed, since otherwise active registry entries will not be destroyed */
26764       ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {  /* regl is locked */
26765 
26766             ASTOBJ_RDLOCK(iterator); /* now regl is locked, and the object is also locked */
26767             if (iterator->call) {
26768                ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
26769                /* This will also remove references to the registry */
26770                dialog_unlink_all(iterator->call, TRUE, TRUE);
26771                iterator->call = dialog_unref(iterator->call, "remove iterator->call from registry traversal");
26772             }
26773             if (iterator->expire > -1) {
26774                AST_SCHED_DEL_UNREF(sched, iterator->expire, registry_unref(iterator, "reg ptr unref from reload config"));
26775             }
26776             if (iterator->timeout > -1) {
26777                AST_SCHED_DEL_UNREF(sched, iterator->timeout, registry_unref(iterator, "reg ptr unref from reload config"));
26778             }
26779             ASTOBJ_UNLOCK(iterator);
26780       } while(0));
26781 
26782       /* Then, actually destroy users and registry */
26783       ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
26784       ast_debug(4, "--------------- Done destroying registry list\n");
26785       ao2_t_callback(peers, OBJ_NODATA, peer_markall_func, NULL, "callback to mark all peers");
26786    }
26787 
26788    /* Reset certificate handling for TLS sessions */
26789    if (reason != CHANNEL_MODULE_LOAD) {
26790       ast_free(default_tls_cfg.certfile);
26791       ast_free(default_tls_cfg.pvtfile);
26792       ast_free(default_tls_cfg.cipher);
26793       ast_free(default_tls_cfg.cafile);
26794       ast_free(default_tls_cfg.capath);
26795    }
26796    default_tls_cfg.certfile = ast_strdup(AST_CERTFILE); /*XXX Not sure if this is useful */
26797    default_tls_cfg.pvtfile = ast_strdup("");
26798    default_tls_cfg.cipher = ast_strdup("");
26799    default_tls_cfg.cafile = ast_strdup("");
26800    default_tls_cfg.capath = ast_strdup("");
26801 
26802    /* Initialize copy of current sip_cfg.regcontext for later use in removing stale contexts */
26803    ast_copy_string(oldcontexts, sip_cfg.regcontext, sizeof(oldcontexts));
26804    oldregcontext = oldcontexts;
26805 
26806    /* Clear all flags before setting default values */
26807    /* Preserve debugging settings for console */
26808    sipdebug &= sip_debug_console;
26809    ast_clear_flag(&global_flags[0], AST_FLAGS_ALL);
26810    ast_clear_flag(&global_flags[1], AST_FLAGS_ALL);
26811 
26812    /* Reset IP addresses  */
26813    ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0);
26814    memset(&internip, 0, sizeof(internip));
26815 
26816    /* Free memory for local network address mask */
26817    ast_free_ha(localaddr);
26818    memset(&localaddr, 0, sizeof(localaddr));
26819    memset(&externaddr, 0, sizeof(externaddr));
26820    memset(&media_address, 0, sizeof(media_address));
26821    memset(&default_prefs, 0 , sizeof(default_prefs));
26822    memset(&sip_cfg.outboundproxy, 0, sizeof(struct sip_proxy));
26823    sip_cfg.outboundproxy.force = FALSE;      /*!< Don't force proxy usage, use route: headers */
26824    default_transports = 0;          /*!< Reset default transport to zero here, default value later on */
26825    default_primary_transport = 0;         /*!< Reset default primary transport to zero here, default value later on */
26826    ourport_tcp = STANDARD_SIP_PORT;
26827    ourport_tls = STANDARD_TLS_PORT;
26828    externtcpport = STANDARD_SIP_PORT;
26829    externtlsport = STANDARD_TLS_PORT;
26830    sip_cfg.srvlookup = DEFAULT_SRVLOOKUP;
26831    global_tos_sip = DEFAULT_TOS_SIP;
26832    global_tos_audio = DEFAULT_TOS_AUDIO;
26833    global_tos_video = DEFAULT_TOS_VIDEO;
26834    global_tos_text = DEFAULT_TOS_TEXT;
26835    global_cos_sip = DEFAULT_COS_SIP;
26836    global_cos_audio = DEFAULT_COS_AUDIO;
26837    global_cos_video = DEFAULT_COS_VIDEO;
26838    global_cos_text = DEFAULT_COS_TEXT;
26839 
26840    externhost[0] = '\0';         /* External host name (for behind NAT DynDNS support) */
26841    externexpire = 0;       /* Expiration for DNS re-issuing */
26842    externrefresh = 10;
26843 
26844    /* Reset channel settings to default before re-configuring */
26845    sip_cfg.allow_external_domains = DEFAULT_ALLOW_EXT_DOM;           /* Allow external invites */
26846    sip_cfg.regcontext[0] = '\0';
26847    sip_cfg.capability = DEFAULT_CAPABILITY;
26848    sip_cfg.regextenonqualify = DEFAULT_REGEXTENONQUALIFY;
26849    sip_cfg.notifyringing = DEFAULT_NOTIFYRINGING;
26850    sip_cfg.notifycid = DEFAULT_NOTIFYCID;
26851    sip_cfg.notifyhold = FALSE;      /*!< Keep track of hold status for a peer */
26852    sip_cfg.directrtpsetup = FALSE;     /* Experimental feature, disabled by default */
26853    sip_cfg.alwaysauthreject = DEFAULT_ALWAYSAUTHREJECT;
26854    sip_cfg.auth_options_requests = DEFAULT_AUTH_OPTIONS;
26855    sip_cfg.allowsubscribe = FALSE;
26856    sip_cfg.disallowed_methods = SIP_UNKNOWN;
26857    sip_cfg.contact_ha = NULL;    /* Reset the contact ACL */
26858    snprintf(global_useragent, sizeof(global_useragent), "%s %s", DEFAULT_USERAGENT, ast_get_version());
26859    snprintf(global_sdpsession, sizeof(global_sdpsession), "%s %s", DEFAULT_SDPSESSION, ast_get_version());
26860    snprintf(global_sdpowner, sizeof(global_sdpowner), "%s", DEFAULT_SDPOWNER);
26861    global_prematuremediafilter = TRUE;
26862    ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime));
26863    ast_copy_string(sip_cfg.realm, S_OR(ast_config_AST_SYSTEM_NAME, DEFAULT_REALM), sizeof(sip_cfg.realm));
26864    sip_cfg.domainsasrealm = DEFAULT_DOMAINSASREALM;
26865    ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid));
26866    ast_copy_string(default_mwi_from, DEFAULT_MWI_FROM, sizeof(default_mwi_from));
26867    sip_cfg.compactheaders = DEFAULT_COMPACTHEADERS;
26868    global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
26869    global_regattempts_max = 0;
26870    sip_cfg.pedanticsipchecking = DEFAULT_PEDANTIC;
26871    sip_cfg.autocreatepeer = DEFAULT_AUTOCREATEPEER;
26872    global_autoframing = 0;
26873    sip_cfg.allowguest = DEFAULT_ALLOWGUEST;
26874    global_callcounter = DEFAULT_CALLCOUNTER;
26875    global_match_auth_username = FALSE;    /*!< Match auth username if available instead of From: Default off. */
26876    global_rtptimeout = 0;
26877    global_rtpholdtimeout = 0;
26878    global_rtpkeepalive = DEFAULT_RTPKEEPALIVE;
26879    sip_cfg.allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */
26880    sip_cfg.rtautoclear = 120;
26881    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE);   /* Default for all devices: TRUE */
26882    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP);     /* Default for all devices: TRUE */
26883    sip_cfg.peer_rtupdate = TRUE;
26884    global_dynamic_exclude_static = 0;  /* Exclude static peers */
26885    sip_cfg.tcp_enabled = FALSE;
26886 
26887    /* Session-Timers */
26888    global_st_mode = SESSION_TIMER_MODE_ACCEPT;
26889    global_st_refresher = SESSION_TIMER_REFRESHER_UAS;
26890    global_min_se  = DEFAULT_MIN_SE;
26891    global_max_se  = DEFAULT_MAX_SE;
26892 
26893    /* Peer poking settings */
26894    global_qualify_gap = DEFAULT_QUALIFY_GAP;
26895    global_qualify_peers = DEFAULT_QUALIFY_PEERS;
26896 
26897    /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for devices */
26898    ast_copy_string(sip_cfg.default_context, DEFAULT_CONTEXT, sizeof(sip_cfg.default_context));
26899    sip_cfg.default_subscribecontext[0] = '\0';
26900    sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS;
26901    default_language[0] = '\0';
26902    default_fromdomain[0] = '\0';
26903    default_fromdomainport = 0;
26904    default_qualify = DEFAULT_QUALIFY;
26905    default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
26906    ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret));
26907    ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest));
26908    ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten));
26909    ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833);        /*!< Default DTMF setting: RFC2833 */
26910    ast_set_flag(&global_flags[0], SIP_DIRECT_MEDIA);        /*!< Allow re-invites */
26911    ast_copy_string(default_engine, DEFAULT_ENGINE, sizeof(default_engine));
26912    ast_copy_string(default_parkinglot, DEFAULT_PARKINGLOT, sizeof(default_parkinglot));
26913 
26914    /* Debugging settings, always default to off */
26915    dumphistory = FALSE;
26916    recordhistory = FALSE;
26917    sipdebug &= ~sip_debug_config;
26918 
26919    /* Misc settings for the channel */
26920    global_relaxdtmf = FALSE;
26921    sip_cfg.callevents = DEFAULT_CALLEVENTS;
26922    global_authfailureevents = FALSE;
26923    global_t1 = DEFAULT_TIMER_T1;
26924    global_timer_b = 64 * DEFAULT_TIMER_T1;
26925    global_t1min = DEFAULT_T1MIN;
26926    global_qualifyfreq = DEFAULT_QUALIFYFREQ;
26927    global_t38_maxdatagram = -1;
26928    global_shrinkcallerid = 1;
26929    authlimit = DEFAULT_AUTHLIMIT;
26930    authtimeout = DEFAULT_AUTHTIMEOUT;
26931 
26932    sip_cfg.matchexternaddrlocally = DEFAULT_MATCHEXTERNADDRLOCALLY;
26933 
26934    /* Copy the default jb config over global_jbconf */
26935    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
26936 
26937    ast_clear_flag(&global_flags[1], SIP_PAGE2_FAX_DETECT);
26938    ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_VIDEOSUPPORT_ALWAYS);
26939    ast_clear_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT);
26940    ast_clear_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION);
26941 
26942 
26943    /* Read the [general] config section of sip.conf (or from realtime config) */
26944    for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
26945       if (handle_common_options(&global_flags[0], &dummy[0], v)) {
26946          continue;
26947       }
26948       if (handle_t38_options(&global_flags[0], &dummy[0], v, &global_t38_maxdatagram)) {
26949          continue;
26950       }
26951       /* handle jb conf */
26952       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
26953          continue;
26954 
26955       /* handle tls conf */
26956       if (!ast_tls_read_conf(&default_tls_cfg, &sip_tls_desc, v->name, v->value)) {
26957          continue;
26958       }
26959 
26960       if (!strcasecmp(v->name, "context")) {
26961          ast_copy_string(sip_cfg.default_context, v->value, sizeof(sip_cfg.default_context));
26962       } else if (!strcasecmp(v->name, "subscribecontext")) {
26963          ast_copy_string(sip_cfg.default_subscribecontext, v->value, sizeof(sip_cfg.default_subscribecontext));
26964       } else if (!strcasecmp(v->name, "callcounter")) {
26965          global_callcounter = ast_true(v->value) ? 1 : 0;
26966       } else if (!strcasecmp(v->name, "allowguest")) {
26967          sip_cfg.allowguest = ast_true(v->value) ? 1 : 0;
26968       } else if (!strcasecmp(v->name, "realm")) {
26969          ast_copy_string(sip_cfg.realm, v->value, sizeof(sip_cfg.realm));
26970       } else if (!strcasecmp(v->name, "domainsasrealm")) {
26971          sip_cfg.domainsasrealm = ast_true(v->value);
26972       } else if (!strcasecmp(v->name, "useragent")) {
26973          ast_copy_string(global_useragent, v->value, sizeof(global_useragent));
26974          ast_debug(1, "Setting SIP channel User-Agent Name to %s\n", global_useragent);
26975       } else if (!strcasecmp(v->name, "sdpsession")) {
26976          ast_copy_string(global_sdpsession, v->value, sizeof(global_sdpsession));
26977       } else if (!strcasecmp(v->name, "sdpowner")) {
26978          /* Field cannot contain spaces */
26979          if (!strstr(v->value, " ")) {
26980             ast_copy_string(global_sdpowner, v->value, sizeof(global_sdpowner));
26981          } else {
26982             ast_log(LOG_WARNING, "'%s' must not contain spaces at line %d.  Using default.\n", v->value, v->lineno);
26983          }
26984       } else if (!strcasecmp(v->name, "allowtransfer")) {
26985          sip_cfg.allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
26986       } else if (!strcasecmp(v->name, "rtcachefriends")) {
26987          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS);
26988       } else if (!strcasecmp(v->name, "rtsavesysname")) {
26989          sip_cfg.rtsave_sysname = ast_true(v->value);
26990       } else if (!strcasecmp(v->name, "rtupdate")) {
26991          sip_cfg.peer_rtupdate = ast_true(v->value);
26992       } else if (!strcasecmp(v->name, "ignoreregexpire")) {
26993          sip_cfg.ignore_regexpire = ast_true(v->value);
26994       } else if (!strcasecmp(v->name, "timert1")) {
26995          /* Defaults to 500ms, but RFC 3261 states that it is recommended
26996           * for the value to be set higher, though a lower value is only
26997           * allowed on private networks unconnected to the Internet. */
26998          global_t1 = atoi(v->value);
26999       } else if (!strcasecmp(v->name, "timerb")) {
27000          int tmp = atoi(v->value);
27001          if (tmp < 500) {
27002             global_timer_b = global_t1 * 64;
27003             ast_log(LOG_WARNING, "Invalid value for timerb ('%s').  Setting to default ('%d').\n", v->value, global_timer_b);
27004          }
27005          timerb_set = 1;
27006       } else if (!strcasecmp(v->name, "t1min")) {
27007          global_t1min = atoi(v->value);
27008       } else if (!strcasecmp(v->name, "transport") && !ast_strlen_zero(v->value)) {
27009          char *val = ast_strdupa(v->value);
27010          char *trans;
27011 
27012          while ((trans = strsep(&val, ","))) {
27013             trans = ast_skip_blanks(trans);
27014 
27015             if (!strncasecmp(trans, "udp", 3)) {
27016                default_transports |= SIP_TRANSPORT_UDP;
27017             } else if (!strncasecmp(trans, "tcp", 3)) {
27018                default_transports |= SIP_TRANSPORT_TCP;
27019             } else if (!strncasecmp(trans, "tls", 3)) {
27020                default_transports |= SIP_TRANSPORT_TLS;
27021             } else {
27022                ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, udp will be used.\n", trans);
27023             }
27024             if (default_primary_transport == 0) {
27025                default_primary_transport = default_transports;
27026             }
27027          }
27028       } else if (!strcasecmp(v->name, "tcpenable")) {
27029          if (!ast_false(v->value)) {
27030             ast_debug(2, "Enabling TCP socket for listening\n");
27031             sip_cfg.tcp_enabled = TRUE;
27032          }
27033       } else if (!strcasecmp(v->name, "tcpbindaddr")) {
27034          if (ast_parse_arg(v->value, PARSE_ADDR,
27035                  &sip_tcp_desc.local_address)) {
27036             ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n",
27037                v->name, v->value, v->lineno, config);
27038          }
27039          ast_debug(2, "Setting TCP socket address to %s\n",
27040               ast_sockaddr_stringify(&sip_tcp_desc.local_address));
27041       } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) {
27042          global_dynamic_exclude_static = ast_true(v->value);
27043       } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) {
27044          int ha_error = 0;
27045          sip_cfg.contact_ha = ast_append_ha(v->name + 7, v->value, sip_cfg.contact_ha, &ha_error);
27046          if (ha_error) {
27047             ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
27048          }
27049       } else if (!strcasecmp(v->name, "rtautoclear")) {
27050          int i = atoi(v->value);
27051          if (i > 0) {
27052             sip_cfg.rtautoclear = i;
27053          } else {
27054             i = 0;
27055          }
27056          ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR);
27057       } else if (!strcasecmp(v->name, "usereqphone")) {
27058          ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE);
27059       } else if (!strcasecmp(v->name, "prematuremedia")) {
27060          global_prematuremediafilter = ast_true(v->value);
27061       } else if (!strcasecmp(v->name, "relaxdtmf")) {
27062          global_relaxdtmf = ast_true(v->value);
27063       } else if (!strcasecmp(v->name, "vmexten")) {
27064          ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten));
27065       } else if (!strcasecmp(v->name, "rtptimeout")) {
27066          if ((sscanf(v->value, "%30d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) {
27067             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
27068             global_rtptimeout = 0;
27069          }
27070       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
27071          if ((sscanf(v->value, "%30d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) {
27072             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
27073             global_rtpholdtimeout = 0;
27074          }
27075       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
27076          if ((sscanf(v->value, "%30d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) {
27077             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
27078             global_rtpkeepalive = DEFAULT_RTPKEEPALIVE;
27079          }
27080       } else if (!strcasecmp(v->name, "compactheaders")) {
27081          sip_cfg.compactheaders = ast_true(v->value);
27082       } else if (!strcasecmp(v->name, "notifymimetype")) {
27083          ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
27084       } else if (!strcasecmp(v->name, "directrtpsetup")) {
27085          sip_cfg.directrtpsetup = ast_true(v->value);
27086       } else if (!strcasecmp(v->name, "notifyringing")) {
27087          sip_cfg.notifyringing = ast_true(v->value);
27088       } else if (!strcasecmp(v->name, "notifyhold")) {
27089          sip_cfg.notifyhold = ast_true(v->value);
27090       } else if (!strcasecmp(v->name, "notifycid")) {
27091          if (!strcasecmp(v->value, "ignore-context")) {
27092             sip_cfg.notifycid = IGNORE_CONTEXT;
27093          } else {
27094             sip_cfg.notifycid = ast_true(v->value);
27095          }
27096       } else if (!strcasecmp(v->name, "alwaysauthreject")) {
27097          sip_cfg.alwaysauthreject = ast_true(v->value);
27098       } else if (!strcasecmp(v->name, "auth_options_requests")) {
27099          if (ast_true(v->value)) {
27100             sip_cfg.auth_options_requests = 1;
27101          }
27102       } else if (!strcasecmp(v->name, "mohinterpret")) {
27103          ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret));
27104       } else if (!strcasecmp(v->name, "mohsuggest")) {
27105          ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest));
27106       } else if (!strcasecmp(v->name, "language")) {
27107          ast_copy_string(default_language, v->value, sizeof(default_language));
27108       } else if (!strcasecmp(v->name, "regcontext")) {
27109          ast_copy_string(newcontexts, v->value, sizeof(newcontexts));
27110          stringp = newcontexts;
27111          /* Let's remove any contexts that are no longer defined in regcontext */
27112          cleanup_stale_contexts(stringp, oldregcontext);
27113          /* Create contexts if they don't exist already */
27114          while ((context = strsep(&stringp, "&"))) {
27115             ast_copy_string(used_context, context, sizeof(used_context));
27116             ast_context_find_or_create(NULL, NULL, context, "SIP");
27117          }
27118          ast_copy_string(sip_cfg.regcontext, v->value, sizeof(sip_cfg.regcontext));
27119       } else if (!strcasecmp(v->name, "regextenonqualify")) {
27120          sip_cfg.regextenonqualify = ast_true(v->value);
27121       } else if (!strcasecmp(v->name, "callerid")) {
27122          ast_copy_string(default_callerid, v->value, sizeof(default_callerid));
27123       } else if (!strcasecmp(v->name, "mwi_from")) {
27124          ast_copy_string(default_mwi_from, v->value, sizeof(default_mwi_from));
27125       } else if (!strcasecmp(v->name, "fromdomain")) {
27126          char *fromdomainport;
27127          ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain));
27128          if ((fromdomainport = strchr(default_fromdomain, ':'))) {
27129             *fromdomainport++ = '\0';
27130             if (!(default_fromdomainport = port_str2int(fromdomainport, 0))) {
27131                ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport);
27132             }
27133          } else {
27134             default_fromdomainport = STANDARD_SIP_PORT;
27135          }
27136       } else if (!strcasecmp(v->name, "outboundproxy")) {
27137          char *tok, *proxyname;
27138 
27139          if (ast_strlen_zero(v->value)) {
27140             ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf.", v->lineno);
27141             continue;
27142          }
27143 
27144          tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ","));
27145 
27146          sip_parse_host(tok, v->lineno, &proxyname,
27147                    &sip_cfg.outboundproxy.port,
27148                    &sip_cfg.outboundproxy.transport);
27149 
27150          if ((tok = strtok(NULL, ","))) {
27151             sip_cfg.outboundproxy.force = !strncasecmp(ast_skip_blanks(tok), "force", 5);
27152          } else {
27153             sip_cfg.outboundproxy.force = FALSE;
27154          }
27155 
27156          if (ast_strlen_zero(proxyname)) {
27157             ast_log(LOG_WARNING, "you must specify a name for the outboundproxy on line %d of sip.conf.", v->lineno);
27158             sip_cfg.outboundproxy.name[0] = '\0';
27159             continue;
27160          }
27161 
27162          ast_copy_string(sip_cfg.outboundproxy.name, proxyname, sizeof(sip_cfg.outboundproxy.name));
27163 
27164          proxy_update(&sip_cfg.outboundproxy);
27165       } else if (!strcasecmp(v->name, "autocreatepeer")) {
27166          sip_cfg.autocreatepeer = ast_true(v->value);
27167       } else if (!strcasecmp(v->name, "match_auth_username")) {
27168          global_match_auth_username = ast_true(v->value);
27169       } else if (!strcasecmp(v->name, "srvlookup")) {
27170          sip_cfg.srvlookup = ast_true(v->value);
27171       } else if (!strcasecmp(v->name, "pedantic")) {
27172          sip_cfg.pedanticsipchecking = ast_true(v->value);
27173       } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) {
27174          max_expiry = atoi(v->value);
27175          if (max_expiry < 1) {
27176             max_expiry = DEFAULT_MAX_EXPIRY;
27177          }
27178       } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) {
27179          min_expiry = atoi(v->value);
27180          if (min_expiry < 1) {
27181             min_expiry = DEFAULT_MIN_EXPIRY;
27182          }
27183       } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) {
27184          default_expiry = atoi(v->value);
27185          if (default_expiry < 1) {
27186             default_expiry = DEFAULT_DEFAULT_EXPIRY;
27187          }
27188       } else if (!strcasecmp(v->name, "mwiexpiry") || !strcasecmp(v->name, "mwiexpirey")) {
27189          mwi_expiry = atoi(v->value);
27190          if (mwi_expiry < 1) {
27191             mwi_expiry = DEFAULT_MWI_EXPIRY;
27192          }
27193       } else if (!strcasecmp(v->name, "tcpauthtimeout")) {
27194          if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE,
27195                  &authtimeout, DEFAULT_AUTHTIMEOUT, 1, INT_MAX)) {
27196             ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n",
27197                v->name, v->value, v->lineno, config);
27198          }
27199       } else if (!strcasecmp(v->name, "tcpauthlimit")) {
27200          if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE,
27201                  &authlimit, DEFAULT_AUTHLIMIT, 1, INT_MAX)) {
27202             ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n",
27203                v->name, v->value, v->lineno, config);
27204          }
27205       } else if (!strcasecmp(v->name, "sipdebug")) {
27206          if (ast_true(v->value))
27207             sipdebug |= sip_debug_config;
27208       } else if (!strcasecmp(v->name, "dumphistory")) {
27209          dumphistory = ast_true(v->value);
27210       } else if (!strcasecmp(v->name, "recordhistory")) {
27211          recordhistory = ast_true(v->value);
27212       } else if (!strcasecmp(v->name, "registertimeout")) {
27213          global_reg_timeout = atoi(v->value);
27214          if (global_reg_timeout < 1) {
27215             global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
27216          }
27217       } else if (!strcasecmp(v->name, "registerattempts")) {
27218          global_regattempts_max = atoi(v->value);
27219       } else if (!strcasecmp(v->name, "bindaddr") || !strcasecmp(v->name, "udpbindaddr")) {
27220          if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) {
27221             ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
27222          }
27223       } else if (!strcasecmp(v->name, "localnet")) {
27224          struct ast_ha *na;
27225          int ha_error = 0;
27226 
27227          if (!(na = ast_append_ha("d", v->value, localaddr, &ha_error))) {
27228             ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value);
27229          } else {
27230             localaddr = na;
27231          }
27232          if (ha_error) {
27233             ast_log(LOG_ERROR, "Bad localnet configuration value line %d : %s\n", v->lineno, v->value);
27234          }
27235       } else if (!strcasecmp(v->name, "media_address")) {
27236          if (ast_parse_arg(v->value, PARSE_ADDR, &media_address))
27237             ast_log(LOG_WARNING, "Invalid address for media_address keyword: %s\n", v->value);
27238       } else if (!strcasecmp(v->name, "externaddr") || !strcasecmp(v->name, "externip")) {
27239          if (ast_parse_arg(v->value, PARSE_ADDR, &externaddr)) {
27240             ast_log(LOG_WARNING,
27241                "Invalid address for externaddr keyword: %s\n",
27242                v->value);
27243          }
27244          externexpire = 0;
27245       } else if (!strcasecmp(v->name, "externhost")) {
27246          ast_copy_string(externhost, v->value, sizeof(externhost));
27247          if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) {
27248             ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost);
27249          }
27250          externexpire = time(NULL);
27251       } else if (!strcasecmp(v->name, "externrefresh")) {
27252          if (sscanf(v->value, "%30d", &externrefresh) != 1) {
27253             ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno);
27254             externrefresh = 10;
27255          }
27256       } else if (!strcasecmp(v->name, "externtcpport")) {
27257          if (!(externtcpport = port_str2int(v->value, 0))) {
27258             ast_log(LOG_WARNING, "Invalid externtcpport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno);
27259             externtcpport = 0;
27260          }
27261       } else if (!strcasecmp(v->name, "externtlsport")) {
27262          if (!(externtlsport = port_str2int(v->value, STANDARD_TLS_PORT))) {
27263             ast_log(LOG_WARNING, "Invalid externtlsport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno);
27264          }
27265       } else if (!strcasecmp(v->name, "allow")) {
27266          int error =  ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, TRUE);
27267          if (error) {
27268             ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
27269          }
27270       } else if (!strcasecmp(v->name, "disallow")) {
27271          int error =  ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, FALSE);
27272          if (error) {
27273             ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
27274          }
27275       } else if (!strcasecmp(v->name, "preferred_codec_only")) {
27276          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_PREFERRED_CODEC);
27277       } else if (!strcasecmp(v->name, "autoframing")) {
27278          global_autoframing = ast_true(v->value);
27279       } else if (!strcasecmp(v->name, "allowexternaldomains")) {
27280          sip_cfg.allow_external_domains = ast_true(v->value);
27281       } else if (!strcasecmp(v->name, "autodomain")) {
27282          auto_sip_domains = ast_true(v->value);
27283       } else if (!strcasecmp(v->name, "domain")) {
27284          char *domain = ast_strdupa(v->value);
27285          char *cntx = strchr(domain, ',');
27286 
27287          if (cntx) {
27288             *cntx++ = '\0';
27289          }
27290 
27291          if (ast_strlen_zero(cntx)) {
27292             ast_debug(1, "No context specified at line %d for domain '%s'\n", v->lineno, domain);
27293          }
27294          if (ast_strlen_zero(domain)) {
27295             ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno);
27296          } else {
27297             add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, cntx ? ast_strip(cntx) : "");
27298          }
27299       } else if (!strcasecmp(v->name, "register")) {
27300          if (sip_register(v->value, v->lineno) == 0) {
27301             registry_count++;
27302          }
27303       } else if (!strcasecmp(v->name, "mwi")) {
27304          sip_subscribe_mwi(v->value, v->lineno);
27305       } else if (!strcasecmp(v->name, "tos_sip")) {
27306          if (ast_str2tos(v->value, &global_tos_sip)) {
27307             ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, refer to QoS documentation\n", v->lineno);
27308          }
27309       } else if (!strcasecmp(v->name, "tos_audio")) {
27310          if (ast_str2tos(v->value, &global_tos_audio)) {
27311             ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
27312          }
27313       } else if (!strcasecmp(v->name, "tos_video")) {
27314          if (ast_str2tos(v->value, &global_tos_video)) {
27315             ast_log(LOG_WARNING, "Invalid tos_video value at line %d, refer to QoS documentation\n", v->lineno);
27316          }
27317       } else if (!strcasecmp(v->name, "tos_text")) {
27318          if (ast_str2tos(v->value, &global_tos_text)) {
27319             ast_log(LOG_WARNING, "Invalid tos_text value at line %d, refer to QoS documentation\n", v->lineno);
27320          }
27321       } else if (!strcasecmp(v->name, "cos_sip")) {
27322          if (ast_str2cos(v->value, &global_cos_sip)) {
27323             ast_log(LOG_WARNING, "Invalid cos_sip value at line %d, refer to QoS documentation\n", v->lineno);
27324          }
27325       } else if (!strcasecmp(v->name, "cos_audio")) {
27326          if (ast_str2cos(v->value, &global_cos_audio)) {
27327             ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
27328          }
27329       } else if (!strcasecmp(v->name, "cos_video")) {
27330          if (ast_str2cos(v->value, &global_cos_video)) {
27331             ast_log(LOG_WARNING, "Invalid cos_video value at line %d, refer to QoS documentation\n", v->lineno);
27332          }
27333       } else if (!strcasecmp(v->name, "cos_text")) {
27334          if (ast_str2cos(v->value, &global_cos_text)) {
27335             ast_log(LOG_WARNING, "Invalid cos_text value at line %d, refer to QoS documentation\n", v->lineno);
27336          }
27337       } else if (!strcasecmp(v->name, "bindport")) {
27338          if (sscanf(v->value, "%5d", &bindport) != 1) {
27339             ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
27340          }
27341       } else if (!strcasecmp(v->name, "qualify")) {
27342          if (!strcasecmp(v->value, "no")) {
27343             default_qualify = 0;
27344          } else if (!strcasecmp(v->value, "yes")) {
27345             default_qualify = DEFAULT_MAXMS;
27346          } else if (sscanf(v->value, "%30d", &default_qualify) != 1) {
27347             ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno);
27348             default_qualify = 0;
27349          }
27350       } else if (!strcasecmp(v->name, "qualifyfreq")) {
27351          int i;
27352          if (sscanf(v->value, "%30d", &i) == 1) {
27353             global_qualifyfreq = i * 1000;
27354          } else {
27355             ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config);
27356             global_qualifyfreq = DEFAULT_QUALIFYFREQ;
27357          }
27358       } else if (!strcasecmp(v->name, "callevents")) {
27359          sip_cfg.callevents = ast_true(v->value);
27360       } else if (!strcasecmp(v->name, "authfailureevents")) {
27361          global_authfailureevents = ast_true(v->value);
27362       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
27363          default_maxcallbitrate = atoi(v->value);
27364          if (default_maxcallbitrate < 0)
27365             default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
27366       } else if (!strcasecmp(v->name, "matchexternaddrlocally") || !strcasecmp(v->name, "matchexterniplocally")) {
27367          sip_cfg.matchexternaddrlocally = ast_true(v->value);
27368       } else if (!strcasecmp(v->name, "session-timers")) {
27369          int i = (int) str2stmode(v->value);
27370          if (i < 0) {
27371             ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config);
27372             global_st_mode = SESSION_TIMER_MODE_ACCEPT;
27373          } else {
27374             global_st_mode = i;
27375          }
27376       } else if (!strcasecmp(v->name, "session-expires")) {
27377          if (sscanf(v->value, "%30d", &global_max_se) != 1) {
27378             ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config);
27379             global_max_se = DEFAULT_MAX_SE;
27380          }
27381       } else if (!strcasecmp(v->name, "session-minse")) {
27382          if (sscanf(v->value, "%30d", &global_min_se) != 1) {
27383             ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config);
27384             global_min_se = DEFAULT_MIN_SE;
27385          }
27386          if (global_min_se < 90) {
27387             ast_log(LOG_WARNING, "session-minse '%s' at line %d of %s is not allowed to be < 90 secs\n", v->value, v->lineno, config);
27388             global_min_se = DEFAULT_MIN_SE;
27389          }
27390       } else if (!strcasecmp(v->name, "session-refresher")) {
27391          int i = (int) str2strefresher(v->value);
27392          if (i < 0) {
27393             ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config);
27394             global_st_refresher = SESSION_TIMER_REFRESHER_UAS;
27395          } else {
27396             global_st_refresher = i;
27397          }
27398       } else if (!strcasecmp(v->name, "qualifygap")) {
27399          if (sscanf(v->value, "%30d", &global_qualify_gap) != 1) {
27400             ast_log(LOG_WARNING, "Invalid qualifygap '%s' at line %d of %s\n", v->value, v->lineno, config);
27401             global_qualify_gap = DEFAULT_QUALIFY_GAP;
27402          }
27403       } else if (!strcasecmp(v->name, "qualifypeers")) {
27404          if (sscanf(v->value, "%30d", &global_qualify_peers) != 1) {
27405             ast_log(LOG_WARNING, "Invalid pokepeers '%s' at line %d of %s\n", v->value, v->lineno, config);
27406             global_qualify_peers = DEFAULT_QUALIFY_PEERS;
27407          }
27408       } else if (!strcasecmp(v->name, "disallowed_methods")) {
27409          char *disallow = ast_strdupa(v->value);
27410          mark_parsed_methods(&sip_cfg.disallowed_methods, disallow);
27411       } else if (!strcasecmp(v->name, "shrinkcallerid")) {
27412          if (ast_true(v->value)) {
27413             global_shrinkcallerid = 1;
27414          } else if (ast_false(v->value)) {
27415             global_shrinkcallerid = 0;
27416          } else {
27417             ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
27418          }
27419       } else if (!strcasecmp(v->name, "use_q850_reason")) {
27420          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON);
27421       } else if (!strcasecmp(v->name, "maxforwards")) {
27422          if ((sscanf(v->value, "%30d", &sip_cfg.default_max_forwards) != 1) || (sip_cfg.default_max_forwards < 1)) {
27423             ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d.  Using default.\n", v->value, v->lineno);
27424             sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS;
27425          }
27426       } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
27427          if (ast_true(v->value)) {
27428             subscribe_network_change = 1;
27429          } else if (ast_false(v->value)) {
27430             subscribe_network_change = 0;
27431          } else {
27432             ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
27433          }
27434       } else if (!strcasecmp(v->name, "snom_aoc_enabled")) {
27435          ast_set2_flag(&global_flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC);
27436       } else if (!strcasecmp(v->name, "parkinglot")) {
27437          ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
27438       }
27439    }
27440 
27441    if (subscribe_network_change) {
27442       network_change_event_subscribe();
27443    } else {
27444       network_change_event_unsubscribe();
27445    }
27446 
27447    if (global_t1 < global_t1min) {
27448       ast_log(LOG_WARNING, "'t1min' (%d) cannot be greater than 't1timer' (%d).  Resetting 't1timer' to the value of 't1min'\n", global_t1min, global_t1);
27449       global_t1 = global_t1min;
27450    }
27451 
27452    if (global_timer_b < global_t1 * 64) {
27453       if (timerb_set && timert1_set) {
27454          ast_log(LOG_WARNING, "Timer B has been set lower than recommended (%d < 64 * timert1=%d). (RFC 3261, 17.1.1.2)\n", global_timer_b, global_t1);
27455       } else if (timerb_set) {
27456          if ((global_t1 = global_timer_b / 64) < global_t1min) {
27457             ast_log(LOG_WARNING, "Timer B has been set lower than recommended (%d < 64 * timert1=%d). (RFC 3261, 17.1.1.2)\n", global_timer_b, global_t1);
27458             global_t1 = global_t1min;
27459             global_timer_b = global_t1 * 64;
27460          }
27461       } else {
27462          global_timer_b = global_t1 * 64;
27463       }
27464    }
27465    if (!sip_cfg.allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
27466       ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
27467       sip_cfg.allow_external_domains = 1;
27468    }
27469    /* If not configured, set default transports */
27470    if (default_transports == 0) {
27471       default_transports = default_primary_transport = SIP_TRANSPORT_UDP;
27472    }
27473 
27474    /* Build list of authentication to various SIP realms, i.e. service providers */
27475    for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) {
27476       /* Format for authentication is auth = username:password@realm */
27477       if (!strcasecmp(v->name, "auth")) {
27478          authl = add_realm_authentication(authl, v->value, v->lineno);
27479       }
27480    }
27481 
27482    if (bindport) {
27483       if (ast_sockaddr_port(&bindaddr)) {
27484          ast_log(LOG_WARNING, "bindport is also specified in bindaddr. "
27485             "Using %d.\n", bindport);
27486       }
27487       ast_sockaddr_set_port(&bindaddr, bindport);
27488    }
27489 
27490    if (!ast_sockaddr_port(&bindaddr)) {
27491       ast_sockaddr_set_port(&bindaddr, STANDARD_SIP_PORT);
27492    }
27493 
27494    /* Set UDP address and open socket */
27495    ast_sockaddr_copy(&internip, &bindaddr);
27496    if (ast_find_ourip(&internip, &bindaddr, 0)) {
27497       ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
27498       ast_config_destroy(cfg);
27499       return 0;
27500    }
27501 
27502    ast_mutex_lock(&netlock);
27503    if ((sipsock > -1) && (ast_sockaddr_cmp(&old_bindaddr, &bindaddr))) {
27504       close(sipsock);
27505       sipsock = -1;
27506    }
27507    if (sipsock < 0) {
27508       sipsock = socket(ast_sockaddr_is_ipv6(&bindaddr) ?
27509              AF_INET6 : AF_INET, SOCK_DGRAM, 0);
27510       if (sipsock < 0) {
27511          ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
27512          ast_config_destroy(cfg);
27513          ast_mutex_unlock(&netlock);
27514          return -1;
27515       } else {
27516          /* Allow SIP clients on the same host to access us: */
27517          const int reuseFlag = 1;
27518 
27519          setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR,
27520                (const char*)&reuseFlag,
27521                sizeof reuseFlag);
27522 
27523          ast_enable_packet_fragmentation(sipsock);
27524 
27525          if (ast_bind(sipsock, &bindaddr) < 0) {
27526             ast_log(LOG_WARNING, "Failed to bind to %s: %s\n",
27527                ast_sockaddr_stringify(&bindaddr), strerror(errno));
27528             close(sipsock);
27529             sipsock = -1;
27530          } else {
27531             ast_verb(2, "SIP Listening on %s\n", ast_sockaddr_stringify(&bindaddr));
27532             ast_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP");
27533          }
27534       }
27535    } else {
27536       ast_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP");
27537    }
27538    ast_mutex_unlock(&netlock);
27539 
27540    /* Start TCP server */
27541    if (sip_cfg.tcp_enabled) {
27542       if (ast_sockaddr_isnull(&sip_tcp_desc.local_address)) {
27543          ast_sockaddr_copy(&sip_tcp_desc.local_address, &bindaddr);
27544       }
27545       if (!ast_sockaddr_port(&sip_tcp_desc.local_address)) {
27546          ast_sockaddr_set_port(&sip_tcp_desc.local_address, STANDARD_SIP_PORT);
27547       }
27548    } else {
27549       ast_sockaddr_setnull(&sip_tcp_desc.local_address);
27550    }
27551    ast_tcptls_server_start(&sip_tcp_desc);
27552    if (sip_cfg.tcp_enabled && sip_tcp_desc.accept_fd == -1) {
27553       /* TCP server start failed. Tell the admin */
27554       ast_log(LOG_ERROR, "SIP TCP Server start failed. Not listening on TCP socket.\n");
27555    } else {
27556       ast_debug(2, "SIP TCP server started\n");
27557    }
27558 
27559    /* Start TLS server if needed */
27560    memcpy(sip_tls_desc.tls_cfg, &default_tls_cfg, sizeof(default_tls_cfg));
27561 
27562    if (ast_ssl_setup(sip_tls_desc.tls_cfg)) {
27563       if (ast_sockaddr_isnull(&sip_tls_desc.local_address)) {
27564          ast_sockaddr_copy(&sip_tls_desc.local_address, &bindaddr);
27565          ast_sockaddr_set_port(&sip_tls_desc.local_address,
27566                      STANDARD_TLS_PORT);
27567       }
27568       if (!ast_sockaddr_port(&sip_tls_desc.local_address)) {
27569          ast_sockaddr_set_port(&sip_tls_desc.local_address,
27570                      STANDARD_TLS_PORT);
27571       }
27572       ast_tcptls_server_start(&sip_tls_desc);
27573       if (default_tls_cfg.enabled && sip_tls_desc.accept_fd == -1) {
27574          ast_log(LOG_ERROR, "TLS Server start failed. Not listening on TLS socket.\n");
27575          sip_tls_desc.tls_cfg = NULL;
27576       }
27577    } else if (sip_tls_desc.tls_cfg->enabled) {
27578       sip_tls_desc.tls_cfg = NULL;
27579       ast_log(LOG_WARNING, "SIP TLS server did not load because of errors.\n");
27580    }
27581 
27582    if (ucfg) {
27583       struct ast_variable *gen;
27584       int genhassip, genregistersip;
27585       const char *hassip, *registersip;
27586       
27587       genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip"));
27588       genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip"));
27589       gen = ast_variable_browse(ucfg, "general");
27590       cat = ast_category_browse(ucfg, NULL);
27591       while (cat) {
27592          if (strcasecmp(cat, "general")) {
27593             hassip = ast_variable_retrieve(ucfg, cat, "hassip");
27594             registersip = ast_variable_retrieve(ucfg, cat, "registersip");
27595             if (ast_true(hassip) || (!hassip && genhassip)) {
27596                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, 0);
27597                if (peer) {
27598                   /* user.conf entries are always of type friend */
27599                   peer->type = SIP_TYPE_USER | SIP_TYPE_PEER;
27600                   ao2_t_link(peers, peer, "link peer into peer table");
27601                   if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) {
27602                      ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
27603                   }
27604                   
27605                   unref_peer(peer, "unref_peer: from reload_config");
27606                   peer_count++;
27607                }
27608             }
27609             if (ast_true(registersip) || (!registersip && genregistersip)) {
27610                char tmp[256];
27611                const char *host = ast_variable_retrieve(ucfg, cat, "host");
27612                const char *username = ast_variable_retrieve(ucfg, cat, "username");
27613                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
27614                const char *contact = ast_variable_retrieve(ucfg, cat, "contact");
27615                const char *authuser = ast_variable_retrieve(ucfg, cat, "authuser");
27616                if (!host) {
27617                   host = ast_variable_retrieve(ucfg, "general", "host");
27618                }
27619                if (!username) {
27620                   username = ast_variable_retrieve(ucfg, "general", "username");
27621                }
27622                if (!secret) {
27623                   secret = ast_variable_retrieve(ucfg, "general", "secret");
27624                }
27625                if (!contact) {
27626                   contact = "s";
27627                }
27628                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
27629                   if (!ast_strlen_zero(secret)) {
27630                      if (!ast_strlen_zero(authuser)) {
27631                         snprintf(tmp, sizeof(tmp), "%s?%s:%s:%s@%s/%s", cat, username, secret, authuser, host, contact);
27632                      } else {
27633                         snprintf(tmp, sizeof(tmp), "%s?%s:%s@%s/%s", cat, username, secret, host, contact);
27634                      }
27635                   } else if (!ast_strlen_zero(authuser)) {
27636                      snprintf(tmp, sizeof(tmp), "%s?%s::%s@%s/%s", cat, username, authuser, host, contact);
27637                   } else {
27638                      snprintf(tmp, sizeof(tmp), "%s?%s@%s/%s", cat, username, host, contact);
27639                   }
27640                   if (sip_register(tmp, 0) == 0) {
27641                      registry_count++;
27642                   }
27643                }
27644             }
27645          }
27646          cat = ast_category_browse(ucfg, cat);
27647       }
27648       ast_config_destroy(ucfg);
27649    }
27650 
27651    /* Load peers, users and friends */
27652    cat = NULL;
27653    while ( (cat = ast_category_browse(cfg, cat)) ) {
27654       const char *utype;
27655       if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication"))
27656          continue;
27657       utype = ast_variable_retrieve(cfg, cat, "type");
27658       if (!utype) {
27659          ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
27660          continue;
27661       } else {
27662          if (!strcasecmp(utype, "user")) {
27663             ;
27664          } else if (!strcasecmp(utype, "friend")) {
27665             ;
27666          } else if (!strcasecmp(utype, "peer")) {
27667             ;
27668          } else {
27669             ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
27670             continue;
27671          }
27672          peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0);
27673          if (peer) {
27674             ao2_t_link(peers, peer, "link peer into peers table");
27675             if ((peer->type & SIP_TYPE_PEER) && !ast_sockaddr_isnull(&peer->addr)) {
27676                ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
27677             }
27678             unref_peer(peer, "unref the result of the build_peer call. Now, the links from the tables are the only ones left.");
27679             peer_count++;
27680          }
27681       }
27682    }
27683 
27684    /* Add default domains - host name, IP address and IP:port
27685     * Only do this if user added any sip domain with "localdomains"
27686     * In order to *not* break backwards compatibility
27687     *    Some phones address us at IP only, some with additional port number
27688     */
27689    if (auto_sip_domains) {
27690       char temp[MAXHOSTNAMELEN];
27691 
27692       /* First our default IP address */
27693       if (!ast_sockaddr_isnull(&bindaddr) && !ast_sockaddr_is_any(&bindaddr)) {
27694          add_sip_domain(ast_sockaddr_stringify_addr(&bindaddr),
27695                    SIP_DOMAIN_AUTO, NULL);
27696       } else if (!ast_sockaddr_isnull(&internip) && !ast_sockaddr_is_any(&internip)) {
27697       /* Our internal IP address, if configured */
27698          add_sip_domain(ast_sockaddr_stringify_addr(&internip),
27699                    SIP_DOMAIN_AUTO, NULL);
27700       } else {
27701          ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n");
27702       }
27703 
27704       /* If TCP is running on a different IP than UDP, then add it too */
27705       if (!ast_sockaddr_isnull(&sip_tcp_desc.local_address) &&
27706           !ast_sockaddr_cmp(&bindaddr, &sip_tcp_desc.local_address)) {
27707          add_sip_domain(ast_sockaddr_stringify_addr(&sip_tcp_desc.local_address),
27708                    SIP_DOMAIN_AUTO, NULL);
27709       }
27710 
27711       /* If TLS is running on a different IP than UDP and TCP, then add that too */
27712       if (!ast_sockaddr_isnull(&sip_tls_desc.local_address) &&
27713           !ast_sockaddr_cmp(&bindaddr, &sip_tls_desc.local_address) &&
27714           !ast_sockaddr_cmp(&sip_tcp_desc.local_address,
27715                   &sip_tls_desc.local_address)) {
27716          add_sip_domain(ast_sockaddr_stringify_addr(&sip_tcp_desc.local_address),
27717                    SIP_DOMAIN_AUTO, NULL);
27718       }
27719 
27720       /* Our extern IP address, if configured */
27721       if (!ast_sockaddr_isnull(&externaddr)) {
27722          add_sip_domain(ast_sockaddr_stringify_addr(&externaddr),
27723                    SIP_DOMAIN_AUTO, NULL);
27724       }
27725 
27726       /* Extern host name (NAT traversal support) */
27727       if (!ast_strlen_zero(externhost)) {
27728          add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL);
27729       }
27730       
27731       /* Our host name */
27732       if (!gethostname(temp, sizeof(temp))) {
27733          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
27734       }
27735    }
27736 
27737    /* Release configuration from memory */
27738    ast_config_destroy(cfg);
27739 
27740    /* Load the list of manual NOTIFY types to support */
27741    if (notify_types)
27742       ast_config_destroy(notify_types);
27743    if ((notify_types = ast_config_load(notify_config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
27744       ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed.\n", notify_config);
27745       notify_types = NULL;
27746    }
27747 
27748    /* Done, tell the manager */
27749    manager_event(EVENT_FLAG_SYSTEM, "ChannelReload", "ChannelType: SIP\r\nReloadReason: %s\r\nRegistry_Count: %d\r\nPeer_Count: %d\r\n", channelreloadreason2txt(reason), registry_count, peer_count);
27750    run_end = time(0);
27751    ast_debug(4, "SIP reload_config done...Runtime= %d sec\n", (int)(run_end-run_start));
27752 
27753    return 0;
27754 }

static char * remove_uri_parameters ( char *  uri  )  [static]

Definition at line 11281 of file chan_sip.c.

Referenced by extract_uri(), parse_moved_contact(), register_verify(), reqprep(), and transmit_state_notify().

11282 {
11283    char *atsign;
11284    atsign = strchr(uri, '@'); /* First, locate the at sign */
11285    if (!atsign) {
11286       atsign = uri;  /* Ok hostname only, let's stick with the rest */
11287    }
11288    atsign = strchr(atsign, ';'); /* Locate semi colon */
11289    if (atsign)
11290       *atsign = '\0';   /* Kill at the semi colon */
11291    return uri;
11292 }

static int reply_digest ( struct sip_pvt *  p,
struct sip_request *  req,
char *  header,
int  sipmethod,
char *  digest,
int  digest_len 
) [static]

reply to authentication for outbound registrations

Returns:
Returns -1 if we have no auth
Note:
This is used for register= servers in sip.conf, SIP proxies we register with for receiving calls from.

Definition at line 18278 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_skip_blanks(), ast_string_field_ptr_set, ast_string_field_set, ast_strlen_zero(), build_reply_digest(), get_header(), LOG_WARNING, and strsep().

Referenced by do_proxy_auth(), and do_register_auth().

18279 {
18280    char tmp[512];
18281    char *c;
18282    char oldnonce[256];
18283 
18284    /* table of recognised keywords, and places where they should be copied */
18285    const struct x {
18286       const char *key;
18287       const ast_string_field *field;
18288    } *i, keys[] = {
18289       { "realm=", &p->realm },
18290       { "nonce=", &p->nonce },
18291       { "opaque=", &p->opaque },
18292       { "qop=", &p->qop },
18293       { "domain=", &p->domain },
18294       { NULL, 0 },
18295    };
18296 
18297    ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
18298    if (ast_strlen_zero(tmp))
18299       return -1;
18300    if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
18301       ast_log(LOG_WARNING, "missing Digest.\n");
18302       return -1;
18303    }
18304    c = tmp + strlen("Digest ");
18305    ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
18306    while (c && *(c = ast_skip_blanks(c))) {  /* lookup for keys */
18307       for (i = keys; i->key != NULL; i++) {
18308          char *src, *separator;
18309          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
18310             continue;
18311          /* Found. Skip keyword, take text in quotes or up to the separator. */
18312          c += strlen(i->key);
18313          if (*c == '"') {
18314             src = ++c;
18315             separator = "\"";
18316          } else {
18317             src = c;
18318             separator = ",";
18319          }
18320          strsep(&c, separator); /* clear separator and move ptr */
18321          ast_string_field_ptr_set(p, i->field, src);
18322          break;
18323       }
18324       if (i->key == NULL) /* not found, try ',' */
18325          strsep(&c, ",");
18326    }
18327    /* Reset nonce count */
18328    if (strcmp(p->nonce, oldnonce))
18329       p->noncecount = 0;
18330 
18331    /* Save auth data for following registrations */
18332    if (p->registry) {
18333       struct sip_registry *r = p->registry;
18334 
18335       if (strcmp(r->nonce, p->nonce)) {
18336          ast_string_field_set(r, realm, p->realm);
18337          ast_string_field_set(r, nonce, p->nonce);
18338          ast_string_field_set(r, authdomain, p->domain);
18339          ast_string_field_set(r, opaque, p->opaque);
18340          ast_string_field_set(r, qop, p->qop);
18341          r->noncecount = 0;
18342       }
18343    }
18344    return build_reply_digest(p, sipmethod, digest, digest_len);
18345 }

static int reqprep ( struct sip_request *  req,
struct sip_pvt *  p,
int  sipmethod,
int  seqno,
int  newbranch 
) [static]

Initialize a SIP request message (not the initial one in a dialog).

< Strict routing flag

Definition at line 9788 of file chan_sip.c.

References add_header(), add_header_max_forwards(), add_route(), ast_copy_string(), ast_debug, ast_random(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_via(), copy_header(), FALSE, get_header(), global_useragent, init_req(), remove_uri_parameters(), set_destination(), sip_methods, st_get_se(), strcasestr(), strefresher2str(), text, cfsip_methods::text, TRUE, and url.

09789 {
09790    struct sip_request *orig = &p->initreq;
09791    char stripped[80];
09792    char tmp[80];
09793    char newto[256];
09794    const char *c;
09795    const char *ot, *of;
09796    int is_strict = FALSE;     /*!< Strict routing flag */
09797    int is_outbound = ast_test_flag(&p->flags[0], SIP_OUTGOING);   /* Session direction */
09798 
09799    memset(req, 0, sizeof(struct sip_request));
09800    
09801    snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text);
09802    
09803    if (!seqno) {
09804       p->ocseq++;
09805       seqno = p->ocseq;
09806    }
09807    
09808    /* A CANCEL must have the same branch as the INVITE that it is canceling. */
09809    if (sipmethod == SIP_CANCEL) {
09810       p->branch = p->invite_branch;
09811       build_via(p);
09812    } else if (newbranch && (sipmethod == SIP_INVITE)) {
09813       p->branch ^= ast_random();
09814       p->invite_branch = p->branch;
09815       build_via(p);
09816    } else if (newbranch) {
09817       p->branch ^= ast_random();
09818       build_via(p);
09819    }
09820 
09821    /* Check for strict or loose router */
09822    if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop, ";lr") == NULL) {
09823       is_strict = TRUE;
09824       if (sipdebug)
09825          ast_debug(1, "Strict routing enforced for session %s\n", p->callid);
09826    }
09827    
09828    if (sipmethod == SIP_CANCEL)
09829       c = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); /* Use original URI */
09830    else if (sipmethod == SIP_ACK) {
09831       /* Use URI from Contact: in 200 OK (if INVITE)
09832       (we only have the contacturi on INVITEs) */
09833       if (!ast_strlen_zero(p->okcontacturi))
09834          c = is_strict ? p->route->hop : p->okcontacturi;
09835       else
09836          c = REQ_OFFSET_TO_STR(&p->initreq, rlPart2);
09837    } else if (!ast_strlen_zero(p->okcontacturi))
09838       c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */
09839    else if (!ast_strlen_zero(p->uri))
09840       c = p->uri;
09841    else {
09842       char *n;
09843       /* We have no URI, use To: or From:  header as URI (depending on direction) */
09844       ast_copy_string(stripped, get_header(orig, is_outbound ? "To" : "From"),
09845             sizeof(stripped));
09846       n = get_in_brackets(stripped);
09847       c = remove_uri_parameters(n);
09848    }  
09849    init_req(req, sipmethod, c);
09850 
09851    snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text);
09852 
09853    add_header(req, "Via", p->via);
09854    if (p->route) {
09855       set_destination(p, p->route->hop);
09856       add_route(req, is_strict ? p->route->next : p->route);
09857    }
09858    add_header_max_forwards(p, req);
09859 
09860    ot = get_header(orig, "To");
09861    of = get_header(orig, "From");
09862 
09863    /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
09864       as our original request, including tag (or presumably lack thereof) */
09865    if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) {
09866       /* Add the proper tag if we don't have it already.  If they have specified
09867          their tag, use it.  Otherwise, use our own tag */
09868       if (is_outbound && !ast_strlen_zero(p->theirtag))
09869          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
09870       else if (!is_outbound)
09871          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
09872       else
09873          snprintf(newto, sizeof(newto), "%s", ot);
09874       ot = newto;
09875    }
09876 
09877    if (is_outbound) {
09878       add_header(req, "From", of);
09879       add_header(req, "To", ot);
09880    } else {
09881       add_header(req, "From", ot);
09882       add_header(req, "To", of);
09883    }
09884    /* Do not add Contact for MESSAGE, BYE and Cancel requests */
09885    if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE)
09886       add_header(req, "Contact", p->our_contact);
09887 
09888    copy_header(req, orig, "Call-ID");
09889    add_header(req, "CSeq", tmp);
09890 
09891    if (!ast_strlen_zero(global_useragent))
09892       add_header(req, "User-Agent", global_useragent);
09893 
09894    if (!ast_strlen_zero(p->url)) {
09895       add_header(req, "Access-URL", p->url);
09896       ast_string_field_set(p, url, NULL);
09897    }
09898 
09899    /* Add Session-Timers related headers if the feature is active for this session.
09900       An exception to this behavior is the ACK request. Since Asterisk never requires
09901       session-timers support from a remote end-point (UAS) in an INVITE, it must
09902       not send 'Require: timer' header in the ACK request.
09903       This should only be added in the INVITE transactions, not MESSAGE or REFER or other
09904       in-dialog messages.
09905    */
09906    if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE
09907        && sipmethod == SIP_INVITE) {
09908       char se_hdr[256];
09909       snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval,
09910          strefresher2str(p->stimer->st_ref));
09911       add_header(req, "Require", "timer");
09912       add_header(req, "Session-Expires", se_hdr);
09913       snprintf(se_hdr, sizeof(se_hdr), "%d", st_get_se(p, FALSE));
09914       add_header(req, "Min-SE", se_hdr);
09915    }
09916 
09917    return 0;
09918 }

static int resp_needs_contact ( const char *  msg,
enum sipmethod  method 
) [inline, static]

Test if this response needs a contact header.

Definition at line 9651 of file chan_sip.c.

Referenced by respprep().

09651                                                                              {
09652    /* Requirements for Contact header inclusion in responses generated
09653     * from the header tables found in the following RFCs.  Where the
09654     * Contact header was marked mandatory (m) or optional (o) this
09655     * function returns 1.
09656     *
09657     * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER)
09658     * - RFC 2976 (INFO)
09659     * - RFC 3262 (PRACK)
09660     * - RFC 3265 (SUBSCRIBE, NOTIFY)
09661     * - RFC 3311 (UPDATE)
09662     * - RFC 3428 (MESSAGE)
09663     * - RFC 3515 (REFER)
09664     * - RFC 3903 (PUBLISH)
09665     */
09666 
09667    switch (method) {
09668       /* 1xx, 2xx, 3xx, 485 */
09669       case SIP_INVITE:
09670       case SIP_UPDATE:
09671       case SIP_SUBSCRIBE:
09672       case SIP_NOTIFY:
09673          if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3))
09674             return 1;
09675          break;
09676 
09677       /* 2xx, 3xx, 485 */
09678       case SIP_REGISTER:
09679       case SIP_OPTIONS:
09680          if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3))
09681             return 1;
09682          break;
09683 
09684       /* 3xx, 485 */
09685       case SIP_BYE:
09686       case SIP_PRACK:
09687       case SIP_MESSAGE:
09688       case SIP_PUBLISH:
09689          if (msg[0] == '3' || !strncmp(msg, "485", 3))
09690             return 1;
09691          break;
09692 
09693       /* 2xx, 3xx, 4xx, 5xx, 6xx */
09694       case SIP_REFER:
09695          if (msg[0] >= '2' && msg[0] <= '6')
09696             return 1;
09697          break;
09698 
09699       /* contact will not be included for everything else */
09700       case SIP_ACK:
09701       case SIP_CANCEL:
09702       case SIP_INFO:
09703       case SIP_PING:
09704       default:
09705          return 0;
09706    }
09707    return 0;
09708 }

static int respprep ( struct sip_request *  resp,
struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req 
) [static]

Prepare SIP response packet.

Definition at line 9711 of file chan_sip.c.

References add_header(), add_supported_header(), ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), get_header(), global_useragent, init_resp(), LOG_WARNING, process_via(), resp_needs_contact(), strcasestr(), strefresher2str(), TRUE, and url.

09712 {
09713    char newto[256];
09714    const char *ot;
09715 
09716    init_resp(resp, msg);
09717    copy_via_headers(p, resp, req, "Via");
09718    if (msg[0] == '1' || msg[0] == '2')
09719       copy_all_header(resp, req, "Record-Route");
09720    copy_header(resp, req, "From");
09721    ot = get_header(req, "To");
09722    if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
09723       /* Add the proper tag if we don't have it already.  If they have specified
09724          their tag, use it.  Otherwise, use our own tag */
09725       if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING))
09726          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
09727       else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING))
09728          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
09729       else
09730          ast_copy_string(newto, ot, sizeof(newto));
09731       ot = newto;
09732    }
09733    add_header(resp, "To", ot);
09734    copy_header(resp, req, "Call-ID");
09735    copy_header(resp, req, "CSeq");
09736    if (!ast_strlen_zero(global_useragent))
09737       add_header(resp, "Server", global_useragent);
09738    add_header(resp, "Allow", ALLOWED_METHODS);
09739    add_supported_header(p, resp);
09740 
09741    /* If this is an invite, add Session-Timers related headers if the feature is active for this session */
09742    if (p->method == SIP_INVITE && p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE) {
09743       char se_hdr[256];
09744       snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval,
09745          strefresher2str(p->stimer->st_ref));
09746       add_header(resp, "Session-Expires", se_hdr);
09747    }
09748 
09749    if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) {
09750       /* For registration responses, we also need expiry and
09751          contact info */
09752       char tmp[256];
09753 
09754       snprintf(tmp, sizeof(tmp), "%d", p->expiry);
09755       add_header(resp, "Expires", tmp);
09756       if (p->expiry) {  /* Only add contact if we have an expiry time */
09757          char contact[SIPBUFSIZE];
09758          const char *contact_uri = p->method == SIP_SUBSCRIBE ? p->our_contact : p->fullcontact;
09759          char *brackets = strchr(contact_uri, '<');
09760          snprintf(contact, sizeof(contact), "%s%s%s;expires=%d", brackets ? "" : "<", contact_uri, brackets ? "" : ">", p->expiry);
09761          add_header(resp, "Contact", contact);  /* Not when we unregister */
09762       }
09763    } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) {
09764       add_header(resp, "Contact", p->our_contact);
09765    }
09766 
09767    if (!ast_strlen_zero(p->url)) {
09768       add_header(resp, "Access-URL", p->url);
09769       ast_string_field_set(p, url, NULL);
09770    }
09771 
09772    /* default to routing the response to the address where the request
09773     * came from.  Since we don't have a transport layer, we do this here.
09774     * The process_via() function will update the port to either the port
09775     * specified in the via header or the default port later on (per RFC
09776     * 3261 section 18.2.2).
09777     */
09778    p->sa = p->recv;
09779 
09780    if (process_via(p, req)) {
09781       ast_log(LOG_WARNING, "error processing via header, will send response to originating address\n");
09782    }
09783 
09784    return 0;
09785 }

static int restart_monitor ( void   )  [static]

Start the channel monitor thread.

Definition at line 24735 of file chan_sip.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, LOG_WARNING, monitor_thread, and monlock.

24736 {
24737    /* If we're supposed to be stopped -- stay stopped */
24738    if (monitor_thread == AST_PTHREADT_STOP)
24739       return 0;
24740    ast_mutex_lock(&monlock);
24741    if (monitor_thread == pthread_self()) {
24742       ast_mutex_unlock(&monlock);
24743       ast_log(LOG_WARNING, "Cannot kill myself\n");
24744       return -1;
24745    }
24746    if (monitor_thread != AST_PTHREADT_NULL) {
24747       /* Wake up the thread */
24748       pthread_kill(monitor_thread, SIGURG);
24749    } else {
24750       /* Start a new monitor */
24751       if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
24752          ast_mutex_unlock(&monlock);
24753          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
24754          return -1;
24755       }
24756    }
24757    ast_mutex_unlock(&monlock);
24758    return 0;
24759 }

static void restart_session_timer ( struct sip_pvt *  p  )  [static]

Session-Timers: Restart session timer.

Definition at line 24763 of file chan_sip.c.

References ast_debug, ast_log(), AST_SCHED_DEL_UNREF, LOG_WARNING, start_session_timer(), and TRUE.

Referenced by handle_request_invite().

24764 {
24765    if (!p->stimer) {
24766       ast_log(LOG_WARNING, "Null stimer in restart_session_timer - %s\n", p->callid);
24767       return;
24768    }
24769 
24770    if (p->stimer->st_active == TRUE) {
24771       AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
24772             dialog_unref(p, "Removing session timer ref"));
24773       ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
24774       start_session_timer(p);
24775    }
24776 }

static int retrans_pkt ( const void *  data  )  [static]

Retransmit SIP message if no answer (Called from scheduler).

Definition at line 3460 of file chan_sip.c.

References __sip_xmit(), append_history, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_PROTOCOL_ERROR, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_free, ast_log(), ast_queue_hangup_with_cause(), ast_sockaddr_stringify(), ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), ast_verbose, DEFAULT_RETRANS, LOG_WARNING, pvt_set_needdestroy(), sip_alreadygone(), sip_debug_test_pvt(), sip_methods, sip_nat_mode(), sip_pvt_lock, sip_pvt_unlock, sip_real_dst(), sipdebug, cfsip_methods::text, and UNLINK.

03461 {
03462    struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL;
03463    int reschedule = DEFAULT_RETRANS;
03464    int xmitres = 0;
03465    /* how many ms until retrans timeout is reached */
03466    int64_t diff = pkt->retrans_stop_time - ast_tvdiff_ms(ast_tvnow(), pkt->time_sent);
03467 
03468    /* Do not retransmit if time out is reached. This will be negative if the time between
03469     * the first transmission and now is larger than our timeout period. This is a fail safe
03470     * check in case the scheduler gets behind or the clock is changed. */
03471    if ((diff <= 0) || (diff > pkt->retrans_stop_time)) {
03472       pkt->retrans_stop = 1;
03473    }
03474 
03475    /* Lock channel PVT */
03476    sip_pvt_lock(pkt->owner);
03477 
03478    if (!pkt->retrans_stop) {
03479       pkt->retrans++;
03480       if (!pkt->timer_t1) {   /* Re-schedule using timer_a and timer_t1 */
03481          if (sipdebug) {
03482             ast_debug(4, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n",
03483                pkt->retransid,
03484                sip_methods[pkt->method].text,
03485                pkt->method);
03486          }
03487       } else {
03488          int siptimer_a;
03489 
03490          if (sipdebug) {
03491             ast_debug(4, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n",
03492                pkt->retransid,
03493                pkt->retrans,
03494                sip_methods[pkt->method].text,
03495                pkt->method);
03496          }
03497          if (!pkt->timer_a) {
03498             pkt->timer_a = 2 ;
03499          } else {
03500             pkt->timer_a = 2 * pkt->timer_a;
03501          }
03502 
03503          /* For non-invites, a maximum of 4 secs */
03504          siptimer_a = pkt->timer_t1 * pkt->timer_a;   /* Double each time */
03505          if (pkt->method != SIP_INVITE && siptimer_a > 4000) {
03506             siptimer_a = 4000;
03507          }
03508 
03509          /* Reschedule re-transmit */
03510          reschedule = siptimer_a;
03511          ast_debug(4, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n",
03512             pkt->retrans + 1,
03513             siptimer_a,
03514             pkt->timer_t1,
03515             pkt->retransid);
03516       }
03517 
03518       if (sip_debug_test_pvt(pkt->owner)) {
03519          const struct ast_sockaddr *dst = sip_real_dst(pkt->owner);
03520          ast_verbose("Retransmitting #%d (%s) to %s:\n%s\n---\n",
03521             pkt->retrans, sip_nat_mode(pkt->owner),
03522             ast_sockaddr_stringify(dst),
03523             pkt->data->str);
03524       }
03525 
03526       append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data->str);
03527       xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);
03528 
03529       /* If there was no error during the network transmission, schedule the next retransmission,
03530        * but if the next retransmission is going to be beyond our timeout period, mark the packet's
03531        * stop_retrans value and set the next retransmit to be the exact time of timeout.  This will
03532        * allow any responses to the packet to be processed before the packet is destroyed on the next
03533        * call to this function by the scheduler. */
03534       if (xmitres != XMIT_ERROR) {
03535          if (reschedule >= diff) {
03536             pkt->retrans_stop = 1;
03537             reschedule = diff;
03538          }
03539          sip_pvt_unlock(pkt->owner);
03540          return  reschedule;
03541       }
03542    }
03543 
03544    /* At this point, either the packet's retransmission timed out, or there was a
03545     * transmission error, either way destroy the scheduler item and this packet. */
03546 
03547    pkt->retransid = -1; /* Kill this scheduler item */
03548 
03549    if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) {
03550       if (pkt->is_fatal || sipdebug) { /* Tell us if it's critical or if we're debugging */
03551          ast_log(LOG_WARNING, "Retransmission timeout reached on transmission %s for seqno %d (%s %s) -- See https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions\n"
03552             "Packet timed out after %dms with no response\n",
03553             pkt->owner->callid,
03554             pkt->seqno,
03555             pkt->is_fatal ? "Critical" : "Non-critical",
03556             pkt->is_resp ? "Response" : "Request",
03557             (int) ast_tvdiff_ms(ast_tvnow(), pkt->time_sent));
03558       }
03559    } else if (pkt->method == SIP_OPTIONS && sipdebug) {
03560       ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s)  -- See https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions\n", pkt->owner->callid);
03561    }
03562 
03563    if (xmitres == XMIT_ERROR) {
03564       ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission on Call ID %s\n", pkt->owner->callid);
03565       append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
03566    } else {
03567       append_history(pkt->owner, "MaxRetries", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
03568    }
03569 
03570    if (pkt->is_fatal) {
03571       while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) {
03572          sip_pvt_unlock(pkt->owner);   /* SIP_PVT, not channel */
03573          usleep(1);
03574          sip_pvt_lock(pkt->owner);
03575       }
03576       if (pkt->owner->owner && !pkt->owner->owner->hangupcause) {
03577          pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE;
03578       }
03579       if (pkt->owner->owner) {
03580          ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet (see https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions).\n", pkt->owner->callid);
03581 
03582          if (pkt->is_resp &&
03583             (pkt->response_code >= 200) &&
03584             (pkt->response_code < 300) &&
03585             pkt->owner->pendinginvite &&
03586             ast_test_flag(&pkt->owner->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
03587             /* This is a timeout of the 2XX response to a pending INVITE.  In this case terminate the INVITE
03588              * transaction just as if we received the ACK, but immediately hangup with a BYE (sip_hangup
03589              * will send the BYE as long as the dialog is not set as "alreadygone")
03590              * RFC 3261 section 13.3.1.4.
03591              * "If the server retransmits the 2xx response for 64*T1 seconds without receiving
03592              * an ACK, the dialog is confirmed, but the session SHOULD be terminated.  This is
03593              * accomplished with a BYE, as described in Section 15." */
03594             pkt->owner->invitestate = INV_TERMINATED;
03595             pkt->owner->pendinginvite = 0;
03596          } else {
03597             /* there is nothing left to do, mark the dialog as gone */
03598             sip_alreadygone(pkt->owner);
03599          }
03600          ast_queue_hangup_with_cause(pkt->owner->owner, AST_CAUSE_PROTOCOL_ERROR);
03601          ast_channel_unlock(pkt->owner->owner);
03602       } else {
03603          /* If no channel owner, destroy now */
03604 
03605          /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */
03606          if (pkt->method != SIP_OPTIONS && pkt->method != SIP_REGISTER) {
03607             pvt_set_needdestroy(pkt->owner, "no response to critical packet");
03608             sip_alreadygone(pkt->owner);
03609             append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately");
03610          }
03611       }
03612    }
03613 
03614    if (pkt->method == SIP_BYE) {
03615       /* We're not getting answers on SIP BYE's.  Tear down the call anyway. */
03616       sip_alreadygone(pkt->owner);
03617       if (pkt->owner->owner) {
03618          ast_channel_unlock(pkt->owner->owner);
03619       }
03620       append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway.");
03621       pvt_set_needdestroy(pkt->owner, "no response to BYE");
03622    }
03623 
03624    /* Remove the packet */
03625    for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) {
03626       if (cur == pkt) {
03627          UNLINK(cur, pkt->owner->packets, prev);
03628          sip_pvt_unlock(pkt->owner);
03629          if (pkt->owner) {
03630             pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now");
03631          }
03632          if (pkt->data) {
03633             ast_free(pkt->data);
03634          }
03635          pkt->data = NULL;
03636          ast_free(pkt);
03637          return 0;
03638       }
03639    }
03640    /* error case */
03641    ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n");
03642    sip_pvt_unlock(pkt->owner);
03643    return 0;
03644 }

static int scheduler_process_request_queue ( const void *  data  )  [static]

Definition at line 24082 of file chan_sip.c.

References ast_channel_trylock, sip_pvt_lock, and sip_pvt_unlock.

Referenced by queue_request().

24083 {
24084    struct sip_pvt *p = (struct sip_pvt *) data;
24085    int recount = 0;
24086    int nounlock = 0;
24087    int lockretry;
24088 
24089    for (lockretry = 10; lockretry > 0; lockretry--) {
24090       sip_pvt_lock(p);
24091 
24092       /* lock the owner if it has one -- we may need it */
24093       /* because this is deadlock-prone, we need to try and unlock if failed */
24094       if (!p->owner || !ast_channel_trylock(p->owner)) {
24095          break;   /* locking succeeded */
24096       }
24097 
24098       if (lockretry != 1) {
24099          sip_pvt_unlock(p);
24100          /* Sleep for a very short amount of time */
24101          usleep(1);
24102       }
24103    }
24104 
24105    if (!lockretry) {
24106       int retry = !AST_LIST_EMPTY(&p->request_queue);
24107 
24108       /* we couldn't get the owner lock, which is needed to process
24109          the queued requests, so return a non-zero value, which will
24110          cause the scheduler to run this request again later if there
24111          still requests to be processed
24112       */
24113       sip_pvt_unlock(p);
24114       if (!retry) {
24115          dialog_unref(p, "The ref to a dialog passed to this sched callback is going out of scope; unref it.");
24116       }
24117       return retry;
24118    };
24119 
24120    process_request_queue(p, &recount, &nounlock);
24121    p->request_queue_sched_id = -1;
24122 
24123    if (p->owner && !nounlock) {
24124       ast_channel_unlock(p->owner);
24125    }
24126    sip_pvt_unlock(p);
24127 
24128    if (recount) {
24129       ast_update_use_count();
24130    }
24131 
24132    dialog_unref(p, "The ref to a dialog passed to this sched callback is going out of scope; unref it.");
24133 
24134    return 0;
24135 }

static int send_provisional_keepalive ( const void *  data  )  [static]

Definition at line 4029 of file chan_sip.c.

References send_provisional_keepalive_full().

Referenced by update_provisional_keepalive().

04029                                                         {
04030    struct sip_pvt *pvt = (struct sip_pvt *) data;
04031 
04032    return send_provisional_keepalive_full(pvt, 0);
04033 }

static int send_provisional_keepalive_full ( struct sip_pvt *  pvt,
int  with_sdp 
) [static]

Definition at line 4009 of file chan_sip.c.

References FALSE, S_OR, transmit_response(), and transmit_response_with_sdp().

Referenced by send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().

04010 {
04011    const char *msg = NULL;
04012 
04013    if (!pvt->last_provisional || !strncasecmp(pvt->last_provisional, "100", 3)) {
04014       msg = "183 Session Progress";
04015    }
04016 
04017    if (pvt->invitestate < INV_COMPLETED) {
04018       if (with_sdp) {
04019          transmit_response_with_sdp(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq, XMIT_UNRELIABLE, FALSE, FALSE);
04020       } else {
04021          transmit_response(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq);
04022       }
04023       return PROVIS_KEEPALIVE_TIMEOUT;
04024    }
04025 
04026    return 0;
04027 }

static int send_provisional_keepalive_with_sdp ( const void *  data  )  [static]

Definition at line 4035 of file chan_sip.c.

References send_provisional_keepalive_full().

Referenced by update_provisional_keepalive().

04035                                                                  {
04036    struct sip_pvt *pvt = (void *)data;
04037 
04038    return send_provisional_keepalive_full(pvt, 1);
04039 }

static int send_request ( struct sip_pvt *  p,
struct sip_request *  req,
enum xmittype  reliable,
int  seqno 
) [static]

Send SIP Request to the other part of the dialogue.

Returns:
see __sip_xmit

Definition at line 4090 of file chan_sip.c.

References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_sockaddr_stringify(), ast_test_flag, ast_verbose, deinit_req(), finalize_content(), get_header(), parse_copy(), sip_debug_test_pvt(), sip_methods, and cfsip_methods::text.

04091 {
04092    int res;
04093 
04094    /* If we have an outbound proxy, reset peer address
04095       Only do this once.
04096    */
04097    if (p->outboundproxy) {
04098       p->sa = p->outboundproxy->ip;
04099    }
04100 
04101    finalize_content(req);
04102    add_blank(req);
04103    if (sip_debug_test_pvt(p)) {
04104       if (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) {
04105          ast_verbose("%sTransmitting (NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->recv), req->data->str);
04106       } else {
04107          ast_verbose("%sTransmitting (no NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", ast_sockaddr_stringify(&p->sa), req->data->str);
04108       }
04109    }
04110    if (p->do_history) {
04111       struct sip_request tmp = { .rlPart1 = 0, };
04112       parse_copy(&tmp, req);
04113       append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data->str, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text);
04114       deinit_req(&tmp);
04115    }
04116    res = (reliable) ?
04117       __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
04118       __sip_xmit(p, req->data, req->len);
04119    deinit_req(req);
04120    return res;
04121 }

static int send_response ( struct sip_pvt *  p,
struct sip_request *  req,
enum xmittype  reliable,
int  seqno 
) [static]

Transmit response on SIP request.

Definition at line 4050 of file chan_sip.c.

References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, AST_SCHED_DEL_UNREF, ast_sockaddr_stringify(), ast_verbose, deinit_req(), finalize_content(), get_header(), parse_copy(), sip_debug_test_pvt(), sip_methods, sip_nat_mode(), sip_real_dst(), and cfsip_methods::text.

04051 {
04052    int res;
04053 
04054    finalize_content(req);
04055    add_blank(req);
04056    if (sip_debug_test_pvt(p)) {
04057       const struct ast_sockaddr *dst = sip_real_dst(p);
04058 
04059       ast_verbose("\n<--- %sTransmitting (%s) to %s --->\n%s\n<------------>\n",
04060          reliable ? "Reliably " : "", sip_nat_mode(p),
04061          ast_sockaddr_stringify(dst),
04062          req->data->str);
04063    }
04064    if (p->do_history) {
04065       struct sip_request tmp = { .rlPart1 = 0, };
04066       parse_copy(&tmp, req);
04067       append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data->str, get_header(&tmp, "CSeq"),
04068          (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? REQ_OFFSET_TO_STR(&tmp, rlPart2) : sip_methods[tmp.method].text);
04069       deinit_req(&tmp);
04070    }
04071 
04072    /* If we are sending a final response to an INVITE, stop retransmitting provisional responses */
04073    if (p->initreq.method == SIP_INVITE && reliable == XMIT_CRITICAL) {
04074       AST_SCHED_DEL_UNREF(sched, p->provisional_keepalive_sched_id, dialog_unref(p, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr"));
04075    }
04076 
04077    res = (reliable) ?
04078        __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
04079       __sip_xmit(p, req->data, req->len);
04080    deinit_req(req);
04081    if (res > 0) {
04082       return 0;
04083    }
04084    return res;
04085 }

static enum ast_cc_service_type service_string_to_service_type ( const char *const   service_string  )  [static]

Definition at line 837 of file chan_sip.c.

References AST_CC_CCBS, AST_CC_CCNL, AST_CC_NONE, service, and sip_cc_service_map.

Referenced by sip_get_cc_information().

00838 {
00839    enum ast_cc_service_type service;
00840    for (service = AST_CC_CCBS; service <= AST_CC_CCNL; ++service) {
00841       if (!strcasecmp(service_string, sip_cc_service_map[service].service_string)) {
00842          return service;
00843       }
00844    }
00845    return AST_CC_NONE;
00846 }

static int set_address_from_contact ( struct sip_pvt *  pvt  )  [static]

Change the other partys IP address based on given contact.

Todo:
We need to save the TRANSPORT here too

Definition at line 13199 of file chan_sip.c.

References __set_address_from_contact(), and ast_test_flag.

Referenced by handle_response_invite().

13200 {
13201    if (ast_test_flag(&pvt->flags[0], SIP_NAT_FORCE_RPORT)) {
13202       /* NAT: Don't trust the contact field.  Just use what they came to us
13203          with. */
13204       /*! \todo We need to save the TRANSPORT here too */
13205       pvt->sa = pvt->recv;
13206       return 0;
13207    }
13208 
13209    return __set_address_from_contact(pvt->fullcontact, &pvt->sa, pvt->socket.type == SIP_TRANSPORT_TLS ? 1 : 0);
13210 }

static void set_destination ( struct sip_pvt *  p,
char *  uri 
) [static]

Set destination from SIP URI.

Parse uri to h (host) and port - uri is already just the part inside the <> general form we are expecting is sip[s]:username[:password][;parameter][:port][;...] If there's a port given, turn NAPTR/SRV off. NAPTR might indicate SIPS preference even for SIP: uri's

If there's a sips: uri scheme, TLS will be required.

Todo:
XXX If we have sip_cfg.srvlookup on, then look for NAPTR/SRV, otherwise, just look for A records

Todo:
XXX If we have sip_cfg.srvlookup on, then look for NAPTR/SRV, otherwise, just look for A records

Definition at line 9518 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_verbose, debug, FALSE, hostname, LOG_WARNING, PARSE_PORT_FORBID, sip_debug_test_pvt(), and TRUE.

Referenced by reqprep().

09519 {
09520    char *h, *maddr, hostname[256];
09521    int hn;
09522    int debug=sip_debug_test_pvt(p);
09523    int tls_on = FALSE;
09524 
09525    if (debug)
09526       ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
09527 
09528    /* Find and parse hostname */
09529    h = strchr(uri, '@');
09530    if (h)
09531       ++h;
09532    else {
09533       h = uri;
09534       if (!strncasecmp(h, "sip:", 4)) {
09535          h += 4;
09536       } else if (!strncasecmp(h, "sips:", 5)) {
09537          h += 5;
09538          tls_on = TRUE;
09539       }
09540    }
09541    hn = strcspn(h, ";>") + 1;
09542    if (hn > sizeof(hostname))
09543       hn = sizeof(hostname);
09544    ast_copy_string(hostname, h, hn);
09545    /* XXX bug here if string has been trimmed to sizeof(hostname) */
09546    h += hn - 1;
09547 
09548    /*! \todo XXX If we have sip_cfg.srvlookup on, then look for NAPTR/SRV,
09549     * otherwise, just look for A records */
09550    if (ast_sockaddr_resolve_first(&p->sa, hostname, 0)) {
09551       ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
09552       return;
09553    }
09554 
09555    /* Got the hostname - but maybe there's a "maddr=" to override address? */
09556    maddr = strstr(h, "maddr=");
09557    if (maddr) {
09558       int port;
09559 
09560       maddr += 6;
09561       hn = strspn(maddr, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
09562                     "0123456789-.:[]") + 1;
09563       if (hn > sizeof(hostname))
09564          hn = sizeof(hostname);
09565       ast_copy_string(hostname, maddr, hn);
09566 
09567       port = ast_sockaddr_port(&p->sa);
09568 
09569       /*! \todo XXX If we have sip_cfg.srvlookup on, then look for
09570        * NAPTR/SRV, otherwise, just look for A records */
09571       if (ast_sockaddr_resolve_first(&p->sa, hostname, PARSE_PORT_FORBID)) {
09572          ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
09573          return;
09574       }
09575 
09576       ast_sockaddr_set_port(&p->sa, port);
09577    }
09578 
09579    if (!ast_sockaddr_port(&p->sa)) {
09580       ast_sockaddr_set_port(&p->sa, tls_on ?
09581                   STANDARD_TLS_PORT : STANDARD_SIP_PORT);
09582    }
09583 
09584    if (debug) {
09585       ast_verbose("set_destination: set destination to %s\n",
09586              ast_sockaddr_stringify(&p->sa));
09587    }
09588 }

static void set_insecure_flags ( struct ast_flags *  flags,
const char *  value,
int  lineno 
) [static]

Parse insecure= setting in sip.conf and set flags according to setting.

Definition at line 25503 of file chan_sip.c.

References ast_copy_string(), ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), LOG_WARNING, strsep(), and word.

Referenced by get_insecure_variable_from_config(), and handle_common_options().

25504 {
25505    if (ast_strlen_zero(value))
25506       return;
25507 
25508    if (!ast_false(value)) {
25509       char buf[64];
25510       char *word, *next;
25511 
25512       ast_copy_string(buf, value, sizeof(buf));
25513       next = buf;
25514       while ((word = strsep(&next, ","))) {
25515          if (!strcasecmp(word, "port"))
25516             ast_set_flag(&flags[0], SIP_INSECURE_PORT);
25517          else if (!strcasecmp(word, "invite"))
25518             ast_set_flag(&flags[0], SIP_INSECURE_INVITE);
25519          else
25520             ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno);
25521       }
25522    }
25523 }

static void set_nonce_randdata ( struct sip_pvt *  p,
int  forceupdate 
) [static]

builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one.

Definition at line 13576 of file chan_sip.c.

References ast_random(), ast_string_field_build, and ast_strlen_zero().

Referenced by check_auth(), and transmit_fake_auth_response().

13577 {
13578    if (p->stalenonce || forceupdate || ast_strlen_zero(p->randdata)) {
13579       ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
13580       p->stalenonce = 0;
13581    }
13582 }

static void set_peer_defaults ( struct sip_peer *  peer  )  [static]

Set peer defaults before configuring specific configurations.

Definition at line 25888 of file chan_sip.c.

References ast_copy_flags, ast_sockaddr_setnull(), ast_string_field_set, cid_name, cid_num, clear_peer_mailboxes(), context, default_engine, default_language, default_maxcallbitrate, default_mohinterpret, default_mohsuggest, default_prefs, default_primary_transport, default_qualify, default_transports, default_vmexten, global_autoframing, global_callcounter, global_flags, global_max_se, global_min_se, global_qualifyfreq, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_st_mode, global_st_refresher, global_t1, global_t38_maxdatagram, global_timer_b, language, mohinterpret, mohsuggest, secret, set_socket_transport(), and sip_cfg.

Referenced by build_peer(), and temp_peer().

25889 {
25890    if (peer->expire == 0) {
25891       /* Don't reset expire or port time during reload
25892          if we have an active registration
25893       */
25894       peer->expire = -1;
25895       peer->pokeexpire = -1;
25896       set_socket_transport(&peer->socket, SIP_TRANSPORT_UDP);
25897    }
25898    peer->type = SIP_TYPE_PEER;
25899    ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
25900    ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
25901    ast_copy_flags(&peer->flags[2], &global_flags[2], SIP_PAGE3_FLAGS_TO_COPY);
25902    ast_string_field_set(peer, context, sip_cfg.default_context);
25903    ast_string_field_set(peer, subscribecontext, sip_cfg.default_subscribecontext);
25904    ast_string_field_set(peer, language, default_language);
25905    ast_string_field_set(peer, mohinterpret, default_mohinterpret);
25906    ast_string_field_set(peer, mohsuggest, default_mohsuggest);
25907    ast_string_field_set(peer, engine, default_engine);
25908    ast_sockaddr_setnull(&peer->addr);
25909    ast_sockaddr_setnull(&peer->defaddr);
25910    peer->capability = sip_cfg.capability;
25911    peer->maxcallbitrate = default_maxcallbitrate;
25912    peer->rtptimeout = global_rtptimeout;
25913    peer->rtpholdtimeout = global_rtpholdtimeout;
25914    peer->rtpkeepalive = global_rtpkeepalive;
25915    peer->allowtransfer = sip_cfg.allowtransfer;
25916    peer->autoframing = global_autoframing;
25917    peer->t38_maxdatagram = global_t38_maxdatagram;
25918    peer->qualifyfreq = global_qualifyfreq;
25919    if (global_callcounter)
25920       peer->call_limit=INT_MAX;
25921    ast_string_field_set(peer, vmexten, default_vmexten);
25922    ast_string_field_set(peer, secret, "");
25923    ast_string_field_set(peer, remotesecret, "");
25924    ast_string_field_set(peer, md5secret, "");
25925    ast_string_field_set(peer, cid_num, "");
25926    ast_string_field_set(peer, cid_name, "");
25927    ast_string_field_set(peer, cid_tag, "");
25928    ast_string_field_set(peer, fromdomain, "");
25929    ast_string_field_set(peer, fromuser, "");
25930    ast_string_field_set(peer, regexten, "");
25931    peer->callgroup = 0;
25932    peer->pickupgroup = 0;
25933    peer->maxms = default_qualify;
25934    peer->prefs = default_prefs;
25935    peer->stimer.st_mode_oper = global_st_mode;  /* Session-Timers */
25936    peer->stimer.st_ref = global_st_refresher;
25937    peer->stimer.st_min_se = global_min_se;
25938    peer->stimer.st_max_se = global_max_se;
25939    peer->timer_t1 = global_t1;
25940    peer->timer_b = global_timer_b;
25941    clear_peer_mailboxes(peer);
25942    peer->disallowed_methods = sip_cfg.disallowed_methods;
25943    peer->transports = default_transports;
25944    peer->default_outbound_transport = default_primary_transport;
25945 }

static unsigned int set_pvt_allowed_methods ( struct sip_pvt *  pvt,
struct sip_request *  req 
) [static]

A wrapper for parse_allowed_methods geared toward sip_pvts

This function, in addition to setting the allowed methods for a sip_pvt also will take into account the setting of the SIP_PAGE2_RPID_UPDATE flag.

Parameters:
pvt The sip_pvt we are setting the allowed_methods for
req The request which we are parsing
Return values:
The methods alloweded by the sip_pvt

Definition at line 7957 of file chan_sip.c.

References ast_test_flag, mark_method_allowed(), and parse_allowed_methods().

Referenced by check_peer_ok(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), handle_response_invite(), and handle_response_subscribe().

07958 {
07959    pvt->allowed_methods = parse_allowed_methods(req);
07960    
07961    if (ast_test_flag(&pvt->flags[1], SIP_PAGE2_RPID_UPDATE)) {
07962       mark_method_allowed(&pvt->allowed_methods, SIP_UPDATE);
07963    }
07964    pvt->allowed_methods &= ~(pvt->disallowed_methods);
07965 
07966    return pvt->allowed_methods;
07967 }

static void set_socket_transport ( struct sip_socket *  socket,
int  transport 
) [static]

Definition at line 12984 of file chan_sip.c.

References ao2_ref.

Referenced by __sip_subscribe_mwi_do(), build_peer(), create_addr(), expire_register(), get_transport_pvt(), parse_moved_contact(), parse_register_contact(), set_peer_defaults(), sip_alloc(), sip_request_call(), sip_send_mwi_to_peer(), sipsock_read(), and transmit_register().

12985 {
12986    /* if the transport type changes, clear all socket data */
12987    if (socket->type != transport) {
12988       socket->fd = -1;
12989       socket->type = transport;
12990       if (socket->tcptls_session) {
12991          ao2_ref(socket->tcptls_session, -1);
12992          socket->tcptls_session = NULL;
12993       }
12994    }
12995 }

static void set_t38_capabilities ( struct sip_pvt *  p  )  [static]

Set the global T38 capabilities on a SIP dialog structure.

Definition at line 4916 of file chan_sip.c.

References ast_test_flag, ast_udptl_set_error_correction_scheme(), UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.

Referenced by check_peer_ok(), create_addr_from_peer(), handle_request_invite(), and sip_alloc().

04917 {
04918    if (p->udptl) {
04919       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY) {
04920                         ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY);
04921       } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL_FEC) {
04922          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC);
04923       } else if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) == SIP_PAGE2_T38SUPPORT_UDPTL) {
04924          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE);
04925       }
04926    }
04927 }

static int setup_srtp ( struct sip_srtp **  srtp  )  [static]

Definition at line 28308 of file chan_sip.c.

References ast_log(), ast_rtp_engine_srtp_is_registered(), and LOG_ERROR.

Referenced by process_crypto(), and sip_call().

28309 {
28310    if (!ast_rtp_engine_srtp_is_registered()) {
28311       ast_log(LOG_ERROR, "No SRTP module loaded, can't setup SRTP session.\n");
28312       return -1;
28313    }
28314 
28315    if (!(*srtp = sip_srtp_alloc())) { /* Allocate SRTP data structure */
28316       return -1;
28317    }
28318 
28319    return 0;
28320 }

static int show_channels_cb ( void *  __cur,
void *  __arg,
int  flags 
) [static]

callback for show channel|subscription

Definition at line 17423 of file chan_sip.c.

References ast_cli(), AST_CLI_YESNO, ast_extension_state2str(), ast_getformatname_multiple(), ast_sockaddr_stringify_addr(), ast_str_alloca, ast_test_flag, FORMAT, FORMAT4, NONE, peer_mailboxes_to_str(), referstatus2str(), S_OR, sip_real_dst(), and subscription_type2str().

Referenced by sip_show_channels().

17424 {
17425    struct sip_pvt *cur = __cur;
17426    struct __show_chan_arg *arg = __arg;
17427    const struct ast_sockaddr *dst = sip_real_dst(cur);
17428    
17429    /* XXX indentation preserved to reduce diff. Will be fixed later */
17430    if (cur->subscribed == NONE && !arg->subscriptions) {
17431       /* set if SIP transfer in progress */
17432       const char *referstatus = cur->refer ? referstatus2str(cur->refer->status) : "";
17433       char formatbuf[SIPBUFSIZE/2];
17434       
17435       ast_cli(arg->fd, FORMAT, ast_sockaddr_stringify_addr(dst),
17436             S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
17437             cur->callid,
17438             ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0),
17439             AST_CLI_YESNO(ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD)),
17440             cur->needdestroy ? "(d)" : "",
17441             cur->lastmsg ,
17442             referstatus,
17443             cur->relatedpeer ? cur->relatedpeer->name : "<guest>"
17444          );
17445       arg->numchans++;
17446    }
17447    if (cur->subscribed != NONE && arg->subscriptions) {
17448       struct ast_str *mailbox_str = ast_str_alloca(512);
17449       if (cur->subscribed == MWI_NOTIFICATION && cur->relatedpeer)
17450          peer_mailboxes_to_str(&mailbox_str, cur->relatedpeer);
17451       ast_cli(arg->fd, FORMAT4, ast_sockaddr_stringify_addr(dst),
17452             S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
17453                cur->callid,
17454             /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */
17455             cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri,
17456             cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate),
17457             subscription_type2str(cur->subscribed),
17458             cur->subscribed == MWI_NOTIFICATION ? S_OR(mailbox_str->str, "<none>") : "<none>",
17459             cur->expiry
17460          );
17461       arg->numchans++;
17462    }
17463    return 0;   /* don't care, we scan all channels */
17464 }

static int show_chanstats_cb ( void *  __cur,
void *  __arg,
int  flags 
) [static]

Callback for show_chanstats.

Definition at line 17066 of file chan_sip.c.

References ast_cli(), ast_rtp_instance_get_stats(), AST_RTP_INSTANCE_STAT_ALL, ast_sockaddr_stringify_addr(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_channel::cdr, invstate2stringtable::desc, FORMAT, invitestate2string, NONE, ast_rtp_instance_stats::rxcount, ast_rtp_instance_stats::rxjitter, ast_rtp_instance_stats::rxploss, ast_cdr::start, ast_rtp_instance_stats::txcount, ast_rtp_instance_stats::txjitter, and ast_rtp_instance_stats::txploss.

Referenced by sip_show_channelstats().

17067 {
17068 #define FORMAT2 "%-15.15s  %-11.11s  %-8.8s %-10.10s  %-10.10s (     %%) %-6.6s %-10.10s  %-10.10s (     %%) %-6.6s\n"
17069 #define FORMAT  "%-15.15s  %-11.11s  %-8.8s %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.4lf\n"
17070    struct sip_pvt *cur = __cur;
17071    struct ast_rtp_instance_stats stats;
17072    char durbuf[10];
17073    int duration;
17074    int durh, durm, durs;
17075    struct ast_channel *c = cur->owner;
17076    struct __show_chan_arg *arg = __arg;
17077    int fd = arg->fd;
17078 
17079 
17080    if (cur->subscribed != NONE) /* Subscriptions */
17081       return 0;   /* don't care, we scan all channels */
17082 
17083    if (!cur->rtp) {
17084       if (sipdebug) {
17085          ast_cli(fd, "%-15.15s  %-11.11s (inv state: %s) -- %s\n",
17086             ast_sockaddr_stringify_addr(&cur->sa), cur->callid,
17087             invitestate2string[cur->invitestate].desc,
17088             "-- No RTP active");
17089       }
17090       return 0;   /* don't care, we scan all channels */
17091    }
17092 
17093    ast_rtp_instance_get_stats(cur->rtp, &stats, AST_RTP_INSTANCE_STAT_ALL);
17094 
17095    if (c && c->cdr && !ast_tvzero(c->cdr->start)) {
17096       duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000);
17097       durh = duration / 3600;
17098       durm = (duration % 3600) / 60;
17099       durs = duration % 60;
17100       snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
17101    } else {
17102       durbuf[0] = '\0';
17103    }
17104 
17105    ast_cli(fd, FORMAT,
17106       ast_sockaddr_stringify_addr(&cur->sa),
17107       cur->callid,
17108       durbuf,
17109       stats.rxcount > (unsigned int) 100000 ? (unsigned int) (stats.rxcount)/(unsigned int) 1000 : stats.rxcount,
17110       stats.rxcount > (unsigned int) 100000 ? "K":" ",
17111       stats.rxploss,
17112       (stats.rxcount + stats.rxploss) > 0 ? (double) stats.rxploss / (stats.rxcount + stats.rxploss) * 100 : 0,
17113       stats.rxjitter,
17114       stats.txcount > (unsigned int) 100000 ? (unsigned int) (stats.txcount)/(unsigned int) 1000 : stats.txcount,
17115       stats.txcount > (unsigned int) 100000 ? "K":" ",
17116       stats.txploss,
17117       stats.txcount > 0 ? (double) stats.txploss / stats.txcount * 100 : 0,
17118       stats.txjitter
17119    );
17120    arg->numchans++;
17121 
17122    return 0;   /* don't care, we scan all channels */
17123 }

static int sip_addheader ( struct ast_channel *  chan,
const char *  data 
) [static]

Add a SIP header to an outbound INVITE.

Definition at line 28100 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, ast_debug, ast_get_encoded_str(), ast_log(), ast_strlen_zero(), FALSE, inbuf(), len(), LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and TRUE.

Referenced by load_module().

28101 {
28102    int no = 0;
28103    int ok = FALSE;
28104    char varbuf[30];
28105    const char *inbuf = data;
28106    char *subbuf;
28107    
28108    if (ast_strlen_zero(inbuf)) {
28109       ast_log(LOG_WARNING, "This application requires the argument: Header\n");
28110       return 0;
28111    }
28112    ast_channel_lock(chan);
28113 
28114    /* Check for headers */
28115    while (!ok && no <= 50) {
28116       no++;
28117       snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no);
28118 
28119       /* Compare without the leading underscores */
28120       if ((pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL)) {
28121          ok = TRUE;
28122       }
28123    }
28124    if (ok) {
28125       size_t len = strlen(inbuf);
28126       subbuf = alloca(len + 1);
28127       ast_get_encoded_str(inbuf, subbuf, len + 1);
28128       pbx_builtin_setvar_helper(chan, varbuf, subbuf);
28129       if (sipdebug) {
28130          ast_debug(1, "SIP Header added \"%s\" as %s\n", inbuf, varbuf);
28131       }
28132    } else {
28133       ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
28134    }
28135    ast_channel_unlock(chan);
28136    return 0;
28137 }

struct sip_pvt* sip_alloc ( ast_string_field  callid,
struct ast_sockaddr *  addr,
int  useglobal_nat,
const int  intended_method,
struct sip_request *  req 
)

Allocate sip_pvt structure, set defaults and link in the container. Returns a reference to the object so whoever uses it later must remember to release the reference.

Definition at line 7242 of file chan_sip.c.

References ao2_t_alloc, ao2_t_link, ao2_t_ref, ast_cc_config_params_init, ast_clear_flag, ast_copy_flags, ast_debug, AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_random(), AST_RTP_DTMF, ast_sip_ouraddrfor(), ast_sockaddr_copy(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_new_with_bindaddr(), ast_udptl_setqos(), bindaddr, build_callid_pvt(), build_via(), context, default_engine, default_fromdomain, default_fromdomainport, default_maxcallbitrate, default_mohinterpret, default_mohsuggest, default_parkinglot, default_prefs, dialogs, do_setnat(), get_header(), global_autoframing, global_cos_audio, global_flags, global_t1, global_t38_maxdatagram, global_timer_b, global_tos_audio, internip, io, LOG_ERROR, make_our_tag(), mohinterpret, mohsuggest, NONE, parkinglot, recordhistory, set_socket_transport(), set_t38_capabilities(), sip_cfg, sip_destroy_fn(), sip_methods, cfsip_methods::text, and TRUE.

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

07244 {
07245    struct sip_pvt *p;
07246 
07247    if (!(p = ao2_t_alloc(sizeof(*p), sip_destroy_fn, "allocate a dialog(pvt) struct")))
07248       return NULL;
07249 
07250    if (ast_string_field_init(p, 512)) {
07251       ao2_t_ref(p, -1, "failed to string_field_init, drop p");
07252       return NULL;
07253    }
07254 
07255    if (!(p->cc_params = ast_cc_config_params_init())) {
07256       ao2_t_ref(p, -1, "Yuck, couldn't allocate cc_params struct. Get rid o' p");
07257       return NULL;
07258    }
07259 
07260    /* If this dialog is created as the result of an incoming Request. Lets store
07261     * some information about that request */
07262    if (req) {
07263       struct sip_via *via;
07264       const char *cseq = get_header(req, "Cseq");
07265       unsigned int seqno;
07266 
07267       /* get branch parameter from initial Request that started this dialog */
07268       via = parse_via(get_header(req, "Via"));
07269       if (via) {
07270          /* only store the branch if it begins with the magic prefix "z9hG4bK", otherwise
07271           * it is not useful to us to have it */
07272          if (!ast_strlen_zero(via->branch) && !strncasecmp(via->branch, "z9hG4bK", 7)) {
07273             ast_string_field_set(p, initviabranch, via->branch);
07274             ast_string_field_set(p, initviasentby, via->sent_by);
07275          }
07276          free_via(via);
07277       }
07278 
07279       /* Store initial incoming cseq. An error in sscanf here is ignored.  There is no approperiate
07280        * except not storing the number.  CSeq validation must take place before dialog creation in find_call */
07281       if (!ast_strlen_zero(cseq) && (sscanf(cseq, "%30u", &seqno) == 1)) {
07282          p->init_icseq = seqno;
07283       }
07284       /* Later in ast_sip_ouraddrfor we need this to choose the right ip and port for the specific transport */
07285       set_socket_transport(&p->socket, req->socket.type);
07286    } else {
07287       set_socket_transport(&p->socket, SIP_TRANSPORT_UDP);
07288    }
07289 
07290    p->socket.fd = -1;
07291    p->method = intended_method;
07292    p->initid = -1;
07293    p->waitid = -1;
07294    p->autokillid = -1;
07295    p->request_queue_sched_id = -1;
07296    p->provisional_keepalive_sched_id = -1;
07297    p->t38id = -1;
07298    p->subscribed = NONE;
07299    p->stateid = -1;
07300    p->sessionversion_remote = -1;
07301    p->session_modify = TRUE;
07302    p->stimer = NULL;
07303    p->prefs = default_prefs;     /* Set default codecs for this call */
07304    p->maxforwards = sip_cfg.default_max_forwards;
07305 
07306    if (intended_method != SIP_OPTIONS) {  /* Peerpoke has it's own system */
07307       p->timer_t1 = global_t1;   /* Default SIP retransmission timer T1 (RFC 3261) */
07308       p->timer_b = global_timer_b;  /* Default SIP transaction timer B (RFC 3261) */
07309    }
07310 
07311    if (!addr) {
07312       p->ourip = internip;
07313    } else {
07314       ast_sockaddr_copy(&p->sa, addr);
07315       ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
07316    }
07317 
07318    /* Copy global flags to this PVT at setup. */
07319    ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
07320    ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
07321    ast_copy_flags(&p->flags[2], &global_flags[2], SIP_PAGE3_FLAGS_TO_COPY);
07322 
07323    p->do_history = recordhistory;
07324 
07325    p->branch = ast_random();  
07326    make_our_tag(p->tag, sizeof(p->tag));
07327    p->ocseq = INITIAL_CSEQ;
07328    p->allowed_methods = UINT_MAX;
07329 
07330    if (sip_methods[intended_method].need_rtp) {
07331       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) {
07332          if ((p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &bindaddr))) {
07333             ast_udptl_setqos(p->udptl, global_tos_audio, global_cos_audio);
07334             p->t38_maxdatagram = global_t38_maxdatagram;
07335          } else {
07336             /* udptl creation failed, T38 can not be supported on this dialog */
07337             ast_log(LOG_ERROR, "UDPTL creation failed\n");
07338             ast_clear_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT);
07339          }
07340       }
07341       p->maxcallbitrate = default_maxcallbitrate;
07342       p->autoframing = global_autoframing;
07343    }
07344 
07345    if (useglobal_nat && addr) {
07346       /* Setup NAT structure according to global settings if we have an address */
07347       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT);
07348       ast_sockaddr_copy(&p->recv, addr);
07349 
07350       do_setnat(p);
07351    }
07352 
07353    if (p->method != SIP_REGISTER) {
07354       ast_string_field_set(p, fromdomain, default_fromdomain);
07355       p->fromdomainport = default_fromdomainport;
07356    }
07357    build_via(p);
07358    if (!callid)
07359       build_callid_pvt(p);
07360    else
07361       ast_string_field_set(p, callid, callid);
07362    /* Assign default music on hold class */
07363    ast_string_field_set(p, mohinterpret, default_mohinterpret);
07364    ast_string_field_set(p, mohsuggest, default_mohsuggest);
07365    p->capability = sip_cfg.capability;
07366    p->allowtransfer = sip_cfg.allowtransfer;
07367    if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
07368        (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
07369       p->noncodeccapability |= AST_RTP_DTMF;
07370    if (p->udptl) {
07371       p->t38_maxdatagram = global_t38_maxdatagram;
07372       set_t38_capabilities(p);
07373    }
07374    ast_string_field_set(p, context, sip_cfg.default_context);
07375    ast_string_field_set(p, parkinglot, default_parkinglot);
07376    ast_string_field_set(p, engine, default_engine);
07377 
07378    AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue);
07379 
07380    /* Add to active dialog list */
07381 
07382    ao2_t_link(dialogs, p, "link pvt into dialogs table");
07383    
07384    ast_debug(1, "Allocating new SIP dialog for %s - %s (%s)\n", callid ? callid : p->callid, sip_methods[intended_method].text, p->rtp ? "With RTP" : "No RTP");
07385    return p;
07386 }

static void sip_alreadygone ( struct sip_pvt *  dialog  )  [static]

Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.

Definition at line 2999 of file chan_sip.c.

References ast_debug.

Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_publish(), handle_response_subscribe(), retrans_pkt(), sip_indicate(), and sip_sipredirect().

03000 {
03001    ast_debug(3, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid);
03002    dialog->alreadygone = 1;
03003 }

static int sip_answer ( struct ast_channel *  ast  )  [static]

sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface

Definition at line 6184 of file chan_sip.c.

References ast_channel::_state, ast_debug, ast_rtp_instance_update_source(), ast_set_flag, ast_setstate(), AST_STATE_UP, FALSE, ast_channel::name, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_response_with_sdp(), TRUE, and try_suggested_sip_codec().

06185 {
06186    int res = 0;
06187    struct sip_pvt *p = ast->tech_pvt;
06188 
06189    sip_pvt_lock(p);
06190    if (ast->_state != AST_STATE_UP) {
06191       try_suggested_sip_codec(p);   
06192 
06193       ast_setstate(ast, AST_STATE_UP);
06194       ast_debug(1, "SIP answering channel: %s\n", ast->name);
06195       ast_rtp_instance_update_source(p->rtp);
06196       res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL, FALSE, TRUE);
06197       ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
06198    }
06199    sip_pvt_unlock(p);
06200    return res;
06201 }

static int sip_call ( struct ast_channel *  ast,
char *  dest,
int  timeout 
) [static]

Initiate SIP call from PBX used from the dial() application.

Definition at line 5274 of file chan_sip.c.

References ast_channel::_state, ao2_t_ref, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_USER_BUSY, ast_cc_get_monitor_by_recall_core_id(), ast_cc_is_recall(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_clear_flag, ast_copy_string(), ast_debug, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), ast_party_id_presentation(), ast_rtp_instance_available_formats(), AST_SCHED_REPLACE_UNREF, ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_test_flag, ast_var_name(), ast_var_value(), auto_congest(), ast_channel::caller, cid_name, ast_channel::hangupcause, ast_party_caller::id, LOG_WARNING, ast_channel::name, ast_cc_monitor::private_data, setup_srtp(), sip_pvt_lock, sip_pvt_unlock, sipdebug, ast_channel::tech_pvt, transmit_invite(), update_call_counter(), and ast_channel::varshead.

05275 {
05276    int res;
05277    struct sip_pvt *p = ast->tech_pvt;  /* chan is locked, so the reference cannot go away */
05278    struct varshead *headp;
05279    struct ast_var_t *current;
05280    const char *referer = NULL;   /* SIP referrer */
05281    int cc_core_id;
05282    char uri[SIPBUFSIZE] = "";
05283 
05284    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
05285       ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name);
05286       return -1;
05287    }
05288 
05289    if (ast_cc_is_recall(ast, &cc_core_id, "SIP")) {
05290       char device_name[AST_CHANNEL_NAME];
05291       struct ast_cc_monitor *recall_monitor;
05292       struct sip_monitor_instance *monitor_instance;
05293       ast_channel_get_device_name(ast, device_name, sizeof(device_name));
05294       if ((recall_monitor = ast_cc_get_monitor_by_recall_core_id(cc_core_id, device_name))) {
05295          monitor_instance = recall_monitor->private_data;
05296          ast_copy_string(uri, monitor_instance->notify_uri, sizeof(uri));
05297          ao2_t_ref(recall_monitor, -1, "Got the URI we need so unreffing monitor");
05298       }
05299    }
05300 
05301    /* Check whether there is vxml_url, distinctive ring variables */
05302    headp=&ast->varshead;
05303    AST_LIST_TRAVERSE(headp, current, entries) {
05304       /* Check whether there is a VXML_URL variable */
05305       if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) {
05306          p->options->vxml_url = ast_var_value(current);
05307       } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) {
05308          p->options->uri_options = ast_var_value(current);
05309       } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
05310          /* Check whether there is a variable with a name starting with SIPADDHEADER */
05311          p->options->addsipheaders = 1;
05312       } else if (!strcasecmp(ast_var_name(current), "SIPFROMDOMAIN")) {
05313          ast_string_field_set(p, fromdomain, ast_var_value(current));
05314       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) {
05315          /* This is a transfered call */
05316          p->options->transfer = 1;
05317       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) {
05318          /* This is the referrer */
05319          referer = ast_var_value(current);
05320       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) {
05321          /* We're replacing a call. */
05322          p->options->replaces = ast_var_value(current);
05323       } else if (!strcasecmp(ast_var_name(current), "SIP_MAX_FORWARDS")) {
05324          if (sscanf(ast_var_value(current), "%d", &(p->maxforwards)) != 1) {
05325             ast_log(LOG_WARNING, "The SIP_MAX_FORWARDS channel variable is not a valid integer.");
05326          }
05327       }
05328    }
05329 
05330    /* Check to see if we should try to force encryption */
05331    if (p->req_secure_signaling && p->socket.type != SIP_TRANSPORT_TLS) {
05332       ast_log(LOG_WARNING, "Encrypted signaling is required\n");
05333       ast->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05334       return -1;
05335    }
05336 
05337    if (ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) {
05338       if (ast_test_flag(&p->flags[0], SIP_REINVITE)) {
05339          ast_debug(1, "Direct media not possible when using SRTP, ignoring canreinvite setting\n");
05340          ast_clear_flag(&p->flags[0], SIP_REINVITE);
05341       }
05342 
05343       if (p->rtp && !p->srtp && setup_srtp(&p->srtp) < 0) {
05344          ast_log(LOG_WARNING, "SRTP audio setup failed\n");
05345          return -1;
05346       }
05347 
05348       if (p->vrtp && !p->vsrtp && setup_srtp(&p->vsrtp) < 0) {
05349          ast_log(LOG_WARNING, "SRTP video setup failed\n");
05350          return -1;
05351       }
05352 
05353       if (p->trtp && !p->vsrtp && setup_srtp(&p->tsrtp) < 0) {
05354          ast_log(LOG_WARNING, "SRTP text setup failed\n");
05355          return -1;
05356       }
05357    }
05358 
05359    res = 0;
05360    ast_set_flag(&p->flags[0], SIP_OUTGOING);
05361 
05362    /* T.38 re-INVITE FAX detection should never be done for outgoing calls,
05363     * so ensure it is disabled.
05364     */
05365    ast_clear_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_T38);
05366 
05367    if (p->options->transfer) {
05368       char buf[SIPBUFSIZE/2];
05369 
05370       if (referer) {
05371          if (sipdebug)
05372             ast_debug(3, "Call for %s transfered by %s\n", p->username, referer);
05373          snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer);
05374       } else
05375          snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name);
05376       ast_string_field_set(p, cid_name, buf);
05377    }
05378    ast_debug(1, "Outgoing Call for %s\n", p->username);
05379 
05380    res = update_call_counter(p, INC_CALL_RINGING);
05381 
05382    if (res == -1) {
05383       ast->hangupcause = AST_CAUSE_USER_BUSY;
05384       return res;
05385    }
05386    p->callingpres = ast_party_id_presentation(&ast->caller.id);
05387    p->jointcapability = ast_rtp_instance_available_formats(p->rtp, p->capability, p->prefcodec);
05388    p->jointnoncodeccapability = p->noncodeccapability;
05389 
05390    /* If there are no audio formats left to offer, punt */
05391    if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
05392       ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username);
05393       res = -1;
05394    } else {
05395       int xmitres;
05396 
05397       sip_pvt_lock(p);
05398       xmitres = transmit_invite(p, SIP_INVITE, 1, 2, uri);
05399       sip_pvt_unlock(p);
05400       if (xmitres == XMIT_ERROR)
05401          return -1;
05402       p->invitestate = INV_CALLING;
05403 
05404       /* Initialize auto-congest time */
05405       AST_SCHED_REPLACE_UNREF(p->initid, sched, p->timer_b, auto_congest, p,
05406                         dialog_unref(_data, "dialog ptr dec when SCHED_REPLACE del op succeeded"),
05407                         dialog_unref(p, "dialog ptr dec when SCHED_REPLACE add failed"),
05408                         dialog_ref(p, "dialog ptr inc when SCHED_REPLACE add succeeded") );
05409    }
05410    return res;
05411 }

int sip_cancel_destroy ( struct sip_pvt *  p  ) 

Cancel destruction of SIP dialog. Be careful as this also absorbs the reference - if you call it from within the scheduler, this might be the last reference.

Definition at line 3863 of file chan_sip.c.

References append_history, and ast_sched_del().

Referenced by handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), sip_hangup(), and sip_scheddestroy().

03864 {
03865    int res = 0;
03866 
03867    if (p->final_destruction_scheduled) {
03868       return res;
03869    }
03870 
03871    if (p->autokillid > -1) {
03872       int res3;
03873 
03874       if (!(res3 = ast_sched_del(sched, p->autokillid))) {
03875          append_history(p, "CancelDestroy", "");
03876          p->autokillid = -1;
03877          dialog_unref(p, "dialog unrefd because autokillid is de-sched'd");
03878       }
03879    }
03880    return res;
03881 }

static void sip_cc_agent_destructor ( struct ast_cc_agent *  agent  )  [static]

Definition at line 1784 of file chan_sip.c.

References ast_free, ast_test_flag, ast_cc_agent::private_data, sip_cc_agent_stop_offer_timer(), sip_pvt_lock, sip_pvt_unlock, and transmit_response().

01785 {
01786    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01787 
01788    if (!agent_pvt) {
01789       /* The agent constructor probably failed. */
01790       return;
01791    }
01792 
01793    sip_cc_agent_stop_offer_timer(agent);
01794    if (agent_pvt->subscribe_pvt) {
01795       sip_pvt_lock(agent_pvt->subscribe_pvt);
01796       if (!ast_test_flag(&agent_pvt->subscribe_pvt->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
01797          /* If we haven't sent a 200 OK for the SUBSCRIBE dialog yet, then we need to send a response letting
01798           * the subscriber know something went wrong
01799           */
01800          transmit_response(agent_pvt->subscribe_pvt, "500 Internal Server Error", &agent_pvt->subscribe_pvt->initreq);
01801       }
01802       sip_pvt_unlock(agent_pvt->subscribe_pvt);
01803       agent_pvt->subscribe_pvt = dialog_unref(agent_pvt->subscribe_pvt, "SIP CC agent destructor: Remove ref to subscription");
01804    }
01805    ast_free(agent_pvt);
01806 }

static int sip_cc_agent_init ( struct ast_cc_agent *  agent,
struct ast_channel *  chan 
) [static]

Definition at line 1671 of file chan_sip.c.

References ast_assert, ast_calloc, ast_copy_string(), ast_set_flag, ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech, ast_channel::tech_pvt, and ast_channel_tech::type.

01672 {
01673    struct sip_cc_agent_pvt *agent_pvt = ast_calloc(1, sizeof(*agent_pvt));
01674    struct sip_pvt *call_pvt = chan->tech_pvt;
01675 
01676    if (!agent_pvt) {
01677       return -1;
01678    }
01679 
01680    ast_assert(!strcmp(chan->tech->type, "SIP"));
01681 
01682    ast_copy_string(agent_pvt->original_callid, call_pvt->callid, sizeof(agent_pvt->original_callid));
01683    ast_copy_string(agent_pvt->original_exten, call_pvt->exten, sizeof(agent_pvt->original_exten));
01684    agent_pvt->offer_timer_id = -1;
01685    agent->private_data = agent_pvt;
01686    sip_pvt_lock(call_pvt);
01687    ast_set_flag(&call_pvt->flags[0], SIP_OFFER_CC);
01688    sip_pvt_unlock(call_pvt);
01689    return 0;
01690 }

static int sip_cc_agent_recall ( struct ast_cc_agent *  agent  )  [static]

Definition at line 1764 of file chan_sip.c.

References ast_cc_agent_caller_busy(), ast_cc_agent::core_id, ast_cc_agent::device_name, ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, and transmit_cc_notify().

01765 {
01766    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01767    /* If we have received a PUBLISH beforehand stating that the caller in question
01768     * is not available, we can save ourself a bit of effort here and just report
01769     * the caller as busy
01770     */
01771    if (!agent_pvt->is_available) {
01772       return ast_cc_agent_caller_busy(agent->core_id, "Caller %s is busy, reporting to the core",
01773             agent->device_name);
01774    }
01775    /* Otherwise, we transmit a NOTIFY to the caller and await either
01776     * a PUBLISH or an INVITE
01777     */
01778    sip_pvt_lock(agent_pvt->subscribe_pvt);
01779    transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_READY);
01780    sip_pvt_unlock(agent_pvt->subscribe_pvt);
01781    return 0;
01782 }

static void sip_cc_agent_respond ( struct ast_cc_agent *  agent,
enum ast_cc_agent_response_reason  reason 
) [static]

Definition at line 1720 of file chan_sip.c.

References AST_CC_AGENT_RESPONSE_SUCCESS, ast_set_flag, ast_strlen_zero(), ast_cc_agent::private_data, sip_pvt_lock, sip_pvt_unlock, transmit_cc_notify(), transmit_response(), and TRUE.

01721 {
01722    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01723 
01724    sip_pvt_lock(agent_pvt->subscribe_pvt);
01725    ast_set_flag(&agent_pvt->subscribe_pvt->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
01726    if (reason == AST_CC_AGENT_RESPONSE_SUCCESS || !ast_strlen_zero(agent_pvt->notify_uri)) {
01727       /* The second half of this if statement may be a bit hard to grasp,
01728        * so here's an explanation. When a subscription comes into
01729        * chan_sip, as long as it is not malformed, it will be passed
01730        * to the CC core. If the core senses an out-of-order state transition,
01731        * then the core will call this callback with the "reason" set to a
01732        * failure condition.
01733        * However, an out-of-order state transition will occur during a resubscription
01734        * for CC. In such a case, we can see that we have already generated a notify_uri
01735        * and so we can detect that this isn't a *real* failure. Rather, it is just
01736        * something the core doesn't recognize as a legitimate SIP state transition.
01737        * Thus we respond with happiness and flowers.
01738        */
01739       transmit_response(agent_pvt->subscribe_pvt, "200 OK", &agent_pvt->subscribe_pvt->initreq);
01740       transmit_cc_notify(agent, agent_pvt->subscribe_pvt, CC_QUEUED);
01741    } else {
01742       transmit_response(agent_pvt->subscribe_pvt, "500 Internal Error", &agent_pvt->subscribe_pvt->initreq);
01743    }
01744    sip_pvt_unlock(agent_pvt->subscribe_pvt);
01745    agent_pvt->is_available = TRUE;
01746 }

static int sip_cc_agent_start_monitoring ( struct ast_cc_agent *  agent  )  [static]

Definition at line 1755 of file chan_sip.c.

01756 {
01757    /* To start monitoring just means to wait for an incoming PUBLISH
01758     * to tell us that the caller has become available again. No special
01759     * action is needed
01760     */
01761    return 0;
01762 }

static int sip_cc_agent_start_offer_timer ( struct ast_cc_agent *  agent  )  [static]

Definition at line 1702 of file chan_sip.c.

References ast_get_cc_offer_timer(), ast_sched_add(), ast_cc_agent::cc_params, ast_cc_agent::private_data, sched, and sip_offer_timer_expire().

01703 {
01704    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01705    int when;
01706 
01707    when = ast_get_cc_offer_timer(agent->cc_params) * 1000;
01708    agent_pvt->offer_timer_id = ast_sched_add(sched, when, sip_offer_timer_expire, agent);
01709    return 0;
01710 }

static int sip_cc_agent_status_request ( struct ast_cc_agent *  agent  )  [static]

Definition at line 1748 of file chan_sip.c.

References ast_cc_agent_status_response(), AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, ast_device_state(), ast_cc_agent::core_id, and ast_cc_agent::private_data.

01749 {
01750    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01751    enum ast_device_state state = agent_pvt->is_available ? AST_DEVICE_NOT_INUSE : AST_DEVICE_INUSE;
01752    return ast_cc_agent_status_response(agent->core_id, state);
01753 }

static int sip_cc_agent_stop_offer_timer ( struct ast_cc_agent *  agent  )  [static]

Definition at line 1712 of file chan_sip.c.

References AST_SCHED_DEL, ast_cc_agent::private_data, and sched.

Referenced by sip_cc_agent_destructor().

01713 {
01714    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01715 
01716    AST_SCHED_DEL(sched, agent_pvt->offer_timer_id);
01717    return 0;
01718 }

static int sip_cc_monitor_cancel_available_timer ( struct ast_cc_monitor *  monitor,
int *  sched_id 
) [static]

Definition at line 2022 of file chan_sip.c.

References ao2_t_ref, AST_SCHED_DEL, monitor, and sched.

02023 {
02024    if (*sched_id != -1) {
02025       AST_SCHED_DEL(sched, *sched_id);
02026       ao2_t_ref(monitor, -1, "Removing scheduler's reference to the monitor");
02027    }
02028    return 0;
02029 }

static void sip_cc_monitor_destructor ( void *  private_data  )  [static]

Definition at line 2031 of file chan_sip.c.

References ao2_unlink, ast_module_unref(), and sip_monitor_instances.

02032 {
02033    struct sip_monitor_instance *monitor_instance = private_data;
02034    ao2_unlink(sip_monitor_instances, monitor_instance);
02035    ast_module_unref(ast_module_info->self);
02036 }

static int sip_cc_monitor_request_cc ( struct ast_cc_monitor *  monitor,
int *  available_timer_id 
) [static]

Definition at line 1890 of file chan_sip.c.

References ao2_t_ref, ast_cc_available_timer_expire(), AST_CC_CCBS, ast_get_ccbs_available_timer(), ast_get_ccnr_available_timer(), ast_sched_add(), ast_sip_ouraddrfor(), create_addr(), FALSE, monitor, sched, service, sip_alloc(), sip_pvt_lock, sip_pvt_unlock, and transmit_invite().

01891 {
01892    struct sip_monitor_instance *monitor_instance = monitor->private_data;
01893    enum ast_cc_service_type service = monitor->service_offered;
01894    int when;
01895 
01896    if (!monitor_instance) {
01897       return -1;
01898    }
01899 
01900    if (!(monitor_instance->subscription_pvt = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL))) {
01901       return -1;
01902    }
01903 
01904    when = service == AST_CC_CCBS ? ast_get_ccbs_available_timer(monitor->interface->config_params) :
01905       ast_get_ccnr_available_timer(monitor->interface->config_params);
01906 
01907    sip_pvt_lock(monitor_instance->subscription_pvt);
01908    create_addr(monitor_instance->subscription_pvt, monitor_instance->peername, 0, 1, NULL);
01909    ast_sip_ouraddrfor(&monitor_instance->subscription_pvt->sa, &monitor_instance->subscription_pvt->ourip, monitor_instance->subscription_pvt);
01910    monitor_instance->subscription_pvt->subscribed = CALL_COMPLETION;
01911    monitor_instance->subscription_pvt->expiry = when;
01912 
01913    transmit_invite(monitor_instance->subscription_pvt, SIP_SUBSCRIBE, FALSE, 2, monitor_instance->subscribe_uri);
01914    sip_pvt_unlock(monitor_instance->subscription_pvt);
01915 
01916    ao2_t_ref(monitor, +1, "Adding a ref to the monitor for the scheduler");
01917    *available_timer_id = ast_sched_add(sched, when * 1000, ast_cc_available_timer_expire, monitor);
01918    return 0;
01919 }

static int sip_cc_monitor_suspend ( struct ast_cc_monitor *  monitor  )  [static]

Definition at line 1947 of file chan_sip.c.

References ao2_ref, ast_calloc, ast_log(), ast_strlen_zero(), construct_pidf_body(), create_epa_entry(), LOG_WARNING, monitor, and transmit_publish().

01948 {
01949    struct sip_monitor_instance *monitor_instance = monitor->private_data;
01950    enum sip_publish_type publish_type;
01951    struct cc_epa_entry *cc_entry;
01952 
01953    if (!monitor_instance) {
01954       return -1;
01955    }
01956 
01957    if (!monitor_instance->suspension_entry) {
01958       /* We haven't yet allocated the suspension entry, so let's give it a shot */
01959       if (!(monitor_instance->suspension_entry = create_epa_entry("call-completion", monitor_instance->peername))) {
01960          ast_log(LOG_WARNING, "Unable to allocate sip EPA entry for call-completion\n");
01961          ao2_ref(monitor_instance, -1);
01962          return -1;
01963       }
01964       if (!(cc_entry = ast_calloc(1, sizeof(*cc_entry)))) {
01965          ast_log(LOG_WARNING, "Unable to allocate space for instance data of EPA entry for call-completion\n");
01966          ao2_ref(monitor_instance, -1);
01967          return -1;
01968       }
01969       cc_entry->core_id = monitor->core_id;
01970       monitor_instance->suspension_entry->instance_data = cc_entry;
01971       publish_type = SIP_PUBLISH_INITIAL;
01972    } else {
01973       publish_type = SIP_PUBLISH_MODIFY;
01974       cc_entry = monitor_instance->suspension_entry->instance_data;
01975    }
01976 
01977    cc_entry->current_state = CC_CLOSED;
01978 
01979    if (ast_strlen_zero(monitor_instance->notify_uri)) {
01980       /* If we have no set notify_uri, then what this means is that we have
01981        * not received a NOTIFY from this destination stating that he is
01982        * currently available.
01983        *
01984        * This situation can arise when the core calls the suspend callbacks
01985        * of multiple destinations. If one of the other destinations aside
01986        * from this one notified Asterisk that he is available, then there
01987        * is no reason to take any suspension action on this device. Rather,
01988        * we should return now and if we receive a NOTIFY while monitoring
01989        * is still "suspended" then we can immediately respond with the
01990        * proper PUBLISH to let this endpoint know what is going on.
01991        */
01992       return 0;
01993    }
01994    construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername);
01995    return transmit_publish(monitor_instance->suspension_entry, publish_type, monitor_instance->notify_uri);
01996 }

static int sip_cc_monitor_unsuspend ( struct ast_cc_monitor *  monitor  )  [static]

Definition at line 1998 of file chan_sip.c.

References ast_assert, ast_strlen_zero(), construct_pidf_body(), monitor, and transmit_publish().

01999 {
02000    struct sip_monitor_instance *monitor_instance = monitor->private_data;
02001    struct cc_epa_entry *cc_entry;
02002 
02003    if (!monitor_instance) {
02004       return -1;
02005    }
02006 
02007    ast_assert(monitor_instance->suspension_entry != NULL);
02008 
02009    cc_entry = monitor_instance->suspension_entry->instance_data;
02010    cc_entry->current_state = CC_OPEN;
02011    if (ast_strlen_zero(monitor_instance->notify_uri)) {
02012       /* This means we are being asked to unsuspend a call leg we never
02013        * sent a PUBLISH on. As such, there is no reason to send another
02014        * PUBLISH at this point either. We can just return instead.
02015        */
02016       return 0;
02017    }
02018    construct_pidf_body(CC_OPEN, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body), monitor_instance->peername);
02019    return transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_MODIFY, monitor_instance->notify_uri);
02020 }

static int sip_check_authtimeout ( time_t  start  )  [static]

Check if the authtimeout has expired.

Parameters:
start the time when the session started
Return values:
0 the timeout has expired
-1 error
Returns:
the number of milliseconds until the timeout will expire

Definition at line 2452 of file chan_sip.c.

References ast_log(), authtimeout, errno, and LOG_ERROR.

Referenced by _sip_tcp_helper_thread().

02453 {
02454    int timeout;
02455    time_t now;
02456    if(time(&now) == -1) {
02457       ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
02458       return -1;
02459    }
02460 
02461    timeout = (authtimeout - (now - start)) * 1000;
02462    if (timeout < 0) {
02463       /* we have timed out */
02464       return 0;
02465    }
02466 
02467    return timeout;
02468 }

static char * sip_cli_notify ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

Cli command to send SIP notify to peer.

Definition at line 18115 of file chan_sip.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_log(), ast_set_flag, ast_str_append(), ast_str_strlen(), ast_unescape_semicolon(), ast_variable_browse(), ast_variable_new(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, complete_sipnotify(), create_addr(), dialog_unlink_all(), ast_cli_args::fd, ast_cli_args::line, LOG_WARNING, ast_cli_args::n, notify_config, notify_types, ast_cli_args::pos, sip_alloc(), sip_notify_allocate(), TRUE, ast_cli_entry::usage, var, and ast_cli_args::word.

18116 {
18117    struct ast_variable *varlist;
18118    int i;
18119 
18120    switch (cmd) {
18121    case CLI_INIT:
18122       e->command = "sip notify";
18123       e->usage =
18124          "Usage: sip notify <type> <peer> [<peer>...]\n"
18125          "       Send a NOTIFY message to a SIP peer or peers\n"
18126          "       Message types are defined in sip_notify.conf\n";
18127       return NULL;
18128    case CLI_GENERATE:
18129       return complete_sipnotify(a->line, a->word, a->pos, a->n);
18130    }
18131 
18132    if (a->argc < 4)
18133       return CLI_SHOWUSAGE;
18134 
18135    if (!notify_types) {
18136       ast_cli(a->fd, "No %s file found, or no types listed there\n", notify_config);
18137       return CLI_FAILURE;
18138    }
18139 
18140    varlist = ast_variable_browse(notify_types, a->argv[2]);
18141 
18142    if (!varlist) {
18143       ast_cli(a->fd, "Unable to find notify type '%s'\n", a->argv[2]);
18144       return CLI_FAILURE;
18145    }
18146 
18147    for (i = 3; i < a->argc; i++) {
18148       struct sip_pvt *p;
18149       char buf[512];
18150       struct ast_variable *header, *var;
18151 
18152       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) {
18153          ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n");
18154          return CLI_FAILURE;
18155       }
18156 
18157       if (create_addr(p, a->argv[i], NULL, 1, NULL)) {
18158          /* Maybe they're not registered, etc. */
18159          dialog_unlink_all(p, TRUE, TRUE);
18160          dialog_unref(p, "unref dialog inside for loop" );
18161          /* sip_destroy(p); */
18162          ast_cli(a->fd, "Could not create address for '%s'\n", a->argv[i]);
18163          continue;
18164       }
18165 
18166       /* Notify is outgoing call */
18167       ast_set_flag(&p->flags[0], SIP_OUTGOING);
18168       sip_notify_allocate(p);
18169       p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", "");
18170 
18171       for (var = varlist; var; var = var->next) {
18172          ast_copy_string(buf, var->value, sizeof(buf));
18173          ast_unescape_semicolon(buf);
18174 
18175          if (!strcasecmp(var->name, "Content")) {
18176             if (ast_str_strlen(p->notify->content))
18177                ast_str_append(&p->notify->content, 0, "\r\n");
18178             ast_str_append(&p->notify->content, 0, "%s", buf);
18179          } else if (!strcasecmp(var->name, "Content-Length")) {
18180             ast_log(LOG_WARNING, "it is not necessary to specify Content-Length in sip_notify.conf, ignoring");
18181          } else {
18182             header->next = ast_variable_new(var->name, buf, "");
18183             header = header->next;
18184          }
18185       }
18186 
18187       /* Recalculate our side, and recalculate Call ID */
18188       ast_cli(a->fd, "Sending NOTIFY of type '%s' to '%s'\n", a->argv[2], a->argv[i]);
18189       dialog_ref(p, "bump the count of p, which transmit_sip_request will decrement.");
18190       sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
18191       transmit_invite(p, SIP_NOTIFY, 0, 2, NULL);
18192    }
18193 
18194    return CLI_SUCCESS;
18195 }

static int sip_debug_test_addr ( const struct ast_sockaddr *  addr  )  [inline, static]

See if we pass debug IP filter.

Definition at line 3096 of file chan_sip.c.

References ast_sockaddr_cmp(), ast_sockaddr_cmp_addr(), ast_sockaddr_isnull(), ast_sockaddr_port, debugaddr, and sipdebug.

Referenced by check_peer_ok(), handle_request_do(), and sip_debug_test_pvt().

03097 {
03098    /* Can't debug if sipdebug is not enabled */
03099    if (!sipdebug) {
03100       return 0;
03101    }
03102 
03103    /* A null debug_addr means we'll debug any address */
03104    if (ast_sockaddr_isnull(&debugaddr)) {
03105       return 1;
03106    }
03107 
03108    /* If no port was specified for a debug address, just compare the
03109     * addresses, otherwise compare the address and port
03110     */
03111    if (ast_sockaddr_port(&debugaddr)) {
03112       return !ast_sockaddr_cmp(&debugaddr, addr);
03113    } else {
03114       return !ast_sockaddr_cmp_addr(&debugaddr, addr);
03115    }
03116 }

static int sip_debug_test_pvt ( struct sip_pvt *  p  )  [inline, static]

Test PVT for debugging output.

Definition at line 3135 of file chan_sip.c.

References sip_debug_test_addr(), sip_real_dst(), and sipdebug.

Referenced by __sip_destroy(), add_sdp(), build_route(), check_via(), do_register_auth(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), handle_incoming(), process_sdp(), process_sdp_a_audio(), process_sdp_a_text(), process_sdp_a_video(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendhtml(), sip_sendtext(), and transmit_register().

03136 {
03137    if (!sipdebug) {
03138       return 0;
03139    }
03140    return sip_debug_test_addr(sip_real_dst(p));
03141 }

struct sip_pvt* sip_destroy ( struct sip_pvt *  p  ) 

Destroy SIP call structure. Make it return NULL so the caller can do things like foo = sip_destroy(foo); and reduce the chance of bugs due to dangling pointers.

Definition at line 5766 of file chan_sip.c.

References __sip_destroy(), ast_debug, and TRUE.

Referenced by sip_destroy_fn(), and sip_subscribe_mwi_destroy().

05767 {
05768    ast_debug(3, "Destroying SIP dialog %s\n", p->callid);
05769    __sip_destroy(p, TRUE, TRUE);
05770    return NULL;
05771 }

static void sip_destroy_fn ( void *  p  )  [static]

Definition at line 5756 of file chan_sip.c.

References sip_destroy().

Referenced by sip_alloc().

05757 {
05758    sip_destroy(p);
05759 }

static void sip_destroy_peer ( struct sip_peer *  peer  )  [static]

Destroy peer object from memory.

Definition at line 4471 of file chan_sip.c.

References ao2_ref, apeerobjs, ast_atomic_fetchadd_int(), ast_cc_config_params_destroy(), ast_debug, ast_dnsmgr_release(), ast_free_ha(), ast_string_field_free_memory, ast_variables_destroy(), clear_peer_mailboxes(), clear_realm_authentication(), dialog_unlink_all(), FALSE, register_peer_exten(), rpeerobjs, speerobjs, and TRUE.

Referenced by sip_destroy_peer_fn().

04472 {
04473    ast_debug(3, "Destroying SIP peer %s\n", peer->name);
04474    if (peer->outboundproxy)
04475       ao2_ref(peer->outboundproxy, -1);
04476    peer->outboundproxy = NULL;
04477 
04478    /* Delete it, it needs to disappear */
04479    if (peer->call) {
04480       dialog_unlink_all(peer->call, TRUE, TRUE);
04481       peer->call = dialog_unref(peer->call, "peer->call is being unset");
04482    }
04483    
04484 
04485    if (peer->mwipvt) {  /* We have an active subscription, delete it */
04486       dialog_unlink_all(peer->mwipvt, TRUE, TRUE);
04487       peer->mwipvt = dialog_unref(peer->mwipvt, "unreffing peer->mwipvt");
04488    }
04489    
04490    if (peer->chanvars) {
04491       ast_variables_destroy(peer->chanvars);
04492       peer->chanvars = NULL;
04493    }
04494    
04495    register_peer_exten(peer, FALSE);
04496    ast_free_ha(peer->ha);
04497    ast_free_ha(peer->directmediaha);
04498    if (peer->selfdestruct)
04499       ast_atomic_fetchadd_int(&apeerobjs, -1);
04500    else if (peer->is_realtime) {
04501       ast_atomic_fetchadd_int(&rpeerobjs, -1);
04502       ast_debug(3, "-REALTIME- peer Destroyed. Name: %s. Realtime Peer objects: %d\n", peer->name, rpeerobjs);
04503    } else
04504       ast_atomic_fetchadd_int(&speerobjs, -1);
04505    clear_realm_authentication(peer->auth);
04506    peer->auth = NULL;
04507    if (peer->dnsmgr)
04508       ast_dnsmgr_release(peer->dnsmgr);
04509    clear_peer_mailboxes(peer);
04510 
04511    if (peer->socket.tcptls_session) {
04512       ao2_ref(peer->socket.tcptls_session, -1);
04513       peer->socket.tcptls_session = NULL;
04514    }
04515 
04516    ast_cc_config_params_destroy(peer->cc_params);
04517 
04518    ast_string_field_free_memory(peer);
04519 }

static void sip_destroy_peer_fn ( void *  peer  )  [static]

Definition at line 4465 of file chan_sip.c.

References sip_destroy_peer().

Referenced by build_peer(), and temp_peer().

04466 {
04467    sip_destroy_peer(peer);
04468 }

static int sip_devicestate ( void *  data  )  [static]

Part of PBX channel interface.

Note:
Return values:---
If we have qualify on and the device is not reachable, regardless of registration state we return AST_DEVICE_UNAVAILABLE

For peers with call limit:

For peers without call limit:

Peers that does not have a known call and can't be reached by OPTIONS

If we return AST_DEVICE_UNKNOWN, the device state engine will try to find out a state by walking the channel list.

The queue system (app_queue.c) treats a member as "active" if devicestate is != AST_DEVICE_UNAVAILBALE && != AST_DEVICE_INVALID

When placing a call to the queue member, queue system sets a member to busy if != AST_DEVICE_NOT_INUSE and != AST_DEVICE_UNKNOWN

Definition at line 25225 of file chan_sip.c.

References ast_debug, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_sockaddr_isnull(), ast_strdupa, FALSE, find_peer(), TRUE, and unref_peer().

25226 {
25227    char *host;
25228    char *tmp;
25229    struct sip_peer *p;
25230 
25231    int res = AST_DEVICE_INVALID;
25232 
25233    /* make sure data is not null. Maybe unnecessary, but better be safe */
25234    host = ast_strdupa(data ? data : "");
25235    if ((tmp = strchr(host, '@')))
25236       host = tmp + 1;
25237 
25238    ast_debug(3, "Checking device state for peer %s\n", host);
25239 
25240    /* If find_peer asks for a realtime peer, then this breaks rtautoclear.  This
25241     * is because when a peer tries to autoexpire, the last thing it does is to
25242     * queue up an event telling the system that the devicestate has changed
25243     * (presumably to unavailable).  If we ask for a realtime peer here, this would
25244     * load it BACK into memory, thus defeating the point of trying to clear dead
25245     * hosts out of memory.
25246     */
25247    if ((p = find_peer(host, NULL, FALSE, FINDALLDEVICES, TRUE, 0))) {
25248       if (!(ast_sockaddr_isnull(&p->addr) && ast_sockaddr_isnull(&p->defaddr))) {
25249          /* we have an address for the peer */
25250       
25251          /* Check status in this order
25252             - Hold
25253             - Ringing
25254             - Busy (enforced only by call limit)
25255             - Inuse (we have a call)
25256             - Unreachable (qualify)
25257             If we don't find any of these state, report AST_DEVICE_NOT_INUSE
25258             for registered devices */
25259 
25260          if (p->onHold)
25261             /* First check for hold or ring states */
25262             res = AST_DEVICE_ONHOLD;
25263          else if (p->inRinging) {
25264             if (p->inRinging == p->inUse)
25265                res = AST_DEVICE_RINGING;
25266             else
25267                res = AST_DEVICE_RINGINUSE;
25268          } else if (p->call_limit && (p->inUse == p->call_limit))
25269             /* check call limit */
25270             res = AST_DEVICE_BUSY;
25271          else if (p->call_limit && p->busy_level && p->inUse >= p->busy_level)
25272             /* We're forcing busy before we've reached the call limit */
25273             res = AST_DEVICE_BUSY;
25274          else if (p->call_limit && p->inUse)
25275             /* Not busy, but we do have a call */
25276             res = AST_DEVICE_INUSE;
25277          else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0)))
25278             /* We don't have a call. Are we reachable at all? Requires qualify= */
25279             res = AST_DEVICE_UNAVAILABLE;
25280          else  /* Default reply if we're registered and have no other data */
25281             res = AST_DEVICE_NOT_INUSE;
25282       } else {
25283          /* there is no address, it's unavailable */
25284          res = AST_DEVICE_UNAVAILABLE;
25285       }
25286       unref_peer(p, "unref_peer, from sip_devicestate, release ref from find_peer");
25287    } else {
25288       res = AST_DEVICE_UNKNOWN;
25289    }
25290 
25291    return res;
25292 }

static char * sip_do_debug ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

Turn on SIP debugging (CLI command).

Note:
this can be a special debug command - "sip debug text" or something

Definition at line 18072 of file chan_sip.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_peer(), debugaddr, ast_cli_args::fd, ast_cli_args::n, ast_cli_args::pos, sip_do_debug_ip(), sip_do_debug_peer(), sipdebug_text, ast_cli_entry::usage, and ast_cli_args::word.

18073 {
18074    int oldsipdebug = sipdebug & sip_debug_console;
18075    const char *what;
18076 
18077    if (cmd == CLI_INIT) {
18078       e->command = "sip set debug {on|off|ip|peer}";
18079       e->usage =
18080          "Usage: sip set debug {off|on|ip addr[:port]|peer peername}\n"
18081          "       Globally disables dumping of SIP packets,\n"
18082          "       or enables it either globally or for a (single)\n"
18083          "       IP address or registered peer.\n";
18084       return NULL;
18085    } else if (cmd == CLI_GENERATE) {
18086       if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
18087          return complete_sip_peer(a->word, a->n, 0);
18088       return NULL;
18089         }
18090 
18091    what = a->argv[e->args-1];      /* guaranteed to exist */
18092    if (a->argc == e->args) {       /* on/off */
18093       if (!strcasecmp(what, "on")) {
18094          sipdebug |= sip_debug_console;
18095          sipdebug_text = 1;   /*! \note this can be a special debug command - "sip debug text" or something */
18096          memset(&debugaddr, 0, sizeof(debugaddr));
18097          ast_cli(a->fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
18098          return CLI_SUCCESS;
18099       } else if (!strcasecmp(what, "off")) {
18100          sipdebug &= ~sip_debug_console;
18101          sipdebug_text = 0;
18102          ast_cli(a->fd, "SIP Debugging Disabled\n");
18103          return CLI_SUCCESS;
18104       }
18105    } else if (a->argc == e->args +1) {/* ip/peer */
18106       if (!strcasecmp(what, "ip"))
18107          return sip_do_debug_ip(a->fd, a->argv[e->args]);
18108       else if (!strcasecmp(what, "peer"))
18109          return sip_do_debug_peer(a->fd, a->argv[e->args]);
18110    }
18111    return CLI_SHOWUSAGE;   /* default, failure */
18112 }

static char * sip_do_debug_ip ( int  fd,
const char *  arg 
) [static]

Enable SIP Debugging for a single IP.

Definition at line 18041 of file chan_sip.c.

References ast_cli(), ast_sockaddr_resolve_first(), ast_sockaddr_stringify_addr(), CLI_SHOWUSAGE, CLI_SUCCESS, and debugaddr.

Referenced by sip_do_debug().

18042 {
18043    if (ast_sockaddr_resolve_first(&debugaddr, arg, 0)) {
18044       return CLI_SHOWUSAGE;
18045    }
18046 
18047    ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr));
18048    sipdebug |= sip_debug_console;
18049 
18050    return CLI_SUCCESS;
18051 }

static char * sip_do_debug_peer ( int  fd,
const char *  arg 
) [static]

Turn on SIP debugging for a given peer.

Definition at line 18054 of file chan_sip.c.

References ast_cli(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_stringify_addr(), CLI_SUCCESS, debugaddr, FALSE, find_peer(), TRUE, and unref_peer().

Referenced by sip_do_debug().

18055 {
18056    struct sip_peer *peer = find_peer(arg, NULL, TRUE, FINDPEERS, FALSE, 0);
18057    if (!peer)
18058       ast_cli(fd, "No such peer '%s'\n", arg);
18059    else if (ast_sockaddr_isnull(&peer->addr))
18060       ast_cli(fd, "Unable to get IP address of peer '%s'\n", arg);
18061    else {
18062       ast_sockaddr_copy(&debugaddr, &peer->addr);
18063       ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_sockaddr_stringify_addr(&debugaddr));
18064       sipdebug |= sip_debug_console;
18065    }
18066    if (peer)
18067       unref_peer(peer, "sip_do_debug_peer: unref_peer, from find_peer call");
18068    return CLI_SUCCESS;
18069 }

static int sip_do_reload ( enum channelreloadreason  reason  )  [static]

Reload module.

Definition at line 28358 of file chan_sip.c.

References ast_debug, ast_sched_dump(), reload_config(), sip_poke_all_peers(), sip_send_all_mwi_subscriptions(), sip_send_all_registers(), and unlink_marked_peers_from_tables().

Referenced by do_monitor().

28359 {
28360    time_t start_poke, end_poke;
28361    
28362    reload_config(reason);
28363    ast_sched_dump(sched);
28364 
28365    start_poke = time(0);
28366    /* Prune peers who still are supposed to be deleted */
28367    unlink_marked_peers_from_tables();
28368 
28369    ast_debug(4, "--------------- Done destroying pruned peers\n");
28370 
28371    /* Send qualify (OPTIONS) to all peers */
28372    sip_poke_all_peers();
28373 
28374    /* Register with all services */
28375    sip_send_all_registers();
28376 
28377    sip_send_all_mwi_subscriptions();
28378 
28379    end_poke = time(0);
28380    
28381    ast_debug(4, "do_reload finished. peer poke/prune reg contact time = %d sec.\n", (int)(end_poke-start_poke));
28382 
28383    ast_debug(4, "--------------- SIP reload done\n");
28384 
28385    return 0;
28386 }

static int sip_dtmfmode ( struct ast_channel *  chan,
const char *  data 
) [static]

Set the DTMFmode for an outbound SIP call (application).

Definition at line 28046 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_log(), AST_RTP_DTMF, ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_DTMF, ast_set_flag, ast_test_flag, disable_dsp_detect(), enable_dsp_detect(), LOG_WARNING, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech, and ast_channel::tech_pvt.

Referenced by load_module().

28047 {
28048    struct sip_pvt *p;
28049    const char *mode = data;
28050 
28051    if (!data) {
28052       ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
28053       return 0;
28054    }
28055    ast_channel_lock(chan);
28056    if (!IS_SIP_TECH(chan->tech)) {
28057       ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
28058       ast_channel_unlock(chan);
28059       return 0;
28060    }
28061    p = chan->tech_pvt;
28062    if (!p) {
28063       ast_channel_unlock(chan);
28064       return 0;
28065    }
28066    sip_pvt_lock(p);
28067    if (!strcasecmp(mode, "info")) {
28068       ast_clear_flag(&p->flags[0], SIP_DTMF);
28069       ast_set_flag(&p->flags[0], SIP_DTMF_INFO);
28070       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
28071    } else if (!strcasecmp(mode, "shortinfo")) {
28072       ast_clear_flag(&p->flags[0], SIP_DTMF);
28073       ast_set_flag(&p->flags[0], SIP_DTMF_SHORTINFO);
28074       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
28075    } else if (!strcasecmp(mode, "rfc2833")) {
28076       ast_clear_flag(&p->flags[0], SIP_DTMF);
28077       ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
28078       p->jointnoncodeccapability |= AST_RTP_DTMF;
28079    } else if (!strcasecmp(mode, "inband")) {
28080       ast_clear_flag(&p->flags[0], SIP_DTMF);
28081       ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
28082       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
28083    } else {
28084       ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n", mode);
28085    }
28086    if (p->rtp)
28087       ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
28088    if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) ||
28089        (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
28090       enable_dsp_detect(p);
28091    } else {
28092       disable_dsp_detect(p);
28093    }
28094    sip_pvt_unlock(p);
28095    ast_channel_unlock(chan);
28096    return 0;
28097 }

static void sip_dump_history ( struct sip_pvt *  dialog  )  [static]

Dump SIP history to debug log file at end of lifespan for SIP dialog.

Definition at line 17826 of file chan_sip.c.

References ast_debug, AST_LIST_TRAVERSE, ast_log(), LOG_NOTICE, and option_debug.

Referenced by __sip_destroy().

17827 {
17828    int x = 0;
17829    struct sip_history *hist;
17830    static int errmsg = 0;
17831 
17832    if (!dialog)
17833       return;
17834 
17835    if (!option_debug && !sipdebug) {
17836       if (!errmsg) {
17837          ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n");
17838          errmsg = 1;
17839       }
17840       return;
17841    }
17842 
17843    ast_debug(1, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
17844    if (dialog->subscribed)
17845       ast_debug(1, "  * Subscription\n");
17846    else
17847       ast_debug(1, "  * SIP Call\n");
17848    if (dialog->history)
17849       AST_LIST_TRAVERSE(dialog->history, hist, list)
17850          ast_debug(1, "  %-3.3d. %s\n", ++x, hist->event);
17851    if (!x)
17852       ast_debug(1, "Call '%s' has no history\n", dialog->callid);
17853    ast_debug(1, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
17854 }

static int sip_epa_register ( const struct epa_static_data *  static_data  )  [static]

Definition at line 858 of file chan_sip.c.

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, and AST_LIST_UNLOCK.

Referenced by load_module().

00859 {
00860    struct epa_backend *backend = ast_calloc(1, sizeof(*backend));
00861 
00862    if (!backend) {
00863       return -1;
00864    }
00865 
00866    backend->static_data = static_data;
00867 
00868    AST_LIST_LOCK(&epa_static_data_list);
00869    AST_LIST_INSERT_TAIL(&epa_static_data_list, backend, next);
00870    AST_LIST_UNLOCK(&epa_static_data_list);
00871    return 0;
00872 }

static int sip_fixup ( struct ast_channel *  oldchan,
struct ast_channel *  newchan 
) [static]

sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links

Definition at line 6311 of file chan_sip.c.

References append_history, ast_debug, AST_FLAG_ZOMBIE, ast_log(), ast_test_flag, LOG_WARNING, ast_channel::name, sip_pvt_lock, sip_pvt_unlock, sip_set_rtp_peer(), and ast_channel::tech_pvt.

06312 {
06313    int ret = -1;
06314    struct sip_pvt *p;
06315 
06316    if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE))
06317       ast_debug(1, "New channel is zombie\n");
06318    if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE))
06319       ast_debug(1, "Old channel is zombie\n");
06320 
06321    if (!newchan || !newchan->tech_pvt) {
06322       if (!newchan)
06323          ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name);
06324       else
06325          ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name);
06326       return -1;
06327    }
06328    p = newchan->tech_pvt;
06329 
06330    sip_pvt_lock(p);
06331    append_history(p, "Masq", "Old channel: %s\n", oldchan->name);
06332    append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name);
06333    if (p->owner != oldchan)
06334       ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
06335    else {
06336       p->owner = newchan;
06337       /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native
06338          RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be
06339          able to do this if the masquerade happens before the bridge breaks (e.g., AMI
06340          redirect of both channels). Note that a channel can not be masqueraded *into*
06341          a native bridge. So there is no danger that this breaks a native bridge that
06342          should stay up. */
06343       sip_set_rtp_peer(newchan, NULL, NULL, 0, 0, 0);
06344       ret = 0;
06345    }
06346    ast_debug(3, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name);
06347 
06348    sip_pvt_unlock(p);
06349    return ret;
06350 }

static const char * sip_get_callid ( struct ast_channel *  chan  )  [static]

Deliver SIP call ID for the call.

Definition at line 4328 of file chan_sip.c.

References ast_channel::tech_pvt.

04329 {
04330    return chan->tech_pvt ? ((struct sip_pvt *) chan->tech_pvt)->callid : "";
04331 }

static int sip_get_cc_information ( struct sip_request *  req,
char *  subscribe_uri,
size_t  size,
enum ast_cc_service_type *  service 
) [static]

Definition at line 2038 of file chan_sip.c.

References AST_CC_NONE, ast_copy_string(), ast_strdupa, ast_strlen_zero(), get_header(), service_string_to_service_type(), and strsep().

Referenced by sip_handle_cc().

02039 {
02040    char *call_info = ast_strdupa(get_header(req, "Call-Info"));
02041    char *uri;
02042    char *purpose;
02043    char *service_str;
02044    static const char cc_purpose[] = "purpose=call-completion";
02045    static const int cc_purpose_len = sizeof(cc_purpose) - 1;
02046 
02047    if (ast_strlen_zero(call_info)) {
02048       /* No Call-Info present. Definitely no CC offer */
02049       return -1;
02050    }
02051 
02052    uri = strsep(&call_info, ";");
02053 
02054    while ((purpose = strsep(&call_info, ";"))) {
02055       if (!strncmp(purpose, cc_purpose, cc_purpose_len)) {
02056          break;
02057       }
02058    }
02059    if (!purpose) {
02060       /* We didn't find the appropriate purpose= parameter. Oh well */
02061       return -1;
02062    }
02063 
02064    /* Okay, call-completion has been offered. Let's figure out what type of service this is */
02065    while ((service_str = strsep(&call_info, ";"))) {
02066       if (!strncmp(service_str, "m=", 2)) {
02067          break;
02068       }
02069    }
02070    if (!service_str) {
02071       /* So they didn't offer a particular service, We'll just go with CCBS since it really
02072        * doesn't matter anyway
02073        */
02074       service_str = "BS";
02075    } else {
02076       /* We already determined that there is an "m=" so no need to check
02077        * the result of this strsep
02078        */
02079       strsep(&service_str, "=");
02080    }
02081 
02082    if ((*service = service_string_to_service_type(service_str)) == AST_CC_NONE) {
02083       /* Invalid service offered */
02084       return -1;
02085    }
02086 
02087    ast_copy_string(subscribe_uri, get_in_brackets(uri), size);
02088 
02089    return 0;
02090 }

static format_t sip_get_codec ( struct ast_channel *  chan  )  [static]

Definition at line 28026 of file chan_sip.c.

References ast_channel::tech_pvt.

28027 {
28028    struct sip_pvt *p = chan->tech_pvt;
28029    return p->peercapability ? p->peercapability : p->capability;
28030 }

static enum ast_rtp_glue_result sip_get_rtp_peer ( struct ast_channel *  chan,
struct ast_rtp_instance **  instance 
) [static]

Definition at line 27840 of file chan_sip.c.

References ao2_ref, apply_directmedia_ha(), AST_JB_FORCED, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, global_jbconf, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.

27841 {
27842    struct sip_pvt *p = NULL;
27843    enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL;
27844 
27845    if (!(p = chan->tech_pvt)) {
27846       return AST_RTP_GLUE_RESULT_FORBID;
27847    }
27848 
27849    sip_pvt_lock(p);
27850    if (!(p->rtp)) {
27851       sip_pvt_unlock(p);
27852       return AST_RTP_GLUE_RESULT_FORBID;
27853    }
27854 
27855    ao2_ref(p->rtp, +1);
27856    *instance = p->rtp;
27857 
27858    if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
27859       res = AST_RTP_GLUE_RESULT_REMOTE;
27860       if (!apply_directmedia_ha(p, "audio")) {
27861          res = AST_RTP_GLUE_RESULT_FORBID;
27862       }
27863    } else if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) {
27864       res = AST_RTP_GLUE_RESULT_REMOTE;
27865    } else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) {
27866       res = AST_RTP_GLUE_RESULT_FORBID;
27867    }
27868 
27869    if (p->srtp) {
27870       res = AST_RTP_GLUE_RESULT_FORBID;
27871    }
27872 
27873    sip_pvt_unlock(p);
27874 
27875    return res;
27876 }

static enum ast_rtp_glue_result sip_get_trtp_peer ( struct ast_channel *  chan,
struct ast_rtp_instance **  instance 
) [static]

Definition at line 27908 of file chan_sip.c.

References ao2_ref, apply_directmedia_ha(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.

27909 {
27910    struct sip_pvt *p = NULL;
27911    enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID;
27912 
27913    if (!(p = chan->tech_pvt)) {
27914       return AST_RTP_GLUE_RESULT_FORBID;
27915    }
27916 
27917    sip_pvt_lock(p);
27918    if (!(p->trtp)) {
27919       sip_pvt_unlock(p);
27920       return AST_RTP_GLUE_RESULT_FORBID;
27921    }
27922 
27923    ao2_ref(p->trtp, +1);
27924    *instance = p->trtp;
27925 
27926    if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
27927       res = AST_RTP_GLUE_RESULT_REMOTE;
27928       if (!apply_directmedia_ha(p, "text")) {
27929          res = AST_RTP_GLUE_RESULT_FORBID;
27930       }
27931    }
27932 
27933    sip_pvt_unlock(p);
27934 
27935    return res;
27936 }

static struct ast_udptl * sip_get_udptl_peer ( struct ast_channel *  chan  )  [static]

Definition at line 27775 of file chan_sip.c.

References apply_directmedia_ha(), ast_test_flag, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.

27776 {
27777    struct sip_pvt *p;
27778    struct ast_udptl *udptl = NULL;
27779    
27780    p = chan->tech_pvt;
27781    if (!p) {
27782       return NULL;
27783    }
27784    
27785    sip_pvt_lock(p);
27786    if (p->udptl && ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
27787       if (apply_directmedia_ha(p, "UDPTL T.38 data")) {
27788          udptl = p->udptl;
27789       }
27790    }
27791    sip_pvt_unlock(p);
27792    return udptl;
27793 }

static enum ast_rtp_glue_result sip_get_vrtp_peer ( struct ast_channel *  chan,
struct ast_rtp_instance **  instance 
) [static]

Definition at line 27878 of file chan_sip.c.

References ao2_ref, apply_directmedia_ha(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_REMOTE, ast_test_flag, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.

27879 {
27880    struct sip_pvt *p = NULL;
27881    enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID;
27882 
27883    if (!(p = chan->tech_pvt)) {
27884       return AST_RTP_GLUE_RESULT_FORBID;
27885    }
27886 
27887    sip_pvt_lock(p);
27888    if (!(p->vrtp)) {
27889       sip_pvt_unlock(p);
27890       return AST_RTP_GLUE_RESULT_FORBID;
27891    }
27892 
27893    ao2_ref(p->vrtp, +1);
27894    *instance = p->vrtp;
27895 
27896    if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
27897       res = AST_RTP_GLUE_RESULT_REMOTE;
27898       if (!apply_directmedia_ha(p, "video")) {
27899          res = AST_RTP_GLUE_RESULT_FORBID;
27900       }
27901    }
27902 
27903    sip_pvt_unlock(p);
27904 
27905    return res;
27906 }

static void sip_handle_cc ( struct sip_pvt *  pvt,
struct sip_request *  req,
enum ast_cc_service_type  service 
) [static]

Definition at line 2109 of file chan_sip.c.

References ao2_ref, AST_CC_GENERIC_MONITOR_TYPE, ast_cc_get_current_core_id(), AST_CC_MONITOR_ALWAYS, AST_CC_MONITOR_GENERIC, AST_CC_MONITOR_NATIVE, AST_CC_MONITOR_NEVER, ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_get_cc_monitor_policy(), ast_module_ref(), ast_queue_cc_frame(), sip_get_cc_information(), and sip_monitor_instance_init().

Referenced by handle_response(), and handle_response_invite().

02110 {
02111    enum ast_cc_monitor_policies monitor_policy = ast_get_cc_monitor_policy(pvt->cc_params);
02112    int core_id;
02113    char interface_name[AST_CHANNEL_NAME];
02114 
02115    if (monitor_policy == AST_CC_MONITOR_NEVER) {
02116       /* Don't bother, just return */
02117       return;
02118    }
02119 
02120    if ((core_id = ast_cc_get_current_core_id(pvt->owner)) == -1) {
02121       /* For some reason, CC is invalid, so don't try it! */
02122       return;
02123    }
02124 
02125    ast_channel_get_device_name(pvt->owner, interface_name, sizeof(interface_name));
02126 
02127    if (monitor_policy == AST_CC_MONITOR_ALWAYS || monitor_policy == AST_CC_MONITOR_NATIVE) {
02128       char subscribe_uri[SIPBUFSIZE];
02129       char device_name[AST_CHANNEL_NAME];
02130       enum ast_cc_service_type offered_service;
02131       struct sip_monitor_instance *monitor_instance;
02132       if (sip_get_cc_information(req, subscribe_uri, sizeof(subscribe_uri), &offered_service)) {
02133          /* If CC isn't being offered to us, or for some reason the CC offer is
02134           * not formatted correctly, then it may still be possible to use generic
02135           * call completion since the monitor policy may be "always"
02136           */
02137          goto generic;
02138       }
02139       ast_channel_get_device_name(pvt->owner, device_name, sizeof(device_name));
02140       if (!(monitor_instance = sip_monitor_instance_init(core_id, subscribe_uri, pvt->peername, device_name))) {
02141          /* Same deal. We can try using generic still */
02142          goto generic;
02143       }
02144       /* We bump the refcount of chan_sip because once we queue this frame, the CC core
02145        * will have a reference to callbacks in this module. We decrement the module
02146        * refcount once the monitor destructor is called
02147        */
02148       ast_module_ref(ast_module_info->self);
02149       ast_queue_cc_frame(pvt->owner, "SIP", pvt->dialstring, offered_service, monitor_instance);
02150       ao2_ref(monitor_instance, -1);
02151       return;
02152    }
02153 
02154 generic:
02155    if (monitor_policy == AST_CC_MONITOR_GENERIC || monitor_policy == AST_CC_MONITOR_ALWAYS) {
02156       ast_queue_cc_frame(pvt->owner, AST_CC_GENERIC_MONITOR_TYPE, interface_name, service, NULL);
02157    }
02158 }

static int sip_hangup ( struct ast_channel *  ast  )  [static]

sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup

Definition at line 5945 of file chan_sip.c.

References __sip_semi_ack(), ast_channel::_state, append_history, ast_bridged_channel(), ast_cause2str(), AST_CAUSE_ANSWERED_ELSEWHERE, ast_channel_trylock, ast_channel_unlock, ast_clear_flag, ast_debug, AST_FLAG_ANSWERED_ELSEWHERE, AST_FLAG_ZOMBIE, ast_log(), AST_MAX_USER_FIELD, ast_module_unref(), ast_rtp_instance_get_quality(), ast_rtp_instance_set_stats_vars(), AST_RTP_INSTANCE_STAT_FIELD_QUALITY, AST_SCHED_DEL_UNREF, ast_set_flag, ast_state2str(), AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_channel::bridge, CHANNEL_DEADLOCK_AVOIDANCE, disable_dsp_detect(), FALSE, find_sip_method(), hangup_cause2sip(), ast_channel::hangupcause, LOG_WARNING, ast_channel::name, pbx_builtin_setvar_helper(), pvt_set_needdestroy(), quality, sip_cancel_destroy(), sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_scheddestroy(), sipdebug, stop_media_flows(), stop_session_timer(), ast_channel::tech, ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, and update_call_counter().

05946 {
05947    struct sip_pvt *p = ast->tech_pvt;
05948    int needcancel = FALSE;
05949    int needdestroy = 0;
05950    struct ast_channel *oldowner = ast;
05951 
05952    if (!p) {
05953       ast_debug(1, "Asked to hangup channel that was not connected\n");
05954       return 0;
05955    }
05956    if (ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE) || ast->hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE) {
05957       ast_debug(1, "This call was answered elsewhere");
05958       if (ast->hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE) {
05959          ast_debug(1, "####### It's the cause code, buddy. The cause code!!!\n");
05960       }
05961       append_history(p, "Cancel", "Call answered elsewhere");
05962       p->answered_elsewhere = TRUE;
05963    }
05964 
05965    /* Store hangupcause locally in PVT so we still have it before disconnect */
05966    if (p->owner)
05967       p->hangupcause = p->owner->hangupcause;
05968 
05969    if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
05970       if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
05971          if (sipdebug)
05972             ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
05973          update_call_counter(p, DEC_CALL_LIMIT);
05974       }
05975       ast_debug(4, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid);
05976       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
05977       ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */
05978       p->needdestroy = 0;
05979       p->owner->tech_pvt = dialog_unref(p->owner->tech_pvt, "unref p->owner->tech_pvt");
05980       sip_pvt_lock(p);
05981       p->owner = NULL;  /* Owner will be gone after we return, so take it away */
05982       sip_pvt_unlock(p);
05983       ast_module_unref(ast_module_info->self);
05984       return 0;
05985    }
05986 
05987    if (ast_test_flag(ast, AST_FLAG_ZOMBIE)) {
05988       if (p->refer)
05989          ast_debug(1, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid);
05990       else
05991          ast_debug(1, "Hanging up zombie call. Be scared.\n");
05992    } else
05993       ast_debug(1, "Hangup call %s, SIP callid %s\n", ast->name, p->callid);
05994 
05995    sip_pvt_lock(p);
05996    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
05997       if (sipdebug)
05998          ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
05999       update_call_counter(p, DEC_CALL_LIMIT);
06000    }
06001 
06002    /* Determine how to disconnect */
06003    if (p->owner != ast) {
06004       ast_log(LOG_WARNING, "Huh?  We aren't the owner? Can't hangup call.\n");
06005       sip_pvt_unlock(p);
06006       return 0;
06007    }
06008    /* If the call is not UP, we need to send CANCEL instead of BYE */
06009    /* In case of re-invites, the call might be UP even though we have an incomplete invite transaction */
06010    if (p->invitestate < INV_COMPLETED && p->owner->_state != AST_STATE_UP) {
06011       needcancel = TRUE;
06012       ast_debug(4, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state));
06013    }
06014 
06015    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
06016 
06017    append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->hangupcause) : "Unknown");
06018 
06019    /* Disconnect */
06020    disable_dsp_detect(p);
06021 
06022    p->owner = NULL;
06023    ast->tech_pvt = dialog_unref(ast->tech_pvt, "unref ast->tech_pvt");
06024 
06025    ast_module_unref(ast_module_info->self);
06026    /* Do not destroy this pvt until we have timeout or
06027       get an answer to the BYE or INVITE/CANCEL
06028       If we get no answer during retransmit period, drop the call anyway.
06029       (Sorry, mother-in-law, you can't deny a hangup by sending
06030       603 declined to BYE...)
06031    */
06032    if (p->alreadygone)
06033       needdestroy = 1;  /* Set destroy flag at end of this function */
06034    else if (p->invitestate != INV_CALLING)
06035       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
06036 
06037    /* Start the process if it's not already started */
06038    if (!p->alreadygone && p->initreq.data && !ast_strlen_zero(p->initreq.data->str)) {
06039       if (needcancel) { /* Outgoing call, not up */
06040          if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06041             /* if we can't send right now, mark it pending */
06042             if (p->invitestate == INV_CALLING) {
06043                /* We can't send anything in CALLING state */
06044                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
06045                /* Do we need a timer here if we don't hear from them at all? Yes we do or else we will get hung dialogs and those are no fun. */
06046                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
06047                append_history(p, "DELAY", "Not sending cancel, waiting for timeout");
06048             } else {
06049                struct sip_pkt *cur;
06050 
06051                for (cur = p->packets; cur; cur = cur->next) {
06052                   __sip_semi_ack(p, cur->seqno, cur->is_resp, cur->method ? cur->method : find_sip_method(cur->data->str));
06053                }
06054                p->invitestate = INV_CANCELLED;
06055                /* Send a new request: CANCEL */
06056                transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
06057                /* Actually don't destroy us yet, wait for the 487 on our original
06058                   INVITE, but do set an autodestruct just in case we never get it. */
06059                needdestroy = 0;
06060                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
06061             }
06062          } else { /* Incoming call, not up */
06063             const char *res;
06064             AST_SCHED_DEL_UNREF(sched, p->provisional_keepalive_sched_id, dialog_unref(p, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr"));
06065             if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause)))
06066                transmit_response_reliable(p, res, &p->initreq);
06067             else
06068                transmit_response_reliable(p, "603 Declined", &p->initreq);
06069             p->invitestate = INV_TERMINATED;
06070          }
06071       } else { /* Call is in UP state, send BYE */
06072          if (p->stimer->st_active == TRUE) {
06073             stop_session_timer(p);
06074          }
06075 
06076          if (!p->pendinginvite) {
06077             struct ast_channel *bridge = ast_bridged_channel(oldowner);
06078             char quality_buf[AST_MAX_USER_FIELD], *quality;
06079 
06080             /* We need to get the lock on bridge because ast_rtp_instance_set_stats_vars will attempt
06081              * to lock the bridge. This may get hairy...
06082              */
06083             while (bridge && ast_channel_trylock(bridge)) {
06084                sip_pvt_unlock(p);
06085                do {
06086                   CHANNEL_DEADLOCK_AVOIDANCE(oldowner);
06087                } while (sip_pvt_trylock(p));
06088                bridge = ast_bridged_channel(oldowner);
06089             }
06090 
06091             if (p->rtp) {
06092                ast_rtp_instance_set_stats_vars(oldowner, p->rtp);
06093             }
06094 
06095             if (bridge) {
06096                struct sip_pvt *q = bridge->tech_pvt;
06097 
06098                if (IS_SIP_TECH(bridge->tech) && q && q->rtp) {
06099                   ast_rtp_instance_set_stats_vars(bridge, q->rtp);
06100                }
06101                ast_channel_unlock(bridge);
06102             }
06103 
06104             if (p->do_history || oldowner) {
06105                if (p->rtp && (quality = ast_rtp_instance_get_quality(p->rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
06106                   if (p->do_history) {
06107                      append_history(p, "RTCPaudio", "Quality:%s", quality);
06108                   }
06109                   if (oldowner) {
06110                      pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", quality);
06111                   }
06112                }
06113                if (p->vrtp && (quality = ast_rtp_instance_get_quality(p->vrtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
06114                   if (p->do_history) {
06115                      append_history(p, "RTCPvideo", "Quality:%s", quality);
06116                   }
06117                   if (oldowner) {
06118                      pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", quality);
06119                   }
06120                }
06121                if (p->trtp && (quality = ast_rtp_instance_get_quality(p->trtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
06122                   if (p->do_history) {
06123                      append_history(p, "RTCPtext", "Quality:%s", quality);
06124                   }
06125                   if (oldowner) {
06126                      pbx_builtin_setvar_helper(oldowner, "RTPTEXTQOS", quality);
06127                   }
06128                }
06129             }
06130 
06131             /* Send a hangup */
06132             if (oldowner->_state == AST_STATE_UP) {
06133                transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
06134             }
06135 
06136          } else {
06137             /* Note we will need a BYE when this all settles out
06138                but we can't send one while we have "INVITE" outstanding. */
06139             ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
06140             ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
06141             AST_SCHED_DEL_UNREF(sched, p->waitid, dialog_unref(p, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr"));
06142             if (sip_cancel_destroy(p))
06143                ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
06144          }
06145       }
06146    }
06147    if (needdestroy) {
06148       pvt_set_needdestroy(p, "hangup");
06149    }
06150    sip_pvt_unlock(p);
06151    return 0;
06152 }

static int sip_indicate ( struct ast_channel *  ast,
int  condition,
const void *  data,
size_t  datalen 
) [static]

Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc.

Returns:
-1 to force ast_indicate to send indication in audio, 0 if SIP can handle the indication by sending a message

Definition at line 6514 of file chan_sip.c.

References ast_channel::_state, AST_AOC_D, ast_aoc_decode(), ast_aoc_destroy_decoded(), AST_AOC_E, ast_aoc_get_msg_type(), ast_aoc_get_termination_request(), AST_AOC_REQUEST, AST_AOC_S, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_debug, ast_log(), ast_moh_start(), ast_moh_stop(), ast_rtp_instance_change_source(), ast_rtp_instance_update_source(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, interpret_t38_parameters(), LOG_ERROR, LOG_WARNING, sip_alreadygone(), sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_info_with_aoc(), transmit_info_with_vidupdate(), transmit_provisional_response(), transmit_response(), transmit_response_reliable(), TRUE, update_connectedline(), and update_redirecting().

06515 {
06516    struct sip_pvt *p = ast->tech_pvt;
06517    int res = 0;
06518 
06519    sip_pvt_lock(p);
06520    switch(condition) {
06521    case AST_CONTROL_RINGING:
06522       if (ast->_state == AST_STATE_RING) {
06523          p->invitestate = INV_EARLY_MEDIA;
06524          if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) ||
06525              (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) {            
06526             /* Send 180 ringing if out-of-band seems reasonable */
06527             transmit_provisional_response(p, "180 Ringing", &p->initreq, 0);
06528             ast_set_flag(&p->flags[0], SIP_RINGING);
06529             if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES)
06530                break;
06531          } else {
06532             /* Well, if it's not reasonable, just send in-band */
06533          }
06534       }
06535       res = -1;
06536       break;
06537    case AST_CONTROL_BUSY:
06538       if (ast->_state != AST_STATE_UP) {
06539          transmit_response_reliable(p, "486 Busy Here", &p->initreq);
06540          p->invitestate = INV_COMPLETED;
06541          sip_alreadygone(p);
06542          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
06543          break;
06544       }
06545       res = -1;
06546       break;
06547    case AST_CONTROL_CONGESTION:
06548       if (ast->_state != AST_STATE_UP) {
06549          transmit_response_reliable(p, "503 Service Unavailable", &p->initreq);
06550          p->invitestate = INV_COMPLETED;
06551          sip_alreadygone(p);
06552          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
06553          break;
06554       }
06555       res = -1;
06556       break;
06557    case AST_CONTROL_PROCEEDING:
06558       if ((ast->_state != AST_STATE_UP) &&
06559           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
06560           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06561          transmit_response(p, "100 Trying", &p->initreq);
06562          p->invitestate = INV_PROCEEDING;
06563          break;
06564       }
06565       res = -1;
06566       break;
06567    case AST_CONTROL_PROGRESS:
06568       if ((ast->_state != AST_STATE_UP) &&
06569           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
06570           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06571          p->invitestate = INV_EARLY_MEDIA;
06572          transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
06573          ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
06574          break;
06575       }
06576       res = -1;
06577       break;
06578    case AST_CONTROL_HOLD:
06579       ast_rtp_instance_update_source(p->rtp);
06580       ast_moh_start(ast, data, p->mohinterpret);
06581       break;
06582    case AST_CONTROL_UNHOLD:
06583       ast_rtp_instance_update_source(p->rtp);
06584       ast_moh_stop(ast);
06585       break;
06586    case AST_CONTROL_VIDUPDATE:   /* Request a video frame update */
06587       if (p->vrtp && !p->novideo) {
06588          transmit_info_with_vidupdate(p);
06589          /* ast_rtcp_send_h261fur(p->vrtp); */
06590       } else
06591          res = -1;
06592       break;
06593    case AST_CONTROL_T38_PARAMETERS:
06594       if (datalen != sizeof(struct ast_control_t38_parameters)) {
06595          ast_log(LOG_ERROR, "Invalid datalen for AST_CONTROL_T38_PARAMETERS. Expected %d, got %d\n", (int) sizeof(struct ast_control_t38_parameters), (int) datalen);
06596          res = -1;
06597       } else {
06598          const struct ast_control_t38_parameters *parameters = data;
06599          res = interpret_t38_parameters(p, parameters);
06600       }
06601       break;
06602    case AST_CONTROL_SRCUPDATE:
06603       ast_rtp_instance_update_source(p->rtp);
06604       break;
06605    case AST_CONTROL_SRCCHANGE:
06606       ast_rtp_instance_change_source(p->rtp);
06607       break;
06608    case AST_CONTROL_CONNECTED_LINE:
06609       update_connectedline(p, data, datalen);
06610       break;
06611    case AST_CONTROL_REDIRECTING:
06612       update_redirecting(p, data, datalen);
06613       break;
06614    case AST_CONTROL_AOC:
06615       {
06616          struct ast_aoc_decoded *decoded = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, ast);
06617          if (!decoded) {
06618             ast_log(LOG_ERROR, "Error decoding indicated AOC data\n");
06619             res = -1;
06620             break;
06621          }
06622          switch (ast_aoc_get_msg_type(decoded)) {
06623          case AST_AOC_REQUEST:
06624             if (ast_aoc_get_termination_request(decoded)) {
06625                /* TODO, once there is a way to get AOC-E on hangup, attempt that here
06626                 * before hanging up the channel.*/
06627 
06628                /* The other side has already initiated the hangup. This frame
06629                 * just says they are waiting to get AOC-E before completely tearing
06630                 * the call down.  Since SIP does not support this at the moment go
06631                 * ahead and terminate the call here to avoid an unnecessary timeout. */
06632                ast_debug(1, "AOC-E termination request received on %s. This is not yet supported on sip. Continue with hangup \n", p->owner->name);
06633                ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
06634             }
06635             break;
06636          case AST_AOC_D:
06637          case AST_AOC_E:
06638             if (ast_test_flag(&p->flags[2], SIP_PAGE3_SNOM_AOC)) {
06639                transmit_info_with_aoc(p, decoded);
06640             }
06641             break;
06642          case AST_AOC_S: /* S not supported yet */
06643          default:
06644             break;
06645          }
06646          ast_aoc_destroy_decoded(decoded);
06647       }
06648       break;
06649    case -1:
06650       res = -1;
06651       break;
06652    default:
06653       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
06654       res = -1;
06655       break;
06656    }
06657    sip_pvt_unlock(p);
06658    return res;
06659 }

static int sip_is_xml_parsable ( void   )  [static]

Definition at line 28231 of file chan_sip.c.

References FALSE, and TRUE.

Referenced by load_module().

28232 {
28233 #ifdef HAVE_LIBXML2
28234    return TRUE;
28235 #else
28236    return FALSE;
28237 #endif
28238 }

static int sip_monitor_instance_cmp_fn ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 1816 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by load_module().

01817 {
01818    struct sip_monitor_instance *monitor_instance1 = obj;
01819    struct sip_monitor_instance *monitor_instance2 = arg;
01820 
01821    return monitor_instance1->core_id == monitor_instance2->core_id ? CMP_MATCH | CMP_STOP : 0;
01822 }

static void sip_monitor_instance_destructor ( void *  data  )  [static]

Definition at line 1824 of file chan_sip.c.

References ao2_t_ref, ast_string_field_free_memory, FALSE, sip_pvt_lock, sip_pvt_unlock, transmit_invite(), and transmit_publish().

Referenced by sip_monitor_instance_init().

01825 {
01826    struct sip_monitor_instance *monitor_instance = data;
01827    if (monitor_instance->subscription_pvt) {
01828       sip_pvt_lock(monitor_instance->subscription_pvt);
01829       monitor_instance->subscription_pvt->expiry = 0;
01830       transmit_invite(monitor_instance->subscription_pvt, SIP_SUBSCRIBE, FALSE, 0, monitor_instance->subscribe_uri);
01831       sip_pvt_unlock(monitor_instance->subscription_pvt);
01832       dialog_unref(monitor_instance->subscription_pvt, "Unref monitor instance ref of subscription pvt");
01833    }
01834    if (monitor_instance->suspension_entry) {
01835       monitor_instance->suspension_entry->body[0] = '\0';
01836       transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_REMOVE ,monitor_instance->notify_uri);
01837       ao2_t_ref(monitor_instance->suspension_entry, -1, "Decrementing suspension entry refcount in sip_monitor_instance_destructor");
01838    }
01839    ast_string_field_free_memory(monitor_instance);
01840 }

static int sip_monitor_instance_hash_fn ( const void *  obj,
const int  flags 
) [static]

Definition at line 1810 of file chan_sip.c.

Referenced by load_module().

01811 {
01812    const struct sip_monitor_instance *monitor_instance = obj;
01813    return monitor_instance->core_id;
01814 }

static struct sip_monitor_instance* sip_monitor_instance_init ( int  core_id,
const char *const   subscribe_uri,
const char *const   peername,
const char *const   device_name 
) [static]

Definition at line 1842 of file chan_sip.c.

References ao2_alloc, ao2_link, ao2_ref, ast_string_field_init, ast_string_field_set, sip_monitor_instance_destructor(), and sip_monitor_instances.

Referenced by sip_handle_cc().

01843 {
01844    struct sip_monitor_instance *monitor_instance = ao2_alloc(sizeof(*monitor_instance), sip_monitor_instance_destructor);
01845 
01846    if (!monitor_instance) {
01847       return NULL;
01848    }
01849 
01850    if (ast_string_field_init(monitor_instance, 256)) {
01851       ao2_ref(monitor_instance, -1);
01852       return NULL;
01853    }
01854 
01855    ast_string_field_set(monitor_instance, subscribe_uri, subscribe_uri);
01856    ast_string_field_set(monitor_instance, peername, peername);
01857    ast_string_field_set(monitor_instance, device_name, device_name);
01858    monitor_instance->core_id = core_id;
01859    ao2_link(sip_monitor_instances, monitor_instance);
01860    return monitor_instance;
01861 }

static const char * sip_nat_mode ( const struct sip_pvt *  p  )  [static]

Display SIP nat mode.

Definition at line 3129 of file chan_sip.c.

References ast_test_flag.

Referenced by check_via(), retrans_pkt(), and send_response().

03130 {
03131    return ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) ? "NAT" : "no NAT";
03132 }

static struct ast_channel* sip_new ( struct sip_pvt *  i,
int  state,
const char *  title,
const char *  linkedid 
) [static]

Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.

Definition at line 6666 of file chan_sip.c.

References accountcode, ast_channel::adsicpe, ast_channel::amaflags, ast_party_caller::ani, append_history, AST_ADSI_UNAVAILABLE, ast_atomic_fetchadd_int(), ast_best_codec(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc, ast_channel_cc_params_init(), ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_codec_choose(), ast_copy_string(), ast_debug, ast_exists_extension(), AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_get_encoded_str(), ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_pbx_start(), AST_RTP_DTMF_MODE_INBAND, AST_RTP_DTMF_MODE_RFC2833, ast_rtp_instance_dtmf_mode_set(), ast_rtp_instance_fd(), ast_rtp_instance_set_read_format(), ast_rtp_instance_set_write_format(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), ast_uri_decode(), ast_channel::caller, ast_channel::callgroup, chan_idx, ast_channel::context, ast_channel::dialed, enable_dsp_detect(), EVENT_FLAG_SYSTEM, ast_channel::exten, ast_party_redirecting::from, global_jbconf, ast_channel::hangupcause, ast_party_caller::id, language, LOG_WARNING, manager_event, ast_channel::name, ast_variable::name, ast_party_id::name, ast_channel::nativeformats, ast_variable::next, ast_party_dialed::number, ast_party_id::number, parkinglot, pbx_builtin_setvar_helper(), ast_channel::pickupgroup, ast_party_number::presentation, ast_party_name::presentation, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::redirecting, ast_channel::rings, sip_cfg, sip_pvt_lock, sip_pvt_unlock, sip_tech, sip_tech_info, ast_party_dialed::str, ast_party_number::str, ast_party_id::tag, ast_channel::tech, ast_channel::tech_pvt, text, ast_channel::uniqueid, ast_party_number::valid, ast_variable::value, and ast_channel::writeformat.

Referenced by handle_request_invite(), and sip_request_call().

06667 {
06668    struct ast_channel *tmp;
06669    struct ast_variable *v = NULL;
06670    format_t fmt;
06671    format_t what;
06672    format_t video;
06673    format_t text;
06674    format_t needvideo = 0;
06675    int needtext = 0;
06676    char buf[SIPBUFSIZE];
06677    char *decoded_exten;
06678 
06679    {
06680       const char *my_name; /* pick a good name */
06681    
06682       if (title) {
06683          my_name = title;
06684       } else {
06685          my_name = ast_strdupa(i->fromdomain);
06686       }
06687 
06688       sip_pvt_unlock(i);
06689       /* Don't hold a sip pvt lock while we allocate a channel */
06690       tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "SIP/%s-%08x", my_name, ast_atomic_fetchadd_int((int *)&chan_idx, +1));
06691    }
06692    if (!tmp) {
06693       ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n");
06694       sip_pvt_lock(i);
06695       return NULL;
06696    }
06697    ast_channel_lock(tmp);
06698    sip_pvt_lock(i);
06699    ast_channel_cc_params_init(tmp, i->cc_params);
06700    tmp->caller.id.tag = ast_strdup(i->cid_tag);
06701    ast_channel_unlock(tmp);
06702 
06703    tmp->tech = ( ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO || ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO) ?  &sip_tech_info : &sip_tech;
06704 
06705    /* Select our native format based on codec preference until we receive
06706       something from another device to the contrary. */
06707    if (i->jointcapability) {  /* The joint capabilities of us and peer */
06708       what = i->jointcapability;
06709       video = i->jointcapability & AST_FORMAT_VIDEO_MASK;
06710       text = i->jointcapability & AST_FORMAT_TEXT_MASK;
06711    } else if (i->capability) {      /* Our configured capability for this peer */
06712       what = i->capability;
06713       video = i->capability & AST_FORMAT_VIDEO_MASK;
06714       text = i->capability & AST_FORMAT_TEXT_MASK;
06715    } else {
06716       what = sip_cfg.capability; /* Global codec support */
06717       video = sip_cfg.capability & AST_FORMAT_VIDEO_MASK;
06718       text = sip_cfg.capability & AST_FORMAT_TEXT_MASK;
06719    }
06720 
06721    /* Set the native formats for audio  and merge in video */
06722    tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video | text;
06723    ast_debug(3, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats));
06724    ast_debug(3, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability));
06725    ast_debug(3, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability));
06726    ast_debug(3, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1)));
06727    if (i->prefcodec)
06728       ast_debug(3, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec));
06729 
06730    /* XXX Why are we choosing a codec from the native formats?? */
06731    fmt = ast_best_codec(tmp->nativeformats);
06732 
06733    /* If we have a prefcodec setting, we have an inbound channel that set a
06734       preferred format for this call. Otherwise, we check the jointcapability
06735       We also check for vrtp. If it's not there, we are not allowed do any video anyway.
06736     */
06737    if (i->vrtp) {
06738       if (ast_test_flag(&i->flags[1], SIP_PAGE2_VIDEOSUPPORT))
06739          needvideo = AST_FORMAT_VIDEO_MASK;
06740       else if (i->prefcodec)
06741          needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK;  /* Outbound call */
06742       else
06743          needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK;  /* Inbound call */
06744    }
06745 
06746    if (i->trtp) {
06747       if (i->prefcodec)
06748          needtext = i->prefcodec & AST_FORMAT_TEXT_MASK; /* Outbound call */
06749       else
06750          needtext = i->jointcapability & AST_FORMAT_TEXT_MASK; /* Inbound call */
06751    }
06752 
06753    if (needvideo)
06754       ast_debug(3, "This channel can handle video! HOLLYWOOD next!\n");
06755    else
06756       ast_debug(3, "This channel will not be able to handle video.\n");
06757 
06758    enable_dsp_detect(i);
06759 
06760    if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) ||
06761        (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
06762       if (!i->rtp || ast_rtp_instance_dtmf_mode_set(i->rtp, AST_RTP_DTMF_MODE_INBAND)) {
06763          enable_dsp_detect(i);
06764       }
06765    } else if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) {
06766       if (i->rtp) {
06767          ast_rtp_instance_dtmf_mode_set(i->rtp, AST_RTP_DTMF_MODE_RFC2833);
06768       }
06769    }
06770 
06771    /* Set file descriptors for audio, video, realtime text and UDPTL as needed */
06772    if (i->rtp) {
06773       ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(i->rtp, 0));
06774       ast_channel_set_fd(tmp, 1, ast_rtp_instance_fd(i->rtp, 1));
06775    }
06776    if (needvideo && i->vrtp) {
06777       ast_channel_set_fd(tmp, 2, ast_rtp_instance_fd(i->vrtp, 0));
06778       ast_channel_set_fd(tmp, 3, ast_rtp_instance_fd(i->vrtp, 1));
06779    }
06780    if (needtext && i->trtp)
06781       ast_channel_set_fd(tmp, 4, ast_rtp_instance_fd(i->trtp, 0));
06782    if (i->udptl)
06783       ast_channel_set_fd(tmp, 5, ast_udptl_fd(i->udptl));
06784 
06785    if (state == AST_STATE_RING)
06786       tmp->rings = 1;
06787    tmp->adsicpe = AST_ADSI_UNAVAILABLE;
06788 
06789    tmp->writeformat = fmt;
06790    tmp->rawwriteformat = fmt;
06791    ast_rtp_instance_set_write_format(i->rtp, fmt);
06792 
06793    tmp->readformat = fmt;
06794    tmp->rawreadformat = fmt;
06795    ast_rtp_instance_set_read_format(i->rtp, fmt);
06796 
06797    tmp->tech_pvt = dialog_ref(i, "sip_new: set chan->tech_pvt to i");
06798 
06799    tmp->callgroup = i->callgroup;
06800    tmp->pickupgroup = i->pickupgroup;
06801    tmp->caller.id.name.presentation = i->callingpres;
06802    tmp->caller.id.number.presentation = i->callingpres;
06803    if (!ast_strlen_zero(i->parkinglot))
06804       ast_string_field_set(tmp, parkinglot, i->parkinglot);
06805    if (!ast_strlen_zero(i->accountcode))
06806       ast_string_field_set(tmp, accountcode, i->accountcode);
06807    if (i->amaflags)
06808       tmp->amaflags = i->amaflags;
06809    if (!ast_strlen_zero(i->language))
06810       ast_string_field_set(tmp, language, i->language);
06811    i->owner = tmp;
06812    ast_module_ref(ast_module_info->self);
06813    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
06814    /*Since it is valid to have extensions in the dialplan that have unescaped characters in them
06815     * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt
06816     * structure so that there aren't issues when forming URI's
06817     */
06818    if (ast_exists_extension(NULL, i->context, i->exten, 1, i->cid_num)) {
06819       /* encoded in dialplan, so keep extension encoded */
06820       ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
06821    } else {
06822       decoded_exten = ast_strdupa(i->exten);
06823       ast_uri_decode(decoded_exten);
06824       ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten));
06825    }
06826 
06827    /* Don't use ast_set_callerid() here because it will
06828     * generate an unnecessary NewCallerID event  */
06829    if (!ast_strlen_zero(i->cid_num)) {
06830       tmp->caller.ani.number.valid = 1;
06831       tmp->caller.ani.number.str = ast_strdup(i->cid_num);
06832    }
06833    if (!ast_strlen_zero(i->rdnis)) {
06834       tmp->redirecting.from.number.valid = 1;
06835       tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
06836    }
06837 
06838    if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) {
06839       tmp->dialed.number.str = ast_strdup(i->exten);
06840    }
06841 
06842    tmp->priority = 1;
06843    if (!ast_strlen_zero(i->uri))
06844       pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri);
06845    if (!ast_strlen_zero(i->domain))
06846       pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain);
06847    if (!ast_strlen_zero(i->callid))
06848       pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid);
06849    if (i->rtp)
06850       ast_jb_configure(tmp, &global_jbconf);
06851 
06852    /* Set channel variables for this call from configuration */
06853    for (v = i->chanvars ; v ; v = v->next) {
06854       char valuebuf[1024];
06855       pbx_builtin_setvar_helper(tmp, v->name, ast_get_encoded_str(v->value, valuebuf, sizeof(valuebuf)));
06856    }
06857 
06858    if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
06859       ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
06860       tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
06861       ast_hangup(tmp);
06862       tmp = NULL;
06863    }
06864 
06865    if (i->do_history)
06866       append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid);
06867 
06868    /* Inform manager user about new channel and their SIP call ID */
06869    if (sip_cfg.callevents)
06870       manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
06871          "Channel: %s\r\nUniqueid: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\n",
06872          tmp->name, tmp->uniqueid, "SIP", i->callid, i->fullcontact);
06873 
06874    return tmp;
06875 }

static int sip_notify_allocate ( struct sip_pvt *  p  )  [static]

Allocate SIP refer structure.

Definition at line 12737 of file chan_sip.c.

References ast_calloc, and ast_str_create().

Referenced by manager_sipnotify(), and sip_cli_notify().

12738 {
12739    p->notify = ast_calloc(1, sizeof(struct sip_notify));
12740    if (p->notify) {
12741       p->notify->content = ast_str_create(128);
12742    }
12743    return p->notify ? 1 : 0;
12744 }

static int sip_offer_timer_expire ( const void *  data  )  [static]

Definition at line 1692 of file chan_sip.c.

References ast_cc_failed(), ast_cc_agent::core_id, ast_cc_agent::device_name, and ast_cc_agent::private_data.

Referenced by sip_cc_agent_start_offer_timer().

01693 {
01694    struct ast_cc_agent *agent = (struct ast_cc_agent *) data;
01695    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
01696 
01697    agent_pvt->offer_timer_id = -1;
01698 
01699    return ast_cc_failed(agent->core_id, "SIP agent %s's offer timer expired", agent->device_name);
01700 }

static int sip_park ( struct ast_channel *  chan1,
struct ast_channel *  chan2,
struct sip_request *  req,
int  seqno,
char *  parkexten 
) [static]

Park a call using the subsystem in res_features.c This is executed in a separate thread.

Definition at line 20410 of file chan_sip.c.

References ast_channel::accountcode, ast_channel::amaflags, ast_calloc, AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc, ast_channel_masquerade(), ast_channel_trylock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_do_masquerade(), ast_free, ast_hangup(), ast_log(), ast_pthread_create_detached_background, AST_STATE_DOWN, ast_string_field_set, ast_strlen_zero(), ast_channel::context, copy_request(), deinit_req(), ast_channel::exten, ast_channel::hangupcause, ast_channel::linkedid, LOG_WARNING, ast_channel::name, parkinglot, ast_channel::parkinglot, ast_channel::priority, ast_channel::readformat, sip_park_thread(), sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and ast_channel::writeformat.

Referenced by handle_request_refer().

20411 {
20412    struct sip_dual *d;
20413    struct ast_channel *transferee, *transferer;
20414       /* Chan2m: The transferer, chan1m: The transferee */
20415    pthread_t th;
20416 
20417    transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
20418    transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "SIPPeer/%s", chan2->name);
20419    if ((!transferer) || (!transferee)) {
20420       if (transferee) {
20421          transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
20422          ast_hangup(transferee);
20423       }
20424       if (transferer) {
20425          transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
20426          ast_hangup(transferer);
20427       }
20428       return -1;
20429    }
20430 
20431    /* Make formats okay */
20432    transferee->readformat = chan1->readformat;
20433    transferee->writeformat = chan1->writeformat;
20434 
20435    /* Prepare for taking over the channel */
20436    ast_channel_masquerade(transferee, chan1);
20437 
20438    /* Setup the extensions and such */
20439    ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context));
20440    ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten));
20441    transferee->priority = chan1->priority;
20442       
20443    /* We make a clone of the peer channel too, so we can play
20444       back the announcement */
20445 
20446    /* Make formats okay */
20447    transferer->readformat = chan2->readformat;
20448    transferer->writeformat = chan2->writeformat;
20449    if (!ast_strlen_zero(chan2->parkinglot))
20450       ast_string_field_set(transferer, parkinglot, chan2->parkinglot);
20451 
20452    /* Prepare for taking over the channel.  Go ahead and grab this channel
20453     * lock here to avoid a deadlock with callbacks into the channel driver
20454     * that hold the channel lock and want the pvt lock.  */
20455    while (ast_channel_trylock(chan2)) {
20456       struct sip_pvt *pvt = chan2->tech_pvt;
20457       sip_pvt_unlock(pvt);
20458       usleep(1);
20459       sip_pvt_lock(pvt);
20460    }
20461    ast_channel_masquerade(transferer, chan2);
20462    ast_channel_unlock(chan2);
20463 
20464    /* Setup the extensions and such */
20465    ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context));
20466    ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten));
20467    transferer->priority = chan2->priority;
20468 
20469    if (ast_do_masquerade(transferer)) {
20470       ast_log(LOG_WARNING, "Masquerade failed :(\n");
20471       transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
20472       ast_hangup(transferer);
20473       return -1;
20474    }
20475    if (!transferer || !transferee) {
20476       if (!transferer) {
20477          ast_debug(1, "No transferer channel, giving up parking\n");
20478       }
20479       if (!transferee) {
20480          ast_debug(1, "No transferee channel, giving up parking\n");
20481       }
20482       return -1;
20483    }
20484    if (!(d = ast_calloc(1, sizeof(*d)))) {
20485       return -1;
20486    }
20487 
20488    /* Save original request for followup */
20489    copy_request(&d->req, req);
20490    d->chan1 = transferee;  /* Transferee */
20491    d->chan2 = transferer;  /* Transferer */
20492    d->seqno = seqno;
20493    d->parkexten = parkexten;
20494    if (ast_pthread_create_detached_background(&th, NULL, sip_park_thread, d) < 0) {
20495       /* Could not start thread */
20496       deinit_req(&d->req);
20497       ast_free(d);   /* We don't need it anymore. If thread is created, d will be free'd
20498                by sip_park_thread() */
20499       return -1;
20500    }
20501    return 0;
20502 }

static void * sip_park_thread ( void *  stuff  )  [static]

Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup.

Definition at line 20345 of file chan_sip.c.

References append_history, AST_CAUSE_NORMAL_CLEARING, ast_debug, ast_do_masquerade(), ast_free, ast_hangup(), ast_log(), ast_park_call(), copy_request(), deinit_req(), ext, ast_channel::hangupcause, LOG_ERROR, LOG_WARNING, ast_channel::name, ast_channel::tech_pvt, transmit_message_with_text(), transmit_notify_with_sipfrag(), transmit_response(), and TRUE.

Referenced by sip_park().

20346 {
20347    struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */
20348    struct sip_dual *d;
20349    struct sip_request req = {0,};
20350    int ext;
20351    int res;
20352 
20353    d = stuff;
20354    transferee = d->chan1;
20355    transferer = d->chan2;
20356    copy_request(&req, &d->req);
20357 
20358    if (!transferee || !transferer) {
20359       ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" );
20360       deinit_req(&d->req);
20361       ast_free(d);
20362       return NULL;
20363    }
20364    ast_debug(4, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name);
20365 
20366    if (ast_do_masquerade(transferee)) {
20367       ast_log(LOG_WARNING, "Masquerade failed.\n");
20368       transmit_response(transferer->tech_pvt, "503 Internal error", &req);
20369       deinit_req(&d->req);
20370       ast_free(d);
20371       return NULL;
20372    }
20373 
20374    res = ast_park_call(transferee, transferer, 0, d->parkexten, &ext);
20375    
20376 
20377 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE
20378    if (!res) {
20379       transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n");
20380    } else {
20381       /* Then tell the transferer what happened */
20382       sprintf(buf, "Call parked on extension '%d'", ext);
20383       transmit_message_with_text(transferer->tech_pvt, buf);
20384    }
20385 #endif
20386 
20387    /* Any way back to the current call??? */
20388    /* Transmit response to the REFER request */
20389    if (!res)   {
20390       /* Transfer succeeded */
20391       append_history(transferer->tech_pvt, "SIPpark", "Parked call on %d", ext);
20392       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE);
20393       transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING;
20394       ast_hangup(transferer); /* This will cause a BYE */
20395       ast_debug(1, "SIP Call parked on extension '%d'\n", ext);
20396    } else {
20397       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE);
20398       append_history(transferer->tech_pvt, "SIPpark", "Parking failed\n");
20399       ast_debug(1, "SIP Call parked failed \n");
20400       /* Do not hangup call */
20401    }
20402    deinit_req(&d->req);
20403    ast_free(d);
20404    return NULL;
20405 }

static void sip_peer_hold ( struct sip_pvt *  p,
int  hold 
) [static]

Change onhold state of a peer using a pvt structure.

Definition at line 13777 of file chan_sip.c.

References ast_atomic_fetchadd_int(), AST_DEVICE_UNKNOWN, and ast_devstate_changed().

Referenced by change_hold_state(), and update_call_counter().

13778 {
13779    if (!p->relatedpeer) {
13780       return;
13781    }
13782 
13783    /* If they put someone on hold, increment the value... otherwise decrement it */
13784    ast_atomic_fetchadd_int(&p->relatedpeer->onHold, (hold ? +1 : -1));
13785 
13786    /* Request device state update */
13787    ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", p->relatedpeer->name);
13788    
13789    return;
13790 }

static int sip_pidf_validate ( struct sip_request *  req,
struct ast_xml_doc **  pidf_doc 
) [static]

Makes sure that body is properly formatted PIDF.

Specifically, we check that the document has a "presence" element at the root and that within that, there is at least one "tuple" element that contains a "status" element.

XXX This function currently assumes a default namespace is used. Of course if you're not using a default namespace, you're probably a stupid jerk anyway.

Parameters:
req The SIP request to check
[out] pidf_doc The validated PIDF doc.
Return values:
FALSE The XML was malformed or the basic PIDF structure was marred
TRUE The PIDF document is of a valid format

Definition at line 22980 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), ast_xml_close(), ast_xml_read_memory(), FALSE, get_header(), get_pidf_body(), LOG_WARNING, pidf_validate_presence(), and TRUE.

Referenced by cc_esc_publish_handler().

22981 {
22982    struct ast_xml_doc *doc;
22983    int content_length;
22984    const char *content_length_str = get_header(req, "Content-Length");
22985    const char *content_type = get_header(req, "Content-Type");
22986    char pidf_body[SIPBUFSIZE];
22987    int res;
22988 
22989    if (ast_strlen_zero(content_type) || strcmp(content_type, "application/pidf+xml")) {
22990       ast_log(LOG_WARNING, "Content type is not PIDF\n");
22991       return FALSE;
22992    }
22993 
22994    if (ast_strlen_zero(content_length_str)) {
22995       ast_log(LOG_WARNING, "No content length. Can't determine bounds of PIDF document\n");
22996       return FALSE;
22997    }
22998 
22999    if (sscanf(content_length_str, "%30d", &content_length) != 1) {
23000       ast_log(LOG_WARNING, "Invalid content length provided\n");
23001       return FALSE;
23002    }
23003 
23004    if (content_length > sizeof(pidf_body)) {
23005       ast_log(LOG_WARNING, "Content length of PIDF document truncated to %d bytes\n", (int) sizeof(pidf_body));
23006       content_length = sizeof(pidf_body);
23007    }
23008 
23009    get_pidf_body(req, pidf_body, content_length);
23010 
23011    if (!(doc = ast_xml_read_memory(pidf_body, content_length))) {
23012       ast_log(LOG_WARNING, "Unable to open XML PIDF document. Is it malformed?\n");
23013       return FALSE;
23014    }
23015 
23016    res = pidf_validate_presence(doc);
23017    if (res == TRUE) {
23018       *pidf_doc = doc;
23019    } else {
23020       ast_xml_close(doc);
23021    }
23022    return res;
23023 }

static void sip_poke_all_peers ( void   )  [static]

Send a poke to all known peers.

Definition at line 28241 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, AST_SCHED_REPLACE_UNREF, global_qualify_gap, global_qualify_peers, ref_peer(), sip_poke_peer_s(), speerobjs, and unref_peer().

Referenced by load_module(), and sip_do_reload().

28242 {
28243    int ms = 0, num = 0;
28244    struct ao2_iterator i;
28245    struct sip_peer *peer;
28246 
28247    if (!speerobjs) { /* No peers, just give up */
28248       return;
28249    }
28250 
28251    i = ao2_iterator_init(peers, 0);
28252    while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
28253       ao2_lock(peer);
28254       if (num == global_qualify_peers) {
28255          ms += global_qualify_gap;
28256          num = 0;
28257       } else {
28258          num++;
28259       }
28260       AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, ms, sip_poke_peer_s, peer,
28261             unref_peer(_data, "removing poke peer ref"),
28262             unref_peer(peer, "removing poke peer ref"),
28263             ref_peer(peer, "adding poke peer ref"));
28264       ao2_unlock(peer);
28265       unref_peer(peer, "toss iterator peer ptr");
28266    }
28267    ao2_iterator_destroy(&i);
28268 }

static int sip_poke_noanswer ( const void *  data  )  [static]

React to lack of answer to Qualify poke.

Definition at line 25066 of file chan_sip.c.

References ast_check_realtime(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_log(), AST_SCHED_REPLACE_UNREF, ast_update_realtime(), DEFAULT_FREQ_NOTOK, dialog_unlink_all(), EVENT_FLAG_SYSTEM, FALSE, LOG_NOTICE, manager_event, ref_peer(), register_peer_exten(), SENTINEL, sip_cfg, sip_poke_peer_s(), TRUE, and unref_peer().

Referenced by sip_poke_peer(), and sip_show_sched().

25067 {
25068    struct sip_peer *peer = (struct sip_peer *)data;
25069 
25070    peer->pokeexpire = -1;
25071 
25072    if (peer->lastms > -1) {
25073       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
25074       if (sip_cfg.peer_rtupdate) {
25075          ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", "-1", SENTINEL);
25076       }
25077       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
25078       if (sip_cfg.regextenonqualify) {
25079          register_peer_exten(peer, FALSE);
25080       }
25081    }
25082 
25083    if (peer->call) {
25084       dialog_unlink_all(peer->call, TRUE, TRUE);
25085       peer->call = dialog_unref(peer->call, "unref dialog peer->call");
25086       /* peer->call = sip_destroy(peer->call);*/
25087    }
25088 
25089    /* Don't send a devstate change if nothing changed. */
25090    if (peer->lastms > -1) {
25091       peer->lastms = -1;
25092       ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
25093    }
25094 
25095    /* Try again quickly */
25096    AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched,
25097          DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer,
25098          unref_peer(_data, "removing poke peer ref"),
25099          unref_peer(peer, "removing poke peer ref"),
25100          ref_peer(peer, "adding poke peer ref"));
25101 
25102    /* Release the ref held by the running scheduler entry */
25103    unref_peer(peer, "release peer poke noanswer ref");
25104 
25105    return 0;
25106 }

static int sip_poke_peer ( struct sip_peer *  peer,
int  force 
) [static]

Check availability of peer, also keep NAT open.

Note:
This is done with 60 seconds between each ping, unless forced by cli or manager. If peer is unreachable, we check every 10th second by default.

Definition at line 25113 of file chan_sip.c.

References ao2_t_link, ao2_t_unlink, ast_copy_flags, ast_copy_string(), ast_log(), AST_SCHED_DEL_UNREF, AST_SCHED_REPLACE_UNREF, ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_isnull(), ast_sockaddr_stringify_host(), ast_string_field_set, ast_strlen_zero(), ast_tvnow(), build_callid_pvt(), build_via(), copy_socket_data(), dialog_unlink_all(), dialogs, LOG_NOTICE, ref_peer(), sip_alloc(), sip_poke_noanswer(), transmit_invite(), TRUE, and unref_peer().

Referenced by _sip_qualify_peer(), build_peer(), parse_register_contact(), reg_source_db(), and sip_poke_peer_s().

25114 {
25115    struct sip_pvt *p;
25116    int xmitres = 0;
25117    
25118    if ((!peer->maxms && !force) || ast_sockaddr_isnull(&peer->addr)) {
25119       /* IF we have no IP, or this isn't to be monitored, return
25120         immediately after clearing things out */
25121       AST_SCHED_DEL_UNREF(sched, peer->pokeexpire,
25122             unref_peer(peer, "removing poke peer ref"));
25123       
25124       peer->lastms = 0;
25125       if (peer->call) {
25126          peer->call = dialog_unref(peer->call, "unref dialog peer->call");
25127       }
25128       return 0;
25129    }
25130    if (peer->call) {
25131       if (sipdebug) {
25132          ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
25133       }
25134       dialog_unlink_all(peer->call, TRUE, TRUE);
25135       peer->call = dialog_unref(peer->call, "unref dialog peer->call");
25136       /* peer->call = sip_destroy(peer->call); */
25137    }
25138    if (!(p = sip_alloc(NULL, NULL, 0, SIP_OPTIONS, NULL))) {
25139       return -1;
25140    }
25141    peer->call = dialog_ref(p, "copy sip alloc from p to peer->call");
25142    
25143    p->sa = peer->addr;
25144    p->recv = peer->addr;
25145    copy_socket_data(&p->socket, &peer->socket);
25146    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
25147    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
25148    ast_copy_flags(&p->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
25149 
25150    /* Send OPTIONs to peer's fullcontact */
25151    if (!ast_strlen_zero(peer->fullcontact))
25152       ast_string_field_set(p, fullcontact, peer->fullcontact);
25153 
25154    if (!ast_strlen_zero(peer->tohost))
25155       ast_string_field_set(p, tohost, peer->tohost);
25156    else
25157       ast_string_field_set(p, tohost, ast_sockaddr_stringify_host(&peer->addr));
25158 
25159    /* Recalculate our side, and recalculate Call ID */
25160    ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
25161    build_via(p);
25162    ao2_t_unlink(dialogs, p, "About to change the callid -- remove the old name");
25163    build_callid_pvt(p);
25164    ao2_t_link(dialogs, p, "Linking in under new name");
25165 
25166    AST_SCHED_DEL_UNREF(sched, peer->pokeexpire,
25167          unref_peer(peer, "removing poke peer ref"));
25168    
25169    if (p->relatedpeer)
25170       p->relatedpeer = unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else.");
25171    p->relatedpeer = ref_peer(peer, "setting the relatedpeer field in the dialog");
25172    ast_set_flag(&p->flags[0], SIP_OUTGOING);
25173 #ifdef VOCAL_DATA_HACK
25174    ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
25175    xmitres = transmit_invite(p, SIP_INVITE, 0, 2, NULL); /* sinks the p refcount */
25176 #else
25177    xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2, NULL); /* sinks the p refcount */
25178 #endif
25179    peer->ps = ast_tvnow();
25180    if (xmitres == XMIT_ERROR) {
25181       sip_poke_noanswer(peer);   /* Immediately unreachable, network problems */
25182    } else if (!force) {
25183       AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, peer->maxms * 2, sip_poke_noanswer, peer,
25184             unref_peer(_data, "removing poke peer ref"),
25185             unref_peer(peer, "removing poke peer ref"),
25186             ref_peer(peer, "adding poke peer ref"));
25187    }
25188    dialog_unref(p, "unref dialog at end of sip_poke_peer, obtained from sip_alloc, just before it goes out of scope");
25189    return 0;
25190 }

static int sip_poke_peer_s ( const void *  data  )  [static]

Poke peer (send qualify to check if peer is alive and well).

Definition at line 13043 of file chan_sip.c.

References ao2_find, OBJ_POINTER, sip_poke_peer(), and unref_peer().

Referenced by handle_response_peerpoke(), reg_source_db(), sip_poke_all_peers(), sip_poke_noanswer(), and sip_show_sched().

13044 {
13045    struct sip_peer *peer = (struct sip_peer *)data;
13046    struct sip_peer *foundpeer;
13047 
13048    peer->pokeexpire = -1;
13049 
13050    foundpeer = ao2_find(peers, peer, OBJ_POINTER);
13051    if (!foundpeer) {
13052       unref_peer(peer, "removing poke peer ref");
13053       return 0;
13054    } else if (foundpeer->name != peer->name) {
13055       unref_peer(foundpeer, "removing above peer ref");
13056       unref_peer(peer, "removing poke peer ref");
13057       return 0;
13058    }
13059 
13060    unref_peer(foundpeer, "removing above peer ref");
13061    sip_poke_peer(peer, 0);
13062    unref_peer(peer, "removing poke peer ref");
13063 
13064    return 0;
13065 }

static int sip_prepare_socket ( struct sip_pvt *  p  )  [static]

Todo:
Get socket for dialog, prepare if needed, and return file handle

Todo:
Check this... This might be wrong, depending on the proxy configuration If proxy is in "force" mode its correct.

Definition at line 24380 of file chan_sip.c.

References ao2_alloc, ao2_ref, ao2_t_ref, ao2_t_unlink, ast_calloc, ast_copy_string(), ast_debug, ast_pthread_create_background, ast_sockaddr_copy(), ast_strdup, ast_strlen_zero(), ast_tcptls_client_create(), ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, default_tls_cfg, ast_tcptls_session_instance::fd, name, ast_tls_config::pvtfile, sip_real_dst(), sip_tcp_locate(), sip_tcp_worker_fn(), sip_tcptls_client_args_destructor(), sip_threadinfo_create(), sipsock, and threadt.

Referenced by __sip_xmit().

24381 {
24382    struct sip_socket *s = &p->socket;
24383    static const char name[] = "SIP socket";
24384    struct sip_threadinfo *th = NULL;
24385    struct ast_tcptls_session_instance *tcptls_session;
24386    struct ast_tcptls_session_args *ca;
24387    struct ast_sockaddr sa_tmp;
24388 
24389    /* check to see if a socket is already active */
24390    if ((s->fd != -1) && (s->type == SIP_TRANSPORT_UDP)) {
24391       return s->fd;
24392    }
24393    if ((s->type & (SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS)) &&
24394          (s->tcptls_session) &&
24395          (s->tcptls_session->fd != -1)) {
24396       return s->tcptls_session->fd;
24397    }
24398 
24399    /*! \todo Check this... This might be wrong, depending on the proxy configuration
24400       If proxy is in "force" mode its correct.
24401     */
24402    if (p->outboundproxy && p->outboundproxy->transport) {
24403       s->type = p->outboundproxy->transport;
24404    }
24405 
24406    if (s->type == SIP_TRANSPORT_UDP) {
24407       s->fd = sipsock;
24408       return s->fd;
24409    }
24410 
24411    /* At this point we are dealing with a TCP/TLS connection
24412     * 1. We need to check to see if a connectin thread exists
24413     *    for this address, if so use that.
24414     * 2. If a thread does not exist for this address, but the tcptls_session
24415     *    exists on the socket, the connection was closed.
24416     * 3. If no tcptls_session thread exists for the address, and no tcptls_session
24417     *    already exists on the socket, create a new one and launch a new thread.
24418     */
24419 
24420    /* 1.  check for existing threads */
24421    ast_sockaddr_copy(&sa_tmp, sip_real_dst(p));
24422    if ((tcptls_session = sip_tcp_locate(&sa_tmp))) {
24423       s->fd = tcptls_session->fd;
24424       if (s->tcptls_session) {
24425          ao2_ref(s->tcptls_session, -1);
24426          s->tcptls_session = NULL;
24427       }
24428       s->tcptls_session = tcptls_session;
24429       return s->fd;
24430    /* 2.  Thread not found, if tcptls_session already exists, it once had a thread and is now terminated */
24431    } else if (s->tcptls_session) {
24432       return s->fd; /* XXX whether reconnection is ever necessary here needs to be investigated further */
24433    }
24434 
24435    /* 3.  Create a new TCP/TLS client connection */
24436    /* create new session arguments for the client connection */
24437    if (!(ca = ao2_alloc(sizeof(*ca), sip_tcptls_client_args_destructor)) ||
24438       !(ca->name = ast_strdup(name))) {
24439       goto create_tcptls_session_fail;
24440    }
24441    ca->accept_fd = -1;
24442    ast_sockaddr_copy(&ca->remote_address,sip_real_dst(p));
24443    /* if type is TLS, we need to create a tls cfg for this session arg */
24444    if (s->type == SIP_TRANSPORT_TLS) {
24445       if (!(ca->tls_cfg = ast_calloc(1, sizeof(*ca->tls_cfg)))) {
24446          goto create_tcptls_session_fail;
24447       }
24448       memcpy(ca->tls_cfg, &default_tls_cfg, sizeof(*ca->tls_cfg));
24449 
24450       if (!(ca->tls_cfg->certfile = ast_strdup(default_tls_cfg.certfile)) ||
24451          !(ca->tls_cfg->pvtfile = ast_strdup(default_tls_cfg.pvtfile)) ||
24452          !(ca->tls_cfg->cipher = ast_strdup(default_tls_cfg.cipher)) ||
24453          !(ca->tls_cfg->cafile = ast_strdup(default_tls_cfg.cafile)) ||
24454          !(ca->tls_cfg->capath = ast_strdup(default_tls_cfg.capath))) {
24455 
24456          goto create_tcptls_session_fail;
24457       }
24458 
24459       /* this host is used as the common name in ssl/tls */
24460       if (!ast_strlen_zero(p->tohost)) {
24461          ast_copy_string(ca->hostname, p->tohost, sizeof(ca->hostname));
24462       }
24463    }
24464 
24465    /* Create a client connection for address, this does not start the connection, just sets it up. */
24466    if (!(s->tcptls_session = ast_tcptls_client_create(ca))) {
24467       goto create_tcptls_session_fail;
24468    }
24469 
24470    s->fd = s->tcptls_session->fd;
24471 
24472    /* client connections need to have the sip_threadinfo object created before
24473     * the thread is detached.  This ensures the alert_pipe is up before it will
24474     * be used.  Note that this function links the new threadinfo object into the
24475     * threadt container. */
24476    if (!(th = sip_threadinfo_create(s->tcptls_session, s->type))) {
24477       goto create_tcptls_session_fail;
24478    }
24479 
24480    /* Give the new thread a reference to the tcptls_session */
24481    ao2_ref(s->tcptls_session, +1);
24482 
24483    if (ast_pthread_create_background(&ca->master, NULL, sip_tcp_worker_fn, s->tcptls_session)) {
24484       ast_debug(1, "Unable to launch '%s'.", ca->name);
24485       ao2_ref(s->tcptls_session, -1); /* take away the thread ref we just gave it */
24486       goto create_tcptls_session_fail;
24487    }
24488 
24489    return s->fd;
24490 
24491 create_tcptls_session_fail:
24492    if (ca) {
24493       ao2_t_ref(ca, -1, "failed to create client, getting rid of client tcptls_session arguments");
24494    }
24495    if (s->tcptls_session) {
24496       close(tcptls_session->fd);
24497       s->fd = tcptls_session->fd = -1;
24498       ao2_ref(s->tcptls_session, -1);
24499       s->tcptls_session = NULL;
24500    }
24501    if (th) {
24502       ao2_t_unlink(threadt, th, "Removing tcptls thread info object, thread failed to open");
24503    }
24504 
24505    return -1;
24506 }

static char * sip_prune_realtime ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

Remove temporary realtime objects from memory (CLI).

Todo:
XXXX Propably needs an overhaul after removal of the devices

Definition at line 16238 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_find, ao2_t_iterator_next, ao2_t_link, ao2_t_unlink, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_complete(), ast_copy_string(), ast_sockaddr_isnull(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_peer(), FALSE, ast_cli_args::fd, ast_cli_args::n, name, OBJ_POINTER, OBJ_UNLINK, peers_by_ip, ast_cli_args::pos, TRUE, unlink_marked_peers_from_tables(), unref_peer(), ast_cli_entry::usage, and ast_cli_args::word.

16239 {
16240    struct sip_peer *peer, *pi;
16241    int prunepeer = FALSE;
16242    int multi = FALSE;
16243    const char *name = NULL;
16244    regex_t regexbuf;
16245    struct ao2_iterator i;
16246    static const char * const choices[] = { "all", "like", NULL };
16247    char *cmplt;
16248    
16249    if (cmd == CLI_INIT) {
16250       e->command = "sip prune realtime [peer|all]";
16251       e->usage =
16252          "Usage: sip prune realtime [peer [<name>|all|like <pattern>]|all]\n"
16253          "       Prunes object(s) from the cache.\n"
16254          "       Optional regular expression pattern is used to filter the objects.\n";
16255       return NULL;
16256    } else if (cmd == CLI_GENERATE) {
16257       if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) {
16258          cmplt = ast_cli_complete(a->word, choices, a->n);
16259          if (!cmplt)
16260             cmplt = complete_sip_peer(a->word, a->n - sizeof(choices), SIP_PAGE2_RTCACHEFRIENDS);
16261          return cmplt;
16262       }
16263       if (a->pos == 5 && !strcasecmp(a->argv[4], "like"))
16264          return complete_sip_peer(a->word, a->n, SIP_PAGE2_RTCACHEFRIENDS);
16265       return NULL;
16266    }
16267    switch (a->argc) {
16268    case 4:
16269       name = a->argv[3];
16270       /* we accept a name in position 3, but keywords are not good. */
16271       if (!strcasecmp(name, "peer") || !strcasecmp(name, "like"))
16272          return CLI_SHOWUSAGE;
16273       prunepeer = TRUE;
16274       if (!strcasecmp(name, "all")) {
16275          multi = TRUE;
16276          name = NULL;
16277       }
16278       /* else a single name, already set */
16279       break;
16280    case 5:
16281       /* sip prune realtime {peer|like} name */
16282       name = a->argv[4];
16283       if (!strcasecmp(a->argv[3], "peer"))
16284          prunepeer = TRUE;
16285       else if (!strcasecmp(a->argv[3], "like")) {
16286          prunepeer = TRUE;
16287          multi = TRUE;
16288       } else
16289          return CLI_SHOWUSAGE;
16290       if (!strcasecmp(name, "like"))
16291          return CLI_SHOWUSAGE;
16292       if (!multi && !strcasecmp(name, "all")) {
16293          multi = TRUE;
16294          name = NULL;
16295       }
16296       break;
16297    case 6:
16298       name = a->argv[5];
16299       multi = TRUE;
16300       /* sip prune realtime {peer} like name */
16301       if (strcasecmp(a->argv[4], "like"))
16302          return CLI_SHOWUSAGE;
16303       if (!strcasecmp(a->argv[3], "peer")) {
16304          prunepeer = TRUE;
16305       } else
16306          return CLI_SHOWUSAGE;
16307       break;
16308    default:
16309       return CLI_SHOWUSAGE;
16310    }
16311 
16312    if (multi && name) {
16313       if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB))
16314          return CLI_SHOWUSAGE;
16315    }
16316 
16317    if (multi) {
16318       if (prunepeer) {
16319          int pruned = 0;
16320          
16321          i = ao2_iterator_init(peers, 0);
16322          while ((pi = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
16323             ao2_lock(pi);
16324             if (name && regexec(&regexbuf, pi->name, 0, NULL, 0)) {
16325                unref_peer(pi, "toss iterator peer ptr before continue");
16326                ao2_unlock(pi);
16327                continue;
16328             };
16329             if (ast_test_flag(&pi->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
16330                pi->the_mark = 1;
16331                pruned++;
16332             }
16333             ao2_unlock(pi);
16334             unref_peer(pi, "toss iterator peer ptr");
16335          }
16336          ao2_iterator_destroy(&i);
16337          if (pruned) {
16338             unlink_marked_peers_from_tables();
16339             ast_cli(a->fd, "%d peers pruned.\n", pruned);
16340          } else
16341             ast_cli(a->fd, "No peers found to prune.\n");
16342       }
16343    } else {
16344       if (prunepeer) {
16345          struct sip_peer tmp;
16346          ast_copy_string(tmp.name, name, sizeof(tmp.name));
16347          if ((peer = ao2_t_find(peers, &tmp, OBJ_POINTER | OBJ_UNLINK, "finding to unlink from peers"))) {
16348             if (!ast_sockaddr_isnull(&peer->addr)) {
16349                ao2_t_unlink(peers_by_ip, peer, "unlinking peer from peers_by_ip also");
16350             }
16351             if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
16352                ast_cli(a->fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
16353                /* put it back! */
16354                ao2_t_link(peers, peer, "link peer into peer table");
16355                if (!ast_sockaddr_isnull(&peer->addr)) {
16356                   ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
16357                }
16358             } else
16359                ast_cli(a->fd, "Peer '%s' pruned.\n", name);
16360             unref_peer(peer, "sip_prune_realtime: unref_peer: tossing temp peer ptr");
16361          } else
16362             ast_cli(a->fd, "Peer '%s' not found.\n", name);
16363       }
16364    }
16365 
16366    return CLI_SUCCESS;
16367 }

static char * sip_qualify_peer ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

Send an OPTIONS packet to a SIP peer.

Definition at line 16516 of file chan_sip.c.

References _sip_qualify_peer(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_sip_show_peer(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

16517 {
16518    switch (cmd) {
16519    case CLI_INIT:
16520       e->command = "sip qualify peer";
16521       e->usage =
16522          "Usage: sip qualify peer <name> [load]\n"
16523          "       Requests a response from one SIP peer and the current status.\n"
16524          "       Option \"load\" forces lookup of peer in realtime storage.\n";
16525       return NULL;
16526    case CLI_GENERATE:
16527       return complete_sip_show_peer(a->line, a->word, a->pos, a->n);
16528    }
16529    return _sip_qualify_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv);
16530 }

static int sip_queryoption ( struct ast_channel *  chan,
int  option,
void *  data,
int *  datalen 
) [static]

Query an option on a SIP dialog.

Definition at line 4210 of file chan_sip.c.

References ast_copy_string(), ast_debug, ast_log(), AST_OPTION_DEVICE_NAME, AST_OPTION_DIGIT_DETECT, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, AST_OPTION_T38_STATE, ast_test_flag, LOG_ERROR, ast_channel::name, sip_pvt_lock, sip_pvt_unlock, T38_STATE_NEGOTIATED, T38_STATE_NEGOTIATING, T38_STATE_UNAVAILABLE, T38_STATE_UNKNOWN, and ast_channel::tech_pvt.

04211 {
04212    int res = -1;
04213    enum ast_t38_state state = T38_STATE_UNAVAILABLE;
04214    struct sip_pvt *p = (struct sip_pvt *) chan->tech_pvt;
04215    char *cp;
04216 
04217    switch (option) {
04218    case AST_OPTION_T38_STATE:
04219       /* Make sure we got an ast_t38_state enum passed in */
04220       if (*datalen != sizeof(enum ast_t38_state)) {
04221          ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option. Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen);
04222          return -1;
04223       }
04224 
04225       sip_pvt_lock(p);
04226 
04227       /* Now if T38 support is enabled we need to look and see what the current state is to get what we want to report back */
04228       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) {
04229          switch (p->t38.state) {
04230          case T38_LOCAL_REINVITE:
04231          case T38_PEER_REINVITE:
04232             state = T38_STATE_NEGOTIATING;
04233             break;
04234          case T38_ENABLED:
04235             state = T38_STATE_NEGOTIATED;
04236             break;
04237          default:
04238             state = T38_STATE_UNKNOWN;
04239          }
04240       }
04241 
04242       sip_pvt_unlock(p);
04243 
04244       *((enum ast_t38_state *) data) = state;
04245       res = 0;
04246 
04247       break;
04248    case AST_OPTION_DIGIT_DETECT:
04249       cp = (char *) data;
04250       *cp = p->dsp ? 1 : 0;
04251       ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", chan->name);
04252       break;
04253    case AST_OPTION_SECURE_SIGNALING:
04254       *((unsigned int *) data) = p->req_secure_signaling;
04255       res = 0;
04256       break;
04257    case AST_OPTION_SECURE_MEDIA:
04258       *((unsigned int *) data) = ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP) ? 1 : 0;
04259       res = 0;
04260       break;
04261    case AST_OPTION_DEVICE_NAME:
04262       if (p && p->outgoing_call) {
04263          cp = (char *) data;
04264          ast_copy_string(cp, p->dialstring, *datalen);
04265          res = 0;
04266       }
04267       /* We purposely break with a return of -1 in the
04268        * implied else case here
04269        */
04270       break;
04271    default:
04272       break;
04273    }
04274 
04275    return res;
04276 }

static struct ast_frame * sip_read ( struct ast_channel *  ast  )  [static]

Read SIP RTP from channel.

Definition at line 7122 of file chan_sip.c.

References ast_channel::_state, ast_async_goto(), ast_channel_lock, ast_channel_unlock, ast_exists_extension(), AST_FRAME_VOICE, ast_log(), ast_null_frame, AST_STATE_UP, ast_test_flag, ast_verbose, FALSE, ast_frame::frametype, LOG_NOTICE, pbx_builtin_setvar_helper(), S_COR, S_OR, sip_pvt_lock, sip_pvt_unlock, sip_rtp_read(), ast_channel::tech_pvt, and VERBOSE_PREFIX_2.

07123 {
07124    struct ast_frame *fr;
07125    struct sip_pvt *p = ast->tech_pvt;
07126    int faxdetected = FALSE;
07127 
07128    sip_pvt_lock(p);
07129    fr = sip_rtp_read(ast, p, &faxdetected);
07130    p->lastrtprx = time(NULL);
07131 
07132    /* If we detect a CNG tone and fax detection is enabled then send us off to the fax extension */
07133    if (faxdetected && ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_CNG)) {
07134       ast_channel_lock(ast);
07135       if (strcmp(ast->exten, "fax")) {
07136          const char *target_context = S_OR(ast->macrocontext, ast->context);
07137          ast_channel_unlock(ast);
07138          if (ast_exists_extension(ast, target_context, "fax", 1,
07139             S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) {
07140             ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to CNG detection\n", ast->name);
07141             pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
07142             if (ast_async_goto(ast, target_context, "fax", 1)) {
07143                ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
07144             }
07145             fr = &ast_null_frame;
07146          } else {
07147             ast_log(LOG_NOTICE, "FAX CNG detected but no fax extension\n");
07148          }
07149       } else {
07150          ast_channel_unlock(ast);
07151       }
07152    }
07153 
07154    /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */
07155    if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) {
07156       fr = &ast_null_frame;
07157    }
07158 
07159    sip_pvt_unlock(p);
07160 
07161    return fr;
07162 }

static struct ast_sockaddr * sip_real_dst ( const struct sip_pvt *  p  )  [static]

The real destination address for a write.

Definition at line 3119 of file chan_sip.c.

References ast_test_flag.

Referenced by __sip_xmit(), check_via(), retrans_pkt(), send_response(), show_channels_cb(), sip_debug_test_pvt(), and sip_prepare_socket().

03120 {
03121    if (p->outboundproxy) {
03122       return &p->outboundproxy->ip;
03123    }
03124 
03125    return ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT) ? &p->recv : &p->sa;
03126 }

static const char* sip_reason_code_to_str ( enum AST_REDIRECTING_REASON  code  )  [static]

Definition at line 2257 of file chan_sip.c.

References ARRAY_LEN, sip_reason_table, and sip_reasons::text.

Referenced by add_diversion_header().

02258 {
02259    if (code >= 0 && code < ARRAY_LEN(sip_reason_table)) {
02260       return sip_reason_table[code].text;
02261    }
02262 
02263    return "unknown";
02264 }

static enum AST_REDIRECTING_REASON sip_reason_str_to_code ( const char *  text  )  [static]

Definition at line 2242 of file chan_sip.c.

References ARRAY_LEN, AST_REDIRECTING_REASON_UNKNOWN, sip_reasons::code, and sip_reason_table.

Referenced by get_rdnis().

02243 {
02244    enum AST_REDIRECTING_REASON ast = AST_REDIRECTING_REASON_UNKNOWN;
02245    int i;
02246 
02247    for (i = 0; i < ARRAY_LEN(sip_reason_table); ++i) {
02248       if (!strcasecmp(text, sip_reason_table[i].text)) {
02249          ast = sip_reason_table[i].code;
02250          break;
02251       }
02252    }
02253 
02254    return ast;
02255 }

static int sip_refer_allocate ( struct sip_pvt *  p  )  [static]

Allocate SIP refer structure.

Definition at line 12730 of file chan_sip.c.

References ast_calloc.

Referenced by get_also_info(), handle_request_invite(), handle_request_refer(), and transmit_refer().

12731 {
12732    p->refer = ast_calloc(1, sizeof(struct sip_refer));
12733    return p->refer ? 1 : 0;
12734 }

static int sip_reg_timeout ( const void *  data  )  [static]

Registration timeout, register again Registered as a timeout handler during transmit_register(), to retransmit the packet if a reply does not come back. This is called by the scheduler so the event is not pending anymore when we are called.

Definition at line 12430 of file chan_sip.c.

References __sip_pretend_ack(), ast_dnsmgr_refresh(), ast_log(), EVENT_FLAG_SYSTEM, global_regattempts_max, LOG_NOTICE, manager_event, pvt_set_needdestroy(), REG_STATE_UNREGISTERED, registry_unref(), regstate2str(), sip_pvt_lock, sip_pvt_unlock, and transmit_register().

Referenced by sip_show_sched(), and transmit_register().

12431 {
12432 
12433    /* if we are here, our registration timed out, so we'll just do it over */
12434    struct sip_registry *r = (struct sip_registry *)data; /* the ref count should have been bumped when the sched item was added */
12435    struct sip_pvt *p;
12436    int res;
12437 
12438    /* if we couldn't get a reference to the registry object, punt */
12439    if (!r) {
12440       return 0;
12441    }
12442 
12443    if (r->dnsmgr) {
12444       /* If the registration has timed out, maybe the IP changed.  Force a refresh. */
12445       ast_dnsmgr_refresh(r->dnsmgr);
12446    }
12447 
12448    /* If the initial tranmission failed, we may not have an existing dialog,
12449     * so it is possible that r->call == NULL.
12450     * Otherwise destroy it, as we have a timeout so we don't want it.
12451     */
12452    if (r->call) {
12453       /* Unlink us, destroy old call.  Locking is not relevant here because all this happens
12454          in the single SIP manager thread. */
12455       p = r->call;
12456       sip_pvt_lock(p);
12457       pvt_set_needdestroy(p, "registration timeout");
12458       /* Pretend to ACK anything just in case */
12459       __sip_pretend_ack(p);
12460       sip_pvt_unlock(p);
12461 
12462       /* decouple the two objects */
12463       /* p->registry == r, so r has 2 refs, and the unref won't take the object away */
12464       if (p->registry) {
12465          p->registry = registry_unref(p->registry, "p->registry unreffed");
12466       }
12467       r->call = dialog_unref(r->call, "unrefing r->call");
12468    }
12469    /* If we have a limit, stop registration and give up */
12470    r->timeout = -1;
12471    if (global_regattempts_max && r->regattempts >= global_regattempts_max) {
12472       /* Ok, enough is enough. Don't try any more */
12473       /* We could add an external notification here...
12474          steal it from app_voicemail :-) */
12475       ast_log(LOG_NOTICE, "   -- Last Registration Attempt #%d failed, Giving up forever trying to register '%s@%s'\n", r->regattempts, r->username, r->hostname);
12476       r->regstate = REG_STATE_FAILED;
12477    } else {
12478       r->regstate = REG_STATE_UNREGISTERED;
12479       res = transmit_register(r, SIP_REGISTER, NULL, NULL);
12480       ast_log(LOG_NOTICE, "   -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts);
12481    }
12482    manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate));
12483    registry_unref(r, "unreffing registry_unref r");
12484    return 0;
12485 }

static int sip_register ( const char *  value,
int  lineno 
) [static]

create sip_registry object from register=> line in sip.conf and link into reg container

Definition at line 7769 of file chan_sip.c.

References ast_atomic_fetchadd_int(), ast_calloc_with_stringfields, ast_log(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, default_expiry, LOG_ERROR, registry_unref(), regl, and regobjs.

Referenced by build_peer().

07770 {
07771    struct sip_registry *reg;
07772 
07773    if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
07774       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
07775       return -1;
07776    }
07777 
07778    ast_atomic_fetchadd_int(&regobjs, 1);
07779    ASTOBJ_INIT(reg);
07780 
07781    if (sip_parse_register_line(reg, default_expiry, value, lineno)) {
07782       registry_unref(reg, "failure to parse, unref the reg pointer");
07783       return -1;
07784    }
07785 
07786    /* set default expiry if necessary */
07787    if (reg->refresh && !reg->expiry && !reg->configured_expiry) {
07788       reg->refresh = reg->expiry = reg->configured_expiry = default_expiry;
07789    }
07790 
07791    /* Add the new registry entry to the list */
07792    ASTOBJ_CONTAINER_LINK(&regl, reg);
07793 
07794    /* release the reference given by ASTOBJ_INIT. The container has another reference */
07795    registry_unref(reg, "unref the reg pointer");
07796 
07797    return 0;
07798 }

static void sip_register_tests ( void   )  [static]

SIP test registration.

Definition at line 28617 of file chan_sip.c.

Referenced by load_module().

28618 {
28619    sip_config_parser_register_tests();
28620    sip_request_parser_register_tests();
28621    sip_dialplan_function_register_tests();
28622 }

static void sip_registry_destroy ( struct sip_registry *  reg  )  [static]

Destroy registry object Objects created with the register= statement in static configuration.

Definition at line 5415 of file chan_sip.c.

References ast_atomic_fetchadd_int(), ast_debug, ast_dnsmgr_release(), ast_free, AST_SCHED_DEL, ast_string_field_free_memory, dialog_unlink_all(), registry_unref(), regobjs, and TRUE.

Referenced by registry_unref(), and unload_module().

05416 {
05417    /* Really delete */
05418    ast_debug(3, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname);
05419 
05420    if (reg->call) {
05421       /* Clear registry before destroying to ensure
05422          we don't get reentered trying to grab the registry lock */
05423       reg->call->registry = registry_unref(reg->call->registry, "destroy reg->call->registry");
05424       ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
05425       dialog_unlink_all(reg->call, TRUE, TRUE);
05426       reg->call = dialog_unref(reg->call, "unref reg->call");
05427       /* reg->call = sip_destroy(reg->call); */
05428    }
05429    AST_SCHED_DEL(sched, reg->expire);  
05430    AST_SCHED_DEL(sched, reg->timeout);
05431    
05432    ast_string_field_free_memory(reg);
05433    ast_atomic_fetchadd_int(&regobjs, -1);
05434    ast_dnsmgr_release(reg->dnsmgr);
05435    ast_free(reg);
05436 }

static int sip_reinvite_retry ( const void *  data  )  [static]

Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler.

Definition at line 18901 of file chan_sip.c.

References ast_channel_trylock, ast_channel_unlock, ast_set_flag, check_pendings(), sip_pvt_lock, and sip_pvt_unlock.

Referenced by handle_response_invite(), and sip_show_sched().

18902 {
18903    struct sip_pvt *p = (struct sip_pvt *) data;
18904    struct ast_channel *owner;
18905 
18906    sip_pvt_lock(p); /* called from schedule thread which requires a lock */
18907    while ((owner = p->owner) && ast_channel_trylock(owner)) {
18908       sip_pvt_unlock(p);
18909       usleep(1);
18910       sip_pvt_lock(p);
18911    }
18912    ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
18913    p->waitid = -1;
18914    check_pendings(p);
18915    sip_pvt_unlock(p);
18916    if (owner) {
18917       ast_channel_unlock(owner);
18918    }
18919    dialog_unref(p, "unref the dialog ptr from sip_reinvite_retry, because it held a dialog ptr");
18920    return 0;
18921 }

static char * sip_reload ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

Force reload of module from cli.

Definition at line 28389 of file chan_sip.c.

References ast_mutex_lock, ast_mutex_unlock, ast_verbose, CHANNEL_CLI_RELOAD, CHANNEL_MODULE_RELOAD, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, restart_monitor(), sip_reload_lock, sip_reloading, sip_reloadreason, TRUE, and ast_cli_entry::usage.

Referenced by reload().

28390 {
28391    
28392    switch (cmd) {
28393    case CLI_INIT:
28394       e->command = "sip reload";
28395       e->usage =
28396          "Usage: sip reload\n"
28397          "       Reloads SIP configuration from sip.conf\n";
28398       return NULL;
28399    case CLI_GENERATE:
28400       return NULL;
28401    }
28402 
28403    ast_mutex_lock(&sip_reload_lock);
28404    if (sip_reloading) {
28405       ast_verbose("Previous SIP reload not yet done\n");
28406    } else {
28407       sip_reloading = TRUE;
28408       sip_reloadreason = (a && a->fd) ? CHANNEL_CLI_RELOAD : CHANNEL_MODULE_RELOAD;
28409    }
28410    ast_mutex_unlock(&sip_reload_lock);
28411    restart_monitor();
28412 
28413    return CLI_SUCCESS;
28414 }

static int sip_removeheader ( struct ast_channel *  chan,
const char *  data 
) [static]

Remove SIP headers added previously with SipAddHeader application.

Definition at line 28140 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, ast_debug, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_strlen_zero(), ast_var_delete(), ast_var_name(), ast_var_value(), inbuf(), and ast_channel::varshead.

Referenced by load_module().

28141 {
28142    struct ast_var_t *newvariable;
28143    struct varshead *headp;
28144    int removeall = 0;
28145    char *inbuf = (char *) data;
28146 
28147    if (ast_strlen_zero(inbuf)) {
28148       removeall = 1;
28149    }
28150    ast_channel_lock(chan);
28151 
28152    headp=&chan->varshead;
28153    AST_LIST_TRAVERSE_SAFE_BEGIN (headp, newvariable, entries) {
28154       if (strncasecmp(ast_var_name(newvariable), "SIPADDHEADER", strlen("SIPADDHEADER")) == 0) {
28155          if (removeall || (!strncasecmp(ast_var_value(newvariable),inbuf,strlen(inbuf)))) {
28156             if (sipdebug)
28157                ast_debug(1,"removing SIP Header \"%s\" as %s\n",
28158                   ast_var_value(newvariable),
28159                   ast_var_name(newvariable));
28160             AST_LIST_REMOVE_CURRENT(entries);
28161             ast_var_delete(newvariable);
28162          }
28163       }
28164    }
28165    AST_LIST_TRAVERSE_SAFE_END;
28166 
28167    ast_channel_unlock(chan);
28168    return 0;
28169 }

static struct ast_channel * sip_request_call ( const char *  type,
format_t  format,
const struct ast_channel *  requestor,
void *  data,
int *  cause 
) [static]

PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.

 * 	SIP Dial string syntax
 *		SIP/exten@host!dnid
 *	or	SIP/host/exten!dnid
 *	or	SIP/host!dnid
 * 

Definition at line 25304 of file chan_sip.c.

References ao2_t_link, ao2_t_unlink, args, AST_APP_ARG, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CHANNEL_UNACCEPTABLE, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, AST_FORMAT_AUDIO_MASK, ast_getformatname(), ast_getformatname_multiple(), ast_log(), AST_NONSTANDARD_APP_ARGS, ast_sip_ouraddrfor(), ast_sockaddr_port, ast_sockaddr_resolve_first(), ast_sockaddr_set_port, AST_STATE_DOWN, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_callid_pvt(), build_via(), create_addr(), dialog_unlink_all(), dialogs, EVENT_FLAG_SYSTEM, ext, exten, ast_channel::linkedid, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, restart_monitor(), secret, set_socket_transport(), sip_alloc(), sip_cfg, sip_new(), sip_pvt_lock, sip_pvt_unlock, and TRUE.

25305 {
25306    struct sip_pvt *p;
25307    struct ast_channel *tmpc = NULL;
25308    char *ext = NULL, *host;
25309    char tmp[256];
25310    char *dest = data;
25311    char *dnid;
25312    char *secret = NULL;
25313    char *md5secret = NULL;
25314    char *authname = NULL;
25315    char *trans = NULL;
25316    char dialstring[256];
25317    char *remote_address;
25318    enum sip_transport transport = 0;
25319    struct ast_sockaddr remote_address_sa = { {0,} };
25320    format_t oldformat = format;
25321    AST_DECLARE_APP_ARGS(args,
25322       AST_APP_ARG(peerorhost);
25323       AST_APP_ARG(exten);
25324       AST_APP_ARG(remote_address);
25325    );
25326 
25327    /* mask request with some set of allowed formats.
25328     * XXX this needs to be fixed.
25329     * The original code uses AST_FORMAT_AUDIO_MASK, but it is
25330     * unclear what to use here. We have global_capabilities, which is
25331     * configured from sip.conf, and sip_tech.capabilities, which is
25332     * hardwired to all audio formats.
25333     */
25334    format &= AST_FORMAT_AUDIO_MASK;
25335    if (!format) {
25336       ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format %s while capability is %s\n", ast_getformatname(oldformat), ast_getformatname(sip_cfg.capability));
25337       *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;   /* Can't find codec to connect to host */
25338       return NULL;
25339    }
25340    ast_debug(1, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat));
25341 
25342    if (ast_strlen_zero(dest)) {
25343       ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n");
25344       *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
25345       return NULL;
25346    }
25347 
25348    if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE, NULL))) {
25349       ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", dest);
25350       *cause = AST_CAUSE_SWITCH_CONGESTION;
25351       return NULL;
25352    }
25353 
25354    p->outgoing_call = TRUE;
25355 
25356    snprintf(dialstring, sizeof(dialstring), "%s/%s", type, dest);
25357    ast_string_field_set(p, dialstring, dialstring);
25358 
25359    if (!(p->options = ast_calloc(1, sizeof(*p->options)))) {
25360       dialog_unlink_all(p, TRUE, TRUE);
25361       dialog_unref(p, "unref dialog p from mem fail");
25362       /* sip_destroy(p); */
25363       ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
25364       *cause = AST_CAUSE_SWITCH_CONGESTION;
25365       return NULL;
25366    }
25367 
25368    /* Save the destination, the SIP dial string */
25369    ast_copy_string(tmp, dest, sizeof(tmp));
25370 
25371    /* Find DNID and take it away */
25372    dnid = strchr(tmp, '!');
25373    if (dnid != NULL) {
25374       *dnid++ = '\0';
25375       ast_string_field_set(p, todnid, dnid);
25376    }
25377 
25378    /* Divvy up the items separated by slashes */
25379    AST_NONSTANDARD_APP_ARGS(args, tmp, '/');
25380 
25381    /* Find at sign - @ */
25382    host = strchr(args.peerorhost, '@');
25383    if (host) {
25384       *host++ = '\0';
25385       ext = args.peerorhost;
25386       secret = strchr(ext, ':');
25387    }
25388    if (secret) {
25389       *secret++ = '\0';
25390       md5secret = strchr(secret, ':');
25391    }
25392    if (md5secret) {
25393       *md5secret++ = '\0';
25394       authname = strchr(md5secret, ':');
25395    }
25396    if (authname) {
25397       *authname++ = '\0';
25398       trans = strchr(authname, ':');
25399    }
25400    if (trans) {
25401       *trans++ = '\0';
25402       if (!strcasecmp(trans, "tcp"))
25403          transport = SIP_TRANSPORT_TCP;
25404       else if (!strcasecmp(trans, "tls"))
25405          transport = SIP_TRANSPORT_TLS;
25406       else {
25407          if (strcasecmp(trans, "udp"))
25408             ast_log(LOG_WARNING, "'%s' is not a valid transport option to Dial() for SIP calls, using udp by default.\n", trans);
25409          transport = SIP_TRANSPORT_UDP;
25410       }
25411    } else { /* use default */
25412       transport = SIP_TRANSPORT_UDP;
25413    }
25414 
25415    if (!host) {
25416       ext = args.exten;
25417       host = args.peerorhost;
25418       remote_address = args.remote_address;
25419    } else {
25420       remote_address = args.remote_address;
25421       if (!ast_strlen_zero(args.exten)) {
25422          ast_log(LOG_NOTICE, "Conflicting extension values given. Using '%s' and not '%s'\n", ext, args.exten);
25423       }
25424    }
25425 
25426    if (!ast_strlen_zero(remote_address)) {
25427       if (ast_sockaddr_resolve_first(&remote_address_sa, remote_address, 0)) {
25428          ast_log(LOG_WARNING, "Unable to find IP address for host %s. We will not use this remote IP address\n", remote_address);
25429       } else {
25430          if (!ast_sockaddr_port(&remote_address_sa)) {
25431             ast_sockaddr_set_port(&remote_address_sa,
25432                         transport & SIP_TRANSPORT_TLS ?
25433                         STANDARD_TLS_PORT :
25434                         STANDARD_SIP_PORT);
25435          }
25436       }
25437    }
25438 
25439    set_socket_transport(&p->socket, transport);
25440 
25441    /* We now have
25442       host = peer name, DNS host name or DNS domain (for SRV)
25443       ext = extension (user part of URI)
25444       dnid = destination of the call (applies to the To: header)
25445    */
25446    if (create_addr(p, host, NULL, 1, &remote_address_sa)) {
25447       *cause = AST_CAUSE_UNREGISTERED;
25448       ast_debug(3, "Cant create SIP call - target device not registered\n");
25449       dialog_unlink_all(p, TRUE, TRUE);
25450       dialog_unref(p, "unref dialog p UNREGISTERED");
25451       /* sip_destroy(p); */
25452       return NULL;
25453    }
25454    if (ast_strlen_zero(p->peername) && ext)
25455       ast_string_field_set(p, peername, ext);
25456    /* Recalculate our side, and recalculate Call ID */
25457    ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
25458    build_via(p);
25459    ao2_t_unlink(dialogs, p, "About to change the callid -- remove the old name");
25460    build_callid_pvt(p);
25461    ao2_t_link(dialogs, p, "Linking in under new name");
25462    
25463    /* We have an extension to call, don't use the full contact here */
25464    /* This to enable dialing registered peers with extension dialling,
25465       like SIP/peername/extension   
25466       SIP/peername will still use the full contact
25467     */
25468    if (ext) {
25469       ast_string_field_set(p, username, ext);
25470       ast_string_field_set(p, fullcontact, NULL);
25471    }
25472    if (secret && !ast_strlen_zero(secret))
25473       ast_string_field_set(p, peersecret, secret);
25474 
25475    if (md5secret && !ast_strlen_zero(md5secret))
25476       ast_string_field_set(p, peermd5secret, md5secret);
25477 
25478    if (authname && !ast_strlen_zero(authname))
25479       ast_string_field_set(p, authname, authname);
25480 #if 0
25481    printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
25482 #endif
25483    p->prefcodec = oldformat;           /* Format for this call */
25484    p->jointcapability = oldformat & p->capability;
25485    sip_pvt_lock(p);
25486    tmpc = sip_new(p, AST_STATE_DOWN, host, requestor ? requestor->linkedid : NULL); /* Place the call */
25487    if (sip_cfg.callevents)
25488       manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
25489          "Channel: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n",
25490          p->owner? p->owner->name : "", "SIP", p->callid, p->fullcontact, p->peername);
25491    sip_pvt_unlock(p);
25492    if (!tmpc) {
25493       dialog_unlink_all(p, TRUE, TRUE);
25494       /* sip_destroy(p); */
25495    }
25496    dialog_unref(p, "toss pvt ptr at end of sip_request_call");
25497    ast_update_use_count();
25498    restart_monitor();
25499    return tmpc;
25500 }

static int sip_reregister ( const void *  data  )  [static]

Update registration with SIP Proxy. Called from the scheduler when the previous registration expires, so we don't have to cancel the pending event. We assume the reference so the sip_registry is valid, since it is stored in the scheduled event anyways.

Definition at line 12387 of file chan_sip.c.

References __sip_do_register(), append_history, ast_log(), LOG_NOTICE, registry_unref(), and sipdebug.

Referenced by handle_response_register(), sip_send_all_registers(), and sip_show_sched().

12388 {
12389    /* if we are here, we know that we need to reregister. */
12390    struct sip_registry *r = (struct sip_registry *) data;
12391 
12392    /* if we couldn't get a reference to the registry object, punt */
12393    if (!r) {
12394       return 0;
12395    }
12396 
12397    if (r->call && r->call->do_history) {
12398       append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname);
12399    }
12400    /* Since registry's are only added/removed by the the monitor thread, this
12401       may be overkill to reference/dereference at all here */
12402    if (sipdebug) {
12403       ast_log(LOG_NOTICE, "   -- Re-registration for  %s@%s\n", r->username, r->hostname);
12404    }
12405 
12406    r->expire = -1;
12407    r->expiry = r->configured_expiry;
12408    __sip_do_register(r);
12409    registry_unref(r, "unref the re-register scheduled event");
12410    return 0;
12411 }

static struct ast_frame* sip_rtp_read ( struct ast_channel *  ast,
struct sip_pvt *  p,
int *  faxdetect 
) [static]

Read RTP from network.

Definition at line 7033 of file chan_sip.c.

References ast_debug, ast_dsp_free(), ast_dsp_process(), ast_dsp_set_features(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_getformatname(), ast_null_frame, ast_rtp_instance_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), ast_verbose, DSP_FEATURE_DIGIT_DETECT, f, ast_channel::fdno, ast_channel::name, and sipdebug_text.

Referenced by sip_read().

07034 {
07035    /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
07036    struct ast_frame *f;
07037    
07038    if (!p->rtp) {
07039       /* We have no RTP allocated for this channel */
07040       return &ast_null_frame;
07041    }
07042 
07043    switch(ast->fdno) {
07044    case 0:
07045       f = ast_rtp_instance_read(p->rtp, 0);  /* RTP Audio */
07046       break;
07047    case 1:
07048       f = ast_rtp_instance_read(p->rtp, 1);  /* RTCP Control Channel */
07049       break;
07050    case 2:
07051       f = ast_rtp_instance_read(p->vrtp, 0); /* RTP Video */
07052       break;
07053    case 3:
07054       f = ast_rtp_instance_read(p->vrtp, 1); /* RTCP Control Channel for video */
07055       break;
07056    case 4:
07057       f = ast_rtp_instance_read(p->trtp, 0); /* RTP Text */
07058       if (sipdebug_text) {
07059          int i;
07060          unsigned char* arr = f->data.ptr;
07061          for (i=0; i < f->datalen; i++)
07062             ast_verbose("%c", (arr[i] > ' ' && arr[i] < '}') ? arr[i] : '.');
07063          ast_verbose(" -> ");
07064          for (i=0; i < f->datalen; i++)
07065             ast_verbose("%02X ", arr[i]);
07066          ast_verbose("\n");
07067       }
07068       break;
07069    case 5:
07070       f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */
07071       break;
07072    default:
07073       f = &ast_null_frame;
07074    }
07075    /* Don't forward RFC2833 if we're not supposed to */
07076    if (f && (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) &&
07077        (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) {
07078       ast_debug(1, "Ignoring DTMF (%c) RTP frame because dtmfmode is not RFC2833\n", f->subclass.integer);
07079       return &ast_null_frame;
07080    }
07081 
07082    /* We already hold the channel lock */
07083    if (!p->owner || (f && f->frametype != AST_FRAME_VOICE))
07084       return f;
07085 
07086    if (f && f->subclass.codec != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
07087       if (!(f->subclass.codec & p->jointcapability)) {
07088          ast_debug(1, "Bogus frame of format '%s' received from '%s'!\n",
07089             ast_getformatname(f->subclass.codec), p->owner->name);
07090          return &ast_null_frame;
07091       }
07092       ast_debug(1, "Oooh, format changed to %s\n",
07093          ast_getformatname(f->subclass.codec));
07094       p->owner->nativeformats = (p->owner->nativeformats & (AST_FORMAT_VIDEO_MASK | AST_FORMAT_TEXT_MASK)) | f->subclass.codec;
07095       ast_set_read_format(p->owner, p->owner->readformat);
07096       ast_set_write_format(p->owner, p->owner->writeformat);
07097    }
07098 
07099    if (f && p->dsp) {
07100       f = ast_dsp_process(p->owner, p->dsp, f);
07101       if (f && f->frametype == AST_FRAME_DTMF) {
07102          if (f->subclass.integer == 'f') {
07103             ast_debug(1, "Fax CNG detected on %s\n", ast->name);
07104             *faxdetect = 1;
07105             /* If we only needed this DSP for fax detection purposes we can just drop it now */
07106             if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
07107                ast_dsp_set_features(p->dsp, DSP_FEATURE_DIGIT_DETECT);
07108             } else {
07109                ast_dsp_free(p->dsp);
07110                p->dsp = NULL;
07111             }
07112          } else {
07113             ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.integer);
07114          }
07115       }
07116    }
07117    
07118    return f;
07119 }

void sip_scheddestroy ( struct sip_pvt *  p,
int  ms 
)

Schedule destruction of SIP dialog.

Definition at line 3827 of file chan_sip.c.

References __sip_autodestruct(), append_history, ast_log(), ast_sched_add(), ast_verbose, global_t1, global_timer_b, LOG_WARNING, sip_cancel_destroy(), sip_debug_test_pvt(), sip_methods, stop_session_timer(), cfsip_methods::text, and TRUE.

Referenced by __sip_autodestruct(), auto_congest(), cb_extensionstate(), check_auth(), check_pendings(), handle_incoming(), handle_invite_replaces(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_publish(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_scheddestroy_final(), sip_send_mwi_to_peer(), sip_sipredirect(), transmit_fake_auth_response(), and transmit_publish().

03828 {
03829    if (p->final_destruction_scheduled) {
03830       return; /* already set final destruction */
03831    }
03832 
03833    if (ms < 0) {
03834       if (p->timer_t1 == 0) {
03835          p->timer_t1 = global_t1;   /* Set timer T1 if not set (RFC 3261) */
03836       }
03837       if (p->timer_b == 0) {
03838          p->timer_b = global_timer_b;  /* Set timer B if not set (RFC 3261) */
03839       }
03840       ms = p->timer_t1 * 64;
03841    }
03842    if (sip_debug_test_pvt(p)) {
03843       ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text);
03844    }
03845    if (sip_cancel_destroy(p)) {
03846       ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
03847    }
03848 
03849    if (p->do_history) {
03850       append_history(p, "SchedDestroy", "%d ms", ms);
03851    }
03852    p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, dialog_ref(p, "setting ref as passing into ast_sched_add for __sip_autodestruct"));
03853 
03854    if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_schedid > 0) {
03855       stop_session_timer(p);
03856    }
03857 }

void sip_scheddestroy_final ( struct sip_pvt *  p,
int  ms 
)

Schedule final destruction of SIP dialog. This can not be canceled. This function is used to keep a dialog around for a period of time in order to properly respond to any retransmits.

Definition at line 3814 of file chan_sip.c.

References sip_scheddestroy().

Referenced by handle_request_bye().

03815 {
03816    if (p->final_destruction_scheduled) {
03817       return; /* already set final destruction */
03818    }
03819 
03820    sip_scheddestroy(p, ms);
03821    if (p->autokillid != -1) {
03822       p->final_destruction_scheduled = 1;
03823    }
03824 }

static void sip_send_all_mwi_subscriptions ( void   )  [static]

Send all MWI subscriptions.

Definition at line 28295 of file chan_sip.c.

References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, sip_subscribe_mwi_destroy(), sip_subscribe_mwi_do(), and submwil.

Referenced by load_module(), network_change_event_sched_cb(), and sip_do_reload().

28296 {
28297    ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
28298       ASTOBJ_WRLOCK(iterator);
28299       AST_SCHED_DEL(sched, iterator->resub);
28300       if ((iterator->resub = ast_sched_add(sched, 1, sip_subscribe_mwi_do, ASTOBJ_REF(iterator))) < 0) {
28301          ASTOBJ_UNREF(iterator, sip_subscribe_mwi_destroy);
28302       }
28303       ASTOBJ_UNLOCK(iterator);
28304    } while (0));
28305 }

static void sip_send_all_registers ( void   )  [static]

Send all known registrations.

Definition at line 28271 of file chan_sip.c.

References AST_SCHED_REPLACE_UNREF, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, default_expiry, registry_addref(), registry_unref(), regl, regobjs, and sip_reregister().

Referenced by load_module(), network_change_event_sched_cb(), and sip_do_reload().

28272 {
28273    int ms;
28274    int regspacing;
28275    if (!regobjs)
28276       return;
28277    regspacing = default_expiry * 1000/regobjs;
28278    if (regspacing > 100) {
28279       regspacing = 100;
28280    }
28281    ms = regspacing;
28282    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
28283       ASTOBJ_WRLOCK(iterator);
28284       ms += regspacing;
28285       AST_SCHED_REPLACE_UNREF(iterator->expire, sched, ms, sip_reregister, iterator,
28286                         registry_unref(_data, "REPLACE sched del decs the refcount"),
28287                         registry_unref(iterator, "REPLACE sched add failure decs the refcount"),
28288                         registry_addref(iterator, "REPLACE sched add incs the refcount"));
28289       ASTOBJ_UNLOCK(iterator);
28290    } while (0)
28291    );
28292 }

static int sip_send_mwi_to_peer ( struct sip_peer *  peer,
const struct ast_event *  event,
int  cache_only 
) [static]

Send message waiting indication to alert peer that they've got voicemail.

Definition at line 24534 of file chan_sip.c.

References ao2_t_link, ao2_t_unlink, ast_app_inboxcount(), ast_event_get_ie_uint(), AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_isnull(), ast_str_alloca, ast_string_field_set, ast_strlen_zero(), ast_test_flag, build_callid_pvt(), build_via(), create_addr_from_peer(), default_mwi_from, dialog_unlink_all(), dialogs, get_cached_mwi(), peer_mailboxes_to_str(), set_socket_transport(), sip_alloc(), sip_scheddestroy(), transmit_notify_with_mwi(), and TRUE.

Referenced by build_peer(), handle_request_subscribe(), and mwi_event_cb().

24535 {
24536    /* Called with peerl lock, but releases it */
24537    struct sip_pvt *p;
24538    int newmsgs = 0, oldmsgs = 0;
24539 
24540    if (ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY) && !peer->mwipvt)
24541       return 0;
24542 
24543    /* Do we have an IP address? If not, skip this peer */
24544    if (ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr))
24545       return 0;
24546 
24547    if (event) {
24548       newmsgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
24549       oldmsgs = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
24550    } else if (!cache_only) { /* Fall back to manually checking the mailbox */
24551       struct ast_str *mailbox_str = ast_str_alloca(512);
24552       peer_mailboxes_to_str(&mailbox_str, peer);
24553       ast_app_inboxcount(mailbox_str->str, &newmsgs, &oldmsgs);
24554    } else {
24555       get_cached_mwi(peer, &newmsgs, &oldmsgs);
24556    }
24557    
24558    if (peer->mwipvt) {
24559       /* Base message on subscription */
24560       p = dialog_ref(peer->mwipvt, "sip_send_mwi_to_peer: Setting dialog ptr p from peer->mwipvt-- should this be done?");
24561    } else {
24562       /* Build temporary dialog for this message */
24563       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL)))
24564          return -1;
24565       /* If we don't set the socket type to 0, then create_addr_from_peer will fail immediately if the peer
24566        * uses any transport other than UDP. We set the type to 0 here and then let create_addr_from_peer copy
24567        * the peer's socket information to the sip_pvt we just allocated
24568        */
24569       set_socket_transport(&p->socket, 0);
24570       if (create_addr_from_peer(p, peer)) {
24571          /* Maybe they're not registered, etc. */
24572          dialog_unlink_all(p, TRUE, TRUE);
24573          dialog_unref(p, "unref dialog p just created via sip_alloc");
24574          /* sip_destroy(p); */
24575          return 0;
24576       }
24577       /* Recalculate our side, and recalculate Call ID */
24578       ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
24579       build_via(p);
24580       ao2_t_unlink(dialogs, p, "About to change the callid -- remove the old name");
24581       build_callid_pvt(p);
24582       if (!ast_strlen_zero(peer->mwi_from)) {
24583          ast_string_field_set(p, mwi_from, peer->mwi_from);
24584       } else if (!ast_strlen_zero(default_mwi_from)) {
24585          ast_string_field_set(p, mwi_from, default_mwi_from);
24586       }
24587       ao2_t_link(dialogs, p, "Linking in under new name");
24588       /* Destroy this session after 32 secs */
24589       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
24590    }
24591 
24592    /* Send MWI */
24593    ast_set_flag(&p->flags[0], SIP_OUTGOING);
24594    /* the following will decrement the refcount on p as it finishes */
24595    transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
24596    dialog_unref(p, "unref dialog ptr p just before it goes out of scope at the end of sip_send_mwi_to_peer.");
24597    return 0;
24598 }

static int sip_senddigit_begin ( struct ast_channel *  ast,
char  digit 
) [static]

Definition at line 6352 of file chan_sip.c.

References AST_RTP_DTMF_MODE_INBAND, ast_rtp_instance_dtmf_begin(), ast_rtp_instance_dtmf_mode_get(), ast_test_flag, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.

06353 {
06354    struct sip_pvt *p = ast->tech_pvt;
06355    int res = 0;
06356 
06357    sip_pvt_lock(p);
06358    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
06359    case SIP_DTMF_INBAND:
06360       if (p->rtp && ast_rtp_instance_dtmf_mode_get(p->rtp) == AST_RTP_DTMF_MODE_INBAND) {
06361          ast_rtp_instance_dtmf_begin(p->rtp, digit);
06362       } else {
06363          res = -1; /* Tell Asterisk to generate inband indications */
06364       }
06365       break;
06366    case SIP_DTMF_RFC2833:
06367       if (p->rtp)
06368          ast_rtp_instance_dtmf_begin(p->rtp, digit);
06369       break;
06370    default:
06371       break;
06372    }
06373    sip_pvt_unlock(p);
06374 
06375    return res;
06376 }

static int sip_senddigit_end ( struct ast_channel *  ast,
char  digit,
unsigned int  duration 
) [static]

Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously.

Definition at line 6380 of file chan_sip.c.

References AST_RTP_DTMF_MODE_INBAND, ast_rtp_instance_dtmf_end(), ast_rtp_instance_dtmf_end_with_duration(), ast_rtp_instance_dtmf_mode_get(), ast_test_flag, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and transmit_info_with_digit().

06381 {
06382    struct sip_pvt *p = ast->tech_pvt;
06383    int res = 0;
06384 
06385    sip_pvt_lock(p);
06386    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
06387    case SIP_DTMF_INFO:
06388    case SIP_DTMF_SHORTINFO:
06389       transmit_info_with_digit(p, digit, duration);
06390       break;
06391    case SIP_DTMF_RFC2833:
06392       if (p->rtp)
06393          ast_rtp_instance_dtmf_end_with_duration(p->rtp, digit, duration);
06394       break;
06395    case SIP_DTMF_INBAND:
06396       if (p->rtp && ast_rtp_instance_dtmf_mode_get(p->rtp) == AST_RTP_DTMF_MODE_INBAND) {
06397          ast_rtp_instance_dtmf_end(p->rtp, digit);
06398       } else {
06399          res = -1; /* Tell Asterisk to stop inband indications */
06400       }
06401       break;
06402    }
06403    sip_pvt_unlock(p);
06404 
06405    return res;
06406 }

static int sip_sendhtml ( struct ast_channel *  chan,
int  subclass,
const char *  data,
int  datalen 
) [static]

Send message with Access-URL header, if this is an HTML URL only!

Definition at line 4294 of file chan_sip.c.

References ast_channel::_state, ast_debug, AST_HTML_URL, ast_log(), ast_set_flag, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_string_field_build, ast_test_flag, FALSE, LOG_WARNING, sip_debug_test_pvt(), ast_channel::tech_pvt, transmit_reinvite_with_sdp(), transmit_response(), and url.

04295 {
04296    struct sip_pvt *p = chan->tech_pvt;
04297 
04298    if (subclass != AST_HTML_URL)
04299       return -1;
04300 
04301    ast_string_field_build(p, url, "<%s>;mode=active", data);
04302 
04303    if (sip_debug_test_pvt(p))
04304       ast_debug(1, "Send URL %s, state = %d!\n", data, chan->_state);
04305 
04306    switch (chan->_state) {
04307    case AST_STATE_RING:
04308       transmit_response(p, "100 Trying", &p->initreq);
04309       break;
04310    case AST_STATE_RINGING:
04311       transmit_response(p, "180 Ringing", &p->initreq);
04312       break;
04313    case AST_STATE_UP:
04314       if (!p->pendinginvite) {      /* We are up, and have no outstanding invite */
04315          transmit_reinvite_with_sdp(p, FALSE, FALSE);
04316       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
04317          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
04318       }  
04319       break;
04320    default:
04321       ast_log(LOG_WARNING, "Don't know how to send URI when state is %d!\n", chan->_state);
04322    }
04323 
04324    return 0;
04325 }

static int sip_sendtext ( struct ast_channel *  ast,
const char *  text 
) [static]

Send SIP MESSAGE text within a call Called from PBX core sendtext() application.

Definition at line 4335 of file chan_sip.c.

References ast_debug, ast_verbose, debug, is_method_allowed(), ast_channel::name, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().

04336 {
04337    struct sip_pvt *dialog = ast->tech_pvt;
04338    int debug = sip_debug_test_pvt(dialog);
04339 
04340    if (!dialog)
04341       return -1;
04342    /* NOT ast_strlen_zero, because a zero-length message is specifically
04343     * allowed by RFC 3428 (See section 10, Examples) */
04344    if (!text)
04345       return 0;
04346    if(!is_method_allowed(&dialog->allowed_methods, SIP_MESSAGE)) {
04347       ast_debug(2, "Trying to send MESSAGE to device that does not support it.\n");
04348       return(0);
04349    }
04350    if (debug)
04351       ast_verbose("Sending text %s on %s\n", text, ast->name);
04352    transmit_message_with_text(dialog, text);
04353    return 0;   
04354 }

static char * sip_set_history ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

Enable/Disable SIP History logging (CLI).

Definition at line 18198 of file chan_sip.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, recordhistory, TRUE, and ast_cli_entry::usage.

18199 {
18200    switch (cmd) {
18201    case CLI_INIT:
18202       e->command = "sip set history {on|off}";
18203       e->usage =
18204          "Usage: sip set history {on|off}\n"
18205          "       Enables/Disables recording of SIP dialog history for debugging purposes.\n"
18206          "       Use 'sip show history' to view the history of a call number.\n";
18207       return NULL;
18208    case CLI_GENERATE:
18209       return NULL;
18210    }
18211 
18212    if (a->argc != e->args)
18213       return CLI_SHOWUSAGE;
18214 
18215    if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
18216       recordhistory = TRUE;
18217       ast_cli(a->fd, "SIP History Recording Enabled (use 'sip show history')\n");
18218    } else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) {
18219       recordhistory = FALSE;
18220       ast_cli(a->fd, "SIP History Recording Disabled\n");
18221    } else {
18222       return CLI_SHOWUSAGE;
18223    }
18224    return CLI_SUCCESS;
18225 }

static void sip_set_redirstr ( struct sip_pvt *  p,
char *  reason 
) [static]

Translate referring cause.

Definition at line 14261 of file chan_sip.c.

References ast_string_field_set.

Referenced by get_rdnis().

14261                                                               {
14262 
14263    if (!strcmp(reason, "unknown")) {
14264       ast_string_field_set(p, redircause, "UNKNOWN");
14265    } else if (!strcmp(reason, "user-busy")) {
14266       ast_string_field_set(p, redircause, "BUSY");
14267    } else if (!strcmp(reason, "no-answer")) {
14268       ast_string_field_set(p, redircause, "NOANSWER");
14269    } else if (!strcmp(reason, "unavailable")) {
14270       ast_string_field_set(p, redircause, "UNREACHABLE");
14271    } else if (!strcmp(reason, "unconditional")) {
14272       ast_string_field_set(p, redircause, "UNCONDITIONAL");
14273    } else if (!strcmp(reason, "time-of-day")) {
14274       ast_string_field_set(p, redircause, "UNKNOWN");
14275    } else if (!strcmp(reason, "do-not-disturb")) {
14276       ast_string_field_set(p, redircause, "UNKNOWN");
14277    } else if (!strcmp(reason, "deflection")) {
14278       ast_string_field_set(p, redircause, "UNKNOWN");
14279    } else if (!strcmp(reason, "follow-me")) {
14280       ast_string_field_set(p, redircause, "UNKNOWN");
14281    } else if (!strcmp(reason, "out-of-service")) {
14282       ast_string_field_set(p, redircause, "UNREACHABLE");
14283    } else if (!strcmp(reason, "away")) {
14284       ast_string_field_set(p, redircause, "UNREACHABLE");
14285    } else {
14286       ast_string_field_set(p, redircause, "UNKNOWN");
14287    }
14288 }

static int sip_set_rtp_peer ( struct ast_channel *  chan,
struct ast_rtp_instance *  instance,
struct ast_rtp_instance *  vinstance,
struct ast_rtp_instance *  tinstance,
format_t  codecs,
int  nat_active 
) [static]

Definition at line 27938 of file chan_sip.c.

References ast_channel::_state, append_history, ast_bridged_channel(), ast_channel_trylock, ast_channel_unlock, ast_debug, ast_rtp_instance_get_and_cmp_remote_address(), ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify(), AST_STATE_UP, ast_test_flag, FALSE, sip_cfg, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and transmit_reinvite_with_sdp().

Referenced by sip_fixup().

27939 {
27940    struct sip_pvt *p;
27941    int changed = 0;
27942 
27943    p = chan->tech_pvt;
27944    if (!p) {
27945       return -1;
27946    }
27947 
27948    /* Disable early RTP bridge  */
27949    if (!ast_bridged_channel(chan) && !sip_cfg.directrtpsetup)  /* We are in early state */
27950       return 0;
27951 
27952    /*
27953     * Lock both the pvt and it's owner safely.
27954     */
27955    sip_pvt_lock(p);
27956    while (p->owner && ast_channel_trylock(p->owner)) {
27957       sip_pvt_unlock(p);
27958       usleep(1);
27959       sip_pvt_lock(p);
27960    }
27961 
27962    if (!p->owner) {
27963       sip_pvt_unlock(p);
27964       return 0;
27965    }
27966 
27967    if (p->alreadygone) {
27968       /* If we're destroyed, don't bother */
27969       ast_channel_unlock(p->owner);
27970       sip_pvt_unlock(p);
27971       return 0;
27972    }
27973 
27974    /* if this peer cannot handle reinvites of the media stream to devices
27975       that are known to be behind a NAT, then stop the process now
27976    */
27977    if (nat_active && !ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) {
27978       ast_channel_unlock(p->owner);
27979       sip_pvt_unlock(p);
27980       return 0;
27981    }
27982 
27983    if (instance) {
27984       changed |= ast_rtp_instance_get_and_cmp_remote_address(instance, &p->redirip);
27985    } else if (!ast_sockaddr_isnull(&p->redirip)) {
27986       memset(&p->redirip, 0, sizeof(p->redirip));
27987       changed = 1;
27988    }
27989    if (vinstance) {
27990       changed |= ast_rtp_instance_get_and_cmp_remote_address(vinstance, &p->vredirip);
27991    } else if (!ast_sockaddr_isnull(&p->vredirip)) {
27992       memset(&p->vredirip, 0, sizeof(p->vredirip));
27993       changed = 1;
27994    }
27995    if (tinstance) {
27996       changed |= ast_rtp_instance_get_and_cmp_remote_address(tinstance, &p->tredirip);
27997    } else if (!ast_sockaddr_isnull(&p->tredirip)) {
27998       memset(&p->tredirip, 0, sizeof(p->tredirip));
27999       changed = 1;
28000    }
28001    if (codecs && (p->redircodecs != codecs)) {
28002       p->redircodecs = codecs;
28003       changed = 1;
28004    }
28005    if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
28006       if (chan->_state != AST_STATE_UP) {     /* We are in early state */
28007          if (p->do_history)
28008             append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
28009          ast_debug(1, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip));
28010       } else if (!p->pendinginvite) {   /* We are up, and have no outstanding invite */
28011          ast_debug(3, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip));
28012          transmit_reinvite_with_sdp(p, FALSE, FALSE);
28013       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
28014          ast_debug(3, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_sockaddr_stringify(instance ? &p->redirip : &p->ourip));
28015          /* We have a pending Invite. Send re-invite when we're done with the invite */
28016          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
28017       }
28018    }
28019    /* Reset lastrtprx timer */
28020    p->lastrtprx = p->lastrtptx = time(NULL);
28021    ast_channel_unlock(p->owner);
28022    sip_pvt_unlock(p);
28023    return 0;
28024 }

static int sip_set_udptl_peer ( struct ast_channel *  chan,
struct ast_udptl *  udptl 
) [static]

Definition at line 27795 of file chan_sip.c.

References ast_channel_trylock, ast_channel_unlock, ast_debug, ast_set_flag, ast_sockaddr_stringify(), ast_test_flag, ast_udptl_get_peer(), FALSE, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), and TRUE.

27796 {
27797    struct sip_pvt *p;
27798    
27799    p = chan->tech_pvt;
27800    if (!p) {
27801       return -1;
27802    }
27803    /*
27804     * Lock both the pvt and it's owner safely.
27805     */
27806    sip_pvt_lock(p);
27807    while (p->owner && ast_channel_trylock(p->owner)) {
27808       sip_pvt_unlock(p);
27809       usleep(1);
27810       sip_pvt_lock(p);
27811    }
27812 
27813    if (!p->owner) {
27814       sip_pvt_unlock(p);
27815       return 0;
27816    }
27817    if (udptl) {
27818       ast_udptl_get_peer(udptl, &p->udptlredirip);
27819    } else {
27820       memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
27821    }
27822    if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
27823       if (!p->pendinginvite) {
27824          ast_debug(3, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s\n",
27825                p->callid, ast_sockaddr_stringify(udptl ? &p->udptlredirip : &p->ourip));
27826          transmit_reinvite_with_sdp(p, TRUE, FALSE);
27827       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
27828          ast_debug(3, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s\n",
27829                p->callid, ast_sockaddr_stringify(udptl ? &p->udptlredirip : &p->ourip));
27830          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
27831       }
27832    }
27833    /* Reset lastrtprx timer */
27834    p->lastrtprx = p->lastrtptx = time(NULL);
27835    ast_channel_unlock(p->owner);
27836    sip_pvt_unlock(p);
27837    return 0;
27838 }

static int sip_setoption ( struct ast_channel *  chan,
int  option,
void *  data,
int  datalen 
) [static]

Set an option on a SIP dialog.

Definition at line 4165 of file chan_sip.c.

References ast_debug, AST_OPTION_DIGIT_DETECT, AST_OPTION_FORMAT_READ, AST_OPTION_FORMAT_WRITE, AST_OPTION_MAKE_COMPATIBLE, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, ast_rtp_instance_make_compatible(), ast_rtp_instance_set_read_format(), ast_rtp_instance_set_write_format(), ast_set2_flag, ast_test_flag, disable_dsp_detect(), enable_dsp_detect(), ast_channel::name, and ast_channel::tech_pvt.

04166 {
04167    int res = -1;
04168    struct sip_pvt *p = chan->tech_pvt;
04169 
04170    switch (option) {
04171    case AST_OPTION_FORMAT_READ:
04172       res = ast_rtp_instance_set_read_format(p->rtp, *(int *) data);
04173       break;
04174    case AST_OPTION_FORMAT_WRITE:
04175       res = ast_rtp_instance_set_write_format(p->rtp, *(int *) data);
04176       break;
04177    case AST_OPTION_MAKE_COMPATIBLE:
04178       res = ast_rtp_instance_make_compatible(chan, p->rtp, (struct ast_channel *) data);
04179       break;
04180    case AST_OPTION_DIGIT_DETECT:
04181       if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) ||
04182           (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) {
04183          char *cp = (char *) data;
04184 
04185          ast_debug(1, "%sabling digit detection on %s\n", *cp ? "En" : "Dis", chan->name);
04186          if (*cp) {
04187             enable_dsp_detect(p);
04188          } else {
04189             disable_dsp_detect(p);
04190          }
04191          res = 0;
04192       }
04193       break;
04194    case AST_OPTION_SECURE_SIGNALING:
04195       p->req_secure_signaling = *(unsigned int *) data;
04196       res = 0;
04197       break;
04198    case AST_OPTION_SECURE_MEDIA:
04199       ast_set2_flag(&p->flags[1], *(unsigned int *) data, SIP_PAGE2_USE_SRTP);
04200       res = 0;
04201       break;
04202    default:
04203       break;
04204    }
04205 
04206    return res;
04207 }

static char * sip_show_channel ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

Show details of one active dialog.

Definition at line 17650 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli_args::argv, ARRAY_LEN, ast_cli(), AST_CLI_YESNO, ast_getformatname_multiple(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strlen_zero(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sipch(), dialogs, dtmfmode2str(), ast_cli_args::fd, len(), ast_cli_args::line, ast_cli_args::n, NONE, ast_cli_args::pos, sip_pvt_lock, sip_pvt_unlock, stmode2str(), strefresher2str(), subscription_type2str(), transfermode2str(), TRUE, ast_cli_entry::usage, and ast_cli_args::word.

17651 {
17652    struct sip_pvt *cur;
17653    size_t len;
17654    int found = 0;
17655    struct ao2_iterator i;
17656 
17657    switch (cmd) {
17658    case CLI_INIT:
17659       e->command = "sip show channel";
17660       e->usage =
17661          "Usage: sip show channel <call-id>\n"
17662          "       Provides detailed status on a given SIP dialog (identified by SIP call-id).\n";
17663       return NULL;
17664    case CLI_GENERATE:
17665       return complete_sipch(a->line, a->word, a->pos, a->n);
17666    }
17667 
17668    if (a->argc != 4)
17669       return CLI_SHOWUSAGE;
17670    len = strlen(a->argv[3]);
17671    
17672    i = ao2_iterator_init(dialogs, 0);
17673    while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
17674       sip_pvt_lock(cur);
17675 
17676       if (!strncasecmp(cur->callid, a->argv[3], len)) {
17677          char formatbuf[SIPBUFSIZE/2];
17678          ast_cli(a->fd, "\n");
17679          if (cur->subscribed != NONE)
17680             ast_cli(a->fd, "  * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
17681          else
17682             ast_cli(a->fd, "  * SIP Call\n");
17683          ast_cli(a->fd, "  Curr. trans. direction:  %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming");
17684          ast_cli(a->fd, "  Call-ID:                %s\n", cur->callid);
17685          ast_cli(a->fd, "  Owner channel ID:       %s\n", cur->owner ? cur->owner->name : "<none>");
17686          ast_cli(a->fd, "  Our Codec Capability:   %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->capability));
17687          ast_cli(a->fd, "  Non-Codec Capability (DTMF):   %d\n", cur->noncodeccapability);
17688          ast_cli(a->fd, "  Their Codec Capability:   %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->peercapability));
17689          ast_cli(a->fd, "  Joint Codec Capability:   %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->jointcapability));
17690          ast_cli(a->fd, "  Format:                 %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) );
17691          ast_cli(a->fd, "  T.38 support            %s\n", AST_CLI_YESNO(cur->udptl != NULL));
17692          ast_cli(a->fd, "  Video support           %s\n", AST_CLI_YESNO(cur->vrtp != NULL));
17693          ast_cli(a->fd, "  MaxCallBR:              %d kbps\n", cur->maxcallbitrate);
17694          ast_cli(a->fd, "  Theoretical Address:    %s\n", ast_sockaddr_stringify(&cur->sa));
17695          ast_cli(a->fd, "  Received Address:       %s\n", ast_sockaddr_stringify(&cur->recv));
17696          ast_cli(a->fd, "  SIP Transfer mode:      %s\n", transfermode2str(cur->allowtransfer));
17697          ast_cli(a->fd, "  Force rport:            %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_NAT_FORCE_RPORT)));
17698          if (ast_sockaddr_isnull(&cur->redirip)) {
17699             ast_cli(a->fd,
17700                "  Audio IP:               %s (local)\n",
17701                ast_sockaddr_stringify_addr(&cur->ourip));
17702          } else {
17703             ast_cli(a->fd,
17704                "  Audio IP:               %s (Outside bridge)\n",
17705                ast_sockaddr_stringify_addr(&cur->redirip));
17706          }
17707          ast_cli(a->fd, "  Our Tag:                %s\n", cur->tag);
17708          ast_cli(a->fd, "  Their Tag:              %s\n", cur->theirtag);
17709          ast_cli(a->fd, "  SIP User agent:         %s\n", cur->useragent);
17710          if (!ast_strlen_zero(cur->username))
17711             ast_cli(a->fd, "  Username:               %s\n", cur->username);
17712          if (!ast_strlen_zero(cur->peername))
17713             ast_cli(a->fd, "  Peername:               %s\n", cur->peername);
17714          if (!ast_strlen_zero(cur->uri))
17715             ast_cli(a->fd, "  Original uri:           %s\n", cur->uri);
17716          if (!ast_strlen_zero(cur->cid_num))
17717             ast_cli(a->fd, "  Caller-ID:              %s\n", cur->cid_num);
17718          ast_cli(a->fd, "  Need Destroy:           %s\n", AST_CLI_YESNO(cur->needdestroy));
17719          ast_cli(a->fd, "  Last Message:           %s\n", cur->lastmsg);
17720          ast_cli(a->fd, "  Promiscuous Redir:      %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR)));
17721          ast_cli(a->fd, "  Route:                  %s\n", cur->route ? cur->route->hop : "N/A");
17722          ast_cli(a->fd, "  DTMF Mode:              %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF)));
17723          ast_cli(a->fd, "  SIP Options:            ");
17724          if (cur->sipoptions) {
17725             int x;
17726             for (x = 0 ; x < ARRAY_LEN(sip_options); x++) {
17727                if (cur->sipoptions & sip_options[x].id)
17728                   ast_cli(a->fd, "%s ", sip_options[x].text);
17729             }
17730             ast_cli(a->fd, "\n");
17731          } else
17732             ast_cli(a->fd, "(none)\n");
17733 
17734          if (!cur->stimer)
17735             ast_cli(a->fd, "  Session-Timer:          Uninitiallized\n");
17736          else {
17737             ast_cli(a->fd, "  Session-Timer:          %s\n", cur->stimer->st_active ? "Active" : "Inactive");
17738             if (cur->stimer->st_active == TRUE) {
17739                ast_cli(a->fd, "  S-Timer Interval:       %d\n", cur->stimer->st_interval);
17740                ast_cli(a->fd, "  S-Timer Refresher:      %s\n", strefresher2str(cur->stimer->st_ref));
17741                ast_cli(a->fd, "  S-Timer Expirys:        %d\n", cur->stimer->st_expirys);
17742                ast_cli(a->fd, "  S-Timer Sched Id:       %d\n", cur->stimer->st_schedid);
17743                ast_cli(a->fd, "  S-Timer Peer Sts:       %s\n", cur->stimer->st_active_peer_ua ? "Active" : "Inactive");
17744                ast_cli(a->fd, "  S-Timer Cached Min-SE:  %d\n", cur->stimer->st_cached_min_se);
17745                ast_cli(a->fd, "  S-Timer Cached SE:      %d\n", cur->stimer->st_cached_max_se);
17746                ast_cli(a->fd, "  S-Timer Cached Ref:     %s\n", strefresher2str(cur->stimer->st_cached_ref));
17747                ast_cli(a->fd, "  S-Timer Cached Mode:    %s\n", stmode2str(cur->stimer->st_cached_mode));
17748             }
17749          }
17750 
17751          ast_cli(a->fd, "\n\n");
17752 
17753          found++;
17754       }
17755 
17756       sip_pvt_unlock(cur);
17757 
17758       ao2_t_ref(cur, -1, "toss dialog ptr set by iterator_next");
17759    }
17760    ao2_iterator_destroy(&i);
17761 
17762    if (!found)
17763       ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]);
17764 
17765    return CLI_SUCCESS;
17766 }

static char* sip_show_channels ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

CLI for show channels or subscriptions. This is a new-style CLI handler so a single function contains the prototype for the function, the 'generator' to produce multiple entries in case it is required, and the actual handler for the command.

Definition at line 17471 of file chan_sip.c.

References ao2_t_callback, ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dialogs, ESS, ast_cli_args::fd, FORMAT2, FORMAT3, OBJ_NODATA, show_channels_cb(), and ast_cli_entry::usage.

17472 {
17473    struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 };
17474 
17475 
17476    if (cmd == CLI_INIT) {
17477       e->command = "sip show {channels|subscriptions}";
17478       e->usage =
17479          "Usage: sip show channels\n"
17480          "       Lists all currently active SIP calls (dialogs).\n"
17481          "Usage: sip show subscriptions\n"
17482          "       Lists active SIP subscriptions.\n";
17483       return NULL;
17484    } else if (cmd == CLI_GENERATE)
17485       return NULL;
17486 
17487    if (a->argc != e->args)
17488       return CLI_SHOWUSAGE;
17489    arg.subscriptions = !strcasecmp(a->argv[e->args - 1], "subscriptions");
17490    if (!arg.subscriptions)
17491       ast_cli(arg.fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Format", "Hold", "Last Message", "Expiry", "Peer");
17492    else
17493       ast_cli(arg.fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry");
17494 
17495    /* iterate on the container and invoke the callback on each item */
17496    ao2_t_callback(dialogs, OBJ_NODATA, show_channels_cb, &arg, "callback to show channels");
17497    
17498    /* print summary information */
17499    ast_cli(arg.fd, "%d active SIP %s%s\n", arg.numchans,
17500       (arg.subscriptions ? "subscription" : "dialog"),
17501       ESS(arg.numchans));  /* ESS(n) returns an "s" if n>1 */
17502    return CLI_SUCCESS;
17503 #undef FORMAT
17504 #undef FORMAT2
17505 #undef FORMAT3
17506 }

static char * sip_show_channelstats ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

SIP show channelstats CLI (main function).

Definition at line 17126 of file chan_sip.c.

References ao2_t_callback, ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dialogs, ast_cli_args::fd, FORMAT2, OBJ_NODATA, show_chanstats_cb(), and ast_cli_entry::usage.

17127 {
17128    struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 };
17129 
17130    switch (cmd) {
17131    case CLI_INIT:
17132       e->command = "sip show channelstats";
17133       e->usage =
17134          "Usage: sip show channelstats\n"
17135          "       Lists all currently active SIP channel's RTCP statistics.\n"
17136          "       Note that calls in the much optimized RTP P2P bridge mode will not show any packets here.";
17137       return NULL;
17138    case CLI_GENERATE:
17139       return NULL;
17140    }
17141 
17142    if (a->argc != 3)
17143       return CLI_SHOWUSAGE;
17144 
17145    ast_cli(a->fd, FORMAT2, "Peer", "Call ID", "Duration", "Recv: Pack", "Lost", "Jitter", "Send: Pack", "Lost", "Jitter");
17146    /* iterate on the container and invoke the callback on each item */
17147    ao2_t_callback(dialogs, OBJ_NODATA, show_chanstats_cb, &arg, "callback to sip show chanstats");
17148    ast_cli(a->fd, "%d active SIP channel%s\n", arg.numchans, (arg.numchans != 1) ? "s" : "");
17149    return CLI_SUCCESS;
17150 }

static char * sip_show_domains ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

CLI command to list local domains.

Definition at line 16402 of file chan_sip.c.

References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, domain_mode_to_text(), ast_cli_args::fd, FORMAT, S_OR, and ast_cli_entry::usage.

16403 {
16404    struct domain *d;
16405 #define FORMAT "%-40.40s %-20.20s %-16.16s\n"
16406 
16407    switch (cmd) {
16408    case CLI_INIT:
16409       e->command = "sip show domains";
16410       e->usage =
16411          "Usage: sip show domains\n"
16412          "       Lists all configured SIP local domains.\n"
16413          "       Asterisk only responds to SIP messages to local domains.\n";
16414       return NULL;
16415    case CLI_GENERATE:
16416       return NULL;
16417    }
16418 
16419    if (AST_LIST_EMPTY(&domain_list)) {
16420       ast_cli(a->fd, "SIP Domain support not enabled.\n\n");
16421       return CLI_SUCCESS;
16422    } else {
16423       ast_cli(a->fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
16424       AST_LIST_LOCK(&domain_list);
16425       AST_LIST_TRAVERSE(&domain_list, d, list)
16426          ast_cli(a->fd, FORMAT, d->domain, S_OR(d->context, "(default)"),
16427             domain_mode_to_text(d->mode));
16428       AST_LIST_UNLOCK(&domain_list);
16429       ast_cli(a->fd, "\n");
16430       return CLI_SUCCESS;
16431    }
16432 }

static char * sip_show_history ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

Show history details of one dialog.

Definition at line 17769 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_TRAVERSE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_show_history(), dialogs, ast_cli_args::fd, len(), ast_cli_args::line, ast_cli_args::n, NONE, ast_cli_args::pos, recordhistory, sip_pvt_lock, sip_pvt_unlock, ast_cli_entry::usage, and ast_cli_args::word.

17770 {
17771    struct sip_pvt *cur;
17772    size_t len;
17773    int found = 0;
17774    struct ao2_iterator i;
17775 
17776    switch (cmd) {
17777    case CLI_INIT:
17778       e->command = "sip show history";
17779       e->usage =
17780          "Usage: sip show history <call-id>\n"
17781          "       Provides detailed dialog history on a given SIP call (specified by call-id).\n";
17782       return NULL;
17783    case CLI_GENERATE:
17784       return complete_sip_show_history(a->line, a->word, a->pos, a->n);
17785    }
17786 
17787    if (a->argc != 4)
17788       return CLI_SHOWUSAGE;
17789 
17790    if (!recordhistory)
17791       ast_cli(a->fd, "\n***Note: History recording is currently DISABLED.  Use 'sip set history on' to ENABLE.\n");
17792 
17793    len = strlen(a->argv[3]);
17794 
17795    i = ao2_iterator_init(dialogs, 0);
17796    while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
17797       sip_pvt_lock(cur);
17798       if (!strncasecmp(cur->callid, a->argv[3], len)) {
17799          struct sip_history *hist;
17800          int x = 0;
17801 
17802          ast_cli(a->fd, "\n");
17803          if (cur->subscribed != NONE)
17804             ast_cli(a->fd, "  * Subscription\n");
17805          else
17806             ast_cli(a->fd, "  * SIP Call\n");
17807          if (cur->history)
17808             AST_LIST_TRAVERSE(cur->history, hist, list)
17809                ast_cli(a->fd, "%d. %s\n", ++x, hist->event);
17810          if (x == 0)
17811             ast_cli(a->fd, "Call '%s' has no history\n", cur->callid);
17812          found++;
17813       }
17814       sip_pvt_unlock(cur);
17815       ao2_t_ref(cur, -1, "toss dialog ptr from iterator_next");
17816    }
17817    ao2_iterator_destroy(&i);
17818 
17819    if (!found)
17820       ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]);
17821 
17822    return CLI_SUCCESS;
17823 }

static char * sip_show_inuse ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

CLI Command to show calls within limits set by call_limit.

Definition at line 15537 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock, ao2_t_iterator_next, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, FORMAT, FORMAT2, TRUE, unref_peer(), and ast_cli_entry::usage.

15538 {
15539 #define FORMAT "%-25.25s %-15.15s %-15.15s \n"
15540 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
15541    char ilimits[40];
15542    char iused[40];
15543    int showall = FALSE;
15544    struct ao2_iterator i;
15545    struct sip_peer *peer;
15546    
15547    switch (cmd) {
15548    case CLI_INIT:
15549       e->command = "sip show inuse";
15550       e->usage =
15551          "Usage: sip show inuse [all]\n"
15552          "       List all SIP devices usage counters and limits.\n"
15553          "       Add option \"all\" to show all devices, not only those with a limit.\n";
15554       return NULL;
15555    case CLI_GENERATE:
15556       return NULL;
15557    }
15558 
15559    if (a->argc < 3)
15560       return CLI_SHOWUSAGE;
15561 
15562    if (a->argc == 4 && !strcmp(a->argv[3], "all"))
15563       showall = TRUE;
15564    
15565    ast_cli(a->fd, FORMAT, "* Peer name", "In use", "Limit");
15566 
15567    i = ao2_iterator_init(peers, 0);
15568    while ((peer = ao2_t_iterator_next(&i, "iterate thru peer table"))) {
15569       ao2_lock(peer);
15570       if (peer->call_limit)
15571          snprintf(ilimits, sizeof(ilimits), "%d", peer->call_limit);
15572       else
15573          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
15574       snprintf(iused, sizeof(iused), "%d/%d/%d", peer->inUse, peer->inRinging, peer->onHold);
15575       if (showall || peer->call_limit)
15576          ast_cli(a->fd, FORMAT2, peer->name, iused, ilimits);
15577       ao2_unlock(peer);
15578       unref_peer(peer, "toss iterator pointer");
15579    }
15580    ao2_iterator_destroy(&i);
15581 
15582    return CLI_SUCCESS;
15583 #undef FORMAT
15584 #undef FORMAT2
15585 }

static char * sip_show_mwi ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

Definition at line 17354 of file chan_sip.c.

References ast_cli(), AST_CLI_YESNO, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, submwil, and ast_cli_entry::usage.

17355 {
17356 #define FORMAT  "%-30.30s  %-12.12s  %-10.10s  %-10.10s\n"
17357    char host[80];
17358    
17359    switch (cmd) {
17360    case CLI_INIT:
17361       e->command = "sip show mwi";
17362       e->usage =
17363          "Usage: sip show mwi\n"
17364          "       Provides a list of MWI subscriptions and status.\n";
17365       return NULL;
17366    case CLI_GENERATE:
17367       return NULL;
17368    }
17369    
17370    ast_cli(a->fd, FORMAT, "Host", "Username", "Mailbox", "Subscribed");
17371    
17372    ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do {
17373       ASTOBJ_RDLOCK(iterator);
17374       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
17375       ast_cli(a->fd, FORMAT, host, iterator->username, iterator->mailbox, AST_CLI_YESNO(iterator->subscribed));
17376       ASTOBJ_UNLOCK(iterator);
17377    } while(0));
17378 
17379    return CLI_SUCCESS;
17380 #undef FORMAT
17381 }

static char * sip_show_objects ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

List all allocated SIP Objects (realtime or static).

Definition at line 16074 of file chan_sip.c.

References ao2_t_callback, apeerobjs, ast_cli_args::argc, ast_cli(), ASTOBJ_CONTAINER_DUMP, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dialog_dump_func(), dialogs, ast_cli_args::fd, OBJ_NODATA, peer_dump_func(), regl, regobjs, rpeerobjs, speerobjs, and ast_cli_entry::usage.

16075 {
16076    char tmp[256];
16077    
16078    switch (cmd) {
16079    case CLI_INIT:
16080       e->command = "sip show objects";
16081       e->usage =
16082          "Usage: sip show objects\n"
16083          "       Lists status of known SIP objects\n";
16084       return NULL;
16085    case CLI_GENERATE:
16086       return NULL;
16087    }  
16088 
16089    if (a->argc != 3)
16090       return CLI_SHOWUSAGE;
16091    ast_cli(a->fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
16092    ao2_t_callback(peers, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers");
16093    ast_cli(a->fd, "-= Registry objects: %d =-\n\n", regobjs);
16094    ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), &regl);
16095    ast_cli(a->fd, "-= Dialog objects:\n\n");
16096    ao2_t_callback(dialogs, OBJ_NODATA, dialog_dump_func, a, "initiate ao2_callback to dump dialogs");
16097    return CLI_SUCCESS;
16098 }

static char * sip_show_peer ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

Show one peer in detail.

Definition at line 16457 of file chan_sip.c.

References _sip_show_peer(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_sip_show_peer(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

16458 {
16459    switch (cmd) {
16460    case CLI_INIT:
16461       e->command = "sip show peer";
16462       e->usage =
16463          "Usage: sip show peer <name> [load]\n"
16464          "       Shows all details on one SIP peer and the current status.\n"
16465          "       Option \"load\" forces lookup of peer in realtime storage.\n";
16466       return NULL;
16467    case CLI_GENERATE:
16468       return complete_sip_show_peer(a->line, a->word, a->pos, a->n);
16469    }
16470    return _sip_show_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv);
16471 }

static char * sip_show_peers ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

CLI Show Peers command.

Definition at line 15849 of file chan_sip.c.

References _sip_show_peers(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

15850 {
15851    switch (cmd) {
15852    case CLI_INIT:
15853       e->command = "sip show peers";
15854       e->usage =
15855          "Usage: sip show peers [like <pattern>]\n"
15856          "       Lists all known SIP peers.\n"
15857          "       Optional regular expression pattern is used to filter the peer list.\n";
15858       return NULL;
15859    case CLI_GENERATE:
15860       return NULL;
15861    }
15862 
15863    return _sip_show_peers(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv);
15864 }

static char * sip_show_registry ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

Show SIP Registry (registrations with other SIP proxies.

Definition at line 16975 of file chan_sip.c.

References ast_cli_args::argc, ast_cli(), ast_localtime(), ast_strftime(), ast_strlen_zero(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, FORMAT2, regl, regstate2str(), and ast_cli_entry::usage.

16976 {
16977 #define FORMAT2 "%-39.39s %-6.6s %-12.12s  %8.8s %-20.20s %-25.25s\n"
16978 #define FORMAT  "%-39.39s %-6.6s %-12.12s  %8d %-20.20s %-25.25s\n"
16979    char host[80];
16980    char user[80];
16981    char tmpdat[256];
16982    struct ast_tm tm;
16983    int counter = 0;
16984 
16985    switch (cmd) {
16986    case CLI_INIT:
16987       e->command = "sip show registry";
16988       e->usage =
16989          "Usage: sip show registry\n"
16990          "       Lists all registration requests and status.\n";
16991       return NULL;
16992    case CLI_GENERATE:
16993       return NULL;
16994    }
16995 
16996    if (a->argc != 3)
16997       return CLI_SHOWUSAGE;
16998    ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Refresh", "State", "Reg.Time");
16999    
17000    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
17001       ASTOBJ_RDLOCK(iterator);
17002       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
17003       snprintf(user, sizeof(user), "%s", iterator->username);
17004       if (!ast_strlen_zero(iterator->regdomain)) {
17005          snprintf(tmpdat, sizeof(tmpdat), "%s", user);
17006          snprintf(user, sizeof(user), "%s@%s", tmpdat, iterator->regdomain);}
17007       if (iterator->regdomainport) {
17008          snprintf(tmpdat, sizeof(tmpdat), "%s", user);
17009          snprintf(user, sizeof(user), "%s:%d", tmpdat, iterator->regdomainport);}
17010       if (iterator->regtime.tv_sec) {
17011          ast_localtime(&iterator->regtime, &tm, NULL);
17012          ast_strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm);
17013       } else
17014          tmpdat[0] = '\0';
17015       ast_cli(a->fd, FORMAT, host, (iterator->dnsmgr) ? "Y" : "N", user, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
17016       ASTOBJ_UNLOCK(iterator);
17017       counter++;
17018    } while(0));
17019    ast_cli(a->fd, "%d SIP registrations.\n", counter);
17020    return CLI_SUCCESS;
17021 #undef FORMAT
17022 #undef FORMAT2
17023 }

static char * sip_show_sched ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

Definition at line 16932 of file chan_sip.c.

References __sip_autodestruct(), ast_cli(), ast_sched_report(), ast_str_alloca, auto_congest(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, expire_register(), ast_cli_args::fd, retrans_pkt(), sip_poke_noanswer(), sip_poke_peer_s(), sip_reg_timeout(), sip_reinvite_retry(), sip_reregister(), and ast_cli_entry::usage.

16933 {
16934    struct ast_str *cbuf;
16935    struct ast_cb_names cbnames = {9, { "retrans_pkt",
16936                                         "__sip_autodestruct",
16937                                         "expire_register",
16938                                         "auto_congest",
16939                                         "sip_reg_timeout",
16940                                         "sip_poke_peer_s",
16941                                         "sip_poke_noanswer",
16942                                         "sip_reregister",
16943                                         "sip_reinvite_retry"},
16944                            { retrans_pkt,
16945                                      __sip_autodestruct,
16946                                      expire_register,
16947                                      auto_congest,
16948                                      sip_reg_timeout,
16949                                      sip_poke_peer_s,
16950                                      sip_poke_noanswer,
16951                                      sip_reregister,
16952                                      sip_reinvite_retry}};
16953    
16954    switch (cmd) {
16955    case CLI_INIT:
16956       e->command = "sip show sched";
16957       e->usage =
16958          "Usage: sip show sched\n"
16959          "       Shows stats on what's in the sched queue at the moment\n";
16960       return NULL;
16961    case CLI_GENERATE:
16962       return NULL;
16963    }
16964 
16965    cbuf = ast_str_alloca(2048);
16966 
16967    ast_cli(a->fd, "\n");
16968    ast_sched_report(sched, &cbuf, &cbnames);
16969    ast_cli(a->fd, "%s", cbuf->str);
16970 
16971    return CLI_SUCCESS;
16972 }

static char * sip_show_settings ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

List global settings for the SIP channel.

Definition at line 17155 of file chan_sip.c.

References ast_ha::addr, ast_cli_args::argc, ast_check_realtime(), ast_cli(), AST_CLI_ONOFF, AST_CLI_YESNO, ast_getformatname_multiple(), AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, AST_LIST_EMPTY, ast_sockaddr_is_any(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_tos2str(), authl, bindaddr, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, default_callerid, default_expiry, default_fromdomain, default_fromdomainport, default_language, default_maxcallbitrate, default_mohinterpret, default_mohsuggest, default_notifymime, default_prefs, default_primary_transport, default_qualify, default_tls_cfg, default_transports, default_vmexten, dtmfmode2str(), ast_tls_config::enabled, externaddr, externhost, externrefresh, FALSE, faxec2str(), ast_cli_args::fd, get_transport(), get_transport_list(), global_authfailureevents, global_autoframing, global_callcounter, global_cos_audio, global_cos_sip, global_cos_text, global_cos_video, global_flags, global_jbconf, global_match_auth_username, global_max_se, global_min_se, global_prematuremediafilter, global_qualifyfreq, global_reg_timeout, global_regattempts_max, global_relaxdtmf, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_sdpowner, global_sdpsession, global_st_mode, global_st_refresher, global_t1, global_t1min, global_t38_maxdatagram, global_timer_b, global_tos_audio, global_tos_sip, global_tos_text, global_tos_video, global_useragent, ast_jb_conf::impl, ast_tcptls_session_args::local_address, localaddr, max_expiry, ast_jb_conf::max_size, min_expiry, ast_ha::netmask, ast_ha::next, prefix, print_codec_to_cli(), recordhistory, ast_jb_conf::resync_threshold, S_OR, sip_cfg, sip_tcp_desc, sip_tls_desc, stmode2str(), strefresher2str(), transfermode2str(), and ast_cli_entry::usage.

17156 {
17157    int realtimepeers;
17158    int realtimeregs;
17159    char codec_buf[SIPBUFSIZE];
17160    const char *msg;  /* temporary msg pointer */
17161 
17162    switch (cmd) {
17163    case CLI_INIT:
17164       e->command = "sip show settings";
17165       e->usage =
17166          "Usage: sip show settings\n"
17167          "       Provides detailed list of the configuration of the SIP channel.\n";
17168       return NULL;
17169    case CLI_GENERATE:
17170       return NULL;
17171    }
17172 
17173 
17174    realtimepeers = ast_check_realtime("sippeers");
17175    realtimeregs = ast_check_realtime("sipregs");
17176 
17177    if (a->argc != 3)
17178       return CLI_SHOWUSAGE;
17179    ast_cli(a->fd, "\n\nGlobal Settings:\n");
17180    ast_cli(a->fd, "----------------\n");
17181    ast_cli(a->fd, "  UDP Bindaddress:        %s\n", ast_sockaddr_stringify(&bindaddr));
17182    if (ast_sockaddr_is_ipv6(&bindaddr) && ast_sockaddr_is_any(&bindaddr)) {
17183       ast_cli(a->fd, "  ** Additional Info:\n");
17184       ast_cli(a->fd, "     [::] may include IPv4 in addition to IPv6, if such a feature is enabled in the OS.\n");
17185    }
17186    ast_cli(a->fd, "  TCP SIP Bindaddress:    %s\n",
17187       sip_cfg.tcp_enabled != FALSE ?
17188             ast_sockaddr_stringify(&sip_tcp_desc.local_address) :
17189             "Disabled");
17190    ast_cli(a->fd, "  TLS SIP Bindaddress:    %s\n",
17191       default_tls_cfg.enabled != FALSE ?
17192             ast_sockaddr_stringify(&sip_tls_desc.local_address) :
17193             "Disabled");
17194    ast_cli(a->fd, "  Videosupport:           %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT)));
17195    ast_cli(a->fd, "  Textsupport:            %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT)));
17196    ast_cli(a->fd, "  Ignore SDP sess. ver.:  %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION)));
17197    ast_cli(a->fd, "  AutoCreate Peer:        %s\n", AST_CLI_YESNO(sip_cfg.autocreatepeer));
17198    ast_cli(a->fd, "  Match Auth Username:    %s\n", AST_CLI_YESNO(global_match_auth_username));
17199    ast_cli(a->fd, "  Allow unknown access:   %s\n", AST_CLI_YESNO(sip_cfg.allowguest));
17200    ast_cli(a->fd, "  Allow subscriptions:    %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)));
17201    ast_cli(a->fd, "  Allow overlap dialing:  %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP)));
17202    ast_cli(a->fd, "  Allow promsic. redir:   %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_PROMISCREDIR)));
17203    ast_cli(a->fd, "  Enable call counters:   %s\n", AST_CLI_YESNO(global_callcounter));
17204    ast_cli(a->fd, "  SIP domain support:     %s\n", AST_CLI_YESNO(!AST_LIST_EMPTY(&domain_list)));
17205    ast_cli(a->fd, "  Realm. auth:            %s\n", AST_CLI_YESNO(authl != NULL));
17206    ast_cli(a->fd, "  Our auth realm          %s\n", sip_cfg.realm);
17207    ast_cli(a->fd, "  Use domains as realms:  %s\n", AST_CLI_YESNO(sip_cfg.domainsasrealm));
17208    ast_cli(a->fd, "  Call to non-local dom.: %s\n", AST_CLI_YESNO(sip_cfg.allow_external_domains));
17209    ast_cli(a->fd, "  URI user is phone no:   %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USEREQPHONE)));
17210    ast_cli(a->fd, "  Always auth rejects:    %s\n", AST_CLI_YESNO(sip_cfg.alwaysauthreject));
17211    ast_cli(a->fd, "  Direct RTP setup:       %s\n", AST_CLI_YESNO(sip_cfg.directrtpsetup));
17212    ast_cli(a->fd, "  User Agent:             %s\n", global_useragent);
17213    ast_cli(a->fd, "  SDP Session Name:       %s\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession);
17214    ast_cli(a->fd, "  SDP Owner Name:         %s\n", ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner);
17215    ast_cli(a->fd, "  Reg. context:           %s\n", S_OR(sip_cfg.regcontext, "(not set)"));
17216    ast_cli(a->fd, "  Regexten on Qualify:    %s\n", AST_CLI_YESNO(sip_cfg.regextenonqualify));
17217    ast_cli(a->fd, "  Caller ID:              %s\n", default_callerid);
17218    if ((default_fromdomainport) && (default_fromdomainport != STANDARD_SIP_PORT)) {
17219       ast_cli(a->fd, "  From: Domain:           %s:%d\n", default_fromdomain, default_fromdomainport);
17220    } else {
17221       ast_cli(a->fd, "  From: Domain:           %s\n", default_fromdomain);
17222    }
17223    ast_cli(a->fd, "  Record SIP history:     %s\n", AST_CLI_ONOFF(recordhistory));
17224    ast_cli(a->fd, "  Call Events:            %s\n", AST_CLI_ONOFF(sip_cfg.callevents));
17225    ast_cli(a->fd, "  Auth. Failure Events:   %s\n", AST_CLI_ONOFF(global_authfailureevents));
17226 
17227    ast_cli(a->fd, "  T.38 support:           %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT)));
17228    ast_cli(a->fd, "  T.38 EC mode:           %s\n", faxec2str(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT)));
17229    ast_cli(a->fd, "  T.38 MaxDtgrm:          %d\n", global_t38_maxdatagram);
17230    if (!realtimepeers && !realtimeregs)
17231       ast_cli(a->fd, "  SIP realtime:           Disabled\n" );
17232    else
17233       ast_cli(a->fd, "  SIP realtime:           Enabled\n" );
17234    ast_cli(a->fd, "  Qualify Freq :          %d ms\n", global_qualifyfreq);
17235    ast_cli(a->fd, "  Q.850 Reason header:    %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_Q850_REASON)));
17236    ast_cli(a->fd, "\nNetwork QoS Settings:\n");
17237    ast_cli(a->fd, "---------------------------\n");
17238    ast_cli(a->fd, "  IP ToS SIP:             %s\n", ast_tos2str(global_tos_sip));
17239    ast_cli(a->fd, "  IP ToS RTP audio:       %s\n", ast_tos2str(global_tos_audio));
17240    ast_cli(a->fd, "  IP ToS RTP video:       %s\n", ast_tos2str(global_tos_video));
17241    ast_cli(a->fd, "  IP ToS RTP text:        %s\n", ast_tos2str(global_tos_text));
17242    ast_cli(a->fd, "  802.1p CoS SIP:         %d\n", global_cos_sip);
17243    ast_cli(a->fd, "  802.1p CoS RTP audio:   %d\n", global_cos_audio);
17244    ast_cli(a->fd, "  802.1p CoS RTP video:   %d\n", global_cos_video);
17245    ast_cli(a->fd, "  802.1p CoS RTP text:    %d\n", global_cos_text);
17246    ast_cli(a->fd, "  Jitterbuffer enabled:   %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_ENABLED)));
17247    ast_cli(a->fd, "  Jitterbuffer forced:    %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_FORCED)));
17248    ast_cli(a->fd, "  Jitterbuffer max size:  %ld\n", global_jbconf.max_size);
17249    ast_cli(a->fd, "  Jitterbuffer resync:    %ld\n", global_jbconf.resync_threshold);
17250    ast_cli(a->fd, "  Jitterbuffer impl:      %s\n", global_jbconf.impl);
17251    ast_cli(a->fd, "  Jitterbuffer log:       %s\n", AST_CLI_YESNO(ast_test_flag(&global_jbconf, AST_JB_LOG)));
17252 
17253    ast_cli(a->fd, "\nNetwork Settings:\n");
17254    ast_cli(a->fd, "---------------------------\n");
17255    /* determine if/how SIP address can be remapped */
17256    if (localaddr == NULL)
17257       msg = "Disabled, no localnet list";
17258    else if (ast_sockaddr_isnull(&externaddr))
17259       msg = "Disabled";
17260    else if (!ast_strlen_zero(externhost))
17261       msg = "Enabled using externhost";
17262    else
17263       msg = "Enabled using externaddr";
17264    ast_cli(a->fd, "  SIP address remapping:  %s\n", msg);
17265    ast_cli(a->fd, "  Externhost:             %s\n", S_OR(externhost, "<none>"));
17266    ast_cli(a->fd, "  externaddr:               %s\n", ast_sockaddr_stringify(&externaddr));
17267    ast_cli(a->fd, "  Externrefresh:          %d\n", externrefresh);
17268    {
17269       struct ast_ha *d;
17270       const char *prefix = "Localnet:";
17271 
17272       for (d = localaddr; d ; prefix = "", d = d->next) {
17273          const char *addr = ast_strdupa(ast_sockaddr_stringify_addr(&d->addr));
17274          const char *mask = ast_strdupa(ast_sockaddr_stringify_addr(&d->netmask));
17275          ast_cli(a->fd, "  %-24s%s/%s\n", prefix, addr, mask);
17276       }
17277    }
17278    ast_cli(a->fd, "\nGlobal Signalling Settings:\n");
17279    ast_cli(a->fd, "---------------------------\n");
17280    ast_cli(a->fd, "  Codecs:                 ");
17281    ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, sip_cfg.capability);
17282    ast_cli(a->fd, "%s\n", codec_buf);
17283    ast_cli(a->fd, "  Codec Order:            ");
17284    print_codec_to_cli(a->fd, &default_prefs);
17285    ast_cli(a->fd, "\n");
17286    ast_cli(a->fd, "  Relax DTMF:             %s\n", AST_CLI_YESNO(global_relaxdtmf));
17287    ast_cli(a->fd, "  RFC2833 Compensation:   %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE)));
17288    ast_cli(a->fd, "  Symmetric RTP:          %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_SYMMETRICRTP)));
17289    ast_cli(a->fd, "  Compact SIP headers:    %s\n", AST_CLI_YESNO(sip_cfg.compactheaders));
17290    ast_cli(a->fd, "  RTP Keepalive:          %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
17291    ast_cli(a->fd, "  RTP Timeout:            %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
17292    ast_cli(a->fd, "  RTP Hold Timeout:       %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
17293    ast_cli(a->fd, "  MWI NOTIFY mime type:   %s\n", default_notifymime);
17294    ast_cli(a->fd, "  DNS SRV lookup:         %s\n", AST_CLI_YESNO(sip_cfg.srvlookup));
17295    ast_cli(a->fd, "  Pedantic SIP support:   %s\n", AST_CLI_YESNO(sip_cfg.pedanticsipchecking));
17296    ast_cli(a->fd, "  Reg. min duration       %d secs\n", min_expiry);
17297    ast_cli(a->fd, "  Reg. max duration:      %d secs\n", max_expiry);
17298    ast_cli(a->fd, "  Reg. default duration:  %d secs\n", default_expiry);
17299    ast_cli(a->fd, "  Outbound reg. timeout:  %d secs\n", global_reg_timeout);
17300    ast_cli(a->fd, "  Outbound reg. attempts: %d\n", global_regattempts_max);
17301    ast_cli(a->fd, "  Notify ringing state:   %s\n", AST_CLI_YESNO(sip_cfg.notifyringing));
17302    if (sip_cfg.notifyringing) {
17303       ast_cli(a->fd, "    Include CID:          %s%s\n",
17304             AST_CLI_YESNO(sip_cfg.notifycid),
17305             sip_cfg.notifycid == IGNORE_CONTEXT ? " (Ignoring context)" : "");
17306    }
17307    ast_cli(a->fd, "  Notify hold state:      %s\n", AST_CLI_YESNO(sip_cfg.notifyhold));
17308    ast_cli(a->fd, "  SIP Transfer mode:      %s\n", transfermode2str(sip_cfg.allowtransfer));
17309    ast_cli(a->fd, "  Max Call Bitrate:       %d kbps\n", default_maxcallbitrate);
17310    ast_cli(a->fd, "  Auto-Framing:           %s\n", AST_CLI_YESNO(global_autoframing));
17311    ast_cli(a->fd, "  Outb. proxy:            %s %s\n", ast_strlen_zero(sip_cfg.outboundproxy.name) ? "<not set>" : sip_cfg.outboundproxy.name,
17312                      sip_cfg.outboundproxy.force ? "(forced)" : "");
17313    ast_cli(a->fd, "  Session Timers:         %s\n", stmode2str(global_st_mode));
17314    ast_cli(a->fd, "  Session Refresher:      %s\n", strefresher2str (global_st_refresher));
17315    ast_cli(a->fd, "  Session Expires:        %d secs\n", global_max_se);
17316    ast_cli(a->fd, "  Session Min-SE:         %d secs\n", global_min_se);
17317    ast_cli(a->fd, "  Timer T1:               %d\n", global_t1);
17318    ast_cli(a->fd, "  Timer T1 minimum:       %d\n", global_t1min);
17319    ast_cli(a->fd, "  Timer B:                %d\n", global_timer_b);
17320    ast_cli(a->fd, "  No premature media:     %s\n", AST_CLI_YESNO(global_prematuremediafilter));
17321    ast_cli(a->fd, "  Max forwards:           %d\n", sip_cfg.default_max_forwards);
17322 
17323    ast_cli(a->fd, "\nDefault Settings:\n");
17324    ast_cli(a->fd, "-----------------\n");
17325    ast_cli(a->fd, "  Allowed transports:     %s\n", get_transport_list(default_transports));
17326    ast_cli(a->fd, "  Outbound transport:    %s\n", get_transport(default_primary_transport));
17327    ast_cli(a->fd, "  Context:                %s\n", sip_cfg.default_context);
17328    ast_cli(a->fd, "  Force rport:            %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_NAT_FORCE_RPORT)));
17329    ast_cli(a->fd, "  DTMF:                   %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF)));
17330    ast_cli(a->fd, "  Qualify:                %d\n", default_qualify);
17331    ast_cli(a->fd, "  Use ClientCode:         %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_USECLIENTCODE)));
17332    ast_cli(a->fd, "  Progress inband:        %s\n", (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_NO)));
17333    ast_cli(a->fd, "  Language:               %s\n", default_language);
17334    ast_cli(a->fd, "  MOH Interpret:          %s\n", default_mohinterpret);
17335    ast_cli(a->fd, "  MOH Suggest:            %s\n", default_mohsuggest);
17336    ast_cli(a->fd, "  Voice Mail Extension:   %s\n", default_vmexten);
17337 
17338    
17339    if (realtimepeers || realtimeregs) {
17340       ast_cli(a->fd, "\nRealtime SIP Settings:\n");
17341       ast_cli(a->fd, "----------------------\n");
17342       ast_cli(a->fd, "  Realtime Peers:         %s\n", AST_CLI_YESNO(realtimepeers));
17343       ast_cli(a->fd, "  Realtime Regs:          %s\n", AST_CLI_YESNO(realtimeregs));
17344       ast_cli(a->fd, "  Cache Friends:          %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)));
17345       ast_cli(a->fd, "  Update:                 %s\n", AST_CLI_YESNO(sip_cfg.peer_rtupdate));
17346       ast_cli(a->fd, "  Ignore Reg. Expire:     %s\n", AST_CLI_YESNO(sip_cfg.ignore_regexpire));
17347       ast_cli(a->fd, "  Save sys. name:         %s\n", AST_CLI_YESNO(sip_cfg.rtsave_sysname));
17348       ast_cli(a->fd, "  Auto Clear:             %d (%s)\n", sip_cfg.rtautoclear, ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR) ? "Enabled" : "Disabled");
17349    }
17350    ast_cli(a->fd, "\n----\n");
17351    return CLI_SUCCESS;
17352 }

static char* sip_show_tcp ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

Show active TCP connections.

Definition at line 15664 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli(), ast_sockaddr_stringify(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, FORMAT2, get_transport(), threadt, and ast_cli_entry::usage.

15665 {
15666    struct sip_threadinfo *th;
15667    struct ao2_iterator i;
15668 
15669 #define FORMAT2 "%-47.47s %9.9s %6.6s\n"
15670 #define FORMAT  "%-47.47s %-9.9s %-6.6s\n"
15671 
15672    switch (cmd) {
15673    case CLI_INIT:
15674       e->command = "sip show tcp";
15675       e->usage =
15676          "Usage: sip show tcp\n"
15677          "       Lists all active TCP/TLS sessions.\n";
15678       return NULL;
15679    case CLI_GENERATE:
15680       return NULL;
15681    }
15682 
15683    if (a->argc != 3)
15684       return CLI_SHOWUSAGE;
15685 
15686    ast_cli(a->fd, FORMAT2, "Address", "Transport", "Type");
15687 
15688    i = ao2_iterator_init(threadt, 0);
15689    while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) {
15690       ast_cli(a->fd, FORMAT,
15691          ast_sockaddr_stringify(&th->tcptls_session->remote_address),
15692          get_transport(th->type),
15693          (th->tcptls_session->client ? "Client" : "Server"));
15694       ao2_t_ref(th, -1, "decrement ref from iterator");
15695    }
15696    ao2_iterator_destroy(&i);
15697 
15698    return CLI_SUCCESS;
15699 #undef FORMAT
15700 #undef FORMAT2
15701 }

static char* sip_show_user ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

Show one user in detail.

Definition at line 16856 of file chan_sip.c.

References ao2_lock, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), AST_CLI_YESNO, ast_describe_caller_presentation(), ast_strlen_zero(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_show_user(), FALSE, ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, ast_variable::name, ast_variable::next, ast_cli_args::pos, print_codec_to_cli(), print_group(), stmode2str(), strefresher2str(), transfermode2str(), TRUE, unref_peer(), ast_cli_entry::usage, ast_variable::value, and ast_cli_args::word.

16857 {
16858    char cbuf[256];
16859    struct sip_peer *user;
16860    struct ast_variable *v;
16861    int load_realtime;
16862 
16863    switch (cmd) {
16864    case CLI_INIT:
16865       e->command = "sip show user";
16866       e->usage =
16867          "Usage: sip show user <name> [load]\n"
16868          "       Shows all details on one SIP user and the current status.\n"
16869          "       Option \"load\" forces lookup of peer in realtime storage.\n";
16870       return NULL;
16871    case CLI_GENERATE:
16872       return complete_sip_show_user(a->line, a->word, a->pos, a->n);
16873    }
16874 
16875    if (a->argc < 4)
16876       return CLI_SHOWUSAGE;
16877 
16878    /* Load from realtime storage? */
16879    load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? TRUE : FALSE;
16880 
16881    if ((user = find_peer(a->argv[3], NULL, load_realtime, FINDUSERS, FALSE, 0))) {
16882       ao2_lock(user);
16883       ast_cli(a->fd, "\n\n");
16884       ast_cli(a->fd, "  * Name       : %s\n", user->name);
16885       ast_cli(a->fd, "  Secret       : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
16886       ast_cli(a->fd, "  MD5Secret    : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
16887       ast_cli(a->fd, "  Context      : %s\n", user->context);
16888       ast_cli(a->fd, "  Language     : %s\n", user->language);
16889       if (!ast_strlen_zero(user->accountcode))
16890          ast_cli(a->fd, "  Accountcode  : %s\n", user->accountcode);
16891       ast_cli(a->fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
16892       ast_cli(a->fd, "  Transfer mode: %s\n", transfermode2str(user->allowtransfer));
16893       ast_cli(a->fd, "  MaxCallBR    : %d kbps\n", user->maxcallbitrate);
16894       ast_cli(a->fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
16895       ast_cli(a->fd, "  Call limit   : %d\n", user->call_limit);
16896       ast_cli(a->fd, "  Callgroup    : ");
16897       print_group(a->fd, user->callgroup, 0);
16898       ast_cli(a->fd, "  Pickupgroup  : ");
16899       print_group(a->fd, user->pickupgroup, 0);
16900       ast_cli(a->fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
16901       ast_cli(a->fd, "  ACL          : %s\n", AST_CLI_YESNO(user->ha != NULL));
16902       ast_cli(a->fd, "  Sess-Timers  : %s\n", stmode2str(user->stimer.st_mode_oper));
16903       ast_cli(a->fd, "  Sess-Refresh : %s\n", strefresher2str(user->stimer.st_ref));
16904       ast_cli(a->fd, "  Sess-Expires : %d secs\n", user->stimer.st_max_se);
16905       ast_cli(a->fd, "  Sess-Min-SE  : %d secs\n", user->stimer.st_min_se);
16906       ast_cli(a->fd, "  RTP Engine   : %s\n", user->engine);
16907 
16908       ast_cli(a->fd, "  Codec Order  : (");
16909       print_codec_to_cli(a->fd, &user->prefs);
16910       ast_cli(a->fd, ")\n");
16911 
16912       ast_cli(a->fd, "  Auto-Framing:  %s \n", AST_CLI_YESNO(user->autoframing));
16913       if (user->chanvars) {
16914          ast_cli(a->fd, "  Variables    :\n");
16915          for (v = user->chanvars ; v ; v = v->next)
16916             ast_cli(a->fd, "                 %s = %s\n", v->name, v->value);
16917       }
16918 
16919       ast_cli(a->fd, "\n");
16920 
16921       ao2_unlock(user);
16922       unref_peer(user, "sip show user");
16923    } else {
16924       ast_cli(a->fd, "User %s not found.\n", a->argv[3]);
16925       ast_cli(a->fd, "\n");
16926    }
16927 
16928    return CLI_SUCCESS;
16929 }

static char* sip_show_users ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

CLI Command 'SIP Show Users'.

Definition at line 15704 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_CLI_YESNO, ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, FORMAT, TRUE, unref_peer(), and ast_cli_entry::usage.

15705 {
15706    regex_t regexbuf;
15707    int havepattern = FALSE;
15708    struct ao2_iterator user_iter;
15709    struct sip_peer *user;
15710 
15711 #define FORMAT  "%-25.25s  %-15.15s  %-15.15s  %-15.15s  %-5.5s%-10.10s\n"
15712 
15713    switch (cmd) {
15714    case CLI_INIT:
15715       e->command = "sip show users";
15716       e->usage =
15717          "Usage: sip show users [like <pattern>]\n"
15718          "       Lists all known SIP users.\n"
15719          "       Optional regular expression pattern is used to filter the user list.\n";
15720       return NULL;
15721    case CLI_GENERATE:
15722       return NULL;
15723    }
15724 
15725    switch (a->argc) {
15726    case 5:
15727       if (!strcasecmp(a->argv[3], "like")) {
15728          if (regcomp(&regexbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
15729             return CLI_SHOWUSAGE;
15730          havepattern = TRUE;
15731       } else
15732          return CLI_SHOWUSAGE;
15733    case 3:
15734       break;
15735    default:
15736       return CLI_SHOWUSAGE;
15737    }
15738 
15739    ast_cli(a->fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "ForcerPort");
15740 
15741    user_iter = ao2_iterator_init(peers, 0);
15742    while ((user = ao2_iterator_next(&user_iter))) {
15743       ao2_lock(user);
15744       if (!(user->type & SIP_TYPE_USER)) {
15745          ao2_unlock(user);
15746          unref_peer(user, "sip show users");
15747          continue;
15748       }
15749 
15750       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0)) {
15751          ao2_unlock(user);
15752          unref_peer(user, "sip show users");
15753          continue;
15754       }
15755 
15756       ast_cli(a->fd, FORMAT, user->name,
15757          user->secret,
15758          user->accountcode,
15759          user->context,
15760          AST_CLI_YESNO(user->ha != NULL),
15761          AST_CLI_YESNO(ast_test_flag(&user->flags[0], SIP_NAT_FORCE_RPORT)));
15762       ao2_unlock(user);
15763       unref_peer(user, "sip show users");
15764    }
15765    ao2_iterator_destroy(&user_iter);
15766 
15767    if (havepattern)
15768       regfree(&regexbuf);
15769 
15770    return CLI_SUCCESS;
15771 #undef FORMAT
15772 }

static int sip_sipredirect ( struct sip_pvt *  p,
const char *  dest 
) [static]

Transfer call before connect with a 302 redirect.

Note:
Called by the transfer() dialplan application through the sip_transfer() pbx interface function if the call is in ringing state
Todo:
Fix this function so that we wait for reply to the REFER and react to errors, denials or other issues the other end might have.

Definition at line 28177 of file chan_sip.c.

References AST_CONTROL_TRANSFER, ast_copy_string(), ast_log(), ast_queue_control_data(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), AST_TRANSFER_SUCCESS, get_header(), LOG_ERROR, sip_alreadygone(), sip_scheddestroy(), strcasestr(), strsep(), and transmit_response_reliable().

Referenced by sip_transfer().

28178 {
28179    char *cdest;
28180    char *extension, *domain;
28181 
28182    cdest = ast_strdupa(dest);
28183    
28184    extension = strsep(&cdest, "@");
28185    domain = strsep(&cdest, ":");
28186    if (ast_strlen_zero(extension)) {
28187       ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
28188       return 0;
28189    }
28190 
28191    /* we'll issue the redirect message here */
28192    if (!domain) {
28193       char *local_to_header;
28194       char to_header[256];
28195 
28196       ast_copy_string(to_header, get_header(&p->initreq, "To"), sizeof(to_header));
28197       if (ast_strlen_zero(to_header)) {
28198          ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
28199          return 0;
28200       }
28201       if (((local_to_header = strcasestr(to_header, "sip:")) || (local_to_header = strcasestr(to_header, "sips:")))
28202          && (local_to_header = strchr(local_to_header, '@'))) {
28203          char ldomain[256];
28204 
28205          memset(ldomain, 0, sizeof(ldomain));
28206          local_to_header++;
28207          /* This is okey because lhost and lport are as big as tmp */
28208          sscanf(local_to_header, "%256[^<>; ]", ldomain);
28209          if (ast_strlen_zero(ldomain)) {
28210             ast_log(LOG_ERROR, "Can't find the host address\n");
28211             return 0;
28212          }
28213          domain = ast_strdupa(ldomain);
28214       }
28215    }
28216 
28217    ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s>", extension, domain);
28218    transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq);
28219 
28220    sip_scheddestroy(p, SIP_TRANS_TIMEOUT);   /* Make sure we stop send this reply. */
28221    sip_alreadygone(p);
28222 
28223    if (p->owner) {
28224       enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
28225       ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
28226    }
28227    /* hangup here */
28228    return 0;
28229 }

static struct sip_st_dlg * sip_st_alloc ( struct sip_pvt *const   p  )  [static]

Allocate Session-Timers struct w/in dialog.

Definition at line 7219 of file chan_sip.c.

References ast_calloc, ast_log(), and LOG_ERROR.

Referenced by handle_request_invite(), and st_get_mode().

07220 {
07221    struct sip_st_dlg *stp;
07222 
07223    if (p->stimer) {
07224       ast_log(LOG_ERROR, "Session-Timer struct already allocated\n");
07225       return p->stimer;
07226    }
07227 
07228    if (!(stp = ast_calloc(1, sizeof(struct sip_st_dlg))))
07229       return NULL;
07230 
07231    p->stimer = stp;
07232 
07233    stp->st_schedid = -1;           /* Session-Timers ast_sched scheduler id */
07234 
07235    return p->stimer;
07236 }

static int sip_standard_port ( enum sip_transport  type,
int  port 
) [static]

Returns the port to use for this socket.

Parameters:
type The type of transport used
port Port we are checking to see if it's the standard port.
Note:
port is expected in host byte order

Definition at line 24327 of file chan_sip.c.

Referenced by initreqprep(), and transmit_notify_with_mwi().

24328 {
24329    if (type & SIP_TRANSPORT_TLS)
24330       return port == STANDARD_TLS_PORT;
24331    else
24332       return port == STANDARD_SIP_PORT;
24333 }

static int sip_subscribe_mwi ( const char *  value,
int  lineno 
) [static]

Parse mwi=> line in sip.conf and add to list.

--- SIP MWI Subscription support

Definition at line 7801 of file chan_sip.c.

References ast_calloc_with_stringfields, ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, hostname, LOG_WARNING, mailbox, secret, sip_subscribe_mwi_destroy(), and submwil.

07802 {
07803    struct sip_subscription_mwi *mwi;
07804    int portnum = 0;
07805    enum sip_transport transport = SIP_TRANSPORT_UDP;
07806    char buf[256] = "";
07807    char *username = NULL, *hostname = NULL, *secret = NULL, *authuser = NULL, *porta = NULL, *mailbox = NULL, *at = NULL;
07808 
07809    if (!value) {
07810       return -1;
07811    }
07812 
07813    ast_copy_string(buf, value, sizeof(buf));
07814 
07815    if (!(at = strstr(buf, "@"))) {
07816       return -1;
07817    }
07818 
07819    if ((hostname = strrchr(buf, '@'))) {
07820       *hostname++ = '\0';
07821       username = buf;
07822    }
07823 
07824    if ((secret = strchr(username, ':'))) {
07825       *secret++ = '\0';
07826       if ((authuser = strchr(secret, ':'))) {
07827          *authuser++ = '\0';
07828       }
07829    }
07830 
07831    if ((mailbox = strchr(hostname, '/'))) {
07832       *mailbox++ = '\0';
07833    }
07834 
07835    if (ast_strlen_zero(username) || ast_strlen_zero(hostname) || ast_strlen_zero(mailbox)) {
07836       ast_log(LOG_WARNING, "Format for MWI subscription is user[:secret[:authuser]]@host[:port]/mailbox at line %d\n", lineno);
07837       return -1;
07838    }
07839 
07840    if ((porta = strchr(hostname, ':'))) {
07841       *porta++ = '\0';
07842       if (!(portnum = atoi(porta))) {
07843          ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
07844          return -1;
07845       }
07846    }
07847 
07848    if (!(mwi = ast_calloc_with_stringfields(1, struct sip_subscription_mwi, 256))) {
07849       return -1;
07850    }
07851 
07852    ASTOBJ_INIT(mwi);
07853    ast_string_field_set(mwi, username, username);
07854    if (secret) {
07855       ast_string_field_set(mwi, secret, secret);
07856    }
07857    if (authuser) {
07858       ast_string_field_set(mwi, authuser, authuser);
07859    }
07860    ast_string_field_set(mwi, hostname, hostname);
07861    ast_string_field_set(mwi, mailbox, mailbox);
07862    mwi->resub = -1;
07863    mwi->portno = portnum;
07864    mwi->transport = transport;
07865 
07866    ASTOBJ_CONTAINER_LINK(&submwil, mwi);
07867    ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy);
07868 
07869    return 0;
07870 }

static void sip_subscribe_mwi_destroy ( struct sip_subscription_mwi *  mwi  )  [static]

Destroy MWI subscription object.

Definition at line 5439 of file chan_sip.c.

References ast_dnsmgr_release(), ast_free, AST_SCHED_DEL, ast_string_field_free_memory, and sip_destroy().

Referenced by handle_response_subscribe(), sip_send_all_mwi_subscriptions(), sip_subscribe_mwi(), sip_subscribe_mwi_do(), and unload_module().

05440 {
05441    if (mwi->call) {
05442       mwi->call->mwi = NULL;
05443       sip_destroy(mwi->call);
05444    }
05445    
05446    AST_SCHED_DEL(sched, mwi->resub);
05447    ast_string_field_free_memory(mwi);
05448    ast_dnsmgr_release(mwi->dnsmgr);
05449    ast_free(mwi);
05450 }

static int sip_subscribe_mwi_do ( const void *  data  )  [static]

Send a subscription or resubscription for MWI.

Definition at line 11747 of file chan_sip.c.

References __sip_subscribe_mwi_do(), ASTOBJ_UNREF, and sip_subscribe_mwi_destroy().

Referenced by handle_response_subscribe(), and sip_send_all_mwi_subscriptions().

11748 {
11749    struct sip_subscription_mwi *mwi = (struct sip_subscription_mwi*)data;
11750    
11751    if (!mwi) {
11752       return -1;
11753    }
11754    
11755    mwi->resub = -1;
11756    __sip_subscribe_mwi_do(mwi);
11757    ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy);
11758    
11759    return 0;
11760 }

static int sip_t38_abort ( const void *  data  )  [static]

Called to deny a T38 reinvite if the core does not respond to our request.

Definition at line 21061 of file chan_sip.c.

References change_t38_state(), sip_pvt_lock, sip_pvt_unlock, and transmit_response_reliable().

Referenced by handle_request_invite().

21062 {
21063    struct sip_pvt *p = (struct sip_pvt *) data;
21064 
21065    sip_pvt_lock(p);
21066    /* an application may have taken ownership of the T.38 negotiation on this
21067     * channel while we were waiting to grab the lock... if it did, the scheduler
21068     * id will have been reset to -1, which is our indication that we do *not*
21069     * want to abort the negotiation process
21070     */
21071    if (p->t38id != -1) {
21072       change_t38_state(p, T38_DISABLED);
21073       transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
21074       p->t38id = -1;
21075       dialog_unref(p, "unref the dialog ptr from sip_t38_abort, because it held a dialog ptr");
21076    }
21077    sip_pvt_unlock(p);
21078    return 0;
21079 }

static struct ast_tcptls_session_instance* sip_tcp_locate ( struct ast_sockaddr *  s  )  [static]

Find thread for TCP/TLS session (based on IP/Port.

Note:
This function returns an astobj2 reference

Definition at line 24352 of file chan_sip.c.

References ao2_callback, ao2_ref, ao2_t_ref, threadinfo_locate_cb(), and threadt.

Referenced by sip_prepare_socket().

24353 {
24354    struct sip_threadinfo *th;
24355    struct ast_tcptls_session_instance *tcptls_instance = NULL;
24356 
24357    if ((th = ao2_callback(threadt, 0, threadinfo_locate_cb, s))) {
24358       tcptls_instance = (ao2_ref(th->tcptls_session, +1), th->tcptls_session);
24359       ao2_t_ref(th, -1, "decrement ref from callback");
24360    }
24361 
24362    return tcptls_instance;
24363 }

static void * sip_tcp_worker_fn ( void *   )  [static]

SIP TCP connection handler.

Definition at line 2438 of file chan_sip.c.

References _sip_tcp_helper_thread().

Referenced by sip_prepare_socket().

02439 {
02440    struct ast_tcptls_session_instance *tcptls_session = data;
02441 
02442    return _sip_tcp_helper_thread(NULL, tcptls_session);
02443 }

static void sip_tcptls_client_args_destructor ( void *  obj  )  [static]

Definition at line 2320 of file chan_sip.c.

References args, and ast_free.

Referenced by sip_prepare_socket().

02321 {
02322    struct ast_tcptls_session_args *args = obj;
02323    if (args->tls_cfg) {
02324       ast_free(args->tls_cfg->certfile);
02325       ast_free(args->tls_cfg->pvtfile);
02326       ast_free(args->tls_cfg->cipher);
02327       ast_free(args->tls_cfg->cafile);
02328       ast_free(args->tls_cfg->capath);
02329    }
02330    ast_free(args->tls_cfg);
02331    ast_free((char *) args->name);
02332 }

static int sip_tcptls_write ( struct ast_tcptls_session_instance *  tcptls_session,
const void *  buf,
size_t  len 
) [static]

used to indicate to a tcptls thread that data is ready to be written

Definition at line 2380 of file chan_sip.c.

References ao2_alloc, ao2_lock, ao2_t_find, ao2_t_ref, ao2_unlock, AST_LIST_INSERT_TAIL, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_str_create(), ast_str_set(), errno, ast_tcptls_session_instance::fd, ast_tcptls_session_instance::lock, LOG_ERROR, OBJ_POINTER, tcptls_packet_destructor(), and threadt.

Referenced by __sip_xmit().

02381 {
02382    int res = len;
02383    struct sip_threadinfo *th = NULL;
02384    struct tcptls_packet *packet = NULL;
02385    struct sip_threadinfo tmp = {
02386       .tcptls_session = tcptls_session,
02387    };
02388    enum sip_tcptls_alert alert = TCPTLS_ALERT_DATA;
02389 
02390    if (!tcptls_session) {
02391       return XMIT_ERROR;
02392    }
02393 
02394    ast_mutex_lock(&tcptls_session->lock);
02395 
02396    if ((tcptls_session->fd == -1) ||
02397       !(th = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread")) ||
02398       !(packet = ao2_alloc(sizeof(*packet), tcptls_packet_destructor)) ||
02399       !(packet->data = ast_str_create(len))) {
02400       goto tcptls_write_setup_error;
02401    }
02402 
02403    /* goto tcptls_write_error should _NOT_ be used beyond this point */
02404    ast_str_set(&packet->data, 0, "%s", (char *) buf);
02405    packet->len = len;
02406 
02407    /* alert tcptls thread handler that there is a packet to be sent.
02408     * must lock the thread info object to guarantee control of the
02409     * packet queue */
02410    ao2_lock(th);
02411    if (write(th->alert_pipe[1], &alert, sizeof(alert)) == -1) {
02412       ast_log(LOG_ERROR, "write() to alert pipe failed: %s\n", strerror(errno));
02413       ao2_t_ref(packet, -1, "could not write to alert pipe, remove packet");
02414       packet = NULL;
02415       res = XMIT_ERROR;
02416    } else { /* it is safe to queue the frame after issuing the alert when we hold the threadinfo lock */
02417       AST_LIST_INSERT_TAIL(&th->packet_q, packet, entry);
02418    }
02419    ao2_unlock(th);
02420 
02421    ast_mutex_unlock(&tcptls_session->lock);
02422    ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo object after finding it");
02423    return res;
02424 
02425 tcptls_write_setup_error:
02426    if (th) {
02427       ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo obj, could not create packet");
02428    }
02429    if (packet) {
02430       ao2_t_ref(packet, -1, "could not allocate packet's data");
02431    }
02432    ast_mutex_unlock(&tcptls_session->lock);
02433 
02434    return XMIT_ERROR;
02435 }

static struct sip_threadinfo* sip_threadinfo_create ( struct ast_tcptls_session_instance *  tcptls_session,
int  transport 
) [static]

creates a sip_threadinfo object and links it into the threadt table.

Definition at line 2356 of file chan_sip.c.

References ao2_alloc, ao2_t_link, ao2_t_ref, ast_log(), errno, LOG_ERROR, sip_threadinfo_destructor(), ast_tcptls_session_instance::ssl, and threadt.

Referenced by _sip_tcp_helper_thread(), and sip_prepare_socket().

02357 {
02358    struct sip_threadinfo *th;
02359 
02360    if (!tcptls_session || !(th = ao2_alloc(sizeof(*th), sip_threadinfo_destructor))) {
02361       return NULL;
02362    }
02363 
02364    th->alert_pipe[0] = th->alert_pipe[1] = -1;
02365 
02366    if (pipe(th->alert_pipe) == -1) {
02367       ao2_t_ref(th, -1, "Failed to open alert pipe on sip_threadinfo");
02368       ast_log(LOG_ERROR, "Could not create sip alert pipe in tcptls thread, error %s\n", strerror(errno));
02369       return NULL;
02370    }
02371    ao2_t_ref(tcptls_session, +1, "tcptls_session ref for sip_threadinfo object");
02372    th->tcptls_session = tcptls_session;
02373    th->type = transport ? transport : (tcptls_session->ssl ? SIP_TRANSPORT_TLS: SIP_TRANSPORT_TCP);
02374    ao2_t_link(threadt, th, "Adding new tcptls helper thread");
02375    ao2_t_ref(th, -1, "Decrementing threadinfo ref from alloc, only table ref remains");
02376    return th;
02377 }

static void sip_threadinfo_destructor ( void *  obj  )  [static]

Definition at line 2334 of file chan_sip.c.

References ao2_t_ref, and AST_LIST_REMOVE_HEAD.

Referenced by sip_threadinfo_create().

02335 {
02336    struct sip_threadinfo *th = obj;
02337    struct tcptls_packet *packet;
02338    if (th->alert_pipe[1] > -1) {
02339       close(th->alert_pipe[0]);
02340    }
02341    if (th->alert_pipe[1] > -1) {
02342       close(th->alert_pipe[1]);
02343    }
02344    th->alert_pipe[0] = th->alert_pipe[1] = -1;
02345 
02346    while ((packet = AST_LIST_REMOVE_HEAD(&th->packet_q, entry))) {
02347       ao2_t_ref(packet, -1, "thread destruction, removing packet from frame queue");
02348    }
02349 
02350    if (th->tcptls_session) {
02351       ao2_t_ref(th->tcptls_session, -1, "remove tcptls_session for sip_threadinfo object");
02352    }
02353 }

static int sip_transfer ( struct ast_channel *  ast,
const char *  dest 
) [static]

Transfer SIP call.

Definition at line 6409 of file chan_sip.c.

References ast_channel::_state, AST_STATE_RING, sip_pvt_lock, sip_pvt_unlock, sip_sipredirect(), ast_channel::tech_pvt, and transmit_refer().

06410 {
06411    struct sip_pvt *p = ast->tech_pvt;
06412    int res;
06413 
06414    if (dest == NULL) /* functions below do not take a NULL */
06415       dest = "";
06416    sip_pvt_lock(p);
06417    if (ast->_state == AST_STATE_RING)
06418       res = sip_sipredirect(p, dest);
06419    else
06420       res = transmit_refer(p, dest);
06421    sip_pvt_unlock(p);
06422    return res;
06423 }

static char * sip_unregister ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
) [static]

Unregister (force expiration) a SIP peer in the registry via CLI.

Note:
This function does not tell the SIP device what's going on, so use it with great care.

Definition at line 17029 of file chan_sip.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_SCHED_DEL_UNREF, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_unregister(), expire_register(), ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ref_peer(), TRUE, unref_peer(), ast_cli_entry::usage, and ast_cli_args::word.

17030 {
17031    struct sip_peer *peer;
17032    int load_realtime = 0;
17033 
17034    switch (cmd) {
17035    case CLI_INIT:
17036       e->command = "sip unregister";
17037       e->usage =
17038          "Usage: sip unregister <peer>\n"
17039          "       Unregister (force expiration) a SIP peer from the registry\n";
17040       return NULL;
17041    case CLI_GENERATE:
17042       return complete_sip_unregister(a->line, a->word, a->pos, a->n);
17043    }
17044    
17045    if (a->argc != 3)
17046       return CLI_SHOWUSAGE;
17047    
17048    if ((peer = find_peer(a->argv[2], NULL, load_realtime, FINDPEERS, TRUE, 0))) {
17049       if (peer->expire > 0) {
17050          AST_SCHED_DEL_UNREF(sched, peer->expire,
17051             unref_peer(peer, "remove register expire ref"));
17052          expire_register(ref_peer(peer, "ref for expire_register"));
17053          ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]);
17054       } else {
17055          ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
17056       }
17057       unref_peer(peer, "sip_unregister: unref_peer via sip_unregister: done with peer from find_peer call");
17058    } else {
17059       ast_cli(a->fd, "Peer unknown: \'%s\'. Not unregistered.\n", a->argv[2]);
17060    }
17061    
17062    return CLI_SUCCESS;
17063 }

static void sip_unregister_tests ( void   )  [static]

SIP test registration.

Definition at line 28625 of file chan_sip.c.

Referenced by unload_module().

28626 {
28627    sip_config_parser_unregister_tests();
28628    sip_request_parser_unregister_tests();
28629    sip_dialplan_function_unregister_tests();
28630 }

static int sip_write ( struct ast_channel *  ast,
struct ast_frame *  frame 
) [static]

Send frame to media channel (rtp).

Definition at line 6204 of file chan_sip.c.

References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_rtp_instance_update_source(), ast_rtp_instance_write(), ast_rtp_red_buffer(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), ast_frame_subclass::codec, ast_frame::frametype, global_prematuremediafilter, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, sip_pvt_lock, sip_pvt_unlock, ast_frame::subclass, ast_channel::tech_pvt, transmit_provisional_response(), TRUE, and ast_channel::writeformat.

06205 {
06206    struct sip_pvt *p = ast->tech_pvt;
06207    int res = 0;
06208 
06209    switch (frame->frametype) {
06210    case AST_FRAME_VOICE:
06211       if (!(frame->subclass.codec & ast->nativeformats)) {
06212          char s1[512], s2[512], s3[512];
06213          ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s read/write = %s/%s\n",
06214             ast_getformatname(frame->subclass.codec),
06215             ast_getformatname_multiple(s1, sizeof(s1), ast->nativeformats & AST_FORMAT_AUDIO_MASK),
06216             ast_getformatname_multiple(s2, sizeof(s2), ast->readformat),
06217             ast_getformatname_multiple(s3, sizeof(s3), ast->writeformat));
06218          return 0;
06219       }
06220       if (p) {
06221          sip_pvt_lock(p);
06222          if (p->rtp) {
06223             /* If channel is not up, activate early media session */
06224             if ((ast->_state != AST_STATE_UP) &&
06225                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
06226                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06227                ast_rtp_instance_update_source(p->rtp);
06228                if (!global_prematuremediafilter) {
06229                   p->invitestate = INV_EARLY_MEDIA;
06230                   transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
06231                   ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
06232                }
06233             } else if (p->t38.state == T38_ENABLED) {
06234                /* drop frame, can't sent VOICE frames while in T.38 mode */
06235             } else {
06236                p->lastrtptx = time(NULL);
06237                res = ast_rtp_instance_write(p->rtp, frame);
06238             }
06239          }
06240          sip_pvt_unlock(p);
06241       }
06242       break;
06243    case AST_FRAME_VIDEO:
06244       if (p) {
06245          sip_pvt_lock(p);
06246          if (p->vrtp) {
06247             /* Activate video early media */
06248             if ((ast->_state != AST_STATE_UP) &&
06249                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
06250                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06251                p->invitestate = INV_EARLY_MEDIA;
06252                transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
06253                ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
06254             }
06255             p->lastrtptx = time(NULL);
06256             res = ast_rtp_instance_write(p->vrtp, frame);
06257          }
06258          sip_pvt_unlock(p);
06259       }
06260       break;
06261    case AST_FRAME_TEXT:
06262       if (p) {
06263          sip_pvt_lock(p);
06264          if (p->red) {
06265             ast_rtp_red_buffer(p->trtp, frame);
06266          } else {
06267             if (p->trtp) {
06268                /* Activate text early media */
06269                if ((ast->_state != AST_STATE_UP) &&
06270                    !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
06271                    !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06272                   p->invitestate = INV_EARLY_MEDIA;
06273                   transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
06274                   ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
06275                }
06276                p->lastrtptx = time(NULL);
06277                res = ast_rtp_instance_write(p->trtp, frame);
06278             }
06279          }
06280          sip_pvt_unlock(p);
06281       }
06282       break;
06283    case AST_FRAME_IMAGE:
06284       return 0;
06285       break;
06286    case AST_FRAME_MODEM:
06287       if (p) {
06288          sip_pvt_lock(p);
06289          /* UDPTL requires two-way communication, so early media is not needed here.
06290             we simply forget the frames if we get modem frames before the bridge is up.
06291             Fax will re-transmit.
06292          */
06293          if ((ast->_state == AST_STATE_UP) &&
06294              p->udptl &&
06295              (p->t38.state == T38_ENABLED)) {
06296             res = ast_udptl_write(p->udptl, frame);
06297          }
06298          sip_pvt_unlock(p);
06299       }
06300       break;
06301    default:
06302       ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype);
06303       return 0;
06304    }
06305 
06306    return res;
06307 }

static int sipsock_read ( int *  id,
int  fd,
short  events,
void *  ignore 
) [static]

Read data from SIP UDP socket.

Note:
sipsock_read locks the owner channel while we are processing the SIP message
Returns:
1 on error, 0 on success
Note:
Successful messages is connected to SIP call and forwarded to handle_incoming()

Definition at line 24161 of file chan_sip.c.

References AST_DYNSTR_BUILD_FAILED, ast_log(), ast_recvfrom(), ast_sockaddr_port, ast_str_create(), ast_str_set(), ast_str_strlen(), bindaddr, deinit_req(), errno, handle_request_do(), LOG_NOTICE, LOG_WARNING, set_socket_transport(), and sipsock.

Referenced by do_monitor().

24162 {
24163    struct sip_request req;
24164    struct ast_sockaddr addr;
24165    int res;
24166    static char readbuf[65535];
24167 
24168    memset(&req, 0, sizeof(req));
24169    res = ast_recvfrom(fd, readbuf, sizeof(readbuf) - 1, 0, &addr);
24170    if (res < 0) {
24171 #if !defined(__FreeBSD__)
24172       if (errno == EAGAIN)
24173          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
24174       else
24175 #endif
24176       if (errno != ECONNREFUSED)
24177          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
24178       return 1;
24179    }
24180 
24181    readbuf[res] = '\0';
24182 
24183    if (!(req.data = ast_str_create(SIP_MIN_PACKET))) {
24184       return 1;
24185    }
24186 
24187    if (ast_str_set(&req.data, 0, "%s", readbuf) == AST_DYNSTR_BUILD_FAILED) {
24188       return -1;
24189    }
24190 
24191    /* req.data will have the correct length in case of nulls */
24192    req.len = ast_str_strlen(req.data);
24193    req.socket.fd = sipsock;
24194    set_socket_transport(&req.socket, SIP_TRANSPORT_UDP);
24195    req.socket.tcptls_session  = NULL;
24196    req.socket.port = htons(ast_sockaddr_port(&bindaddr));
24197 
24198    handle_request_do(&req, &addr);
24199    deinit_req(&req);
24200 
24201    return 1;
24202 }

enum st_mode st_get_mode ( struct sip_pvt *  p  )  [static]

Get the session-timer mode.

Parameters:
p pointer to the SIP dialog

Definition at line 25047 of file chan_sip.c.

References global_st_mode, and sip_st_alloc().

Referenced by add_supported_header(), handle_request_invite(), handle_response_invite(), and transmit_invite().

25048 {
25049    if (!p->stimer)
25050       sip_st_alloc(p);
25051 
25052    if (p->stimer->st_cached_mode != SESSION_TIMER_MODE_INVALID)
25053       return p->stimer->st_cached_mode;
25054 
25055    if (p->relatedpeer) {
25056       p->stimer->st_cached_mode = p->relatedpeer->stimer.st_mode_oper;
25057       return p->stimer->st_cached_mode;
25058    }
25059 
25060    p->stimer->st_cached_mode = global_st_mode;
25061    return global_st_mode;
25062 }

enum st_refresher st_get_refresher ( struct sip_pvt *  p  )  [static]

Get the entity (UAC or UAS) that's acting as the session-timer refresher.

Parameters:
p pointer to the SIP dialog

Definition at line 25029 of file chan_sip.c.

References global_st_refresher.

Referenced by handle_request_invite().

25030 {
25031    if (p->stimer->st_cached_ref != SESSION_TIMER_REFRESHER_AUTO)
25032       return p->stimer->st_cached_ref;
25033 
25034    if (p->relatedpeer) {
25035       p->stimer->st_cached_ref = p->relatedpeer->stimer.st_ref;
25036       return p->stimer->st_cached_ref;
25037    }
25038    
25039    p->stimer->st_cached_ref = global_st_refresher;
25040    return global_st_refresher;
25041 }

int st_get_se ( struct sip_pvt *  p,
int  max 
) [static]

Get Max or Min SE (session timer expiry).

Parameters:
p pointer to the SIP dialog
max if true, get max se, otherwise min se

Definition at line 25000 of file chan_sip.c.

References global_max_se, global_min_se, and TRUE.

Referenced by handle_request_invite(), reqprep(), and transmit_invite().

25001 {
25002    if (max == TRUE) {
25003       if (p->stimer->st_cached_max_se) {
25004          return  p->stimer->st_cached_max_se;
25005       }
25006       if (p->relatedpeer) {
25007          p->stimer->st_cached_max_se = p->relatedpeer->stimer.st_max_se;
25008          return (p->stimer->st_cached_max_se);
25009       }
25010       p->stimer->st_cached_max_se = global_max_se;
25011       return (p->stimer->st_cached_max_se);
25012    } 
25013    /* Find Min SE timer */
25014    if (p->stimer->st_cached_min_se) {
25015       return p->stimer->st_cached_min_se;
25016    } 
25017    if (p->relatedpeer) {
25018       p->stimer->st_cached_min_se = p->relatedpeer->stimer.st_min_se;
25019       return (p->stimer->st_cached_min_se);
25020    }
25021    p->stimer->st_cached_min_se = global_min_se;
25022    return (p->stimer->st_cached_min_se);
25023 }

static void start_session_timer ( struct sip_pvt *  p  )  [static]

Session-Timers: Start session timer.

Definition at line 24797 of file chan_sip.c.

References ast_debug, ast_log(), ast_sched_add(), LOG_ERROR, LOG_WARNING, and proc_session_timer().

Referenced by handle_request_invite(), handle_response_invite(), and restart_session_timer().

24798 {
24799    if (!p->stimer) {
24800       ast_log(LOG_WARNING, "Null stimer in start_session_timer - %s\n", p->callid);
24801       return;
24802    }
24803 
24804    p->stimer->st_schedid  = ast_sched_add(sched, p->stimer->st_interval * 1000 / 2, proc_session_timer,
24805          dialog_ref(p, "adding session timer ref"));
24806    if (p->stimer->st_schedid < 0) {
24807       dialog_unref(p, "removing session timer ref");
24808       ast_log(LOG_ERROR, "ast_sched_add failed.\n");
24809    }
24810    ast_debug(2, "Session timer started: %d - %s\n", p->stimer->st_schedid, p->callid);
24811 }

static void state_notify_build_xml ( int  state,
int  full,
const char *  exten,
const char *  context,
struct ast_str **  tmp,
struct sip_pvt *  p,
int  subscribed,
const char *  mfrom,
const char *  mto 
) [static]

Builds XML portion of NOTIFY messages for presence or dialog updates.

Definition at line 11859 of file chan_sip.c.

References ast_channel_callback(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), AST_MAX_EXTENSION, ast_str_append(), ast_strdupa, ast_channel::caller, cid_num, find_calling_channel(), ast_party_caller::id, ast_party_id::name, NONE, ast_party_id::number, S_COR, sip_cfg, ast_party_name::str, ast_party_number::str, strsep(), ast_party_name::valid, and ast_party_number::valid.

Referenced by transmit_state_notify().

11860 {
11861    enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
11862    const char *statestring = "terminated";
11863    const char *pidfstate = "--";
11864    const char *pidfnote= "Ready";
11865    char hint[AST_MAX_EXTENSION];
11866 
11867    switch (state) {
11868    case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
11869       statestring = (sip_cfg.notifyringing) ? "early" : "confirmed";
11870       local_state = NOTIFY_INUSE;
11871       pidfstate = "busy";
11872       pidfnote = "Ringing";
11873       break;
11874    case AST_EXTENSION_RINGING:
11875       statestring = "early";
11876       local_state = NOTIFY_INUSE;
11877       pidfstate = "busy";
11878       pidfnote = "Ringing";
11879       break;
11880    case AST_EXTENSION_INUSE:
11881       statestring = "confirmed";
11882       local_state = NOTIFY_INUSE;
11883       pidfstate = "busy";
11884       pidfnote = "On the phone";
11885       break;
11886    case AST_EXTENSION_BUSY:
11887       statestring = "confirmed";
11888       local_state = NOTIFY_CLOSED;
11889       pidfstate = "busy";
11890       pidfnote = "On the phone";
11891       break;
11892    case AST_EXTENSION_UNAVAILABLE:
11893       statestring = "terminated";
11894       local_state = NOTIFY_CLOSED;
11895       pidfstate = "away";
11896       pidfnote = "Unavailable";
11897       break;
11898    case AST_EXTENSION_ONHOLD:
11899       statestring = "confirmed";
11900       local_state = NOTIFY_CLOSED;
11901       pidfstate = "busy";
11902       pidfnote = "On hold";
11903       break;
11904    case AST_EXTENSION_NOT_INUSE:
11905    default:
11906       /* Default setting */
11907       break;
11908    }
11909 
11910    /* Check which device/devices we are watching  and if they are registered */
11911    if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten)) {
11912       char *hint2 = hint, *individual_hint = NULL;
11913       int hint_count = 0, unavailable_count = 0;
11914 
11915       while ((individual_hint = strsep(&hint2, "&"))) {
11916          hint_count++;
11917 
11918          if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE)
11919             unavailable_count++;
11920       }
11921 
11922       /* If none of the hinted devices are registered, we will
11923        * override notification and show no availability.
11924        */
11925       if (hint_count > 0 && hint_count == unavailable_count) {
11926          local_state = NOTIFY_CLOSED;
11927          pidfstate = "away";
11928          pidfnote = "Not online";
11929       }
11930    }
11931 
11932    switch (subscribed) {
11933    case XPIDF_XML:
11934    case CPIM_PIDF_XML:
11935       ast_str_append(tmp, 0,
11936          "<?xml version=\"1.0\"?>\n"
11937          "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
11938          "<presence>\n");
11939       ast_str_append(tmp, 0, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
11940       ast_str_append(tmp, 0, "<atom id=\"%s\">\n", exten);
11941       ast_str_append(tmp, 0, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
11942       ast_str_append(tmp, 0, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
11943       ast_str_append(tmp, 0, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
11944       ast_str_append(tmp, 0, "</address>\n</atom>\n</presence>\n");
11945       break;
11946    case PIDF_XML: /* Eyebeam supports this format */
11947       ast_str_append(tmp, 0,
11948          "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
11949          "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \nxmlns:pp=\"urn:ietf:params:xml:ns:pidf:person\"\nxmlns:es=\"urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status\"\nxmlns:ep=\"urn:ietf:params:xml:ns:pidf:rpid:rpid-person\"\nentity=\"%s\">\n", mfrom);
11950       ast_str_append(tmp, 0, "<pp:person><status>\n");
11951       if (pidfstate[0] != '-') {
11952          ast_str_append(tmp, 0, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
11953       }
11954       ast_str_append(tmp, 0, "</status></pp:person>\n");
11955       ast_str_append(tmp, 0, "<note>%s</note>\n", pidfnote); /* Note */
11956       ast_str_append(tmp, 0, "<tuple id=\"%s\">\n", exten); /* Tuple start */
11957       ast_str_append(tmp, 0, "<contact priority=\"1\">%s</contact>\n", mto);
11958       if (pidfstate[0] == 'b') /* Busy? Still open ... */
11959          ast_str_append(tmp, 0, "<status><basic>open</basic></status>\n");
11960       else
11961          ast_str_append(tmp, 0, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
11962       ast_str_append(tmp, 0, "</tuple>\n</presence>\n");
11963       break;
11964    case DIALOG_INFO_XML: /* SNOM subscribes in this format */
11965       ast_str_append(tmp, 0, "<?xml version=\"1.0\"?>");
11966       ast_str_append(tmp, 0, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">", p->dialogver, full ? "full" : "partial", mto);
11967       if ((state & AST_EXTENSION_RINGING) && sip_cfg.notifyringing) {
11968          const char *local_display = exten;
11969          char *local_target = ast_strdupa(mto);
11970 
11971          /* There are some limitations to how this works.  The primary one is that the
11972             callee must be dialing the same extension that is being monitored.  Simply dialing
11973             the hint'd device is not sufficient. */
11974          if (sip_cfg.notifycid) {
11975             struct ast_channel *caller;
11976 
11977             if ((caller = ast_channel_callback(find_calling_channel, NULL, p, 0))) {
11978                char *cid_num;
11979                int need;
11980 
11981                ast_channel_lock(caller);
11982                cid_num = S_COR(caller->caller.id.number.valid,
11983                   caller->caller.id.number.str, "");
11984                need = strlen(cid_num) + strlen(p->fromdomain) + sizeof("sip:@");
11985                local_target = alloca(need);
11986                snprintf(local_target, need, "sip:%s@%s", cid_num, p->fromdomain);
11987                local_display = ast_strdupa(S_COR(caller->caller.id.name.valid,
11988                   caller->caller.id.name.str, ""));
11989                ast_channel_unlock(caller);
11990                caller = ast_channel_unref(caller);
11991             }
11992 
11993             /* We create a fake call-id which the phone will send back in an INVITE
11994                Replaces header which we can grab and do some magic with. */
11995             if (sip_cfg.pedanticsipchecking) {
11996                ast_str_append(tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" local-tag=\"%s\" remote-tag=\"%s\" direction=\"recipient\">\n",
11997                   exten, p->callid, p->theirtag, p->tag);
11998             } else {
11999                ast_str_append(tmp, 0, "<dialog id=\"%s\" call-id=\"pickup-%s\" direction=\"recipient\">\n",
12000                   exten, p->callid);
12001             }
12002             ast_str_append(tmp, 0,
12003                   "<remote>\n"
12004                   /* See the limitations of this above.  Luckily the phone seems to still be
12005                      happy when these values are not correct. */
12006                   "<identity display=\"%s\">%s</identity>\n"
12007                   "<target uri=\"%s\"/>\n"
12008                   "</remote>\n"
12009                   "<local>\n"
12010                   "<identity>%s</identity>\n"
12011                   "<target uri=\"%s\"/>\n"
12012                   "</local>\n",
12013                   local_display, local_target, local_target, mto, mto);
12014          } else {
12015             ast_str_append(tmp, 0, "<dialog id=\"%s\" direction=\"recipient\">\n", exten);
12016          }
12017 
12018       } else {
12019          ast_str_append(tmp, 0, "<dialog id=\"%s\">", exten);
12020       }
12021       ast_str_append(tmp, 0, "<state>%s</state>\n", statestring);
12022       if (state == AST_EXTENSION_ONHOLD) {
12023             ast_str_append(tmp, 0, "<local>\n<target uri=\"%s\">\n"
12024                                              "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n"
12025                                              "</target>\n</local>\n", mto);
12026       }
12027       ast_str_append(tmp, 0, "</dialog>\n</dialog-info>\n");
12028       break;
12029    case NONE:
12030    default:
12031       break;
12032    }
12033 }

static const char* stmode2str ( enum st_mode  m  )  [static]

Definition at line 15611 of file chan_sip.c.

References map_x_s(), and stmodes.

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

15612 {
15613    return map_x_s(stmodes, m, "Unknown");
15614 }

static void stop_media_flows ( struct sip_pvt *  p  )  [static]

Immediately stop RTP, VRTP and UDPTL as applicable.

Definition at line 19867 of file chan_sip.c.

References ast_rtp_instance_stop(), and ast_udptl_stop().

Referenced by handle_request_bye(), handle_request_cancel(), handle_response(), and sip_hangup().

19868 {
19869    /* Immediately stop RTP, VRTP and UDPTL as applicable */
19870    if (p->rtp)
19871       ast_rtp_instance_stop(p->rtp);
19872    if (p->vrtp)
19873       ast_rtp_instance_stop(p->vrtp);
19874    if (p->trtp)
19875       ast_rtp_instance_stop(p->trtp);
19876    if (p->udptl)
19877       ast_udptl_stop(p->udptl);
19878 }

static void stop_session_timer ( struct sip_pvt *  p  )  [static]

Session-Timers: Stop session timer.

Definition at line 24780 of file chan_sip.c.

References ast_debug, ast_log(), AST_SCHED_DEL_UNREF, FALSE, LOG_WARNING, and TRUE.

Referenced by handle_request_bye(), proc_session_timer(), sip_hangup(), and sip_scheddestroy().

24781 {
24782    if (!p->stimer) {
24783       ast_log(LOG_WARNING, "Null stimer in stop_session_timer - %s\n", p->callid);
24784       return;
24785    }
24786 
24787    if (p->stimer->st_active == TRUE) {
24788       p->stimer->st_active = FALSE;
24789       AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
24790             dialog_unref(p, "removing session timer ref"));
24791       ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
24792    }
24793 }

static int str2dtmfmode ( const char *  str  )  [static]

maps a string to dtmfmode, returns -1 on error

Definition at line 16123 of file chan_sip.c.

References dtmfstr, and map_s_x().

16124 {
16125    return map_s_x(dtmfstr, str, -1);
16126 }

static enum st_mode str2stmode ( const char *  s  )  [static]

Definition at line 15616 of file chan_sip.c.

References map_s_x(), and stmodes.

Referenced by build_peer().

15617 {
15618    return map_s_x(stmodes, s, -1);
15619 }

static enum st_refresher str2strefresher ( const char *  s  )  [static]

Definition at line 15634 of file chan_sip.c.

References map_s_x(), and strefreshers.

Referenced by build_peer().

15635 {
15636    return map_s_x(strefreshers, s, -1);
15637 }

static const char * strefresher2str ( enum st_refresher  r  )  [static]

Definition at line 15629 of file chan_sip.c.

References map_x_s(), and strefreshers.

Referenced by _sip_show_peer(), reqprep(), respprep(), sip_show_channel(), sip_show_settings(), and sip_show_user().

15630 {
15631    return map_x_s(strefreshers, r, "Unknown");
15632 }

static const char * subscription_type2str ( enum subscriptiontype  subtype  )  [static]

Show subscription type in string format.

Definition at line 17385 of file chan_sip.c.

References ARRAY_LEN, subscription_types, cfsubscription_types::text, and type.

Referenced by show_channels_cb(), and sip_show_channel().

17386 {
17387    int i;
17388 
17389    for (i = 1; i < ARRAY_LEN(subscription_types); i++) {
17390       if (subscription_types[i].type == subtype) {
17391          return subscription_types[i].text;
17392       }
17393    }
17394    return subscription_types[0].text;
17395 }

static unsigned int t38_get_rate ( enum ast_control_t38_rate  rate  )  [static]

Get Max T.38 Transmission rate from T38 capabilities.

Definition at line 10534 of file chan_sip.c.

References AST_T38_RATE_12000, AST_T38_RATE_14400, AST_T38_RATE_2400, AST_T38_RATE_4800, AST_T38_RATE_7200, and AST_T38_RATE_9600.

Referenced by add_sdp().

10535 {
10536    switch (rate) {
10537    case AST_T38_RATE_2400:
10538       return 2400;
10539    case AST_T38_RATE_4800:
10540       return 4800;
10541    case AST_T38_RATE_7200:
10542       return 7200;
10543    case AST_T38_RATE_9600:
10544       return 9600;
10545    case AST_T38_RATE_12000:
10546       return 12000;
10547    case AST_T38_RATE_14400:
10548       return 14400;
10549    default:
10550       return 0;
10551    }
10552 }

static void tcptls_packet_destructor ( void *  obj  )  [static]

Definition at line 2313 of file chan_sip.c.

References ast_free.

Referenced by sip_tcptls_write().

02314 {
02315    struct tcptls_packet *packet = obj;
02316 
02317    ast_free(packet->data);
02318 }

static struct sip_peer * temp_peer ( const char *  name  )  [static]

Create temporary peer (used in autocreatepeer mode).

Definition at line 25948 of file chan_sip.c.

References ao2_t_alloc, ao2_t_ref, apeerobjs, ast_atomic_fetchadd_int(), ast_cc_config_params_init, ast_copy_string(), ast_string_field_init, default_prefs, reg_source_db(), set_peer_defaults(), sip_destroy_peer_fn(), and TRUE.

Referenced by register_verify().

25949 {
25950    struct sip_peer *peer;
25951 
25952    if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct")))
25953       return NULL;
25954 
25955    if (ast_string_field_init(peer, 512)) {
25956       ao2_t_ref(peer, -1, "failed to string_field_init, drop peer");
25957       return NULL;
25958    }
25959    
25960    if (!(peer->cc_params = ast_cc_config_params_init())) {
25961       ao2_t_ref(peer, -1, "failed to allocate cc_params for peer");
25962       return NULL;
25963    }
25964 
25965    ast_atomic_fetchadd_int(&apeerobjs, 1);
25966    set_peer_defaults(peer);
25967 
25968    ast_copy_string(peer->name, name, sizeof(peer->name));
25969 
25970    peer->selfdestruct = TRUE;
25971    peer->host_dynamic = TRUE;
25972    peer->prefs = default_prefs;
25973    reg_source_db(peer);
25974 
25975    return peer;
25976 }

static void temp_pvt_cleanup ( void *   )  [static]

Definition at line 9996 of file chan_sip.c.

References ast_free, and ast_string_field_free_memory.

09997 {
09998    struct sip_pvt *p = data;
09999 
10000    ast_string_field_free_memory(p);
10001 
10002    ast_free(data);
10003 }

static int temp_pvt_init ( void *   )  [static]

Definition at line 9988 of file chan_sip.c.

References ast_string_field_init.

09989 {
09990    struct sip_pvt *p = data;
09991 
09992    p->do_history = 0;   /* XXX do we need it ? isn't already all 0 ? */
09993    return ast_string_field_init(p, 512);
09994 }

static char* terminate_uri ( char *  uri  )  [static]

Terminate the uri at the first ';' or space. Technically we should ignore escaped space per RFC3261 (19.1.1 etc) but don't do it for the time being. Remember the uri format is: (User-parameters was added after RFC 3261)

 *
 *	sip:user:password;user-parameters@host:port;uri-parameters?headers
 *	sips:user:password;user-parameters@host:port;uri-parameters?headers
 *
 *
Todo:
As this function does not support user-parameters, it's considered broken and needs fixing.

Definition at line 13983 of file chan_sip.c.

Referenced by check_user_full(), and register_verify().

13984 {
13985    char *t = uri;
13986    while (*t && *t > ' ' && *t != ';') {
13987       t++;
13988    }
13989    *t = '\0';
13990    return uri;
13991 }

static int threadinfo_locate_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 24335 of file chan_sip.c.

References ast_sockaddr_cmp(), CMP_MATCH, and CMP_STOP.

Referenced by sip_tcp_locate().

24336 {
24337    struct sip_threadinfo *th = obj;
24338    struct ast_sockaddr *s = arg;
24339 
24340    if (!ast_sockaddr_cmp(s, &th->tcptls_session->remote_address)) {
24341       return CMP_MATCH | CMP_STOP;
24342    }
24343 
24344    return 0;
24345 }

static int threadt_cmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 28552 of file chan_sip.c.

References CMP_MATCH, and CMP_STOP.

Referenced by load_module().

28553 {
28554    struct sip_threadinfo *th = obj, *th2 = arg;
28555 
28556    return (th->tcptls_session == th2->tcptls_session) ? CMP_MATCH | CMP_STOP : 0;
28557 }

static int threadt_hash_cb ( const void *  obj,
const int  flags 
) [static]

Definition at line 28545 of file chan_sip.c.

References ast_sockaddr_hash().

Referenced by load_module().

28546 {
28547    const struct sip_threadinfo *th = obj;
28548 
28549    return ast_sockaddr_hash(&th->tcptls_session->remote_address);
28550 }

static char * transfermode2str ( enum transfermodes  mode  )  const [static]

Convert transfer mode to text string.

Definition at line 15589 of file chan_sip.c.

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

15590 {
15591    if (mode == TRANSFER_OPENFORALL)
15592       return "open";
15593    else if (mode == TRANSFER_CLOSED)
15594       return "closed";
15595    return "strict";
15596 }

static int transmit_cc_notify ( struct ast_cc_agent *  agent,
struct sip_pvt *  subscription,
enum sip_cc_notify_state  state 
) [static]

Definition at line 12035 of file chan_sip.c.

References add_content(), add_header(), ast_log(), generate_uri(), LOG_WARNING, ast_cc_agent::private_data, reqprep(), send_request(), sip_cc_notify_state_map, state_string, and TRUE.

Referenced by sip_cc_agent_recall(), and sip_cc_agent_respond().

12036 {
12037    struct sip_request req;
12038    struct sip_cc_agent_pvt *agent_pvt = agent->private_data;
12039    char uri[SIPBUFSIZE];
12040    char state_str[64];
12041 
12042    if (state < CC_QUEUED || state > CC_READY) {
12043       ast_log(LOG_WARNING, "Invalid state provided for transmit_cc_notify (%d)\n", state);
12044       return -1;
12045    }
12046 
12047    reqprep(&req, subscription, SIP_NOTIFY, 0, TRUE);
12048    snprintf(state_str, sizeof(state_str), "%s\r\n", sip_cc_notify_state_map[state].state_string);
12049    add_header(&req, "Event", "call-completion");
12050    add_header(&req, "Content-Type", "application/call-completion");
12051    if (state == CC_READY) {
12052       generate_uri(subscription, agent_pvt->notify_uri, sizeof(agent_pvt->notify_uri));
12053       snprintf(uri, sizeof(uri) - 1, "cc-URI: %s\r\n", agent_pvt->notify_uri);
12054    }
12055    add_content(&req, state_str);
12056    if (state == CC_READY) {
12057       add_content(&req, uri);
12058    }
12059    return send_request(subscription, &req, XMIT_RELIABLE, subscription->ocseq);
12060 }

static void transmit_fake_auth_response ( struct sip_pvt *  p,
int  sipmethod,
struct sip_request *  req,
enum xmittype  reliable 
) [static]

Send a fake 401 Unauthorized response when the administrator wants to hide the names of local devices from fishers.

Definition at line 13877 of file chan_sip.c.

References AST_DYNSTR_BUILD_FAILED, ast_skip_blanks(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), check_auth_buf, CHECK_AUTH_BUF_INITLEN, get_header(), set_nonce_randdata(), sip_scheddestroy(), strsep(), transmit_response(), and transmit_response_with_auth().

Referenced by handle_request_invite(), handle_request_options(), handle_request_publish(), handle_request_subscribe(), and register_verify().

13878 {
13879    /* We have to emulate EXACTLY what we'd get with a good peer
13880     * and a bad password, or else we leak information. */
13881    const char *response = "407 Proxy Authentication Required";
13882    const char *reqheader = "Proxy-Authorization";
13883    const char *respheader = "Proxy-Authenticate";
13884    const char *authtoken;
13885    struct ast_str *buf;
13886    char *c;
13887 
13888    /* table of recognised keywords, and their value in the digest */
13889    enum keys { K_NONCE, K_LAST };
13890    struct x {
13891       const char *key;
13892       const char *s;
13893    } *i, keys[] = {
13894       [K_NONCE] = { "nonce=", "" },
13895       [K_LAST] = { NULL, NULL}
13896    };
13897 
13898    if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
13899       response = "401 Unauthorized";
13900       reqheader = "Authorization";
13901       respheader = "WWW-Authenticate";
13902    }
13903    authtoken = get_header(req, reqheader);
13904    if (req->ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
13905       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
13906        * information */
13907       transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0);
13908       /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
13909       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13910       return;
13911    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
13912       /* We have no auth, so issue challenge and request authentication */
13913       set_nonce_randdata(p, 1);
13914       transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0);
13915       /* Schedule auto destroy in 32 seconds */
13916       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13917       return;
13918    }
13919 
13920    if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) {
13921       transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
13922       return;
13923    }
13924 
13925    /* Make a copy of the response and parse it */
13926    if (ast_str_set(&buf, 0, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) {
13927       transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
13928       return;
13929    }
13930 
13931    c = buf->str;
13932 
13933    while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */
13934       for (i = keys; i->key != NULL; i++) {
13935          const char *separator = ",";  /* default */
13936 
13937          if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
13938             continue;
13939          }
13940          /* Found. Skip keyword, take text in quotes or up to the separator. */
13941          c += strlen(i->key);
13942          if (*c == '"') { /* in quotes. Skip first and look for last */
13943             c++;
13944             separator = "\"";
13945          }
13946          i->s = c;
13947          strsep(&c, separator);
13948          break;
13949       }
13950       if (i->key == NULL) { /* not found, jump after space or comma */
13951          strsep(&c, " ,");
13952       }
13953    }
13954 
13955    /* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
13956    if (strcasecmp(p->randdata, keys[K_NONCE].s)) {
13957       if (!req->ignore) {
13958          set_nonce_randdata(p, 1);
13959       }
13960       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
13961 
13962       /* Schedule auto destroy in 32 seconds */
13963       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13964    } else {
13965       transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
13966    }
13967 }

static int transmit_info_with_aoc ( struct sip_pvt *  p,
struct ast_aoc_decoded *  decoded 
) [static]

Send SIP INFO advice of charge message.

Definition at line 12830 of file chan_sip.c.

References add_header(), ast_aoc_unit_entry::amount, AST_AOC_CHARGE_CURRENCY, AST_AOC_CHARGE_FREE, AST_AOC_CHARGE_UNIT, AST_AOC_D, AST_AOC_E, ast_aoc_get_charge_type(), ast_aoc_get_currency_amount(), ast_aoc_get_currency_multiplier_decimal(), ast_aoc_get_currency_name(), ast_aoc_get_msg_type(), ast_aoc_get_unit_info(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_strlen_zero(), reqprep(), send_request(), and str.

Referenced by sip_indicate().

12831 {
12832    struct sip_request req;
12833    struct ast_str *str = ast_str_alloca(512);
12834    const struct ast_aoc_unit_entry *unit_entry = ast_aoc_get_unit_info(decoded, 0);
12835    enum ast_aoc_charge_type charging = ast_aoc_get_charge_type(decoded);
12836 
12837    reqprep(&req, p, SIP_INFO, 0, 1);
12838 
12839    if (ast_aoc_get_msg_type(decoded) == AST_AOC_D) {
12840       ast_str_append(&str, 0, "type=active;");
12841    } else if (ast_aoc_get_msg_type(decoded) == AST_AOC_E) {
12842       ast_str_append(&str, 0, "type=terminated;");
12843    } else {
12844       /* unsupported message type */
12845       return -1;
12846    }
12847 
12848    switch (charging) {
12849    case AST_AOC_CHARGE_FREE:
12850       ast_str_append(&str, 0, "free-of-charge;");
12851       break;
12852    case AST_AOC_CHARGE_CURRENCY:
12853       ast_str_append(&str, 0, "charging;");
12854       ast_str_append(&str, 0, "charging-info=currency;");
12855       ast_str_append(&str, 0, "amount=%u;", ast_aoc_get_currency_amount(decoded));
12856       ast_str_append(&str, 0, "multiplier=%s;", ast_aoc_get_currency_multiplier_decimal(decoded));
12857       if (!ast_strlen_zero(ast_aoc_get_currency_name(decoded))) {
12858          ast_str_append(&str, 0, "currency=%s;", ast_aoc_get_currency_name(decoded));
12859       }
12860       break;
12861    case AST_AOC_CHARGE_UNIT:
12862       ast_str_append(&str, 0, "charging;");
12863       ast_str_append(&str, 0, "charging-info=pulse;");
12864       if (unit_entry) {
12865          ast_str_append(&str, 0, "recorded-units=%u;", unit_entry->amount);
12866       }
12867       break;
12868    default:
12869       ast_str_append(&str, 0, "not-available;");
12870    };
12871 
12872    add_header(&req, "AOC", ast_str_buffer(str));
12873 
12874    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
12875 }

static int transmit_info_with_digit ( struct sip_pvt *  p,
const char  digit,
unsigned int  duration 
) [static]

Send SIP INFO dtmf message, see Cisco documentation on cisco.com.

Definition at line 12878 of file chan_sip.c.

References add_digit(), ast_test_flag, reqprep(), and send_request().

Referenced by sip_senddigit_end().

12879 {
12880    struct sip_request req;
12881    
12882    reqprep(&req, p, SIP_INFO, 0, 1);
12883    add_digit(&req, digit, duration, (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO));
12884    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
12885 }

static int transmit_info_with_vidupdate ( struct sip_pvt *  p  )  [static]

Send SIP INFO with video update request.

Definition at line 12888 of file chan_sip.c.

References add_vidupdate(), reqprep(), and send_request().

Referenced by sip_indicate().

12889 {
12890    struct sip_request req;
12891    
12892    reqprep(&req, p, SIP_INFO, 0, 1);
12893    add_vidupdate(&req);
12894    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
12895 }

static int transmit_invite ( struct sip_pvt *  p,
int  sipmethod,
int  sdp,
int  init,
const char *const   explicit_uri 
) [static]

Build REFER/INVITE/OPTIONS/SUBSCRIBE message and transmit it.

Parameters:
p sip_pvt structure
sipmethod 
sdp unknown
init 0 = Prepare request within dialog, 1= prepare request, new branch, 2= prepare new request and new dialog. do_proxy_auth calls this with init!=2
explicit_uri 

Definition at line 11580 of file chan_sip.c.

References add_content(), add_diversion_header(), add_header(), add_rpid(), add_sdp(), add_supported_header(), append_date(), ast_channel_lock, ast_channel_unlock, ast_debug, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_skip_blanks(), ast_str_buffer(), ast_str_strlen(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_var_name(), ast_var_value(), build_via(), ast_var_t::entries, FALSE, initialize_initreq(), initreqprep(), LOG_WARNING, reqprep(), send_request(), st_get_mode(), st_get_se(), TRUE, try_suggested_sip_codec(), var, and ast_channel::varshead.

Referenced by __sip_subscribe_mwi_do(), cc_handle_publish_error(), do_proxy_auth(), proc_422_rsp(), sip_call(), sip_cc_monitor_request_cc(), sip_monitor_instance_destructor(), sip_poke_peer(), and transmit_publish().

11581 {
11582    struct sip_request req;
11583    struct ast_variable *var;
11584    
11585    req.method = sipmethod;
11586    if (init) {/* Bump branch even on initial requests */
11587       p->branch ^= ast_random();
11588       p->invite_branch = p->branch;
11589       build_via(p);
11590    }
11591    if (init > 1) {
11592       initreqprep(&req, p, sipmethod, explicit_uri);
11593    } else {
11594       /* If init=1, we should not generate a new branch. If it's 0, we need a new branch. */
11595       reqprep(&req, p, sipmethod, 0, init ? 0 : 1);
11596    }
11597       
11598    if (p->options && p->options->auth) {
11599       add_header(&req, p->options->authheader, p->options->auth);
11600    }
11601    append_date(&req);
11602    if (sipmethod == SIP_REFER) { /* Call transfer */
11603       if (p->refer) {
11604          char buf[SIPBUFSIZE];
11605          if (!ast_strlen_zero(p->refer->refer_to)) {
11606             add_header(&req, "Refer-To", p->refer->refer_to);
11607          }
11608          if (!ast_strlen_zero(p->refer->referred_by)) {
11609             snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by);
11610             add_header(&req, "Referred-By", buf);
11611          }
11612       }
11613    } else if (sipmethod == SIP_SUBSCRIBE) {
11614       char buf[SIPBUFSIZE];
11615       if (p->subscribed == MWI_NOTIFICATION) {
11616          add_header(&req, "Event", "message-summary");
11617          add_header(&req, "Accept", "application/simple-message-summary");
11618       } else if (p->subscribed == CALL_COMPLETION) {
11619          add_header(&req, "Event", "call-completion");
11620          add_header(&req, "Accept", "application/call-completion");
11621       }
11622       snprintf(buf, sizeof(buf), "%d", p->expiry);
11623       add_header(&req, "Expires", buf);
11624    }
11625 
11626    /* This new INVITE is part of an attended transfer. Make sure that the
11627    other end knows and replace the current call with this new call */
11628    if (p->options && !ast_strlen_zero(p->options->replaces)) {
11629       add_header(&req, "Replaces", p->options->replaces);
11630       add_header(&req, "Require", "replaces");
11631    }
11632 
11633    /* Add Session-Timers related headers */
11634    if (st_get_mode(p) == SESSION_TIMER_MODE_ORIGINATE) {
11635       char i2astr[10];
11636 
11637       if (!p->stimer->st_interval) {
11638          p->stimer->st_interval = st_get_se(p, TRUE);
11639       }
11640 
11641       p->stimer->st_active = TRUE;
11642       
11643       snprintf(i2astr, sizeof(i2astr), "%d", p->stimer->st_interval);
11644       add_header(&req, "Session-Expires", i2astr);
11645       snprintf(i2astr, sizeof(i2astr), "%d", st_get_se(p, FALSE));
11646       add_header(&req, "Min-SE", i2astr);
11647    }
11648 
11649    add_header(&req, "Allow", ALLOWED_METHODS);
11650    add_supported_header(p, &req);
11651 
11652    if (p->options && p->options->addsipheaders && p->owner) {
11653       struct ast_channel *chan = p->owner; /* The owner channel */
11654       struct varshead *headp;
11655    
11656       ast_channel_lock(chan);
11657 
11658       headp = &chan->varshead;
11659 
11660       if (!headp) {
11661          ast_log(LOG_WARNING, "No Headp for the channel...ooops!\n");
11662       } else {
11663          const struct ast_var_t *current;
11664          AST_LIST_TRAVERSE(headp, current, entries) {
11665             /* SIPADDHEADER: Add SIP header to outgoing call */
11666             if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
11667                char *content, *end;
11668                const char *header = ast_var_value(current);
11669                char *headdup = ast_strdupa(header);
11670 
11671                /* Strip of the starting " (if it's there) */
11672                if (*headdup == '"') {
11673                   headdup++;
11674                }
11675                if ((content = strchr(headdup, ':'))) {
11676                   *content++ = '\0';
11677                   content = ast_skip_blanks(content); /* Skip white space */
11678                   /* Strip the ending " (if it's there) */
11679                   end = content + strlen(content) -1; 
11680                   if (*end == '"') {
11681                      *end = '\0';
11682                   }
11683                
11684                   add_header(&req, headdup, content);
11685                   if (sipdebug) {
11686                      ast_debug(1, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content);
11687                   }
11688                }
11689             }
11690          }
11691       }
11692 
11693       ast_channel_unlock(chan);
11694    }
11695    if ((sipmethod == SIP_INVITE || sipmethod == SIP_UPDATE) && ast_test_flag(&p->flags[0], SIP_SENDRPID))
11696       add_rpid(&req, p);
11697    if (sipmethod == SIP_INVITE) {
11698       add_diversion_header(&req, p);
11699    }
11700    if (sdp) {
11701       memset(p->offered_media, 0, sizeof(p->offered_media));
11702       if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) {
11703          ast_debug(1, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
11704          add_sdp(&req, p, FALSE, FALSE, TRUE);
11705       } else if (p->rtp) {
11706          try_suggested_sip_codec(p);
11707          add_sdp(&req, p, FALSE, TRUE, FALSE);
11708       }
11709    } else if (p->notify) {
11710       for (var = p->notify->headers; var; var = var->next) {
11711          add_header(&req, var->name, var->value);
11712       }
11713       if (ast_str_strlen(p->notify->content)) {
11714          add_content(&req, ast_str_buffer(p->notify->content));
11715       }
11716    } else if (sipmethod == SIP_PUBLISH) {
11717       char expires[SIPBUFSIZE];
11718 
11719       switch (p->epa_entry->static_data->event) {
11720       case CALL_COMPLETION:
11721          snprintf(expires, sizeof(expires), "%d", p->expiry);
11722          add_header(&req, "Event", "call-completion");
11723          add_header(&req, "Expires", expires);
11724          if (p->epa_entry->publish_type != SIP_PUBLISH_INITIAL) {
11725             add_header(&req, "SIP-If-Match", p->epa_entry->entity_tag);
11726          }
11727 
11728          if (!ast_strlen_zero(p->epa_entry->body)) {
11729             add_header(&req, "Content-Type", "application/pidf+xml");
11730             add_content(&req, p->epa_entry->body);
11731          }
11732       default:
11733          break;
11734       }
11735    }
11736 
11737    if (!p->initreq.headers || init > 2) {
11738       initialize_initreq(p, &req);
11739    }
11740    if (sipmethod == SIP_INVITE || sipmethod == SIP_SUBSCRIBE) {
11741       p->lastinvite = p->ocseq;
11742    }
11743    return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
11744 }

static int transmit_message_with_text ( struct sip_pvt *  p,
const char *  text 
) [static]

Transmit text with SIP MESSAGE method.

Definition at line 12720 of file chan_sip.c.

References add_text(), reqprep(), and send_request().

Referenced by sip_park_thread(), and sip_sendtext().

12721 {
12722    struct sip_request req;
12723    
12724    reqprep(&req, p, SIP_MESSAGE, 0, 1);
12725    add_text(&req, text);
12726    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
12727 }

static int transmit_notify_with_mwi ( struct sip_pvt *  p,
int  newmsgs,
int  oldmsgs,
const char *  vmexten 
) [static]

Notify user of messages waiting in voicemail (RFC3842).

Note:
- Notification only works for registered peers with mailbox= definitions in sip.conf
  • We use the SIP Event package message-summary MIME type defaults to "application/simple-message-summary";

Definition at line 12152 of file chan_sip.c.

References add_content(), add_header(), ast_sockaddr_port, ast_sockaddr_stringify_host(), ast_str_alloca, ast_str_append(), ast_test_flag, default_notifymime, default_vmexten, exten, get_transport(), initialize_initreq(), initreqprep(), ourport, S_OR, send_request(), and sip_standard_port().

Referenced by sip_send_mwi_to_peer().

12153 {
12154    struct sip_request req;
12155    struct ast_str *out = ast_str_alloca(500);
12156    int ourport = (p->fromdomainport) ? p->fromdomainport : ast_sockaddr_port(&p->ourip);
12157    const char *domain = S_OR(p->fromdomain, ast_sockaddr_stringify_host(&p->ourip));
12158    const char *exten = S_OR(vmexten, default_vmexten);
12159 
12160    initreqprep(&req, p, SIP_NOTIFY, NULL);
12161    add_header(&req, "Event", "message-summary");
12162    add_header(&req, "Content-Type", default_notifymime);
12163    ast_str_append(&out, 0, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
12164 
12165 
12166    if (!sip_standard_port(p->socket.type, ourport)) {
12167       if (p->socket.type == SIP_TRANSPORT_UDP) {
12168          ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d\r\n", exten, domain, ourport);
12169       } else {
12170          ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d;transport=%s\r\n", exten, domain, ourport, get_transport(p->socket.type));
12171       }
12172    } else {
12173       if (p->socket.type == SIP_TRANSPORT_UDP) {
12174          ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n", exten, domain);
12175       } else {
12176          ast_str_append(&out, 0, "Message-Account: sip:%s@%s;transport=%s\r\n", exten, domain, get_transport(p->socket.type));
12177       }
12178    }
12179    /* Cisco has a bug in the SIP stack where it can't accept the
12180       (0/0) notification. This can temporarily be disabled in
12181       sip.conf with the "buggymwi" option */
12182    ast_str_append(&out, 0, "Voice-Message: %d/%d%s\r\n",
12183       newmsgs, oldmsgs, (ast_test_flag(&p->flags[1], SIP_PAGE2_BUGGY_MWI) ? "" : " (0/0)"));
12184 
12185    if (p->subscribed) {
12186       if (p->expiry) {
12187          add_header(&req, "Subscription-State", "active");
12188       } else { /* Expired */
12189          add_header(&req, "Subscription-State", "terminated;reason=timeout");
12190       }
12191    }
12192 
12193    add_content(&req, out->str);
12194 
12195    if (!p->initreq.headers) {
12196       initialize_initreq(p, &req);
12197    }
12198    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
12199 }

static int transmit_notify_with_sipfrag ( struct sip_pvt *  p,
int  cseq,
char *  message,
int  terminate 
) [static]

Notify a transferring party of the status of transfer (RFC3515).

Definition at line 12202 of file chan_sip.c.

References add_content(), add_header(), add_supported_header(), initialize_initreq(), reqprep(), and send_request().

Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().

12203 {
12204    struct sip_request req;
12205    char tmp[SIPBUFSIZE/2];
12206    
12207    reqprep(&req, p, SIP_NOTIFY, 0, 1);
12208    snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
12209    add_header(&req, "Event", tmp);
12210    add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
12211    add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
12212    add_header(&req, "Allow", ALLOWED_METHODS);
12213    add_supported_header(p, &req);
12214 
12215    snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
12216    add_content(&req, tmp);
12217 
12218    if (!p->initreq.headers) {
12219       initialize_initreq(p, &req);
12220    }
12221 
12222    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
12223 }

static int transmit_provisional_response ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req,
int  with_sdp 
) [static]

Definition at line 10256 of file chan_sip.c.

References FALSE, transmit_response(), transmit_response_with_sdp(), and update_provisional_keepalive().

Referenced by handle_request_invite(), sip_indicate(), and sip_write().

10257 {
10258    int res;
10259 
10260    if (!(res = with_sdp ? transmit_response_with_sdp(p, msg, req, XMIT_UNRELIABLE, FALSE, FALSE) : transmit_response(p, msg, req))) {
10261       p->last_provisional = msg;
10262       update_provisional_keepalive(p, with_sdp);
10263    }
10264 
10265    return res;
10266 }

static int transmit_publish ( struct sip_epa_entry *  epa_entry,
enum sip_publish_type  publish_type,
const char *const   explicit_uri 
) [static]

Definition at line 11536 of file chan_sip.c.

References ao2_ref, ast_set_flag, ast_sip_ouraddrfor(), create_addr(), DEFAULT_PUBLISH_EXPIRES, dialog_unlink_all(), FALSE, sip_alloc(), sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), transmit_invite(), and TRUE.

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

11537 {
11538    struct sip_pvt *pvt;
11539    int expires;
11540 
11541    epa_entry->publish_type = publish_type;
11542 
11543    if (!(pvt = sip_alloc(NULL, NULL, 0, SIP_PUBLISH, NULL))) {
11544       return -1;
11545    }
11546 
11547    sip_pvt_lock(pvt);
11548 
11549    if (create_addr(pvt, epa_entry->destination, NULL, TRUE, NULL)) {
11550       sip_pvt_unlock(pvt);
11551       dialog_unlink_all(pvt, TRUE, TRUE);
11552       dialog_unref(pvt, "create_addr failed in transmit_publish. Unref dialog");
11553       return -1;
11554    }
11555    ast_sip_ouraddrfor(&pvt->sa, &pvt->ourip, pvt);
11556    ast_set_flag(&pvt->flags[0], SIP_OUTGOING);
11557    expires = (publish_type == SIP_PUBLISH_REMOVE) ? 0 : DEFAULT_PUBLISH_EXPIRES;
11558    pvt->expiry = expires;
11559 
11560    /* Bump refcount for sip_pvt's reference */
11561    ao2_ref(epa_entry, +1);
11562    pvt->epa_entry = epa_entry;
11563 
11564    transmit_invite(pvt, SIP_PUBLISH, FALSE, 2, explicit_uri);
11565    sip_pvt_unlock(pvt);
11566    sip_scheddestroy(pvt, DEFAULT_TRANS_TIMEOUT);
11567    dialog_unref(pvt, "Done with the sip_pvt allocated for transmitting PUBLISH");
11568    return 0;
11569 }

static int transmit_refer ( struct sip_pvt *  p,
const char *  dest 
) [static]

Transmit SIP REFER message (initiated by the transfer() dialplan application.

Note:
this is currently broken as we have no way of telling the dialplan engine whether a transfer succeeds or fails.
Todo:
Fix the transfer() dialplan function so that a transfer may fail

Todo:
In theory, we should hang around and wait for a reply, before returning to the dial plan here. Don't know really how that would affect the transfer() app or the pbx, but, well, to make this useful we should have a STATUS code on transfer().

Definition at line 12751 of file chan_sip.c.

References add_header(), add_supported_header(), ast_copy_string(), ast_debug, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, FALSE, get_header(), LOG_NOTICE, reqprep(), send_request(), sip_refer_allocate(), sipdebug, and TRUE.

Referenced by sip_transfer().

12752 {
12753    struct sip_request req = {
12754       .headers = 0,  
12755    };
12756    char from[256];
12757    const char *of;
12758    char *c;
12759    char referto[256];
12760    char *ttag, *ftag;
12761    char *theirtag = ast_strdupa(p->theirtag);
12762    int   use_tls=FALSE;
12763 
12764    if (sipdebug) {
12765       ast_debug(1, "SIP transfer of %s to %s\n", p->callid, dest);
12766    }
12767 
12768    /* Are we transfering an inbound or outbound call ? */
12769    if (ast_test_flag(&p->flags[0], SIP_OUTGOING))  {
12770       of = get_header(&p->initreq, "To");
12771       ttag = theirtag;
12772       ftag = p->tag;
12773    } else {
12774       of = get_header(&p->initreq, "From");
12775       ftag = theirtag;
12776       ttag = p->tag;
12777    }
12778 
12779    ast_copy_string(from, of, sizeof(from));
12780    of = get_in_brackets(from);
12781    ast_string_field_set(p, from, of);
12782    if (!strncasecmp(of, "sip:", 4)) {
12783       of += 4;
12784    } else if (!strncasecmp(of, "sips:", 5)) {
12785       of += 5;
12786       use_tls = TRUE;
12787    } else {
12788       ast_log(LOG_NOTICE, "From address missing 'sip(s):', assuming sip:\n");
12789    }
12790    /* Get just the username part */
12791    if ((c = strchr(dest, '@'))) {
12792       c = NULL;
12793    } else if ((c = strchr(of, '@'))) {
12794       *c++ = '\0';
12795    }
12796    if (c) {
12797       snprintf(referto, sizeof(referto), "<sip%s:%s@%s>", use_tls ? "s" : "", dest, c);
12798    } else {
12799       snprintf(referto, sizeof(referto), "<sip%s:%s>", use_tls ? "s" : "", dest);
12800    }
12801 
12802    /* save in case we get 407 challenge */
12803    sip_refer_allocate(p);
12804    ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to));
12805    ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by));
12806    p->refer->status = REFER_SENT;   /* Set refer status */
12807 
12808    reqprep(&req, p, SIP_REFER, 0, 1);
12809 
12810    add_header(&req, "Refer-To", referto);
12811    add_header(&req, "Allow", ALLOWED_METHODS);
12812    add_supported_header(p, &req);
12813    if (!ast_strlen_zero(p->our_contact)) {
12814       add_header(&req, "Referred-By", p->our_contact);
12815    }
12816 
12817    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
12818 
12819    /* We should propably wait for a NOTIFY here until we ack the transfer */
12820    /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */
12821 
12822    /*! \todo In theory, we should hang around and wait for a reply, before
12823    returning to the dial plan here. Don't know really how that would
12824    affect the transfer() app or the pbx, but, well, to make this
12825    useful we should have a STATUS code on transfer().
12826    */
12827 }

static int transmit_register ( struct sip_registry *  r,
int  sipmethod,
const char *  auth,
const char *  authheader 
) [static]

Transmit register to SIP proxy or UA auth = NULL on the initial registration (from sip_reregister()).

Definition at line 12490 of file chan_sip.c.

References add_header(), add_header_max_forwards(), append_history, ast_debug, ast_dnsmgr_lookup(), ast_log(), ast_random(), ast_sched_add(), AST_SCHED_REPLACE_UNREF, ast_set_flag, ast_sip_ouraddrfor(), ast_sockaddr_port, ast_sockaddr_set_port, ast_string_field_set, ast_strlen_zero(), ast_verbose, bindaddr, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), create_addr(), default_fromdomain, dialog_unlink_all(), exten, FALSE, find_peer(), get_address_family_filter(), get_srv_protocol(), get_srv_service(), global_reg_timeout, global_useragent, init_req(), initialize_initreq(), internip, ast_tcptls_session_args::local_address, LOG_NOTICE, LOG_WARNING, make_our_tag(), MAXHOSTNAMELEN, REG_STATE_AUTHSENT, REG_STATE_REGSENT, registry_addref(), registry_unref(), S_OR, send_request(), set_socket_transport(), sip_alloc(), sip_cfg, sip_debug_test_pvt(), sip_methods, sip_reg_timeout(), sip_tcp_desc, sipdebug, cfsip_methods::text, TRUE, and unref_peer().

Referenced by __sip_do_register(), do_register_auth(), handle_response_register(), and sip_reg_timeout().

12491 {
12492    struct sip_request req;
12493    char from[256];
12494    char to[256];
12495    char tmp[80];
12496    char addr[80];
12497    struct sip_pvt *p;
12498    struct sip_peer *peer = NULL;
12499    int res;
12500    int portno = 0;
12501 
12502    /* exit if we are already in process with this registrar ?*/
12503    if (r == NULL || ((auth == NULL) && (r->regstate == REG_STATE_REGSENT || r->regstate == REG_STATE_AUTHSENT))) {
12504       if (r) {
12505          ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
12506       }
12507       return 0;
12508    }
12509 
12510    if (r->dnsmgr == NULL) {
12511       char transport[MAXHOSTNAMELEN];
12512       peer = find_peer(r->hostname, NULL, TRUE, FINDPEERS, FALSE, 0);
12513       snprintf(transport, sizeof(transport), "_%s._%s",get_srv_service(r->transport), get_srv_protocol(r->transport)); /* have to use static get_transport function */
12514       r->us.ss.ss_family = get_address_family_filter(&bindaddr); /* Filter address family */
12515       ast_dnsmgr_lookup(peer ? peer->tohost : r->hostname, &r->us, &r->dnsmgr, sip_cfg.srvlookup ? transport : NULL);
12516       if (peer) {
12517          peer = unref_peer(peer, "removing peer ref for dnsmgr_lookup");
12518       }
12519    }
12520 
12521    if (r->call) { /* We have a registration */
12522       if (!auth) {
12523          ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
12524          return 0;
12525       } else {
12526          p = dialog_ref(r->call, "getting a copy of the r->call dialog in transmit_register");
12527          make_our_tag(p->tag, sizeof(p->tag));  /* create a new local tag for every register attempt */
12528          ast_string_field_set(p, theirtag, NULL);  /* forget their old tag, so we don't match tags when getting response */
12529       }
12530    } else {
12531       /* Build callid for registration if we haven't registered before */
12532       if (!r->callid_valid) {
12533          build_callid_registry(r, &internip, default_fromdomain);
12534          r->callid_valid = TRUE;
12535       }
12536       /* Allocate SIP dialog for registration */
12537       if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER, NULL))) {
12538          ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
12539          return 0;
12540       }
12541       
12542       if (p->do_history) {
12543          append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
12544       }
12545 
12546       /* Use port number specified if no SRV record was found */
12547       if (!ast_sockaddr_port(&r->us) && r->portno) {
12548          ast_sockaddr_set_port(&r->us, r->portno);
12549       }
12550 
12551       /* Find address to hostname */
12552       if (create_addr(p, S_OR(r->peername, r->hostname), &r->us, 0, NULL)) {
12553          /* we have what we hope is a temporary network error,
12554           * probably DNS.  We need to reschedule a registration try */
12555          dialog_unlink_all(p, TRUE, TRUE);
12556          p = dialog_unref(p, "unref dialog after unlink_all");
12557          if (r->timeout > -1) {
12558             AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r,
12559                               registry_unref(_data, "del for REPLACE of registry ptr"),
12560                               registry_unref(r, "object ptr dec when SCHED_REPLACE add failed"),
12561                               registry_addref(r,"add for REPLACE registry ptr"));
12562             ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
12563          } else {
12564             r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, registry_addref(r, "add for REPLACE registry ptr"));
12565             ast_log(LOG_WARNING, "Probably a DNS error for registration to %s@%s, trying REGISTER again (after %d seconds)\n", r->username, r->hostname, global_reg_timeout);
12566          }
12567          r->regattempts++;
12568          return 0;
12569       }
12570 
12571       /* Copy back Call-ID in case create_addr changed it */
12572       ast_string_field_set(r, callid, p->callid);
12573 
12574       if (!r->dnsmgr && r->portno) {
12575          ast_sockaddr_set_port(&p->sa, r->portno);
12576          ast_sockaddr_set_port(&p->recv, r->portno);
12577       }
12578       if (!ast_strlen_zero(p->fromdomain)) {
12579          portno = (p->fromdomainport) ? p->fromdomainport : STANDARD_SIP_PORT;
12580       } else if (!ast_strlen_zero(r->regdomain)) {
12581          portno = (r->regdomainport) ? r->regdomainport : STANDARD_SIP_PORT;
12582       } else {
12583          portno = ast_sockaddr_port(&p->sa);
12584       }
12585 
12586       ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
12587       r->call = dialog_ref(p, "copying dialog into registry r->call");     /* Save pointer to SIP dialog */
12588       p->registry = registry_addref(r, "transmit_register: addref to p->registry in transmit_register"); /* Add pointer to registry in packet */
12589       if (!ast_strlen_zero(r->secret)) {  /* Secret (password) */
12590          ast_string_field_set(p, peersecret, r->secret);
12591       }
12592       if (!ast_strlen_zero(r->md5secret))
12593          ast_string_field_set(p, peermd5secret, r->md5secret);
12594       /* User name in this realm
12595       - if authuser is set, use that, otherwise use username */
12596       if (!ast_strlen_zero(r->authuser)) {
12597          ast_string_field_set(p, peername, r->authuser);
12598          ast_string_field_set(p, authname, r->authuser);
12599       } else if (!ast_strlen_zero(r->username)) {
12600          ast_string_field_set(p, peername, r->username);
12601          ast_string_field_set(p, authname, r->username);
12602          ast_string_field_set(p, fromuser, r->username);
12603       }
12604       if (!ast_strlen_zero(r->username)) {
12605          ast_string_field_set(p, username, r->username);
12606       }
12607       /* Save extension in packet */
12608       if (!ast_strlen_zero(r->callback)) {
12609          ast_string_field_set(p, exten, r->callback);
12610       }
12611 
12612       /* Set transport and port so the correct contact is built */
12613       set_socket_transport(&p->socket, r->transport);
12614       if (r->transport == SIP_TRANSPORT_TLS || r->transport == SIP_TRANSPORT_TCP) {
12615          p->socket.port =
12616              htons(ast_sockaddr_port(&sip_tcp_desc.local_address));
12617       }
12618 
12619       /*
12620         check which address we should use in our contact header
12621         based on whether the remote host is on the external or
12622         internal network so we can register through nat
12623        */
12624       ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
12625       build_contact(p);
12626    }
12627 
12628    /* set up a timeout */
12629    if (auth == NULL)  {
12630       if (r->timeout > -1) {
12631          ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
12632       }
12633       AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r,
12634                         registry_unref(_data,"reg ptr unrefed from del in SCHED_REPLACE"),
12635                         registry_unref(r,"reg ptr unrefed from add failure in SCHED_REPLACE"),
12636                         registry_addref(r,"reg ptr reffed from add in SCHED_REPLACE"));
12637       ast_debug(1, "Scheduled a registration timeout for %s id  #%d \n", r->hostname, r->timeout);
12638    }
12639 
12640    snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain,p->tohost), p->tag);
12641    if (!ast_strlen_zero(p->theirtag)) {
12642       snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain,p->tohost), p->theirtag);
12643    } else {
12644       snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, S_OR(r->regdomain,p->tohost));
12645    }
12646 
12647    /* Fromdomain is what we are registering to, regardless of actual
12648       host name from SRV */
12649    if (portno && portno != STANDARD_SIP_PORT) {
12650       snprintf(addr, sizeof(addr), "sip:%s:%d", S_OR(p->fromdomain,S_OR(r->regdomain,r->hostname)), portno);
12651    } else {
12652       snprintf(addr, sizeof(addr), "sip:%s", S_OR(p->fromdomain,S_OR(r->regdomain,r->hostname)));
12653    }
12654 
12655    ast_string_field_set(p, uri, addr);
12656 
12657    p->branch ^= ast_random();
12658 
12659    init_req(&req, sipmethod, addr);
12660 
12661    /* Add to CSEQ */
12662    snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text);
12663    p->ocseq = r->ocseq;
12664 
12665    build_via(p);
12666    add_header(&req, "Via", p->via);
12667    add_header_max_forwards(p, &req);
12668    add_header(&req, "From", from);
12669    add_header(&req, "To", to);
12670    add_header(&req, "Call-ID", p->callid);
12671    add_header(&req, "CSeq", tmp);
12672    if (!ast_strlen_zero(global_useragent))
12673       add_header(&req, "User-Agent", global_useragent);
12674 
12675    if (auth) {    /* Add auth header */
12676       add_header(&req, authheader, auth);
12677    } else if (!ast_strlen_zero(r->nonce)) {
12678       char digest[1024];
12679 
12680       /* We have auth data to reuse, build a digest header.
12681        * Note, this is not always useful because some parties do not
12682        * like nonces to be reused (for good reasons!) so they will
12683        * challenge us anyways.
12684        */
12685       if (sipdebug) {
12686          ast_debug(1, "   >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
12687       }
12688       ast_string_field_set(p, realm, r->realm);
12689       ast_string_field_set(p, nonce, r->nonce);
12690       ast_string_field_set(p, domain, r->authdomain);
12691       ast_string_field_set(p, opaque, r->opaque);
12692       ast_string_field_set(p, qop, r->qop);
12693       p->noncecount = ++r->noncecount;
12694 
12695       memset(digest, 0, sizeof(digest));
12696       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
12697          add_header(&req, "Authorization", digest);
12698       } else {
12699          ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname);
12700       }
12701    }
12702 
12703    snprintf(tmp, sizeof(tmp), "%d", r->expiry);
12704    add_header(&req, "Expires", tmp);
12705    add_header(&req, "Contact", p->our_contact);
12706 
12707    initialize_initreq(p, &req);
12708    if (sip_debug_test_pvt(p)) {
12709       ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
12710    }
12711    r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT;
12712    r->regattempts++; /* Another attempt */
12713    ast_debug(4, "REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
12714    res = send_request(p, &req, XMIT_CRITICAL, p->ocseq);
12715    dialog_unref(p, "p is finished here at the end of transmit_register");
12716    return res;
12717 }

static int transmit_reinvite_with_sdp ( struct sip_pvt *  p,
int  t38version,
int  oldsdp 
) [static]

Transmit reinvite with SDP.

Note:
A re-invite is basically a new INVITE with the same CALL-ID and TAG as the INVITE that opened the SIP dialogue We reinvite so that the audio stream (RTP) go directly between the SIP UAs. SIP Signalling stays with * in the path.
If t38version is TRUE, we send T38 SDP for re-invite from audio/video to T38 UDPTL transmission on the channel

If oldsdp is TRUE then the SDP version number is not incremented. This is needed for Session-Timers so we can send a re-invite to refresh the SIP session without modifying the media session.

Definition at line 11242 of file chan_sip.c.

References add_header(), add_rpid(), add_sdp(), add_supported_header(), append_history, ast_set_flag, ast_test_flag, FALSE, initialize_initreq(), reqprep(), send_request(), TRUE, and try_suggested_sip_codec().

Referenced by check_pendings(), handle_response_invite(), interpret_t38_parameters(), proc_session_timer(), sip_sendhtml(), sip_set_rtp_peer(), and sip_set_udptl_peer().

11243 {
11244    struct sip_request req;
11245    
11246    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
11247 
11248    add_header(&req, "Allow", ALLOWED_METHODS);
11249    add_supported_header(p, &req);
11250    if (sipdebug) {
11251       if (oldsdp == TRUE)
11252          add_header(&req, "X-asterisk-Info", "SIP re-invite (Session-Timers)");
11253       else
11254          add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)");
11255    }
11256 
11257    if (ast_test_flag(&p->flags[0], SIP_SENDRPID))
11258       add_rpid(&req, p);
11259 
11260    if (p->do_history) {
11261       append_history(p, "ReInv", "Re-invite sent");
11262    }
11263    memset(p->offered_media, 0, sizeof(p->offered_media));
11264 
11265    try_suggested_sip_codec(p);
11266    if (t38version) {
11267       add_sdp(&req, p, oldsdp, FALSE, TRUE);
11268    } else {
11269       add_sdp(&req, p, oldsdp, TRUE, FALSE);
11270    }
11271 
11272    /* Use this as the basis */
11273    initialize_initreq(p, &req);
11274    p->lastinvite = p->ocseq;
11275    ast_set_flag(&p->flags[0], SIP_OUTGOING);       /* Change direction of this dialog */
11276 
11277    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
11278 }

static int transmit_request ( struct sip_pvt *  p,
int  sipmethod,
int  inc,
enum xmittype  reliable,
int  newbranch 
) [static]

Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).

Definition at line 12900 of file chan_sip.c.

References add_header(), reqprep(), and send_request().

Referenced by check_pendings(), handle_response(), handle_response_invite(), and sip_hangup().

12901 {
12902    struct sip_request resp;
12903    
12904    if (sipmethod == SIP_ACK) {
12905       p->invitestate = INV_CONFIRMED;
12906    }
12907 
12908    reqprep(&resp, p, sipmethod, seqno, newbranch);
12909    if (sipmethod == SIP_CANCEL && p->answered_elsewhere) {
12910       add_header(&resp, "Reason", "SIP;cause=200;text=\"Call completed elsewhere\"");
12911    }
12912 
12913    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
12914 }

static int transmit_request_with_auth ( struct sip_pvt *  p,
int  sipmethod,
int  seqno,
enum xmittype  reliable,
int  newbranch 
) [static]

Transmit SIP request, auth added.

Definition at line 12932 of file chan_sip.c.

References add_header(), ast_cause2str(), ast_log(), ast_strlen_zero(), ast_test_flag, auth_headers(), build_reply_digest(), dummy(), LOG_WARNING, reqprep(), and send_request().

Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().

12933 {
12934    struct sip_request resp;
12935    
12936    reqprep(&resp, p, sipmethod, seqno, newbranch);
12937    if (!ast_strlen_zero(p->realm)) {
12938       char digest[1024];
12939 
12940       memset(digest, 0, sizeof(digest));
12941       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
12942          char *dummy, *response;
12943          enum sip_auth_type code = p->options ? p->options->auth_type : PROXY_AUTH; /* XXX force 407 if unknown */
12944          auth_headers(code, &dummy, &response);
12945          add_header(&resp, response, digest);
12946       } else {
12947          ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid);
12948       }
12949    }
12950    /* If we are hanging up and know a cause for that, send it in clear text to make
12951       debugging easier. */
12952    if (sipmethod == SIP_BYE)  {
12953       char buf[20];
12954 
12955       if (ast_test_flag(&p->flags[1], SIP_PAGE2_Q850_REASON) && p->hangupcause) {
12956          sprintf(buf, "Q.850;cause=%i", p->hangupcause & 0x7f);
12957          add_header(&resp, "Reason", buf);
12958       }
12959 
12960       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->hangupcause));
12961       snprintf(buf, sizeof(buf), "%d", p->hangupcause);
12962       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
12963    }
12964 
12965    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);   
12966 }

static int transmit_response ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req 
) [static]

Transmit response, no retransmits.

Definition at line 10059 of file chan_sip.c.

References __transmit_response().

10060 {
10061    return __transmit_response(p, msg, req, XMIT_UNRELIABLE);
10062 }

static int transmit_response_reliable ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req 
) [static]

Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK.

Definition at line 10092 of file chan_sip.c.

References __transmit_response().

Referenced by handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_publish(), handle_request_subscribe(), interpret_t38_parameters(), sip_hangup(), sip_indicate(), sip_sipredirect(), and sip_t38_abort().

10093 {
10094    return __transmit_response(p, msg, req, req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL);
10095 }

static int transmit_response_using_temp ( ast_string_field  callid,
struct ast_sockaddr *  addr,
int  useglobal_nat,
const int  intended_method,
const struct sip_request *  req,
const char *  msg 
) [static]

Transmit response, no retransmits, using a temporary pvt structure.

Definition at line 10006 of file chan_sip.c.

References __transmit_response(), ast_copy_flags, ast_log(), ast_random(), ast_sip_ouraddrfor(), ast_sockaddr_copy(), ast_string_field_init, ast_string_field_set, ast_threadstorage_get(), build_via(), copy_socket_data(), default_fromdomain, default_fromdomainport, do_setnat(), global_flags, internip, LOG_ERROR, make_our_tag(), and ts_temp_pvt.

Referenced by find_call().

10007 {
10008    struct sip_pvt *p = NULL;
10009 
10010    if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) {
10011       ast_log(LOG_ERROR, "Failed to get temporary pvt\n");
10012       return -1;
10013    }
10014 
10015    /* XXX the structure may be dirty from previous usage.
10016     * Here we should state clearly how we should reinitialize it
10017     * before using it.
10018     * E.g. certainly the threadstorage should be left alone,
10019     * but other thihngs such as flags etc. maybe need cleanup ?
10020     */
10021 
10022    /* Initialize the bare minimum */
10023    p->method = intended_method;
10024 
10025    if (!addr) {
10026       ast_sockaddr_copy(&p->ourip, &internip);
10027    } else {
10028       ast_sockaddr_copy(&p->sa, addr);
10029       ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
10030    }
10031 
10032    p->branch = ast_random();
10033    make_our_tag(p->tag, sizeof(p->tag));
10034    p->ocseq = INITIAL_CSEQ;
10035 
10036    if (useglobal_nat && addr) {
10037       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT);
10038       ast_sockaddr_copy(&p->recv, addr);
10039       do_setnat(p);
10040    }
10041 
10042    ast_string_field_set(p, fromdomain, default_fromdomain);
10043    p->fromdomainport = default_fromdomainport;
10044    build_via(p);
10045    ast_string_field_set(p, callid, callid);
10046 
10047    copy_socket_data(&p->socket, &req->socket);
10048 
10049    /* Use this temporary pvt structure to send the message */
10050    __transmit_response(p, msg, req, XMIT_UNRELIABLE);
10051 
10052    /* Free the string fields, but not the pool space */
10053    ast_string_field_init(p, 0);
10054 
10055    return 0;
10056 }

static int transmit_response_with_allow ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req,
enum xmittype  reliable 
) [static]

Append Accept header, content length before transmitting response.

Definition at line 10128 of file chan_sip.c.

References add_header(), respprep(), and send_response().

Referenced by handle_incoming(), and handle_request_options().

10129 {
10130    struct sip_request resp;
10131    respprep(&resp, p, msg, req);
10132    add_header(&resp, "Accept", "application/sdp");
10133    return send_response(p, &resp, reliable, 0);
10134 }

static int transmit_response_with_auth ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req,
const char *  rand,
enum xmittype  reliable,
const char *  header,
int  stale 
) [static]

Respond with authorization request.

Definition at line 10149 of file chan_sip.c.

References add_header(), append_history, ast_log(), get_header(), get_realm(), LOG_WARNING, respprep(), and send_response().

Referenced by check_auth(), and transmit_fake_auth_response().

10150 {
10151    struct sip_request resp;
10152    char tmp[512];
10153    int seqno = 0;
10154 
10155    if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) {
10156       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
10157       return -1;
10158    }
10159    /* Choose Realm */
10160    get_realm(p, req);
10161 
10162    /* Stale means that they sent us correct authentication, but
10163       based it on an old challenge (nonce) */
10164    snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", p->realm, randdata, stale ? ", stale=true" : "");
10165    respprep(&resp, p, msg, req);
10166    add_header(&resp, header, tmp);
10167    append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount);
10168    return send_response(p, &resp, reliable, seqno);
10169 }

static int transmit_response_with_date ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req 
) [static]

Append date and content length before transmitting response.

Definition at line 10119 of file chan_sip.c.

References append_date(), respprep(), and send_response().

Referenced by handle_response_subscribe(), and register_verify().

10120 {
10121    struct sip_request resp;
10122    respprep(&resp, p, msg, req);
10123    append_date(&resp);
10124    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
10125 }

static int transmit_response_with_minexpires ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req 
) [static]

Append Min-Expires header, content length before transmitting response.

Definition at line 10137 of file chan_sip.c.

References add_header(), min_expiry, respprep(), and send_response().

Referenced by handle_request_subscribe().

10138 {
10139    struct sip_request resp;
10140    char tmp[32];
10141 
10142    snprintf(tmp, sizeof(tmp), "%d", min_expiry);
10143    respprep(&resp, p, msg, req);
10144    add_header(&resp, "Min-Expires", tmp);
10145    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
10146 }

static int transmit_response_with_minse ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req,
int  minse_int 
) [static]

Transmit 422 response with Min-SE header (Session-Timers).

Definition at line 10075 of file chan_sip.c.

References add_header(), append_date(), respprep(), and send_response().

Referenced by handle_request_invite().

10076 {
10077    struct sip_request resp;
10078    char minse_str[20];
10079 
10080    respprep(&resp, p, msg, req);
10081    append_date(&resp);
10082 
10083    snprintf(minse_str, sizeof(minse_str), "%d", minse_int);
10084    add_header(&resp, "Min-SE", minse_str);
10085    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
10086 }

static int transmit_response_with_retry_after ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req,
const char *  seconds 
) [static]

Append Retry-After header field when transmitting response.

Definition at line 10110 of file chan_sip.c.

References add_header(), respprep(), and send_response().

Referenced by handle_incoming().

10111 {
10112    struct sip_request resp;
10113    respprep(&resp, p, msg, req);
10114    add_header(&resp, "Retry-After", seconds);
10115    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
10116 }

static int transmit_response_with_sdp ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req,
enum xmittype  reliable,
int  oldsdp,
int  rpid 
) [static]

Used for 200 OK and 183 early media.

Returns:
Will return XMIT_ERROR for network errors.

Definition at line 11152 of file chan_sip.c.

References add_cc_call_info_to_response(), add_rpid(), add_sdp(), ast_debug, ast_log(), ast_rtp_codecs_packetization_set(), ast_rtp_instance_activate(), ast_rtp_instance_get_codecs(), ast_test_flag, FALSE, get_header(), LOG_ERROR, LOG_WARNING, respprep(), send_response(), TRUE, and try_suggested_sip_codec().

Referenced by handle_invite_replaces(), handle_request_invite(), send_provisional_keepalive_full(), sip_answer(), and transmit_provisional_response().

11153 {
11154    struct sip_request resp;
11155    int seqno;
11156    if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) {
11157       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
11158       return -1;
11159    }
11160    respprep(&resp, p, msg, req);
11161    if (rpid == TRUE) {
11162       add_rpid(&resp, p);
11163    }
11164    if (ast_test_flag(&p->flags[0], SIP_OFFER_CC)) {
11165       add_cc_call_info_to_response(p, &resp);
11166    }
11167    if (p->rtp) {
11168       if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
11169          ast_debug(1, "Setting framing from config on incoming call\n");
11170          ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &p->prefs);
11171       }
11172       ast_rtp_instance_activate(p->rtp);
11173       try_suggested_sip_codec(p);
11174       if (p->t38.state == T38_ENABLED) {
11175          add_sdp(&resp, p, oldsdp, TRUE, TRUE);
11176       } else {
11177          add_sdp(&resp, p, oldsdp, TRUE, FALSE);
11178       }
11179    } else
11180       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
11181    if (reliable && !p->pendinginvite)
11182       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
11183    return send_response(p, &resp, reliable, seqno);
11184 }

static int transmit_response_with_sip_etag ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req,
struct sip_esc_entry *  esc_entry,
int  need_new_etag 
) [static]

Definition at line 9975 of file chan_sip.c.

References add_header(), create_new_sip_etag(), respprep(), and send_response().

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

09976 {
09977    struct sip_request resp;
09978 
09979    if (need_new_etag) {
09980       create_new_sip_etag(esc_entry, 1);
09981    }
09982    respprep(&resp, p, msg, req);
09983    add_header(&resp, "SIP-ETag", esc_entry->entity_tag);
09984 
09985    return send_response(p, &resp, 0, 0);
09986 }

static int transmit_response_with_t38_sdp ( struct sip_pvt *  p,
char *  msg,
struct sip_request *  req,
int  retrans 
) [static]

Used for 200 OK and 183 early media.

Definition at line 11070 of file chan_sip.c.

References add_sdp(), ast_log(), get_header(), LOG_ERROR, LOG_WARNING, respprep(), and send_response().

Referenced by handle_request_invite(), and interpret_t38_parameters().

11071 {
11072    struct sip_request resp;
11073    int seqno;
11074    
11075    if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) {
11076       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
11077       return -1;
11078    }
11079    respprep(&resp, p, msg, req);
11080    if (p->udptl) {
11081       add_sdp(&resp, p, 0, 0, 1);
11082    } else
11083       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid);
11084    if (retrans && !p->pendinginvite)
11085       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
11086    return send_response(p, &resp, retrans, seqno);
11087 }

static int transmit_response_with_unsupported ( struct sip_pvt *  p,
const char *  msg,
const struct sip_request *  req,
const char *  unsupported 
) [static]

Transmit response, no retransmits.

Definition at line 10065 of file chan_sip.c.

References add_header(), append_date(), respprep(), and send_response().

Referenced by handle_request_bye(), and handle_request_invite().

10066 {
10067    struct sip_request resp;
10068    respprep(&resp, p, msg, req);
10069    append_date(&resp);
10070    add_header(&resp, "Unsupported", unsupported);
10071    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
10072 }

static int transmit_state_notify ( struct sip_pvt *  p,
int  state,
int  full,
int  timeout 
) [static]

Used in the SUBSCRIBE notification subsystem (RFC3265).

Definition at line 12063 of file chan_sip.c.

References add_content(), add_header(), ast_copy_string(), AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_log(), ast_str_alloca, cfsubscription_types::event, find_subscription_type(), get_header(), LOG_WARNING, cfsubscription_types::mediatype, NONE, remove_uri_parameters(), reqprep(), send_request(), and state_notify_build_xml().

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

12064 {
12065    struct ast_str *tmp = ast_str_alloca(4000);
12066    char from[256], to[256];
12067    char *c, *mfrom, *mto;
12068    struct sip_request req;
12069    const struct cfsubscription_types *subscriptiontype;
12070 
12071    memset(from, 0, sizeof(from));
12072    memset(to, 0, sizeof(to));
12073 
12074    subscriptiontype = find_subscription_type(p->subscribed);
12075 
12076    ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
12077    c = get_in_brackets(from);
12078    if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
12079       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
12080       return -1;
12081    }
12082 
12083    mfrom = remove_uri_parameters(c);
12084 
12085    ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
12086    c = get_in_brackets(to);
12087    if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
12088       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
12089       return -1;
12090    }
12091    mto = remove_uri_parameters(c);
12092 
12093    reqprep(&req, p, SIP_NOTIFY, 0, 1);
12094 
12095    switch(state) {
12096    case AST_EXTENSION_DEACTIVATED:
12097       if (timeout)
12098          add_header(&req, "Subscription-State", "terminated;reason=timeout");
12099       else {
12100          add_header(&req, "Subscription-State", "terminated;reason=probation");
12101          add_header(&req, "Retry-After", "60");
12102       }
12103       break;
12104    case AST_EXTENSION_REMOVED:
12105       add_header(&req, "Subscription-State", "terminated;reason=noresource");
12106       break;
12107    default:
12108       if (p->expiry)
12109          add_header(&req, "Subscription-State", "active");
12110       else  /* Expired */
12111          add_header(&req, "Subscription-State", "terminated;reason=timeout");
12112    }
12113 
12114    switch (p->subscribed) {
12115    case XPIDF_XML:
12116    case CPIM_PIDF_XML:
12117       add_header(&req, "Event", subscriptiontype->event);
12118       state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto);
12119       add_header(&req, "Content-Type", subscriptiontype->mediatype);
12120       p->dialogver++;
12121       break;
12122    case PIDF_XML: /* Eyebeam supports this format */
12123       add_header(&req, "Event", subscriptiontype->event);
12124       state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto);
12125       add_header(&req, "Content-Type", subscriptiontype->mediatype);
12126       p->dialogver++;
12127       break;
12128    case DIALOG_INFO_XML: /* SNOM subscribes in this format */
12129       add_header(&req, "Event", subscriptiontype->event);
12130       state_notify_build_xml(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto);
12131       add_header(&req, "Content-Type", subscriptiontype->mediatype);
12132       p->dialogver++;
12133       break;
12134    case NONE:
12135    default:
12136       break;
12137    }
12138 
12139    add_content(&req, tmp->str);
12140 
12141    p->pendinginvite = p->ocseq;  /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */
12142 
12143    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
12144 }

static void try_suggested_sip_codec ( struct sip_pvt *  p  )  [static]

Try setting codec suggested by the SIP_CODEC channel variable.

Definition at line 6155 of file chan_sip.c.

References ast_getformatbyname(), ast_log(), LOG_NOTICE, and pbx_builtin_getvar_helper().

Referenced by sip_answer(), transmit_invite(), transmit_reinvite_with_sdp(), and transmit_response_with_sdp().

06156 {
06157    format_t fmt;
06158    const char *codec;
06159 
06160    if (p->outgoing_call) {
06161       codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_OUTBOUND");
06162    } else if (!(codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_INBOUND"))) {
06163       codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC");
06164    }
06165 
06166    if (!codec) 
06167       return;
06168 
06169    fmt = ast_getformatbyname(codec);
06170    if (fmt) {
06171       ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec);
06172       if (p->jointcapability & fmt) {
06173          p->jointcapability &= fmt;
06174          p->capability &= fmt;
06175       } else
06176          ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
06177    } else
06178       ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec);
06179    return;  
06180 }

static void unlink_marked_peers_from_tables ( void   )  [static]

Definition at line 2803 of file chan_sip.c.

References ao2_t_callback, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, peer_is_marked(), and peers_by_ip.

Referenced by sip_do_reload(), and sip_prune_realtime().

02804 {
02805    ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, NULL,
02806                   "initiating callback to remove marked peers");
02807    ao2_t_callback(peers_by_ip, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, NULL,
02808                   "initiating callback to remove marked peers");
02809 }

static void unlink_peer_from_tables ( struct sip_peer *  peer  )  [static]

Definition at line 2812 of file chan_sip.c.

References ao2_t_unlink, ast_sockaddr_isnull(), and peers_by_ip.

Referenced by expire_register().

02813 {
02814    ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table");
02815    if (!ast_sockaddr_isnull(&peer->addr)) {
02816       ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
02817    }
02818 }

static int unload_module ( void   )  [static]

PBX unload module API.

Definition at line 29144 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ARRAY_LEN, ast_cc_agent_unregister(), ast_cc_monitor_unregister(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_context_find(), ast_custom_function_unregister(), ast_data_unregister, ast_free, ast_free_ha(), ast_manager_unregister(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_glue_unregister(), ast_sched_dump(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_tcptls_server_stop(), AST_TEST_UNREGISTER, ast_udptl_proto_unregister(), ast_unload_realtime(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, checksipdomain_function, ast_tls_config::cipher, clear_realm_authentication(), clear_sip_domains(), cli_sip, default_tls_cfg, destroy_escs(), dialog_unlink_all(), dialogs, localaddr, ast_tcptls_session_args::master, monitor_thread, monlock, network_change_event_unsubscribe(), peers_by_ip, ast_tls_config::pvtfile, regl, sched_context_destroy(), sip_cc_agent_callbacks, sip_cc_monitor_callbacks, sip_cfg, sip_header_function, sip_registry_destroy(), sip_rtp_glue, sip_subscribe_mwi_destroy(), sip_tcp_desc, sip_tech, sip_tls_desc, sip_udptl, sip_unregister_tests(), sipchaninfo_function, sippeer_function, sipsock, submwil, thread, threadt, TRUE, and used_context.

29145 {
29146    struct sip_pvt *p;
29147    struct sip_threadinfo *th;
29148    struct ast_context *con;
29149    struct ao2_iterator i;
29150 
29151    network_change_event_unsubscribe();
29152 
29153    ast_sched_dump(sched);
29154    
29155    /* First, take us out of the channel type list */
29156    ast_channel_unregister(&sip_tech);
29157 
29158    /* Unregister dial plan functions */
29159    ast_custom_function_unregister(&sipchaninfo_function);
29160    ast_custom_function_unregister(&sippeer_function);
29161    ast_custom_function_unregister(&sip_header_function);
29162    ast_custom_function_unregister(&checksipdomain_function);
29163 
29164    /* Unregister dial plan applications */
29165    ast_unregister_application(app_dtmfmode);
29166    ast_unregister_application(app_sipaddheader);
29167    ast_unregister_application(app_sipremoveheader);
29168 
29169 #ifdef TEST_FRAMEWORK
29170    AST_TEST_UNREGISTER(test_sip_peers_get);
29171    AST_TEST_UNREGISTER(test_sip_mwi_subscribe_parse);
29172 #endif
29173    /* Unregister all the AstData providers */
29174    ast_data_unregister(NULL);
29175 
29176    /* Unregister CLI commands */
29177    ast_cli_unregister_multiple(cli_sip, ARRAY_LEN(cli_sip));
29178 
29179    /* Disconnect from UDPTL */
29180    ast_udptl_proto_unregister(&sip_udptl);
29181 
29182    /* Disconnect from RTP engine */
29183    ast_rtp_glue_unregister(&sip_rtp_glue);
29184 
29185    /* Unregister AMI actions */
29186    ast_manager_unregister("SIPpeers");
29187    ast_manager_unregister("SIPshowpeer");
29188    ast_manager_unregister("SIPqualifypeer");
29189    ast_manager_unregister("SIPshowregistry");
29190    ast_manager_unregister("SIPnotify");
29191    
29192    /* Kill TCP/TLS server threads */
29193    if (sip_tcp_desc.master) {
29194       ast_tcptls_server_stop(&sip_tcp_desc);
29195    }
29196    if (sip_tls_desc.master) {
29197       ast_tcptls_server_stop(&sip_tls_desc);
29198    }
29199 
29200    /* Kill all existing TCP/TLS threads */
29201    i = ao2_iterator_init(threadt, 0);
29202    while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) {
29203       pthread_t thread = th->threadid;
29204       th->stop = 1;
29205       pthread_kill(thread, SIGURG);
29206       pthread_join(thread, NULL);
29207       ao2_t_ref(th, -1, "decrement ref from iterator");
29208    }
29209    ao2_iterator_destroy(&i);
29210 
29211    /* Hangup all dialogs if they have an owner */
29212    i = ao2_iterator_init(dialogs, 0);
29213    while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
29214       if (p->owner)
29215          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
29216       ao2_t_ref(p, -1, "toss dialog ptr from iterator_next");
29217    }
29218    ao2_iterator_destroy(&i);
29219 
29220    ast_mutex_lock(&monlock);
29221    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
29222       pthread_cancel(monitor_thread);
29223       pthread_kill(monitor_thread, SIGURG);
29224       pthread_join(monitor_thread, NULL);
29225    }
29226    monitor_thread = AST_PTHREADT_STOP;
29227    ast_mutex_unlock(&monlock);
29228 
29229    /* Destroy all the dialogs and free their memory */
29230    i = ao2_iterator_init(dialogs, 0);
29231    while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
29232       dialog_unlink_all(p, TRUE, TRUE);
29233       ao2_t_ref(p, -1, "throw away iterator result");
29234    }
29235    ao2_iterator_destroy(&i);
29236 
29237    /* Free memory for local network address mask */
29238    ast_free_ha(localaddr);
29239 
29240    clear_realm_authentication(authl);
29241 
29242    destroy_escs();
29243 
29244    if (default_tls_cfg.certfile) {
29245       ast_free(default_tls_cfg.certfile);
29246    }
29247    if (default_tls_cfg.pvtfile) {
29248       ast_free(default_tls_cfg.pvtfile);
29249    }
29250    if (default_tls_cfg.cipher) {
29251       ast_free(default_tls_cfg.cipher);
29252    }
29253    if (default_tls_cfg.cafile) {
29254       ast_free(default_tls_cfg.cafile);
29255    }
29256    if (default_tls_cfg.capath) {
29257       ast_free(default_tls_cfg.capath);
29258    }
29259 
29260    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
29261    ASTOBJ_CONTAINER_DESTROY(&regl);
29262    ASTOBJ_CONTAINER_DESTROYALL(&submwil, sip_subscribe_mwi_destroy);
29263    ASTOBJ_CONTAINER_DESTROY(&submwil);
29264 
29265    ao2_t_ref(peers, -1, "unref the peers table");
29266    ao2_t_ref(peers_by_ip, -1, "unref the peers_by_ip table");
29267    ao2_t_ref(dialogs, -1, "unref the dialogs table");
29268    ao2_t_ref(threadt, -1, "unref the thread table");
29269 
29270    clear_sip_domains();
29271    ast_free_ha(sip_cfg.contact_ha);
29272    close(sipsock);
29273    sched_context_destroy(sched);
29274    con = ast_context_find(used_context);
29275    if (con) {
29276       ast_context_destroy(con, "SIP");
29277    }
29278    ast_unload_realtime("sipregs");
29279    ast_unload_realtime("sippeers");
29280    ast_cc_monitor_unregister(&sip_cc_monitor_callbacks);
29281    ast_cc_agent_unregister(&sip_cc_agent_callbacks);
29282 
29283    sip_reqresp_parser_exit();
29284    sip_unregister_tests();
29285 
29286    return 0;
29287 }

static void* unref_peer ( struct sip_peer *  peer,
char *  tag 
) [static]

helper functions to unreference various types of objects. By handling them this way, we don't have to declare the destructor on each call, which removes the chance of errors.

Definition at line 2825 of file chan_sip.c.

References ao2_t_ref.

Referenced by __sip_destroy(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), build_peer(), check_peer_ok(), complete_sip_peer(), complete_sip_registered_peer(), complete_sip_user(), create_addr(), expire_register(), find_peer(), function_sippeer(), handle_request_invite(), handle_request_notify(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), reg_source_db(), register_verify(), sip_devicestate(), sip_do_debug_peer(), sip_poke_all_peers(), sip_poke_noanswer(), sip_poke_peer(), sip_poke_peer_s(), sip_prune_realtime(), sip_show_inuse(), sip_show_user(), sip_show_users(), sip_unregister(), transmit_register(), and update_call_counter().

02826 {
02827    ao2_t_ref(peer, -1, tag);
02828    return NULL;
02829 }

static int update_call_counter ( struct sip_pvt *  fup,
int  event 
) [static]

update_call_counter: Handle call_limit for SIP devices Setting a call-limit will cause calls above the limit not to be accepted.

Remember that for a type=friend, there's one limit for the user and another for the peer, not a combined call limit. This will cause unexpected behaviour in subscriptions, since a "friend" is *two* devices in Asterisk, not one.

Thought: For realtime, we should probably update storage with inuse counter...

Returns:
0 if call is ok (no call limit, below threshold) -1 on rejection of call

Definition at line 5613 of file chan_sip.c.

References ao2_lock, ao2_unlock, ast_clear_flag, ast_copy_string(), ast_debug, AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_log(), ast_set_flag, ast_test_flag, FALSE, LOG_ERROR, LOG_NOTICE, name, ref_peer(), sip_cfg, sip_peer_hold(), sip_pvt_lock, sip_pvt_unlock, sipdebug, and unref_peer().

Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().

05614 {
05615    char name[256];
05616    int *inuse = NULL, *call_limit = NULL, *inringing = NULL;
05617    int outgoing = fup->outgoing_call;
05618    struct sip_peer *p = NULL;
05619 
05620    ast_debug(3, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
05621 
05622 
05623    /* Test if we need to check call limits, in order to avoid
05624       realtime lookups if we do not need it */
05625    if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD))
05626       return 0;
05627 
05628    ast_copy_string(name, fup->username, sizeof(name));
05629 
05630    /* Check the list of devices */
05631    if (fup->relatedpeer) {
05632       p = ref_peer(fup->relatedpeer, "ref related peer for update_call_counter");
05633       inuse = &p->inUse;
05634       call_limit = &p->call_limit;
05635       inringing = &p->inRinging;
05636       ast_copy_string(name, fup->peername, sizeof(name));
05637    }
05638    if (!p) {
05639       ast_debug(2, "%s is not a local device, no call limit\n", name);
05640       return 0;
05641    }
05642 
05643    switch(event) {
05644    /* incoming and outgoing affects the inUse counter */
05645    case DEC_CALL_LIMIT:
05646       /* Decrement inuse count if applicable */
05647       if (inuse) {
05648          sip_pvt_lock(fup);
05649          ao2_lock(p);
05650          if (*inuse > 0) {
05651             if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
05652                (*inuse)--;
05653                ast_clear_flag(&fup->flags[0], SIP_INC_COUNT);
05654             }
05655          } else {
05656             *inuse = 0;
05657          }
05658          ao2_unlock(p);
05659          sip_pvt_unlock(fup);
05660       }
05661 
05662       /* Decrement ringing count if applicable */
05663       if (inringing) {
05664          sip_pvt_lock(fup);
05665          ao2_lock(p);
05666          if (*inringing > 0) {
05667             if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) {
05668                (*inringing)--;
05669                ast_clear_flag(&fup->flags[0], SIP_INC_RINGING);
05670             }
05671          } else {
05672             *inringing = 0;
05673          }
05674          ao2_unlock(p);
05675          sip_pvt_unlock(fup);
05676       }
05677 
05678       /* Decrement onhold count if applicable */
05679       sip_pvt_lock(fup);
05680       ao2_lock(p);
05681       if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && sip_cfg.notifyhold) {
05682          ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD);
05683          ao2_unlock(p);
05684          sip_pvt_unlock(fup);
05685          sip_peer_hold(fup, FALSE);
05686       } else {
05687          ao2_unlock(p);
05688          sip_pvt_unlock(fup);
05689       }
05690       if (sipdebug)
05691          ast_debug(2, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", "peer", name, *call_limit);
05692       break;
05693 
05694    case INC_CALL_RINGING:
05695    case INC_CALL_LIMIT:
05696       /* If call limit is active and we have reached the limit, reject the call */
05697       if (*call_limit > 0 ) {
05698          if (*inuse >= *call_limit) {
05699             ast_log(LOG_NOTICE, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", "peer", name, *call_limit);
05700             unref_peer(p, "update_call_counter: unref peer p, call limit exceeded");
05701             return -1;
05702          }
05703       }
05704       if (inringing && (event == INC_CALL_RINGING)) {
05705          sip_pvt_lock(fup);
05706          ao2_lock(p);
05707          if (!ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) {
05708             (*inringing)++;
05709             ast_set_flag(&fup->flags[0], SIP_INC_RINGING);
05710          }
05711          ao2_unlock(p);
05712          sip_pvt_unlock(fup);
05713       }
05714       if (inuse) {
05715          sip_pvt_lock(fup);
05716          ao2_lock(p);
05717          if (!ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
05718             (*inuse)++;
05719             ast_set_flag(&fup->flags[0], SIP_INC_COUNT);
05720          }
05721          ao2_unlock(p);
05722          sip_pvt_unlock(fup);
05723       }
05724       if (sipdebug) {
05725          ast_debug(2, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", "peer", name, *inuse, *call_limit);
05726       }
05727       break;
05728 
05729    case DEC_CALL_RINGING:
05730       if (inringing) {
05731          sip_pvt_lock(fup);
05732          ao2_lock(p);
05733          if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) {
05734             if (*inringing > 0) {
05735                (*inringing)--;
05736             }
05737             ast_clear_flag(&fup->flags[0], SIP_INC_RINGING);
05738          }
05739          ao2_unlock(p);
05740          sip_pvt_unlock(fup);
05741       }
05742       break;
05743 
05744    default:
05745       ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event);
05746    }
05747 
05748    if (p) {
05749       ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", p->name);
05750       unref_peer(p, "update_call_counter: unref_peer from call counter");
05751    }
05752    return 0;
05753 }

static void update_connectedline ( struct sip_pvt *  p,
const void *  data,
size_t  datalen 
) [static]

Notify peer that the connected line has changed.

Definition at line 12299 of file chan_sip.c.

References add_header(), add_rpid(), add_sdp(), add_supported_header(), append_history, ast_debug, ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, FALSE, initialize_initreq(), is_method_allowed(), reqprep(), respprep(), S_COR, send_request(), send_response(), and TRUE.

Referenced by sip_indicate(), and skinny_indicate().

12300 {
12301 
12302    if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) {
12303       return;
12304    }
12305    if (!p->owner->connected.id.number.valid
12306       || ast_strlen_zero(p->owner->connected.id.number.str)) {
12307       return;
12308    }
12309 
12310    append_history(p, "ConnectedLine", "%s party is now %s <%s>",
12311       ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "Calling" : "Called",
12312       S_COR(p->owner->connected.id.name.valid, p->owner->connected.id.name.str, ""),
12313       S_COR(p->owner->connected.id.number.valid, p->owner->connected.id.number.str, ""));
12314 
12315    if (p->owner->_state == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
12316       struct sip_request req;
12317 
12318       if (p->invitestate == INV_CONFIRMED || p->invitestate == INV_TERMINATED) {
12319          reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1);
12320 
12321          add_header(&req, "Allow", ALLOWED_METHODS);
12322          add_supported_header(p, &req);
12323          add_rpid(&req, p);
12324          add_sdp(&req, p, FALSE, TRUE, FALSE);
12325 
12326          initialize_initreq(p, &req);
12327          p->lastinvite = p->ocseq;
12328          ast_set_flag(&p->flags[0], SIP_OUTGOING);
12329          p->invitestate = INV_CALLING;
12330          send_request(p, &req, XMIT_CRITICAL, p->ocseq);
12331       } else if (is_method_allowed(&p->allowed_methods, SIP_UPDATE)) {
12332          reqprep(&req, p, SIP_UPDATE, 0, 1);
12333          add_rpid(&req, p);
12334          add_header(&req, "X-Asterisk-rpid-update", "Yes");
12335          send_request(p, &req, XMIT_CRITICAL, p->ocseq);
12336       } else {
12337          /* We cannot send the update yet, so we have to wait until we can */
12338          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
12339       }
12340    } else {
12341       if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPID_IMMEDIATE)) {
12342          struct sip_request resp;
12343 
12344          if ((p->owner->_state == AST_STATE_RING) && !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT)) {
12345             respprep(&resp, p, "180 Ringing", &p->initreq);
12346             add_rpid(&resp, p);
12347             send_response(p, &resp, XMIT_UNRELIABLE, 0);
12348             ast_set_flag(&p->flags[0], SIP_RINGING);
12349          } else if (p->owner->_state == AST_STATE_RINGING) {
12350             respprep(&resp, p, "183 Session Progress", &p->initreq);
12351             add_rpid(&resp, p);
12352             send_response(p, &resp, XMIT_UNRELIABLE, 0);
12353             ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
12354          } else {
12355             ast_debug(1, "Unable able to send update to '%s' in state '%s'\n", p->owner->name, ast_state2str(p->owner->_state));
12356          }
12357       } else {
12358          ast_set_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND);
12359       }
12360    }
12361 }

static void update_peer ( struct sip_peer *  p,
int  expire 
) [static]

Update peer data in database (if used).

Definition at line 4522 of file chan_sip.c.

References ast_test_flag, realtime_update_peer(), and sip_cfg.

Referenced by register_verify().

04523 {
04524    int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
04525    if (sip_cfg.peer_rtupdate &&
04526        (p->is_realtime || rtcachefriends)) {
04527       realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, p->useragent, expire, p->deprecated_username, p->lastms);
04528    }
04529 }

static void update_provisional_keepalive ( struct sip_pvt *  pvt,
int  with_sdp 
) [static]

Definition at line 4041 of file chan_sip.c.

References ast_sched_add(), AST_SCHED_DEL_UNREF, send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().

Referenced by transmit_provisional_response().

04042 {
04043    AST_SCHED_DEL_UNREF(sched, pvt->provisional_keepalive_sched_id, dialog_unref(pvt, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr"));
04044 
04045    pvt->provisional_keepalive_sched_id = ast_sched_add(sched, PROVIS_KEEPALIVE_TIMEOUT,
04046       with_sdp ? send_provisional_keepalive_with_sdp : send_provisional_keepalive, dialog_ref(pvt, "Increment refcount to pass dialog pointer to sched callback"));
04047 }

static void update_redirecting ( struct sip_pvt *  p,
const void *  data,
size_t  datalen 
) [static]

Send a provisional response indicating that a call was redirected.

Definition at line 12285 of file chan_sip.c.

References add_diversion_header(), AST_STATE_UP, ast_test_flag, respprep(), and send_response().

Referenced by change_redirecting_information(), handle_request_invite(), handle_response(), handle_response_invite(), misdn_copy_redirecting_to_ast(), and sip_indicate().

12286 {
12287    struct sip_request resp;
12288 
12289    if (p->owner->_state == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
12290       return;
12291    }
12292 
12293    respprep(&resp, p, "181 Call is being forwarded", &p->initreq);
12294    add_diversion_header(&resp, p);
12295    send_response(p, &resp, XMIT_UNRELIABLE, 0);
12296 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Session Initiation Protocol (SIP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto,chan_local", } [static]

Definition at line 29295 of file chan_sip.c.

int apeerobjs = 0 [static]

Autocreated peer objects

Definition at line 762 of file chan_sip.c.

Referenced by sip_destroy_peer(), sip_show_objects(), and temp_peer().

char* app_dtmfmode = "SIPDtmfMode" [static]

Definition at line 28041 of file chan_sip.c.

char* app_sipaddheader = "SIPAddHeader" [static]

Definition at line 28042 of file chan_sip.c.

char* app_sipremoveheader = "SIPRemoveHeader" [static]

Definition at line 28043 of file chan_sip.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 29295 of file chan_sip.c.

struct sip_auth* authl = NULL [static]

Authentication list for realm authentication.

Todo:
Move the sip_auth list to AST_LIST

Definition at line 1110 of file chan_sip.c.

Referenced by build_reply_digest(), reload_config(), sip_show_settings(), and unload_module().

int authlimit = DEFAULT_AUTHLIMIT [static]

Definition at line 563 of file chan_sip.c.

Referenced by __init_manager(), _sip_tcp_helper_thread(), and session_do().

int authtimeout = DEFAULT_AUTHTIMEOUT [static]

Definition at line 564 of file chan_sip.c.

Referenced by __init_manager(), do_message(), and sip_check_authtimeout().

struct ast_sockaddr bindaddr

UDP: The address we bind to

Definition at line 1130 of file chan_sip.c.

int can_parse_xml [static]

We use libxml2 in order to parse XML that may appear in the body of a SIP message. Currently, the only usage is for parsing PIDF bodies of incoming PUBLISH requests in the call-completion event package. This variable is set at module load time and may be checked at runtime to determine if XML parsing support was found.

Definition at line 755 of file chan_sip.c.

Referenced by build_peer(), and load_module().

struct epa_static_data cc_epa_static_data [static]

Definition at line 883 of file chan_sip.c.

Referenced by load_module().

struct sip_esc_publish_callbacks cc_esc_publish_callbacks [static]

Initial value:

 {
   .initial_handler = cc_esc_publish_handler,
   .modify_handler = cc_esc_publish_handler,
}

Definition at line 931 of file chan_sip.c.

unsigned int chan_idx [static]

used in naming sip channel

Definition at line 705 of file chan_sip.c.

Referenced by sip_new().

struct ast_threadstorage check_auth_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_check_auth_buf , .custom_init = NULL , } [static]

Definition at line 13584 of file chan_sip.c.

Referenced by check_auth(), and transmit_fake_auth_response().

struct ast_custom_function checksipdomain_function [static]

Initial value:

 {
   .name = "CHECKSIPDOMAIN",
   .read = func_check_sipdomain,
}

Definition at line 18502 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_sip[] [static]

SIP Cli commands definition.

Definition at line 28590 of file chan_sip.c.

Referenced by load_module(), and unload_module().

const char config[] = "sip.conf" [static]

Main configuration file

Definition at line 577 of file chan_sip.c.

struct ast_sockaddr debugaddr [static]

Definition at line 1174 of file chan_sip.c.

char default_callerid[AST_MAX_EXTENSION] [static]

Default caller ID for sip messages

Definition at line 678 of file chan_sip.c.

Referenced by initreqprep(), and sip_show_settings().

char default_engine[256] [static]

Default RTP engine

Definition at line 689 of file chan_sip.c.

Referenced by ast_speech_register(), ast_speech_unregister(), find_engine(), set_peer_defaults(), and sip_alloc().

int default_expiry = DEFAULT_DEFAULT_EXPIRY [static]

Definition at line 559 of file chan_sip.c.

Referenced by handle_response_register(), parse_register_contact(), sip_register(), sip_send_all_registers(), and sip_show_settings().

char default_fromdomain[AST_MAX_EXTENSION] [static]

Default domain on outound messages

Definition at line 680 of file chan_sip.c.

Referenced by sip_alloc(), sip_show_settings(), transmit_register(), and transmit_response_using_temp().

int default_fromdomainport [static]

Default domain port on outbound messages

Definition at line 681 of file chan_sip.c.

Referenced by sip_alloc(), sip_show_settings(), and transmit_response_using_temp().

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled.

Definition at line 567 of file chan_sip.c.

char default_language[MAX_LANGUAGE] [static]

Default language setting for new channels

Definition at line 677 of file chan_sip.c.

Referenced by set_peer_defaults(), and sip_show_settings().

int default_maxcallbitrate [static]

Maximum bitrate for call

Definition at line 690 of file chan_sip.c.

Referenced by build_peer(), set_peer_defaults(), sip_alloc(), and sip_show_settings().

char default_mohinterpret[MAX_MUSICCLASS] [static]

Global setting for moh class to use when put on hold

Definition at line 685 of file chan_sip.c.

Referenced by set_peer_defaults(), sip_alloc(), and sip_show_settings().

char default_mohsuggest[MAX_MUSICCLASS] [static]

Global setting for moh class to suggest when putting a bridged channel on hold

Definition at line 686 of file chan_sip.c.

Referenced by set_peer_defaults(), sip_alloc(), and sip_show_settings().

char default_mwi_from[80] [static]

Default caller ID for MWI updates

Definition at line 679 of file chan_sip.c.

Referenced by sip_send_mwi_to_peer().

char default_notifymime[AST_MAX_EXTENSION] [static]

Default MIME media type for MWI notify messages

Definition at line 682 of file chan_sip.c.

Referenced by sip_show_settings(), and transmit_notify_with_mwi().

char default_parkinglot[AST_MAX_CONTEXT] [static]

Parkinglot

Definition at line 688 of file chan_sip.c.

struct ast_codec_pref default_prefs [static]

Default codec prefs

Definition at line 691 of file chan_sip.c.

Referenced by config_load(), config_parse_variables(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and temp_peer().

unsigned int default_primary_transport [static]

Default primary Transport (enum sip_transport) for outbound connections to devices

Definition at line 693 of file chan_sip.c.

Referenced by build_peer(), set_peer_defaults(), and sip_show_settings().

const int DEFAULT_PUBLISH_EXPIRES = 3600 [static]

Definition at line 926 of file chan_sip.c.

Referenced by determine_sip_publish_type(), and transmit_publish().

int default_qualify [static]

Default Qualify= setting

Definition at line 684 of file chan_sip.c.

Referenced by build_peer(), set_peer_defaults(), and sip_show_settings().

struct ast_tls_config default_tls_cfg [static]

Default TLS connection configuration.

Definition at line 2164 of file chan_sip.c.

Referenced by reload_config(), sip_prepare_socket(), sip_show_settings(), and unload_module().

unsigned int default_transports [static]

Default Transports (enum sip_transport) that are acceptable

Definition at line 692 of file chan_sip.c.

Referenced by build_peer(), set_peer_defaults(), and sip_show_settings().

char default_vmexten[AST_MAX_EXTENSION] [static]

Default From Username on MWI updates

Definition at line 683 of file chan_sip.c.

Referenced by set_peer_defaults(), sip_show_settings(), and transmit_notify_with_mwi().

struct ao2_container* dialogs [static]

Here we implement the container for dialogs (sip_pvt), defining generic wrapper functions to ease the transition from the current implementation (a single linked list) to a different container. In addition to a reference to the container, we need functions to lock/unlock the container and individual items, and functions to add/remove references to the individual items.

Definition at line 1080 of file chan_sip.c.

Referenced by complete_sipch(), create_addr_from_peer(), dialog_unlink_all(), do_monitor(), find_call(), get_sip_pvt_byid_locked(), load_module(), sip_alloc(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), sip_show_channel(), sip_show_channels(), sip_show_channelstats(), sip_show_history(), sip_show_objects(), and unload_module().

struct _map_x_s dtmfstr[] [static]

mapping between dtmf flags and strings

Definition at line 16107 of file chan_sip.c.

Referenced by conf_run(), dtmfmode2str(), handle_link_data(), handle_remote_data(), send_dtmf(), and str2dtmfmode().

unsigned int dumphistory [static]

Dump history to verbose before destroying SIP dialog

Definition at line 728 of file chan_sip.c.

Referenced by __sip_destroy(), and append_history_full().

int esc_etag_counter [static]

Used to create new entity IDs by ESCs.

Definition at line 925 of file chan_sip.c.

const int ESC_MAX_BUCKETS = 37 [static]

Definition at line 960 of file chan_sip.c.

struct event_state_compositor event_state_compositors[] [static]

The Event State Compositors.

An Event State Compositor is an entity which accepts PUBLISH requests and acts appropriately based on these requests.

The actual event_state_compositor structure is simply an ao2_container of sip_esc_entrys. When an incoming PUBLISH is received, we can match the appropriate sip_esc_entry using the entity ID of the incoming PUBLISH.

Referenced by destroy_escs(), get_esc(), and initialize_escs().

struct ast_sockaddr externaddr [static]

our external IP address/port for SIP sessions. externaddr.sin_addr is only set when we know we might be behind a NAT, and this is done using a variety of (mutually exclusive) ways from the config file:

+ with "externaddr = host[:port]" we specify the address/port explicitly. The address is looked up only once when (re)loading the config file;

+ with "externhost = host[:port]" we do a similar thing, but the hostname is stored in externhost, and the hostname->IP mapping is refreshed every 'externrefresh' seconds;

Other variables (externhost, externexpire, externrefresh) are used to support the above functions. External IP address if we are behind NAT

Definition at line 1155 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and sip_show_settings().

time_t externexpire [static]

Expiration counter for re-resolving external host name in dynamic DNS

Definition at line 1159 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor().

char externhost[MAXHOSTNAMELEN] [static]

External host name

Definition at line 1158 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and sip_show_settings().

int externrefresh = 10 [static]

Refresh timer for DNS-based external address (dyndns)

Definition at line 1160 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), and sip_show_settings().

uint16_t externtcpport [static]

external tcp port

Definition at line 1161 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor().

uint16_t externtlsport [static]

external tls port

Definition at line 1162 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor().

struct _map_x_s faxecmodes[] [static]

Definition at line 16546 of file chan_sip.c.

Referenced by faxec2str().

int global_authfailureevents [static]

Whether we send authentication failure manager events or not. Default no.

Definition at line 732 of file chan_sip.c.

Referenced by register_verify(), and sip_show_settings().

unsigned int global_autoframing [static]

Turn autoframing on or off.

Definition at line 736 of file chan_sip.c.

Referenced by set_peer_defaults(), sip_alloc(), and sip_show_settings().

int global_callcounter [static]

Enable call counters for all devices. This is currently enabled by setting the peer call-limit to INT_MAX. When we remove the call-limit from the code, we can make it with just a boolean flag in the device structure

Definition at line 716 of file chan_sip.c.

Referenced by set_peer_defaults(), and sip_show_settings().

unsigned int global_cos_audio [static]

802.1p class of service for audio RTP packets

Definition at line 724 of file chan_sip.c.

Referenced by dialog_initialize_rtp(), sip_alloc(), and sip_show_settings().

unsigned int global_cos_sip [static]

802.1p class of service for SIP packets

Definition at line 723 of file chan_sip.c.

Referenced by sip_show_settings().

unsigned int global_cos_text [static]

802.1p class of service for text RTP packets

Definition at line 726 of file chan_sip.c.

Referenced by sip_show_settings().

unsigned int global_cos_video [static]

802.1p class of service for video RTP packets

Definition at line 725 of file chan_sip.c.

Referenced by sip_show_settings().

int global_dynamic_exclude_static = 0 [static]

Exclude static peers from contact registrations

Definition at line 746 of file chan_sip.c.

Referenced by build_peer().

struct ast_flags global_flags[3] = {{0}} [static]

global SIP_ flags

Definition at line 766 of file chan_sip.c.

struct ast_jb_conf global_jbconf [static]

Global jitterbuffer configuration

Definition at line 575 of file chan_sip.c.

int global_match_auth_username [static]

Match auth username if available instead of From: Default off.

Definition at line 706 of file chan_sip.c.

Referenced by check_user_full(), and sip_show_settings().

int global_max_se [static]

Highest threshold for session refresh interval

Definition at line 744 of file chan_sip.c.

Referenced by build_peer(), handle_request_invite(), set_peer_defaults(), sip_show_settings(), and st_get_se().

int global_min_se [static]

Lowest threshold for session refresh interval

Definition at line 743 of file chan_sip.c.

Referenced by build_peer(), set_peer_defaults(), sip_show_settings(), and st_get_se().

int global_prematuremediafilter [static]

Enable/disable premature frames in a call (causing 183 early media)

Definition at line 709 of file chan_sip.c.

Referenced by sip_show_settings(), and sip_write().

int global_qualify_gap [static]

Time between our group of peer pokes

Definition at line 738 of file chan_sip.c.

Referenced by sip_poke_all_peers().

int global_qualify_peers [static]

Number of peers to poke at a given time

Definition at line 739 of file chan_sip.c.

Referenced by sip_poke_all_peers().

int global_qualifyfreq [static]

Qualify frequency

Definition at line 737 of file chan_sip.c.

Referenced by build_peer(), set_peer_defaults(), and sip_show_settings().

int global_reg_timeout [static]

Global time between attempts for outbound registrations

Definition at line 713 of file chan_sip.c.

Referenced by sip_show_settings(), and transmit_register().

int global_regattempts_max [static]

Registration attempts before giving up

Definition at line 714 of file chan_sip.c.

Referenced by sip_reg_timeout(), and sip_show_settings().

int global_relaxdtmf [static]

Relax DTMF

Definition at line 708 of file chan_sip.c.

Referenced by enable_dsp_detect(), and sip_show_settings().

int global_rtpholdtimeout [static]

Time out call if no RTP during hold

Definition at line 711 of file chan_sip.c.

Referenced by build_peer(), dialog_initialize_rtp(), set_peer_defaults(), and sip_show_settings().

int global_rtpkeepalive [static]

Send RTP keepalives

Definition at line 712 of file chan_sip.c.

Referenced by build_peer(), set_peer_defaults(), and sip_show_settings().

int global_rtptimeout [static]

Time out call if no RTP

Definition at line 710 of file chan_sip.c.

Referenced by build_peer(), dialog_initialize_rtp(), set_peer_defaults(), and sip_show_settings().

char global_sdpowner[AST_MAX_EXTENSION] [static]

SDP owner name for the SIP channel

Definition at line 731 of file chan_sip.c.

Referenced by add_sdp(), and sip_show_settings().

char global_sdpsession[AST_MAX_EXTENSION] [static]

SDP session name for the SIP channel

Definition at line 730 of file chan_sip.c.

Referenced by add_sdp(), and sip_show_settings().

int global_shrinkcallerid [static]

enable or disable shrinking of caller id

Definition at line 715 of file chan_sip.c.

Referenced by check_peer_ok(), check_user_full(), get_pai(), and get_rpid().

enum st_mode global_st_mode [static]

Mode of operation for Session-Timers

Definition at line 741 of file chan_sip.c.

Referenced by build_peer(), set_peer_defaults(), sip_show_settings(), and st_get_mode().

enum st_refresher global_st_refresher [static]

Session-Timer refresher

Definition at line 742 of file chan_sip.c.

Referenced by build_peer(), set_peer_defaults(), sip_show_settings(), and st_get_refresher().

int global_t1 [static]

T1 time

Definition at line 733 of file chan_sip.c.

Referenced by create_addr(), set_peer_defaults(), sip_alloc(), sip_scheddestroy(), and sip_show_settings().

int global_t1min [static]

T1 roundtrip time minimum

Definition at line 734 of file chan_sip.c.

Referenced by build_peer(), check_peer_ok(), create_addr_from_peer(), and sip_show_settings().

int global_t38_maxdatagram [static]

global T.38 FaxMaxDatagram override

Definition at line 767 of file chan_sip.c.

Referenced by handle_request_invite(), handle_t38_options(), set_peer_defaults(), sip_alloc(), and sip_show_settings().

int global_timer_b [static]

Timer B - RFC 3261 Section 17.1.1.2

Definition at line 735 of file chan_sip.c.

Referenced by build_peer(), create_addr(), set_peer_defaults(), sip_alloc(), sip_scheddestroy(), and sip_show_settings().

unsigned int global_tos_audio [static]

IP type of service for audio RTP packets

Definition at line 720 of file chan_sip.c.

Referenced by dialog_initialize_rtp(), sip_alloc(), and sip_show_settings().

unsigned int global_tos_sip [static]

IP type of service for SIP packets

Definition at line 719 of file chan_sip.c.

Referenced by sip_show_settings().

unsigned int global_tos_text [static]

IP type of service for text RTP packets

Definition at line 722 of file chan_sip.c.

Referenced by sip_show_settings().

unsigned int global_tos_video [static]

IP type of service for video RTP packets

Definition at line 721 of file chan_sip.c.

Referenced by sip_show_settings().

char global_useragent[AST_MAX_EXTENSION] [static]

Useragent for the SIP channel

Definition at line 729 of file chan_sip.c.

Referenced by curl_instance_init(), initreqprep(), reqprep(), respprep(), sip_show_settings(), and transmit_register().

const int HASH_DIALOG_SIZE = 563 [static]

Definition at line 824 of file chan_sip.c.

Referenced by load_module().

const int HASH_PEER_SIZE = 563 [static]

Size of peer hash table, prime number preferred!

Definition at line 823 of file chan_sip.c.

Referenced by load_module().

struct _map_x_s insecurestr[] [static]

Definition at line 16128 of file chan_sip.c.

Referenced by insecure2str().

struct ast_sockaddr internip [static]

our (internal) default address/port to put in SIP/SDP messages internip is initialized picking a suitable address from one of the interfaces, and the same port number we bind to. It is used as the default address/port in SIP messages, and as the default address (but not port) in SDP messages.

Definition at line 1138 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), sip_alloc(), transmit_register(), and transmit_response_using_temp().

struct invstate2stringtable invitestate2string[] [static]

Readable descriptions of device states.

Note:
Should be aligned to above table as index

Referenced by show_chanstats_cb().

struct io_context* io [static]

The IO context

Definition at line 790 of file chan_sip.c.

struct ast_ha* localaddr [static]

List of local networks We store "localnet" addresses from the config file into an access list, marked as 'DENY', so the call to ast_apply_ha() will return AST_SENSE_DENY for 'local' addresses, and AST_SENSE_ALLOW for 'non local' (i.e. presumably public) addresses.

List of local networks, on the same side of NAT as this Asterisk

Definition at line 1170 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), sip_show_settings(), and unload_module().

int max_expiry = DEFAULT_MAX_EXPIRY [static]

Maximum accepted registration time

Definition at line 558 of file chan_sip.c.

Referenced by handle_request_subscribe(), handle_response_register(), parse_register_contact(), and sip_show_settings().

struct ast_sockaddr media_address [static]

External RTP IP address if we are behind NAT

Definition at line 1156 of file chan_sip.c.

Referenced by get_our_media_address().

int min_expiry = DEFAULT_MIN_EXPIRY [static]

Minimum accepted registration time

Definition at line 557 of file chan_sip.c.

Referenced by handle_request_subscribe(), parse_register_contact(), sip_show_settings(), and transmit_response_with_minexpires().

pthread_t monitor_thread = AST_PTHREADT_NULL [static]

This is the thread for the monitor which checks for input on the channels which are not currently in use.

Definition at line 784 of file chan_sip.c.

ast_mutex_t monlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static]

Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.

Definition at line 778 of file chan_sip.c.

int mwi_expiry = DEFAULT_MWI_EXPIRY [static]

Definition at line 560 of file chan_sip.c.

Referenced by __sip_subscribe_mwi_do(), and handle_response_subscribe().

ast_mutex_t netlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static]

Definition at line 774 of file chan_sip.c.

int network_change_event_sched_id = -1 [static]

Definition at line 770 of file chan_sip.c.

struct ast_event_sub* network_change_event_subscription [static]

subscription id for network change events

Definition at line 769 of file chan_sip.c.

const char notify_config[] = "sip_notify.conf" [static]

Configuration file for sending Notify with CLI commands to reconfigure or reboot phones

Definition at line 578 of file chan_sip.c.

Referenced by sip_cli_notify().

struct ast_config* notify_types = NULL [static]

The list of manual NOTIFY types we know how to send

Definition at line 1176 of file chan_sip.c.

Referenced by complete_sipnotify(), and sip_cli_notify().

int ourport_tcp [static]

The port used for TCP connections

Definition at line 1172 of file chan_sip.c.

int ourport_tls [static]

The port used for TCP/TLS connections

Definition at line 1173 of file chan_sip.c.

struct ao2_container* peers [static]

The peer list: Users, Peers and Friends.

Definition at line 1089 of file chan_sip.c.

struct ao2_container* peers_by_ip [static]

Definition at line 1090 of file chan_sip.c.

Referenced by find_peer(), load_module(), parse_register_contact(), register_verify(), sip_prune_realtime(), unlink_marked_peers_from_tables(), unlink_peer_from_tables(), and unload_module().

struct ast_data_handler peers_data_provider [static]

Initial value:

Definition at line 29002 of file chan_sip.c.

unsigned int recordhistory [static]

Record SIP history. Off by default

Definition at line 727 of file chan_sip.c.

Referenced by append_history_full(), sip_alloc(), sip_set_history(), sip_show_history(), and sip_show_settings().

struct _map_x_s referstatusstrings[] [static]

Definition at line 805 of file chan_sip.c.

Referenced by referstatus2str().

struct ast_register_list regl [static]

The register list: Other SIP proxies we register with and receive calls from.

Referenced by load_module(), manager_show_registry(), reload_config(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().

int regobjs = 0 [static]

Registry objects

Definition at line 763 of file chan_sip.c.

Referenced by sip_register(), sip_registry_destroy(), sip_send_all_registers(), and sip_show_objects().

struct _map_x_s regstatestrings[] [static]

Definition at line 12363 of file chan_sip.c.

Referenced by regstate2str().

int rpeerobjs = 0 [static]

Realtime peers

Definition at line 761 of file chan_sip.c.

Referenced by build_peer(), expire_register(), sip_destroy_peer(), and sip_show_objects().

struct sched_context* sched

The scheduling context

Definition at line 789 of file chan_sip.c.

enum ast_cc_service_type service

Definition at line 828 of file chan_sip.c.

Referenced by cc_generic_monitor_request_cc(), create_addr(), launch_ha_netscript(), service_string_to_service_type(), and sip_cc_monitor_request_cc().

const char* service_string

Definition at line 829 of file chan_sip.c.

struct ast_cc_agent_callbacks sip_cc_agent_callbacks [static]

Definition at line 1614 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_cc_monitor_callbacks sip_cc_monitor_callbacks [static]

Definition at line 1881 of file chan_sip.c.

Referenced by load_module(), and unload_module().

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.

Note:
in the future we could have multiple of these (per domain, per device group etc) use this macro when ast_uri_decode is dependent on pedantic checking to be on.

Definition at line 696 of file chan_sip.c.

Referenced by __get_header(), __sip_subscribe_mwi_do(), _sip_show_peer(), add_header(), ast_sip_ouraddrfor(), build_peer(), change_hold_state(), check_user_full(), create_addr(), destroy_association(), do_magic_pickup(), find_call(), find_calling_channel(), get_also_info(), get_destination(), get_realm(), get_refer_info(), get_sip_pvt_byid_locked(), handle_incoming(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_options(), handle_request_refer(), handle_request_subscribe(), handle_response_invite(), handle_response_peerpoke(), initreqprep(), obproxy_get(), parse_register_contact(), proxy_update(), realtime_update_peer(), ref_proxy(), register_peer_exten(), register_verify(), reload_config(), set_peer_defaults(), sip_alloc(), sip_new(), sip_poke_noanswer(), sip_request_call(), sip_set_rtp_peer(), sip_show_settings(), state_notify_build_xml(), transmit_register(), unload_module(), update_call_counter(), and update_peer().

struct ast_data_entry sip_data_providers[] [static]

Initial value:

 {
   AST_DATA_ENTRY("asterisk/channel/sip/peers", &peers_data_provider),
}

Definition at line 29007 of file chan_sip.c.

Referenced by load_module().

struct ast_custom_function sip_header_function [static]

Initial value:

 {
   .name = "SIP_HEADER",
   .read = func_header_read,
}

Definition at line 18483 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct cfsip_methods sip_methods[] [static]

The core structure to setup dialogs. We parse incoming messages by using structure and then route the messages according to the type.

Note:
Note that sip_methods[i].id == i must hold or the code breaks

Referenced by __sip_autodestruct(), __sip_destroy(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), dialog_initialize_rtp(), dialog_needdestroy(), do_proxy_auth(), find_call(), find_sip_method(), get_destination(), handle_incoming(), handle_request_bye(), handle_request_invite(), handle_request_register(), handle_request_subscribe(), handle_response(), init_req(), initialize_initreq(), initreqprep(), method_match(), reqprep(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_scheddestroy(), and transmit_register().

struct ao2_container* sip_monitor_instances

Definition at line 1808 of file chan_sip.c.

Referenced by cc_handle_publish_error(), handle_cc_notify(), handle_response(), load_module(), sip_cc_monitor_destructor(), and sip_monitor_instance_init().

struct sip_reasons sip_reason_table[] [static]

Diversion header reasons.

The core defines a bunch of constants used to define redirecting reasons. This provides a translation table between those and the strings which may be present in a SIP Diversion header

Referenced by sip_reason_code_to_str(), and sip_reason_str_to_code().

ast_mutex_t sip_reload_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static]

Definition at line 780 of file chan_sip.c.

Referenced by do_monitor(), and sip_reload().

int sip_reloading = FALSE [static]

Flag for avoiding multiple reloads at the same time

Definition at line 786 of file chan_sip.c.

Referenced by do_monitor(), and sip_reload().

enum channelreloadreason sip_reloadreason [static]

Reason for last reload/load of configuration

Definition at line 787 of file chan_sip.c.

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

struct ast_rtp_glue sip_rtp_glue [static]

Definition at line 28032 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_tcptls_session_args sip_tcp_desc [static]

The TCP server definition.

Definition at line 2167 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), sip_show_settings(), transmit_register(), and unload_module().

struct ast_channel_tech sip_tech

Definition of this channel for PBX channel registration.

Definition at line 1568 of file chan_sip.c.

Referenced by load_module(), sip_new(), and unload_module().

struct ast_channel_tech sip_tech_info

This version of the sip channel tech has no send_digit_begin callback so that the core knows that the channel does not want DTMF BEGIN frames. The struct is initialized just before registering the channel driver, and is for use with channels using SIP INFO DTMF.

Definition at line 1603 of file chan_sip.c.

Referenced by load_module(), and sip_new().

struct ast_tls_config sip_tls_cfg [static]

Working TLS connection configuration.

Definition at line 2161 of file chan_sip.c.

struct ast_tcptls_session_args sip_tls_desc [static]

The TCP/TLS server definition.

Definition at line 2178 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), sip_show_settings(), and unload_module().

struct ast_udptl_protocol sip_udptl [static]

Initial value:

 {
   type: "SIP",
   get_udptl_info: sip_get_udptl_peer,
   set_udptl_peer: sip_set_udptl_peer,
}
Interface structure with callbacks used to connect to UDPTL module.

Definition at line 2955 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function sipchaninfo_function [static]

Initial value:

 {
   .name = "SIPCHANINFO",
   .read = function_sipchaninfo_read,
}
Structure to declare a dialplan function: SIPCHANINFO.

Definition at line 18667 of file chan_sip.c.

Referenced by load_module(), and unload_module().

enum sip_debug_e sipdebug [static]

Definition at line 797 of file chan_sip.c.

Referenced by __sip_ack(), __sip_reliable_xmit(), __sip_semi_ack(), obproxy_get(), parse_request(), retrans_pkt(), sip_call(), sip_debug_test_addr(), sip_debug_test_pvt(), sip_hangup(), sip_reregister(), transmit_refer(), transmit_register(), and update_call_counter().

int sipdebug_text [static]

extra debugging for 'text' related events. At the moment this is set together with sip_debug_console.

Note:
It should either go away or be implemented properly.

Definition at line 803 of file chan_sip.c.

Referenced by add_sdp(), sip_do_debug(), and sip_rtp_read().

struct ast_custom_function sippeer_function [static]

Initial value:

 {
   .name = "SIPPEER",
   .read = function_sippeer,
}
Structure to declare a dialplan function: SIPPEER.

Definition at line 18601 of file chan_sip.c.

Referenced by load_module(), and unload_module().

int sipsock = -1 [static]

Main socket for UDP SIP communication.

sipsock is shared between the SIP manager thread (which handles reload requests), the udp io handler (sipsock_read()) and the user routines that issue udp writes (using __sip_xmit()). The socket is -1 only when opening fails (this is a permanent condition), or when we are handling a reload() that changes its address (this is a transient situation during which we might have a harmless race, see below). Because the conditions for the race to be possible are extremely rare, we don't want to pay the cost of locking on every I/O. Rather, we remember that when the race may occur, communication is bound to fail anyways, so we just live with this event and let the protocol handle this above us.

Definition at line 1128 of file chan_sip.c.

Referenced by do_monitor(), process_via(), reg_source_db(), sip_prepare_socket(), sipsock_read(), and unload_module().

int* sipsock_read_id [static]

ID of IO entry for sipsock FD

Definition at line 791 of file chan_sip.c.

Referenced by do_monitor().

int speerobjs = 0 [static]

Static peers

Definition at line 760 of file chan_sip.c.

Referenced by build_peer(), sip_destroy_peer(), sip_poke_all_peers(), and sip_show_objects().

enum sip_cc_notify_state state

Definition at line 849 of file chan_sip.c.

Referenced by adpcm(), adsi_process(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_moh_files_next(), clearflag(), decode(), find_cache(), gen_alloc(), gen_closestream(), gen_generate(), gen_nextfile(), gen_readframe(), gen_release(), getdisplaybyname(), getflagbyname(), getkeybyname(), getstatebyname(), getsubbyname(), handle_characters(), handle_end_element(), handle_start_element(), iax2_write(), local_ast_moh_cleanup(), local_ast_moh_start(), moh_alloc(), moh_files_alloc(), moh_files_generator(), moh_files_release(), onevent(), parse_cdata(), parse_tag(), process_opcode(), process_returncode(), register_verify(), setflag(), showdisplay(), showkeys(), stun_process_attr(), subscript(), update_caldav(), update_exchangecal(), and update_registry().

const char* state_string

Definition at line 850 of file chan_sip.c.

Referenced by transmit_cc_notify().

struct _map_x_s stmodes[] [static]

Report Peer status in character string.

Returns:
0 if peer is unreachable, 1 if peer is online, -1 if unmonitored

Definition at line 15604 of file chan_sip.c.

Referenced by stmode2str(), and str2stmode().

struct _map_x_s strefreshers[] [static]

Definition at line 15622 of file chan_sip.c.

Referenced by str2strefresher(), and strefresher2str().

struct ast_subscription_mwi_list submwil [static]

The MWI subscription list.

Referenced by load_module(), sip_send_all_mwi_subscriptions(), sip_show_mwi(), sip_subscribe_mwi(), and unload_module().

struct cfsubscription_types subscription_types[] [static]

Subscription types that we support. We support

Referenced by find_subscription_type(), and subscription_type2str().

struct ao2_container* threadt [static]

The table of TCP threads.

Definition at line 1086 of file chan_sip.c.

Referenced by _sip_tcp_helper_thread(), load_module(), sip_prepare_socket(), sip_show_tcp(), sip_tcp_locate(), sip_tcptls_write(), sip_threadinfo_create(), and unload_module().

struct ast_threadstorage ts_temp_pvt = { .once = PTHREAD_ONCE_INIT , .key_init = __init_ts_temp_pvt , .custom_init = temp_pvt_init , } [static]

Definition at line 1106 of file chan_sip.c.

Referenced by transmit_response_using_temp().

int unauth_sessions = 0 [static]

Definition at line 562 of file chan_sip.c.

Referenced by _sip_tcp_helper_thread(), action_login(), and session_do().

char used_context[AST_MAX_CONTEXT] [static]

name of automatically created context for unloading

Definition at line 772 of file chan_sip.c.

Referenced by unload_module().


Generated on Mon Jun 27 16:51:10 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7