#include "asterisk.h"
#include <ctype.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/signal.h>
#include <regex.h>
#include "asterisk/network.h"
#include "asterisk/paths.h"
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.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/astobj.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/netsock.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/tcptls.h"
Go to the source code of this file.
Data Structures | |
struct | __show_chan_arg |
argument for the 'show channels|subscriptions' callback. More... | |
struct | _map_x_s |
generic struct to map between strings and integers. Fill it with x-s pairs, terminate with an entry with s = NULL; Then you can call map_x_s(...) to map an integer to a string, and map_s_x() for the string -> integer mapping. More... | |
struct | ast_peer_list |
The peer list: Peers and Friends. More... | |
struct | ast_register_list |
The register list: Other SIP proxies we register with and place calls to. More... | |
struct | ast_user_list |
The user list: Users and friends. 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 | cfsip_options |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More... | |
struct | cfsubscription_types |
Subscription types that we support. We support
| |
struct | domain |
Domain data structure. More... | |
struct | domain_list |
struct | sip_auth |
sip_auth: Credentials for authentication to other SIP services More... | |
struct | sip_dual |
structure used in transfers More... | |
struct | sip_history |
sip_history: Structure for saving transactions within a SIP dialog More... | |
struct | sip_history_head |
struct | sip_invite_param |
Parameters to the transmit_invite function. More... | |
struct | sip_mailbox |
A peer's mailbox. More... | |
struct | sip_peer |
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host). More... | |
struct | sip_pkt |
sip packet - raw format for outbound packets that are sent or scheduled for transmission Packets are linked in a list, whose head is in the struct sip_pvt they belong to. Each packet holds a reference to the parent struct sip_pvt. This structure is allocated in __sip_reliable_xmit() and only for packets that require retransmissions. More... | |
struct | sip_proxy |
definition of a sip proxy server More... | |
struct | sip_pvt |
sip_pvt: structures used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized by sip_alloc(), the descriptor goes into the list of descriptors (dialoglist). More... | |
struct | sip_pvt::request_queue |
struct | sip_refer |
Structure to handle SIP transfers. Dynamically allocated when needed. More... | |
struct | sip_registry |
Registrations with other SIP proxies Created by sip_register(), the entry is linked in the 'regl' list, and never deleted (other than at 'sip reload' or module unload times). The entry always has a pending timeout, either waiting for an ACK to the REGISTER message (in which case we have to retransmit the request), or waiting for the next REGISTER message to be sent (either the initial one, or once the previously completed registration one expires). The registration can be in one of many states, though at the moment the handling is a bit mixed. Note that the entire evolution of sip_registry (transmissions, incoming packets and timeouts) is driven by one single thread, do_monitor(), so there is almost no synchronization issue. The only exception is the sip_pvt creation/lookup, as the dialoglist is also manipulated by other threads. More... | |
struct | sip_request |
sip_request: The data grabbed from the UDP socket More... | |
struct | sip_route |
Structure to save routing information for a SIP session. More... | |
struct | sip_settings |
a place to store all global settings for the sip channel driver More... | |
struct | sip_socket |
struct | sip_st_cfg |
Structure that encapsulates all attributes related to configuration of SIP Session-Timers feature on a per user/peer basis. More... | |
struct | sip_st_dlg |
Structure that encapsulates all attributes related to running SIP Session-Timers feature on a per dialog basis. More... | |
struct | sip_threadinfo |
struct | sip_user |
Structure for SIP user data. User's place calls to us. More... | |
struct | t38properties |
T.38 channel settings (at some point we need to make this alloc'ed. More... | |
struct | threadl |
The thread list of TCP threads. More... | |
Object counters @{ | |
| |
#define | DEC_CALL_LIMIT 0 |
#define | DEC_CALL_RINGING 2 |
#define | INC_CALL_LIMIT 1 |
#define | INC_CALL_RINGING 3 |
enum | domain_mode { SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG } |
Modes for SIP domain handling in the PBX. More... | |
static int | apeerobjs = 0 |
static struct ast_flags | global_flags [2] = {{0}} |
static struct io_context * | io |
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 = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
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 = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
static int | regobjs = 0 |
static int | rpeerobjs = 0 |
static int | ruserobjs = 0 |
static struct sched_context * | sched |
static ast_mutex_t | sip_reload_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
static int | sip_reloading = FALSE |
static enum channelreloadreason | sip_reloadreason |
static int * | sipsock_read_id |
static int | speerobjs = 0 |
static int | suserobjs = 0 |
static char | used_context [AST_MAX_CONTEXT] |
DefaultValues Default values, set and reset in reload_config before reading configuration | |
These are default values in the source. There are other recommended values in the sip.conf.sample for new installations. These may differ to keep backwards compatibility, yet encouraging new behaviour on new installations | |
#define | DEFAULT_ALLOW_EXT_DOM TRUE |
#define | DEFAULT_ALLOWGUEST TRUE |
#define | DEFAULT_AUTOCREATEPEER FALSE |
#define | DEFAULT_CALLCOUNTER FALSE |
#define | DEFAULT_CALLERID "asterisk" |
#define | DEFAULT_COMPACTHEADERS FALSE |
#define | DEFAULT_CONTEXT "default" |
#define | DEFAULT_COS_AUDIO 5 |
#define | DEFAULT_COS_SIP 4 |
#define | DEFAULT_COS_TEXT 5 |
#define | DEFAULT_COS_VIDEO 6 |
#define | DEFAULT_MAX_CALL_BITRATE (384) |
#define | DEFAULT_MOHINTERPRET "default" |
#define | DEFAULT_MOHSUGGEST "" |
#define | DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define | DEFAULT_NOTIFYRINGING TRUE |
#define | DEFAULT_PEDANTIC FALSE |
#define | DEFAULT_QUALIFY FALSE |
#define | DEFAULT_REALM "asterisk" |
#define | DEFAULT_REGEXTENONQUALIFY FALSE |
#define | DEFAULT_SDPOWNER "root" |
#define | DEFAULT_SDPSESSION "Asterisk PBX" |
#define | DEFAULT_SRVLOOKUP TRUE |
#define | DEFAULT_T1MIN 100 |
#define | DEFAULT_TOS_AUDIO 0 |
#define | DEFAULT_TOS_SIP 0 |
#define | DEFAULT_TOS_TEXT 0 |
#define | DEFAULT_TOS_VIDEO 0 |
#define | DEFAULT_USERAGENT "Asterisk PBX" |
#define | DEFAULT_VMEXTEN "asterisk" |
SIPflags | |
Various flags for the flags field in the pvt structure Trying to sort these up (one or more of the following): D: Dialog P: Peer/user G: Global flag When flags are used by multiple structures, it is important that they have a common layout so it is easy to copy them. | |
#define | SIP_CALL_LIMIT (1 << 7) |
#define | SIP_CAN_REINVITE (1 << 20) |
#define | SIP_CAN_REINVITE_NAT (2 << 20) |
#define | SIP_DEFER_BYE_ON_TRANSFER (1 << 10) |
#define | SIP_DTMF (7 << 15) |
#define | SIP_DTMF_AUTO (3 << 15) |
#define | SIP_DTMF_INBAND (1 << 15) |
#define | SIP_DTMF_INFO (2 << 15) |
#define | SIP_DTMF_RFC2833 (0 << 15) |
#define | SIP_DTMF_SHORTINFO (4 << 15) |
#define | SIP_FLAGS_TO_COPY |
Flags to copy from peer/user to dialog. | |
#define | SIP_G726_NONSTANDARD (1 << 31) |
#define | SIP_GOTREFER (1 << 6) |
#define | SIP_INC_COUNT (1 << 8) |
#define | SIP_INC_RINGING (1 << 9) |
#define | SIP_INSECURE (3 << 23) |
#define | SIP_INSECURE_INVITE (1 << 24) |
#define | SIP_INSECURE_NONE (0 << 23) |
#define | SIP_INSECURE_PORT (1 << 23) |
#define | SIP_NAT (3 << 18) |
#define | SIP_NAT_ALWAYS (3 << 18) |
#define | SIP_NAT_NEVER (0 << 18) |
#define | SIP_NAT_RFC3581 (1 << 18) |
#define | SIP_NAT_ROUTE (2 << 18) |
#define | SIP_NEEDREINVITE (1 << 4) |
#define | SIP_OUTGOING (1 << 0) |
#define | SIP_PENDINGBYE (1 << 5) |
#define | SIP_PROG_INBAND (3 << 25) |
#define | SIP_PROG_INBAND_NEVER (0 << 25) |
#define | SIP_PROG_INBAND_NO (1 << 25) |
#define | SIP_PROG_INBAND_YES (2 << 25) |
#define | SIP_PROGRESS_SENT (1 << 3) |
#define | SIP_PROMISCREDIR (1 << 11) |
#define | SIP_REINVITE (7 << 20) |
#define | SIP_REINVITE_NONE (0 << 20) |
#define | SIP_REINVITE_UPDATE (4 << 20) |
#define | SIP_RINGING (1 << 2) |
#define | SIP_SENDRPID (1 << 29) |
#define | SIP_TRUSTRPID (1 << 12) |
#define | SIP_USECLIENTCODE (1 << 14) |
#define | SIP_USEREQPHONE (1 << 13) |
SIPflags2 | |
a second page of flags (for flags[1] | |
#define | SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
#define | SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
#define | SIP_PAGE2_BUGGY_MWI (1 << 26) |
#define | SIP_PAGE2_CALL_ONHOLD (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) |
#define | SIP_PAGE2_DIALOG_ESTABLISHED (1 << 27) |
#define | SIP_PAGE2_FLAGS_TO_COPY |
#define | SIP_PAGE2_IGNORESDPVERSION (1 << 19) |
#define | SIP_PAGE2_REGISTERTRYING (1 << 29) |
#define | SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
#define | SIP_PAGE2_RPORT_PRESENT (1 << 10) |
#define | SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
#define | SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
#define | SIP_PAGE2_STATECHANGEQUEUE (1 << 9) |
#define | SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
#define | SIP_PAGE2_T38SUPPORT (7 << 20) |
#define | SIP_PAGE2_T38SUPPORT_RTP (2 << 20) |
#define | SIP_PAGE2_T38SUPPORT_TCP (4 << 20) |
#define | SIP_PAGE2_T38SUPPORT_UDPTL (1 << 20) |
#define | SIP_PAGE2_TEXTSUPPORT (1 << 15) |
#define | SIP_PAGE2_UDPTL_DESTINATION (1 << 30) |
#define | SIP_PAGE2_VIDEOSUPPORT (1 << 14) |
SIPflagsT38 | |
T.38 set of flags | |
#define | T38FAX_FILL_BIT_REMOVAL (1 << 0) |
#define | T38FAX_RATE_12000 (1 << 12) |
#define | T38FAX_RATE_14400 (1 << 13) |
#define | T38FAX_RATE_2400 (1 << 8) |
#define | T38FAX_RATE_4800 (1 << 9) |
#define | T38FAX_RATE_7200 (1 << 10) |
#define | T38FAX_RATE_9600 (1 << 11) |
#define | T38FAX_RATE_MANAGEMENT_LOCAL_TCF (1 << 3) |
#define | T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
#define | T38FAX_TRANSCODING_JBIG (1 << 2) |
#define | T38FAX_TRANSCODING_MMR (1 << 1) |
#define | T38FAX_UDP_EC_FEC (1 << 4) |
#define | T38FAX_UDP_EC_NONE (0 << 4) |
#define | T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
#define | T38FAX_VERSION (3 << 6) |
#define | T38FAX_VERSION_0 (0 << 6) |
#define | T38FAX_VERSION_1 (1 << 6) |
static int | global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 |
GlobalSettings | |
Global settings apply to the channel (often settings you can change in the general section of sip.conf | |
static int | allow_external_domains |
static int | autocreatepeer |
static int | compactheaders |
static int | dumphistory |
static int | global_allowguest |
static int | global_allowsubscribe |
static enum transfermodes | global_allowtransfer |
static int | global_alwaysauthreject |
static int | global_autoframing |
static int | global_callcounter |
static int | global_callevents |
static int | global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 |
Codecs that we support by default:. | |
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_directrtpsetup |
static int | global_limitonpeers |
static int | global_match_auth_username |
static int | global_matchexterniplocally |
static int | global_max_se |
static int | global_min_se |
static int | global_notifyhold |
static int | global_notifyringing |
static struct sip_proxy | global_outboundproxy |
static int | global_qualifyfreq |
static char | global_realm [MAXHOSTNAMELEN] |
static int | global_reg_timeout |
static int | global_regattempts_max |
static char | global_regcontext [AST_MAX_CONTEXT] |
static int | global_regextenonqualify |
static int | global_relaxdtmf |
static int | global_rtautoclear |
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_srvlookup |
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 int | pedanticsipchecking |
static int | recordhistory |
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_context [AST_MAX_CONTEXT] |
static char | default_fromdomain [AST_MAX_EXTENSION] |
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_notifymime [AST_MAX_EXTENSION] |
static struct ast_codec_pref | default_prefs |
static int | default_qualify |
static char | default_subscribecontext [AST_MAX_CONTEXT] |
static char | default_vmexten [AST_MAX_EXTENSION] |
static struct sip_settings | sip_cfg |
Defines | |
#define | ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO" |
SIP Methods we support. | |
#define | append_history(p, event, fmt, args...) append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history. | |
#define | CALLERID_UNKNOWN "Unknown" |
#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 | DEFAULT_DEFAULT_EXPIRY 120 |
#define | DEFAULT_EXPIRY 900 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_MAX_EXPIRY 3600 |
#define | DEFAULT_MAX_FORWARDS "70" |
#define | DEFAULT_MAX_SE 1800 |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_MIN_EXPIRY 60 |
#define | DEFAULT_MIN_SE 90 |
#define | DEFAULT_QUALIFYFREQ 60 * 1000 |
#define | DEFAULT_REGISTRATION_TIMEOUT 20 |
#define | DEFAULT_RETRANS 1000 |
#define | DEFAULT_TRANS_TIMEOUT -1 |
#define | EXPIRY_GUARD_LIMIT 30 |
#define | EXPIRY_GUARD_MIN 500 |
#define | EXPIRY_GUARD_PCT 0.20 |
#define | EXPIRY_GUARD_SECS 15 |
#define | FALSE 0 |
#define | FORMAT "%-15.15s %-10.10s %-15.15s %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
#define | FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
#define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define | FORMAT "%-25.25s %-15.15s %-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 "%-30.30s %-6d %-9.9s %-6.6s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT2 "%-15.15s %-10.10s %-15.15s %-15.15s %-7.7s %-15.15s\n" |
#define | FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %s\n" |
#define | FORMAT2 "%-30.30s %3.6s %9.9s %6.6s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT3 "%-15.15s %-10.10s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s\n" |
#define | INITIAL_CSEQ 101 |
#define | IS_SIP_TECH(t) ((t) == &sip_tech || (t) == &sip_tech_info) |
#define | MAX(a, b) ((a) > (b) ? (a) : (b)) |
#define | MAX_AUTHTRIES 3 |
#define | MAX_HISTORY_ENTRIES 50 |
#define | MAX_RETRANS 6 |
#define | NO_RTP 0 |
#define | NOT_SUPPORTED 0 |
#define | RTP 1 |
#define | SDP_MAX_RTPMAP_CODECS 32 |
#define | SDP_SAMPLE_RATE(x) 8000 |
#define | SIP_MAX_HEADERS 64 |
#define | SIP_MAX_LINES 64 |
#define | SIP_MAX_PACKET 4096 |
#define | SIP_OPT_100REL (1 << 1) |
#define | SIP_OPT_EARLY_SESSION (1 << 3) |
#define | SIP_OPT_EVENTLIST (1 << 11) |
#define | SIP_OPT_GRUU (1 << 12) |
#define | SIP_OPT_HISTINFO (1 << 15) |
#define | SIP_OPT_JOIN (1 << 4) |
#define | SIP_OPT_NOREFERSUB (1 << 14) |
#define | SIP_OPT_PATH (1 << 5) |
#define | SIP_OPT_PRECONDITION (1 << 7) |
#define | SIP_OPT_PREF (1 << 6) |
#define | SIP_OPT_PRIVACY (1 << 8) |
#define | SIP_OPT_REPLACES (1 << 0) |
#define | SIP_OPT_RESPRIORITY (1 << 16) |
#define | SIP_OPT_SDP_ANAT (1 << 9) |
#define | SIP_OPT_SEC_AGREE (1 << 10) |
#define | SIP_OPT_TARGET_DIALOG (1 << 13) |
#define | SIP_OPT_TIMER (1 << 2) |
#define | SIP_OPT_UNKNOWN (1 << 17) |
#define | sip_pvt_lock(x) ast_mutex_lock(&x->pvt_lock) |
#define | sip_pvt_trylock(x) ast_mutex_trylock(&x->pvt_lock) |
#define | sip_pvt_unlock(x) ast_mutex_unlock(&x->pvt_lock) |
#define | SIP_RESERVED ";/?:@&=+$,# " |
#define | SIP_TIMER_T1 500 |
#define | SIP_TRANS_TIMEOUT 64 * SIP_TIMER_T1 |
#define | SIPBUFSIZE 512 |
#define | STANDARD_SIP_PORT 5060 |
Standard SIP and TLS port from RFC 3261. DO NOT CHANGE THIS. | |
#define | STANDARD_TLS_PORT 5061 |
#define | SUPPORTED 1 |
#define | SUPPORTED_EXTENSIONS "replaces, timer" |
SIP Extensions we support. | |
#define | TRUE 1 |
#define | UNLINK(element, head, prev) |
#define | XMIT_ERROR -2 |
Enumerations | |
enum | can_create_dialog { CAN_NOT_CREATE_DIALOG, CAN_CREATE_DIALOG, CAN_CREATE_DIALOG_UNSUPPORTED_METHOD } |
States whether a SIP message can create a dialog in Asterisk. More... | |
enum | check_auth_result { AUTH_DONT_KNOW = -100, AUTH_SUCCESSFUL = 0, AUTH_CHALLENGE_SENT = 1, AUTH_SECRET_FAILED = -1, AUTH_USERNAME_MISMATCH = -2, AUTH_NOT_FOUND = -3, AUTH_FAKE_AUTH = -4, AUTH_UNKNOWN_DOMAIN = -5, AUTH_PEER_NOT_DYNAMIC = -6, AUTH_ACL_FAILED = -7, AUTH_BAD_TRANSPORT = -8 } |
Authentication result from check_auth* functions. More... | |
enum | invitestates { INV_NONE = 0, INV_CALLING = 1, INV_PROCEEDING = 2, INV_EARLY_MEDIA = 3, INV_COMPLETED = 4, INV_CONFIRMED = 5, INV_TERMINATED = 6, INV_CANCELLED = 7 } |
States for the INVITE transaction, not the dialog. More... | |
enum | media_type { SDP_AUDIO, SDP_VIDEO } |
enum | parse_register_result { PARSE_REGISTER_FAILED, PARSE_REGISTER_UPDATE, PARSE_REGISTER_QUERY } |
enum | referstatus { REFER_IDLE, REFER_SENT, REFER_RECEIVED, REFER_CONFIRMED, REFER_ACCEPTED, REFER_RINGING, REFER_200OK, REFER_FAILED, REFER_NOAUTH } |
Parameters to know status of transfer. More... | |
enum | sip_auth_type { PROXY_AUTH = 407, WWW_AUTH = 401 } |
Authentication types - proxy or www authentication. More... | |
enum | sip_debug_e { sip_debug_none = 0, sip_debug_config = 1, sip_debug_console = 2 } |
debugging state We store separately the debugging requests from the config file and requests from the CLI. Debugging is enabled if either is set (which means that if sipdebug is set in the config file, we can only turn it off by reloading the config). More... | |
enum | sip_result { AST_SUCCESS = 0, AST_FAILURE = -1 } |
enum | sip_transport { SIP_TRANSPORT_UDP = 1, SIP_TRANSPORT_TCP = 1 << 1, SIP_TRANSPORT_TLS = 1 << 2 } |
enum | sipmethod { SIP_UNKNOWN, SIP_RESPONSE, SIP_REGISTER, SIP_OPTIONS, SIP_NOTIFY, SIP_INVITE, SIP_ACK, SIP_PRACK, SIP_BYE, SIP_REFER, SIP_SUBSCRIBE, SIP_MESSAGE, SIP_UPDATE, SIP_INFO, SIP_CANCEL, SIP_PUBLISH, SIP_PING } |
SIP Request methods known by Asterisk. More... | |
enum | sipregistrystate { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH, REG_STATE_FAILED } |
States for outbound registrations (with register= lines in sip.conf. More... | |
enum | st_mode { SESSION_TIMER_MODE_INVALID = 0, SESSION_TIMER_MODE_ACCEPT, SESSION_TIMER_MODE_ORIGINATE, SESSION_TIMER_MODE_REFUSE } |
Modes in which Asterisk can be configured to run SIP Session-Timers. More... | |
enum | st_refresher { SESSION_TIMER_REFRESHER_AUTO, SESSION_TIMER_REFRESHER_UAC, SESSION_TIMER_REFRESHER_UAS } |
The entity playing the refresher role for Session-Timers. More... | |
enum | subscriptiontype { NONE = 0, XPIDF_XML, DIALOG_INFO_XML, CPIM_PIDF_XML, PIDF_XML, MWI_NOTIFICATION } |
enum | t38_action_flag { SDP_T38_NONE = 0, SDP_T38_INITIATE, SDP_T38_ACCEPT } |
enum | t38state { T38_DISABLED = 0, T38_LOCAL_REINVITE, T38_PEER_DIRECT, T38_PEER_REINVITE, T38_ENABLED } |
T38 States for a call. More... | |
enum | transfermodes { TRANSFER_OPENFORALL, TRANSFER_CLOSED } |
Authorization scheme for call transfers. More... | |
enum | xmittype { XMIT_CRITICAL = 2, XMIT_RELIABLE = 1, XMIT_UNRELIABLE = 0 } |
Functions | |
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 sockaddr_in *sin, int tcp) |
static void | __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(). | |
static int | __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. | |
static 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, char *data, int len, int fatal, int sipmethod) |
Transmit packet with retransmits. | |
static 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_xmit (struct sip_pvt *p, char *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_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. | |
static int | acf_channel_read (struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen) |
static void | add_blank (struct sip_request *req) |
add a blank line if no body | |
static void | add_codec_to_sdp (const struct sip_pvt *p, int codec, int sample_rate, 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_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 int | add_header (struct sip_request *req, const char *var, const char *value) |
Add header to SIP message. | |
static int | add_header_contentLength (struct sip_request *req, int len) |
Add 'Content-Length' header to SIP message. | |
static int | add_line (struct sip_request *req, const char *line) |
Add content (not header) to SIP message. | |
static void | add_noncodec_to_sdp (const struct sip_pvt *p, int format, int sample_rate, 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 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 void | add_tcodec_to_sdp (const struct sip_pvt *p, int codec, int sample_rate, 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, int codec, int sample_rate, 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 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 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 (struct in_addr *them, struct sockaddr_in *us, struct sip_pvt *p) |
NAT fix - decide which IP address to use for Asterisk server? | |
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, struct in_addr 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) |
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_rpid (struct sip_pvt *p) |
Build the Remote Party-ID & From using callingpres options. | |
static struct sip_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
Initiate a SIP user structure from configuration (configuration or realtime). | |
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 | 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, 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 sockaddr_in *sin, struct sip_peer **authpeer, enum xmittype reliable, char *rpid_num, char *calleridname, char *uri2) |
Validate peer 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 | |
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, char *uri, enum xmittype reliable, struct sockaddr_in *sin) |
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, char *uri, enum xmittype reliable, struct sockaddr_in *sin, 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 enum check_auth_result | check_user_ok (struct sip_pvt *p, char *of, struct sip_request *req, int sipmethod, struct sockaddr_in *sin, enum xmittype reliable, char *rpid_num, char *calleridname, char *uri2) |
Validate user authentication. | |
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 externip/seternaddr/stunaddr. | |
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 const char * | cli_yesno (int x) |
return Yes or No depending on the argument. This is used in many places in CLI command, having a function to generate this helps maintaining a consistent output (and possibly emitting the output in other languages, at some point). | |
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, int flags2) |
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 | 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) |
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, int newdialog) |
create address structure from peer 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 void | destroy_association (struct sip_peer *peer) |
Remove registration data from realtime database or AST/DB when registration expires. | |
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 struct sip_pvt * | dialog_ref (struct sip_pvt *p) |
static struct sip_pvt * | dialog_unref (struct sip_pvt *p) |
static void | dialoglist_lock (void) |
hide the way the list is locked/unlocked | |
static void | dialoglist_unlock (void) |
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, int natflags) |
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 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 * | find_alias (const char *name, const char *_default) |
Find compressed SIP alias. | |
static struct sip_pvt * | find_call (struct sip_request *req, struct sockaddr_in *sin, 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 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 sockaddr_in *sin, int realtime, int devstate_only) |
Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name. | |
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 int | find_sip_method (const char *msg) |
find_sip_method: Find SIP method from header | |
static struct cfsubscription_types * | find_subscription_type (enum subscriptiontype subtype) |
Find subscription type in array. | |
static struct sip_user * | find_user (const char *name, int realtime) |
Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf). | |
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 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) |
Get a specific line from the message body. | |
static char * | get_body_by_line (const char *line, const char *name, int nameLen) |
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 char * | get_calleridname (const char *input, char *output, size_t outputsize) |
Get caller id name from SIP headers. | |
static int | get_destination (struct sip_pvt *p, struct sip_request *oreq) |
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 const char * | get_header (const struct sip_request *req, const char *name) |
Get header from SIP request. | |
static char * | get_in_brackets (char *tmp) |
Pick out text in brackets from character string. | |
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 sockaddr_in *sin) |
static int | get_msg_text (char *buf, int len, struct sip_request *req) |
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, struct sockaddr_in *sin, struct sockaddr_in *vsin, struct sockaddr_in *tsin, struct sockaddr_in *dest, struct sockaddr_in *vdest) |
Set all IP media addresses for this call. | |
static int | get_rdnis (struct sip_pvt *p, struct sip_request *oreq) |
Get referring dnis. | |
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_num (const char *input, char *output, int maxlen) |
Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found. | |
static const char * | get_sdp (struct sip_request *req, const char *name) |
Get a line from an SDP message body. | |
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 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_transport (enum sip_transport t) |
static const char * | get_transport_list (struct sip_peer *peer) |
static const char * | get_transport_pvt (struct sip_pvt *p) |
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_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v) |
Handle flag-type options common to configuration of devices - users and peers. | |
static int | handle_incoming (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, 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 sockaddr_in *sin) |
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 sockaddr_in *sin) |
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 sockaddr_in *sin, int *recount, 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 sockaddr_in *sin, int seqno, char *e) |
Handle incoming notifications. | |
static int | handle_request_options (struct sip_pvt *p, struct sip_request *req) |
Handle incoming OPTIONS request An OPTIONS request should be answered like an INVITE from the same UA, including SDP. | |
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 sockaddr_in *sin, char *e) |
Handle incoming REGISTER request. | |
static int | handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e) |
Handle incoming SUBSCRIBE request. | |
static void | handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
Handle SIP response in dialogue. | |
static void | handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
Handle SIP response to INVITE dialogue. | |
static void | handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req) |
Handle qualification responses (OPTIONS). | |
static void | handle_response_refer (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
static int | handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
Handle responses on REGISTER to services. | |
static const char * | hangup_cause2sip (int cause) |
Convert Asterisk hangup causes to SIP codes. | |
static 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 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) |
Initiate new SIP request to peer/user. | |
static const char * | insecure2str (int mode) |
Convert Insecure setting to printable string. | |
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) |
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_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 | 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 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 const char * | nat2str (int nat) |
Convert NAT setting to text string. | |
static struct sip_proxy * | obproxy_get (struct sip_pvt *dialog, struct sip_peer *peer) |
Get default outbound proxy or global proxy. | |
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) |
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 unsigned int | parse_sip_options (struct sip_pvt *pvt, const char *supported) |
Parse supported header in incoming packet. | |
static int | parse_uri (char *uri, char *scheme, char **ret_name, char **pass, char **domain, char **port, char **options, char **transport) |
* parses a URI in its components. | |
static void | peer_mailboxes_to_str (struct ast_str **mailbox_str, struct sip_peer *peer) |
list peer mailboxes to CLI | |
static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
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 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 struct sip_proxy * | proxy_allocate (char *name, char *port, int force) |
Allocate and initialize sip proxy. | |
static int | proxy_update (struct sip_proxy *proxy) |
static int | queue_request (struct sip_pvt *p, const struct sip_request *req) |
static struct sip_peer * | realtime_peer (const char *newpeername, struct sockaddr_in *sin, int devstate_only) |
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. | |
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *defaultuser, const char *fullcontact, int expirey, int 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 struct sip_user * | realtime_user (const char *username) |
Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped). | |
static void | receive_message (struct sip_pvt *p, struct sip_request *req) |
Receive SIP MESSAGE method messages. | |
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 sockaddr_in *sin, struct sip_request *req, char *uri) |
Verify registration of user
| |
static struct sip_registry * | registry_addref (struct sip_registry *reg) |
Add object reference to SIP registry. | |
static void * | registry_unref (struct sip_registry *reg) |
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 void | replace_cid (struct sip_pvt *p, const char *rpid_num, const char *calleridname) |
helper function for check_{user|peer}_ok() | |
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_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 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_peer_defaults (struct sip_peer *peer) |
Set peer defaults before configuring specific configurations. | |
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 | show_channels_cb (void *__cur, void *__arg, int flags) |
callback for show channel|subscription | |
static int | sip_addheader (struct ast_channel *chan, void *data) |
Add a SIP header to an outbound INVITE. | |
static int | sip_addrcmp (char *name, struct sockaddr_in *sin) |
Support routine for find_peer. | |
static struct sip_pvt * | sip_alloc (ast_string_field callid, struct sockaddr_in *sin, 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. | |
static 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 int | sip_debug_test_addr (const struct sockaddr_in *addr) |
See if we pass debug IP filter. | |
static int | sip_debug_test_pvt (struct sip_pvt *p) |
Test PVT for debugging output. | |
static struct sip_pvt * | sip_destroy (struct sip_pvt *p) |
Destroy SIP call structure. Make it return NULL so the caller can do things like foo = sip_destroy(foo); and reduce the chance of bugs due to dangling pointers. | |
static void | sip_destroy_peer (struct sip_peer *peer) |
Destroy peer object from memory. | |
static void | sip_destroy_user (struct sip_user *user) |
Remove user object from in-memory storage. | |
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, char *arg) |
Enable SIP Debugging for a single IP. | |
static char * | sip_do_debug_peer (int fd, char *arg) |
Turn on SIP debugging for a given peer. | |
static char * | sip_do_history_deprecated (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Enable/Disable SIP History logging (CLI) - deprecated. use sip_set_history instead. | |
static int | sip_do_reload (enum channelreloadreason reason) |
Reload module. | |
static int | sip_dtmfmode (struct ast_channel *chan, void *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_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_codec (struct ast_channel *chan) |
Return SIP UA's codec (part of the RTP interface). | |
static enum ast_rtp_get_result | sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite audio (part of RTP interface). | |
static enum ast_rtp_get_result | sip_get_trtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite text (part of RTP interface). | |
static struct ast_udptl * | sip_get_udptl_peer (struct ast_channel *chan) |
static enum ast_rtp_get_result | sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite video (part of RTP interface). | |
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 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) |
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 char * | sip_notify (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Cli command to send SIP notify to peer. | |
static int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno) |
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 int | sip_parse_host (char *line, int lineno, char **hostname, int *portnum, enum sip_transport *transport) |
Small function to parse a config line for a host with a transport i.e. tls://www.google.com:8056. | |
static void | sip_peer_hold (struct sip_pvt *p, int hold) |
Change onhold state of a peer using a pvt structure. | |
static void | sip_poke_all_peers (void) |
Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions? | |
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) |
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 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 sockaddr_in * | sip_real_dst (const struct sip_pvt *p) |
The real destination address for a write. | |
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) |
Parse register=> line in sip.conf and add to registry. | |
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 struct ast_channel * | sip_request_call (const char *type, int format, void *data, int *cause) |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here. | |
static int | sip_reregister (const void *data) |
Update registration with SIP Proxy. Called from the scheduler when the previous registration expires, so we don't have to cancel the pending event. We assume the reference so the sip_registry is valid, since it is stored in the scheduled event anyways. | |
static struct ast_frame * | sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect) |
Read RTP from network. | |
static void | sip_scheddestroy (struct sip_pvt *p, int ms) |
Schedule destruction of SIP dialog. | |
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 *rtp, struct ast_rtp *vrtp, struct ast_rtp *trtp, int codecs, int nat_active) |
Set the RTP peer for this call. | |
static int | sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl) |
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_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_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_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_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 sockaddr_in *s) |
Find thread for TCP/TLS session (based on IP/Port. | |
static void * | sip_tcp_worker_fn (void *data) |
SIP TCP connection handler. | |
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 int | sip_uri_cmp (const char *input1, const char *input2) |
static int | sip_uri_headers_cmp (const char *input1, const char *input2) |
helper routine for sip_uri_cmp | |
static int | sip_uri_params_cmp (const char *input1, const char *input2) |
helper routine for sip_uri_cmp | |
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 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 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 int | t38_get_rate (int t38cap) |
Get Max T.38 Transmission rate from T38 capabilities. | |
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 char * | transfermode2str (enum transfermodes mode) |
Convert transfer mode to text string. | |
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 users/peers from fishers. | |
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) |
Build REFER/INVITE/OPTIONS 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, char *vmexten) |
Notify user of messages waiting in voicemail. | |
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. | |
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 sockaddr_in *sin, 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_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_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable, int oldsdp) |
Used for 200 OK and 183 early media. | |
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_sip_request (struct sip_pvt *p, struct sip_request *req) |
Transmit SIP request unreliably (only used in sip_notify subsystem). | |
static int | transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout) |
Used in the SUBSCRIBE notification subsystem. | |
static void | try_suggested_sip_codec (struct sip_pvt *p) |
Try setting codec suggested by the SIP_CODEC channel variable. | |
static int | unload_module (void) |
PBX unload module API. | |
static void | unref_peer (struct sip_peer *peer) |
static void | unref_user (struct sip_user *user) |
static int | update_call_counter (struct sip_pvt *fup, int event) |
update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted. | |
static void | update_peer (struct sip_peer *p, int expiry) |
Update peer data in database (if used). | |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, .reload = reload, } |
static char * | app_dtmfmode = "SIPDtmfMode" |
static char * | app_sipaddheader = "SIPAddHeader" |
static const struct ast_module_info * | ast_module_info = &__mod_info |
static struct sip_auth * | authl = NULL |
Authentication list for realm authentication. | |
static struct sockaddr_in | bindaddr |
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_cli_entry | cli_sip_do_history_deprecated = { .handler = sip_do_history_deprecated , .summary = "Enable/Disable SIP history" ,__VA_ARGS__ } |
static const char | config [] = "sip.conf" |
static struct sockaddr_in | debugaddr |
static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
static struct ast_jb_conf | default_jbconf |
Global jitterbuffer configuration - by default, jb is disabled. | |
static struct ast_tls_config | default_tls_cfg |
Default TLS connection configuration. | |
static char * | descrip_dtmfmode = " SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" |
static char * | descrip_sipaddheader |
static struct sip_pvt * | dialoglist = NULL |
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 ast_mutex_t | dialoglock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
Protect the SIP dialog list (of sip_pvt's). | |
static struct _map_x_s | dtmfstr [] |
mapping between dtmf flags and strings | |
static time_t | externexpire |
static char | externhost [MAXHOSTNAMELEN] |
static struct sockaddr_in | externip |
our external IP address/port for SIP sessions. externip.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 int | externrefresh = 10 |
static struct ast_ha * | global_contact_ha = NULL |
Global list of addresses dynamic peers are not allowed to use. | |
static int | global_dynamic_exclude_static = 0 |
static struct ast_jb_conf | global_jbconf |
static struct _map_x_s | insecurestr [] |
static struct sockaddr_in | 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 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 char | mandescr_show_peer [] |
static char | mandescr_show_peers [] |
static char | mandescr_show_registry [] |
Manager Action SIPShowRegistry description. | |
static int | max_expiry = DEFAULT_MAX_EXPIRY |
static int | min_expiry = DEFAULT_MIN_EXPIRY |
static struct _map_x_s | natmodes [] |
static const char | notify_config [] = "sip_notify.conf" |
static struct ast_config * | notify_types |
static int | ourport_tcp |
static int | ourport_tls |
static struct ast_peer_list | peerl |
The peer list: Peers and Friends. | |
static struct _map_x_s | referstatusstrings [] |
static struct ast_register_list | regl |
The register list: Other SIP proxies we register with and place calls to. | |
static struct _map_x_s | regstatestrings [] |
static struct ast_custom_function | sip_header_function |
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 cfsip_options | sip_options [] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. | |
static struct ast_rtp_protocol | sip_rtp |
Interface structure with callbacks used to connect to RTP module. | |
static struct server_args | sip_tcp_desc |
The TCP server definition. | |
static struct ast_channel_tech | sip_tech |
Definition of this channel for PBX channel registration. | |
static struct ast_channel_tech | sip_tech_info |
This version of the sip channel tech has no send_digit_begin callback so that the core knows that the channel does not want DTMF BEGIN frames. The struct is initialized just before registering the channel driver, and is for use with channels using SIP INFO DTMF. | |
static struct ast_tls_config | sip_tls_cfg |
Working TLS connection configuration. | |
static struct server_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 thie moment this is set together with sip_debug_console. It should either go away or be implemented properly. | |
ast_custom_function | sippeer_function |
Structure to declare a dialplan function: SIPPEER. | |
static int | sipsock = -1 |
Main socket for SIP communication. | |
static struct _map_x_s | stmodes [] |
Report Peer status in character string. | |
static struct _map_x_s | strefreshers [] |
static struct sockaddr_in | stunaddr |
static struct cfsubscription_types | subscription_types [] |
Subscription types that we support. We support
| |
static char * | synopsis_dtmfmode = "Change the dtmfmode for a SIP call" |
static char * | synopsis_sipaddheader = "Add a SIP header to the outbound call" |
static struct ast_threadstorage | ts_temp_pvt = { .once = PTHREAD_ONCE_INIT, .key_init = __init_ts_temp_pvt , .custom_init = temp_pvt_init , } |
static struct ast_user_list | userl |
The user list: Users and friends. |
VIA branch tag transaction checking
Transaction support
We need to test TCP sessions with SIP proxies and in regards to the SIP outbound specs.
A new INVITE is sent to handle_request_invite(), that will end up starting a new channel in the PBX, the new channel after that executing in a separate channel thread. This is an incoming "call". When the call is answered, either by a bridged channel or the PBX itself the sip_answer() function is called.
The actual media - Video or Audio - is mostly handled by the RTP subsystem in rtp.c
Definition in file chan_sip.c.
#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO" |
SIP Methods we support.
Definition at line 586 of file chan_sip.c.
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), and transmit_reinvite_with_sdp().
#define append_history | ( | p, | |||
event, | |||||
fmt, | |||||
args... | ) | append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history.
Definition at line 1945 of file chan_sip.c.
Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), cb_extensionstate(), check_auth(), do_register_auth(), handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), local_attended_transfer(), obproxy_get(), process_sdp(), 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(), and transmit_response_with_auth().
#define CALLERID_UNKNOWN "Unknown" |
#define CHECK_AUTH_BUF_INITLEN 256 |
Definition at line 10630 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 1852 of file chan_sip.c.
Referenced by create_addr_from_peer(), and register_verify().
#define DEC_CALL_LIMIT 0 |
Definition at line 777 of file chan_sip.c.
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_hangup(), and update_call_counter().
#define DEC_CALL_RINGING 2 |
Definition at line 779 of file chan_sip.c.
Referenced by handle_response_invite(), and update_call_counter().
#define DEFAULT_ALLOW_EXT_DOM TRUE |
Definition at line 628 of file chan_sip.c.
#define DEFAULT_ALLOWGUEST TRUE |
Definition at line 616 of file chan_sip.c.
#define DEFAULT_AUTOCREATEPEER FALSE |
Definition at line 632 of file chan_sip.c.
#define DEFAULT_CALLCOUNTER FALSE |
Definition at line 617 of file chan_sip.c.
#define DEFAULT_CALLERID "asterisk" |
Definition at line 614 of file chan_sip.c.
#define DEFAULT_COMPACTHEADERS FALSE |
Definition at line 619 of file chan_sip.c.
#define DEFAULT_CONTEXT "default" |
Definition at line 610 of file chan_sip.c.
#define DEFAULT_COS_AUDIO 5 |
Definition at line 625 of file chan_sip.c.
#define DEFAULT_COS_SIP 4 |
Definition at line 624 of file chan_sip.c.
#define DEFAULT_COS_TEXT 5 |
Definition at line 627 of file chan_sip.c.
#define DEFAULT_COS_VIDEO 6 |
Definition at line 626 of file chan_sip.c.
#define DEFAULT_DEFAULT_EXPIRY 120 |
Definition at line 196 of file chan_sip.c.
#define DEFAULT_EXPIRY 900 |
Expire slowly
Definition at line 213 of file chan_sip.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Qualification: How often to check, if the host is down...
Definition at line 227 of file chan_sip.c.
#define DEFAULT_MAX_CALL_BITRATE (384) |
Max bitrate for video
Definition at line 636 of file chan_sip.c.
#define DEFAULT_MAX_EXPIRY 3600 |
Definition at line 198 of file chan_sip.c.
#define DEFAULT_MAX_FORWARDS "70" |
Definition at line 200 of file chan_sip.c.
Referenced by initreqprep(), reqprep(), and transmit_register().
#define DEFAULT_MAX_SE 1800 |
Session-Timer Default Session-Expires period (RFC 4028)
Definition at line 244 of file chan_sip.c.
#define DEFAULT_MAXMS 2000 |
Qualification: Must be faster than 2 seconds by default
Definition at line 225 of file chan_sip.c.
#define DEFAULT_MIN_EXPIRY 60 |
Definition at line 197 of file chan_sip.c.
#define DEFAULT_MIN_SE 90 |
Session-Timer Default Min-SE period (RFC 4028)
Definition at line 245 of file chan_sip.c.
#define DEFAULT_MOHINTERPRET "default" |
Definition at line 611 of file chan_sip.c.
#define DEFAULT_MOHSUGGEST "" |
Definition at line 612 of file chan_sip.c.
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
Definition at line 615 of file chan_sip.c.
#define DEFAULT_NOTIFYRINGING TRUE |
Definition at line 630 of file chan_sip.c.
#define DEFAULT_PEDANTIC FALSE |
Definition at line 631 of file chan_sip.c.
#define DEFAULT_QUALIFY FALSE |
Definition at line 633 of file chan_sip.c.
#define DEFAULT_QUALIFYFREQ 60 * 1000 |
Qualification: How often to check for the host to be up
Definition at line 226 of file chan_sip.c.
#define DEFAULT_REALM "asterisk" |
Definition at line 629 of file chan_sip.c.
#define DEFAULT_REGEXTENONQUALIFY FALSE |
Definition at line 634 of file chan_sip.c.
#define DEFAULT_REGISTRATION_TIMEOUT 20 |
Definition at line 199 of file chan_sip.c.
#define DEFAULT_RETRANS 1000 |
How frequently to retransmit Default: 2 * 500 ms in RFC 3261
Definition at line 229 of file chan_sip.c.
#define DEFAULT_SDPOWNER "root" |
Default SDP username field in (o=) header unless re-defined in sip.conf
Definition at line 640 of file chan_sip.c.
#define DEFAULT_SDPSESSION "Asterisk PBX" |
Default SDP session name, (s=) header unless re-defined in sip.conf
Definition at line 639 of file chan_sip.c.
#define DEFAULT_SRVLOOKUP TRUE |
Recommended setting is ON
Definition at line 618 of file chan_sip.c.
#define DEFAULT_T1MIN 100 |
100 MS for minimal roundtrip time
Definition at line 635 of file chan_sip.c.
#define DEFAULT_TOS_AUDIO 0 |
Audio packets should be marked as DSCP EF (Expedited Forwarding), but the default is 0 to be compatible with previous versions.
Definition at line 621 of file chan_sip.c.
#define DEFAULT_TOS_SIP 0 |
Call signalling packets should be marked as DSCP CS3, but the default is 0 to be compatible with previous versions.
Definition at line 620 of file chan_sip.c.
#define DEFAULT_TOS_TEXT 0 |
Text packets should be marked as XXXX XXXX, but the default is 0 to be compatible with previous versions.
Definition at line 623 of file chan_sip.c.
#define DEFAULT_TOS_VIDEO 0 |
Video packets should be marked as DSCP AF41, but the default is 0 to be compatible with previous versions.
Definition at line 622 of file chan_sip.c.
#define DEFAULT_TRANS_TIMEOUT -1 |
Definition at line 235 of file chan_sip.c.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), and transmit_fake_auth_response().
#define DEFAULT_USERAGENT "Asterisk PBX" |
Default Useragent: header unless re-defined in sip.conf
Definition at line 638 of file chan_sip.c.
#define DEFAULT_VMEXTEN "asterisk" |
Definition at line 613 of file chan_sip.c.
#define EXPIRY_GUARD_LIMIT 30 |
Below here, we use EXPIRY_GUARD_PCT instead of EXPIRY_GUARD_SECS
Definition at line 205 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_MIN 500 |
This is the minimum guard time applied. If GUARD_PCT turns out to be lower than this, it will use this time instead. This is in milliseconds.
Definition at line 207 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_PCT 0.20 |
Percentage of expires timeout to use when below EXPIRY_GUARD_LIMIT
Definition at line 211 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_SECS 15 |
How long before expiry do we reregister
Definition at line 204 of file chan_sip.c.
Referenced by handle_response_register().
#define FALSE 0 |
Definition at line 181 of file chan_sip.c.
#define FORMAT "%-15.15s %-10.10s %-15.15s %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
Definition at line 13892 of file chan_sip.c.
#define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
Definition at line 13892 of file chan_sip.c.
#define FORMAT "%-40.40s %-20.20s %-16.16s\n" |
Definition at line 13892 of file chan_sip.c.
#define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n" |
Definition at line 13892 of file chan_sip.c.
#define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
Definition at line 13892 of file chan_sip.c.
#define FORMAT "%-30.30s %-6d %-9.9s %-6.6s\n" |
Definition at line 13892 of file chan_sip.c.
#define FORMAT "%-25.25s %-15.15s %-15.15s \n" |
Definition at line 13892 of file chan_sip.c.
#define FORMAT2 "%-15.15s %-10.10s %-15.15s %-15.15s %-7.7s %-15.15s\n" |
Definition at line 13891 of file chan_sip.c.
#define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
Definition at line 13891 of file chan_sip.c.
#define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %s\n" |
Definition at line 13891 of file chan_sip.c.
#define FORMAT2 "%-30.30s %3.6s %9.9s %6.6s\n" |
Definition at line 13891 of file chan_sip.c.
#define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
Definition at line 13891 of file chan_sip.c.
#define FORMAT3 "%-15.15s %-10.10s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s\n" |
Definition at line 13890 of file chan_sip.c.
Referenced by show_channels_cb(), and sip_show_channels().
#define INC_CALL_LIMIT 1 |
Definition at line 778 of file chan_sip.c.
Referenced by handle_request_invite(), and update_call_counter().
#define INC_CALL_RINGING 3 |
The SIP socket definition
Definition at line 780 of file chan_sip.c.
Referenced by sip_call(), and update_call_counter().
#define INITIAL_CSEQ 101 |
our initial sip sequence number
Definition at line 242 of file chan_sip.c.
Referenced by sip_alloc(), sip_register(), and transmit_response_using_temp().
#define IS_SIP_TECH | ( | t | ) | ((t) == &sip_tech || (t) == &sip_tech_info) |
Definition at line 2171 of file chan_sip.c.
Referenced by acf_channel_read(), func_header_read(), function_sipchaninfo_read(), and sip_dtmfmode().
#define MAX | ( | a, | |||
b | ) | ((a) > (b) ? (a) : (b)) |
Definition at line 220 of file chan_sip.c.
#define MAX_AUTHTRIES 3 |
Try authentication three times, then fail
Definition at line 236 of file chan_sip.c.
Referenced by handle_response(), handle_response_invite(), and handle_response_register().
#define MAX_HISTORY_ENTRIES 50 |
Max entires in the history list for a sip_pvt
Definition at line 1325 of file chan_sip.c.
Referenced by append_history_va().
#define MAX_RETRANS 6 |
Try only 6 times for retransmissions, a total of 7 transmissions
Definition at line 230 of file chan_sip.c.
#define NO_RTP 0 |
Definition at line 263 of file chan_sip.c.
#define NOT_SUPPORTED 0 |
Definition at line 513 of file chan_sip.c.
#define RTP 1 |
Definition at line 262 of file chan_sip.c.
#define SDP_MAX_RTPMAP_CODECS 32 |
Maximum number of codecs allowed in received SDP
Definition at line 247 of file chan_sip.c.
Referenced by process_sdp().
#define SDP_SAMPLE_RATE | ( | x | ) | 8000 |
Definition at line 8441 of file chan_sip.c.
Referenced by add_sdp().
#define SIP_CALL_LIMIT (1 << 7) |
D: Call limit enforced for this call
Definition at line 915 of file chan_sip.c.
Referenced by check_peer_ok(), check_user_ok(), create_addr_from_peer(), and update_call_counter().
#define SIP_CAN_REINVITE (1 << 20) |
DP: allow peers to be reinvited to send media directly p2p
Definition at line 943 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), and sip_get_vrtp_peer().
#define SIP_CAN_REINVITE_NAT (2 << 20) |
DP: allow media reinvite when new peer is behind NAT
Definition at line 944 of file chan_sip.c.
Referenced by handle_common_options(), sip_get_rtp_peer(), and sip_set_rtp_peer().
#define SIP_DEFER_BYE_ON_TRANSFER (1 << 10) |
D: Do not hangup at first ast_hangup
Definition at line 918 of file chan_sip.c.
Referenced by handle_invite_replaces(), handle_request_refer(), local_attended_transfer(), sip_hangup(), and sip_set_rtp_peer().
#define SIP_DTMF (7 << 15) |
DP: DTMF Support: five settings, uses three bits
Definition at line 926 of file chan_sip.c.
Referenced by _sip_show_peer(), check_peer_ok(), check_user_ok(), create_addr_from_peer(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit_begin(), sip_senddigit_end(), sip_show_channel(), sip_show_settings(), and transmit_info_with_digit().
#define SIP_DTMF_AUTO (3 << 15) |
DP: DTMF Support: AUTO switch between rfc2833 and in-band DTMF
Definition at line 930 of file chan_sip.c.
Referenced by check_peer_ok(), check_user_ok(), create_addr_from_peer(), handle_common_options(), process_sdp(), sip_alloc(), and sip_new().
#define SIP_DTMF_INBAND (1 << 15) |
DP: DTMF Support: Inband audio, only for ULAW/ALAW - "inband"
Definition at line 928 of file chan_sip.c.
Referenced by handle_common_options(), process_sdp(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
#define SIP_DTMF_INFO (2 << 15) |
DP: DTMF Support: SIP Info messages - "info"
Definition at line 929 of file chan_sip.c.
Referenced by handle_common_options(), sip_dtmfmode(), sip_new(), and sip_senddigit_end().
#define SIP_DTMF_RFC2833 (0 << 15) |
DP: DTMF Support: RTP DTMF - "rfc2833"
Definition at line 927 of file chan_sip.c.
Referenced by check_peer_ok(), check_user_ok(), create_addr_from_peer(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
#define SIP_DTMF_SHORTINFO (4 << 15) |
DP: DTMF Support: SIP Info messages - "info" - short variant
Definition at line 931 of file chan_sip.c.
Referenced by handle_common_options(), sip_dtmfmode(), sip_new(), sip_senddigit_end(), and transmit_info_with_digit().
#define SIP_FLAGS_TO_COPY |
Value:
(SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \ SIP_PROG_INBAND | SIP_USECLIENTCODE | SIP_NAT | SIP_G726_NONSTANDARD | \ SIP_USEREQPHONE | SIP_INSECURE)
Definition at line 963 of file chan_sip.c.
Referenced by build_user(), check_peer_ok(), check_user_ok(), create_addr_from_peer(), set_peer_defaults(), sip_alloc(), and sip_poke_peer().
#define SIP_G726_NONSTANDARD (1 << 31) |
DP: Use non-standard packing for G726-32 data
Definition at line 960 of file chan_sip.c.
Referenced by add_codec_to_sdp(), handle_common_options(), and process_sdp().
#define SIP_GOTREFER (1 << 6) |
D: Got a refer?
Definition at line 914 of file chan_sip.c.
Referenced by handle_request_refer(), local_attended_transfer(), sip_read(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_INC_COUNT (1 << 8) |
D: Did this dialog increment the counter of in-use calls?
Definition at line 916 of file chan_sip.c.
Referenced by __sip_destroy(), handle_request_cancel(), sip_hangup(), and update_call_counter().
#define SIP_INC_RINGING (1 << 9) |
D: Did this connection increment the counter of in-use calls?
Definition at line 917 of file chan_sip.c.
Referenced by update_call_counter().
#define SIP_INSECURE (3 << 23) |
DP: three settings, uses two bits
Definition at line 948 of file chan_sip.c.
Referenced by _sip_show_peer(), and handle_common_options().
#define SIP_INSECURE_INVITE (1 << 24) |
DP: don't require authentication for incoming INVITEs
Definition at line 951 of file chan_sip.c.
Referenced by check_peer_ok(), and set_insecure_flags().
#define SIP_INSECURE_NONE (0 << 23) |
DP: secure mode
Definition at line 949 of file chan_sip.c.
#define SIP_INSECURE_PORT (1 << 23) |
DP: don't require matching port for incoming requests
Definition at line 950 of file chan_sip.c.
Referenced by get_insecure_variable_from_config(), set_insecure_flags(), and sip_addrcmp().
#define SIP_MAX_HEADERS 64 |
Max amount of SIP headers to read
Definition at line 238 of file chan_sip.c.
Referenced by add_header(), and parse_request().
#define SIP_MAX_LINES 64 |
Max amount of lines in SIP attachment (like SDP)
Definition at line 239 of file chan_sip.c.
Referenced by add_line(), and parse_request().
#define SIP_MAX_PACKET 4096 |
Also from RFC 3261 (2543), should sub headers tho
Definition at line 240 of file chan_sip.c.
#define SIP_NAT (3 << 18) |
DP: four settings, uses two bits
Definition at line 934 of file chan_sip.c.
Referenced by _sip_show_peer(), build_via(), copy_via_headers(), create_addr(), create_addr_from_peer(), handle_common_options(), process_sdp(), register_verify(), sip_alloc(), sip_nat_mode(), sip_real_dst(), sip_show_channel(), sip_show_settings(), sip_show_users(), and transmit_response_using_temp().
#define SIP_NAT_ALWAYS (3 << 18) |
DP: NAT Both ROUTE and RFC3581
Definition at line 938 of file chan_sip.c.
Referenced by copy_via_headers(), and handle_common_options().
#define SIP_NAT_NEVER (0 << 18) |
DP: No nat support
Definition at line 935 of file chan_sip.c.
Referenced by handle_common_options().
#define SIP_NAT_RFC3581 (1 << 18) |
DP: NAT RFC3581
Definition at line 936 of file chan_sip.c.
Referenced by build_via(), copy_via_headers(), and handle_common_options().
#define SIP_NAT_ROUTE (2 << 18) |
DP: NAT Only ROUTE
Definition at line 937 of file chan_sip.c.
Referenced by _sip_show_peers(), build_peer(), check_peer_ok(), check_user_full(), check_user_ok(), create_addr(), create_addr_from_peer(), handle_common_options(), parse_register_contact(), send_request(), set_address_from_contact(), sip_alloc(), sip_nat_mode(), sip_real_dst(), and transmit_response_using_temp().
#define SIP_NEEDREINVITE (1 << 4) |
D: Do we need to send another reinvite?
Definition at line 912 of file chan_sip.c.
Referenced by check_pendings(), sip_hangup(), sip_indicate(), sip_read(), sip_reinvite_retry(), sip_sendhtml(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_OPT_100REL (1 << 1) |
Definition at line 517 of file chan_sip.c.
#define SIP_OPT_EARLY_SESSION (1 << 3) |
Definition at line 519 of file chan_sip.c.
#define SIP_OPT_EVENTLIST (1 << 11) |
Definition at line 527 of file chan_sip.c.
#define SIP_OPT_GRUU (1 << 12) |
Definition at line 528 of file chan_sip.c.
#define SIP_OPT_HISTINFO (1 << 15) |
Definition at line 531 of file chan_sip.c.
#define SIP_OPT_JOIN (1 << 4) |
Definition at line 520 of file chan_sip.c.
#define SIP_OPT_NOREFERSUB (1 << 14) |
Definition at line 530 of file chan_sip.c.
#define SIP_OPT_PATH (1 << 5) |
Definition at line 521 of file chan_sip.c.
#define SIP_OPT_PRECONDITION (1 << 7) |
Definition at line 523 of file chan_sip.c.
#define SIP_OPT_PREF (1 << 6) |
Definition at line 522 of file chan_sip.c.
#define SIP_OPT_PRIVACY (1 << 8) |
Definition at line 524 of file chan_sip.c.
#define SIP_OPT_REPLACES (1 << 0) |
#define SIP_OPT_RESPRIORITY (1 << 16) |
Definition at line 532 of file chan_sip.c.
#define SIP_OPT_SDP_ANAT (1 << 9) |
Definition at line 525 of file chan_sip.c.
#define SIP_OPT_SEC_AGREE (1 << 10) |
Definition at line 526 of file chan_sip.c.
#define SIP_OPT_TARGET_DIALOG (1 << 13) |
Definition at line 529 of file chan_sip.c.
#define SIP_OPT_TIMER (1 << 2) |
#define SIP_OPT_UNKNOWN (1 << 17) |
#define SIP_OUTGOING (1 << 0) |
D: Direction of the last transaction in this dialog
Definition at line 909 of file chan_sip.c.
Referenced by get_sip_pvt_byid_locked(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), reqprep(), respprep(), sip_call(), sip_hangup(), sip_indicate(), sip_poke_peer(), sip_send_mwi_to_peer(), sip_show_channel(), sip_write(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_with_sdp().
#define SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
DP: Allow overlap dialing ?
Definition at line 982 of file chan_sip.c.
Referenced by _sip_show_peer(), get_destination(), handle_common_options(), handle_request_invite(), and sip_show_settings().
#define SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
GP: Allow subscriptions from this peer?
Definition at line 981 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), build_user(), handle_common_options(), handle_request_subscribe(), and sip_show_settings().
#define SIP_PAGE2_BUGGY_MWI (1 << 26) |
DP: Buggy CISCO MWI fix
Definition at line 997 of file chan_sip.c.
Referenced by handle_common_options(), and transmit_notify_with_mwi().
#define SIP_PAGE2_CALL_ONHOLD (3 << 23) |
D: Call hold states:
Definition at line 991 of file chan_sip.c.
Referenced by __sip_destroy(), add_sdp(), check_rtp_timeout(), handle_request_cancel(), process_sdp(), show_channels_cb(), sip_hangup(), and update_call_counter().
#define SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 23) |
#define SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 23) |
D: Inactive hold
Definition at line 994 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp().
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) |
D: One directional hold
Definition at line 993 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp().
#define SIP_PAGE2_DIALOG_ESTABLISHED (1 << 27) |
29: Has a dialog been established?
Definition at line 998 of file chan_sip.c.
Referenced by find_call(), handle_request_bye(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), and sip_answer().
#define SIP_PAGE2_FLAGS_TO_COPY |
Value:
(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_IGNORESDPVERSION | \ SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | \ SIP_PAGE2_BUGGY_MWI | SIP_PAGE2_TEXTSUPPORT | SIP_PAGE2_UDPTL_DESTINATION)
Definition at line 1002 of file chan_sip.c.
Referenced by build_user(), check_peer_ok(), check_user_ok(), create_addr_from_peer(), set_peer_defaults(), sip_alloc(), and sip_poke_peer().
#define SIP_PAGE2_IGNORESDPVERSION (1 << 19) |
GDP: Ignore the SDP session version number we receive and treat all sessions as new
Definition at line 984 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), process_sdp(), sip_show_settings(), and sip_show_user().
#define SIP_PAGE2_REGISTERTRYING (1 << 29) |
DP: Send 100 Trying on REGISTER attempts
Definition at line 999 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), and register_verify().
#define SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
DP: Compensate for buggy RFC2833 implementations
Definition at line 996 of file chan_sip.c.
Referenced by create_addr_from_peer(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), and sip_show_settings().
#define SIP_PAGE2_RPORT_PRESENT (1 << 10) |
Was rport received in the Via header?
Definition at line 978 of file chan_sip.c.
Referenced by check_user_full(), and check_via().
#define SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
GP: Should we clean memory from peers after expiry?
Definition at line 974 of file chan_sip.c.
Referenced by expire_register().
#define SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
GP: Should we keep RT objects in memory for extended time?
Definition at line 973 of file chan_sip.c.
Referenced by build_peer(), parse_register_contact(), sip_prune_realtime(), sip_show_settings(), and update_peer().
#define SIP_PAGE2_STATECHANGEQUEUE (1 << 9) |
D: Unsent state pending change exists
Definition at line 976 of file chan_sip.c.
Referenced by cb_extensionstate(), and handle_response().
#define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
GP: Only issue MWI notification if subscribed to
Definition at line 983 of file chan_sip.c.
Referenced by build_peer(), handle_request_subscribe(), register_verify(), and sip_send_mwi_to_peer().
#define SIP_PAGE2_T38SUPPORT (7 << 20) |
GDP: T38 Fax Passthrough Support
Definition at line 986 of file chan_sip.c.
Referenced by create_addr_from_peer(), handle_request_invite(), sip_alloc(), sip_indicate(), sip_queryoption(), and sip_write().
#define SIP_PAGE2_T38SUPPORT_RTP (2 << 20) |
GDP: T38 Fax Passthrough Support (not implemented)
Definition at line 988 of file chan_sip.c.
Referenced by _sip_show_peer(), add_sdp(), handle_common_options(), and sip_show_settings().
#define SIP_PAGE2_T38SUPPORT_TCP (4 << 20) |
GDP: T38 Fax Passthrough Support (not implemented)
Definition at line 989 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and sip_show_settings().
#define SIP_PAGE2_T38SUPPORT_UDPTL (1 << 20) |
GDP: T38 Fax Passthrough Support
Definition at line 987 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), sip_read(), sip_rtp_read(), and sip_show_settings().
#define SIP_PAGE2_TEXTSUPPORT (1 << 15) |
GDP: Global text enable
Definition at line 980 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), check_peer_ok(), check_user_ok(), create_addr_from_peer(), handle_common_options(), sip_alloc(), and sip_show_settings().
#define SIP_PAGE2_UDPTL_DESTINATION (1 << 30) |
DP: Use source IP of RTP as destination if NAT is enabled
Definition at line 1000 of file chan_sip.c.
Referenced by handle_common_options(), and process_sdp().
#define SIP_PAGE2_VIDEOSUPPORT (1 << 14) |
DP: Video supported if offered?
Definition at line 979 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), check_peer_ok(), check_user_ok(), create_addr_from_peer(), handle_common_options(), sip_alloc(), and sip_show_settings().
#define SIP_PENDINGBYE (1 << 5) |
D: Need to send bye after we ack?
Definition at line 913 of file chan_sip.c.
Referenced by check_pendings(), handle_response_invite(), register_verify(), sip_hangup(), sip_indicate(), sip_read(), sip_sendhtml(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_PROG_INBAND (3 << 25) |
DP: three settings, uses two bits
Definition at line 954 of file chan_sip.c.
Referenced by handle_common_options(), sip_indicate(), and sip_show_settings().
#define SIP_PROG_INBAND_NEVER (0 << 25) |
#define SIP_PROG_INBAND_NO (1 << 25) |
Definition at line 956 of file chan_sip.c.
Referenced by handle_common_options(), and sip_show_settings().
#define SIP_PROG_INBAND_YES (2 << 25) |
Definition at line 957 of file chan_sip.c.
Referenced by handle_common_options(), and sip_indicate().
#define SIP_PROGRESS_SENT (1 << 3) |
D: Have sent 183 message progress
Definition at line 911 of file chan_sip.c.
Referenced by sip_indicate(), and sip_write().
#define SIP_PROMISCREDIR (1 << 11) |
DP: Promiscuous redirection
Definition at line 920 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), parse_moved_contact(), sip_show_channel(), and sip_show_settings().
#define sip_pvt_lock | ( | x | ) | ast_mutex_lock(&x->pvt_lock) |
Definition at line 1358 of file chan_sip.c.
Referenced by __sip_ack(), auto_congest(), cb_extensionstate(), check_rtp_timeout(), get_sip_pvt_byid_locked(), handle_request_invite(), handle_request_subscribe(), proc_session_timer(), retrans_pkt(), scheduler_process_request_queue(), sip_answer(), 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_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_transfer(), sip_write(), try_suggested_sip_codec(), and update_call_counter().
#define sip_pvt_trylock | ( | x | ) | ast_mutex_trylock(&x->pvt_lock) |
#define sip_pvt_unlock | ( | x | ) | ast_mutex_unlock(&x->pvt_lock) |
Definition at line 1360 of file chan_sip.c.
Referenced by __sip_ack(), auto_congest(), cb_extensionstate(), check_rtp_timeout(), do_monitor(), get_sip_pvt_byid_locked(), handle_invite_replaces(), handle_request_do(), handle_request_invite(), handle_request_subscribe(), local_attended_transfer(), proc_session_timer(), retrans_pkt(), scheduler_process_request_queue(), sip_answer(), 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_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_transfer(), sip_write(), try_suggested_sip_codec(), and update_call_counter().
#define SIP_REINVITE (7 << 20) |
DP: four settings, uses three bits
Definition at line 941 of file chan_sip.c.
Referenced by handle_common_options().
#define SIP_REINVITE_NONE (0 << 20) |
DP: no reinvite allowed
Definition at line 942 of file chan_sip.c.
#define SIP_REINVITE_UPDATE (4 << 20) |
DP: use UPDATE (RFC3311) when reinviting this peer
Definition at line 945 of file chan_sip.c.
Referenced by handle_common_options(), and transmit_reinvite_with_sdp().
#define SIP_RESERVED ";/?:@&=+$,# " |
Definition at line 192 of file chan_sip.c.
#define SIP_RINGING (1 << 2) |
#define SIP_SENDRPID (1 << 29) |
DP: Remote Party-ID Support
Definition at line 959 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and initreqprep().
#define SIP_TIMER_T1 500 |
Definition at line 231 of file chan_sip.c.
#define SIP_TRANS_TIMEOUT 64 * SIP_TIMER_T1 |
SIP request timeout (rfc 3261) 64*T1
Definition at line 232 of file chan_sip.c.
Referenced by sip_sipredirect().
#define SIP_TRUSTRPID (1 << 12) |
DP: Trust RPID headers?
Definition at line 921 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and replace_cid().
#define SIP_USECLIENTCODE (1 << 14) |
DP: Trust X-ClientCode info message
Definition at line 923 of file chan_sip.c.
Referenced by handle_common_options(), handle_request_info(), and sip_show_settings().
#define SIP_USEREQPHONE (1 << 13) |
DP: Add user=phone to numeric URI. Default off
Definition at line 922 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), initreqprep(), and sip_show_settings().
#define SIPBUFSIZE 512 |
Definition at line 188 of file chan_sip.c.
Referenced by add_route(), add_sdp(), check_peer_ok(), extract_uri(), handle_request_refer(), initreqprep(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), process_sdp(), respprep(), show_channels_cb(), sip_call(), sip_new(), sip_show_channel(), sip_show_settings(), transmit_invite(), and transmit_notify_with_sipfrag().
#define STANDARD_SIP_PORT 5060 |
Standard SIP and TLS port from RFC 3261. DO NOT CHANGE THIS.
Definition at line 592 of file chan_sip.c.
Referenced by __set_address_from_contact(), build_peer(), check_via(), create_addr(), initreqprep(), manager_show_registry(), parse_register_contact(), proxy_allocate(), reload_config(), set_destination(), set_peer_defaults(), sip_parse_host(), sip_show_registry(), sip_standard_port(), and transmit_register().
#define STANDARD_TLS_PORT 5061 |
Definition at line 593 of file chan_sip.c.
Referenced by __set_address_from_contact(), build_peer(), create_addr(), parse_register_contact(), reload_config(), sip_parse_host(), and sip_standard_port().
#define SUPPORTED 1 |
Define SIP option tags, used in Require: and Supported: headers We need to be aware of these properties in the phones to use the replace: header. We should not do that without knowing that the other end supports it... This is nothing we can configure, we learn by the dialog Supported: header on the REGISTER (peer) or the INVITE (other devices) We are not using many of these today, but will in the future. This is documented in RFC 3261
Definition at line 512 of file chan_sip.c.
#define SUPPORTED_EXTENSIONS "replaces, timer" |
SIP Extensions we support.
Definition at line 589 of file chan_sip.c.
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), and transmit_reinvite_with_sdp().
#define T38FAX_FILL_BIT_REMOVAL (1 << 0) |
Default: 0 (unset)
Definition at line 1013 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp().
#define T38FAX_RATE_12000 (1 << 12) |
12000 bps t38FaxRate
Definition at line 1032 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_14400 (1 << 13) |
14400 bps t38FaxRate This is default: NO MMR and JBIG transcoding, NO fill bit removal, transferredTCF TCF, UDP FEC, Version 0 and 9600 max fax rate
Definition at line 1033 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_2400 (1 << 8) |
2400 bps t38FaxRate
Definition at line 1028 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_4800 (1 << 9) |
4800 bps t38FaxRate
Definition at line 1029 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_7200 (1 << 10) |
7200 bps t38FaxRate
Definition at line 1030 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_9600 (1 << 11) |
9600 bps t38FaxRate
Definition at line 1031 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_MANAGEMENT_LOCAL_TCF (1 << 3) |
Unset for transferredTCF (UDPTL), set for localTCF (TPKT)
Definition at line 1018 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp().
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
Definition at line 1017 of file chan_sip.c.
Referenced by process_sdp(), and set_t38_capabilities().
#define T38FAX_TRANSCODING_JBIG (1 << 2) |
Default: 0 (unset)
Definition at line 1015 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp().
#define T38FAX_TRANSCODING_MMR (1 << 1) |
Default: 0 (unset)
Definition at line 1014 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp().
#define T38FAX_UDP_EC_FEC (1 << 4) |
Set for t38UDPFEC
Definition at line 1021 of file chan_sip.c.
Referenced by process_sdp(), and set_t38_capabilities().
#define T38FAX_UDP_EC_NONE (0 << 4) |
two bits, if unset NO t38UDPEC field in T38 SDP
Definition at line 1020 of file chan_sip.c.
Referenced by add_sdp(), process_sdp(), and set_t38_capabilities().
#define T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
Set for t38UDPRedundancy
Definition at line 1022 of file chan_sip.c.
Referenced by add_sdp(), process_sdp(), and set_t38_capabilities().
#define T38FAX_VERSION (3 << 6) |
two bits, 2 values so far, up to 4 values max
Definition at line 1024 of file chan_sip.c.
Referenced by add_sdp().
#define T38FAX_VERSION_0 (0 << 6) |
#define T38FAX_VERSION_1 (1 << 6) |
#define TRUE 1 |
Definition at line 185 of file chan_sip.c.
#define UNLINK | ( | element, | |||
head, | |||||
prev | ) |
some list management macros.
Definition at line 1697 of file chan_sip.c.
Referenced by __sip_ack(), __sip_destroy(), and retrans_pkt().
#define XMIT_ERROR -2 |
Definition at line 190 of file chan_sip.c.
Referenced by __sip_reliable_xmit(), __sip_xmit(), handle_response_invite(), retrans_pkt(), sip_call(), and sip_poke_peer().
enum can_create_dialog |
States whether a SIP message can create a dialog in Asterisk.
Definition at line 437 of file chan_sip.c.
00437 { 00438 CAN_NOT_CREATE_DIALOG, 00439 CAN_CREATE_DIALOG, 00440 CAN_CREATE_DIALOG_UNSUPPORTED_METHOD, 00441 };
enum check_auth_result |
Authentication result from check_auth* functions.
Definition at line 348 of file chan_sip.c.
00348 { 00349 AUTH_DONT_KNOW = -100, /*!< no result, need to check further */ 00350 /* XXX maybe this is the same as AUTH_NOT_FOUND */ 00351 00352 AUTH_SUCCESSFUL = 0, 00353 AUTH_CHALLENGE_SENT = 1, 00354 AUTH_SECRET_FAILED = -1, 00355 AUTH_USERNAME_MISMATCH = -2, 00356 AUTH_NOT_FOUND = -3, /*!< returned by register_verify */ 00357 AUTH_FAKE_AUTH = -4, 00358 AUTH_UNKNOWN_DOMAIN = -5, 00359 AUTH_PEER_NOT_DYNAMIC = -6, 00360 AUTH_ACL_FAILED = -7, 00361 AUTH_BAD_TRANSPORT = -8, 00362 };
enum domain_mode |
Modes for SIP domain handling in the PBX.
SIP_DOMAIN_AUTO | This domain is auto-configured |
SIP_DOMAIN_CONFIG | This domain is from configuration |
Definition at line 863 of file chan_sip.c.
00863 { 00864 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00865 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00866 };
enum invitestates |
States for the INVITE transaction, not the dialog.
Definition at line 282 of file chan_sip.c.
00282 { 00283 INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */ 00284 INV_CALLING = 1, /*!< Invite sent, no answer */ 00285 INV_PROCEEDING = 2, /*!< We got/sent 1xx message */ 00286 INV_EARLY_MEDIA = 3, /*!< We got 18x message with to-tag back */ 00287 INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */ 00288 INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */ 00289 INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 00290 The only way out of this is a BYE from one side */ 00291 INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */ 00292 };
enum media_type |
Definition at line 301 of file chan_sip.c.
00301 { 00302 PARSE_REGISTER_FAILED, 00303 PARSE_REGISTER_UPDATE, 00304 PARSE_REGISTER_QUERY, 00305 };
enum referstatus |
Parameters to know status of transfer.
Definition at line 1079 of file chan_sip.c.
01079 { 01080 REFER_IDLE, /*!< No REFER is in progress */ 01081 REFER_SENT, /*!< Sent REFER to transferee */ 01082 REFER_RECEIVED, /*!< Received REFER from transferrer */ 01083 REFER_CONFIRMED, /*!< Refer confirmed with a 100 TRYING (unused) */ 01084 REFER_ACCEPTED, /*!< Accepted by transferee */ 01085 REFER_RINGING, /*!< Target Ringing */ 01086 REFER_200OK, /*!< Answered by transfer target */ 01087 REFER_FAILED, /*!< REFER declined - go on */ 01088 REFER_NOAUTH /*!< We had no auth for REFER */ 01089 };
enum sip_auth_type |
Authentication types - proxy or www authentication.
Definition at line 342 of file chan_sip.c.
00342 { 00343 PROXY_AUTH = 407, 00344 WWW_AUTH = 401, 00345 };
enum sip_debug_e |
debugging state We store separately the debugging requests from the config file and requests from the CLI. Debugging is enabled if either is set (which means that if sipdebug is set in the config file, we can only turn it off by reloading the config).
Definition at line 1045 of file chan_sip.c.
01045 { 01046 sip_debug_none = 0, 01047 sip_debug_config = 1, 01048 sip_debug_console = 2, 01049 };
enum sip_result |
Definition at line 274 of file chan_sip.c.
00274 { 00275 AST_SUCCESS = 0, 00276 AST_FAILURE = -1, 00277 };
enum sip_transport |
Definition at line 415 of file chan_sip.c.
00415 { 00416 SIP_TRANSPORT_UDP = 1, 00417 SIP_TRANSPORT_TCP = 1 << 1, 00418 SIP_TRANSPORT_TLS = 1 << 2, 00419 };
enum sipmethod |
SIP Request methods known by Asterisk.
Definition at line 453 of file chan_sip.c.
00453 { 00454 SIP_UNKNOWN, /*!< Unknown response */ 00455 SIP_RESPONSE, /*!< Not request, response to outbound request */ 00456 SIP_REGISTER, /*!< Registration to the mothership, tell us where you are located */ 00457 SIP_OPTIONS, /*!< Check capabilities of a device, used for "ping" too */ 00458 SIP_NOTIFY, /*!< Status update, Part of the event package standard, result of a SUBSCRIBE or a REFER */ 00459 SIP_INVITE, /*!< Set up a session */ 00460 SIP_ACK, /*!< End of a three-way handshake started with INVITE. */ 00461 SIP_PRACK, /*!< Reliable pre-call signalling. Not supported in Asterisk. */ 00462 SIP_BYE, /*!< End of a session */ 00463 SIP_REFER, /*!< Refer to another URI (transfer) */ 00464 SIP_SUBSCRIBE, /*!< Subscribe for updates (voicemail, session status, device status, presence) */ 00465 SIP_MESSAGE, /*!< Text messaging */ 00466 SIP_UPDATE, /*!< Update a dialog. We can send UPDATE; but not accept it */ 00467 SIP_INFO, /*!< Information updates during a session */ 00468 SIP_CANCEL, /*!< Cancel an INVITE */ 00469 SIP_PUBLISH, /*!< Not supported in Asterisk */ 00470 SIP_PING, /*!< Not supported at all, no standard but still implemented out there */ 00471 };
enum sipregistrystate |
States for outbound registrations (with register= lines in sip.conf.
Definition at line 365 of file chan_sip.c.
00365 { 00366 REG_STATE_UNREGISTERED = 0, /*!< We are not registered 00367 * \note Initial state. We should have a timeout scheduled for the initial 00368 * (or next) registration transmission, calling sip_reregister 00369 */ 00370 00371 REG_STATE_REGSENT, /*!< Registration request sent 00372 * \note sent initial request, waiting for an ack or a timeout to 00373 * retransmit the initial request. 00374 */ 00375 00376 REG_STATE_AUTHSENT, /*!< We have tried to authenticate 00377 * \note entered after transmit_register with auth info, 00378 * waiting for an ack. 00379 */ 00380 00381 REG_STATE_REGISTERED, /*!< Registered and done */ 00382 00383 REG_STATE_REJECTED, /*!< Registration rejected * 00384 * \note only used when the remote party has an expire larger than 00385 * our max-expire. This is a final state from which we do not 00386 * recover (not sure how correctly). 00387 */ 00388 00389 REG_STATE_TIMEOUT, /*!< Registration timed out * 00390 * \note XXX unused */ 00391 00392 REG_STATE_NOAUTH, /*!< We have no accepted credentials 00393 * \note fatal - no chance to proceed */ 00394 00395 REG_STATE_FAILED, /*!< Registration failed after several tries 00396 * \note fatal - no chance to proceed */ 00397 };
enum st_mode |
Modes in which Asterisk can be configured to run SIP Session-Timers.
Definition at line 400 of file chan_sip.c.
00400 { 00401 SESSION_TIMER_MODE_INVALID = 0, /*!< Invalid value */ 00402 SESSION_TIMER_MODE_ACCEPT, /*!< Honor inbound Session-Timer requests */ 00403 SESSION_TIMER_MODE_ORIGINATE, /*!< Originate outbound and honor inbound requests */ 00404 SESSION_TIMER_MODE_REFUSE /*!< Ignore inbound Session-Timers requests */ 00405 };
enum st_refresher |
The entity playing the refresher role for Session-Timers.
SESSION_TIMER_REFRESHER_AUTO | Negotiated |
SESSION_TIMER_REFRESHER_UAC | Session is refreshed by the UAC |
SESSION_TIMER_REFRESHER_UAS | Session is refreshed by the UAS |
Definition at line 408 of file chan_sip.c.
00408 { 00409 SESSION_TIMER_REFRESHER_AUTO, /*!< Negotiated */ 00410 SESSION_TIMER_REFRESHER_UAC, /*!< Session is refreshed by the UAC */ 00411 SESSION_TIMER_REFRESHER_UAS /*!< Session is refreshed by the UAS */ 00412 };
enum subscriptiontype |
Definition at line 307 of file chan_sip.c.
00307 { 00308 NONE = 0, 00309 XPIDF_XML, 00310 DIALOG_INFO_XML, 00311 CPIM_PIDF_XML, 00312 PIDF_XML, 00313 MWI_NOTIFICATION 00314 };
enum t38_action_flag |
SDP_T38_NONE | Do not modify T38 information at all |
SDP_T38_INITIATE | Remote side has requested T38 with us |
SDP_T38_ACCEPT | Remote side accepted our T38 request |
Definition at line 1704 of file chan_sip.c.
01704 { 01705 SDP_T38_NONE = 0, /*!< Do not modify T38 information at all */ 01706 SDP_T38_INITIATE, /*!< Remote side has requested T38 with us */ 01707 SDP_T38_ACCEPT, /*!< Remote side accepted our T38 request */ 01708 };
enum t38state |
T38 States for a call.
T38_DISABLED | Not enabled |
T38_LOCAL_REINVITE | Offered from local - REINVITE |
T38_PEER_DIRECT | Offered from peer |
T38_PEER_REINVITE | Offered from peer - REINVITE |
T38_ENABLED | Negotiated (enabled) |
Definition at line 1060 of file chan_sip.c.
01060 { 01061 T38_DISABLED = 0, /*!< Not enabled */ 01062 T38_LOCAL_REINVITE, /*!< Offered from local - REINVITE */ 01063 T38_PEER_DIRECT, /*!< Offered from peer */ 01064 T38_PEER_REINVITE, /*!< Offered from peer - REINVITE */ 01065 T38_ENABLED /*!< Negotiated (enabled) */ 01066 };
enum transfermodes |
Authorization scheme for call transfers.
Definition at line 268 of file chan_sip.c.
00268 { 00269 TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */ 00270 TRANSFER_CLOSED, /*!< Allow no SIP transfers */ 00271 };
enum xmittype |
Definition at line 294 of file chan_sip.c.
00294 { 00295 XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits. 00296 If it fails, it's critical and will cause a teardown of the session */ 00297 XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */ 00298 XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */ 00299 };
static const char * __get_header | ( | const struct sip_request * | req, | |
const char * | name, | |||
int * | start | |||
) | [static] |
Definition at line 5802 of file chan_sip.c.
References ast_skip_blanks(), find_alias(), sip_request::header, sip_request::headers, len(), and pass.
05803 { 05804 int pass; 05805 05806 /* 05807 * Technically you can place arbitrary whitespace both before and after the ':' in 05808 * a header, although RFC3261 clearly says you shouldn't before, and place just 05809 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 05810 * a good idea to say you can do it, and if you can do it, why in the hell would. 05811 * you say you shouldn't. 05812 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 05813 * and we always allow spaces after that for compatibility. 05814 */ 05815 for (pass = 0; name && pass < 2;pass++) { 05816 int x, len = strlen(name); 05817 for (x=*start; x<req->headers; x++) { 05818 if (!strncasecmp(req->header[x], name, len)) { 05819 char *r = req->header[x] + len; /* skip name */ 05820 if (pedanticsipchecking) 05821 r = ast_skip_blanks(r); 05822 05823 if (*r == ':') { 05824 *start = x+1; 05825 return ast_skip_blanks(r+1); 05826 } 05827 } 05828 } 05829 if (pass == 0) /* Try aliases */ 05830 name = find_alias(name, NULL); 05831 } 05832 05833 /* Don't return NULL, so get_header is always a valid pointer */ 05834 return ""; 05835 }
static void __init_check_auth_buf | ( | void | ) | [static] |
static void __init_ts_temp_pvt | ( | void | ) | [static] |
static void __reg_module | ( | void | ) | [static] |
Definition at line 23046 of file chan_sip.c.
static int __set_address_from_contact | ( | const char * | fullcontact, | |
struct sockaddr_in * | sin, | |||
int | tcp | |||
) | [static] |
Definition at line 10262 of file chan_sip.c.
References ahp, ast_copy_string(), ast_gethostbyname(), ast_log(), ast_strlen_zero(), hp, LOG_NOTICE, LOG_WARNING, parse_uri(), STANDARD_SIP_PORT, and STANDARD_TLS_PORT.
Referenced by build_peer(), check_peer_ok(), and set_address_from_contact().
10263 { 10264 struct hostent *hp; 10265 struct ast_hostent ahp; 10266 int port; 10267 char *host, *pt; 10268 char contact_buf[256]; 10269 char contact2_buf[256]; 10270 char *contact, *contact2; 10271 10272 /* Work on a copy */ 10273 ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf)); 10274 ast_copy_string(contact2_buf, fullcontact, sizeof(contact2_buf)); 10275 contact = contact_buf; 10276 contact2 = contact2_buf; 10277 10278 /* We have only the part in <brackets> here so we just need to parse a SIP URI.*/ 10279 if (tcp) { 10280 if (parse_uri(contact, "sips:", &contact, NULL, &host, &pt, NULL, NULL)) { 10281 if (parse_uri(contact2, "sip:", &contact, NULL, &host, &pt, NULL, NULL)) 10282 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 10283 } 10284 port = !ast_strlen_zero(pt) ? atoi(pt) : STANDARD_TLS_PORT; 10285 } else { 10286 if (parse_uri(contact, "sip:", &contact, NULL, &host, &pt, NULL, NULL)) 10287 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 10288 port = !ast_strlen_zero(pt) ? atoi(pt) : STANDARD_SIP_PORT; 10289 } 10290 10291 /* XXX This could block for a long time XXX */ 10292 /* We should only do this if it's a name, not an IP */ 10293 hp = ast_gethostbyname(host, &ahp); 10294 if (!hp) { 10295 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 10296 return -1; 10297 } 10298 sin->sin_family = AF_INET; 10299 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 10300 sin->sin_port = htons(port); 10301 10302 return 0; 10303 }
static void __sip_ack | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
int | sipmethod | |||
) | [static] |
Acknowledges receipt of a packet and stops retransmission called with p locked.
Definition at line 3097 of file chan_sip.c.
References ast_debug, ast_free, ast_sched_del(), sip_pvt::callid, dialog_unref(), sip_proxy::force, sip_pkt::is_resp, sip_pkt::method, msg, sip_pkt::next, sip_pvt::outboundproxy, sip_pkt::owner, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::retransid, sched, sip_pkt::seqno, sip_pvt_lock, sip_pvt_unlock, and UNLINK.
Referenced by __sip_pretend_ack(), handle_incoming(), handle_request_invite(), and handle_response().
03098 { 03099 struct sip_pkt *cur, *prev = NULL; 03100 const char *msg = "Not Found"; /* used only for debugging */ 03101 03102 /* If we have an outbound proxy for this dialog, then delete it now since 03103 the rest of the requests in this dialog needs to follow the routing. 03104 If obforcing is set, we will keep the outbound proxy during the whole 03105 dialog, regardless of what the SIP rfc says 03106 */ 03107 if (p->outboundproxy && !p->outboundproxy->force) 03108 p->outboundproxy = NULL; 03109 03110 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 03111 if (cur->seqno != seqno || cur->is_resp != resp) 03112 continue; 03113 if (cur->is_resp || cur->method == sipmethod) { 03114 msg = "Found"; 03115 if (!resp && (seqno == p->pendinginvite)) { 03116 ast_debug(1, "Acked pending invite %d\n", p->pendinginvite); 03117 p->pendinginvite = 0; 03118 } 03119 if (cur->retransid > -1) { 03120 if (sipdebug) 03121 ast_debug(4, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 03122 } 03123 /* This odd section is designed to thwart a 03124 * race condition in the packet scheduler. There are 03125 * two conditions under which deleting the packet from the 03126 * scheduler can fail. 03127 * 03128 * 1. The packet has been removed from the scheduler because retransmission 03129 * is being attempted. The problem is that if the packet is currently attempting 03130 * retransmission and we are at this point in the code, then that MUST mean 03131 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 03132 * lock temporarily to allow retransmission. 03133 * 03134 * 2. The packet has reached its maximum number of retransmissions and has 03135 * been permanently removed from the packet scheduler. If this is the case, then 03136 * the packet's retransid will be set to -1. The atomicity of the setting and checking 03137 * of the retransid to -1 is ensured since in both cases p's lock is held. 03138 */ 03139 while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) { 03140 sip_pvt_unlock(p); 03141 usleep(1); 03142 sip_pvt_lock(p); 03143 } 03144 UNLINK(cur, p->packets, prev); 03145 dialog_unref(cur->owner); 03146 ast_free(cur); 03147 break; 03148 } 03149 } 03150 ast_debug(1, "Stopping retransmission on '%s' of %s %d: Match %s\n", 03151 p->callid, resp ? "Response" : "Request", seqno, msg); 03152 }
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 3009 of file chan_sip.c.
References sip_pvt::alreadygone, append_history, ast_debug, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup(), sip_pvt::autokillid, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, dialog_unref(), LOG_WARNING, sip_pvt::method, NONE, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, sip_pvt::relatedpeer, SIP_BYE, sip_destroy(), sip_methods, sip_scheddestroy(), sip_pvt::subscribed, transmit_request_with_auth(), transmit_state_notify(), TRUE, unref_peer(), and XMIT_RELIABLE.
Referenced by sip_scheddestroy().
03010 { 03011 struct sip_pvt *p = (struct sip_pvt *)data; 03012 03013 /* If this is a subscription, tell the phone that we got a timeout */ 03014 if (p->subscribed) { 03015 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 03016 p->subscribed = NONE; 03017 append_history(p, "Subscribestatus", "timeout"); 03018 ast_debug(3, "Re-scheduled destruction of SIP subscription %s\n", p->callid ? p->callid : "<unknown>"); 03019 return 10000; /* Reschedule this destruction so that we know that it's gone */ 03020 } 03021 03022 /* If there are packets still waiting for delivery, delay the destruction */ 03023 if (p->packets) { 03024 ast_debug(3, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 03025 append_history(p, "ReliableXmit", "timeout"); 03026 return 10000; 03027 } 03028 03029 if (p->subscribed == MWI_NOTIFICATION) 03030 if (p->relatedpeer) 03031 unref_peer(p->relatedpeer); /* Remove link to peer. If it's realtime, make sure it's gone from memory) */ 03032 03033 /* Reset schedule ID */ 03034 p->autokillid = -1; 03035 03036 if (p->owner) { 03037 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 03038 ast_queue_hangup(p->owner); 03039 dialog_unref(p); 03040 } else if (p->refer && !p->alreadygone) { 03041 ast_debug(3, "Finally hanging up channel after transfer: %s\n", p->callid); 03042 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03043 append_history(p, "ReferBYE", "Sending BYE on transferer call leg %s", p->callid); 03044 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03045 dialog_unref(p); 03046 } else { 03047 append_history(p, "AutoDestroy", "%s", p->callid); 03048 ast_debug(3, "Auto destroying SIP dialog '%s'\n", p->callid); 03049 sip_destroy(p); /* Go ahead and destroy dialog. All attempts to recover is done */ 03050 /* sip_destroy also absorbs the reference */ 03051 } 03052 return 0; 03053 }
static int __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner, | |||
int | lockdialoglist | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 4460 of file chan_sip.c.
References ast_channel::_softhangup, ast_channel_lock, ast_channel_unlock, ast_debug, ast_extension_state_del(), ast_free, AST_LIST_REMOVE_HEAD, ast_log(), ast_rtp_destroy(), ast_rtp_get_bridged(), ast_sched_del(), AST_SCHED_DEL, AST_SOFTHANGUP_DEV, ast_test_flag, ast_udptl_destroy(), ast_verbose(), sip_pvt::callid, DEC_CALL_LIMIT, dialog_unref(), dialoglist, dialoglist_lock(), dialoglist_unlock(), sip_pvt::flags, free_old_route(), sip_history::list, LOG_DEBUG, LOG_WARNING, sip_pvt::method, sip_peer::mwipvt, ast_channel::name, sip_pvt::next, sip_request::next, option_debug, sip_pkt::owner, sip_pvt::owner, registry_unref(), sip_pvt::relatedpeer, sip_pkt::retransid, sip_pvt::rtp, sched, sip_debug_test_pvt(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, ast_channel::tech_pvt, TRUE, UNLINK, update_call_counter(), and sip_pvt::vrtp.
Referenced by do_monitor(), sip_destroy(), and unload_module().
04461 { 04462 struct sip_pvt *cur, *prev = NULL; 04463 struct sip_pkt *cp; 04464 struct sip_request *req; 04465 04466 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 04467 if (p->rtp && ast_rtp_get_bridged(p->rtp)) { 04468 ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 04469 return -1; 04470 } 04471 04472 if (p->vrtp && ast_rtp_get_bridged(p->vrtp)) { 04473 ast_debug(2, "Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 04474 return -1; 04475 } 04476 04477 if (sip_debug_test_pvt(p)) 04478 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 04479 04480 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 04481 update_call_counter(p, DEC_CALL_LIMIT); 04482 ast_debug(2, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 04483 } 04484 04485 /* Unlink us from the owner if we have one */ 04486 if (p->owner) { 04487 if (lockowner) 04488 ast_channel_lock(p->owner); 04489 if (option_debug) 04490 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 04491 p->owner->tech_pvt = NULL; 04492 /* Make sure that the channel knows its backend is going away */ 04493 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 04494 if (lockowner) 04495 ast_channel_unlock(p->owner); 04496 /* Give the channel a chance to react before deallocation */ 04497 usleep(1); 04498 } 04499 04500 /* Remove link from peer to subscription of MWI */ 04501 if (p->relatedpeer && p->relatedpeer->mwipvt == p) 04502 p->relatedpeer->mwipvt = dialog_unref(p->relatedpeer->mwipvt); 04503 04504 if (dumphistory) 04505 sip_dump_history(p); 04506 04507 if (p->options) 04508 ast_free(p->options); 04509 04510 if (p->stateid > -1) 04511 ast_extension_state_del(p->stateid, NULL); 04512 AST_SCHED_DEL(sched, p->initid); 04513 AST_SCHED_DEL(sched, p->waitid); 04514 AST_SCHED_DEL(sched, p->autokillid); 04515 AST_SCHED_DEL(sched, p->request_queue_sched_id); 04516 AST_SCHED_DEL(sched, p->t38id); 04517 04518 if (p->rtp) { 04519 ast_rtp_destroy(p->rtp); 04520 } 04521 if (p->vrtp) { 04522 ast_rtp_destroy(p->vrtp); 04523 } 04524 if (p->trtp) { 04525 while (ast_rtp_get_bridged(p->trtp)) 04526 usleep(1); 04527 ast_rtp_destroy(p->trtp); 04528 } 04529 if (p->udptl) 04530 ast_udptl_destroy(p->udptl); 04531 if (p->refer) 04532 ast_free(p->refer); 04533 if (p->route) { 04534 free_old_route(p->route); 04535 p->route = NULL; 04536 } 04537 if (p->registry) { 04538 if (p->registry->call == p) 04539 p->registry->call = NULL; 04540 p->registry = registry_unref(p->registry); 04541 } 04542 04543 /* Destroy Session-Timers if allocated */ 04544 if (p->stimer) { 04545 if (p->stimer->st_active == TRUE && p->stimer->st_schedid > -1) 04546 ast_sched_del(sched, p->stimer->st_schedid); 04547 ast_free(p->stimer); 04548 } 04549 04550 /* Clear history */ 04551 if (p->history) { 04552 struct sip_history *hist; 04553 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 04554 ast_free(hist); 04555 p->history_entries--; 04556 } 04557 ast_free(p->history); 04558 p->history = NULL; 04559 } 04560 04561 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 04562 ast_free(req); 04563 } 04564 04565 /* Lock dialog list before removing ourselves from the list */ 04566 if (lockdialoglist) 04567 dialoglist_lock(); 04568 for (prev = NULL, cur = dialoglist; cur; prev = cur, cur = cur->next) { 04569 if (cur == p) { 04570 UNLINK(cur, dialoglist, prev); 04571 break; 04572 } 04573 } 04574 if (lockdialoglist) 04575 dialoglist_unlock(); 04576 if (!cur) { 04577 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 04578 return 0; 04579 } 04580 04581 /* remove all current packets in this dialog */ 04582 while((cp = p->packets)) { 04583 p->packets = p->packets->next; 04584 AST_SCHED_DEL(sched, cp->retransid); 04585 dialog_unref(cp->owner); 04586 ast_free(cp); 04587 } 04588 if (p->chanvars) { 04589 ast_variables_destroy(p->chanvars); 04590 p->chanvars = NULL; 04591 } 04592 ast_mutex_destroy(&p->pvt_lock); 04593 04594 ast_string_field_free_memory(p); 04595 04596 if (p->socket.tcptls_session) { 04597 ao2_ref(p->socket.tcptls_session, -1); 04598 p->socket.tcptls_session = NULL; 04599 } 04600 04601 ast_free(p); 04602 return 0; 04603 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 9658 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
09659 { 09660 int res; 09661 09662 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 09663 return res; 09664 }
static void __sip_pretend_ack | ( | struct sip_pvt * | p | ) | [static] |
Pretend to ack all packets called with p locked.
Definition at line 3156 of file chan_sip.c.
References __sip_ack(), ast_log(), sip_pkt::data, find_sip_method(), sip_pkt::is_resp, LOG_WARNING, sip_pkt::method, sip_request::method, sip_pvt::packets, sip_pkt::seqno, and sip_methods.
Referenced by handle_request_bye(), handle_request_cancel(), sip_hangup(), and sip_reg_timeout().
03157 { 03158 struct sip_pkt *cur = NULL; 03159 03160 while (p->packets) { 03161 int method; 03162 if (cur == p->packets) { 03163 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 03164 return; 03165 } 03166 cur = p->packets; 03167 method = (cur->method) ? cur->method : find_sip_method(cur->data); 03168 __sip_ack(p, cur->seqno, cur->is_resp, method); 03169 } 03170 }
static enum sip_result __sip_reliable_xmit | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
char * | data, | |||
int | len, | |||
int | fatal, | |||
int | sipmethod | |||
) | [static] |
Transmit packet with retransmits.
Definition at line 2936 of file chan_sip.c.
References __sip_xmit(), append_history, ast_calloc, ast_debug, AST_FAILURE, ast_free, ast_log(), AST_SCHED_DEL, AST_SCHED_REPLACE_VARIABLE, AST_SUCCESS, DEFAULT_RETRANS, dialog_ref(), LOG_ERROR, sip_pkt::next, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::response_code, retrans_pkt(), sched, SIP_INVITE, SIP_TRANSPORT_UDP, sip_pvt::socket, sip_pvt::timer_t1, sip_socket::type, and XMIT_ERROR.
Referenced by send_request(), and send_response().
02937 { 02938 struct sip_pkt *pkt = NULL; 02939 int siptimer_a = DEFAULT_RETRANS; 02940 int xmitres = 0; 02941 int respid; 02942 02943 if (sipmethod == SIP_INVITE) { 02944 /* Note this is a pending invite */ 02945 p->pendinginvite = seqno; 02946 } 02947 02948 /* If the transport is something reliable (TCP or TLS) then don't really send this reliably */ 02949 /* I removed the code from retrans_pkt that does the same thing so it doesn't get loaded into the scheduler */ 02950 /* According to the RFC some packets need to be retransmitted even if its TCP, so this needs to get revisited */ 02951 if (!(p->socket.type & SIP_TRANSPORT_UDP)) { 02952 xmitres = __sip_xmit(dialog_ref(p), data, len); /* Send packet */ 02953 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02954 append_history(p, "XmitErr", "%s", fatal ? "(Critical)" : "(Non-critical)"); 02955 return AST_FAILURE; 02956 } else 02957 return AST_SUCCESS; 02958 } 02959 02960 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 02961 return AST_FAILURE; 02962 /* copy data, add a terminator and save length */ 02963 memcpy(pkt->data, data, len); 02964 pkt->data[len] = '\0'; 02965 pkt->packetlen = len; 02966 /* copy other parameters from the caller */ 02967 pkt->method = sipmethod; 02968 pkt->seqno = seqno; 02969 pkt->is_resp = resp; 02970 pkt->is_fatal = fatal; 02971 pkt->owner = dialog_ref(p); 02972 pkt->next = p->packets; 02973 p->packets = pkt; /* Add it to the queue */ 02974 if (resp) { 02975 /* Parse out the response code */ 02976 if (sscanf(pkt->data, "SIP/2.0 %d", &respid) == 1) { 02977 pkt->response_code = respid; 02978 } 02979 } 02980 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 02981 pkt->retransid = -1; 02982 if (pkt->timer_t1) 02983 siptimer_a = pkt->timer_t1 * 2; 02984 02985 /* Schedule retransmission */ 02986 AST_SCHED_REPLACE_VARIABLE(pkt->retransid, sched, siptimer_a, retrans_pkt, pkt, 1); 02987 if (sipdebug) 02988 ast_debug(4, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 02989 02990 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 02991 02992 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02993 append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 02994 ast_log(LOG_ERROR, "Serious Network Trouble; __sip_xmit returns error for pkt data\n"); 02995 AST_SCHED_DEL(sched, pkt->retransid); 02996 p->packets = pkt->next; 02997 ast_free(pkt); 02998 return AST_FAILURE; 02999 } else { 03000 return AST_SUCCESS; 03001 } 03002 }
static int __sip_semi_ack | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
int | sipmethod | |||
) | [static] |
Acks receipt of packet, keep it around (used for provisional responses).
Definition at line 3173 of file chan_sip.c.
References ast_debug, AST_SCHED_DEL, sip_pvt::callid, sip_pkt::data, sip_pkt::is_resp, method_match(), sip_pkt::next, sip_pvt::packets, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, and cfsip_methods::text.
Referenced by handle_response().
03174 { 03175 struct sip_pkt *cur; 03176 int res = -1; 03177 03178 for (cur = p->packets; cur; cur = cur->next) { 03179 if (cur->seqno == seqno && cur->is_resp == resp && 03180 (cur->is_resp || method_match(sipmethod, cur->data))) { 03181 /* this is our baby */ 03182 if (cur->retransid > -1) { 03183 if (sipdebug) 03184 ast_debug(4, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 03185 } 03186 AST_SCHED_DEL(sched, cur->retransid); 03187 res = 0; 03188 break; 03189 } 03190 } 03191 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"); 03192 return res; 03193 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message Sends a SIP request or response on a given socket (in the pvt) Called by retrans_pkt, send_request, send_response and __sip_reliable_xmit.
Definition at line 2630 of file chan_sip.c.
References ast_debug, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_tcptls_server_write(), errno, ast_tcptls_session_instance::f, sip_socket::fd, get_transport_pvt(), ast_tcptls_session_instance::lock, LOG_WARNING, sip_prepare_socket(), sip_real_dst(), SIP_TRANSPORT_UDP, sip_pvt::socket, sip_socket::tcptls_session, sip_socket::type, and XMIT_ERROR.
Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().
02631 { 02632 int res = 0; 02633 const struct sockaddr_in *dst = sip_real_dst(p); 02634 02635 ast_debug(1, "Trying to put '%.10s' onto %s socket destined for %s:%d\n", data, get_transport_pvt(p), ast_inet_ntoa(dst->sin_addr), htons(dst->sin_port)); 02636 02637 if (sip_prepare_socket(p) < 0) 02638 return XMIT_ERROR; 02639 02640 if (p->socket.tcptls_session) 02641 ast_mutex_lock(&p->socket.tcptls_session->lock); 02642 02643 if (p->socket.type & SIP_TRANSPORT_UDP) { 02644 res = sendto(p->socket.fd, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 02645 } else if (p->socket.tcptls_session) { 02646 if (p->socket.tcptls_session->f) { 02647 res = ast_tcptls_server_write(p->socket.tcptls_session, data, len); 02648 } else { 02649 ast_debug(2, "No p->socket.tcptls_session->f len=%d\n", len); 02650 } 02651 } else { 02652 ast_debug(2, "Socket type is TCP but no tcptls_session is present to write to\n"); 02653 return XMIT_ERROR; 02654 } 02655 02656 if (p->socket.tcptls_session) 02657 ast_mutex_unlock(&p->socket.tcptls_session->lock); 02658 02659 if (res == -1) { 02660 switch (errno) { 02661 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 02662 case EHOSTUNREACH: /* Host can't be reached */ 02663 case ENETDOWN: /* Inteface down */ 02664 case ENETUNREACH: /* Network failure */ 02665 case ECONNREFUSED: /* ICMP port unreachable */ 02666 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 02667 } 02668 } 02669 if (res != len) 02670 ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), res, strerror(errno)); 02671 02672 return res; 02673 }
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 8013 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), buf, get_header(), ast_channel::hangupcause, LOG_WARNING, sip_pvt::method, sip_pvt::owner, respprep(), send_response(), and SIP_INVITE.
Referenced by transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().
08014 { 08015 struct sip_request resp; 08016 int seqno = 0; 08017 08018 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 08019 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 08020 return -1; 08021 } 08022 respprep(&resp, p, msg, req); 08023 add_header_contentLength(&resp, 0); 08024 /* If we are cancelling an incoming invite for some reason, add information 08025 about the reason why we are doing this in clear text */ 08026 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 08027 char buf[10]; 08028 08029 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 08030 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 08031 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 08032 } 08033 return send_response(p, &resp, reliable, seqno); 08034 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 23046 of file chan_sip.c.
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 13260 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ARRAY_LEN, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_print_group(), ast_sched_when(), ast_str_alloca, ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), sip_peer::auth, sip_peer::autoframing, buf, sip_peer::busy_level, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, CLI_SHOWUSAGE, CLI_SUCCESS, cli_yesno(), sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, FALSE, find_peer(), sip_peer::flags, sip_proxy::force, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, get_transport(), sip_peer::ha, sip_peer::host_dynamic, cfsip_options::id, insecure2str(), sip_peer::is_realtime, sip_peer::language, sip_peer::lastmsgssent, sip_peer::maxcallbitrate, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, sip_proxy::name, sip_peer::name, nat2str(), ast_variable::next, sip_auth::next, sip_peer::outboundproxy, peer_mailboxes_to_str(), peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_peer::qualifyfreq, sip_auth::realm, sip_peer::regexten, s, S_OR, sched, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, SIP_DTMF, SIP_INSECURE, SIP_NAT, sip_options, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNORESDPVERSION, SIP_PAGE2_REGISTERTRYING, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_PROMISCREDIR, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::socket, sip_st_cfg::st_max_se, sip_st_cfg::st_min_se, sip_st_cfg::st_mode_oper, sip_st_cfg::st_ref, status, sip_peer::stimer, stmode2str(), ast_str::str, strefresher2str(), sip_peer::subscribecontext, text, sip_peer::timer_b, sip_peer::timer_t1, sip_peer::tohost, transfermode2str(), TRUE, sip_socket::type, unref_peer(), sip_peer::useragent, sip_peer::username, sip_auth::username, ast_variable::value, and sip_peer::vmexten.
Referenced by manager_sip_show_peer(), and sip_show_peer().
13261 { 13262 char status[30] = ""; 13263 char cbuf[256]; 13264 struct sip_peer *peer; 13265 char codec_buf[512]; 13266 struct ast_codec_pref *pref; 13267 struct ast_variable *v; 13268 struct sip_auth *auth; 13269 int x = 0, codec = 0, load_realtime; 13270 int realtimepeers; 13271 13272 realtimepeers = ast_check_realtime("sippeers"); 13273 13274 if (argc < 4) 13275 return CLI_SHOWUSAGE; 13276 13277 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 13278 peer = find_peer(argv[3], NULL, load_realtime, 0); 13279 if (s) { /* Manager */ 13280 if (peer) { 13281 const char *id = astman_get_header(m, "ActionID"); 13282 13283 astman_append(s, "Response: Success\r\n"); 13284 if (!ast_strlen_zero(id)) 13285 astman_append(s, "ActionID: %s\r\n", id); 13286 } else { 13287 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]); 13288 astman_send_error(s, m, cbuf); 13289 return CLI_SUCCESS; 13290 } 13291 } 13292 if (peer && type==0 ) { /* Normal listing */ 13293 struct ast_str *mailbox_str = ast_str_alloca(512); 13294 ast_cli(fd, "\n\n"); 13295 ast_cli(fd, " * Name : %s\n", peer->name); 13296 if (realtimepeers) { /* Realtime is enabled */ 13297 ast_cli(fd, " Realtime peer: %s\n", peer->is_realtime ? "Yes, cached" : "No"); 13298 } 13299 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 13300 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 13301 for (auth = peer->auth; auth; auth = auth->next) { 13302 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 13303 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 13304 } 13305 ast_cli(fd, " Context : %s\n", peer->context); 13306 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 13307 ast_cli(fd, " Language : %s\n", peer->language); 13308 if (!ast_strlen_zero(peer->accountcode)) 13309 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 13310 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 13311 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 13312 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 13313 if (!ast_strlen_zero(peer->fromuser)) 13314 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 13315 if (!ast_strlen_zero(peer->fromdomain)) 13316 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 13317 ast_cli(fd, " Callgroup : "); 13318 print_group(fd, peer->callgroup, 0); 13319 ast_cli(fd, " Pickupgroup : "); 13320 print_group(fd, peer->pickupgroup, 0); 13321 peer_mailboxes_to_str(&mailbox_str, peer); 13322 ast_cli(fd, " Mailbox : %s\n", mailbox_str->str); 13323 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 13324 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 13325 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 13326 if (peer->busy_level) 13327 ast_cli(fd, " Busy level : %d\n", peer->busy_level); 13328 ast_cli(fd, " Dynamic : %s\n", cli_yesno(peer->host_dynamic)); 13329 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 13330 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 13331 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 13332 ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE))); 13333 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 13334 ast_cli(fd, " ACL : %s\n", cli_yesno(peer->ha != NULL)); 13335 ast_cli(fd, " T38 pt UDPTL : %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL))); 13336 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 13337 ast_cli(fd, " T38 pt RTP : %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP))); 13338 ast_cli(fd, " T38 pt TCP : %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP))); 13339 #endif 13340 ast_cli(fd, " CanReinvite : %s\n", cli_yesno(ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE))); 13341 ast_cli(fd, " PromiscRedir : %s\n", cli_yesno(ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR))); 13342 ast_cli(fd, " User=Phone : %s\n", cli_yesno(ast_test_flag(&peer->flags[0], SIP_USEREQPHONE))); 13343 ast_cli(fd, " Video Support: %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT))); 13344 ast_cli(fd, " Text Support : %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT))); 13345 ast_cli(fd, " Ign SDP ver : %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_IGNORESDPVERSION))); 13346 ast_cli(fd, " Trust RPID : %s\n", cli_yesno(ast_test_flag(&peer->flags[0], SIP_TRUSTRPID))); 13347 ast_cli(fd, " Send RPID : %s\n", cli_yesno(ast_test_flag(&peer->flags[0], SIP_SENDRPID))); 13348 ast_cli(fd, " Subscriptions: %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))); 13349 ast_cli(fd, " Overlap dial : %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP))); 13350 if (peer->outboundproxy) 13351 ast_cli(fd, " Outb. proxy : %s %s\n", ast_strlen_zero(peer->outboundproxy->name) ? "<not set>" : peer->outboundproxy->name, 13352 peer->outboundproxy->force ? "(forced)" : ""); 13353 13354 /* - is enumerated */ 13355 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 13356 ast_cli(fd, " Timer T1 : %d\n", peer->timer_t1); 13357 ast_cli(fd, " Timer B : %d\n", peer->timer_b); 13358 ast_cli(fd, " ToHost : %s\n", peer->tohost); 13359 ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port)); 13360 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 13361 ast_cli(fd, " Transport : %s\n", get_transport(peer->socket.type)); 13362 if (!ast_strlen_zero(global_regcontext)) 13363 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 13364 ast_cli(fd, " Def. Username: %s\n", peer->username); 13365 ast_cli(fd, " SIP Options : "); 13366 if (peer->sipoptions) { 13367 int lastoption = -1; 13368 for (x = 0 ; x < ARRAY_LEN(sip_options); x++) { 13369 if (sip_options[x].id != lastoption) { 13370 if (peer->sipoptions & sip_options[x].id) 13371 ast_cli(fd, "%s ", sip_options[x].text); 13372 lastoption = x; 13373 } 13374 } 13375 } else 13376 ast_cli(fd, "(none)"); 13377 13378 ast_cli(fd, "\n"); 13379 ast_cli(fd, " Codecs : "); 13380 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 13381 ast_cli(fd, "%s\n", codec_buf); 13382 ast_cli(fd, " Codec Order : ("); 13383 print_codec_to_cli(fd, &peer->prefs); 13384 ast_cli(fd, ")\n"); 13385 13386 ast_cli(fd, " Auto-Framing : %s \n", cli_yesno(peer->autoframing)); 13387 ast_cli(fd, " 100 on REG : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_REGISTERTRYING) ? "Yes" : "No"); 13388 ast_cli(fd, " Status : "); 13389 peer_status(peer, status, sizeof(status)); 13390 ast_cli(fd, "%s\n", status); 13391 ast_cli(fd, " Useragent : %s\n", peer->useragent); 13392 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 13393 ast_cli(fd, " Qualify Freq : %d ms\n", peer->qualifyfreq); 13394 if (peer->chanvars) { 13395 ast_cli(fd, " Variables :\n"); 13396 for (v = peer->chanvars ; v ; v = v->next) 13397 ast_cli(fd, " %s = %s\n", v->name, v->value); 13398 } 13399 13400 ast_cli(fd, " Sess-Timers : %s\n", stmode2str(peer->stimer.st_mode_oper)); 13401 ast_cli(fd, " Sess-Refresh : %s\n", strefresher2str(peer->stimer.st_ref)); 13402 ast_cli(fd, " Sess-Expires : %d secs\n", peer->stimer.st_max_se); 13403 ast_cli(fd, " Min-Sess : %d secs\n", peer->stimer.st_min_se); 13404 ast_cli(fd, "\n"); 13405 unref_peer(peer); 13406 } else if (peer && type == 1) { /* manager listing */ 13407 char buf[256]; 13408 struct ast_str *mailbox_str = ast_str_alloca(512); 13409 astman_append(s, "Channeltype: SIP\r\n"); 13410 astman_append(s, "ObjectName: %s\r\n", peer->name); 13411 astman_append(s, "ChanObjectType: peer\r\n"); 13412 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 13413 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 13414 astman_append(s, "Context: %s\r\n", peer->context); 13415 astman_append(s, "Language: %s\r\n", peer->language); 13416 if (!ast_strlen_zero(peer->accountcode)) 13417 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 13418 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 13419 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 13420 if (!ast_strlen_zero(peer->fromuser)) 13421 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 13422 if (!ast_strlen_zero(peer->fromdomain)) 13423 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 13424 astman_append(s, "Callgroup: "); 13425 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 13426 astman_append(s, "Pickupgroup: "); 13427 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 13428 peer_mailboxes_to_str(&mailbox_str, peer); 13429 astman_append(s, "VoiceMailbox: %s\r\n", mailbox_str->str); 13430 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 13431 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 13432 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 13433 astman_append(s, "Busy-level: %d\r\n", peer->busy_level); 13434 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 13435 astman_append(s, "Dynamic: %s\r\n", peer->host_dynamic?"Y":"N"); 13436 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 13437 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched, peer->expire)); 13438 astman_append(s, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE))); 13439 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 13440 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 13441 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 13442 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 13443 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 13444 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 13445 astman_append(s, "SIP-TextSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT)?"Y":"N")); 13446 astman_append(s, "SIP-Sess-Timers: %s\r\n", stmode2str(peer->stimer.st_mode_oper)); 13447 astman_append(s, "SIP-Sess-Refresh: %s\r\n", strefresher2str(peer->stimer.st_ref)); 13448 astman_append(s, "SIP-Sess-Expires: %d\r\n", peer->stimer.st_max_se); 13449 astman_append(s, "SIP-Sess-Min: %d\r\n", peer->stimer.st_min_se); 13450 13451 /* - is enumerated */ 13452 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 13453 astman_append(s, "ToHost: %s\r\n", peer->tohost); 13454 astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", ntohs(peer->addr.sin_port)); 13455 astman_append(s, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 13456 astman_append(s, "Default-Username: %s\r\n", peer->username); 13457 if (!ast_strlen_zero(global_regcontext)) 13458 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 13459 astman_append(s, "Codecs: "); 13460 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 13461 astman_append(s, "%s\r\n", codec_buf); 13462 astman_append(s, "CodecOrder: "); 13463 pref = &peer->prefs; 13464 for(x = 0; x < 32 ; x++) { 13465 codec = ast_codec_pref_index(pref, x); 13466 if (!codec) 13467 break; 13468 astman_append(s, "%s", ast_getformatname(codec)); 13469 if (x < 31 && ast_codec_pref_index(pref, x+1)) 13470 astman_append(s, ","); 13471 } 13472 13473 astman_append(s, "\r\n"); 13474 astman_append(s, "Status: "); 13475 peer_status(peer, status, sizeof(status)); 13476 astman_append(s, "%s\r\n", status); 13477 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 13478 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 13479 astman_append(s, "QualifyFreq : %d ms\n", peer->qualifyfreq); 13480 if (peer->chanvars) { 13481 for (v = peer->chanvars ; v ; v = v->next) { 13482 astman_append(s, "ChanVariable:\n"); 13483 astman_append(s, " %s,%s\r\n", v->name, v->value); 13484 } 13485 } 13486 13487 unref_peer(peer); 13488 13489 } else { 13490 ast_cli(fd, "Peer %s not found.\n", argv[3]); 13491 ast_cli(fd, "\n"); 13492 } 13493 13494 return CLI_SUCCESS; 13495 }
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 12744 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_copy_string(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, CLI_SHOWUSAGE, CLI_SUCCESS, FALSE, FORMAT, FORMAT2, id, name, peer_status(), peerl, s, SIP_NAT_ROUTE, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, status, and TRUE.
Referenced by manager_sip_show_peers(), and sip_show_peers().
12745 { 12746 regex_t regexbuf; 12747 int havepattern = FALSE; 12748 12749 /* the last argument is left-aligned, so we don't need a size anyways */ 12750 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %s\n" 12751 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n" 12752 12753 char name[256]; 12754 int total_peers = 0; 12755 int peers_mon_online = 0; 12756 int peers_mon_offline = 0; 12757 int peers_unmon_offline = 0; 12758 int peers_unmon_online = 0; 12759 const char *id; 12760 char idtext[256] = ""; 12761 int realtimepeers; 12762 12763 realtimepeers = ast_check_realtime("sippeers"); 12764 12765 if (s) { /* Manager - get ActionID */ 12766 id = astman_get_header(m, "ActionID"); 12767 if (!ast_strlen_zero(id)) 12768 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 12769 } 12770 12771 switch (argc) { 12772 case 5: 12773 if (!strcasecmp(argv[3], "like")) { 12774 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 12775 return CLI_SHOWUSAGE; 12776 havepattern = TRUE; 12777 } else 12778 return CLI_SHOWUSAGE; 12779 case 3: 12780 break; 12781 default: 12782 return CLI_SHOWUSAGE; 12783 } 12784 12785 if (!s) /* Normal list */ 12786 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 12787 12788 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 12789 char status[20] = ""; 12790 char srch[2000]; 12791 char pstatus; 12792 12793 ASTOBJ_RDLOCK(iterator); 12794 12795 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 12796 ASTOBJ_UNLOCK(iterator); 12797 continue; 12798 } 12799 12800 if (!ast_strlen_zero(iterator->username) && !s) 12801 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 12802 else 12803 ast_copy_string(name, iterator->name, sizeof(name)); 12804 12805 pstatus = peer_status(iterator, status, sizeof(status)); 12806 if (pstatus == 1) 12807 peers_mon_online++; 12808 else if (pstatus == 0) 12809 peers_mon_offline++; 12810 else { 12811 if (iterator->addr.sin_port == 0) 12812 peers_unmon_offline++; 12813 else 12814 peers_unmon_online++; 12815 } 12816 12817 snprintf(srch, sizeof(srch), FORMAT, name, 12818 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 12819 iterator->host_dynamic ? " D " : " ", /* Dynamic or not? */ 12820 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 12821 iterator->ha ? " A " : " ", /* permit/deny */ 12822 ntohs(iterator->addr.sin_port), status, 12823 realtimepeers ? (iterator->is_realtime ? "Cached RT":"") : ""); 12824 12825 if (!s) {/* Normal CLI list */ 12826 ast_cli(fd, FORMAT, name, 12827 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 12828 iterator->host_dynamic ? " D " : " ", /* Dynamic or not? */ 12829 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 12830 iterator->ha ? " A " : " ", /* permit/deny */ 12831 12832 ntohs(iterator->addr.sin_port), status, 12833 realtimepeers ? (iterator->is_realtime ? "Cached RT":"") : ""); 12834 } else { /* Manager format */ 12835 /* The names here need to be the same as other channels */ 12836 astman_append(s, 12837 "Event: PeerEntry\r\n%s" 12838 "Channeltype: SIP\r\n" 12839 "ObjectName: %s\r\n" 12840 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 12841 "IPaddress: %s\r\n" 12842 "IPport: %d\r\n" 12843 "Dynamic: %s\r\n" 12844 "Natsupport: %s\r\n" 12845 "VideoSupport: %s\r\n" 12846 "TextSupport: %s\r\n" 12847 "ACL: %s\r\n" 12848 "Status: %s\r\n" 12849 "RealtimeDevice: %s\r\n\r\n", 12850 idtext, 12851 iterator->name, 12852 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 12853 ntohs(iterator->addr.sin_port), 12854 iterator->host_dynamic ? "yes" : "no", /* Dynamic or not? */ 12855 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 12856 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 12857 ast_test_flag(&iterator->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "yes" : "no", /* TEXTSUPPORT=yes? */ 12858 iterator->ha ? "yes" : "no", /* permit/deny */ 12859 status, 12860 realtimepeers ? (iterator->is_realtime ? "yes":"no") : "no"); 12861 } 12862 12863 ASTOBJ_UNLOCK(iterator); 12864 12865 total_peers++; 12866 } while(0) ); 12867 12868 if (!s) 12869 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 12870 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 12871 12872 if (havepattern) 12873 regfree(®exbuf); 12874 12875 if (total) 12876 *total = total_peers; 12877 12878 12879 return CLI_SUCCESS; 12880 #undef FORMAT 12881 #undef FORMAT2 12882 }
static void * _sip_tcp_helper_thread | ( | struct sip_pvt * | pvt, | |
struct ast_tcptls_session_instance * | tcptls_session | |||
) | [static] |
SIP TCP thread management function.
Definition at line 2220 of file chan_sip.c.
References ast_calloc, ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_wait_for_input(), buf, cleanup(), sip_request::data, sip_request::debug, ast_tcptls_session_instance::f, ast_tcptls_session_instance::fd, sip_socket::fd, get_header(), handle_request_do(), sip_request::ignore, sip_request::len, sip_threadinfo::list, ast_tcptls_session_instance::lock, me, ourport_tcp, ourport_tls, parse_copy(), sip_socket::port, ast_tcptls_session_instance::requestor, set_socket_transport(), SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, sip_request::socket, ast_tcptls_session_instance::ssl, sip_socket::tcptls_session, and sip_threadinfo::tcptls_session.
Referenced by sip_tcp_worker_fn().
02221 { 02222 int res, cl; 02223 struct sip_request req = { 0, } , reqcpy = { 0, }; 02224 struct sip_threadinfo *me; 02225 char buf[1024] = ""; 02226 02227 me = ast_calloc(1, sizeof(*me)); 02228 02229 if (!me) 02230 goto cleanup2; 02231 02232 me->threadid = pthread_self(); 02233 me->tcptls_session = tcptls_session; 02234 if (tcptls_session->ssl) 02235 me->type = SIP_TRANSPORT_TLS; 02236 else 02237 me->type = SIP_TRANSPORT_TCP; 02238 02239 ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP"); 02240 02241 AST_LIST_LOCK(&threadl); 02242 AST_LIST_INSERT_TAIL(&threadl, me, list); 02243 AST_LIST_UNLOCK(&threadl); 02244 02245 02246 for (;;) { 02247 memset(req.data, 0, sizeof(req.data)); 02248 req.len = 0; 02249 req.ignore = 0; 02250 req.debug = 0; 02251 02252 if (tcptls_session->ssl) { 02253 set_socket_transport(&req.socket, SIP_TRANSPORT_TLS); 02254 req.socket.port = htons(ourport_tls); 02255 } else { 02256 set_socket_transport(&req.socket, SIP_TRANSPORT_TCP); 02257 req.socket.port = htons(ourport_tcp); 02258 } 02259 req.socket.fd = tcptls_session->fd; 02260 res = ast_wait_for_input(tcptls_session->fd, -1); 02261 if (res < 0) { 02262 ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res); 02263 goto cleanup; 02264 } 02265 02266 /* Read in headers one line at a time */ 02267 while (req.len < 4 || strncmp((char *)&req.data + req.len - 4, "\r\n\r\n", 4)) { 02268 ast_mutex_lock(&tcptls_session->lock); 02269 if (!fgets(buf, sizeof(buf), tcptls_session->f)) { 02270 ast_mutex_unlock(&tcptls_session->lock); 02271 goto cleanup; 02272 } 02273 ast_mutex_unlock(&tcptls_session->lock); 02274 if (me->stop) 02275 goto cleanup; 02276 strncat(req.data, buf, sizeof(req.data) - req.len - 1); 02277 req.len = strlen(req.data); 02278 } 02279 parse_copy(&reqcpy, &req); 02280 if (sscanf(get_header(&reqcpy, "Content-Length"), "%d", &cl)) { 02281 while (cl > 0) { 02282 ast_mutex_lock(&tcptls_session->lock); 02283 if (!fread(buf, (cl < sizeof(buf)) ? cl : sizeof(buf), 1, tcptls_session->f)) { 02284 ast_mutex_unlock(&tcptls_session->lock); 02285 goto cleanup; 02286 } 02287 ast_mutex_unlock(&tcptls_session->lock); 02288 if (me->stop) 02289 goto cleanup; 02290 cl -= strlen(buf); 02291 strncat(req.data, buf, sizeof(req.data) - req.len - 1); 02292 req.len = strlen(req.data); 02293 } 02294 } 02295 req.socket.tcptls_session = tcptls_session; 02296 handle_request_do(&req, &tcptls_session->requestor); 02297 } 02298 02299 cleanup: 02300 AST_LIST_LOCK(&threadl); 02301 AST_LIST_REMOVE(&threadl, me, list); 02302 AST_LIST_UNLOCK(&threadl); 02303 ast_free(me); 02304 cleanup2: 02305 fclose(tcptls_session->f); 02306 tcptls_session->f = NULL; 02307 tcptls_session->fd = -1; 02308 02309 ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP"); 02310 02311 ao2_ref(tcptls_session, -1); 02312 tcptls_session = NULL; 02313 02314 return NULL; 02315 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
const char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 18398 of file chan_sip.c.
References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_inet_ntoa(), ast_log(), ast_rtp_get_peer(), ast_rtp_get_quality(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), chan, IS_SIP_TECH, LOG_ERROR, LOG_WARNING, parse(), sip_pvt::rtp, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::trtp, type, and sip_pvt::vrtp.
18399 { 18400 struct sip_pvt *p = chan->tech_pvt; 18401 char *all = "", *parse = ast_strdupa(preparse); 18402 int res = 0; 18403 AST_DECLARE_APP_ARGS(args, 18404 AST_APP_ARG(param); 18405 AST_APP_ARG(type); 18406 AST_APP_ARG(field); 18407 ); 18408 AST_STANDARD_APP_ARGS(args, parse); 18409 18410 /* Sanity check */ 18411 if (!IS_SIP_TECH(chan->tech)) { 18412 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 18413 return 0; 18414 } 18415 18416 memset(buf, 0, buflen); 18417 18418 if (p == NULL) { 18419 return -1; 18420 } 18421 18422 if (!strcasecmp(args.param, "rtpdest")) { 18423 struct sockaddr_in sin; 18424 18425 if (ast_strlen_zero(args.type)) 18426 args.type = "audio"; 18427 18428 if (!strcasecmp(args.type, "audio")) 18429 ast_rtp_get_peer(p->rtp, &sin); 18430 else if (!strcasecmp(args.type, "video")) 18431 ast_rtp_get_peer(p->vrtp, &sin); 18432 else if (!strcasecmp(args.type, "text")) 18433 ast_rtp_get_peer(p->trtp, &sin); 18434 18435 snprintf(buf, buflen, "%s:%d", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 18436 } else if (!strcasecmp(args.param, "rtpqos")) { 18437 struct ast_rtp_quality qos; 18438 18439 memset(&qos, 0, sizeof(qos)); 18440 18441 if (ast_strlen_zero(args.type)) 18442 args.type = "audio"; 18443 if (ast_strlen_zero(args.field)) 18444 args.field = "all"; 18445 18446 if (!strcasecmp(args.type, "AUDIO")) { 18447 all = ast_rtp_get_quality(p->rtp, &qos); 18448 } else if (!strcasecmp(args.type, "VIDEO")) { 18449 all = ast_rtp_get_quality(p->vrtp, &qos); 18450 } else if (!strcasecmp(args.type, "TEXT")) { 18451 all = ast_rtp_get_quality(p->trtp, &qos); 18452 } 18453 18454 if (!strcasecmp(args.field, "local_ssrc")) 18455 snprintf(buf, buflen, "%u", qos.local_ssrc); 18456 else if (!strcasecmp(args.field, "local_lostpackets")) 18457 snprintf(buf, buflen, "%u", qos.local_lostpackets); 18458 else if (!strcasecmp(args.field, "local_jitter")) 18459 snprintf(buf, buflen, "%.0f", qos.local_jitter * 1000.0); 18460 else if (!strcasecmp(args.field, "local_count")) 18461 snprintf(buf, buflen, "%u", qos.local_count); 18462 else if (!strcasecmp(args.field, "remote_ssrc")) 18463 snprintf(buf, buflen, "%u", qos.remote_ssrc); 18464 else if (!strcasecmp(args.field, "remote_lostpackets")) 18465 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 18466 else if (!strcasecmp(args.field, "remote_jitter")) 18467 snprintf(buf, buflen, "%.0f", qos.remote_jitter * 1000.0); 18468 else if (!strcasecmp(args.field, "remote_count")) 18469 snprintf(buf, buflen, "%u", qos.remote_count); 18470 else if (!strcasecmp(args.field, "rtt")) 18471 snprintf(buf, buflen, "%.0f", qos.rtt * 1000.0); 18472 else if (!strcasecmp(args.field, "all")) 18473 ast_copy_string(buf, all, buflen); 18474 else { 18475 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 18476 return -1; 18477 } 18478 } else { 18479 res = -1; 18480 } 18481 return res; 18482 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 3206 of file chan_sip.c.
References ast_copy_string(), sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
03207 { 03208 if (!req->lines) { 03209 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 03210 ast_copy_string(req->data + req->len, "\r\n", sizeof(req->data) - req->len); 03211 req->len += strlen(req->data + req->len); 03212 } 03213 }
static void add_codec_to_sdp | ( | const struct sip_pvt * | p, | |
int | codec, | |||
int | sample_rate, | |||
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 8263 of file chan_sip.c.
References ast_codec_pref_getsize(), AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_ILBC, ast_getformatname(), ast_rtp_codec_getpref(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), AST_RTP_OPT_G726_NONSTANDARD, ast_str_append(), ast_test_flag, ast_verbose(), ast_format_list::cur_ms, sip_pvt::flags, sip_pvt::rtp, and SIP_G726_NONSTANDARD.
Referenced by add_sdp().
08266 { 08267 int rtp_code; 08268 struct ast_format_list fmt; 08269 08270 08271 if (debug) 08272 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 08273 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 08274 return; 08275 08276 if (p->rtp) { 08277 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 08278 fmt = ast_codec_pref_getsize(pref, codec); 08279 } else /* I dont see how you couldn't have p->rtp, but good to check for and error out if not there like earlier code */ 08280 return; 08281 ast_str_append(m_buf, 0, " %d", rtp_code); 08282 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code, 08283 ast_rtp_lookup_mime_subtype(1, codec, 08284 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 08285 sample_rate); 08286 if (codec == AST_FORMAT_G729A) { 08287 /* Indicate that we don't support VAD (G.729 annex B) */ 08288 ast_str_append(a_buf, 0, "a=fmtp:%d annexb=no\r\n", rtp_code); 08289 } else if (codec == AST_FORMAT_G723_1) { 08290 /* Indicate that we don't support VAD (G.723.1 annex A) */ 08291 ast_str_append(a_buf, 0, "a=fmtp:%d annexa=no\r\n", rtp_code); 08292 } else if (codec == AST_FORMAT_ILBC) { 08293 /* Add information about us using only 20/30 ms packetization */ 08294 ast_str_append(a_buf, 0, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 08295 } 08296 08297 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 08298 *min_packet_size = fmt.cur_ms; 08299 08300 /* Our first codec packetization processed cannot be zero */ 08301 if ((*min_packet_size)==0 && fmt.cur_ms) 08302 *min_packet_size = fmt.cur_ms; 08303 }
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 8214 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
08215 { 08216 char tmp[256]; 08217 int event; 08218 if (mode) { 08219 /* Application/dtmf short version used by some implementations */ 08220 if (digit == '*') 08221 event = 10; 08222 else if (digit == '#') 08223 event = 11; 08224 else if ((digit >= 'A') && (digit <= 'D')) 08225 event = 12 + digit - 'A'; 08226 else 08227 event = atoi(&digit); 08228 snprintf(tmp, sizeof(tmp), "%d\r\n", event); 08229 add_header(req, "Content-Type", "application/dtmf"); 08230 add_header_contentLength(req, strlen(tmp)); 08231 add_line(req, tmp); 08232 } else { 08233 /* Application/dtmf-relay as documented by Cisco */ 08234 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 08235 add_header(req, "Content-Type", "application/dtmf-relay"); 08236 add_header_contentLength(req, strlen(tmp)); 08237 add_line(req, tmp); 08238 } 08239 return 0; 08240 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 7471 of file chan_sip.c.
References ast_log(), sip_request::data, find_alias(), sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, LOG_WARNING, and SIP_MAX_HEADERS.
07472 { 07473 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 07474 07475 if (req->headers == SIP_MAX_HEADERS) { 07476 ast_log(LOG_WARNING, "Out of SIP header space\n"); 07477 return -1; 07478 } 07479 07480 if (req->lines) { 07481 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 07482 return -1; 07483 } 07484 07485 if (maxlen <= 0) { 07486 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 07487 return -1; 07488 } 07489 07490 req->header[req->headers] = req->data + req->len; 07491 07492 if (compactheaders) 07493 var = find_alias(var, var); 07494 07495 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 07496 req->len += strlen(req->header[req->headers]); 07497 req->headers++; 07498 07499 return 0; 07500 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 7503 of file chan_sip.c.
References add_header().
Referenced by __transmit_response(), add_digit(), add_sdp(), add_text(), add_vidupdate(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_request(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_minse(), transmit_response_with_unsupported(), and transmit_state_notify().
07504 { 07505 char clen[10]; 07506 07507 snprintf(clen, sizeof(clen), "%d", len); 07508 return add_header(req, "Content-Length", clen); 07509 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 7512 of file chan_sip.c.
References ast_copy_string(), ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, LOG_WARNING, and SIP_MAX_LINES.
07513 { 07514 if (req->lines == SIP_MAX_LINES) { 07515 ast_log(LOG_WARNING, "Out of SIP line space\n"); 07516 return -1; 07517 } 07518 if (!req->lines) { 07519 /* Add extra empty return */ 07520 ast_copy_string(req->data + req->len, "\r\n", sizeof(req->data) - req->len); 07521 req->len += strlen(req->data + req->len); 07522 } 07523 if (req->len >= sizeof(req->data) - 4) { 07524 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 07525 return -1; 07526 } 07527 req->line[req->lines] = req->data + req->len; 07528 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 07529 req->len += strlen(req->line[req->lines]); 07530 req->lines++; 07531 return 0; 07532 }
static void add_noncodec_to_sdp | ( | const struct sip_pvt * | p, | |
int | format, | |||
int | sample_rate, | |||
struct ast_str ** | m_buf, | |||
struct ast_str ** | a_buf, | |||
int | debug | |||
) | [static] |
Add RFC 2833 DTMF offer to SDP.
Definition at line 8381 of file chan_sip.c.
References AST_RTP_DTMF, ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), ast_str_append(), ast_verbose(), and sip_pvt::rtp.
Referenced by add_sdp().
08384 { 08385 int rtp_code; 08386 08387 if (debug) 08388 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 08389 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 08390 return; 08391 08392 ast_str_append(m_buf, 0, " %d", rtp_code); 08393 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code, 08394 ast_rtp_lookup_mime_subtype(0, format, 0), 08395 sample_rate); 08396 if (format == AST_RTP_DTMF) /* Indicate we support DTMF and FLASH... */ 08397 ast_str_append(a_buf, 0, "a=fmtp:%d 0-16\r\n", rtp_code); 08398 }
static void add_peer_mailboxes | ( | struct sip_peer * | peer, | |
const char * | value | |||
) | [static] |
Definition at line 21063 of file chan_sip.c.
References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, ast_strdup, ast_strdupa, ast_strlen_zero(), sip_mailbox::entry, mailbox, sip_peer::mailboxes, mbox(), sip_peer::next, and strsep().
Referenced by build_peer().
21064 { 21065 char *next, *mbox, *context; 21066 21067 next = ast_strdupa(value); 21068 21069 while ((mbox = context = strsep(&next, ","))) { 21070 struct sip_mailbox *mailbox; 21071 21072 if (!(mailbox = ast_calloc(1, sizeof(*mailbox)))) 21073 continue; 21074 21075 strsep(&context, "@"); 21076 if (ast_strlen_zero(mbox)) { 21077 ast_free(mailbox); 21078 continue; 21079 } 21080 mailbox->mailbox = ast_strdup(mbox); 21081 mailbox->context = ast_strdup(context); 21082 21083 AST_LIST_INSERT_TAIL(&peer->mailboxes, mailbox, entry); 21084 } 21085 }
static void add_peer_mwi_subs | ( | struct sip_peer * | peer | ) | [static] |
Definition at line 18582 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, sip_mailbox::entry, mailbox, sip_peer::mailboxes, mwi_event_cb(), and S_OR.
Referenced by build_peer(), and handle_request_subscribe().
18583 { 18584 struct sip_mailbox *mailbox; 18585 18586 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 18587 mailbox->event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, peer, 18588 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox, 18589 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"), 18590 AST_EVENT_IE_END); 18591 } 18592 }
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 20733 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_debug, ast_log(), ast_strlen_zero(), ast_verb, LOG_WARNING, sip_auth::next, sip_auth::realm, and strsep().
Referenced by build_peer().
20734 { 20735 char authcopy[256]; 20736 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 20737 char *stringp; 20738 struct sip_auth *a, *b, *auth; 20739 20740 if (ast_strlen_zero(configuration)) 20741 return authlist; 20742 20743 ast_debug(1, "Auth config :: %s\n", configuration); 20744 20745 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 20746 stringp = authcopy; 20747 20748 username = stringp; 20749 realm = strrchr(stringp, '@'); 20750 if (realm) 20751 *realm++ = '\0'; 20752 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 20753 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 20754 return authlist; 20755 } 20756 stringp = username; 20757 username = strsep(&stringp, ":"); 20758 if (username) { 20759 secret = strsep(&stringp, ":"); 20760 if (!secret) { 20761 stringp = username; 20762 md5secret = strsep(&stringp, "#"); 20763 } 20764 } 20765 if (!(auth = ast_calloc(1, sizeof(*auth)))) 20766 return authlist; 20767 20768 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 20769 ast_copy_string(auth->username, username, sizeof(auth->username)); 20770 if (secret) 20771 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 20772 if (md5secret) 20773 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 20774 20775 /* find the end of the list */ 20776 for (b = NULL, a = authlist; a ; b = a, a = a->next) 20777 ; 20778 if (b) 20779 b->next = auth; /* Add structure add end of list */ 20780 else 20781 authlist = auth; 20782 20783 ast_verb(3, "Added authentication for realm %s\n", realm); 20784 20785 return authlist; 20786 20787 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 7635 of file chan_sip.c.
References add_header(), ast_copy_string(), sip_route::hop, sip_route::next, and SIPBUFSIZE.
Referenced by reqprep().
07636 { 07637 char r[SIPBUFSIZE*2], *p; 07638 int n, rem = sizeof(r); 07639 07640 if (!route) 07641 return; 07642 07643 p = r; 07644 for (;route ; route = route->next) { 07645 n = strlen(route->hop); 07646 if (rem < n+3) /* we need room for ",<route>" */ 07647 break; 07648 if (p != r) { /* add a separator after fist route */ 07649 *p++ = ','; 07650 --rem; 07651 } 07652 *p++ = '<'; 07653 ast_copy_string(p, route->hop, rem); /* cannot fail */ 07654 p += n; 07655 *p++ = '>'; 07656 rem -= (n+2); 07657 } 07658 *p = '\0'; 07659 add_header(req, "Route", r); 07660 }
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 8449 of file chan_sip.c.
References add_codec_to_sdp(), add_header(), add_header_contentLength(), add_line(), add_noncodec_to_sdp(), add_tcodec_to_sdp(), add_vcodec_to_sdp(), ast_codec_pref_index(), ast_debug, AST_FAILURE, AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_inet_ntoa(), ast_internal_timing_enabled(), ast_log(), ast_random(), AST_RTP_MAX, ast_str_alloca, ast_str_append(), ast_strlen_zero(), AST_SUCCESS, ast_test_flag, ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), ast_verbose(), buf, t38properties::capability, debug, FALSE, sip_pvt::flags, get_our_media_address(), t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, ast_str::len, len(), LOG_WARNING, sip_pvt::maxcallbitrate, sip_pvt::notext, sip_pvt::novideo, sip_pvt::ourip, sip_pvt::owner, t38properties::peercapability, sip_pvt::prefcodec, sip_pvt::prefs, sip_pvt::rtp, SDP_SAMPLE_RATE, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_T38SUPPORT_RTP, SIPBUFSIZE, ast_str::str, sip_pvt::t38, t38_get_rate(), T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION, T38FAX_VERSION_0, T38FAX_VERSION_1, t38properties::t38support, sip_pvt::tredirip, sip_pvt::trtp, TRUE, sip_pvt::udptl, sip_pvt::udptlredirip, ast_str::used, version, and sip_pvt::vrtp.
08450 { 08451 int len = 0; 08452 int alreadysent = 0; 08453 08454 struct sockaddr_in sin; 08455 struct sockaddr_in vsin; 08456 struct sockaddr_in tsin; 08457 struct sockaddr_in dest; 08458 struct sockaddr_in udptlsin; 08459 struct sockaddr_in vdest = { 0, }; 08460 struct sockaddr_in tdest = { 0, }; 08461 struct sockaddr_in udptldest = { 0, }; 08462 08463 /* SDP fields */ 08464 char *version = "v=0\r\n"; /* Protocol version */ 08465 char subject[256]; /* Subject of the session */ 08466 char owner[256]; /* Session owner/creator */ 08467 char connection[256]; /* Connection data */ 08468 char *stime = "t=0 0\r\n"; /* Time the session is active */ 08469 char bandwidth[256] = ""; /* Max bitrate */ 08470 char *hold = ""; 08471 struct ast_str *m_audio = ast_str_alloca(256); /* Media declaration line for audio */ 08472 struct ast_str *m_video = ast_str_alloca(256); /* Media declaration line for video */ 08473 struct ast_str *m_text = ast_str_alloca(256); /* Media declaration line for text */ 08474 struct ast_str *m_modem = ast_str_alloca(256); /* Media declaration line for modem */ 08475 struct ast_str *a_audio = ast_str_alloca(1024); /* Attributes for audio */ 08476 struct ast_str *a_video = ast_str_alloca(1024); /* Attributes for video */ 08477 struct ast_str *a_text = ast_str_alloca(1024); /* Attributes for text */ 08478 struct ast_str *a_modem = ast_str_alloca(1024); /* Attributes for modem */ 08479 08480 int x; 08481 int capability = 0; 08482 int needaudio = FALSE; 08483 int needvideo = FALSE; 08484 int needtext = FALSE; 08485 int debug = sip_debug_test_pvt(p); 08486 int min_audio_packet_size = 0; 08487 int min_video_packet_size = 0; 08488 int min_text_packet_size = 0; 08489 08490 char codecbuf[SIPBUFSIZE]; 08491 char buf[SIPBUFSIZE]; 08492 08493 /* Set the SDP session name */ 08494 snprintf(subject, sizeof(subject), "s=%s\r\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession); 08495 08496 if (!p->rtp) { 08497 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 08498 return AST_FAILURE; 08499 } 08500 /* XXX We should not change properties in the SIP dialog until 08501 we have acceptance of the offer if this is a re-invite */ 08502 08503 /* Set RTP Session ID and version */ 08504 if (!p->sessionid) { 08505 p->sessionid = (int)ast_random(); 08506 p->sessionversion = p->sessionid; 08507 } else { 08508 if (oldsdp == FALSE) 08509 p->sessionversion++; 08510 } 08511 08512 get_our_media_address(p, needvideo, &sin, &vsin, &tsin, &dest, &vdest); 08513 08514 snprintf(owner, sizeof(owner), "o=%s %d %d IN IP4 %s\r\n", ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner, p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 08515 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 08516 08517 if (add_audio) { 08518 capability = p->jointcapability; 08519 08520 /* XXX note, Video and Text are negated - 'true' means 'no' */ 08521 ast_debug(1, "** Our capability: %s Video flag: %s Text flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability), 08522 p->novideo ? "True" : "False", p->notext ? "True" : "False"); 08523 ast_debug(1, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 08524 08525 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 08526 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 08527 ast_str_append(&m_audio, 0, " %d", 191); 08528 ast_str_append(&a_audio, 0, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 08529 } 08530 #endif 08531 08532 /* Check if we need audio */ 08533 if (capability & AST_FORMAT_AUDIO_MASK) 08534 needaudio = TRUE; 08535 08536 /* Check if we need video in this call */ 08537 if ((capability & AST_FORMAT_VIDEO_MASK) && !p->novideo) { 08538 if (p->vrtp) { 08539 needvideo = TRUE; 08540 ast_debug(2, "This call needs video offers!\n"); 08541 } else 08542 ast_debug(2, "This call needs video offers, but there's no video support enabled!\n"); 08543 } 08544 08545 if (debug) 08546 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(sin.sin_port)); 08547 08548 /* Ok, we need video. Let's add what we need for video and set codecs. 08549 Video is handled differently than audio since we can not transcode. */ 08550 if (needvideo) { 08551 ast_str_append(&m_video, 0, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 08552 08553 /* Build max bitrate string */ 08554 if (p->maxcallbitrate) 08555 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 08556 if (debug) 08557 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(vsin.sin_port)); 08558 } 08559 08560 /* Check if we need text in this call */ 08561 if((capability & AST_FORMAT_TEXT_MASK) && !p->notext) { 08562 if (sipdebug_text) 08563 ast_verbose("We think we can do text\n"); 08564 if (p->trtp) { 08565 if (sipdebug_text) 08566 ast_verbose("And we have a text rtp object\n"); 08567 needtext = TRUE; 08568 ast_debug(2, "This call needs text offers! \n"); 08569 } else 08570 ast_debug(2, "This call needs text offers, but there's no text support enabled ! \n"); 08571 } 08572 08573 /* Ok, we need text. Let's add what we need for text and set codecs. 08574 Text is handled differently than audio since we can not transcode. */ 08575 if (needtext) { 08576 if (sipdebug_text) 08577 ast_verbose("Lets set up the text sdp\n"); 08578 /* Determine text destination */ 08579 if (p->tredirip.sin_addr.s_addr) { 08580 tdest.sin_addr = p->tredirip.sin_addr; 08581 tdest.sin_port = p->tredirip.sin_port; 08582 } else { 08583 tdest.sin_addr = p->ourip.sin_addr; 08584 tdest.sin_port = tsin.sin_port; 08585 } 08586 ast_str_append(&m_text, 0, "m=text %d RTP/AVP", ntohs(tdest.sin_port)); 08587 08588 if (debug) /* XXX should I use tdest below ? */ 08589 ast_verbose("Text is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(tsin.sin_port)); 08590 08591 } 08592 08593 /* Start building generic SDP headers */ 08594 08595 /* We break with the "recommendation" and send our IP, in order that our 08596 peer doesn't have to ast_gethostbyname() us */ 08597 08598 ast_str_append(&m_audio, 0, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 08599 08600 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 08601 hold = "a=recvonly\r\n"; 08602 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 08603 hold = "a=inactive\r\n"; 08604 else 08605 hold = "a=sendrecv\r\n"; 08606 08607 /* Now, start adding audio codecs. These are added in this order: 08608 - First what was requested by the calling channel 08609 - Then preferences in order from sip.conf device config for this peer/user 08610 - Then other codecs in capabilities, including video 08611 */ 08612 08613 /* Prefer the audio codec we were requested to use, first, no matter what 08614 Note that p->prefcodec can include video codecs, so mask them out 08615 */ 08616 if (capability & p->prefcodec) { 08617 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 08618 08619 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 08620 &m_audio, &a_audio, 08621 debug, &min_audio_packet_size); 08622 alreadysent |= codec; 08623 } 08624 08625 /* Start by sending our preferred audio/video codecs */ 08626 for (x = 0; x < 32; x++) { 08627 int codec; 08628 08629 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 08630 break; 08631 08632 if (!(capability & codec)) 08633 continue; 08634 08635 if (alreadysent & codec) 08636 continue; 08637 08638 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 08639 &m_audio, &a_audio, 08640 debug, &min_audio_packet_size); 08641 alreadysent |= codec; 08642 } 08643 08644 /* Now send any other common audio and video codecs, and non-codec formats: */ 08645 for (x = 1; x <= (needtext ? AST_FORMAT_TEXT_MASK : (needvideo ? AST_FORMAT_VIDEO_MASK : AST_FORMAT_AUDIO_MASK)); x <<= 1) { 08646 if (!(capability & x)) /* Codec not requested */ 08647 continue; 08648 08649 if (alreadysent & x) /* Already added to SDP */ 08650 continue; 08651 08652 if (x & AST_FORMAT_AUDIO_MASK) 08653 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 08654 &m_audio, &a_audio, debug, &min_audio_packet_size); 08655 else if (x & AST_FORMAT_VIDEO_MASK) 08656 add_vcodec_to_sdp(p, x, 90000, 08657 &m_video, &a_video, debug, &min_video_packet_size); 08658 else if (x & AST_FORMAT_TEXT_MASK) 08659 add_tcodec_to_sdp(p, x, 1000, 08660 &m_text, &a_text, debug, &min_text_packet_size); 08661 } 08662 08663 /* Now add DTMF RFC2833 telephony-event as a codec */ 08664 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 08665 if (!(p->jointnoncodeccapability & x)) 08666 continue; 08667 08668 add_noncodec_to_sdp(p, x, 8000, &m_audio, &a_audio, debug); 08669 } 08670 08671 ast_debug(3, "-- Done with adding codecs to SDP\n"); 08672 08673 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 08674 ast_str_append(&a_audio, 0, "a=silenceSupp:off - - - -\r\n"); 08675 08676 if (min_audio_packet_size) 08677 ast_str_append(&a_audio, 0, "a=ptime:%d\r\n", min_audio_packet_size); 08678 08679 /* XXX don't think you can have ptime for video */ 08680 if (min_video_packet_size) 08681 ast_str_append(&a_video, 0, "a=ptime:%d\r\n", min_video_packet_size); 08682 08683 /* XXX don't think you can have ptime for text */ 08684 if (min_text_packet_size) 08685 ast_str_append(&a_text, 0, "a=ptime:%d\r\n", min_text_packet_size); 08686 } 08687 08688 if (add_t38) { 08689 ast_udptl_get_us(p->udptl, &udptlsin); 08690 08691 /* Determine T.38 UDPTL destination */ 08692 if (p->udptlredirip.sin_addr.s_addr) { 08693 udptldest.sin_port = p->udptlredirip.sin_port; 08694 udptldest.sin_addr = p->udptlredirip.sin_addr; 08695 } else { 08696 udptldest.sin_addr = p->ourip.sin_addr; 08697 udptldest.sin_port = udptlsin.sin_port; 08698 } 08699 08700 if (debug) 08701 ast_debug(1, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(udptlsin.sin_port)); 08702 08703 /* We break with the "recommendation" and send our IP, in order that our 08704 peer doesn't have to ast_gethostbyname() us */ 08705 08706 if (debug) { 08707 ast_debug(1, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 08708 p->t38.capability, 08709 p->t38.peercapability, 08710 p->t38.jointcapability); 08711 } 08712 08713 ast_str_append(&m_modem, 0, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 08714 08715 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 08716 ast_str_append(&a_modem, 0, "a=T38FaxVersion:0\r\n"); 08717 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 08718 ast_str_append(&a_modem, 0, "a=T38FaxVersion:1\r\n"); 08719 if ((x = t38_get_rate(p->t38.jointcapability))) 08720 ast_str_append(&a_modem, 0, "a=T38MaxBitRate:%d\r\n", x); 08721 if ((p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) == T38FAX_FILL_BIT_REMOVAL) 08722 ast_str_append(&a_modem, 0, "a=T38FaxFillBitRemoval\r\n"); 08723 if ((p->t38.jointcapability & T38FAX_TRANSCODING_MMR) == T38FAX_TRANSCODING_MMR) 08724 ast_str_append(&a_modem, 0, "a=T38FaxTranscodingMMR\r\n"); 08725 if ((p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) == T38FAX_TRANSCODING_JBIG) 08726 ast_str_append(&a_modem, 0, "a=T38FaxTranscodingJBIG\r\n"); 08727 ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 08728 x = ast_udptl_get_local_max_datagram(p->udptl); 08729 ast_str_append(&a_modem, 0, "a=T38FaxMaxBuffer:%d\r\n", x); 08730 ast_str_append(&a_modem, 0, "a=T38FaxMaxDatagram:%d\r\n", x); 08731 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 08732 ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 08733 } 08734 08735 if (m_audio->len - m_audio->used < 2 || m_video->len - m_video->used < 2 || 08736 m_text->len - m_text->used < 2 || a_text->len - a_text->used < 2 || 08737 a_audio->len - a_audio->used < 2 || a_video->len - a_video->used < 2) 08738 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 08739 08740 if (needaudio) 08741 ast_str_append(&m_audio, 0, "\r\n"); 08742 if (needvideo) 08743 ast_str_append(&m_video, 0, "\r\n"); 08744 if (needtext) 08745 ast_str_append(&m_text, 0, "\r\n"); 08746 08747 len = strlen(version) + strlen(subject) + strlen(owner) + 08748 strlen(connection) + strlen(stime); 08749 if (needaudio) 08750 len += m_audio->used + a_audio->used + strlen(hold); 08751 if (needvideo) /* only if video response is appropriate */ 08752 len += m_video->used + a_video->used + strlen(bandwidth) + strlen(hold); 08753 if (needtext) /* only if text response is appropriate */ 08754 len += m_text->used + a_text->used + strlen(hold); 08755 if (add_t38) 08756 len += m_modem->used + a_modem->used; 08757 08758 add_header(resp, "Content-Type", "application/sdp"); 08759 add_header_contentLength(resp, len); 08760 add_line(resp, version); 08761 add_line(resp, owner); 08762 add_line(resp, subject); 08763 add_line(resp, connection); 08764 if (needvideo) /* only if video response is appropriate */ 08765 add_line(resp, bandwidth); 08766 add_line(resp, stime); 08767 if (needaudio) { 08768 add_line(resp, m_audio->str); 08769 add_line(resp, a_audio->str); 08770 add_line(resp, hold); 08771 } 08772 if (needvideo) { /* only if video response is appropriate */ 08773 add_line(resp, m_video->str); 08774 add_line(resp, a_video->str); 08775 add_line(resp, hold); /* Repeat hold for the video stream */ 08776 } 08777 if (needtext) { /* only if text response is appropriate */ 08778 add_line(resp, m_text->str); 08779 add_line(resp, a_text->str); 08780 add_line(resp, hold); /* Repeat hold for the text stream */ 08781 } 08782 if (add_t38) { 08783 add_line(resp, m_modem->str); 08784 add_line(resp, a_modem->str); 08785 } 08786 08787 /* Update lastrtprx when we send our SDP */ 08788 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 08789 08790 ast_debug(3, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 08791 08792 return AST_SUCCESS; 08793 }
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 20669 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), domain::list, and LOG_WARNING.
20670 { 20671 struct domain *d; 20672 20673 if (ast_strlen_zero(domain)) { 20674 ast_log(LOG_WARNING, "Zero length domain.\n"); 20675 return 1; 20676 } 20677 20678 if (!(d = ast_calloc(1, sizeof(*d)))) 20679 return 0; 20680 20681 ast_copy_string(d->domain, domain, sizeof(d->domain)); 20682 20683 if (!ast_strlen_zero(context)) 20684 ast_copy_string(d->context, context, sizeof(d->context)); 20685 20686 d->mode = mode; 20687 20688 AST_LIST_LOCK(&domain_list); 20689 AST_LIST_INSERT_TAIL(&domain_list, d, list); 20690 AST_LIST_UNLOCK(&domain_list); 20691 20692 if (sipdebug) 20693 ast_debug(1, "Added local SIP domain '%s'\n", domain); 20694 20695 return 1; 20696 }
static void add_tcodec_to_sdp | ( | const struct sip_pvt * | p, | |
int | codec, | |||
int | sample_rate, | |||
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 8329 of file chan_sip.c.
References ast_getformatname(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), ast_str_append(), ast_verbose(), and sip_pvt::trtp.
Referenced by add_sdp().
08332 { 08333 int rtp_code; 08334 08335 if (!p->trtp) 08336 return; 08337 08338 if (debug) 08339 ast_verbose("Adding text codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 08340 08341 if ((rtp_code = ast_rtp_lookup_code(p->trtp, 1, codec)) == -1) 08342 return; 08343 08344 ast_str_append(m_buf, 0, " %d", rtp_code); 08345 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code, 08346 ast_rtp_lookup_mime_subtype(1, codec, 0), sample_rate); 08347 /* Add fmtp code here */ 08348 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 8201 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
08202 { 08203 /* XXX Convert \n's to \r\n's XXX */ 08204 add_header(req, "Content-Type", "text/plain"); 08205 add_header_contentLength(req, strlen(text)); 08206 add_line(req, text); 08207 return 0; 08208 }
static struct ast_variable* add_var | ( | const char * | buf, | |
struct ast_variable * | list | |||
) | [static] |
implement the setvar config line
Definition at line 20820 of file chan_sip.c.
References ast_strdupa, ast_variable_new(), and ast_variable::next.
Referenced by build_device(), build_peer(), and build_user().
20821 { 20822 struct ast_variable *tmpvar = NULL; 20823 char *varname = ast_strdupa(buf), *varval = NULL; 20824 20825 if ((varval = strchr(varname, '='))) { 20826 *varval++ = '\0'; 20827 if ((tmpvar = ast_variable_new(varname, varval, ""))) { 20828 tmpvar->next = list; 20829 list = tmpvar; 20830 } 20831 } 20832 return list; 20833 }
static void add_vcodec_to_sdp | ( | const struct sip_pvt * | p, | |
int | codec, | |||
int | sample_rate, | |||
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 8307 of file chan_sip.c.
References ast_getformatname(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), ast_str_append(), ast_verbose(), and sip_pvt::vrtp.
Referenced by add_sdp().
08310 { 08311 int rtp_code; 08312 08313 if (!p->vrtp) 08314 return; 08315 08316 if (debug) 08317 ast_verbose("Adding video codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 08318 08319 if ((rtp_code = ast_rtp_lookup_code(p->vrtp, 1, codec)) == -1) 08320 return; 08321 08322 ast_str_append(m_buf, 0, " %d", rtp_code); 08323 ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code, 08324 ast_rtp_lookup_mime_subtype(1, codec, 0), sample_rate); 08325 /* Add fmtp code here */ 08326 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 8244 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
08245 { 08246 const char *xml_is_a_huge_waste_of_space = 08247 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 08248 " <media_control>\r\n" 08249 " <vc_primitive>\r\n" 08250 " <to_encoder>\r\n" 08251 " <picture_fast_update>\r\n" 08252 " </picture_fast_update>\r\n" 08253 " </to_encoder>\r\n" 08254 " </vc_primitive>\r\n" 08255 " </media_control>\r\n"; 08256 add_header(req, "Content-Type", "application/media_control+xml"); 08257 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 08258 add_line(req, xml_is_a_huge_waste_of_space); 08259 return 0; 08260 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 8148 of file chan_sip.c.
References add_header().
Referenced by build_csv_record(), transmit_invite(), transmit_response_with_date(), transmit_response_with_minse(), and transmit_response_with_unsupported().
08149 { 08150 char tmpdat[256]; 08151 struct tm tm; 08152 time_t t = time(NULL); 08153 08154 gmtime_r(&t, &tm); 08155 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 08156 add_header(req, "Date", tmpdat); 08157 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 2797 of file chan_sip.c.
References append_history_va(), and sip_pvt::do_history.
02798 { 02799 va_list ap; 02800 02801 if (!p) 02802 return; 02803 02804 if (!p->do_history && !recordhistory && !dumphistory) 02805 return; 02806 02807 va_start(ap, fmt); 02808 append_history_va(p, fmt, ap); 02809 va_end(ap); 02810 02811 return; 02812 }
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 2770 of file chan_sip.c.
References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, buf, sip_history::list, MAX_HISTORY_ENTRIES, and strsep().
Referenced by append_history_full().
02771 { 02772 char buf[80], *c = buf; /* max history length */ 02773 struct sip_history *hist; 02774 int l; 02775 02776 vsnprintf(buf, sizeof(buf), fmt, ap); 02777 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 02778 l = strlen(buf) + 1; 02779 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 02780 return; 02781 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 02782 ast_free(hist); 02783 return; 02784 } 02785 memcpy(hist->event, buf, l); 02786 if (p->history_entries == MAX_HISTORY_ENTRIES) { 02787 struct sip_history *oldest; 02788 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 02789 p->history_entries--; 02790 ast_free(oldest); 02791 } 02792 AST_LIST_INSERT_TAIL(p->history, hist, list); 02793 p->history_entries++; 02794 }
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 16495 of file chan_sip.c.
References ast_channel::_state, ast_deactivate_generator(), AST_FLAG_MOH, ast_moh_stop(), AST_STATE_UP, ast_test_flag, and chan.
Referenced by attempt_transfer(), and handle_invite_replaces().
16496 { 16497 if (chan && chan->_state == AST_STATE_UP) { 16498 if (ast_test_flag(chan, AST_FLAG_MOH)) 16499 ast_moh_stop(chan); 16500 else if (chan->generatordata) 16501 ast_deactivate_generator(chan); 16502 } 16503 }
static void ast_sip_ouraddrfor | ( | struct in_addr * | them, | |
struct sockaddr_in * | 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 externip or can get away with our internal bindaddr 'us' is always overwritten.
Definition at line 2695 of file chan_sip.c.
References ast_apply_ha(), ast_debug, ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), ast_parse_arg(), AST_SENSE_ALLOW, ast_stun_request(), bindaddr, externexpire, externhost, externip, externrefresh, get_transport(), internip, localaddr, LOG_NOTICE, LOG_WARNING, PARSE_INADDR, server_args::sin, sip_tcp_desc, sip_tls_desc, SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, sipsock, sip_pvt::socket, stunaddr, and sip_socket::type.
Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_register(), and transmit_response_using_temp().
02696 { 02697 struct sockaddr_in theirs; 02698 /* Set want_remap to non-zero if we want to remap 'us' to an externally 02699 * reachable IP address and port. This is done if: 02700 * 1. we have a localaddr list (containing 'internal' addresses marked 02701 * as 'deny', so ast_apply_ha() will return AST_SENSE_DENY on them, 02702 * and AST_SENSE_ALLOW on 'external' ones); 02703 * 2. either stunaddr or externip is set, so we know what to use as the 02704 * externally visible address; 02705 * 3. the remote address, 'them', is external; 02706 * 4. the address returned by ast_ouraddrfor() is 'internal' (AST_SENSE_DENY 02707 * when passed to ast_apply_ha() so it does need to be remapped. 02708 * This fourth condition is checked later. 02709 */ 02710 int want_remap; 02711 02712 *us = internip; /* starting guess for the internal address */ 02713 /* now ask the system what would it use to talk to 'them' */ 02714 ast_ouraddrfor(them, &us->sin_addr); 02715 theirs.sin_addr = *them; 02716 02717 want_remap = localaddr && 02718 (externip.sin_addr.s_addr || stunaddr.sin_addr.s_addr) && 02719 ast_apply_ha(localaddr, &theirs) == AST_SENSE_ALLOW ; 02720 02721 if (want_remap && 02722 (!global_matchexterniplocally || !ast_apply_ha(localaddr, us)) ) { 02723 /* if we used externhost or stun, see if it is time to refresh the info */ 02724 if (externexpire && time(NULL) >= externexpire) { 02725 if (stunaddr.sin_addr.s_addr) { 02726 ast_stun_request(sipsock, &stunaddr, NULL, &externip); 02727 } else { 02728 if (ast_parse_arg(externhost, PARSE_INADDR, &externip)) 02729 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 02730 } 02731 externexpire = time(NULL) + externrefresh; 02732 } 02733 if (externip.sin_addr.s_addr) 02734 *us = externip; 02735 else 02736 ast_log(LOG_WARNING, "stun failed\n"); 02737 ast_debug(1, "Target address %s is not local, substituting externip\n", 02738 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 02739 } else if (p) { 02740 /* no remapping, but we bind to a specific address, so use it. */ 02741 switch (p->socket.type) { 02742 case SIP_TRANSPORT_TCP: 02743 if (sip_tcp_desc.sin.sin_addr.s_addr) { 02744 *us = sip_tcp_desc.sin; 02745 } else { 02746 us->sin_port = sip_tcp_desc.sin.sin_port; 02747 } 02748 break; 02749 case SIP_TRANSPORT_TLS: 02750 if (sip_tls_desc.sin.sin_addr.s_addr) { 02751 *us = sip_tls_desc.sin; 02752 } else { 02753 us->sin_port = sip_tls_desc.sin.sin_port; 02754 } 02755 break; 02756 case SIP_TRANSPORT_UDP: 02757 /* fall through on purpose */ 02758 default: 02759 if (bindaddr.sin_addr.s_addr) { 02760 *us = bindaddr; 02761 } 02762 } 02763 } else if (bindaddr.sin_addr.s_addr) { 02764 *us = bindaddr; 02765 } 02766 ast_debug(3, "Setting SIP_TRANSPORT_%s with address %s:%d\n", get_transport(p->socket.type), ast_inet_ntoa(us->sin_addr), ntohs(us->sin_port)); 02767 }
Attempt transfer of SIP call This fix for attended transfers on a local PBX.
Definition at line 16507 of file chan_sip.c.
References ast_channel::_state, ast_channel_masquerade(), ast_debug, ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_state2str(), sip_dual::chan1, sip_dual::chan2, LOG_NOTICE, LOG_WARNING, and ast_channel::name.
16508 { 16509 int res = 0; 16510 struct ast_channel *peera = NULL, 16511 *peerb = NULL, 16512 *peerc = NULL, 16513 *peerd = NULL; 16514 16515 16516 /* We will try to connect the transferee with the target and hangup 16517 all channels to the transferer */ 16518 ast_debug(4, "Sip transfer:--------------------\n"); 16519 if (transferer->chan1) 16520 ast_debug(4, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 16521 else 16522 ast_debug(4, "-- No transferer first channel - odd??? \n"); 16523 if (target->chan1) 16524 ast_debug(4, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 16525 else 16526 ast_debug(4, "-- No target first channel ---\n"); 16527 if (transferer->chan2) 16528 ast_debug(4, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 16529 else 16530 ast_debug(4, "-- No bridged call to transferee\n"); 16531 if (target->chan2) 16532 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)"); 16533 else 16534 ast_debug(4, "-- No target second channel ---\n"); 16535 ast_debug(4, "-- END Sip transfer:--------------------\n"); 16536 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 16537 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 16538 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 16539 peerc = transferer->chan2; /* Asterisk to Transferee */ 16540 peerd = target->chan2; /* Asterisk to Target */ 16541 ast_debug(3, "SIP transfer: Four channels to handle\n"); 16542 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 16543 peera = target->chan1; /* Transferer to PBX -> target channel */ 16544 peerb = transferer->chan1; /* Transferer to IVR*/ 16545 peerc = target->chan2; /* Asterisk to Target */ 16546 peerd = transferer->chan2; /* Nothing */ 16547 ast_debug(3, "SIP transfer: Three channels to handle\n"); 16548 } 16549 16550 if (peera && peerb && peerc && (peerb != peerc)) { 16551 ast_quiet_chan(peera); /* Stop generators */ 16552 ast_quiet_chan(peerb); 16553 ast_quiet_chan(peerc); 16554 if (peerd) 16555 ast_quiet_chan(peerd); 16556 16557 ast_debug(4, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 16558 if (ast_channel_masquerade(peerb, peerc)) { 16559 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 16560 res = -1; 16561 } else 16562 ast_debug(4, "SIP transfer: Succeeded to masquerade channels.\n"); 16563 return res; 16564 } else { 16565 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 16566 if (transferer->chan1) 16567 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 16568 if (target->chan1) 16569 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 16570 return -1; 16571 } 16572 return 0; 16573 }
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 10069 of file chan_sip.c.
References ast_verbose(), PROXY_AUTH, and WWW_AUTH.
Referenced by check_auth(), do_proxy_auth(), do_register_auth(), and transmit_request_with_auth().
10070 { 10071 if (code == WWW_AUTH) { /* 401 */ 10072 *header = "WWW-Authenticate"; 10073 *respheader = "Authorization"; 10074 } else if (code == PROXY_AUTH) { /* 407 */ 10075 *header = "Proxy-Authenticate"; 10076 *respheader = "Proxy-Authorization"; 10077 } else { 10078 ast_verbose("-- wrong response code %d\n", code); 10079 *header = *respheader = "Invalid"; 10080 } 10081 }
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 4330 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_CONGESTION, ast_log(), ast_queue_control(), dialog_unref(), LOG_NOTICE, sip_pvt_lock, and sip_pvt_unlock.
04331 { 04332 struct sip_pvt *p = (struct sip_pvt *)arg; 04333 04334 sip_pvt_lock(p); 04335 p->initid = -1; /* event gone, will not be rescheduled */ 04336 if (p->owner) { 04337 /* XXX fails on possible deadlock */ 04338 if (!ast_channel_trylock(p->owner)) { 04339 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 04340 append_history(p, "Cong", "Auto-congesting (timer)"); 04341 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 04342 ast_channel_unlock(p->owner); 04343 } 04344 } 04345 sip_pvt_unlock(p); 04346 dialog_unref(p); 04347 return 0; 04348 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 5979 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, buf, sip_pvt::callid, sip_pvt::fromdomain, generate_random_string(), sip_pvt::ourip, and S_OR.
Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), and sip_send_mwi_to_peer().
05980 { 05981 char buf[33]; 05982 05983 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip.sin_addr)); 05984 05985 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 05986 05987 }
static void build_callid_registry | ( | struct sip_registry * | reg, | |
struct in_addr | ourip, | |||
const char * | fromdomain | |||
) | [static] |
Build SIP Call-ID value for a REGISTER transaction.
Definition at line 5990 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, buf, sip_pvt::callid, generate_random_string(), and S_OR.
Referenced by transmit_register().
05991 { 05992 char buf[33]; 05993 05994 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 05995 05996 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 05997 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 8976 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), sip_pvt::exten, get_transport(), sip_pvt::ourip, ourport, sip_standard_port(), SIP_TRANSPORT_UDP, sip_pvt::socket, and sip_socket::type.
Referenced by check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().
08977 { 08978 int ourport = ntohs(p->ourip.sin_port); 08979 /* only add port if it's non-standard for the transport type */ 08980 if (!sip_standard_port(p->socket.type, ourport)) { 08981 if (p->socket.type == SIP_TRANSPORT_UDP) 08982 ast_string_field_build(p, our_contact, "<sip:%s%s%s:%d>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip.sin_addr), ourport); 08983 else 08984 ast_string_field_build(p, our_contact, "<sip:%s%s%s:%d;transport=%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip.sin_addr), ourport, get_transport(p->socket.type)); 08985 } else { 08986 if (p->socket.type == SIP_TRANSPORT_UDP) 08987 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip.sin_addr)); 08988 else 08989 ast_string_field_build(p, our_contact, "<sip:%s%s%s;transport=%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip.sin_addr), get_transport(p->socket.type)); 08990 } 08991 }
static struct sip_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static] |
Build peer from configuration (file or realtime static/dynamic).
< The first transport listed should be default outbound
Definition at line 21088 of file chan_sip.c.
References __set_address_from_contact(), sip_peer::accountcode, add_peer_mailboxes(), add_peer_mwi_subs(), add_realm_authentication(), add_var(), sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, asprintf, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_copy_flags, ast_copy_string(), ast_debug, ast_free, ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), ast_get_time_t(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), AST_SCHED_DEL, ast_set2_flag, ast_skip_blanks(), ast_str_alloca, ast_str_append(), ast_str_reset(), ast_str_set(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_FLAG_MARKED, ASTOBJ_INIT, ASTOBJ_REF, ASTOBJ_UNMARK, sip_peer::auth, sip_peer::autoframing, sip_peer::busy_level, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, clear_realm_authentication(), sip_peer::contactha, sip_peer::context, sip_peer::defaddr, DEFAULT_MAXMS, sip_peer::default_outbound_transport, sip_peer::deprecated_username, destroy_association(), errno, sip_peer::expire, FALSE, ast_flags::flags, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_contact_ha, global_flags, sip_peer::ha, handle_common_options(), sip_peer::host_dynamic, sip_settings::ignore_regexpire, inet_aton(), sip_peer::is_realtime, sip_peer::language, sip_peer::lastms, sip_peer::lastmsgssent, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_peer::mailboxes, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, sip_peer::name, ast_variable::next, sip_peer::objflags, sip_peer::outboundproxy, peerl, sip_peer::pickupgroup, sip_socket::port, sip_peer::prefs, proxy_allocate(), sip_peer::qualifyfreq, reg_source_db(), sip_peer::regexten, sip_peer::rt_fromcontact, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sched, sip_peer::secret, set_peer_defaults(), set_socket_transport(), sip_cfg, SIP_NAT_ROUTE, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_REGISTERTRYING, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_SUBSCRIBEMWIONLY, sip_poke_peer(), sip_register(), sip_send_mwi_to_peer(), SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, SIP_USEREQPHONE, sip_peer::socket, srvlookup, sip_st_cfg::st_max_se, sip_st_cfg::st_min_se, sip_st_cfg::st_mode_oper, sip_st_cfg::st_ref, STANDARD_SIP_PORT, STANDARD_TLS_PORT, sip_peer::stimer, ast_str::str, str2stmode(), str2strefresher(), strsep(), sip_peer::subscribecontext, sip_peer::timer_b, sip_peer::timer_t1, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, sip_peer::transports, TRUE, sip_socket::type, unref_peer(), ast_str::used, sip_peer::username, ast_variable::value, and sip_peer::vmexten.
21089 { 21090 struct sip_peer *peer = NULL; 21091 struct ast_ha *oldha = NULL; 21092 int found = 0; 21093 int firstpass = 1; 21094 int format = 0; /* Ama flags */ 21095 time_t regseconds = 0; 21096 struct ast_flags peerflags[2] = {{(0)}}; 21097 struct ast_flags mask[2] = {{(0)}}; 21098 char callback[256] = ""; 21099 const char *srvlookup = NULL; 21100 static int deprecation_warning = 1; 21101 int alt_fullcontact = alt ? 1 : 0; 21102 struct ast_str *fullcontact = ast_str_alloca(512); 21103 21104 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 21105 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 21106 /* We also use a case-sensitive comparison (unlike find_peer) so 21107 that case changes made to the peer name will be properly handled 21108 during reload 21109 */ 21110 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 21111 } 21112 21113 if (peer) { 21114 /* Already in the list, remove it and it will be added back (or FREE'd) */ 21115 found++; 21116 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 21117 firstpass = 0; 21118 } else { 21119 if (!(peer = ast_calloc(1, sizeof(*peer)))) 21120 return NULL; 21121 21122 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 21123 rpeerobjs++; 21124 ast_debug(3, "-REALTIME- peer built. Name: %s. Peer objects: %d\n", name, rpeerobjs); 21125 } else 21126 speerobjs++; 21127 ASTOBJ_INIT(peer); 21128 } 21129 /* Note that our peer HAS had its reference count incrased */ 21130 if (firstpass) { 21131 peer->lastmsgssent = -1; 21132 oldha = peer->ha; 21133 peer->ha = NULL; 21134 set_peer_defaults(peer); /* Set peer defaults */ 21135 } 21136 if (!found && name) 21137 ast_copy_string(peer->name, name, sizeof(peer->name)); 21138 21139 /* If we have channel variables, remove them (reload) */ 21140 if (peer->chanvars) { 21141 ast_variables_destroy(peer->chanvars); 21142 peer->chanvars = NULL; 21143 /* XXX should unregister ? */ 21144 } 21145 21146 /* If we have realm authentication information, remove them (reload) */ 21147 clear_realm_authentication(peer->auth); 21148 peer->auth = NULL; 21149 peer->default_outbound_transport = 0; 21150 peer->transports = 0; 21151 21152 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 21153 if (handle_common_options(&peerflags[0], &mask[0], v)) 21154 continue; 21155 if (!strcasecmp(v->name, "transport") && !ast_strlen_zero(v->value)) { 21156 char *val = ast_strdupa(v->value); 21157 char *trans; 21158 21159 while ((trans = strsep(&val, ","))) { 21160 trans = ast_skip_blanks(trans); 21161 21162 if (!strncasecmp(trans, "udp", 3)) 21163 peer->transports |= SIP_TRANSPORT_UDP; 21164 else if (!strncasecmp(trans, "tcp", 3)) 21165 peer->transports |= SIP_TRANSPORT_TCP; 21166 else if (!strncasecmp(trans, "tls", 3)) 21167 peer->transports |= SIP_TRANSPORT_TLS; 21168 else 21169 ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, udp will be used.\n", trans); 21170 21171 if (!peer->default_outbound_transport) { /*!< The first transport listed should be default outbound */ 21172 peer->default_outbound_transport = peer->transports; 21173 } 21174 } 21175 } else if (realtime && !strcasecmp(v->name, "regseconds")) { 21176 ast_get_time_t(v->value, ®seconds, 0, NULL); 21177 } else if (realtime && !strcasecmp(v->name, "lastms")) { 21178 sscanf(v->value, "%d", &peer->lastms); 21179 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 21180 inet_aton(v->value, &(peer->addr.sin_addr)); 21181 } else if (realtime && !strcasecmp(v->name, "name")) 21182 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 21183 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 21184 if (alt_fullcontact && !alt) { 21185 /* Reset, because the alternate also has a fullcontact and we 21186 * do NOT want the field value to be doubled. It might be 21187 * tempting to skip this, but the first table might not have 21188 * fullcontact and since we're here, we know that the alternate 21189 * absolutely does. */ 21190 alt_fullcontact = 0; 21191 ast_str_reset(fullcontact); 21192 } 21193 /* Reconstruct field, because realtime separates our value at the ';' */ 21194 if (fullcontact->used > 0) { 21195 ast_str_append(&fullcontact, 0, ";%s", v->value); 21196 } else { 21197 ast_str_set(&fullcontact, 0, "%s", v->value); 21198 } 21199 } else if (!strcasecmp(v->name, "secret")) 21200 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 21201 else if (!strcasecmp(v->name, "md5secret")) 21202 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 21203 else if (!strcasecmp(v->name, "auth")) 21204 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 21205 else if (!strcasecmp(v->name, "callerid")) { 21206 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 21207 } else if (!strcasecmp(v->name, "fullname")) { 21208 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 21209 } else if (!strcasecmp(v->name, "cid_number")) { 21210 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 21211 } else if (!strcasecmp(v->name, "context")) { 21212 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 21213 } else if (!strcasecmp(v->name, "subscribecontext")) { 21214 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 21215 } else if (!strcasecmp(v->name, "fromdomain")) { 21216 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 21217 } else if (!strcasecmp(v->name, "usereqphone")) { 21218 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 21219 } else if (!strcasecmp(v->name, "fromuser")) { 21220 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 21221 } else if (!strcasecmp(v->name, "outboundproxy")) { 21222 char *port, *next, *force, *proxyname; 21223 int forceopt = FALSE; 21224 /* Set peer channel variable */ 21225 next = proxyname = ast_strdupa(v->value); 21226 if ((port = strchr(proxyname, ':'))) { 21227 *port++ = '\0'; 21228 next = port; 21229 } 21230 if ((force = strchr(next, ','))) { 21231 *force++ = '\0'; 21232 forceopt = strcmp(force, "force"); 21233 } 21234 /* Allocate proxy object */ 21235 peer->outboundproxy = proxy_allocate(proxyname, port, forceopt); 21236 } else if (!strcasecmp(v->name, "host")) { 21237 if (!strcasecmp(v->value, "dynamic")) { 21238 /* They'll register with us */ 21239 if (!found || !peer->host_dynamic) { 21240 /* Initialize stuff if this is a new peer, or if it used to 21241 * not be dynamic before the reload. */ 21242 memset(&peer->addr.sin_addr, 0, 4); 21243 if (peer->addr.sin_port) { 21244 /* If we've already got a port, make it the default rather than absolute */ 21245 peer->defaddr.sin_port = peer->addr.sin_port; 21246 peer->addr.sin_port = 0; 21247 } 21248 } 21249 peer->host_dynamic = TRUE; 21250 } else { 21251 /* Non-dynamic. Make sure we become that way if we're not */ 21252 AST_SCHED_DEL(sched, peer->expire); 21253 peer->host_dynamic = FALSE; 21254 srvlookup = v->value; 21255 if (global_dynamic_exclude_static) { 21256 int err = 0; 21257 global_contact_ha = ast_append_ha("deny", (char *)ast_inet_ntoa(peer->addr.sin_addr), global_contact_ha, &err); 21258 if (err) { 21259 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 21260 } 21261 } 21262 } 21263 } else if (!strcasecmp(v->name, "defaultip")) { 21264 if (ast_get_ip(&peer->defaddr, v->value)) { 21265 unref_peer(peer); 21266 return NULL; 21267 } 21268 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 21269 int ha_error = 0; 21270 21271 peer->ha = ast_append_ha(v->name, v->value, peer->ha, &ha_error); 21272 if (ha_error) 21273 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 21274 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 21275 int ha_error = 0; 21276 peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha, &ha_error); 21277 if (ha_error) { 21278 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 21279 } 21280 } else if (!strcasecmp(v->name, "port")) { 21281 if (!realtime && peer->host_dynamic) 21282 peer->defaddr.sin_port = htons(atoi(v->value)); 21283 else 21284 peer->addr.sin_port = htons(atoi(v->value)); 21285 } else if (!strcasecmp(v->name, "callingpres")) { 21286 peer->callingpres = ast_parse_caller_presentation(v->value); 21287 if (peer->callingpres == -1) 21288 peer->callingpres = atoi(v->value); 21289 } else if (!strcasecmp(v->name, "username") || !strcmp(v->name, "defaultuser")) { /* "username" is deprecated */ 21290 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 21291 if (!strcasecmp(v->name, "username")) { 21292 if (deprecation_warning) { 21293 ast_log(LOG_NOTICE, "The 'username' field for sip peers has been deprecated in favor of the term 'defaultuser'\n"); 21294 deprecation_warning = 0; 21295 } 21296 peer->deprecated_username = 1; 21297 } 21298 } else if (!strcasecmp(v->name, "language")) { 21299 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 21300 } else if (!strcasecmp(v->name, "regexten")) { 21301 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 21302 } else if (!strcasecmp(v->name, "callbackextension")) { 21303 ast_copy_string(callback, v->value, sizeof(callback)); 21304 } else if (!strcasecmp(v->name, "callcounter")) { 21305 peer->call_limit = ast_true(v->value) ? 999 : 0; 21306 } else if (!strcasecmp(v->name, "call-limit")) { 21307 peer->call_limit = atoi(v->value); 21308 if (peer->call_limit < 0) 21309 peer->call_limit = 0; 21310 } else if (!strcasecmp(v->name, "busylevel")) { 21311 peer->busy_level = atoi(v->value); 21312 if (peer->busy_level < 0) 21313 peer->busy_level = 0; 21314 } else if (!strcasecmp(v->name, "amaflags")) { 21315 format = ast_cdr_amaflags2int(v->value); 21316 if (format < 0) { 21317 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 21318 } else { 21319 peer->amaflags = format; 21320 } 21321 } else if (!strcasecmp(v->name, "accountcode")) { 21322 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 21323 } else if (!strcasecmp(v->name, "mohinterpret")) { 21324 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 21325 } else if (!strcasecmp(v->name, "mohsuggest")) { 21326 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 21327 } else if (!strcasecmp(v->name, "mailbox")) { 21328 add_peer_mailboxes(peer, v->value); 21329 } else if (!strcasecmp(v->name, "hasvoicemail")) { 21330 /* People expect that if 'hasvoicemail' is set, that the mailbox will 21331 * be also set, even if not explicitly specified. */ 21332 if (ast_true(v->value) && AST_LIST_EMPTY(&peer->mailboxes)) { 21333 add_peer_mailboxes(peer, name); 21334 } 21335 } else if (!strcasecmp(v->name, "subscribemwi")) { 21336 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 21337 } else if (!strcasecmp(v->name, "vmexten")) { 21338 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 21339 } else if (!strcasecmp(v->name, "callgroup")) { 21340 peer->callgroup = ast_get_group(v->value); 21341 } else if (!strcasecmp(v->name, "allowtransfer")) { 21342 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 21343 } else if (!strcasecmp(v->name, "pickupgroup")) { 21344 peer->pickupgroup = ast_get_group(v->value); 21345 } else if (!strcasecmp(v->name, "allow")) { 21346 int error = ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, TRUE); 21347 if (error) 21348 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 21349 } else if (!strcasecmp(v->name, "disallow")) { 21350 int error = ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, FALSE); 21351 if (error) 21352 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 21353 } else if (!strcasecmp(v->name, "registertrying")) { 21354 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_REGISTERTRYING); 21355 } else if (!strcasecmp(v->name, "autoframing")) { 21356 peer->autoframing = ast_true(v->value); 21357 } else if (!strcasecmp(v->name, "rtptimeout")) { 21358 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 21359 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 21360 peer->rtptimeout = global_rtptimeout; 21361 } 21362 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 21363 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 21364 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 21365 peer->rtpholdtimeout = global_rtpholdtimeout; 21366 } 21367 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 21368 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 21369 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 21370 peer->rtpkeepalive = global_rtpkeepalive; 21371 } 21372 } else if (!strcasecmp(v->name, "timert1")) { 21373 if ((sscanf(v->value, "%d", &peer->timer_t1) != 1) || (peer->timer_t1 < 0)) { 21374 ast_log(LOG_WARNING, "'%s' is not a valid T1 time at line %d. Using default.\n", v->value, v->lineno); 21375 peer->timer_t1 = global_t1; 21376 } 21377 /* Note that Timer B is dependent upon T1 and MUST NOT be lower 21378 * than T1 * 64, according to RFC 3261, Section 17.1.1.2 */ 21379 if (peer->timer_b < peer->timer_t1 * 64) { 21380 peer->timer_b = peer->timer_t1 * 64; 21381 } 21382 } else if (!strcasecmp(v->name, "timerb")) { 21383 if ((sscanf(v->value, "%d", &peer->timer_b) != 1) || (peer->timer_b < 0)) { 21384 ast_log(LOG_WARNING, "'%s' is not a valid Timer B time at line %d. Using default.\n", v->value, v->lineno); 21385 peer->timer_b = global_timer_b; 21386 } 21387 if (peer->timer_b < peer->timer_t1 * 64) { 21388 static int warning = 0; 21389 if (warning++ % 20 == 0) { 21390 ast_log(LOG_WARNING, "Timer B has been set lower than recommended. (RFC 3261, 17.1.1.2)\n"); 21391 } 21392 } 21393 } else if (!strcasecmp(v->name, "setvar")) { 21394 peer->chanvars = add_var(v->value, peer->chanvars); 21395 } else if (!strcasecmp(v->name, "qualify")) { 21396 if (!strcasecmp(v->value, "no")) { 21397 peer->maxms = 0; 21398 } else if (!strcasecmp(v->value, "yes")) { 21399 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 21400 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 21401 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); 21402 peer->maxms = 0; 21403 } 21404 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) { 21405 /* This would otherwise cause a network storm, where the 21406 * qualify response refreshes the peer from the database, 21407 * which in turn causes another qualify to be sent, ad 21408 * infinitum. */ 21409 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); 21410 peer->maxms = 0; 21411 } 21412 } else if (!strcasecmp(v->name, "qualifyfreq")) { 21413 int i; 21414 if (sscanf(v->value, "%d", &i) == 1) 21415 peer->qualifyfreq = i * 1000; 21416 else { 21417 ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config); 21418 peer->qualifyfreq = global_qualifyfreq; 21419 } 21420 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 21421 peer->maxcallbitrate = atoi(v->value); 21422 if (peer->maxcallbitrate < 0) 21423 peer->maxcallbitrate = default_maxcallbitrate; 21424 } else if (!strcasecmp(v->name, "session-timers")) { 21425 int i = (int) str2stmode(v->value); 21426 if (i < 0) { 21427 ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config); 21428 peer->stimer.st_mode_oper = global_st_mode; 21429 } else { 21430 peer->stimer.st_mode_oper = i; 21431 } 21432 } else if (!strcasecmp(v->name, "session-expires")) { 21433 if (sscanf(v->value, "%d", &peer->stimer.st_max_se) != 1) { 21434 ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config); 21435 peer->stimer.st_max_se = global_max_se; 21436 } 21437 } else if (!strcasecmp(v->name, "session-minse")) { 21438 if (sscanf(v->value, "%d", &peer->stimer.st_min_se) != 1) { 21439 ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config); 21440 peer->stimer.st_min_se = global_min_se; 21441 } 21442 if (peer->stimer.st_min_se < 90) { 21443 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); 21444 peer->stimer.st_min_se = global_min_se; 21445 } 21446 } else if (!strcasecmp(v->name, "session-refresher")) { 21447 int i = (int) str2strefresher(v->value); 21448 if (i < 0) { 21449 ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config); 21450 peer->stimer.st_ref = global_st_refresher; 21451 } else { 21452 peer->stimer.st_ref = i; 21453 } 21454 } 21455 } 21456 21457 if (!peer->default_outbound_transport) { 21458 peer->transports = SIP_TRANSPORT_UDP; 21459 peer->default_outbound_transport = SIP_TRANSPORT_UDP; 21460 } 21461 21462 /* The default transport type set during build_peer should only replace the socket.type when... 21463 * 1. Registration is not present and the socket.type and default transport types are different. 21464 * 2. The socket.type is not an acceptable transport type after rebuilding peer. 21465 * 3. The socket.type is not set yet. */ 21466 if (((peer->socket.type != peer->default_outbound_transport) && (peer->expire == -1)) || 21467 !(peer->socket.type & peer->transports) || !(peer->socket.type)) { 21468 21469 set_socket_transport(&peer->socket, peer->default_outbound_transport); 21470 } 21471 21472 if (fullcontact->used > 0) { 21473 ast_copy_string(peer->fullcontact, fullcontact->str, sizeof(peer->fullcontact)); 21474 peer->rt_fromcontact = TRUE; 21475 /* We have a hostname in the fullcontact, but if we don't have an 21476 * address listed on the entry (or if it's 'dynamic'), then we need to 21477 * parse the entry to obtain the IP address, so a dynamic host can be 21478 * contacted immediately after reload (as opposed to waiting for it to 21479 * register once again). But if we have an address for this peer and NAT was 21480 * specified, use that address instead. */ 21481 /* XXX May need to revisit the final argument; does the realtime DB store whether 21482 * the original contact was over TLS or not? XXX */ 21483 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE) || !peer->addr.sin_addr.s_addr) { 21484 __set_address_from_contact(fullcontact->str, &peer->addr, 0); 21485 } 21486 } 21487 21488 if (srvlookup) { 21489 if (ast_get_ip_or_srv(&peer->addr, srvlookup, 21490 global_srvlookup ? 21491 ((peer->socket.type & SIP_TRANSPORT_UDP) ? "_sip._udp" : 21492 (peer->socket.type & SIP_TRANSPORT_TCP) ? "_sip._tcp" : 21493 "_sip._tls") 21494 : NULL)) { 21495 unref_peer(peer); 21496 return NULL; 21497 } 21498 21499 ast_copy_string(peer->tohost, srvlookup, sizeof(peer->tohost)); 21500 } 21501 21502 if (!peer->addr.sin_port) 21503 peer->addr.sin_port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT)); 21504 21505 if (!peer->socket.port) 21506 peer->socket.port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT)); 21507 21508 if (!sip_cfg.ignore_regexpire && peer->host_dynamic && realtime) { 21509 time_t nowtime = time(NULL); 21510 21511 if ((nowtime - regseconds) > 0) { 21512 destroy_association(peer); 21513 memset(&peer->addr, 0, sizeof(peer->addr)); 21514 peer->lastms = -1; 21515 ast_debug(1, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 21516 } 21517 } 21518 21519 /* Startup regular pokes */ 21520 if (realtime && peer->lastms > 0) { 21521 ASTOBJ_REF(peer); 21522 sip_poke_peer(peer); 21523 } 21524 21525 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 21526 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 21527 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 21528 global_allowsubscribe = TRUE; /* No global ban any more */ 21529 if (!found && peer->host_dynamic && !peer->is_realtime) 21530 reg_source_db(peer); 21531 21532 /* If they didn't request that MWI is sent *only* on subscribe, go ahead and 21533 * subscribe to it now. */ 21534 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 21535 !AST_LIST_EMPTY(&peer->mailboxes)) { 21536 add_peer_mwi_subs(peer); 21537 /* Send MWI from the event cache only. This is so we can send initial 21538 * MWI if app_voicemail got loaded before chan_sip. If it is the other 21539 * way, then we will get events when app_voicemail gets loaded. */ 21540 sip_send_mwi_to_peer(peer, NULL, 1); 21541 } 21542 21543 ASTOBJ_UNMARK(peer); 21544 21545 ast_free_ha(oldha); 21546 if (!ast_strlen_zero(callback)) { /* build string from peer info */ 21547 char *reg_string; 21548 21549 if (asprintf(®_string, "%s:%s@%s/%s", peer->username, peer->secret, peer->tohost, callback) < 0) { 21550 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 21551 } else if (reg_string) { 21552 sip_register(reg_string, 0); /* XXX TODO: count in registry_count */ 21553 ast_free(reg_string); 21554 } 21555 } 21556 return peer; 21557 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 14845 of file chan_sip.c.
References append_history, ast_copy_string(), ast_debug, ast_inet_ntoa(), ast_log(), ast_md5_hash(), ast_random(), ast_strlen_zero(), authl, sip_pvt::authname, sip_pvt::callid, sip_pvt::domain, find_realm_authentication(), LOG_DEBUG, sip_auth::md5secret, sip_pvt::nonce, sip_pvt::noncecount, sip_pvt::opaque, sip_registry::opaque, sip_pvt::peerauth, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_pvt::qop, sip_pvt::realm, sip_pvt::sa, sip_auth::secret, sip_methods, text, sip_pvt::uri, sip_auth::username, and sip_pvt::username.
Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().
14846 { 14847 char a1[256]; 14848 char a2[256]; 14849 char a1_hash[256]; 14850 char a2_hash[256]; 14851 char resp[256]; 14852 char resp_hash[256]; 14853 char uri[256]; 14854 char opaque[256] = ""; 14855 char cnonce[80]; 14856 const char *username; 14857 const char *secret; 14858 const char *md5secret; 14859 struct sip_auth *auth = NULL; /* Realm authentication */ 14860 14861 if (!ast_strlen_zero(p->domain)) 14862 ast_copy_string(uri, p->domain, sizeof(uri)); 14863 else if (!ast_strlen_zero(p->uri)) 14864 ast_copy_string(uri, p->uri, sizeof(uri)); 14865 else 14866 snprintf(uri, sizeof(uri), "sip:%s@%s", p->username, ast_inet_ntoa(p->sa.sin_addr)); 14867 14868 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 14869 14870 /* Check if we have separate auth credentials */ 14871 if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */ 14872 auth = find_realm_authentication(authl, p->realm); /* If not, global list */ 14873 14874 if (auth) { 14875 ast_log(LOG_DEBUG, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username); 14876 username = auth->username; 14877 secret = auth->secret; 14878 md5secret = auth->md5secret; 14879 if (sipdebug) 14880 ast_debug(1, "Using realm %s authentication for call %s\n", p->realm, p->callid); 14881 } else { 14882 /* No authentication, use peer or register= config */ 14883 username = p->authname; 14884 secret = p->peersecret; 14885 md5secret = p->peermd5secret; 14886 } 14887 if (ast_strlen_zero(username)) /* We have no authentication */ 14888 return -1; 14889 14890 /* Calculate SIP digest response */ 14891 snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret); 14892 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[method].text, uri); 14893 if (!ast_strlen_zero(md5secret)) 14894 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 14895 else 14896 ast_md5_hash(a1_hash, a1); 14897 ast_md5_hash(a2_hash, a2); 14898 14899 p->noncecount++; 14900 if (!ast_strlen_zero(p->qop)) 14901 snprintf(resp, sizeof(resp), "%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 14902 else 14903 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, p->nonce, a2_hash); 14904 ast_md5_hash(resp_hash, resp); 14905 14906 /* only include the opaque string if it's set */ 14907 if (!ast_strlen_zero(p->opaque)) { 14908 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 14909 } 14910 14911 /* XXX We hard code our qop to "auth" for now. XXX */ 14912 if (!ast_strlen_zero(p->qop)) 14913 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); 14914 else 14915 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); 14916 14917 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 14918 14919 return 0; 14920 }
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 10527 of file chan_sip.c.
References __get_header(), ast_copy_string(), ast_debug, ast_malloc, ast_strlen_zero(), free_old_route(), get_header(), sip_route::hop, len(), list_route(), sip_route::next, sip_pvt::route, sip_pvt::route_persistant, and sip_debug_test_pvt().
Referenced by build_user_routes(), handle_request_invite(), and handle_response_invite().
10528 { 10529 struct sip_route *thishop, *head, *tail; 10530 int start = 0; 10531 int len; 10532 const char *rr, *contact, *c; 10533 10534 /* Once a persistant route is set, don't fool with it */ 10535 if (p->route && p->route_persistant) { 10536 ast_debug(1, "build_route: Retaining previous route: <%s>\n", p->route->hop); 10537 return; 10538 } 10539 10540 if (p->route) { 10541 free_old_route(p->route); 10542 p->route = NULL; 10543 } 10544 10545 /* We only want to create the route set the first time this is called */ 10546 p->route_persistant = 1; 10547 10548 /* Build a tailq, then assign it to p->route when done. 10549 * If backwards, we add entries from the head so they end up 10550 * in reverse order. However, we do need to maintain a correct 10551 * tail pointer because the contact is always at the end. 10552 */ 10553 head = NULL; 10554 tail = head; 10555 /* 1st we pass through all the hops in any Record-Route headers */ 10556 for (;;) { 10557 /* Each Record-Route header */ 10558 rr = __get_header(req, "Record-Route", &start); 10559 if (*rr == '\0') 10560 break; 10561 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 10562 ++rr; 10563 len = strcspn(rr, ">") + 1; 10564 /* Make a struct route */ 10565 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 10566 /* ast_calloc is not needed because all fields are initialized in this block */ 10567 ast_copy_string(thishop->hop, rr, len); 10568 ast_debug(2, "build_route: Record-Route hop: <%s>\n", thishop->hop); 10569 /* Link in */ 10570 if (backwards) { 10571 /* Link in at head so they end up in reverse order */ 10572 thishop->next = head; 10573 head = thishop; 10574 /* If this was the first then it'll be the tail */ 10575 if (!tail) 10576 tail = thishop; 10577 } else { 10578 thishop->next = NULL; 10579 /* Link in at the end */ 10580 if (tail) 10581 tail->next = thishop; 10582 else 10583 head = thishop; 10584 tail = thishop; 10585 } 10586 } 10587 } 10588 } 10589 10590 /* Only append the contact if we are dealing with a strict router */ 10591 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop, ";lr") == NULL) ) { 10592 /* 2nd append the Contact: if there is one */ 10593 /* Can be multiple Contact headers, comma separated values - we just take the first */ 10594 contact = get_header(req, "Contact"); 10595 if (!ast_strlen_zero(contact)) { 10596 ast_debug(2, "build_route: Contact hop: %s\n", contact); 10597 /* Look for <: delimited address */ 10598 c = strchr(contact, '<'); 10599 if (c) { 10600 /* Take to > */ 10601 ++c; 10602 len = strcspn(c, ">") + 1; 10603 } else { 10604 /* No <> - just take the lot */ 10605 c = contact; 10606 len = strlen(contact) + 1; 10607 } 10608 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 10609 /* ast_calloc is not needed because all fields are initialized in this block */ 10610 ast_copy_string(thishop->hop, c, len); 10611 thishop->next = NULL; 10612 /* Goes at the end */ 10613 if (tail) 10614 tail->next = thishop; 10615 else 10616 head = thishop; 10617 } 10618 } 10619 } 10620 10621 /* Store as new route */ 10622 p->route = head; 10623 10624 /* For debugging dump what we ended up with */ 10625 if (sip_debug_test_pvt(p)) 10626 list_route(p->route); 10627 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 8994 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), 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_string_field_build, ast_string_field_set, ast_strlen_zero(), buf, sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, FALSE, sip_pvt::fromdomain, sip_pvt::fromuser, LOG_WARNING, sip_pvt::ourip, sip_pvt::owner, sip_pvt::rpid, sip_pvt::rpid_from, S_OR, sip_pvt::tag, and TRUE.
Referenced by initreqprep().
08995 { 08996 int send_pres_tags = TRUE; 08997 const char *privacy=NULL; 08998 const char *screen=NULL; 08999 char buf[256]; 09000 const char *clid = default_callerid; 09001 const char *clin = NULL; 09002 const char *fromdomain; 09003 09004 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 09005 return; 09006 09007 if (p->owner && p->owner->cid.cid_num) 09008 clid = p->owner->cid.cid_num; 09009 if (p->owner && p->owner->cid.cid_name) 09010 clin = p->owner->cid.cid_name; 09011 if (ast_strlen_zero(clin)) 09012 clin = clid; 09013 09014 switch (p->callingpres) { 09015 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 09016 privacy = "off"; 09017 screen = "no"; 09018 break; 09019 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 09020 privacy = "off"; 09021 screen = "yes"; 09022 break; 09023 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 09024 privacy = "off"; 09025 screen = "no"; 09026 break; 09027 case AST_PRES_ALLOWED_NETWORK_NUMBER: 09028 privacy = "off"; 09029 screen = "yes"; 09030 break; 09031 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 09032 privacy = "full"; 09033 screen = "no"; 09034 break; 09035 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 09036 privacy = "full"; 09037 screen = "yes"; 09038 break; 09039 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 09040 privacy = "full"; 09041 screen = "no"; 09042 break; 09043 case AST_PRES_PROHIB_NETWORK_NUMBER: 09044 privacy = "full"; 09045 screen = "yes"; 09046 break; 09047 case AST_PRES_NUMBER_NOT_AVAILABLE: 09048 send_pres_tags = FALSE; 09049 break; 09050 default: 09051 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 09052 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 09053 privacy = "full"; 09054 else 09055 privacy = "off"; 09056 screen = "no"; 09057 break; 09058 } 09059 09060 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr)); 09061 09062 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 09063 if (send_pres_tags) 09064 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 09065 ast_string_field_set(p, rpid, buf); 09066 09067 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 09068 S_OR(p->fromuser, clid), 09069 fromdomain, p->tag); 09070 }
static struct sip_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static] |
Initiate a SIP user structure from configuration (configuration or realtime).
Definition at line 20836 of file chan_sip.c.
References add_var(), ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_copy_flags, ast_copy_string(), ast_free_ha(), ast_get_group(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_test_flag, ast_true(), ASTOBJ_INIT, default_prefs, FALSE, ast_flags::flags, format, global_flags, handle_common_options(), ast_variable::lineno, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, SIP_FLAGS_TO_COPY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_FLAGS_TO_COPY, str2stmode(), str2strefresher(), TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, user, and ast_variable::value.
20837 { 20838 struct sip_user *user; 20839 int format; 20840 struct ast_ha *oldha = NULL; 20841 struct ast_flags userflags[2] = {{(0)}}; 20842 struct ast_flags mask[2] = {{(0)}}; 20843 20844 20845 if (!(user = ast_calloc(1, sizeof(*user)))) 20846 return NULL; 20847 20848 suserobjs++; 20849 ASTOBJ_INIT(user); 20850 ast_copy_string(user->name, name, sizeof(user->name)); 20851 oldha = user->ha; 20852 user->ha = NULL; 20853 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 20854 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 20855 user->capability = global_capability; 20856 user->allowtransfer = global_allowtransfer; 20857 user->maxcallbitrate = default_maxcallbitrate; 20858 user->autoframing = global_autoframing; 20859 if (global_callcounter) 20860 user->call_limit=999; 20861 user->prefs = default_prefs; 20862 user->stimer.st_mode_oper = global_st_mode; /* Session-Timers */ 20863 user->stimer.st_ref = global_st_refresher; 20864 user->stimer.st_min_se = global_min_se; 20865 user->stimer.st_max_se = global_max_se; 20866 20867 /* set default context */ 20868 strcpy(user->context, default_context); 20869 strcpy(user->language, default_language); 20870 strcpy(user->mohinterpret, default_mohinterpret); 20871 strcpy(user->mohsuggest, default_mohsuggest); 20872 /* First we walk through the v parameters list and then the alt parameters list */ 20873 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 20874 if (handle_common_options(&userflags[0], &mask[0], v)) 20875 continue; 20876 if (!strcasecmp(v->name, "context")) { 20877 ast_copy_string(user->context, v->value, sizeof(user->context)); 20878 } else if (!strcasecmp(v->name, "subscribecontext")) { 20879 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 20880 } else if (!strcasecmp(v->name, "setvar")) { 20881 user->chanvars = add_var(v->value, user->chanvars); 20882 } else if (!strcasecmp(v->name, "permit") || 20883 !strcasecmp(v->name, "deny")) { 20884 int ha_error = 0; 20885 20886 user->ha = ast_append_ha(v->name, v->value, user->ha, &ha_error); 20887 if (ha_error) 20888 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 20889 } else if (!strcasecmp(v->name, "allowtransfer")) { 20890 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 20891 } else if (!strcasecmp(v->name, "secret")) { 20892 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 20893 } else if (!strcasecmp(v->name, "md5secret")) { 20894 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 20895 } else if (!strcasecmp(v->name, "callerid")) { 20896 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 20897 } else if (!strcasecmp(v->name, "fullname")) { 20898 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 20899 } else if (!strcasecmp(v->name, "cid_number")) { 20900 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 20901 } else if (!strcasecmp(v->name, "callgroup")) { 20902 user->callgroup = ast_get_group(v->value); 20903 } else if (!strcasecmp(v->name, "pickupgroup")) { 20904 user->pickupgroup = ast_get_group(v->value); 20905 } else if (!strcasecmp(v->name, "language")) { 20906 ast_copy_string(user->language, v->value, sizeof(user->language)); 20907 } else if (!strcasecmp(v->name, "mohinterpret")) { 20908 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 20909 } else if (!strcasecmp(v->name, "mohsuggest")) { 20910 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 20911 } else if (!strcasecmp(v->name, "accountcode")) { 20912 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 20913 } else if (!strcasecmp(v->name, "callcounter")) { 20914 user->call_limit = ast_true(v->value) ? 999 : 0; 20915 } else if (!strcasecmp(v->name, "call-limit")) { 20916 user->call_limit = atoi(v->value); 20917 if (user->call_limit < 0) 20918 user->call_limit = 0; 20919 } else if (!strcasecmp(v->name, "amaflags")) { 20920 format = ast_cdr_amaflags2int(v->value); 20921 if (format < 0) { 20922 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 20923 } else { 20924 user->amaflags = format; 20925 } 20926 } else if (!strcasecmp(v->name, "allow")) { 20927 int error = ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, TRUE); 20928 if (error) 20929 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 20930 } else if (!strcasecmp(v->name, "disallow")) { 20931 int error = ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, FALSE); 20932 if (error) 20933 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 20934 } else if (!strcasecmp(v->name, "autoframing")) { 20935 user->autoframing = ast_true(v->value); 20936 } else if (!strcasecmp(v->name, "callingpres")) { 20937 user->callingpres = ast_parse_caller_presentation(v->value); 20938 if (user->callingpres == -1) 20939 user->callingpres = atoi(v->value); 20940 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 20941 user->maxcallbitrate = atoi(v->value); 20942 if (user->maxcallbitrate < 0) 20943 user->maxcallbitrate = default_maxcallbitrate; 20944 } else if (!strcasecmp(v->name, "session-timers")) { 20945 int i = (int) str2stmode(v->value); 20946 if (i < 0) { 20947 ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config); 20948 user->stimer.st_mode_oper = global_st_mode; 20949 } else { 20950 user->stimer.st_mode_oper = i; 20951 } 20952 } else if (!strcasecmp(v->name, "session-expires")) { 20953 if (sscanf(v->value, "%d", &user->stimer.st_max_se) != 1) { 20954 ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config); 20955 user->stimer.st_max_se = global_max_se; 20956 } 20957 } else if (!strcasecmp(v->name, "session-minse")) { 20958 if (sscanf(v->value, "%d", &user->stimer.st_min_se) != 1) { 20959 ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config); 20960 user->stimer.st_min_se = global_min_se; 20961 } 20962 if (user->stimer.st_min_se < 90) { 20963 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); 20964 user->stimer.st_min_se = global_min_se; 20965 } 20966 } else if (!strcasecmp(v->name, "session-refresher")) { 20967 int i = (int) str2strefresher(v->value); 20968 if (i < 0) { 20969 ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config); 20970 user->stimer.st_ref = global_st_refresher; 20971 } else { 20972 user->stimer.st_ref = i; 20973 } 20974 } 20975 20976 /* We can't just report unknown options here because this may be a 20977 * type=friend entry. All user options are valid for a peer, but not 20978 * the other way around. */ 20979 } 20980 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 20981 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 20982 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 20983 global_allowsubscribe = TRUE; /* No global ban any more */ 20984 ast_free_ha(oldha); 20985 return user; 20986 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 2676 of file chan_sip.c.
References ast_inet_ntoa(), ast_test_flag, sip_pvt::branch, sip_pvt::flags, get_transport_pvt(), sip_pvt::ourip, SIP_NAT, SIP_NAT_RFC3581, and sip_pvt::via.
Referenced by reqprep(), sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), transmit_register(), and transmit_response_using_temp().
02677 { 02678 /* Work around buggy UNIDEN UIP200 firmware */ 02679 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 02680 02681 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 02682 snprintf(p->via, sizeof(p->via), "SIP/2.0/%s %s:%d;branch=z9hG4bK%08x%s", 02683 get_transport_pvt(p), 02684 ast_inet_ntoa(p->ourip.sin_addr), 02685 ntohs(p->ourip.sin_port), (int) p->branch, rport); 02686 }
static int cb_extensionstate | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 10841 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_log(), ast_set_flag, ast_test_flag, ast_verb, sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, sip_pvt::laststate, LOG_WARNING, NONE, sip_pvt::pendinginvite, sip_cancel_destroy(), SIP_PAGE2_STATECHANGEQUEUE, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), sip_pvt::stateid, sip_pvt::subscribed, transmit_state_notify(), and sip_pvt::username.
Referenced by handle_request_subscribe(), and handle_response().
10842 { 10843 struct sip_pvt *p = data; 10844 10845 sip_pvt_lock(p); 10846 10847 switch(state) { 10848 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 10849 case AST_EXTENSION_REMOVED: /* Extension is gone */ 10850 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 10851 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 10852 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 10853 ast_verb(2, "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username); 10854 p->stateid = -1; 10855 p->subscribed = NONE; 10856 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 10857 break; 10858 default: /* Tell user */ 10859 p->laststate = state; 10860 break; 10861 } 10862 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 10863 if (!p->pendinginvite) { 10864 transmit_state_notify(p, state, 1, FALSE); 10865 } else { 10866 /* We already have a NOTIFY sent that is not answered. Queue the state up. 10867 if many state changes happen meanwhile, we will only send a notification of the last one */ 10868 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 10869 } 10870 } 10871 ast_verb(2, "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username, 10872 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 10873 10874 sip_pvt_unlock(p); 10875 10876 return 0; 10877 }
static void change_t38_state | ( | struct sip_pvt * | p, | |
int | state | |||
) | [static] |
Change the T38 state on a SIP dialog.
Definition at line 4036 of file chan_sip.c.
References AST_CONTROL_T38, ast_debug, ast_queue_control_data(), AST_T38_NEGOTIATED, AST_T38_REFUSED, AST_T38_REQUEST_NEGOTIATE, AST_T38_TERMINATED, chan, t38properties::direct, ast_channel::name, sip_pvt::owner, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_REINVITE, T38_PEER_DIRECT, and T38_PEER_REINVITE.
Referenced by handle_response_invite(), process_sdp(), sip_answer(), sip_indicate(), sip_read(), sip_t38_abort(), and sip_write().
04037 { 04038 int old = p->t38.state; 04039 struct ast_channel *chan = p->owner; 04040 enum ast_control_t38 message = 0; 04041 04042 /* Don't bother changing if we are already in the state wanted */ 04043 if (old == state) 04044 return; 04045 04046 if (state == T38_PEER_DIRECT) { 04047 p->t38.direct = 1; 04048 } 04049 04050 p->t38.state = state; 04051 ast_debug(2, "T38 state changed to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 04052 04053 /* If no channel was provided we can't send off a control frame */ 04054 if (!chan) 04055 return; 04056 04057 /* Given the state requested and old state determine what control frame we want to queue up */ 04058 if (state == T38_PEER_REINVITE) 04059 message = AST_T38_REQUEST_NEGOTIATE; 04060 else if (state == T38_ENABLED) 04061 message = AST_T38_NEGOTIATED; 04062 else if (state == T38_DISABLED && old == T38_ENABLED) 04063 message = AST_T38_TERMINATED; 04064 else if (state == T38_DISABLED && old == T38_LOCAL_REINVITE) 04065 message = AST_T38_REFUSED; 04066 04067 /* Woot we got a message, create a control frame and send it on! */ 04068 if (message) 04069 ast_queue_control_data(chan, AST_CONTROL_T38, &message, sizeof(message)); 04070 }
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, | |||
char * | uri, | |||
enum xmittype | reliable, | |||
int | ignore | |||
) | [static] |
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
XXX
XXX
Definition at line 10637 of file chan_sip.c.
References append_history, ast_copy_string(), AST_DYNSTR_BUILD_FAILED, ast_log(), ast_md5_hash(), ast_random(), ast_skip_blanks(), ast_str_set(), ast_str_thread_get(), ast_string_field_build, ast_strlen_zero(), AUTH_CHALLENGE_SENT, auth_headers(), AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, AUTH_USERNAME_MISMATCH, buf, check_auth_buf, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), sip_request::ignore, LOG_NOTICE, LOG_WARNING, sip_pvt::randdata, s, S_OR, sip_methods, sip_scheddestroy(), strsep(), text, transmit_response_with_auth(), TRUE, and WWW_AUTH.
Referenced by check_peer_ok(), check_user_ok(), and register_verify().
10640 { 10641 const char *response; 10642 char *reqheader, *respheader; 10643 const char *authtoken; 10644 char a1_hash[256]; 10645 char resp_hash[256]=""; 10646 char *c; 10647 int wrongnonce = FALSE; 10648 int good_response; 10649 const char *usednonce = p->randdata; 10650 struct ast_str *buf; 10651 int res; 10652 10653 /* table of recognised keywords, and their value in the digest */ 10654 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 10655 struct x { 10656 const char *key; 10657 const char *s; 10658 } *i, keys[] = { 10659 [K_RESP] = { "response=", "" }, 10660 [K_URI] = { "uri=", "" }, 10661 [K_USER] = { "username=", "" }, 10662 [K_NONCE] = { "nonce=", "" }, 10663 [K_LAST] = { NULL, NULL} 10664 }; 10665 10666 /* Always OK if no secret */ 10667 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 10668 return AUTH_SUCCESSFUL; 10669 10670 /* Always auth with WWW-auth since we're NOT a proxy */ 10671 /* Using proxy-auth in a B2BUA may block proxy authorization in the same transaction */ 10672 response = "401 Unauthorized"; 10673 10674 /* 10675 * Note the apparent swap of arguments below, compared to other 10676 * usages of auth_headers(). 10677 */ 10678 auth_headers(WWW_AUTH, &respheader, &reqheader); 10679 10680 authtoken = get_header(req, reqheader); 10681 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 10682 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 10683 information */ 10684 if (!reliable) { 10685 /* Resend message if this was NOT a reliable delivery. Otherwise the 10686 retransmission should get it */ 10687 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 10688 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 10689 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10690 } 10691 return AUTH_CHALLENGE_SENT; 10692 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 10693 /* We have no auth, so issue challenge and request authentication */ 10694 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 10695 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 10696 /* Schedule auto destroy in 32 seconds */ 10697 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10698 return AUTH_CHALLENGE_SENT; 10699 } 10700 10701 /* --- We have auth, so check it */ 10702 10703 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 10704 an example in the spec of just what it is you're doing a hash on. */ 10705 10706 if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) 10707 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 10708 10709 /* Make a copy of the response and parse it */ 10710 res = ast_str_set(&buf, 0, "%s", authtoken); 10711 10712 if (res == AST_DYNSTR_BUILD_FAILED) 10713 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 10714 10715 c = buf->str; 10716 10717 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 10718 for (i = keys; i->key != NULL; i++) { 10719 const char *separator = ","; /* default */ 10720 10721 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 10722 continue; 10723 /* Found. Skip keyword, take text in quotes or up to the separator. */ 10724 c += strlen(i->key); 10725 if (*c == '"') { /* in quotes. Skip first and look for last */ 10726 c++; 10727 separator = "\""; 10728 } 10729 i->s = c; 10730 strsep(&c, separator); 10731 break; 10732 } 10733 if (i->key == NULL) /* not found, jump after space or comma */ 10734 strsep(&c, " ,"); 10735 } 10736 10737 /* Verify that digest username matches the username we auth as */ 10738 if (strcmp(username, keys[K_USER].s)) { 10739 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 10740 username, keys[K_USER].s); 10741 /* Oops, we're trying something here */ 10742 return AUTH_USERNAME_MISMATCH; 10743 } 10744 10745 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 10746 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */ 10747 wrongnonce = TRUE; 10748 usednonce = keys[K_NONCE].s; 10749 } 10750 10751 if (!ast_strlen_zero(md5secret)) 10752 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 10753 else { 10754 char a1[256]; 10755 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 10756 ast_md5_hash(a1_hash, a1); 10757 } 10758 10759 /* compute the expected response to compare with what we received */ 10760 { 10761 char a2[256]; 10762 char a2_hash[256]; 10763 char resp[256]; 10764 10765 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 10766 S_OR(keys[K_URI].s, uri)); 10767 ast_md5_hash(a2_hash, a2); 10768 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 10769 ast_md5_hash(resp_hash, resp); 10770 } 10771 10772 good_response = keys[K_RESP].s && 10773 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 10774 if (wrongnonce) { 10775 if (good_response) { 10776 if (sipdebug) 10777 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 10778 /* We got working auth token, based on stale nonce . */ 10779 ast_string_field_build(p, randdata, "%08lx", ast_random()); 10780 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 10781 } else { 10782 /* Everything was wrong, so give the device one more try with a new challenge */ 10783 if (!req->ignore) { 10784 if (sipdebug) 10785 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 10786 ast_string_field_build(p, randdata, "%08lx", ast_random()); 10787 } else { 10788 if (sipdebug) 10789 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 10790 } 10791 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 10792 } 10793 10794 /* Schedule auto destroy in 32 seconds */ 10795 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10796 return AUTH_CHALLENGE_SENT; 10797 } 10798 if (good_response) { 10799 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 10800 return AUTH_SUCCESSFUL; 10801 } 10802 10803 /* Ok, we have a bad username/secret pair */ 10804 /* Tell the UAS not to re-send this authentication data, because 10805 it will continue to fail 10806 */ 10807 10808 return AUTH_SECRET_FAILED; 10809 }
static enum check_auth_result check_peer_ok | ( | struct sip_pvt * | p, | |
char * | of, | |||
struct sip_request * | req, | |||
int | sipmethod, | |||
struct sockaddr_in * | sin, | |||
struct sip_peer ** | authpeer, | |||
enum xmittype | reliable, | |||
char * | rpid_num, | |||
char * | calleridname, | |||
char * | uri2 | |||
) | [static] |
Validate peer authentication.
Definition at line 12029 of file chan_sip.c.
References __set_address_from_contact(), sip_peer::accountcode, sip_peer::amaflags, sip_pvt::amaflags, ast_copy_flags, ast_copy_string(), AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_is_shrinkable_phonenumber(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, AUTH_DONT_KNOW, sip_peer::autoframing, sip_pvt::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, sip_pvt::callingpres, sip_peer::callingpres, sip_peer::capability, sip_pvt::capability, sip_peer::chanvars, sip_pvt::chanvars, check_auth(), sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, copy_vars(), debug, do_setnat(), find_peer(), sip_peer::flags, sip_pvt::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), sip_request::ignore, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_peer::language, sip_peer::lastms, sip_peer::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, sip_peer::name, sip_pvt::noncodeccapability, t38properties::peercapability, sip_pvt::peercapability, sip_pvt::peermd5secret, sip_pvt::peersecret, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_pvt::prefs, sip_peer::prefs, sip_pvt::recv, replace_cid(), sip_pvt::rtp, sip_peer::secret, SIP_CALL_LIMIT, sip_debug_test_addr(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_INSECURE_INVITE, SIP_INVITE, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_SUBSCRIBE, SIP_TRANSPORT_UDP, SIPBUFSIZE, sip_peer::sipoptions, sip_pvt::sipoptions, sip_pvt::socket, sip_peer::subscribecontext, sip_pvt::t38, sip_pvt::timer_b, sip_peer::timer_b, sip_peer::timer_t1, sip_pvt::timer_t1, sip_pvt::trtp, sip_socket::type, unref_peer(), sip_peer::username, and sip_pvt::vrtp.
Referenced by check_user_full().
12034 { 12035 enum check_auth_result res; 12036 int debug=sip_debug_test_addr(sin); 12037 struct sip_peer *peer; 12038 12039 /* For subscribes, match on peer name only; for other methods, 12040 * match on IP address-port of the incoming request. 12041 */ 12042 peer = (sipmethod == SIP_SUBSCRIBE) ? find_peer(of, NULL, 1, 0) : find_peer(NULL, &p->recv, 1, 0); 12043 12044 /* If the peer is still not found, try the address and port from the 12045 * contact header. If the transport type is TCP or TLS it is not possible 12046 * to find the peer using p->recv. Because of the way TCP works, the received 12047 * packet's destination port will not match the one the peer table is 12048 * built with. */ 12049 if (!peer && (p->socket.type != SIP_TRANSPORT_UDP)) { 12050 struct sockaddr_in tmpsin; 12051 char contact[SIPBUFSIZE]; 12052 char *tmp; 12053 memcpy(&tmpsin, &p->recv, sizeof(tmpsin)); 12054 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 12055 tmp = get_in_brackets(contact); 12056 __set_address_from_contact(tmp, &tmpsin, 1); 12057 peer = find_peer(NULL, &tmpsin, 1, 0); 12058 } 12059 if (!peer) { 12060 if (debug) 12061 ast_verbose("No matching peer for '%s' from '%s:%d'\n", 12062 of, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12063 return AUTH_DONT_KNOW; 12064 } 12065 12066 if (debug) 12067 ast_verbose("Found peer '%s' for '%s' from %s:%d\n", 12068 peer->name, of, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12069 12070 /* XXX what about p->prefs = peer->prefs; ? */ 12071 /* Set Frame packetization */ 12072 if (p->rtp) { 12073 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 12074 p->autoframing = peer->autoframing; 12075 } 12076 12077 /* Take the peer */ 12078 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 12079 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 12080 12081 /* Copy SIP extensions profile to peer */ 12082 /* XXX is this correct before a successful auth ? */ 12083 if (p->sipoptions) 12084 peer->sipoptions = p->sipoptions; 12085 12086 replace_cid(p, rpid_num, calleridname); 12087 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 12088 12089 ast_string_field_set(p, peersecret, peer->secret); 12090 ast_string_field_set(p, peermd5secret, peer->md5secret); 12091 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 12092 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 12093 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 12094 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 12095 p->callingpres = peer->callingpres; 12096 if (peer->maxms && peer->lastms) 12097 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 12098 else 12099 p->timer_t1 = peer->timer_t1; 12100 12101 /* Set timer B to control transaction timeouts */ 12102 if (peer->timer_b) 12103 p->timer_b = peer->timer_b; 12104 else 12105 p->timer_b = 64 * p->timer_t1; 12106 12107 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 12108 /* Pretend there is no required authentication */ 12109 ast_string_field_set(p, peersecret, NULL); 12110 ast_string_field_set(p, peermd5secret, NULL); 12111 } 12112 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, req->ignore))) { 12113 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 12114 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 12115 /* If we have a call limit, set flag */ 12116 if (peer->call_limit) 12117 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 12118 ast_string_field_set(p, peername, peer->name); 12119 ast_string_field_set(p, authname, peer->name); 12120 12121 if (sipmethod == SIP_INVITE) { 12122 /* copy channel vars */ 12123 p->chanvars = copy_vars(peer->chanvars); 12124 } 12125 12126 if (authpeer) { 12127 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 12128 } 12129 12130 if (!ast_strlen_zero(peer->username)) { 12131 ast_string_field_set(p, username, peer->username); 12132 /* Use the default username for authentication on outbound calls */ 12133 /* XXX this takes the name from the caller... can we override ? */ 12134 ast_string_field_set(p, authname, peer->username); 12135 } 12136 if (!ast_strlen_zero(peer->cid_num)) { 12137 char *tmp = ast_strdupa(peer->cid_num); 12138 if (ast_is_shrinkable_phonenumber(tmp)) 12139 ast_shrink_phone_number(tmp); 12140 ast_string_field_set(p, cid_num, tmp); 12141 } 12142 if (!ast_strlen_zero(peer->cid_name)) 12143 ast_string_field_set(p, cid_name, peer->cid_name); 12144 ast_string_field_set(p, fullcontact, peer->fullcontact); 12145 if (!ast_strlen_zero(peer->context)) 12146 ast_string_field_set(p, context, peer->context); 12147 ast_string_field_set(p, peersecret, peer->secret); 12148 ast_string_field_set(p, peermd5secret, peer->md5secret); 12149 ast_string_field_set(p, language, peer->language); 12150 ast_string_field_set(p, accountcode, peer->accountcode); 12151 p->amaflags = peer->amaflags; 12152 p->callgroup = peer->callgroup; 12153 p->pickupgroup = peer->pickupgroup; 12154 p->capability = peer->capability; 12155 p->prefs = peer->prefs; 12156 p->jointcapability = peer->capability; 12157 if (p->peercapability) 12158 p->jointcapability &= p->peercapability; 12159 p->maxcallbitrate = peer->maxcallbitrate; 12160 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 12161 ast_rtp_destroy(p->vrtp); 12162 p->vrtp = NULL; 12163 } 12164 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_TEXTSUPPORT) || !(p->capability & AST_FORMAT_TEXT_MASK)) && p->trtp) { 12165 ast_rtp_destroy(p->trtp); 12166 p->trtp = NULL; 12167 } 12168 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 12169 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 12170 p->noncodeccapability |= AST_RTP_DTMF; 12171 else 12172 p->noncodeccapability &= ~AST_RTP_DTMF; 12173 p->jointnoncodeccapability = p->noncodeccapability; 12174 if (p->t38.peercapability) 12175 p->t38.jointcapability &= p->t38.peercapability; 12176 } 12177 unref_peer(peer); 12178 return res; 12179 }
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 15283 of file chan_sip.c.
References ast_clear_flag, ast_debug, ast_test_flag, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, INV_CALLING, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::pendinginvite, SIP_BYE, SIP_CANCEL, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_scheddestroy(), t38properties::state, sip_pvt::t38, T38_LOCAL_REINVITE, transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), TRUE, sip_pvt::waitid, and XMIT_RELIABLE.
Referenced by handle_incoming(), handle_response_invite(), and sip_reinvite_retry().
15284 { 15285 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 15286 /* if we can't BYE, then this is really a pending CANCEL */ 15287 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 15288 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 15289 /* Actually don't destroy us yet, wait for the 487 on our original 15290 INVITE, but do set an autodestruct just in case we never get it. */ 15291 else { 15292 /* We have a pending outbound invite, don't send someting 15293 new in-transaction */ 15294 if (p->pendinginvite) 15295 return; 15296 15297 /* Perhaps there is an SD change INVITE outstanding */ 15298 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 15299 } 15300 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 15301 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15302 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 15303 /* if we can't REINVITE, hold it for later */ 15304 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 15305 ast_debug(2, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 15306 } else { 15307 ast_debug(2, "Sending pending reinvite on '%s'\n", p->callid); 15308 /* Didn't get to reinvite yet, so do it now */ 15309 transmit_reinvite_with_sdp(p, (p->t38.state == T38_LOCAL_REINVITE ? TRUE : FALSE), FALSE); 15310 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 15311 } 15312 } 15313 }
static void check_rtp_timeout | ( | struct sip_pvt * | dialog, | |
time_t | t | |||
) | [static] |
helper function for the monitoring thread
Definition at line 19646 of file chan_sip.c.
References ast_channel::_state, ast_channel_trylock, ast_channel_unlock, ast_log(), ast_rtp_get_peer(), ast_rtp_get_rtpholdtimeout(), ast_rtp_get_rtpkeepalive(), ast_rtp_get_rtptimeout(), ast_rtp_sendcng(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtptimeout(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, LOG_NOTICE, ast_channel::name, sip_pvt::owner, sip_pvt::redirip, sip_pvt::rtp, SIP_PAGE2_CALL_ONHOLD, sip_pvt_lock, sip_pvt_unlock, t38properties::state, sip_pvt::t38, T38_ENABLED, and sip_pvt::vrtp.
Referenced by do_monitor().
19647 { 19648 /* If we have no RTP or no active owner, no need to check timers */ 19649 if (!dialog->rtp || !dialog->owner) 19650 return; 19651 /* If the call is not in UP state or redirected outside Asterisk, no need to check timers */ 19652 if (dialog->owner->_state != AST_STATE_UP || dialog->redirip.sin_addr.s_addr) 19653 return; 19654 19655 /* If the call is involved in a T38 fax session do not check RTP timeout */ 19656 if (dialog->t38.state == T38_ENABLED) 19657 return; 19658 19659 /* If we have no timers set, return now */ 19660 if ((ast_rtp_get_rtpkeepalive(dialog->rtp) == 0) && (ast_rtp_get_rtptimeout(dialog->rtp) == 0) && (ast_rtp_get_rtpholdtimeout(dialog->rtp) == 0)) 19661 return; 19662 19663 /* Check AUDIO RTP keepalives */ 19664 if (dialog->lastrtptx && ast_rtp_get_rtpkeepalive(dialog->rtp) && 19665 (t > dialog->lastrtptx + ast_rtp_get_rtpkeepalive(dialog->rtp))) { 19666 /* Need to send an empty RTP packet */ 19667 dialog->lastrtptx = time(NULL); 19668 ast_rtp_sendcng(dialog->rtp, 0); 19669 } 19670 19671 /*! \todo Check video RTP keepalives 19672 19673 Do we need to move the lastrtptx to the RTP structure to have one for audio and one 19674 for video? It really does belong to the RTP structure. 19675 */ 19676 19677 /* Check AUDIO RTP timers */ 19678 if (dialog->lastrtprx && (ast_rtp_get_rtptimeout(dialog->rtp) || ast_rtp_get_rtpholdtimeout(dialog->rtp)) && 19679 (t > dialog->lastrtprx + ast_rtp_get_rtptimeout(dialog->rtp))) { 19680 19681 /* Might be a timeout now -- see if we're on hold */ 19682 struct sockaddr_in sin; 19683 ast_rtp_get_peer(dialog->rtp, &sin); 19684 if (!ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD) || (ast_rtp_get_rtpholdtimeout(dialog->rtp) && 19685 (t > dialog->lastrtprx + ast_rtp_get_rtpholdtimeout(dialog->rtp)))) { 19686 /* Needs a hangup */ 19687 if (ast_rtp_get_rtptimeout(dialog->rtp)) { 19688 while (dialog->owner && ast_channel_trylock(dialog->owner)) { 19689 sip_pvt_unlock(dialog); 19690 usleep(1); 19691 sip_pvt_lock(dialog); 19692 } 19693 ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 19694 dialog->owner->name, (long) (t - dialog->lastrtprx)); 19695 /* Issue a softhangup */ 19696 ast_softhangup_nolock(dialog->owner, AST_SOFTHANGUP_DEV); 19697 ast_channel_unlock(dialog->owner); 19698 /* forget the timeouts for this call, since a hangup 19699 has already been requested and we don't want to 19700 repeatedly request hangups 19701 */ 19702 ast_rtp_set_rtptimeout(dialog->rtp, 0); 19703 ast_rtp_set_rtpholdtimeout(dialog->rtp, 0); 19704 if (dialog->vrtp) { 19705 ast_rtp_set_rtptimeout(dialog->vrtp, 0); 19706 ast_rtp_set_rtpholdtimeout(dialog->vrtp, 0); 19707 } 19708 } 19709 } 19710 } 19711 }
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 20699 of file chan_sip.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, and domain::list.
Referenced by func_check_sipdomain(), get_destination(), handle_request_refer(), and register_verify().
20700 { 20701 struct domain *d; 20702 int result = 0; 20703 20704 AST_LIST_LOCK(&domain_list); 20705 AST_LIST_TRAVERSE(&domain_list, d, list) { 20706 if (strcasecmp(d->domain, domain)) 20707 continue; 20708 20709 if (len && !ast_strlen_zero(d->context)) 20710 ast_copy_string(context, d->context, len); 20711 20712 result = 1; 20713 break; 20714 } 20715 AST_LIST_UNLOCK(&domain_list); 20716 20717 return result; 20718 }
static int check_user | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | sipmethod, | |||
char * | uri, | |||
enum xmittype | reliable, | |||
struct sockaddr_in * | sin | |||
) | [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 12321 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
12322 { 12323 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 12324 }
static enum check_auth_result check_user_full | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | sipmethod, | |||
char * | uri, | |||
enum xmittype | reliable, | |||
struct sockaddr_in * | sin, | |||
struct sip_peer ** | authpeer | |||
) | [static] |
Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests.
Definition at line 12187 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, ast_uri_decode(), AUTH_DONT_KNOW, AUTH_FAKE_AUTH, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, build_contact(), check_peer_ok(), check_user_ok(), dummy(), exten, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), LOG_NOTICE, parse_uri(), replace_cid(), SIP_NAT_ROUTE, SIP_PAGE2_RPORT_PRESENT, SIP_TRANSPORT_TLS, strsep(), and terminate_uri().
Referenced by check_user(), and handle_request_subscribe().
12190 { 12191 char from[256]; 12192 char *dummy; /* dummy return value for parse_uri */ 12193 char *domain; /* dummy return value for parse_uri */ 12194 char *of, *of2; 12195 char rpid_num[50]; 12196 const char *rpid; 12197 enum check_auth_result res; 12198 char calleridname[50]; 12199 char *uri2 = ast_strdupa(uri); 12200 12201 terminate_uri(uri2); /* trim extra stuff */ 12202 12203 ast_copy_string(from, get_header(req, "From"), sizeof(from)); 12204 if (pedanticsipchecking) 12205 ast_uri_decode(from); 12206 /* XXX here tries to map the username for invite things */ 12207 memset(calleridname, 0, sizeof(calleridname)); 12208 get_calleridname(from, calleridname, sizeof(calleridname)); 12209 if (calleridname[0]) 12210 ast_string_field_set(p, cid_name, calleridname); 12211 12212 rpid = get_header(req, "Remote-Party-ID"); 12213 memset(rpid_num, 0, sizeof(rpid_num)); 12214 if (!ast_strlen_zero(rpid)) 12215 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 12216 12217 of = get_in_brackets(from); 12218 if (ast_strlen_zero(p->exten)) { 12219 char *t = uri2; 12220 if (!strncasecmp(t, "sip:", 4)) 12221 t+= 4; 12222 else if (!strncasecmp(t, "sips:", 5)) 12223 t += 5; 12224 ast_string_field_set(p, exten, t); 12225 t = strchr(p->exten, '@'); 12226 if (t) 12227 *t = '\0'; 12228 if (ast_strlen_zero(p->our_contact)) 12229 build_contact(p); 12230 } 12231 /* save the URI part of the From header */ 12232 ast_string_field_set(p, from, of); 12233 12234 of2 = ast_strdupa(of); 12235 12236 /* ignore all fields but name */ 12237 if (p->socket.type == SIP_TRANSPORT_TLS) { 12238 if (parse_uri(of, "sips:", &of, &dummy, &domain, &dummy, &dummy, NULL)) { 12239 if (parse_uri(of2, "sip:", &of, &dummy, &domain, &dummy, &dummy, NULL)) 12240 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 12241 } 12242 } else { 12243 if (parse_uri(of, "sip:", &of, &dummy, &domain, &dummy, &dummy, NULL)) 12244 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 12245 } 12246 12247 if (ast_strlen_zero(of)) { 12248 /* XXX note: the original code considered a missing @host 12249 * as a username-only URI. The SIP RFC (19.1.1) says that 12250 * this is wrong, and it should be considered as a domain-only URI. 12251 * For backward compatibility, we keep this block, but it is 12252 * really a mistake and should go away. 12253 */ 12254 of = domain; 12255 } 12256 { 12257 char *tmp = ast_strdupa(of); 12258 /* We need to be able to handle auth-headers looking like 12259 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 12260 */ 12261 tmp = strsep(&tmp, ";"); 12262 if (ast_is_shrinkable_phonenumber(tmp)) 12263 ast_shrink_phone_number(tmp); 12264 ast_string_field_set(p, cid_num, tmp); 12265 } 12266 12267 if (global_match_auth_username) { 12268 /* 12269 * XXX This is experimental code to grab the search key from the 12270 * Auth header's username instead of the 'From' name, if available. 12271 * Do not enable this block unless you understand the side effects (if any!) 12272 * Note, the search for "username" should be done in a more robust way. 12273 * Note2, at the moment we check both fields, though maybe we should 12274 * pick one or another depending on the request ? XXX 12275 */ 12276 const char *hdr = get_header(req, "Authorization"); 12277 if (ast_strlen_zero(hdr)) 12278 hdr = get_header(req, "Proxy-Authorization"); 12279 12280 if ( !ast_strlen_zero(hdr) && (hdr = strstr(hdr, "username=\"")) ) { 12281 ast_copy_string(from, hdr + strlen("username=\""), sizeof(from)); 12282 of = from; 12283 of = strsep(&of, "\""); 12284 } 12285 } 12286 12287 if (!authpeer) { 12288 /* If we are looking for a peer, don't check the 12289 user objects (or realtime) */ 12290 res = check_user_ok(p, of, req, sipmethod, sin, 12291 reliable, rpid_num, calleridname, uri2); 12292 if (res != AUTH_DONT_KNOW) 12293 return res; 12294 } 12295 12296 res = check_peer_ok(p, of, req, sipmethod, sin, 12297 authpeer, reliable, rpid_num, calleridname, uri2); 12298 if (res != AUTH_DONT_KNOW) 12299 return res; 12300 12301 /* Finally, apply the guest policy */ 12302 if (global_allowguest) { 12303 replace_cid(p, rpid_num, calleridname); 12304 res = AUTH_SUCCESSFUL; 12305 } else if (global_alwaysauthreject) 12306 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 12307 else 12308 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 12309 12310 12311 if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT)) { 12312 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 12313 } 12314 12315 return res; 12316 }
static enum check_auth_result check_user_ok | ( | struct sip_pvt * | p, | |
char * | of, | |||
struct sip_request * | req, | |||
int | sipmethod, | |||
struct sockaddr_in * | sin, | |||
enum xmittype | reliable, | |||
char * | rpid_num, | |||
char * | calleridname, | |||
char * | uri2 | |||
) | [static] |
Validate user authentication.
Definition at line 11921 of file chan_sip.c.
References sip_pvt::allowtransfer, sip_pvt::amaflags, ast_apply_ha(), ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_is_shrinkable_phonenumber(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), AUTH_DONT_KNOW, sip_pvt::autoframing, sip_pvt::callgroup, sip_pvt::callingpres, sip_pvt::capability, sip_pvt::chanvars, check_auth(), copy_vars(), debug, do_setnat(), find_user(), sip_pvt::flags, sip_request::ignore, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::maxcallbitrate, sip_pvt::noncodeccapability, t38properties::peercapability, sip_pvt::peercapability, sip_pvt::pickupgroup, sip_pvt::prefs, replace_cid(), sip_pvt::rtp, SIP_CALL_LIMIT, sip_cancel_destroy(), sip_debug_test_addr(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, sip_pvt::sipoptions, sip_pvt::t38, sip_pvt::trtp, unref_user(), user, and sip_pvt::vrtp.
Referenced by check_user_full().
11925 { 11926 enum check_auth_result res; 11927 struct sip_user *user = find_user(of, 1); 11928 int debug=sip_debug_test_addr(sin); 11929 11930 /* Find user based on user name in the from header */ 11931 if (!user) { 11932 if (debug) 11933 ast_verbose("No user '%s' in SIP users list\n", of); 11934 return AUTH_DONT_KNOW; 11935 } 11936 if (!ast_apply_ha(user->ha, sin)) { 11937 if (debug) 11938 ast_verbose("Found user '%s' for '%s', but fails host access\n", 11939 user->name, of); 11940 unref_user(user); 11941 return AUTH_DONT_KNOW; 11942 } 11943 if (debug) 11944 ast_verbose("Found user '%s' for '%s'\n", user->name, of); 11945 11946 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 11947 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 11948 if (sipmethod == SIP_INVITE) { 11949 /* copy channel vars */ 11950 p->chanvars = copy_vars(user->chanvars); 11951 } 11952 p->prefs = user->prefs; 11953 /* Set Frame packetization */ 11954 if (p->rtp) { 11955 ast_rtp_codec_setpref(p->rtp, &p->prefs); 11956 p->autoframing = user->autoframing; 11957 } 11958 11959 replace_cid(p, rpid_num, calleridname); 11960 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 11961 11962 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, req->ignore))) { 11963 sip_cancel_destroy(p); 11964 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 11965 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 11966 /* Copy SIP extensions profile from INVITE */ 11967 if (p->sipoptions) 11968 user->sipoptions = p->sipoptions; 11969 11970 /* If we have a call limit, set flag */ 11971 if (user->call_limit) 11972 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 11973 if (!ast_strlen_zero(user->context)) 11974 ast_string_field_set(p, context, user->context); 11975 if (!ast_strlen_zero(user->cid_num)) { 11976 char *tmp = ast_strdupa(user->cid_num); 11977 if (ast_is_shrinkable_phonenumber(tmp)) 11978 ast_shrink_phone_number(tmp); 11979 ast_string_field_set(p, cid_num, tmp); 11980 } 11981 if (!ast_strlen_zero(user->cid_name)) 11982 ast_string_field_set(p, cid_name, user->cid_name); 11983 ast_string_field_set(p, username, user->name); 11984 ast_string_field_set(p, peername, user->name); 11985 ast_string_field_set(p, peersecret, user->secret); 11986 ast_string_field_set(p, peermd5secret, user->md5secret); 11987 ast_string_field_set(p, subscribecontext, user->subscribecontext); 11988 ast_string_field_set(p, accountcode, user->accountcode); 11989 ast_string_field_set(p, language, user->language); 11990 ast_string_field_set(p, mohsuggest, user->mohsuggest); 11991 ast_string_field_set(p, mohinterpret, user->mohinterpret); 11992 p->allowtransfer = user->allowtransfer; 11993 p->amaflags = user->amaflags; 11994 p->callgroup = user->callgroup; 11995 p->pickupgroup = user->pickupgroup; 11996 if (user->callingpres) /* User callingpres setting will override RPID header */ 11997 p->callingpres = user->callingpres; 11998 11999 /* Set default codec settings for this call */ 12000 p->capability = user->capability; /* User codec choice */ 12001 p->jointcapability = user->capability; /* Our codecs */ 12002 if (p->peercapability) /* AND with peer's codecs */ 12003 p->jointcapability &= p->peercapability; 12004 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 12005 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 12006 p->noncodeccapability |= AST_RTP_DTMF; 12007 else 12008 p->noncodeccapability &= ~AST_RTP_DTMF; 12009 p->jointnoncodeccapability = p->noncodeccapability; 12010 if (p->t38.peercapability) 12011 p->t38.jointcapability &= p->t38.peercapability; 12012 p->maxcallbitrate = user->maxcallbitrate; 12013 /* If we do not support video, remove video from call structure */ 12014 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 12015 ast_rtp_destroy(p->vrtp); 12016 p->vrtp = NULL; 12017 } 12018 /* If we do not support text, remove text from call structure */ 12019 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_TEXTSUPPORT) && p->trtp) { 12020 ast_rtp_destroy(p->trtp); 12021 p->trtp = NULL; 12022 } 12023 } 12024 unref_user(user); 12025 return res; 12026 }
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 11764 of file chan_sip.c.
References ahp, ast_copy_string(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_skip_blanks(), ast_verbose(), sip_pvt::flags, get_header(), hp, LOG_WARNING, sip_pvt::sa, sip_debug_test_pvt(), sip_nat_mode(), SIP_PAGE2_RPORT_PRESENT, sip_real_dst(), and STANDARD_SIP_PORT.
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), and handle_request_subscribe().
11765 { 11766 char via[512]; 11767 char *c, *pt; 11768 struct hostent *hp; 11769 struct ast_hostent ahp; 11770 11771 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 11772 11773 /* Work on the leftmost value of the topmost Via header */ 11774 c = strchr(via, ','); 11775 if (c) 11776 *c = '\0'; 11777 11778 /* Check for rport */ 11779 c = strstr(via, ";rport"); 11780 if (c && (c[6] != '=')) /* rport query, not answer */ 11781 ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT); 11782 11783 c = strchr(via, ';'); 11784 if (c) 11785 *c = '\0'; 11786 11787 c = strchr(via, ' '); 11788 if (c) { 11789 *c = '\0'; 11790 c = ast_skip_blanks(c+1); 11791 if (strcasecmp(via, "SIP/2.0/UDP") && strcasecmp(via, "SIP/2.0/TCP") && strcasecmp(via, "SIP/2.0/TLS")) { 11792 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 11793 return; 11794 } 11795 pt = strchr(c, ':'); 11796 if (pt) 11797 *pt++ = '\0'; /* remember port pointer */ 11798 hp = ast_gethostbyname(c, &ahp); 11799 if (!hp) { 11800 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 11801 return; 11802 } 11803 memset(&p->sa, 0, sizeof(p->sa)); 11804 p->sa.sin_family = AF_INET; 11805 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 11806 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 11807 11808 if (sip_debug_test_pvt(p)) { 11809 const struct sockaddr_in *dst = sip_real_dst(p); 11810 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 11811 } 11812 } 11813 }
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 externip/seternaddr/stunaddr.
Definition at line 11734 of file chan_sip.c.
References ast_copy_string(), ast_parse_arg(), get_header(), sip_pvt::ourip, PARSE_INADDR, and strsep().
11735 { 11736 char via[256]; 11737 char *cur, *opts; 11738 11739 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 11740 11741 /* Work on the leftmost value of the topmost Via header */ 11742 opts = strchr(via, ','); 11743 if (opts) 11744 *opts = '\0'; 11745 11746 /* parse all relevant options */ 11747 opts = strchr(via, ';'); 11748 if (!opts) 11749 return; /* no options to parse */ 11750 *opts++ = '\0'; 11751 while ( (cur = strsep(&opts, ";")) ) { 11752 if (!strncmp(cur, "rport=", 6)) { 11753 int port = strtol(cur+6, NULL, 10); 11754 /* XXX add error checking */ 11755 p->ourip.sin_port = ntohs(port); 11756 } else if (!strncmp(cur, "received=", 9)) { 11757 if (ast_parse_arg(cur+9, PARSE_INADDR, &p->ourip)) 11758 ; /* XXX add error checking */ 11759 } 11760 } 11761 }
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 12956 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), ast_copy_string(), AST_MAX_CONTEXT, and strsep().
Referenced by reload_config().
12957 { 12958 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 12959 12960 while ((oldcontext = strsep(&old, "&"))) { 12961 stalecontext = '\0'; 12962 ast_copy_string(newlist, new, sizeof(newlist)); 12963 stringp = newlist; 12964 while ((newcontext = strsep(&stringp, "&"))) { 12965 if (!strcmp(newcontext, oldcontext)) { 12966 /* This is not the context you're looking for */ 12967 stalecontext = '\0'; 12968 break; 12969 } else if (strcmp(newcontext, oldcontext)) { 12970 stalecontext = oldcontext; 12971 } 12972 12973 } 12974 if (stalecontext) 12975 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 12976 } 12977 }
static void clear_peer_mailboxes | ( | struct sip_peer * | peer | ) | [static] |
Destroy all peer-related mailbox subscriptions
Definition at line 3630 of file chan_sip.c.
References AST_LIST_REMOVE_HEAD, destroy_mailbox(), sip_mailbox::entry, mailbox, and sip_peer::mailboxes.
Referenced by set_peer_defaults(), and sip_destroy_peer().
03631 { 03632 struct sip_mailbox *mailbox; 03633 03634 while ((mailbox = AST_LIST_REMOVE_HEAD(&peer->mailboxes, entry))) 03635 destroy_mailbox(mailbox); 03636 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 20790 of file chan_sip.c.
References ast_free, and sip_auth::next.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
20791 { 20792 struct sip_auth *a = authlist; 20793 struct sip_auth *b; 20794 20795 while (a) { 20796 b = a; 20797 a = a->next; 20798 ast_free(b); 20799 } 20800 20801 return 1; 20802 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 20721 of file chan_sip.c.
References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and domain::list.
Referenced by reload_config(), and unload_module().
20722 { 20723 struct domain *d; 20724 20725 AST_LIST_LOCK(&domain_list); 20726 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 20727 ast_free(d); 20728 AST_LIST_UNLOCK(&domain_list); 20729 }
static const char* cli_yesno | ( | int | x | ) | [static] |
return Yes or No depending on the argument. This is used in many places in CLI command, having a function to generate this helps maintaining a consistent output (and possibly emitting the output in other languages, at some point).
Definition at line 12545 of file chan_sip.c.
Referenced by _sip_show_peer(), show_channels_cb(), sip_show_channel(), sip_show_settings(), sip_show_user(), and sip_show_users().
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 14011 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, and peerl.
Referenced by complete_sip_show_peer(), complete_sipnotify(), sip_do_debug(), and sip_prune_realtime().
14012 { 14013 char *result = NULL; 14014 int wordlen = strlen(word); 14015 int which = 0; 14016 14017 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 14018 /* locking of the object is not required because only the name and flags are being compared */ 14019 if (!strncasecmp(word, iterator->name, wordlen) && 14020 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 14021 ++which > state) 14022 result = ast_strdup(iterator->name); 14023 } while(0) ); 14024 return result; 14025 }
static char * complete_sip_registered_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on registered peer name.
Definition at line 14028 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, and peerl.
Referenced by complete_sip_unregister().
14029 { 14030 char *result = NULL; 14031 int wordlen = strlen(word); 14032 int which = 0; 14033 14034 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 14035 ASTOBJ_WRLOCK(iterator); 14036 if (!strncasecmp(word, iterator->name, wordlen) && 14037 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 14038 ++which > state && iterator->expire > 0) 14039 result = ast_strdup(iterator->name); 14040 ASTOBJ_UNLOCK(iterator); 14041 } while(0) ); 14042 return result; 14043 }
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 14046 of file chan_sip.c.
References complete_sipch().
Referenced by sip_show_history().
14047 { 14048 if (pos == 3) 14049 return complete_sipch(line, word, pos, state); 14050 14051 return NULL; 14052 }
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 14055 of file chan_sip.c.
References complete_sip_peer().
Referenced by sip_show_peer().
14056 { 14057 if (pos == 3) 14058 return complete_sip_peer(word, state, 0); 14059 14060 return NULL; 14061 }
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 14093 of file chan_sip.c.
References complete_sip_user().
Referenced by sip_show_user().
14094 { 14095 if (pos == 3) 14096 return complete_sip_user(word, state, 0); 14097 14098 return NULL; 14099 }
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 14064 of file chan_sip.c.
References complete_sip_registered_peer().
Referenced by sip_unregister().
14065 { 14066 if (pos == 2) 14067 return complete_sip_registered_peer(word, state, 0); 14068 14069 return NULL; 14070 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 14073 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, and userl.
Referenced by complete_sip_show_user(), and sip_prune_realtime().
14074 { 14075 char *result = NULL; 14076 int wordlen = strlen(word); 14077 int which = 0; 14078 14079 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 14080 /* locking of the object is not required because only the name and flags are being compared */ 14081 if (!strncasecmp(word, iterator->name, wordlen)) { 14082 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 14083 continue; 14084 if (++which > state) { 14085 result = ast_strdup(iterator->name); 14086 } 14087 } 14088 } while(0) ); 14089 return result; 14090 }
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 13988 of file chan_sip.c.
References ast_strdup, sip_pvt::callid, dialoglist, dialoglist_lock(), and sip_pvt::next.
Referenced by complete_sip_show_history(), and sip_show_channel().
13989 { 13990 int which=0; 13991 struct sip_pvt *cur; 13992 char *c = NULL; 13993 int wordlen = strlen(word); 13994 13995 if (pos != 3) { 13996 return NULL; 13997 } 13998 13999 dialoglist_lock(); 14000 for (cur = dialoglist; cur; cur = cur->next) { 14001 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 14002 c = ast_strdup(cur->callid); 14003 break; 14004 } 14005 } 14006 dialoglist_unlock(); 14007 return c; 14008 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 14102 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
Referenced by sip_notify().
14103 { 14104 char *c = NULL; 14105 14106 if (pos == 2) { 14107 int which = 0; 14108 char *cat = NULL; 14109 int wordlen = strlen(word); 14110 14111 /* do completion for notify type */ 14112 14113 if (!notify_types) 14114 return NULL; 14115 14116 while ( (cat = ast_category_browse(notify_types, cat)) ) { 14117 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 14118 c = ast_strdup(cat); 14119 break; 14120 } 14121 } 14122 return c; 14123 } 14124 14125 if (pos > 2) 14126 return complete_sip_peer(word, state, 0); 14127 14128 return NULL; 14129 }
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 7546 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
07547 { 07548 int start = 0; 07549 int copied = 0; 07550 for (;;) { 07551 const char *tmp = __get_header(orig, field, &start); 07552 07553 if (ast_strlen_zero(tmp)) 07554 break; 07555 /* Add what we're responding to */ 07556 add_header(req, field, tmp); 07557 copied++; 07558 } 07559 return copied ? 0 : -1; 07560 }
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 7535 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
07536 { 07537 const char *tmp = get_header(orig, field); 07538 07539 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 07540 return add_header(req, field, tmp); 07541 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 07542 return -1; 07543 }
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 8817 of file chan_sip.c.
Referenced by handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), queue_request(), sip_park(), and sip_park_thread().
08818 { 08819 long offset; 08820 int x; 08821 offset = ((void *)dst) - ((void *)src); 08822 /* First copy stuff */ 08823 memcpy(dst, src, sizeof(*dst)); 08824 /* Now fix pointer arithmetic */ 08825 for (x=0; x < src->headers; x++) 08826 dst->header[x] += offset; 08827 for (x=0; x < src->lines; x++) 08828 dst->line[x] += offset; 08829 dst->rlPart1 += offset; 08830 dst->rlPart2 += offset; 08831 }
static void copy_socket_data | ( | struct sip_socket * | to_sock, | |
const struct sip_socket * | from_sock | |||
) | [static] |
Definition at line 4087 of file chan_sip.c.
References ao2_ref(), and sip_socket::tcptls_session.
Referenced by create_addr_from_peer(), handle_request_do(), parse_register_contact(), sip_poke_peer(), and transmit_response_using_temp().
04088 { 04089 if (to_sock->tcptls_session) { 04090 ao2_ref(to_sock->tcptls_session, -1); 04091 to_sock->tcptls_session = NULL; 04092 } 04093 04094 if (from_sock->tcptls_session) { 04095 ao2_ref(from_sock->tcptls_session, +1); 04096 } 04097 04098 *to_sock = *from_sock; 04099 }
static struct ast_variable* copy_vars | ( | struct ast_variable * | src | ) | [static] |
duplicate a list of channel variables,
Definition at line 11893 of file chan_sip.c.
References ast_variable_new(), and ast_variable::next.
Referenced by check_peer_ok(), and check_user_ok().
11894 { 11895 struct ast_variable *res = NULL, *tmp, *v = NULL; 11896 11897 for (v = src ; v ; v = v->next) { 11898 if ((tmp = ast_variable_new(v->name, v->value, v->file))) { 11899 tmp->next = res; 11900 res = tmp; 11901 } 11902 } 11903 return res; 11904 }
static int copy_via_headers | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
const struct sip_request * | orig, | |||
const char * | field | |||
) | [static] |
Copy SIP VIA Headers from the request to the response.
We always add ;received=<ip address> to the topmost via header.
Definition at line 7570 of file chan_sip.c.
References __get_header(), add_header(), ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_test_flag, sip_pvt::flags, LOG_NOTICE, sip_pvt::recv, SIP_NAT, SIP_NAT_ALWAYS, and SIP_NAT_RFC3581.
Referenced by respprep().
07571 { 07572 int copied = 0; 07573 int start = 0; 07574 07575 for (;;) { 07576 char new[512]; 07577 const char *oh = __get_header(orig, field, &start); 07578 07579 if (ast_strlen_zero(oh)) 07580 break; 07581 07582 if (!copied) { /* Only check for empty rport in topmost via header */ 07583 char leftmost[512], *others, *rport; 07584 07585 /* Only work on leftmost value */ 07586 ast_copy_string(leftmost, oh, sizeof(leftmost)); 07587 others = strchr(leftmost, ','); 07588 if (others) 07589 *others++ = '\0'; 07590 07591 /* Find ;rport; (empty request) */ 07592 rport = strstr(leftmost, ";rport"); 07593 if (rport && *(rport+6) == '=') 07594 rport = NULL; /* We already have a parameter to rport */ 07595 07596 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 07597 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 07598 /* We need to add received port - rport */ 07599 char *end; 07600 07601 rport = strstr(leftmost, ";rport"); 07602 07603 if (rport) { 07604 end = strchr(rport + 1, ';'); 07605 if (end) 07606 memmove(rport, end, strlen(end) + 1); 07607 else 07608 *rport = '\0'; 07609 } 07610 07611 /* Add rport to first VIA header if requested */ 07612 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 07613 leftmost, ast_inet_ntoa(p->recv.sin_addr), 07614 ntohs(p->recv.sin_port), 07615 others ? "," : "", others ? others : ""); 07616 } else { 07617 /* We should *always* add a received to the topmost via */ 07618 snprintf(new, sizeof(new), "%s;received=%s%s%s", 07619 leftmost, ast_inet_ntoa(p->recv.sin_addr), 07620 others ? "," : "", others ? others : ""); 07621 } 07622 oh = new; /* the header to copy */ 07623 } /* else add the following via headers untouched */ 07624 add_header(req, field, oh); 07625 copied++; 07626 } 07627 if (!copied) { 07628 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 07629 return -1; 07630 } 07631 return 0; 07632 }
static int create_addr | ( | struct sip_pvt * | dialog, | |
const char * | opeer, | |||
int | newdialog | |||
) | [static] |
create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success
Definition at line 4241 of file chan_sip.c.
References ahp, ast_copy_string(), ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, bindaddr, create_addr_from_peer(), do_setnat(), find_peer(), sip_pvt::flags, get_transport(), hp, LOG_WARNING, MAXHOSTNAMELEN, obproxy_get(), sip_pvt::outboundproxy, sip_socket::port, sip_pvt::recv, sip_pvt::sa, service, set_socket_transport(), SIP_NAT, SIP_NAT_ROUTE, SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, sip_pvt::socket, STANDARD_SIP_PORT, STANDARD_TLS_PORT, sip_pvt::timer_b, sip_pvt::timer_t1, sip_socket::type, and unref_peer().
04242 { 04243 struct hostent *hp; 04244 struct ast_hostent ahp; 04245 struct sip_peer *peer; 04246 char *port; 04247 int portno = 0; 04248 char host[MAXHOSTNAMELEN], *hostn; 04249 char peername[256]; 04250 04251 ast_copy_string(peername, opeer, sizeof(peername)); 04252 port = strchr(peername, ':'); 04253 if (port) 04254 *port++ = '\0'; 04255 dialog->sa.sin_family = AF_INET; 04256 dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */ 04257 dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */ 04258 peer = find_peer(peername, NULL, 1, 0); 04259 04260 if (peer) { 04261 int res; 04262 if (newdialog) { 04263 set_socket_transport(&dialog->socket, 0); 04264 } 04265 res = create_addr_from_peer(dialog, peer); 04266 unref_peer(peer); 04267 if (!ast_strlen_zero(port)) { 04268 if ((portno = atoi(port))) { 04269 dialog->sa.sin_port = dialog->recv.sin_port = htons(portno); 04270 } 04271 } 04272 return res; 04273 } 04274 04275 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04276 04277 ast_string_field_set(dialog, tohost, peername); 04278 04279 /* Get the outbound proxy information */ 04280 dialog->outboundproxy = obproxy_get(dialog, NULL); 04281 04282 /* Let's see if we can find the host in DNS. First try DNS SRV records, 04283 then hostname lookup */ 04284 /*! \todo Fix this function. When we ask SRC, we should check all transports 04285 In the future, we should first check NAPTR to find out transport preference 04286 */ 04287 04288 hostn = peername; 04289 /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then 04290 * an A record lookup should be used instead of SRV. 04291 */ 04292 if (!port && global_srvlookup) { 04293 char service[MAXHOSTNAMELEN]; 04294 int tportno; 04295 int ret; 04296 04297 snprintf(service, sizeof(service), "_sip._%s.%s", get_transport(dialog->socket.type), peername); 04298 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 04299 if (ret > 0) { 04300 hostn = host; 04301 portno = tportno; 04302 } 04303 } 04304 if (!portno) 04305 portno = port ? atoi(port) : (dialog->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT; 04306 hp = ast_gethostbyname(hostn, &ahp); 04307 if (!hp) { 04308 ast_log(LOG_WARNING, "No such host: %s\n", peername); 04309 return -1; 04310 } 04311 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 04312 if (ast_strlen_zero(port) || sscanf(port, "%u", &portno) != 1) { 04313 portno = (dialog->socket.type & SIP_TRANSPORT_TLS) ? 04314 STANDARD_TLS_PORT : STANDARD_SIP_PORT; 04315 } 04316 04317 if (!dialog->socket.type) 04318 set_socket_transport(&dialog->socket, SIP_TRANSPORT_UDP); 04319 if (!dialog->socket.port) 04320 dialog->socket.port = bindaddr.sin_port; 04321 04322 dialog->sa.sin_port = htons(portno); 04323 dialog->recv = dialog->sa; 04324 return 0; 04325 }
Create address structure from peer reference. This function copies data from peer to the dialog, so we don't have to look up the peer again from memory or database during the life time of the dialog.
Definition at line 4107 of file chan_sip.c.
References sip_peer::addr, sip_peer::allowtransfer, sip_pvt::allowtransfer, ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_destroy(), ast_udptl_new_with_bindaddr(), sip_peer::auth, sip_peer::autoframing, sip_pvt::autoframing, bindaddr, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, sip_pvt::callid, t38properties::capability, sip_peer::capability, sip_pvt::capability, check_request_transport, sip_peer::context, copy_socket_data(), sip_peer::defaddr, do_setnat(), sip_peer::flags, sip_pvt::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_request::headers, sip_pvt::initreq, io, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, sip_peer::language, sip_peer::lastms, sip_peer::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, sip_peer::name, sip_pvt::noncodeccapability, obproxy_get(), sip_pvt::outboundproxy, sip_pvt::peerauth, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_pvt::rtptimeout, sip_peer::rtptimeout, sip_pvt::sa, sched, sip_peer::secret, set_t38_capabilities(), SIP_CALL_LIMIT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_NAT, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, sip_peer::socket, sip_pvt::socket, sip_pvt::t38, t38properties::t38support, sip_pvt::timer_b, sip_peer::timer_b, sip_peer::timer_t1, sip_pvt::timer_t1, sip_pvt::tohost, sip_peer::tohost, sip_pvt::trtp, sip_socket::type, sip_pvt::udptl, sip_peer::username, and sip_pvt::vrtp.
Referenced by create_addr(), and sip_send_mwi_to_peer().
04108 { 04109 /* this checks that the dialog is contacting the peer on a valid 04110 * transport type based on the peers transport configuration, 04111 * otherwise, this function bails out */ 04112 if (dialog->socket.type && check_request_transport(peer, dialog)) 04113 return -1; 04114 copy_socket_data(&dialog->socket, &peer->socket); 04115 04116 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 04117 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 04118 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 04119 dialog->recv = dialog->sa; 04120 } else 04121 return -1; 04122 04123 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 04124 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04125 dialog->capability = peer->capability; 04126 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 04127 ast_rtp_destroy(dialog->vrtp); 04128 dialog->vrtp = NULL; 04129 } 04130 if (!ast_test_flag(&dialog->flags[1], SIP_PAGE2_TEXTSUPPORT) && dialog->trtp) { 04131 ast_rtp_destroy(dialog->trtp); 04132 dialog->trtp = NULL; 04133 } 04134 dialog->prefs = peer->prefs; 04135 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 04136 if (!dialog->udptl) { 04137 /* t38pt_udptl was enabled in the peer and not in [general] */ 04138 dialog->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04139 } 04140 ast_copy_flags(&dialog->t38.t38support, &peer->flags[1], SIP_PAGE2_T38SUPPORT); 04141 set_t38_capabilities(dialog); 04142 dialog->t38.jointcapability = dialog->t38.capability; 04143 } else if (dialog->udptl) { 04144 ast_udptl_destroy(dialog->udptl); 04145 dialog->udptl = NULL; 04146 } 04147 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04148 04149 if (dialog->rtp) { /* Audio */ 04150 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04151 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04152 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 04153 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 04154 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 04155 /* Set Frame packetization */ 04156 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 04157 dialog->autoframing = peer->autoframing; 04158 } 04159 if (dialog->vrtp) { /* Video */ 04160 ast_rtp_setdtmf(dialog->vrtp, 0); 04161 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 04162 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 04163 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 04164 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 04165 } 04166 if (dialog->trtp) { /* Realtime text */ 04167 ast_rtp_setdtmf(dialog->trtp, 0); 04168 ast_rtp_setdtmfcompensate(dialog->trtp, 0); 04169 ast_rtp_set_rtptimeout(dialog->trtp, peer->rtptimeout); 04170 ast_rtp_set_rtpholdtimeout(dialog->trtp, peer->rtpholdtimeout); 04171 ast_rtp_set_rtpkeepalive(dialog->trtp, peer->rtpkeepalive); 04172 } 04173 04174 ast_string_field_set(dialog, peername, peer->name); 04175 ast_string_field_set(dialog, authname, peer->username); 04176 ast_string_field_set(dialog, username, peer->username); 04177 ast_string_field_set(dialog, peersecret, peer->secret); 04178 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 04179 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 04180 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 04181 ast_string_field_set(dialog, tohost, peer->tohost); 04182 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 04183 ast_string_field_set(dialog, context, peer->context); 04184 dialog->outboundproxy = obproxy_get(dialog, peer); 04185 dialog->callgroup = peer->callgroup; 04186 dialog->pickupgroup = peer->pickupgroup; 04187 dialog->allowtransfer = peer->allowtransfer; 04188 dialog->jointnoncodeccapability = dialog->noncodeccapability; 04189 dialog->rtptimeout = peer->rtptimeout; 04190 dialog->peerauth = peer->auth; 04191 dialog->maxcallbitrate = peer->maxcallbitrate; 04192 if (ast_strlen_zero(dialog->tohost)) 04193 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 04194 if (!ast_strlen_zero(peer->fromdomain)) { 04195 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 04196 if (!dialog->initreq.headers) { 04197 char *c; 04198 char *tmpcall = ast_strdupa(dialog->callid); 04199 04200 c = strchr(tmpcall, '@'); 04201 if (c) { 04202 *c = '\0'; 04203 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 04204 } 04205 } 04206 } 04207 if (!ast_strlen_zero(peer->fromuser)) 04208 ast_string_field_set(dialog, fromuser, peer->fromuser); 04209 if (!ast_strlen_zero(peer->language)) 04210 ast_string_field_set(dialog, language, peer->language); 04211 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 04212 /* Minimum is settable or default to 100 ms */ 04213 /* If there is a maxms and lastms from a qualify use that over a manual T1 04214 value. Otherwise, use the peer's T1 value. */ 04215 if (peer->maxms && peer->lastms) 04216 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 04217 else 04218 dialog->timer_t1 = peer->timer_t1; 04219 04220 /* Set timer B to control transaction timeouts, the peer setting is the default and overrides 04221 the known timer */ 04222 if (peer->timer_b) 04223 dialog->timer_b = peer->timer_b; 04224 else 04225 dialog->timer_b = 64 * dialog->timer_t1; 04226 04227 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04228 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04229 dialog->noncodeccapability |= AST_RTP_DTMF; 04230 else 04231 dialog->noncodeccapability &= ~AST_RTP_DTMF; 04232 if (peer->call_limit) 04233 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 04234 04235 return 0; 04236 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 10116 of file chan_sip.c.
References ast_check_realtime(), ast_db_del(), ast_update_realtime(), sip_peer::deprecated_username, sip_settings::ignore_regexpire, sip_peer::name, sip_settings::peer_rtupdate, sip_peer::rt_fromcontact, and sip_cfg.
Referenced by build_peer(), expire_register(), and parse_register_contact().
10117 { 10118 int realtimeregs = ast_check_realtime("sipregs"); 10119 char *tablename = (realtimeregs) ? "sipregs" : "sippeers"; 10120 10121 if (!sip_cfg.ignore_regexpire) { 10122 if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) { 10123 ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", peer->deprecated_username ? "username" : "defaultuser", "", "regserver", "", NULL); 10124 ast_update_realtime(tablename, "name", peer->name, "lastms", "", NULL); 10125 } else { 10126 ast_db_del("SIP/Registry", peer->name); 10127 } 10128 } 10129 }
static void destroy_mailbox | ( | struct sip_mailbox * | mailbox | ) | [static] |
Destroy mailbox subscriptions
Definition at line 3618 of file chan_sip.c.
References ast_event_unsubscribe(), ast_free, and mailbox.
Referenced by clear_peer_mailboxes().
03619 { 03620 if (mailbox->mailbox) 03621 ast_free(mailbox->mailbox); 03622 if (mailbox->context) 03623 ast_free(mailbox->context); 03624 if (mailbox->event_sub) 03625 ast_event_unsubscribe(mailbox->event_sub); 03626 ast_free(mailbox); 03627 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 8864 of file chan_sip.c.
References ast_debug, ast_skip_blanks(), ast_skip_nonblanks(), ast_trim_blanks(), sip_request::header, sip_request::rlPart1, and sip_request::rlPart2.
08865 { 08866 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 08867 08868 if (!*e) 08869 return -1; 08870 req->rlPart1 = e; /* method or protocol */ 08871 e = ast_skip_nonblanks(e); 08872 if (*e) 08873 *e++ = '\0'; 08874 /* Get URI or status code */ 08875 e = ast_skip_blanks(e); 08876 if ( !*e ) 08877 return -1; 08878 ast_trim_blanks(e); 08879 08880 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 08881 if (strlen(e) < 3) /* status code is 3 digits */ 08882 return -1; 08883 req->rlPart2 = e; 08884 } else { /* We have a request */ 08885 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 08886 ast_debug(3, "Oops. Bogus uri in <> %s\n", e); 08887 e++; 08888 if (!*e) 08889 return -1; 08890 } 08891 req->rlPart2 = e; /* URI */ 08892 e = ast_skip_nonblanks(e); 08893 if (*e) 08894 *e++ = '\0'; 08895 e = ast_skip_blanks(e); 08896 if (strcasecmp(e, "SIP/2.0") ) { 08897 ast_debug(3, "Skipping packet - Bad request protocol %s\n", e); 08898 return -1; 08899 } 08900 } 08901 return 1; 08902 }
when we create or delete references, make sure to use these functions so we keep track of the refcounts. To simplify the code, we allow a NULL to be passed to dialog_unref().
Definition at line 1367 of file chan_sip.c.
Referenced by __sip_reliable_xmit(), handle_response_invite(), sip_alloc(), sip_call(), sip_new(), sip_scheddestroy(), sip_send_mwi_to_peer(), and transmit_register().
Definition at line 1372 of file chan_sip.c.
Referenced by __sip_ack(), __sip_autodestruct(), __sip_destroy(), auto_congest(), get_also_info(), handle_invite_replaces(), handle_request_invite(), handle_response_peerpoke(), sip_cancel_destroy(), sip_hangup(), sip_notify(), sip_reg_timeout(), and sip_reinvite_retry().
static void dialoglist_lock | ( | void | ) | [static] |
hide the way the list is locked/unlocked
Definition at line 1342 of file chan_sip.c.
References ast_mutex_lock(), and dialoglock.
Referenced by __sip_destroy(), complete_sipch(), do_monitor(), find_call(), get_sip_pvt_byid_locked(), handle_request_subscribe(), sip_alloc(), sip_show_channel(), sip_show_channels(), sip_show_history(), and unload_module().
01343 { 01344 ast_mutex_lock(&dialoglock); 01345 }
static void dialoglist_unlock | ( | void | ) | [static] |
Definition at line 1347 of file chan_sip.c.
References ast_mutex_unlock(), and dialoglock.
Referenced by __sip_destroy(), do_monitor(), handle_request_subscribe(), sip_alloc(), sip_show_channels(), and unload_module().
01348 { 01349 ast_mutex_unlock(&dialoglock); 01350 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 19717 of file chan_sip.c.
References __sip_destroy(), 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, check_rtp_timeout(), dialoglist, dialoglist_lock(), dialoglist_unlock(), FALSE, io, monlock, sip_pvt::next, sched, sip_do_reload(), sip_pvt_trylock, sip_pvt_unlock, sip_reload_lock, sipsock, sipsock_read(), and TRUE.
19718 { 19719 int res; 19720 struct sip_pvt *dialog; 19721 time_t t; 19722 int reloading; 19723 19724 /* Add an I/O event to our SIP UDP socket */ 19725 if (sipsock > -1) 19726 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 19727 19728 /* From here on out, we die whenever asked */ 19729 for(;;) { 19730 /* Check for a reload request */ 19731 ast_mutex_lock(&sip_reload_lock); 19732 reloading = sip_reloading; 19733 sip_reloading = FALSE; 19734 ast_mutex_unlock(&sip_reload_lock); 19735 if (reloading) { 19736 ast_verb(1, "Reloading SIP\n"); 19737 sip_do_reload(sip_reloadreason); 19738 19739 /* Change the I/O fd of our UDP socket */ 19740 if (sipsock > -1) { 19741 if (sipsock_read_id) 19742 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 19743 else 19744 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 19745 } else if (sipsock_read_id) { 19746 ast_io_remove(io, sipsock_read_id); 19747 sipsock_read_id = NULL; 19748 } 19749 } 19750 19751 restartsearch: 19752 /* Check for dialogs needing to be killed */ 19753 dialoglist_lock(); 19754 t = time(NULL); 19755 /* don't scan the dialogs list if it hasn't been a reasonable period 19756 of time since the last time we did it (when MWI is being sent, we can 19757 get back to this point every millisecond or less) 19758 */ 19759 for (dialog = dialoglist; dialog; dialog = dialog->next) { 19760 if (sip_pvt_trylock(dialog)) { 19761 dialoglist_unlock(); 19762 usleep(1); 19763 goto restartsearch; 19764 } 19765 19766 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 19767 check_rtp_timeout(dialog, t); 19768 /* If we have sessions that needs to be destroyed, do it now */ 19769 /* Check if we have outstanding requests not responsed to or an active call 19770 - if that's the case, wait with destruction */ 19771 if (dialog->needdestroy && !dialog->packets && !dialog->owner) { 19772 sip_pvt_unlock(dialog); 19773 __sip_destroy(dialog, TRUE, FALSE); 19774 dialoglist_unlock(); 19775 usleep(1); 19776 goto restartsearch; 19777 } 19778 sip_pvt_unlock(dialog); 19779 } 19780 dialoglist_unlock(); 19781 19782 pthread_testcancel(); 19783 /* Wait for sched or io */ 19784 res = ast_sched_wait(sched); 19785 if ((res < 0) || (res > 1000)) 19786 res = 1000; 19787 res = ast_io_wait(io, res); 19788 if (res > 20) 19789 ast_debug(1, "chan_sip: ast_io_wait ran %d all at once\n", res); 19790 ast_mutex_lock(&monlock); 19791 if (res >= 0) { 19792 res = ast_sched_runq(sched); 19793 if (res >= 20) 19794 ast_debug(1, "chan_sip: ast_sched_runq ran %d all at once\n", res); 19795 } 19796 ast_mutex_unlock(&monlock); 19797 } 19798 19799 /* Never reached */ 19800 return NULL; 19801 }
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 14745 of file chan_sip.c.
References ast_calloc, ast_debug, sip_invite_param::auth, auth_headers(), sip_invite_param::authheader, sip_pvt::authtries, sip_pvt::options, reply_digest(), SIP_INVITE, sip_methods, cfsip_methods::text, and transmit_invite().
Referenced by handle_response(), handle_response_invite(), and handle_response_refer().
14746 { 14747 char *header, *respheader; 14748 char digest[1024]; 14749 14750 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 14751 return -2; 14752 14753 p->authtries++; 14754 auth_headers(code, &header, &respheader); 14755 ast_debug(2, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 14756 memset(digest, 0, sizeof(digest)); 14757 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 14758 /* No way to authenticate */ 14759 return -1; 14760 } 14761 /* Now we have a reply digest */ 14762 p->options->auth = digest; 14763 p->options->authheader = respheader; 14764 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 14765 }
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 14721 of file chan_sip.c.
References append_history, ast_verbose(), auth_headers(), sip_pvt::authtries, sip_pvt::do_history, sip_registry::hostname, sip_pvt::registry, reply_digest(), sip_debug_test_pvt(), SIP_REGISTER, and transmit_register().
Referenced by handle_response_register().
14722 { 14723 char *header, *respheader; 14724 char digest[1024]; 14725 14726 p->authtries++; 14727 auth_headers(code, &header, &respheader); 14728 memset(digest, 0, sizeof(digest)); 14729 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 14730 /* There's nothing to use for authentication */ 14731 /* No digest challenge in request */ 14732 if (sip_debug_test_pvt(p) && p->registry) 14733 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 14734 /* No old challenge */ 14735 return -1; 14736 } 14737 if (p->do_history) 14738 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 14739 if (sip_debug_test_pvt(p) && p->registry) 14740 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 14741 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 14742 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 4013 of file chan_sip.c.
References ast_debug, ast_rtp_setnat(), ast_udptl_setnat(), sip_pvt::rtp, sip_pvt::trtp, sip_pvt::udptl, and sip_pvt::vrtp.
Referenced by check_peer_ok(), check_user_ok(), create_addr(), create_addr_from_peer(), sip_alloc(), and transmit_response_using_temp().
04014 { 04015 const char *mode = natflags ? "On" : "Off"; 04016 04017 if (p->rtp) { 04018 ast_debug(1, "Setting NAT on RTP to %s\n", mode); 04019 ast_rtp_setnat(p->rtp, natflags); 04020 } 04021 if (p->vrtp) { 04022 ast_debug(1, "Setting NAT on VRTP to %s\n", mode); 04023 ast_rtp_setnat(p->vrtp, natflags); 04024 } 04025 if (p->udptl) { 04026 ast_debug(1, "Setting NAT on UDPTL to %s\n", mode); 04027 ast_udptl_setnat(p->udptl, natflags); 04028 } 04029 if (p->trtp) { 04030 ast_debug(1, "Setting NAT on TRTP to %s\n", mode); 04031 ast_rtp_setnat(p->trtp, natflags); 04032 } 04033 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 13155 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
13156 { 13157 switch (mode) { 13158 case SIP_DOMAIN_AUTO: 13159 return "[Automatic]"; 13160 case SIP_DOMAIN_CONFIG: 13161 return "[Configured]"; 13162 } 13163 13164 return ""; 13165 }
static const char * dtmfmode2str | ( | int | mode | ) | const [static] |
Convert DTMF mode to printable string.
Definition at line 12928 of file chan_sip.c.
References dtmfstr, and map_x_s().
Referenced by _sip_show_peer(), sip_show_channel(), and sip_show_settings().
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 10144 of file chan_sip.c.
References sip_peer::addr, ast_debug, ast_device_state_changed(), ast_test_flag, ASTOBJ_CONTAINER_UNLINK, sip_peer::default_outbound_transport, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, FALSE, sip_peer::flags, sip_peer::is_realtime, manager_event, sip_peer::name, peerl, register_peer_exten(), sip_peer::selfdestruct, set_socket_transport(), SIP_PAGE2_RTAUTOCLEAR, sip_peer::socket, and unref_peer().
Referenced by parse_register_contact(), reg_source_db(), and sip_unregister().
10145 { 10146 struct sip_peer *peer = (struct sip_peer *)data; 10147 10148 if (!peer) /* Hmmm. We have no peer. Weird. */ 10149 return 0; 10150 10151 memset(&peer->addr, 0, sizeof(peer->addr)); 10152 10153 destroy_association(peer); /* remove registration data from storage */ 10154 set_socket_transport(&peer->socket, peer->default_outbound_transport); 10155 10156 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 10157 register_peer_exten(peer, FALSE); /* Remove regexten */ 10158 peer->expire = -1; 10159 ast_device_state_changed("SIP/%s", peer->name); 10160 10161 /* Do we need to release this peer from memory? 10162 Only for realtime peers and autocreated peers 10163 */ 10164 if (peer->is_realtime) 10165 ast_debug(3, "-REALTIME- peer expired registration. Name: %s. Realtime peer objects now %d\n", peer->name, rpeerobjs); 10166 10167 if (peer->selfdestruct || 10168 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 10169 peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); /* Remove from peer list */ 10170 unref_peer(peer); /* Remove from memory */ 10171 } 10172 10173 return 0; 10174 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 8961 of file chan_sip.c.
References ast_copy_string(), ast_string_field_set, ast_strlen_zero(), get_header(), get_in_brackets(), remove_uri_parameters(), and SIPBUFSIZE.
Referenced by handle_incoming(), and handle_request_invite().
08962 { 08963 char stripped[SIPBUFSIZE]; 08964 char *c; 08965 08966 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 08967 c = get_in_brackets(stripped); 08968 /* Cut the URI at the at sign after the @, not in the username part */ 08969 c = remove_uri_parameters(c); 08970 if (!ast_strlen_zero(c)) 08971 ast_string_field_set(p, uri, c); 08972 08973 }
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 5764 of file chan_sip.c.
References aliases, and ARRAY_LEN.
05765 { 05766 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 05767 static const struct cfalias { 05768 char * const fullname; 05769 char * const shortname; 05770 } aliases[] = { 05771 { "Content-Type", "c" }, 05772 { "Content-Encoding", "e" }, 05773 { "From", "f" }, 05774 { "Call-ID", "i" }, 05775 { "Contact", "m" }, 05776 { "Content-Length", "l" }, 05777 { "Subject", "s" }, 05778 { "To", "t" }, 05779 { "Supported", "k" }, 05780 { "Refer-To", "r" }, 05781 { "Referred-By", "b" }, 05782 { "Allow-Events", "u" }, 05783 { "Event", "o" }, 05784 { "Via", "v" }, 05785 { "Accept-Contact", "a" }, 05786 { "Reject-Contact", "j" }, 05787 { "Request-Disposition", "d" }, 05788 { "Session-Expires", "x" }, 05789 { "Identity", "y" }, 05790 { "Identity-Info", "n" }, 05791 }; 05792 int x; 05793 05794 for (x = 0; x < ARRAY_LEN(aliases); x++) { 05795 if (!strcasecmp(aliases[x].fullname, name)) 05796 return aliases[x].shortname; 05797 } 05798 05799 return _default; 05800 }
static struct sip_pvt * find_call | ( | struct sip_request * | req, | |
struct sockaddr_in * | sin, | |||
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 6189 of file chan_sip.c.
References ast_debug, ast_strlen_zero(), ast_test_flag, sip_pvt::callid, dialoglist, dialoglist_lock(), FALSE, sip_pvt::flags, sip_pvt::from, get_header(), gettag(), sip_request::method, sip_pvt::next, SIP_ACK, SIP_BYE, SIP_INFO, sip_methods, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_REGISTER, SIP_RESPONSE, sip_pvt::tag, cfsip_methods::text, and sip_pvt::theirtag.
Referenced by handle_request_do().
06190 { 06191 struct sip_pvt *p = NULL; 06192 char *tag = ""; /* note, tag is never NULL */ 06193 char totag[128]; 06194 char fromtag[128]; 06195 const char *callid = get_header(req, "Call-ID"); 06196 const char *from = get_header(req, "From"); 06197 const char *to = get_header(req, "To"); 06198 const char *cseq = get_header(req, "Cseq"); 06199 06200 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 06201 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 06202 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 06203 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 06204 return NULL; /* Invalid packet */ 06205 06206 if (pedanticsipchecking) { 06207 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 06208 we need more to identify a branch - so we have to check branch, from 06209 and to tags to identify a call leg. 06210 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 06211 in sip.conf 06212 */ 06213 if (gettag(req, "To", totag, sizeof(totag))) 06214 req->has_to_tag = 1; /* Used in handle_request/response */ 06215 gettag(req, "From", fromtag, sizeof(fromtag)); 06216 06217 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 06218 06219 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); 06220 06221 /* All messages must always have From: tag */ 06222 if (ast_strlen_zero(fromtag)) { 06223 ast_debug(5, "%s request has no from tag, dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from ); 06224 return NULL; 06225 } 06226 /* reject requests that must always have a To: tag */ 06227 if (ast_strlen_zero(totag) && (req->method == SIP_ACK || req->method == SIP_BYE || req->method == SIP_INFO )) { 06228 ast_debug(5, "%s must have a to tag. dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from ); 06229 return NULL; 06230 } 06231 } 06232 06233 dialoglist_lock(); 06234 restartsearch: 06235 for (p = dialoglist; p; p = p->next) { 06236 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 06237 int found = FALSE; 06238 if (ast_strlen_zero(p->callid)) 06239 continue; 06240 if (req->method == SIP_REGISTER) 06241 found = (!strcmp(p->callid, callid)); 06242 else 06243 found = (!strcmp(p->callid, callid) && 06244 (!pedanticsipchecking || ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED) || !strcmp(p->theirtag, tag))) ; 06245 06246 ast_debug(5, "= %s Their Call ID: %s Their Tag %s Our tag: %s\n", found ? "Found" : "No match", p->callid, p->theirtag, p->tag); 06247 06248 /* If we get a new request within an existing to-tag - check the to tag as well */ 06249 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 06250 if (p->tag[0] == '\0' && totag[0]) { 06251 /* We have no to tag, but they have. Wrong dialog */ 06252 found = FALSE; 06253 } else if (totag[0]) { /* Both have tags, compare them */ 06254 if (strcmp(totag, p->tag)) { 06255 found = FALSE; /* This is not our packet */ 06256 } 06257 } 06258 if (!found) 06259 ast_debug(5, "= Being pedantic: This is not our match on request: Call ID: %s Ourtag <null> Totag %s Method %s\n", p->callid, totag, sip_methods[req->method].text); 06260 } 06261 06262 06263 if (found) { 06264 /* Found the call */ 06265 if (sip_pvt_trylock(p)) { 06266 dialoglist_unlock(); 06267 usleep(1); 06268 dialoglist_lock(); 06269 goto restartsearch; 06270 } 06271 dialoglist_unlock(); 06272 return p; 06273 } 06274 } 06275 dialoglist_unlock(); 06276 06277 /* See if the method is capable of creating a dialog */ 06278 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 06279 if (intended_method == SIP_REFER) { 06280 /* We do support REFER, but not outside of a dialog yet */ 06281 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 06282 } else if (intended_method == SIP_NOTIFY) { 06283 /* We do not support out-of-dialog NOTIFY either, 06284 like voicemail notification, so cancel that early */ 06285 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 06286 } else { 06287 /* Ok, time to create a new SIP dialog object, a pvt */ 06288 if ((p = sip_alloc(callid, sin, 1, intended_method, req))) { 06289 /* Ok, we've created a dialog, let's go and process it */ 06290 sip_pvt_lock(p); 06291 } else { 06292 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 06293 getting a dialog from sip_alloc. 06294 06295 Without a dialog we can't retransmit and handle ACKs and all that, but at least 06296 send an error message. 06297 06298 Sorry, we apologize for the inconvienience 06299 */ 06300 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 06301 ast_debug(4, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 06302 } 06303 } 06304 return p; /* can be NULL */ 06305 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 06306 /* A method we do not support, let's take it on the volley */ 06307 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 06308 ast_debug(2, "Got a request with unsupported SIP method.\n"); 06309 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 06310 /* This is a request outside of a dialog that we don't know about */ 06311 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 06312 ast_debug(2, "That's odd... Got a request in unknown dialog. Callid %s\n", callid ? callid : "<unknown>"); 06313 } 06314 /* We do not respond to responses for dialogs that we don't know about, we just drop 06315 the session quickly */ 06316 if (intended_method == SIP_RESPONSE) 06317 ast_debug(2, "That's odd... Got a response on a call we dont know about. Callid %s\n", callid ? callid : "<unknown>"); 06318 06319 return p; 06320 }
static const char* find_closing_quote | ( | const char * | start, | |
const char * | lim | |||
) | [static] |
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 3323 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
03324 { 03325 char last_char = '\0'; 03326 const char *s; 03327 for (s = start; *s && s != lim; last_char = *s++) { 03328 if (*s == '"' && last_char != '\\') 03329 break; 03330 } 03331 return s; 03332 }
static struct sip_peer * find_peer | ( | const char * | peer, | |
struct sockaddr_in * | sin, | |||
int | realtime, | |||
int | devstate_only | |||
) | [static] |
Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name.
Definition at line 3925 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
03926 { 03927 struct sip_peer *p = NULL; 03928 03929 if (peer) 03930 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 03931 else 03932 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 03933 03934 if (!p && realtime) 03935 p = realtime_peer(peer, sin, devstate_only); 03936 03937 return p; 03938 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
const char * | realm | |||
) | [static] |
Find authentication for a specific realm.
Definition at line 20805 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
20806 { 20807 struct sip_auth *a; 20808 20809 for (a = authlist; a; a = a->next) { 20810 if (!strcasecmp(a->realm, realm)) 20811 break; 20812 } 20813 20814 return a; 20815 }
static int find_sdp | ( | struct sip_request * | req | ) | [static] |
Determine whether a SIP message contains an SDP in its body.
req | the SIP request to process |
Definition at line 6550 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, get_header(), sip_request::line, sip_request::lines, LOG_WARNING, sip_request::sdp_end, sip_request::sdp_start, strcasestr(), and TRUE.
Referenced by handle_incoming(), handle_request_invite(), handle_response(), and handle_response_invite().
06551 { 06552 const char *content_type; 06553 const char *content_length; 06554 const char *search; 06555 char *boundary; 06556 unsigned int x; 06557 int boundaryisquoted = FALSE; 06558 int found_application_sdp = FALSE; 06559 int found_end_of_headers = FALSE; 06560 06561 content_length = get_header(req, "Content-Length"); 06562 06563 if (!ast_strlen_zero(content_length)) { 06564 if (sscanf(content_length, "%ud", &x) != 1) { 06565 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 06566 return 0; 06567 } 06568 06569 /* Content-Length of zero means there can't possibly be an 06570 SDP here, even if the Content-Type says there is */ 06571 if (x == 0) 06572 return 0; 06573 } 06574 06575 content_type = get_header(req, "Content-Type"); 06576 06577 /* if the body contains only SDP, this is easy */ 06578 if (!strncasecmp(content_type, "application/sdp", 15)) { 06579 req->sdp_start = 0; 06580 req->sdp_end = req->lines; 06581 return req->lines ? 1 : 0; 06582 } 06583 06584 /* if it's not multipart/mixed, there cannot be an SDP */ 06585 if (strncasecmp(content_type, "multipart/mixed", 15)) 06586 return 0; 06587 06588 /* if there is no boundary marker, it's invalid */ 06589 if ((search = strcasestr(content_type, ";boundary="))) 06590 search += 10; 06591 else if ((search = strcasestr(content_type, "; boundary="))) 06592 search += 11; 06593 else 06594 return 0; 06595 06596 if (ast_strlen_zero(search)) 06597 return 0; 06598 06599 /* If the boundary is quoted with ", remove quote */ 06600 if (*search == '\"') { 06601 search++; 06602 boundaryisquoted = TRUE; 06603 } 06604 06605 /* make a duplicate of the string, with two extra characters 06606 at the beginning */ 06607 boundary = ast_strdupa(search - 2); 06608 boundary[0] = boundary[1] = '-'; 06609 /* Remove final quote */ 06610 if (boundaryisquoted) 06611 boundary[strlen(boundary) - 1] = '\0'; 06612 06613 /* search for the boundary marker, the empty line delimiting headers from 06614 sdp part and the end boundry if it exists */ 06615 06616 for (x = 0; x < (req->lines ); x++) { 06617 if(!strncasecmp(req->line[x], boundary, strlen(boundary))){ 06618 if(found_application_sdp && found_end_of_headers){ 06619 req->sdp_end = x-1; 06620 return 1; 06621 } 06622 found_application_sdp = FALSE; 06623 } 06624 if(!strcasecmp(req->line[x], "Content-Type: application/sdp")) 06625 found_application_sdp = TRUE; 06626 06627 if (ast_strlen_zero(req->line[x])) { 06628 if(found_application_sdp && !found_end_of_headers){ 06629 req->sdp_start = x; 06630 found_end_of_headers = TRUE; 06631 } 06632 } 06633 } 06634 if(found_application_sdp && found_end_of_headers) { 06635 req->sdp_end = x; 06636 return TRUE; 06637 } 06638 return FALSE; 06639 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 2459 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(), and handle_response().
02460 { 02461 int i, res = 0; 02462 02463 if (ast_strlen_zero(msg)) 02464 return 0; 02465 for (i = 1; i < ARRAY_LEN(sip_methods) && !res; i++) { 02466 if (method_match(i, msg)) 02467 res = sip_methods[i].id; 02468 } 02469 return res; 02470 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static] |
Find subscription type in array.
Definition at line 13864 of file chan_sip.c.
References ARRAY_LEN, subscription_types, and type.
Referenced by transmit_state_notify().
13865 { 13866 int i; 13867 13868 for (i = 1; i < ARRAY_LEN(subscription_types); i++) { 13869 if (subscription_types[i].type == subtype) { 13870 return &subscription_types[i]; 13871 } 13872 } 13873 return &subscription_types[0]; 13874 }
static struct sip_user * find_user | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf).
Definition at line 4004 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
04005 { 04006 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 04007 if (!u && realtime) 04008 u = realtime_user(name); 04009 return u; 04010 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 10504 of file chan_sip.c.
References ast_free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
10505 { 10506 struct sip_route *next; 10507 10508 while (route) { 10509 next = route->next; 10510 ast_free(route); 10511 route = next; 10512 } 10513 }
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 14987 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.
14988 { 14989 if (ast_strlen_zero(data)) { 14990 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 14991 return -1; 14992 } 14993 if (check_sip_domain(data, NULL, 0)) 14994 ast_copy_string(buf, data, len); 14995 else 14996 buf[0] = '\0'; 14997 return 0; 14998 }
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 14923 of file chan_sip.c.
References __get_header(), 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(), chan, sip_request::header, sip_pvt::initreq, IS_SIP_TECH, LOG_WARNING, ast_channel::tech, and ast_channel::tech_pvt.
14924 { 14925 struct sip_pvt *p; 14926 const char *content = NULL; 14927 AST_DECLARE_APP_ARGS(args, 14928 AST_APP_ARG(header); 14929 AST_APP_ARG(number); 14930 ); 14931 int i, number, start = 0; 14932 14933 if (ast_strlen_zero(data)) { 14934 ast_log(LOG_WARNING, "This function requires a header name.\n"); 14935 return -1; 14936 } 14937 14938 ast_channel_lock(chan); 14939 if (!IS_SIP_TECH(chan->tech)) { 14940 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 14941 ast_channel_unlock(chan); 14942 return -1; 14943 } 14944 14945 AST_STANDARD_APP_ARGS(args, data); 14946 if (!args.number) { 14947 number = 1; 14948 } else { 14949 sscanf(args.number, "%d", &number); 14950 if (number < 1) 14951 number = 1; 14952 } 14953 14954 p = chan->tech_pvt; 14955 14956 /* If there is no private structure, this channel is no longer alive */ 14957 if (!p) { 14958 ast_channel_unlock(chan); 14959 return -1; 14960 } 14961 14962 for (i = 0; i < number; i++) 14963 content = __get_header(&p->initreq, args.header, &start); 14964 14965 if (ast_strlen_zero(content)) { 14966 ast_channel_unlock(chan); 14967 return -1; 14968 } 14969 14970 ast_copy_string(buf, content, len); 14971 ast_channel_unlock(chan); 14972 14973 return 0; 14974 }
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 15128 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_inet_ntoa(), ast_log(), chan, sip_pvt::from, IS_SIP_TECH, LOG_WARNING, sip_pvt::peername, sip_pvt::recv, sip_pvt::sa, t38properties::state, sip_pvt::t38, T38_DISABLED, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::uri, and sip_pvt::useragent.
15129 { 15130 struct sip_pvt *p; 15131 15132 *buf = 0; 15133 15134 if (!data) { 15135 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 15136 return -1; 15137 } 15138 15139 ast_channel_lock(chan); 15140 if (!IS_SIP_TECH(chan->tech)) { 15141 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 15142 ast_channel_unlock(chan); 15143 return -1; 15144 } 15145 15146 p = chan->tech_pvt; 15147 15148 /* If there is no private structure, this channel is no longer alive */ 15149 if (!p) { 15150 ast_channel_unlock(chan); 15151 return -1; 15152 } 15153 15154 if (!strcasecmp(data, "peerip")) { 15155 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 15156 } else if (!strcasecmp(data, "recvip")) { 15157 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 15158 } else if (!strcasecmp(data, "from")) { 15159 ast_copy_string(buf, p->from, len); 15160 } else if (!strcasecmp(data, "uri")) { 15161 ast_copy_string(buf, p->uri, len); 15162 } else if (!strcasecmp(data, "useragent")) { 15163 ast_copy_string(buf, p->useragent, len); 15164 } else if (!strcasecmp(data, "peername")) { 15165 ast_copy_string(buf, p->peername, len); 15166 } else if (!strcasecmp(data, "t38passthrough")) { 15167 if (p->t38.state == T38_DISABLED) 15168 ast_copy_string(buf, "0", sizeof("0")); 15169 else /* T38 is offered or enabled in this call */ 15170 ast_copy_string(buf, "1", sizeof("1")); 15171 } else { 15172 ast_channel_unlock(chan); 15173 return -1; 15174 } 15175 ast_channel_unlock(chan); 15176 15177 return 0; 15178 }
static int function_sippeer | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
${SIPPEER()} Dialplan function - reads peer data
Definition at line 15012 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_log(), ast_print_group(), ast_str_alloca, sip_peer::busy_level, sip_peer::call_limit, sip_peer::callgroup, sip_peer::capability, chanvar, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::expire, find_peer(), sip_peer::host_dynamic, sip_peer::inUse, sip_peer::language, LOG_WARNING, ast_variable::name, ast_variable::next, peer_mailboxes_to_str(), peer_status(), sip_peer::pickupgroup, sip_peer::prefs, sip_peer::regexten, ast_str::str, strsep(), unref_peer(), sip_peer::useragent, and ast_variable::value.
15013 { 15014 struct sip_peer *peer; 15015 char *colname; 15016 15017 if ((colname = strchr(data, ':'))) { /*! \todo Will be deprecated after 1.4 */ 15018 static int deprecation_warning = 0; 15019 *colname++ = '\0'; 15020 if (deprecation_warning++ % 10 == 0) 15021 ast_log(LOG_WARNING, "SIPPEER(): usage of ':' to separate arguments is deprecated. Please use ',' instead.\n"); 15022 } else if ((colname = strchr(data, ','))) 15023 *colname++ = '\0'; 15024 else 15025 colname = "ip"; 15026 15027 if (!(peer = find_peer(data, NULL, 1, 0))) 15028 return -1; 15029 15030 if (!strcasecmp(colname, "ip")) { 15031 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 15032 } else if (!strcasecmp(colname, "port")) { 15033 snprintf(buf, len, "%d", ntohs(peer->addr.sin_port)); 15034 } else if (!strcasecmp(colname, "status")) { 15035 peer_status(peer, buf, len); 15036 } else if (!strcasecmp(colname, "language")) { 15037 ast_copy_string(buf, peer->language, len); 15038 } else if (!strcasecmp(colname, "regexten")) { 15039 ast_copy_string(buf, peer->regexten, len); 15040 } else if (!strcasecmp(colname, "limit")) { 15041 snprintf(buf, len, "%d", peer->call_limit); 15042 } else if (!strcasecmp(colname, "busylevel")) { 15043 snprintf(buf, len, "%d", peer->busy_level); 15044 } else if (!strcasecmp(colname, "curcalls")) { 15045 snprintf(buf, len, "%d", peer->inUse); 15046 } else if (!strcasecmp(colname, "accountcode")) { 15047 ast_copy_string(buf, peer->accountcode, len); 15048 } else if (!strcasecmp(colname, "callgroup")) { 15049 ast_print_group(buf, len, peer->callgroup); 15050 } else if (!strcasecmp(colname, "pickupgroup")) { 15051 ast_print_group(buf, len, peer->pickupgroup); 15052 } else if (!strcasecmp(colname, "useragent")) { 15053 ast_copy_string(buf, peer->useragent, len); 15054 } else if (!strcasecmp(colname, "mailbox")) { 15055 struct ast_str *mailbox_str = ast_str_alloca(512); 15056 peer_mailboxes_to_str(&mailbox_str, peer); 15057 ast_copy_string(buf, mailbox_str->str, len); 15058 } else if (!strcasecmp(colname, "context")) { 15059 ast_copy_string(buf, peer->context, len); 15060 } else if (!strcasecmp(colname, "expire")) { 15061 snprintf(buf, len, "%d", peer->expire); 15062 } else if (!strcasecmp(colname, "dynamic")) { 15063 ast_copy_string(buf, peer->host_dynamic ? "yes" : "no", len); 15064 } else if (!strcasecmp(colname, "callerid_name")) { 15065 ast_copy_string(buf, peer->cid_name, len); 15066 } else if (!strcasecmp(colname, "callerid_num")) { 15067 ast_copy_string(buf, peer->cid_num, len); 15068 } else if (!strcasecmp(colname, "codecs")) { 15069 ast_getformatname_multiple(buf, len -1, peer->capability); 15070 } else if (!strncasecmp(colname, "chanvar[", 8)) { 15071 char *chanvar=colname + 8; 15072 struct ast_variable *v; 15073 15074 chanvar = strsep(&chanvar, "]"); 15075 for (v = peer->chanvars ; v ; v = v->next) 15076 if (!strcasecmp(v->name, chanvar)) 15077 ast_copy_string(buf, v->value, len); 15078 } else if (!strncasecmp(colname, "codec[", 6)) { 15079 char *codecnum; 15080 int index = 0, codec = 0; 15081 15082 codecnum = colname + 6; /* move past the '[' */ 15083 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 15084 index = atoi(codecnum); 15085 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 15086 ast_copy_string(buf, ast_getformatname(codec), len); 15087 } 15088 } 15089 15090 unref_peer(peer); 15091 15092 return 0; 15093 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 5966 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
05967 { 05968 long val[4]; 05969 int x; 05970 05971 for (x=0; x<4; x++) 05972 val[x] = ast_random(); 05973 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 05974 05975 return buf; 05976 }
static int get_also_info | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Call transfer support (old way, deprecated by the IETF)--.
Definition at line 11661 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_uri_decode(), ast_verbose(), sip_pvt::context, dialog_unref(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, ast_channel::macrocontext, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_call, sip_refer::refer_contact, sip_refer::refer_to, sip_refer::refer_to_domain, sip_refer::referred_by, S_OR, sip_debug_test_pvt(), and sip_refer_allocate().
Referenced by handle_request_bye().
11662 { 11663 char tmp[256] = "", *c, *a; 11664 struct sip_request *req = oreq ? oreq : &p->initreq; 11665 struct sip_refer *referdata = NULL; 11666 const char *transfer_context = NULL; 11667 11668 if (!p->refer && !sip_refer_allocate(p)) 11669 return -1; 11670 11671 referdata = p->refer; 11672 11673 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 11674 c = get_in_brackets(tmp); 11675 11676 if (pedanticsipchecking) 11677 ast_uri_decode(c); 11678 11679 if (!strncasecmp(c, "sip:", 4)) { 11680 c += 4; 11681 } else if (!strncasecmp(c, "sips:", 5)) { 11682 c += 5; 11683 } else { 11684 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 11685 return -1; 11686 } 11687 11688 if ((a = strchr(c, ';'))) /* Remove arguments */ 11689 *a = '\0'; 11690 11691 if ((a = strchr(c, '@'))) { /* Separate Domain */ 11692 *a++ = '\0'; 11693 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 11694 } 11695 11696 if (sip_debug_test_pvt(p)) 11697 ast_verbose("Looking for %s in %s\n", c, p->context); 11698 11699 if (p->owner) /* Mimic behaviour in res_features.c */ 11700 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 11701 11702 /* By default, use the context in the channel sending the REFER */ 11703 if (ast_strlen_zero(transfer_context)) { 11704 transfer_context = S_OR(p->owner->macrocontext, 11705 S_OR(p->context, default_context)); 11706 } 11707 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 11708 /* This is a blind transfer */ 11709 ast_debug(1, "SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 11710 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 11711 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 11712 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 11713 referdata->refer_call = dialog_unref(referdata->refer_call); 11714 /* Set new context */ 11715 ast_string_field_set(p, context, transfer_context); 11716 return 0; 11717 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 11718 return 1; 11719 } 11720 11721 return -1; 11722 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 5748 of file chan_sip.c.
References get_body_by_line(), len(), sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
05749 { 05750 int x; 05751 int len = strlen(name); 05752 char *r; 05753 05754 for (x = 0; x < req->lines; x++) { 05755 r = get_body_by_line(req->line[x], name, len); 05756 if (r[0] != '\0') 05757 return r; 05758 } 05759 05760 return ""; 05761 }
static char* get_body_by_line | ( | const char * | line, | |
const char * | name, | |||
int | nameLen | |||
) | [static] |
Reads one line of SIP message body.
Definition at line 5714 of file chan_sip.c.
References ast_skip_blanks().
Referenced by get_body(), and get_sdp_iterate().
05715 { 05716 if (!strncasecmp(line, name, nameLen) && line[nameLen] == '=') 05717 return ast_skip_blanks(line + nameLen + 1); 05718 05719 return ""; 05720 }
static int get_cached_mwi | ( | struct sip_peer * | peer, | |
int * | new, | |||
int * | old | |||
) | [static] |
Get cached MWI info.
0 | At least one message is waiting | |
1 | no messages waiting |
Definition at line 19569 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_EXISTS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, AST_LIST_TRAVERSE, sip_mailbox::entry, mailbox, sip_peer::mailboxes, and S_OR.
Referenced by sip_send_mwi_to_peer().
19570 { 19571 struct sip_mailbox *mailbox; 19572 19573 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 19574 struct ast_event *event; 19575 event = ast_event_get_cached(AST_EVENT_MWI, 19576 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox, 19577 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"), 19578 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS, 19579 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_EXISTS, 19580 AST_EVENT_IE_END); 19581 if (!event) 19582 continue; 19583 *new += ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 19584 *old += ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 19585 ast_event_destroy(event); 19586 } 19587 19588 return (*new || *old) ? 0 : 1; 19589 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 11816 of file chan_sip.c.
References ast_copy_string(), and ast_skip_blanks().
Referenced by check_user_full().
11817 { 11818 const char *end = strchr(input, '<'); /* first_bracket */ 11819 const char *tmp = strchr(input, '"'); /* first quote */ 11820 int bytes = 0; 11821 int maxbytes = outputsize - 1; 11822 11823 if (!end || end == input) /* we require a part in brackets */ 11824 return NULL; 11825 11826 end--; /* move just before "<" */ 11827 11828 if (tmp && tmp <= end) { 11829 /* The quote (tmp) precedes the bracket (end+1). 11830 * Find the matching quote and return the content. 11831 */ 11832 end = strchr(tmp+1, '"'); 11833 if (!end) 11834 return NULL; 11835 bytes = (int) (end - tmp); 11836 /* protect the output buffer */ 11837 if (bytes > maxbytes) 11838 bytes = maxbytes; 11839 ast_copy_string(output, tmp + 1, bytes); 11840 } else { 11841 /* No quoted string, or it is inside brackets. */ 11842 /* clear the empty characters in the begining*/ 11843 input = ast_skip_blanks(input); 11844 /* clear the empty characters in the end */ 11845 while(*end && *end < 33 && end > input) 11846 end--; 11847 if (end >= input) { 11848 bytes = (int) (end - input) + 2; 11849 /* protect the output buffer */ 11850 if (bytes > maxbytes) 11851 bytes = maxbytes; 11852 ast_copy_string(output, input, bytes); 11853 } else 11854 return NULL; 11855 } 11856 return output; 11857 }
static int get_destination | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Find out who the call is for. We use the request uri as a destination. This code assumes authentication has been done, so that the device (peer/user) context is already set.
Definition at line 11283 of file chan_sip.c.
References ast_canmatch_extension(), 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(), sip_pvt::cid_num, sip_pvt::context, sip_pvt::domain, exten, sip_pvt::exten, get_header(), get_in_brackets(), global_flags, sip_pvt::initreq, LOG_WARNING, sip_request::method, sip_request::rlPart2, S_OR, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_PAGE2_ALLOWOVERLAP, SIP_REFER, SIP_SUBSCRIBE, strsep(), and sip_pvt::subscribecontext.
Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().
11284 { 11285 char tmp[256] = "", *uri, *a; 11286 char tmpf[256] = "", *from = NULL; 11287 struct sip_request *req; 11288 char *colon; 11289 char *decoded_uri; 11290 11291 req = oreq; 11292 if (!req) 11293 req = &p->initreq; 11294 11295 /* Find the request URI */ 11296 if (req->rlPart2) 11297 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 11298 11299 if (pedanticsipchecking) 11300 ast_uri_decode(tmp); 11301 11302 uri = get_in_brackets(tmp); 11303 11304 if (!strncasecmp(uri, "sip:", 4)) { 11305 uri += 4; 11306 } else if (!strncasecmp(uri, "sips:", 5)) { 11307 uri += 5; 11308 } else { 11309 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 11310 return -1; 11311 } 11312 11313 /* Now find the From: caller ID and name */ 11314 /* XXX Why is this done in get_destination? Isn't it already done? 11315 Needs to be checked 11316 */ 11317 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 11318 if (!ast_strlen_zero(tmpf)) { 11319 if (pedanticsipchecking) 11320 ast_uri_decode(tmpf); 11321 from = get_in_brackets(tmpf); 11322 } 11323 11324 if (!ast_strlen_zero(from)) { 11325 if (!strncasecmp(from, "sip:", 4)) { 11326 from += 4; 11327 } else if (!strncasecmp(from, "sips:", 5)) { 11328 from += 5; 11329 } else { 11330 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 11331 return -1; 11332 } 11333 if ((a = strchr(from, '@'))) 11334 *a++ = '\0'; 11335 else 11336 a = from; /* just a domain */ 11337 from = strsep(&from, ";"); /* Remove userinfo options */ 11338 a = strsep(&a, ";"); /* Remove URI options */ 11339 ast_string_field_set(p, fromdomain, a); 11340 } 11341 11342 /* Skip any options and find the domain */ 11343 11344 /* Get the target domain */ 11345 if ((a = strchr(uri, '@'))) { 11346 *a++ = '\0'; 11347 } else { /* No username part */ 11348 a = uri; 11349 uri = "s"; /* Set extension to "s" */ 11350 } 11351 colon = strchr(a, ':'); /* Remove :port */ 11352 if (colon) 11353 *colon = '\0'; 11354 11355 uri = strsep(&uri, ";"); /* Remove userinfo options */ 11356 a = strsep(&a, ";"); /* Remove URI options */ 11357 11358 ast_string_field_set(p, domain, a); 11359 11360 if (!AST_LIST_EMPTY(&domain_list)) { 11361 char domain_context[AST_MAX_EXTENSION]; 11362 11363 domain_context[0] = '\0'; 11364 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 11365 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 11366 ast_debug(1, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 11367 return -2; 11368 } 11369 } 11370 /* If we have a context defined, overwrite the original context */ 11371 if (!ast_strlen_zero(domain_context)) 11372 ast_string_field_set(p, context, domain_context); 11373 } 11374 11375 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 11376 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) 11377 ast_string_field_set(p, context, p->subscribecontext); 11378 11379 if (sip_debug_test_pvt(p)) 11380 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 11381 11382 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 11383 if (req->method == SIP_SUBSCRIBE) { 11384 char hint[AST_MAX_EXTENSION]; 11385 return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1); 11386 } else { 11387 decoded_uri = ast_strdupa(uri); 11388 ast_uri_decode(decoded_uri); 11389 /* Check the dialplan for the username part of the request URI, 11390 the domain will be stored in the SIPDOMAIN variable 11391 Since extensions.conf can have unescaped characters, try matching a decoded 11392 uri in addition to the non-decoded uri 11393 Return 0 if we have a matching extension */ 11394 if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) || ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) || 11395 !strcmp(decoded_uri, ast_pickup_ext())) { 11396 if (!oreq) 11397 ast_string_field_set(p, exten, decoded_uri); 11398 return 0; 11399 } 11400 } 11401 11402 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 11403 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 11404 ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))) || 11405 !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri))) { 11406 return 1; 11407 } 11408 11409 return -1; 11410 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 5840 of file chan_sip.c.
References __get_header().
05841 { 05842 int start = 0; 05843 return __get_header(req, name, &start); 05844 }
static char * get_in_brackets | ( | char * | tmp | ) | [static] |
Pick out text in brackets from character string.
tmp | input string that will be modified Examples: "foo" <bar> valid input, returns bar foo returns the whole string < "foo ... > returns the string between brackets < "foo... bogus (missing closing bracket), returns the whole string XXX maybe should still skip the opening bracket |
Definition at line 3346 of file chan_sip.c.
References ast_log(), find_closing_quote(), LOG_WARNING, and parse().
Referenced by check_peer_ok(), check_user_full(), extract_uri(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), register_verify(), reqprep(), transmit_refer(), and transmit_state_notify().
03347 { 03348 const char *parse = tmp; 03349 char *first_bracket; 03350 03351 /* 03352 * Skip any quoted text until we find the part in brackets. 03353 * On any error give up and return the full string. 03354 */ 03355 while ( (first_bracket = strchr(parse, '<')) ) { 03356 char *first_quote = strchr(parse, '"'); 03357 03358 if (!first_quote || first_quote > first_bracket) 03359 break; /* no need to look at quoted part */ 03360 /* the bracket is within quotes, so ignore it */ 03361 parse = find_closing_quote(first_quote + 1, NULL); 03362 if (!*parse) { /* not found, return full string ? */ 03363 /* XXX or be robust and return in-bracket part ? */ 03364 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 03365 break; 03366 } 03367 parse++; 03368 } 03369 if (first_bracket) { 03370 char *second_bracket = strchr(first_bracket + 1, '>'); 03371 if (second_bracket) { 03372 *second_bracket = '\0'; 03373 tmp = first_bracket + 1; 03374 } else { 03375 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 03376 } 03377 } 03378 03379 return tmp; 03380 }
static struct ast_variable * get_insecure_variable_from_config | ( | struct ast_config * | config | ) | [static] |
Definition at line 3700 of file chan_sip.c.
References ast_category_browse(), ast_category_root(), ast_test_flag, ast_variable_retrieve(), config, ast_flags::flags, set_insecure_flags(), SIP_INSECURE_PORT, and var.
03701 { 03702 struct ast_variable *var = NULL; 03703 struct ast_flags flags = {0}; 03704 char *cat = NULL; 03705 const char *insecure; 03706 while ((cat = ast_category_browse(config, cat))) { 03707 insecure = ast_variable_retrieve(config, cat, "insecure"); 03708 set_insecure_flags(&flags, insecure, -1); 03709 if (ast_test_flag(&flags, SIP_INSECURE_PORT)) { 03710 var = ast_category_root(config, cat); 03711 break; 03712 } 03713 } 03714 return var; 03715 }
static int get_ip_and_port_from_sdp | ( | struct sip_request * | req, | |
const enum media_type | media, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 6646 of file chan_sip.c.
References ast_gethostbyname(), ast_log(), ast_strlen_zero(), get_sdp_iterate(), hp, len(), LOG_WARNING, SDP_AUDIO, sip_request::sdp_start, and SDP_VIDEO.
Referenced by handle_request_invite().
06647 { 06648 const char *m; 06649 const char *c; 06650 int miterator = req->sdp_start; 06651 int citerator = req->sdp_start; 06652 int x = 0; 06653 int numberofports; 06654 int len; 06655 char host[258] = ""; /*Initialize to empty so we will know if we have any input */ 06656 struct ast_hostent audiohp; 06657 struct hostent *hp; 06658 06659 c = get_sdp_iterate(&citerator, req, "c"); 06660 if (sscanf(c, "IN IP4 %256s", host) != 1) { 06661 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 06662 /* Continue since there may be a valid host in a c= line specific to the audio stream */ 06663 } 06664 /* We only want the m and c lines for audio */ 06665 for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) { 06666 if ((media == SDP_AUDIO && ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 06667 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1 && len > 0))) || 06668 (media == SDP_VIDEO && ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 06669 (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1 && len > 0)))) { 06670 /* See if there's a c= line for this media stream. 06671 * XXX There is no guarantee that we'll be grabbing the c= line for this 06672 * particular media stream here. However, this is the same logic used in process_sdp. 06673 */ 06674 c = get_sdp_iterate(&citerator, req, "c"); 06675 if (!ast_strlen_zero(c)) { 06676 sscanf(c, "IN IP4 %256s", host); 06677 } 06678 break; 06679 } 06680 } 06681 06682 if (ast_strlen_zero(host) || x == 0) { 06683 ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video"); 06684 return -1; 06685 } 06686 06687 hp = ast_gethostbyname(host, &audiohp); 06688 if (!hp) { 06689 ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video"); 06690 return -1; 06691 } 06692 06693 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 06694 sin->sin_port = htons(x); 06695 return 0; 06696 }
static int get_msg_text | ( | char * | buf, | |
int | len, | |||
struct sip_request * | req | |||
) | [static] |
Get text out of a SIP MESSAGE packet.
Definition at line 12327 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_info(), handle_request_notify(), and receive_message().
12328 { 12329 int x; 12330 int y; 12331 12332 buf[0] = '\0'; 12333 y = len - strlen(buf) - 5; 12334 if (y < 0) 12335 y = 0; 12336 for (x=0;x<req->lines;x++) { 12337 strncat(buf, req->line[x], y); /* safe */ 12338 y -= strlen(req->line[x]) + 1; 12339 if (y < 0) 12340 y = 0; 12341 if (y != 0) 12342 strcat(buf, "\n"); /* safe */ 12343 } 12344 return 0; 12345 }
static const char * get_name_from_variable | ( | struct ast_variable * | var, | |
const char * | newpeername | |||
) | [static] |
Definition at line 3717 of file chan_sip.c.
References ast_variable::name, ast_variable::next, ast_variable::value, and var.
03718 { 03719 struct ast_variable *tmp; 03720 for (tmp = var; tmp; tmp = tmp->next) { 03721 if (!newpeername && !strcasecmp(tmp->name, "name")) 03722 newpeername = tmp->value; 03723 } 03724 return newpeername; 03725 }
static void get_our_media_address | ( | struct sip_pvt * | p, | |
int | needvideo, | |||
struct sockaddr_in * | sin, | |||
struct sockaddr_in * | vsin, | |||
struct sockaddr_in * | tsin, | |||
struct sockaddr_in * | dest, | |||
struct sockaddr_in * | vdest | |||
) | [static] |
Set all IP media addresses for this call.
Definition at line 8403 of file chan_sip.c.
References ast_rtp_get_us(), sip_pvt::ourip, sip_pvt::redirip, sip_pvt::rtp, sip_pvt::trtp, sip_pvt::vredirip, and sip_pvt::vrtp.
Referenced by add_sdp().
08406 { 08407 /* First, get our address */ 08408 ast_rtp_get_us(p->rtp, sin); 08409 if (p->vrtp) 08410 ast_rtp_get_us(p->vrtp, vsin); 08411 if (p->trtp) 08412 ast_rtp_get_us(p->trtp, tsin); 08413 08414 /* Now, try to figure out where we want them to send data */ 08415 /* Is this a re-invite to move the media out, then use the original offer from caller */ 08416 if (p->redirip.sin_addr.s_addr) { /* If we have a redirection IP, use it */ 08417 dest->sin_port = p->redirip.sin_port; 08418 dest->sin_addr = p->redirip.sin_addr; 08419 } else { 08420 dest->sin_addr = p->ourip.sin_addr; 08421 dest->sin_port = sin->sin_port; 08422 } 08423 if (needvideo) { 08424 /* Determine video destination */ 08425 if (p->vredirip.sin_addr.s_addr) { 08426 vdest->sin_addr = p->vredirip.sin_addr; 08427 vdest->sin_port = p->vredirip.sin_port; 08428 } else { 08429 vdest->sin_addr = p->ourip.sin_addr; 08430 vdest->sin_port = vsin->sin_port; 08431 } 08432 } 08433 08434 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 11216 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_string_field_set, ast_strip_quoted(), ast_strlen_zero(), ast_verbose(), exten, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_debug_test_pvt(), sip_set_redirstr(), strcasestr(), and strsep().
Referenced by handle_request_invite().
11217 { 11218 char tmp[256], *exten, *rexten, *rdomain; 11219 char *params, *reason = NULL; 11220 struct sip_request *req; 11221 11222 req = oreq ? oreq : &p->initreq; 11223 11224 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 11225 if (ast_strlen_zero(tmp)) 11226 return 0; 11227 11228 params = strchr(tmp, ';'); 11229 11230 exten = get_in_brackets(tmp); 11231 if (!strncasecmp(exten, "sip:", 4)) { 11232 exten += 4; 11233 } else if (!strncasecmp(exten, "sips:", 5)) { 11234 exten += 5; 11235 } else { 11236 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", exten); 11237 return -1; 11238 } 11239 11240 /* Get diversion-reason param if present */ 11241 if (params) { 11242 *params = '\0'; /* Cut off parameters */ 11243 params++; 11244 while (*params == ';' || *params == ' ') 11245 params++; 11246 /* Check if we have a reason parameter */ 11247 if ((reason = strcasestr(params, "reason="))) { 11248 reason+=7; 11249 /* Remove enclosing double-quotes */ 11250 if (*reason == '"') 11251 ast_strip_quoted(reason, "\"", "\""); 11252 if (!ast_strlen_zero(reason)) { 11253 sip_set_redirstr(p, reason); 11254 if (p->owner) { 11255 pbx_builtin_setvar_helper(p->owner, "__PRIREDIRECTREASON", p->redircause); 11256 pbx_builtin_setvar_helper(p->owner, "__SIPREDIRECTREASON", reason); 11257 } 11258 } 11259 } 11260 } 11261 11262 rdomain = exten; 11263 rexten = strsep(&rdomain, "@"); /* trim anything after @ */ 11264 if (p->owner) 11265 pbx_builtin_setvar_helper(p->owner, "__SIPRDNISDOMAIN", rdomain); 11266 11267 if (sip_debug_test_pvt(p)) 11268 ast_verbose("RDNIS for this call is is %s (reason %s)\n", exten, reason ? reason : ""); 11269 11270 ast_string_field_set(p, rdnis, rexten); 11271 11272 return 0; 11273 }
static int get_refer_info | ( | struct sip_pvt * | transferer, | |
struct sip_request * | outgoing_req | |||
) | [static] |
Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure.
Definition at line 11485 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(), sip_refer::attendedtransfer, sip_pvt::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, ast_channel::macrocontext, sip_pvt::owner, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), sip_pvt::refer, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::refer_to_urioption, sip_refer::referred_by, sip_refer::referred_by_name, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, S_OR, sip_debug_test_pvt(), and strcasestr().
Referenced by handle_request_refer().
11486 { 11487 11488 const char *p_referred_by = NULL; 11489 char *h_refer_to = NULL; 11490 char *h_referred_by = NULL; 11491 char *refer_to; 11492 const char *p_refer_to; 11493 char *referred_by_uri = NULL; 11494 char *ptr; 11495 struct sip_request *req = NULL; 11496 const char *transfer_context = NULL; 11497 struct sip_refer *referdata; 11498 11499 11500 req = outgoing_req; 11501 referdata = transferer->refer; 11502 11503 if (!req) 11504 req = &transferer->initreq; 11505 11506 p_refer_to = get_header(req, "Refer-To"); 11507 if (ast_strlen_zero(p_refer_to)) { 11508 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 11509 return -2; /* Syntax error */ 11510 } 11511 h_refer_to = ast_strdupa(p_refer_to); 11512 refer_to = get_in_brackets(h_refer_to); 11513 if (pedanticsipchecking) 11514 ast_uri_decode(refer_to); 11515 11516 if (!strncasecmp(refer_to, "sip:", 4)) { 11517 refer_to += 4; /* Skip sip: */ 11518 } else if (!strncasecmp(refer_to, "sips:", 5)) { 11519 refer_to += 5; 11520 } else { 11521 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 11522 return -3; 11523 } 11524 11525 /* Get referred by header if it exists */ 11526 p_referred_by = get_header(req, "Referred-By"); 11527 11528 /* Give useful transfer information to the dialplan */ 11529 if (transferer->owner) { 11530 struct ast_channel *peer = ast_bridged_channel(transferer->owner); 11531 if (peer) { 11532 pbx_builtin_setvar_helper(peer, "SIPREFERRINGCONTEXT", transferer->context); 11533 pbx_builtin_setvar_helper(peer, "SIPREFERREDBYHDR", p_referred_by); 11534 } 11535 } 11536 11537 if (!ast_strlen_zero(p_referred_by)) { 11538 char *lessthan; 11539 h_referred_by = ast_strdupa(p_referred_by); 11540 if (pedanticsipchecking) 11541 ast_uri_decode(h_referred_by); 11542 11543 /* Store referrer's caller ID name */ 11544 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 11545 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 11546 *(lessthan - 1) = '\0'; /* Space */ 11547 } 11548 11549 referred_by_uri = get_in_brackets(h_referred_by); 11550 if (!strncasecmp(referred_by_uri, "sip:", 4)) { 11551 referred_by_uri += 4; /* Skip sip: */ 11552 } else if (!strncasecmp(referred_by_uri, "sips:", 5)) { 11553 referred_by_uri += 5; /* Skip sips: */ 11554 } else { 11555 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 11556 referred_by_uri = NULL; 11557 } 11558 } 11559 11560 /* Check for arguments in the refer_to header */ 11561 if ((ptr = strcasestr(refer_to, "replaces="))) { 11562 char *to = NULL, *from = NULL; 11563 11564 /* This is an attended transfer */ 11565 referdata->attendedtransfer = 1; 11566 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 11567 ast_uri_decode(referdata->replaces_callid); 11568 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 11569 *ptr++ = '\0'; 11570 } 11571 11572 if (ptr) { 11573 /* Find the different tags before we destroy the string */ 11574 to = strcasestr(ptr, "to-tag="); 11575 from = strcasestr(ptr, "from-tag="); 11576 } 11577 11578 /* Grab the to header */ 11579 if (to) { 11580 ptr = to + 7; 11581 if ((to = strchr(ptr, '&'))) 11582 *to = '\0'; 11583 if ((to = strchr(ptr, ';'))) 11584 *to = '\0'; 11585 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 11586 } 11587 11588 if (from) { 11589 ptr = from + 9; 11590 if ((to = strchr(ptr, '&'))) 11591 *to = '\0'; 11592 if ((to = strchr(ptr, ';'))) 11593 *to = '\0'; 11594 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 11595 } 11596 11597 if (!pedanticsipchecking) 11598 ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 11599 else 11600 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>" ); 11601 } 11602 11603 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 11604 char *urioption = NULL, *domain; 11605 *ptr++ = '\0'; 11606 11607 if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */ 11608 *urioption++ = '\0'; 11609 11610 domain = ptr; 11611 if ((ptr = strchr(domain, ':'))) /* Remove :port */ 11612 *ptr = '\0'; 11613 11614 /* Save the domain for the dial plan */ 11615 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 11616 if (urioption) 11617 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 11618 } 11619 11620 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 11621 *ptr = '\0'; 11622 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 11623 11624 if (referred_by_uri) { 11625 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 11626 *ptr = '\0'; 11627 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 11628 } else { 11629 referdata->referred_by[0] = '\0'; 11630 } 11631 11632 /* Determine transfer context */ 11633 if (transferer->owner) /* Mimic behaviour in res_features.c */ 11634 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 11635 11636 /* By default, use the context in the channel sending the REFER */ 11637 if (ast_strlen_zero(transfer_context)) { 11638 transfer_context = S_OR(transferer->owner->macrocontext, 11639 S_OR(transferer->context, default_context)); 11640 } 11641 11642 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 11643 11644 /* Either an existing extension or the parking extension */ 11645 if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 11646 if (sip_debug_test_pvt(transferer)) { 11647 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 11648 } 11649 /* We are ready to transfer to the extension */ 11650 return 0; 11651 } 11652 if (sip_debug_test_pvt(transferer)) 11653 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 11654 11655 /* Failure, we can't find this extension */ 11656 return -1; 11657 }
static int get_rpid_num | ( | const char * | input, | |
char * | output, | |||
int | maxlen | |||
) | [static] |
Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found.
Definition at line 11863 of file chan_sip.c.
References ast_copy_string(), and AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
11864 { 11865 char *start; 11866 char *end; 11867 11868 start = strchr(input, ':'); 11869 if (!start) { 11870 output[0] = '\0'; 11871 return 0; 11872 } 11873 start++; 11874 11875 /* we found "number" */ 11876 ast_copy_string(output, start, maxlen); 11877 output[maxlen-1] = '\0'; 11878 11879 end = strchr(output, '@'); 11880 if (end) 11881 *end = '\0'; 11882 else 11883 output[0] = '\0'; 11884 if (strstr(input, "privacy=full") || strstr(input, "privacy=uri")) 11885 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 11886 11887 return 0; 11888 }
static const char * get_sdp | ( | struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get a line from an SDP message body.
Definition at line 5740 of file chan_sip.c.
References dummy(), and get_sdp_iterate().
05741 { 05742 int dummy = 0; 05743 05744 return get_sdp_iterate(&dummy, req, name); 05745 }
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 5726 of file chan_sip.c.
References get_body_by_line(), len(), and sip_request::line.
05727 { 05728 int len = strlen(name); 05729 05730 while (*start < req->sdp_end) { 05731 const char *r = get_body_by_line(req->line[(*start)++], name, len); 05732 if (r[0] != '\0') 05733 return r; 05734 } 05735 05736 return ""; 05737 }
static struct sip_pvt * get_sip_pvt_byid_locked | ( | const char * | callid, | |
const char * | totag, | |||
const char * | fromtag | |||
) | [static] |
Lock dialog lock and find matching pvt lock
Definition at line 11418 of file chan_sip.c.
References ast_channel_trylock, ast_debug, ast_strlen_zero(), ast_test_flag, sip_pvt::callid, dialoglist, dialoglist_lock(), sip_pvt::flags, match(), sip_pvt::next, sip_pvt::owner, SIP_OUTGOING, sip_pvt_lock, sip_pvt_unlock, sip_pvt::tag, and sip_pvt::theirtag.
Referenced by handle_request_invite(), and local_attended_transfer().
11419 { 11420 struct sip_pvt *sip_pvt_ptr; 11421 11422 11423 if (totag) 11424 ast_debug(4, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 11425 11426 /* Search dialogs and find the match */ 11427 dialoglist_lock(); 11428 for (sip_pvt_ptr = dialoglist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 11429 if (!strcmp(sip_pvt_ptr->callid, callid)) { 11430 int match = 1; 11431 char *ourtag = sip_pvt_ptr->tag; 11432 11433 /* Go ahead and lock it (and its owner) before returning */ 11434 sip_pvt_lock(sip_pvt_ptr); 11435 11436 /* Check if tags match. If not, this is not the call we want 11437 (With a forking SIP proxy, several call legs share the 11438 call id, but have different tags) 11439 */ 11440 11441 /* RFC 3891 11442 * > 3. User Agent Server Behavior: Receiving a Replaces Header 11443 * > The Replaces header contains information used to match an existing 11444 * > SIP dialog (call-id, to-tag, and from-tag). Upon receiving an INVITE 11445 * > with a Replaces header, the User Agent (UA) attempts to match this 11446 * > information with a confirmed or early dialog. The User Agent Server 11447 * > (UAS) matches the to-tag and from-tag parameters as if they were tags 11448 * > present in an incoming request. In other words, the to-tag parameter 11449 * > is compared to the local tag, and the from-tag parameter is compared 11450 * > to the remote tag. 11451 * 11452 * Thus, the totag is always compared to the local tag, regardless if 11453 * this our call is an incoming or outgoing call. 11454 */ 11455 if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, ourtag)))) 11456 match = 0; 11457 11458 if (!match) { 11459 sip_pvt_unlock(sip_pvt_ptr); 11460 continue; 11461 } 11462 11463 if (totag) 11464 ast_debug(4, "Matched %s call - their tag is %s Our tag is %s\n", 11465 ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING", 11466 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 11467 11468 /* deadlock avoidance... */ 11469 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 11470 sip_pvt_unlock(sip_pvt_ptr); 11471 usleep(1); 11472 sip_pvt_lock(sip_pvt_ptr); 11473 } 11474 break; 11475 } 11476 } 11477 dialoglist_unlock(); 11478 if (!sip_pvt_ptr) 11479 ast_debug(4, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 11480 return sip_pvt_ptr; 11481 }
static const char* get_transport | ( | enum sip_transport | t | ) | [inline, static] |
Definition at line 2602 of file chan_sip.c.
References SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, and SIP_TRANSPORT_UDP.
Referenced by _sip_show_peer(), ast_sip_ouraddrfor(), build_contact(), create_addr(), get_transport_pvt(), handle_request_do(), parse_moved_contact(), sip_show_tcp(), and transmit_notify_with_mwi().
02603 { 02604 switch (t) { 02605 case SIP_TRANSPORT_UDP: 02606 return "UDP"; 02607 case SIP_TRANSPORT_TCP: 02608 return "TCP"; 02609 case SIP_TRANSPORT_TLS: 02610 return "TLS"; 02611 } 02612 02613 return "UNKNOWN"; 02614 }
static const char* get_transport_list | ( | struct sip_peer * | peer | ) | [inline, static] |
Definition at line 2582 of file chan_sip.c.
References SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, and sip_peer::transports.
02582 { 02583 switch (peer->transports) { 02584 case SIP_TRANSPORT_UDP: 02585 return "UDP"; 02586 case SIP_TRANSPORT_TCP: 02587 return "TCP"; 02588 case SIP_TRANSPORT_TLS: 02589 return "TLS"; 02590 case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TCP: 02591 return "TCP,UDP"; 02592 case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TLS: 02593 return "TLS,UDP"; 02594 case SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS: 02595 return "TLS,TCP"; 02596 default: 02597 return peer->transports ? 02598 "TLS,TCP,UDP" : "UNKNOWN"; 02599 } 02600 }
static const char* get_transport_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Definition at line 2616 of file chan_sip.c.
References get_transport(), sip_pvt::outboundproxy, set_socket_transport(), sip_pvt::socket, sip_proxy::transport, and sip_socket::type.
Referenced by __sip_xmit(), and build_via().
02617 { 02618 if (p->outboundproxy && p->outboundproxy->transport) { 02619 set_socket_transport(&p->socket, p->outboundproxy->transport); 02620 } 02621 02622 return get_transport(p->socket.type); 02623 }
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 2561 of file chan_sip.c.
References ast_strlen_zero(), SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, and SIP_TRANSPORT_UDP.
Referenced by parse_register_contact().
02562 { 02563 int res = 0; 02564 02565 if (ast_strlen_zero(transport)) { 02566 return res; 02567 } 02568 02569 if (!strcasecmp(transport, "udp")) { 02570 res |= SIP_TRANSPORT_UDP; 02571 } 02572 if (!strcasecmp(transport, "tcp")) { 02573 res |= SIP_TRANSPORT_TCP; 02574 } 02575 if (!strcasecmp(transport, "tls")) { 02576 res |= SIP_TRANSPORT_TLS; 02577 } 02578 02579 return res; 02580 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 16580 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().
16581 { 16582 const char *thetag; 16583 16584 if (!tagbuf) 16585 return NULL; 16586 tagbuf[0] = '\0'; /* reset the buffer */ 16587 thetag = get_header(req, header); 16588 thetag = strcasestr(thetag, ";tag="); 16589 if (thetag) { 16590 thetag += 5; 16591 ast_copy_string(tagbuf, thetag, tagbufsize); 16592 return strsep(&tagbuf, ";"); 16593 } 16594 return NULL; 16595 }
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 - users and peers.
flags | array of two struct ast_flags | |
mask | array of two struct ast_flags | |
v | linked list of config variables to process |
Definition at line 20547 of file chan_sip.c.
References ast_clear_flag, ast_copy_string(), ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), buf, ast_channel::flags, ast_variable::lineno, LOG_WARNING, ast_variable::name, ast_channel::next, set_insecure_flags(), SIP_CAN_REINVITE, SIP_CAN_REINVITE_NAT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_DTMF_SHORTINFO, SIP_G726_NONSTANDARD, SIP_INSECURE, SIP_NAT, SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, SIP_NAT_ROUTE, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_BUGGY_MWI, SIP_PAGE2_IGNORESDPVERSION, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_UDPTL_DESTINATION, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NO, SIP_PROG_INBAND_YES, SIP_PROMISCREDIR, SIP_REINVITE, SIP_REINVITE_UPDATE, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USECLIENTCODE, strsep(), and ast_variable::value.
Referenced by build_peer(), and build_user().
20548 { 20549 int res = 1; 20550 20551 if (!strcasecmp(v->name, "trustrpid")) { 20552 ast_set_flag(&mask[0], SIP_TRUSTRPID); 20553 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 20554 } else if (!strcasecmp(v->name, "sendrpid")) { 20555 ast_set_flag(&mask[0], SIP_SENDRPID); 20556 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 20557 } else if (!strcasecmp(v->name, "g726nonstandard")) { 20558 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 20559 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 20560 } else if (!strcasecmp(v->name, "useclientcode")) { 20561 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 20562 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 20563 } else if (!strcasecmp(v->name, "dtmfmode")) { 20564 ast_set_flag(&mask[0], SIP_DTMF); 20565 ast_clear_flag(&flags[0], SIP_DTMF); 20566 if (!strcasecmp(v->value, "inband")) 20567 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 20568 else if (!strcasecmp(v->value, "rfc2833")) 20569 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 20570 else if (!strcasecmp(v->value, "info")) 20571 ast_set_flag(&flags[0], SIP_DTMF_INFO); 20572 else if (!strcasecmp(v->value, "shortinfo")) 20573 ast_set_flag(&flags[0], SIP_DTMF_SHORTINFO); 20574 else if (!strcasecmp(v->value, "auto")) 20575 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 20576 else { 20577 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 20578 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 20579 } 20580 } else if (!strcasecmp(v->name, "nat")) { 20581 ast_set_flag(&mask[0], SIP_NAT); 20582 ast_clear_flag(&flags[0], SIP_NAT); 20583 if (!strcasecmp(v->value, "never")) 20584 ast_set_flag(&flags[0], SIP_NAT_NEVER); 20585 else if (!strcasecmp(v->value, "route")) 20586 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 20587 else if (ast_true(v->value)) 20588 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 20589 else 20590 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 20591 } else if (!strcasecmp(v->name, "canreinvite")) { 20592 ast_set_flag(&mask[0], SIP_REINVITE); 20593 ast_clear_flag(&flags[0], SIP_REINVITE); 20594 if (ast_true(v->value)) { 20595 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 20596 } else if (!ast_false(v->value)) { 20597 char buf[64]; 20598 char *word, *next = buf; 20599 20600 ast_copy_string(buf, v->value, sizeof(buf)); 20601 while ((word = strsep(&next, ","))) { 20602 if (!strcasecmp(word, "update")) { 20603 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 20604 } else if (!strcasecmp(word, "nonat")) { 20605 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 20606 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 20607 } else { 20608 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 20609 } 20610 } 20611 } 20612 } else if (!strcasecmp(v->name, "insecure")) { 20613 ast_set_flag(&mask[0], SIP_INSECURE); 20614 ast_clear_flag(&flags[0], SIP_INSECURE); 20615 set_insecure_flags(&flags[0], v->value, v->lineno); 20616 } else if (!strcasecmp(v->name, "progressinband")) { 20617 ast_set_flag(&mask[0], SIP_PROG_INBAND); 20618 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 20619 if (ast_true(v->value)) 20620 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 20621 else if (strcasecmp(v->value, "never")) 20622 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 20623 } else if (!strcasecmp(v->name, "promiscredir")) { 20624 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 20625 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 20626 } else if (!strcasecmp(v->name, "videosupport")) { 20627 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 20628 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 20629 } else if (!strcasecmp(v->name, "textsupport")) { 20630 ast_set_flag(&mask[1], SIP_PAGE2_TEXTSUPPORT); 20631 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_TEXTSUPPORT); 20632 res = 1; 20633 } else if (!strcasecmp(v->name, "allowoverlap")) { 20634 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 20635 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 20636 } else if (!strcasecmp(v->name, "allowsubscribe")) { 20637 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 20638 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 20639 } else if (!strcasecmp(v->name, "ignoresdpversion")) { 20640 ast_set_flag(&mask[1], SIP_PAGE2_IGNORESDPVERSION); 20641 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_IGNORESDPVERSION); 20642 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 20643 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 20644 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 20645 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 20646 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 20647 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 20648 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 20649 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 20650 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 20651 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 20652 #endif 20653 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 20654 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 20655 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 20656 } else if (!strcasecmp(v->name, "buggymwi")) { 20657 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 20658 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 20659 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 20660 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 20661 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 20662 } else 20663 res = 0; 20664 20665 return res; 20666 }
static int handle_incoming | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
struct sockaddr_in * | sin, | |||
int * | recount, | |||
int * | nounlock | |||
) | [static] |
Handle incoming SIP requests (methods).
Definition at line 18955 of file chan_sip.c.
References __sip_ack(), append_history, ast_debug, ast_inet_ntoa(), ast_log(), ast_skip_blanks(), ast_string_field_set, ast_strlen_zero(), ast_verbose(), check_pendings(), sip_request::debug, debug, DEFAULT_TRANS_TIMEOUT, 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_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::has_to_tag, sip_request::header, sip_request::headers, cfsip_methods::id, sip_request::ignore, sip_pvt::initreq, INV_TERMINATED, len(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_request::method, sip_pvt::needdestroy, process_sdp(), sip_request::rlPart1, sip_request::rlPart2, SDP_T38_NONE, SIP_ACK, SIP_BYE, SIP_CANCEL, sip_debug_test_pvt(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NOTIFY, SIP_OPTIONS, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_scheddestroy(), SIP_SUBSCRIBE, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, transmit_response(), transmit_response_reliable(), and transmit_response_with_allow().
Referenced by handle_request_do(), and process_request_queue().
18956 { 18957 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 18958 relatively static */ 18959 const char *cmd; 18960 const char *cseq; 18961 const char *useragent; 18962 int seqno; 18963 int len; 18964 int respid; 18965 int res = 0; 18966 int debug = sip_debug_test_pvt(p); 18967 char *e; 18968 int error = 0; 18969 18970 /* Get Method and Cseq */ 18971 cseq = get_header(req, "Cseq"); 18972 cmd = req->header[0]; 18973 18974 /* Must have Cseq */ 18975 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 18976 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 18977 error = 1; 18978 } 18979 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 18980 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 18981 error = 1; 18982 } 18983 if (error) { 18984 if (!p->initreq.headers) /* New call */ 18985 p->needdestroy = 1; /* Make sure we destroy this dialog */ 18986 return -1; 18987 } 18988 /* Get the command XXX */ 18989 18990 cmd = req->rlPart1; 18991 e = req->rlPart2; 18992 18993 /* Save useragent of the client */ 18994 useragent = get_header(req, "User-Agent"); 18995 if (!ast_strlen_zero(useragent)) 18996 ast_string_field_set(p, useragent, useragent); 18997 18998 /* Find out SIP method for incoming request */ 18999 if (req->method == SIP_RESPONSE) { /* Response to our request */ 19000 /* When we get here, we know this is a SIP dialog where we've sent 19001 * a request and have a response, or at least get a response 19002 * within an existing dialog. Do some sanity checks, then 19003 * possibly process the request. In all cases, there function 19004 * terminates at the end of this block 19005 */ 19006 int ret = 0; 19007 19008 if (p->ocseq < seqno && seqno != p->lastnoninvite) { 19009 ast_debug(1, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 19010 ret = -1; 19011 } else if (p->ocseq != seqno && seqno != p->lastnoninvite) { 19012 /* ignore means "don't do anything with it" but still have to 19013 * respond appropriately. 19014 * But in this case this is a response already, so we really 19015 * have nothing to do with this message, and even setting the 19016 * ignore flag is pointless. 19017 */ 19018 req->ignore = 1; 19019 append_history(p, "Ignore", "Ignoring this retransmit\n"); 19020 } else if (e) { 19021 e = ast_skip_blanks(e); 19022 if (sscanf(e, "%d %n", &respid, &len) != 1) { 19023 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 19024 /* XXX maybe should do ret = -1; */ 19025 } else if (respid <= 0) { 19026 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 19027 /* XXX maybe should do ret = -1; */ 19028 } else { /* finally, something worth processing */ 19029 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 19030 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 19031 extract_uri(p, req); 19032 handle_response(p, respid, e + len, req, seqno); 19033 } 19034 } 19035 return 0; 19036 } 19037 19038 /* New SIP request coming in 19039 (could be new request in existing SIP dialog as well...) 19040 */ 19041 19042 p->method = req->method; /* Find out which SIP method they are using */ 19043 ast_debug(4, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 19044 19045 if (p->icseq && (p->icseq > seqno) ) { 19046 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 19047 ast_debug(2, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 19048 } else { 19049 ast_debug(1, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 19050 if (req->method != SIP_ACK) 19051 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 19052 return -1; 19053 } 19054 } else if (p->icseq && 19055 p->icseq == seqno && 19056 req->method != SIP_ACK && 19057 (p->method != SIP_CANCEL || p->alreadygone)) { 19058 /* ignore means "don't do anything with it" but still have to 19059 respond appropriately. We do this if we receive a repeat of 19060 the last sequence number */ 19061 req->ignore = 1; 19062 ast_debug(3, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 19063 } 19064 19065 if (seqno >= p->icseq) 19066 /* Next should follow monotonically (but not necessarily 19067 incrementally -- thanks again to the genius authors of SIP -- 19068 increasing */ 19069 p->icseq = seqno; 19070 19071 /* Find their tag if we haven't got it */ 19072 if (ast_strlen_zero(p->theirtag)) { 19073 char tag[128]; 19074 19075 gettag(req, "From", tag, sizeof(tag)); 19076 ast_string_field_set(p, theirtag, tag); 19077 } 19078 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 19079 19080 if (pedanticsipchecking) { 19081 /* If this is a request packet without a from tag, it's not 19082 correct according to RFC 3261 */ 19083 /* Check if this a new request in a new dialog with a totag already attached to it, 19084 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 19085 if (!p->initreq.headers && req->has_to_tag) { 19086 /* If this is a first request and it got a to-tag, it is not for us */ 19087 if (!req->ignore && req->method == SIP_INVITE) { 19088 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 19089 /* Will cease to exist after ACK */ 19090 } else if (req->method != SIP_ACK) { 19091 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 19092 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 19093 } else { 19094 ast_debug(1, "Got ACK for unknown dialog... strange.\n"); 19095 } 19096 return res; 19097 } 19098 } 19099 19100 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 19101 transmit_response(p, "400 Bad request", req); 19102 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 19103 return -1; 19104 } 19105 19106 /* Handle various incoming SIP methods in requests */ 19107 switch (p->method) { 19108 case SIP_OPTIONS: 19109 res = handle_request_options(p, req); 19110 break; 19111 case SIP_INVITE: 19112 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 19113 break; 19114 case SIP_REFER: 19115 res = handle_request_refer(p, req, debug, seqno, nounlock); 19116 break; 19117 case SIP_CANCEL: 19118 res = handle_request_cancel(p, req); 19119 break; 19120 case SIP_BYE: 19121 res = handle_request_bye(p, req); 19122 break; 19123 case SIP_MESSAGE: 19124 res = handle_request_message(p, req); 19125 break; 19126 case SIP_SUBSCRIBE: 19127 res = handle_request_subscribe(p, req, sin, seqno, e); 19128 break; 19129 case SIP_REGISTER: 19130 res = handle_request_register(p, req, sin, e); 19131 break; 19132 case SIP_INFO: 19133 if (req->debug) 19134 ast_verbose("Receiving INFO!\n"); 19135 if (!req->ignore) 19136 handle_request_info(p, req); 19137 else /* if ignoring, transmit response */ 19138 transmit_response(p, "200 OK", req); 19139 break; 19140 case SIP_NOTIFY: 19141 res = handle_request_notify(p, req, sin, seqno, e); 19142 break; 19143 case SIP_ACK: 19144 /* Make sure we don't ignore this */ 19145 if (seqno == p->pendinginvite) { 19146 p->invitestate = INV_TERMINATED; 19147 p->pendinginvite = 0; 19148 __sip_ack(p, seqno, 1 /* response */, 0); 19149 if (find_sdp(req)) { 19150 if (process_sdp(p, req, SDP_T38_NONE)) 19151 return -1; 19152 } 19153 check_pendings(p); 19154 } else if (p->glareinvite == seqno) { 19155 /* handle ack for the 491 pending sent for glareinvite */ 19156 p->glareinvite = 0; 19157 __sip_ack(p, seqno, 1, 0); 19158 } 19159 /* Got an ACK that we did not match. Ignore silently */ 19160 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 19161 p->needdestroy = 1; 19162 break; 19163 default: 19164 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 19165 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 19166 cmd, ast_inet_ntoa(p->sa.sin_addr)); 19167 /* If this is some new method, and we don't have a call, destroy it now */ 19168 if (!p->initreq.headers) 19169 p->needdestroy = 1; 19170 break; 19171 } 19172 return res; 19173 }
static int handle_invite_replaces | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug, | |||
int | seqno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. Used only once. XXX 'ignore' is unused.
Definition at line 16776 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_masquerade(), ast_channel_unlock, ast_debug, ast_frfree, ast_hangup(), ast_log(), ast_quiet_chan(), ast_read(), ast_set_flag, ast_setstate(), ast_state2str(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, DEFAULT_TRANS_TIMEOUT, dialog_unref(), f, FALSE, sip_pvt::flags, sip_request::ignore, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::name, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_call, SIP_DEFER_BYE_ON_TRANSFER, sip_pvt_unlock, sip_scheddestroy(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), and XMIT_RELIABLE.
Referenced by handle_request_invite().
16777 { 16778 struct ast_frame *f; 16779 int earlyreplace = 0; 16780 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 16781 struct ast_channel *c = p->owner; /* Our incoming call */ 16782 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 16783 struct ast_channel *targetcall; /* The bridge to the take-over target */ 16784 16785 struct ast_channel *test; 16786 16787 /* Check if we're in ring state */ 16788 if (replacecall->_state == AST_STATE_RING) 16789 earlyreplace = 1; 16790 16791 /* Check if we have a bridge */ 16792 if (!(targetcall = ast_bridged_channel(replacecall))) { 16793 /* We have no bridge */ 16794 if (!earlyreplace) { 16795 ast_debug(2, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 16796 oneleggedreplace = 1; 16797 } 16798 } 16799 if (targetcall && targetcall->_state == AST_STATE_RINGING) 16800 ast_debug(4, "SIP transfer: Target channel is in ringing state\n"); 16801 16802 if (targetcall) 16803 ast_debug(4, "SIP transfer: Invite Replace incoming channel should bridge to channel %s while hanging up channel %s\n", targetcall->name, replacecall->name); 16804 else 16805 ast_debug(4, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 16806 16807 if (req->ignore) { 16808 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 16809 /* We should answer something here. If we are here, the 16810 call we are replacing exists, so an accepted 16811 can't harm */ 16812 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE); 16813 /* Do something more clever here */ 16814 ast_channel_unlock(c); 16815 sip_pvt_unlock(p->refer->refer_call); 16816 return 1; 16817 } 16818 if (!c) { 16819 /* What to do if no channel ??? */ 16820 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 16821 transmit_response_reliable(p, "503 Service Unavailable", req); 16822 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 16823 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16824 sip_pvt_unlock(p->refer->refer_call); 16825 return 1; 16826 } 16827 append_history(p, "Xfer", "INVITE/Replace received"); 16828 /* We have three channels to play with 16829 channel c: New incoming call 16830 targetcall: Call from PBX to target 16831 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 16832 replacecall: The owner of the previous 16833 We need to masq C into refer_call to connect to 16834 targetcall; 16835 If we are talking to internal audio stream, target call is null. 16836 */ 16837 16838 /* Fake call progress */ 16839 transmit_response(p, "100 Trying", req); 16840 ast_setstate(c, AST_STATE_RING); 16841 16842 /* Masquerade the new call into the referred call to connect to target call 16843 Targetcall is not touched by the masq */ 16844 16845 /* Answer the incoming call and set channel to UP state */ 16846 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE); 16847 16848 ast_setstate(c, AST_STATE_UP); 16849 16850 /* Stop music on hold and other generators */ 16851 ast_quiet_chan(replacecall); 16852 ast_quiet_chan(targetcall); 16853 ast_debug(4, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 16854 /* Unlock clone, but not original (replacecall) */ 16855 if (!oneleggedreplace) 16856 ast_channel_unlock(c); 16857 16858 /* Unlock PVT */ 16859 sip_pvt_unlock(p->refer->refer_call); 16860 16861 /* Make sure that the masq does not free our PVT for the old call */ 16862 if (! earlyreplace && ! oneleggedreplace ) 16863 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 16864 16865 /* Prepare the masquerade - if this does not happen, we will be gone */ 16866 if(ast_channel_masquerade(replacecall, c)) 16867 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 16868 else 16869 ast_debug(4, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 16870 16871 /* The masquerade will happen as soon as someone reads a frame from the channel */ 16872 16873 /* C should now be in place of replacecall */ 16874 /* ast_read needs to lock channel */ 16875 ast_channel_unlock(c); 16876 16877 if (earlyreplace || oneleggedreplace ) { 16878 /* Force the masq to happen */ 16879 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 16880 ast_frfree(f); 16881 f = NULL; 16882 ast_debug(4, "Invite/Replace: Could successfully read frame from RING channel!\n"); 16883 } else { 16884 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n"); 16885 } 16886 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 16887 if (!oneleggedreplace) 16888 ast_channel_unlock(replacecall); 16889 } else { /* Bridged call, UP channel */ 16890 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 16891 /* Masq ok */ 16892 ast_frfree(f); 16893 f = NULL; 16894 ast_debug(3, "Invite/Replace: Could successfully read frame from channel! Masq done.\n"); 16895 } else { 16896 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n"); 16897 } 16898 ast_channel_unlock(replacecall); 16899 } 16900 sip_pvt_unlock(p->refer->refer_call); 16901 16902 ast_setstate(c, AST_STATE_DOWN); 16903 ast_debug(4, "After transfer:----------------------------\n"); 16904 ast_debug(4, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 16905 if (replacecall) 16906 ast_debug(4, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 16907 if (p->owner) { 16908 ast_debug(4, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 16909 test = ast_bridged_channel(p->owner); 16910 if (test) 16911 ast_debug(4, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 16912 else 16913 ast_debug(4, " -- No call bridged to C->owner \n"); 16914 } else 16915 ast_debug(4, " -- No channel yet \n"); 16916 ast_debug(4, "End After transfer:----------------------------\n"); 16917 16918 ast_channel_unlock(p->owner); /* Unlock new owner */ 16919 if (!oneleggedreplace) 16920 sip_pvt_unlock(p); /* Unlock SIP structure */ 16921 16922 /* The call should be down with no ast_channel, so hang it up */ 16923 c->tech_pvt = dialog_unref(c->tech_pvt); 16924 ast_hangup(c); 16925 return 0; 16926 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 18485 of file chan_sip.c.
References __sip_pretend_ack(), append_history, ast_async_goto(), ast_bridged_channel(), ast_clear_flag, AST_CONTROL_UNHOLD, ast_debug, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_rtp_get_quality(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, sip_pvt::callid, check_via(), sip_pvt::context, copy_request(), DEFAULT_TRANS_TIMEOUT, sip_pvt::do_history, sip_pvt::flags, get_also_info(), get_header(), sip_request::ignore, sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, LOG_NOTICE, LOG_WARNING, sip_request::method, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_pvt::recv, sip_pvt::refer, sip_refer::refer_to, sip_pvt::rtp, sip_alreadygone(), sip_methods, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, sip_scheddestroy(), stop_media_flows(), stop_session_timer(), transmit_response(), transmit_response_reliable(), sip_pvt::trtp, and sip_pvt::vrtp.
Referenced by handle_incoming().
18486 { 18487 struct ast_channel *c=NULL; 18488 int res; 18489 struct ast_channel *bridged_to; 18490 18491 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 18492 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !req->ignore) { 18493 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 18494 } 18495 18496 __sip_pretend_ack(p); 18497 18498 p->invitestate = INV_TERMINATED; 18499 18500 copy_request(&p->initreq, req); 18501 if (sipdebug) 18502 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 18503 check_via(p, req); 18504 sip_alreadygone(p); 18505 18506 /* Get RTCP quality before end of call */ 18507 if (p->do_history || p->owner) { 18508 char *audioqos, *videoqos, *textqos; 18509 if (p->rtp) { 18510 audioqos = ast_rtp_get_quality(p->rtp, NULL); 18511 if (p->do_history) 18512 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 18513 if (p->owner) 18514 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 18515 } 18516 if (p->vrtp) { 18517 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 18518 if (p->do_history) 18519 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 18520 if (p->owner) 18521 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 18522 } 18523 if (p->trtp) { 18524 textqos = ast_rtp_get_quality(p->trtp, NULL); 18525 if (p->do_history) 18526 append_history(p, "RTCPtext", "Quality:%s", textqos); 18527 if (p->owner) 18528 pbx_builtin_setvar_helper(p->owner, "RTPTEXTQOS", textqos); 18529 } 18530 } 18531 18532 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 18533 stop_session_timer(p); /* Stop Session-Timer */ 18534 18535 if (!ast_strlen_zero(get_header(req, "Also"))) { 18536 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 18537 ast_inet_ntoa(p->recv.sin_addr)); 18538 if (ast_strlen_zero(p->context)) 18539 ast_string_field_set(p, context, default_context); 18540 res = get_also_info(p, req); 18541 if (!res) { 18542 c = p->owner; 18543 if (c) { 18544 bridged_to = ast_bridged_channel(c); 18545 if (bridged_to) { 18546 /* Don't actually hangup here... */ 18547 ast_queue_control(c, AST_CONTROL_UNHOLD); 18548 ast_async_goto(bridged_to, p->context, p->refer->refer_to, 1); 18549 } else 18550 ast_queue_hangup(p->owner); 18551 } 18552 } else { 18553 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 18554 if (p->owner) 18555 ast_queue_hangup(p->owner); 18556 } 18557 } else if (p->owner) { 18558 ast_queue_hangup(p->owner); 18559 ast_debug(3, "Received bye, issuing owner hangup\n"); 18560 } else { 18561 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 18562 ast_debug(3, "Received bye, no owner, selfdestruct soon.\n"); 18563 } 18564 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 18565 transmit_response(p, "200 OK", req); 18566 18567 return 1; 18568 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 18333 of file chan_sip.c.
References __sip_pretend_ack(), ast_debug, ast_free, ast_queue_hangup(), AST_SCHED_DEL, AST_STATE_UP, ast_test_flag, check_via(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, INV_CANCELLED, INV_TERMINATED, sip_pvt::invitestate, sip_pkt::next, sip_dual::req, sip_pkt::response_code, sip_pkt::retransid, sched, sip_pkt::seqno, sip_alreadygone(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and update_call_counter().
Referenced by handle_incoming().
18334 { 18335 18336 check_via(p, req); 18337 sip_alreadygone(p); 18338 18339 /* At this point, we could have cancelled the invite at the same time 18340 as the other side sends a CANCEL. Our final reply with error code 18341 might not have been received by the other side before the CANCEL 18342 was sent, so let's just give up retransmissions and waiting for 18343 ACK on our error code. The call is hanging up any way. */ 18344 if (p->invitestate == INV_TERMINATED) 18345 __sip_pretend_ack(p); 18346 else 18347 p->invitestate = INV_CANCELLED; 18348 18349 if (p->owner && p->owner->_state == AST_STATE_UP) { 18350 /* This call is up, cancel is ignored, we need a bye */ 18351 transmit_response(p, "200 OK", req); 18352 ast_debug(1, "Got CANCEL on an answered call. Ignoring... \n"); 18353 return 0; 18354 } 18355 18356 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 18357 update_call_counter(p, DEC_CALL_LIMIT); 18358 18359 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 18360 if (p->owner) 18361 ast_queue_hangup(p->owner); 18362 else 18363 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 18364 if (p->initreq.len > 0) { 18365 struct sip_pkt *pkt, *prev_pkt; 18366 /* If the CANCEL we are receiving is a retransmission, and we already have scheduled 18367 * a reliable 487, then we don't want to schedule another one on top of the previous 18368 * one. 18369 * 18370 * As odd as this may sound, we can't rely on the previously-transmitted "reliable" 18371 * response in this situation. What if we've sent all of our reliable responses 18372 * already and now all of a sudden, we get this second CANCEL? 18373 * 18374 * The only way to do this correctly is to cancel our previously-scheduled reliably- 18375 * transmitted response and send a new one in its place. 18376 */ 18377 for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->next) { 18378 if (pkt->seqno == p->lastinvite && pkt->response_code == 487) { 18379 AST_SCHED_DEL(sched, pkt->retransid); 18380 if (prev_pkt) { 18381 prev_pkt->next = pkt->next; 18382 } else { 18383 p->packets = pkt->next; 18384 } 18385 ast_free(pkt); 18386 break; 18387 } 18388 } 18389 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 18390 transmit_response(p, "200 OK", req); 18391 return 1; 18392 } else { 18393 transmit_response(p, "481 Call Leg Does Not Exist", req); 18394 return 0; 18395 } 18396 }
static int handle_request_do | ( | struct sip_request * | req, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 19297 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, ast_update_use_count(), ast_verbose(), sip_pvt::callid, copy_socket_data(), sip_request::data, sip_request::debug, sip_pvt::do_history, find_call(), find_sip_method(), get_header(), get_transport(), handle_incoming(), sip_request::headers, sip_request::len, sip_request::lines, LOG_ERROR, lws2sws(), sip_request::method, ast_channel::name, netlock, sip_pvt::owner, parse_request(), process_request_queue(), queue_request(), sip_pvt::recv, sip_pvt::request_queue, sip_pvt::request_queue_sched_id, sip_request::rlPart1, sip_request::rlPart2, S_OR, sched, SIP_ACK, sip_debug_test_addr(), sip_pvt_unlock, sip_pvt::socket, sip_request::socket, transmit_response(), and sip_socket::type.
Referenced by _sip_tcp_helper_thread(), and sipsock_read().
19298 { 19299 struct sip_pvt *p; 19300 int recount = 0; 19301 int nounlock = 0; 19302 int lockretry; 19303 19304 if (sip_debug_test_addr(sin)) /* Set the debug flag early on packet level */ 19305 req->debug = 1; 19306 if (pedanticsipchecking) 19307 req->len = lws2sws(req->data, req->len); /* Fix multiline headers */ 19308 if (req->debug) { 19309 ast_verbose("\n<--- SIP read from %s://%s:%d --->\n%s\n<------------->\n", 19310 get_transport(req->socket.type), ast_inet_ntoa(sin->sin_addr), 19311 ntohs(sin->sin_port), req->data); 19312 } 19313 19314 if (parse_request(req) == -1) { /* Bad packet, can't parse */ 19315 req->data[0] = '\0'; /* nulling this out is NOT a good idea here. */ 19316 return 1; 19317 } 19318 19319 req->method = find_sip_method(req->rlPart1); 19320 19321 if (req->debug) 19322 ast_verbose("--- (%d headers %d lines)%s ---\n", req->headers, req->lines, (req->headers + req->lines == 0) ? " Nat keepalive" : ""); 19323 19324 if (req->headers < 2) /* Must have at least two headers */ 19325 return 1; 19326 19327 /* Process request, with netlock held, and with usual deadlock avoidance */ 19328 for (lockretry = 10; lockretry > 0; lockretry--) { 19329 ast_mutex_lock(&netlock); 19330 19331 /* Find the active SIP dialog or create a new one */ 19332 p = find_call(req, sin, req->method); /* returns p locked */ 19333 if (p == NULL) { 19334 ast_debug(1, "Invalid SIP message - rejected , no callid, len %d\n", req->len); 19335 ast_mutex_unlock(&netlock); 19336 return 1; 19337 } 19338 19339 copy_socket_data(&p->socket, &req->socket); 19340 19341 /* Go ahead and lock the owner if it has one -- we may need it */ 19342 /* becaues this is deadlock-prone, we need to try and unlock if failed */ 19343 if (!p->owner || !ast_channel_trylock(p->owner)) 19344 break; /* locking succeeded */ 19345 if (lockretry != 1) { 19346 sip_pvt_unlock(p); 19347 ast_mutex_unlock(&netlock); 19348 /* Sleep for a very short amount of time */ 19349 usleep(1); 19350 } 19351 } 19352 p->recv = *sin; 19353 19354 if (p->do_history) /* This is a request or response, note what it was for */ 19355 append_history(p, "Rx", "%s / %s / %s", req->data, get_header(req, "CSeq"), req->rlPart2); 19356 19357 if (!lockretry) { 19358 if (!queue_request(p, req)) { 19359 /* the request has been queued for later handling */ 19360 sip_pvt_unlock(p); 19361 ast_mutex_unlock(&netlock); 19362 return 1; 19363 } 19364 19365 /* This is unsafe, since p->owner is not locked. */ 19366 if (p->owner) 19367 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 ??? - ")); 19368 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 19369 if (req->method != SIP_ACK) 19370 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 19371 /* XXX We could add retry-after to make sure they come back */ 19372 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 19373 sip_pvt_unlock(p); 19374 ast_mutex_unlock(&netlock); 19375 return 1; 19376 } 19377 19378 /* if there are queued requests on this sip_pvt, process them first, so that everything is 19379 handled in order 19380 */ 19381 if (!AST_LIST_EMPTY(&p->request_queue)) { 19382 AST_SCHED_DEL(sched, p->request_queue_sched_id); 19383 process_request_queue(p, &recount, &nounlock); 19384 } 19385 19386 if (handle_incoming(p, req, sin, &recount, &nounlock) == -1) { 19387 /* Request failed */ 19388 ast_debug(1, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 19389 } 19390 19391 if (recount) 19392 ast_update_use_count(); 19393 19394 if (p->owner && !nounlock) 19395 ast_channel_unlock(p->owner); 19396 sip_pvt_unlock(p); 19397 ast_mutex_unlock(&netlock); 19398 19399 return 1; 19400 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 14313 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(), buf, sip_pvt::callid, ast_channel::cdr, DEFAULT_TRANS_TIMEOUT, sip_history::event, ast_call_feature::exten, f, sip_pvt::flags, get_body(), get_header(), get_msg_text(), LOG_WARNING, sip_pvt::owner, sip_scheddestroy(), SIP_USECLIENTCODE, and transmit_response().
Referenced by handle_incoming().
14314 { 14315 char buf[1024]; 14316 unsigned int event; 14317 const char *c = get_header(req, "Content-Type"); 14318 14319 /* Need to check the media/type */ 14320 if (!strcasecmp(c, "application/dtmf-relay") || 14321 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 14322 unsigned int duration = 0; 14323 14324 if (!p->owner) { /* not a PBX call */ 14325 transmit_response(p, "481 Call leg/transaction does not exist", req); 14326 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14327 return; 14328 } 14329 14330 /* Try getting the "signal=" part */ 14331 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 14332 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 14333 transmit_response(p, "200 OK", req); /* Should return error */ 14334 return; 14335 } else { 14336 ast_copy_string(buf, c, sizeof(buf)); 14337 } 14338 14339 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 14340 duration = atoi(c); 14341 if (!duration) 14342 duration = 100; /* 100 ms */ 14343 14344 14345 if (ast_strlen_zero(buf)) { 14346 transmit_response(p, "200 OK", req); 14347 return; 14348 } 14349 14350 if (buf[0] == '*') 14351 event = 10; 14352 else if (buf[0] == '#') 14353 event = 11; 14354 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 14355 event = 12 + buf[0] - 'A'; 14356 else if (buf[0] == '!') 14357 event = 16; 14358 else 14359 event = atoi(buf); 14360 if (event == 16) { 14361 /* send a FLASH event */ 14362 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 14363 ast_queue_frame(p->owner, &f); 14364 if (sipdebug) 14365 ast_verbose("* DTMF-relay event received: FLASH\n"); 14366 } else { 14367 /* send a DTMF event */ 14368 struct ast_frame f = { AST_FRAME_DTMF, }; 14369 if (event < 10) { 14370 f.subclass = '0' + event; 14371 } else if (event < 11) { 14372 f.subclass = '*'; 14373 } else if (event < 12) { 14374 f.subclass = '#'; 14375 } else if (event < 16) { 14376 f.subclass = 'A' + (event - 12); 14377 } 14378 f.len = duration; 14379 ast_queue_frame(p->owner, &f); 14380 if (sipdebug) 14381 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 14382 } 14383 transmit_response(p, "200 OK", req); 14384 return; 14385 } else if (!strcasecmp(c, "application/dtmf")) { 14386 /*! \todo Note: Doesn't read the duration of the DTMF. Should be fixed. */ 14387 unsigned int duration = 0; 14388 14389 if (!p->owner) { /* not a PBX call */ 14390 transmit_response(p, "481 Call leg/transaction does not exist", req); 14391 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14392 return; 14393 } 14394 14395 get_msg_text(buf, sizeof(buf), req); 14396 duration = 100; /* 100 ms */ 14397 14398 if (ast_strlen_zero(buf)) { 14399 transmit_response(p, "200 OK", req); 14400 return; 14401 } 14402 event = atoi(buf); 14403 if (event == 16) { 14404 /* send a FLASH event */ 14405 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 14406 ast_queue_frame(p->owner, &f); 14407 if (sipdebug) 14408 ast_verbose("* DTMF-relay event received: FLASH\n"); 14409 } else { 14410 /* send a DTMF event */ 14411 struct ast_frame f = { AST_FRAME_DTMF, }; 14412 if (event < 10) { 14413 f.subclass = '0' + event; 14414 } else if (event < 11) { 14415 f.subclass = '*'; 14416 } else if (event < 12) { 14417 f.subclass = '#'; 14418 } else if (event < 16) { 14419 f.subclass = 'A' + (event - 12); 14420 } 14421 f.len = duration; 14422 ast_queue_frame(p->owner, &f); 14423 if (sipdebug) 14424 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 14425 } 14426 transmit_response(p, "200 OK", req); 14427 return; 14428 14429 } else if (!strcasecmp(c, "application/media_control+xml")) { 14430 /* Eh, we'll just assume it's a fast picture update for now */ 14431 if (p->owner) 14432 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 14433 transmit_response(p, "200 OK", req); 14434 return; 14435 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 14436 /* Client code (from SNOM phone) */ 14437 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 14438 if (p->owner && p->owner->cdr) 14439 ast_cdr_setuserfield(p->owner, c); 14440 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 14441 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 14442 transmit_response(p, "200 OK", req); 14443 } else { 14444 transmit_response(p, "403 Forbidden", req); 14445 } 14446 return; 14447 } else if (!ast_strlen_zero(c = get_header(req, "Record"))) { 14448 /* INFO messages generated by some phones to start/stop recording 14449 on phone calls. 14450 OEJ: I think this should be something that is enabled/disabled 14451 per device. I don't want incoming callers to record calls in my 14452 pbx. 14453 */ 14454 /* first, get the feature string, if it exists */ 14455 struct ast_call_feature *feat; 14456 int j; 14457 struct ast_frame f = { AST_FRAME_DTMF, }; 14458 14459 ast_rdlock_call_features(); 14460 feat = ast_find_call_feature("automon"); 14461 if (!feat || ast_strlen_zero(feat->exten)) { 14462 ast_log(LOG_WARNING, "Recording requested, but no One Touch Monitor registered. (See features.conf)\n"); 14463 /* 403 means that we don't support this feature, so don't request it again */ 14464 transmit_response(p, "403 Forbidden", req); 14465 ast_unlock_call_features(); 14466 return; 14467 } 14468 /* Send the feature code to the PBX as DTMF, just like the handset had sent it */ 14469 f.len = 100; 14470 for (j=0; j < strlen(feat->exten); j++) { 14471 f.subclass = feat->exten[j]; 14472 ast_queue_frame(p->owner, &f); 14473 if (sipdebug) 14474 ast_verbose("* DTMF-relay event faked: %c\n", f.subclass); 14475 } 14476 ast_unlock_call_features(); 14477 14478 ast_debug(1, "Got a Request to Record the channel, state %s\n", c); 14479 transmit_response(p, "200 OK", req); 14480 return; 14481 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 14482 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 14483 transmit_response(p, "200 OK", req); 14484 return; 14485 } 14486 14487 /* Other type of INFO message, not really understood by Asterisk */ 14488 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 14489 14490 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 14491 transmit_response(p, "415 Unsupported media type", req); 14492 return; 14493 }
static int handle_request_invite | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug, | |||
int | seqno, | |||
struct sockaddr_in * | sin, | |||
int * | recount, | |||
char * | e, | |||
int * | nounlock | |||
) | [static] |
Handle incoming INVITE request.
Definition at line 17229 of file chan_sip.c.
References __sip_ack(), ast_channel::_state, append_history, AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_clear_flag, AST_CONTROL_BUSY, ast_debug, ast_hangup(), ast_log(), ast_null_frame, 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_set_alt_peer(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_sched_add(), ast_set_flag, ast_setstate(), 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(), AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, bindaddr, build_contact(), build_route(), ast_channel::call_forward, sip_pvt::callid, t38properties::capability, sip_pvt::capability, check_user(), check_via(), sip_pvt::context, copy_request(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, dialog_unref(), sip_pvt::do_history, exten, sip_pvt::exten, extract_uri(), FALSE, find_sdp(), sip_pvt::flags, get_destination(), get_header(), get_ip_and_port_from_sdp(), get_rdnis(), get_sip_pvt_byid_locked(), sip_pvt::glareinvite, handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, sip_request::ignore, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_CONFIRMED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, io, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::lastinvite, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_our_tag(), sip_request::method, msg, ast_channel::name, sip_pvt::owner, parse_minse(), parse_ok_contact(), parse_session_expires(), parse_sip_options(), sip_pvt::peername, sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_pvt::reqsipoptions, restart_session_timer(), sip_request::rlPart2, sip_pvt::rtp, S_OR, sched, SDP_AUDIO, SDP_T38_INITIATE, SDP_VIDEO, sip_pvt::session_modify, SESSION_TIMER_MODE_ACCEPT, SESSION_TIMER_MODE_ORIGINATE, SESSION_TIMER_MODE_REFUSE, SESSION_TIMER_REFRESHER_AUTO, SESSION_TIMER_REFRESHER_UAS, set_t38_capabilities(), sip_alreadygone(), sip_cancel_destroy(), SIP_DTMF, SIP_DTMF_RFC2833, SIP_INVITE, sip_methods, sip_new(), SIP_OPT_REPLACES, SIP_OPT_TIMER, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, sip_pvt_lock, sip_pvt_unlock, sip_refer_allocate(), sip_scheddestroy(), sip_st_alloc(), sip_t38_abort(), sip_uri_cmp(), sip_pvt::sipoptions, sip_st_dlg::st_active, sip_st_dlg::st_active_peer_ua, sip_st_dlg::st_expirys, st_get_mode(), st_get_refresher(), st_get_se(), sip_st_dlg::st_interval, sip_st_dlg::st_ref, start_session_timer(), t38properties::state, sip_pvt::stimer, strcasestr(), strsep(), sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_PEER_REINVITE, sip_pvt::t38id, sip_pvt::tag, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_minse(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, sip_pvt::udptl, update_call_counter(), sip_pvt::username, sip_pvt::vrtp, XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.
Referenced by handle_incoming().
17230 { 17231 int res = 1; 17232 int gotdest; 17233 const char *p_replaces; 17234 char *replace_id = NULL; 17235 const char *required; 17236 unsigned int required_profile = 0; 17237 struct ast_channel *c = NULL; /* New channel */ 17238 int reinvite = 0; 17239 int rtn; 17240 17241 const char *p_uac_se_hdr; /* UAC's Session-Expires header string */ 17242 const char *p_uac_min_se; /* UAC's requested Min-SE interval (char string) */ 17243 int uac_max_se = -1; /* UAC's Session-Expires in integer format */ 17244 int uac_min_se = -1; /* UAC's Min-SE in integer format */ 17245 int st_active = FALSE; /* Session-Timer on/off boolean */ 17246 int st_interval = 0; /* Session-Timer negotiated refresh interval */ 17247 enum st_refresher st_ref; /* Session-Timer session refresher */ 17248 int dlg_min_se = -1; 17249 st_ref = SESSION_TIMER_REFRESHER_AUTO; 17250 17251 /* Find out what they support */ 17252 if (!p->sipoptions) { 17253 const char *supported = get_header(req, "Supported"); 17254 if (!ast_strlen_zero(supported)) 17255 parse_sip_options(p, supported); 17256 } 17257 17258 /* Find out what they require */ 17259 required = get_header(req, "Require"); 17260 if (!ast_strlen_zero(required)) { 17261 required_profile = parse_sip_options(NULL, required); 17262 if (required_profile && required_profile != SIP_OPT_REPLACES && required_profile != SIP_OPT_TIMER) { 17263 /* At this point we only support REPLACES and Session-Timer */ 17264 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 17265 ast_log(LOG_WARNING, "Received SIP INVITE with unsupported required extension: %s\n", required); 17266 p->invitestate = INV_COMPLETED; 17267 if (!p->lastinvite) 17268 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17269 return -1; 17270 } 17271 } 17272 17273 /* The option tags may be present in Supported: or Require: headers. 17274 Include the Require: option tags for further processing as well */ 17275 p->sipoptions |= required_profile; 17276 p->reqsipoptions = required_profile; 17277 17278 /* Check if this is a loop */ 17279 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->invitestate != INV_TERMINATED && p->invitestate != INV_CONFIRMED)) { 17280 /* This is a call to ourself. Send ourselves an error code and stop 17281 processing immediately, as SIP really has no good mechanism for 17282 being able to call yourself */ 17283 /* If pedantic is on, we need to check the tags. If they're different, this is 17284 in fact a forked call through a SIP proxy somewhere. */ 17285 int different; 17286 if (pedanticsipchecking) 17287 different = sip_uri_cmp(p->initreq.rlPart2, req->rlPart2); 17288 else 17289 different = strcmp(p->initreq.rlPart2, req->rlPart2); 17290 if (!different) { 17291 transmit_response(p, "482 Loop Detected", req); 17292 p->invitestate = INV_COMPLETED; 17293 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17294 return 0; 17295 } else { 17296 /* This is a spiral. What we need to do is to just change the outgoing INVITE 17297 * so that it now routes to the new Request URI. Since we created the INVITE ourselves 17298 * that should be all we need to do. 17299 */ 17300 char *uri = ast_strdupa(req->rlPart2); 17301 char *at = strchr(uri, '@'); 17302 char *peerorhost; 17303 ast_debug(3, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", p->initreq.rlPart2, req->rlPart2); 17304 if (at) { 17305 *at = '\0'; 17306 } 17307 /* Parse out "sip:" */ 17308 if ((peerorhost = strchr(uri, ':'))) { 17309 *peerorhost++ = '\0'; 17310 } 17311 ast_string_field_set(p, theirtag, NULL); 17312 /* Treat this as if there were a call forward instead... 17313 */ 17314 ast_string_field_set(p->owner, call_forward, peerorhost); 17315 ast_queue_control(p->owner, AST_CONTROL_BUSY); 17316 return 0; 17317 } 17318 } 17319 17320 if (!req->ignore && p->pendinginvite) { 17321 if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 17322 /* We have received a reINVITE on an incoming call to which we have sent a 200 OK but not yet received 17323 * an ACK. According to RFC 5407, Section 3.1.4, the proper way to handle this race condition is to accept 17324 * the reINVITE since we have established a dialog. 17325 */ 17326 17327 /* Note that this will both clear the pendinginvite flag and cancel the 17328 * retransmission of the 200 OK. Basically, we're accepting this reINVITE as both an ACK 17329 * and a reINVITE in one request. 17330 * */ 17331 __sip_ack(p, p->lastinvite, 1, 0); 17332 } else { 17333 /* We already have a pending invite. Sorry. You are on hold. */ 17334 p->glareinvite = seqno; 17335 if (p->rtp && find_sdp(req)) { 17336 struct sockaddr_in sin; 17337 if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &sin)) { 17338 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Audio may not work properly on this call.\n"); 17339 } else { 17340 ast_rtp_set_alt_peer(p->rtp, &sin); 17341 } 17342 if (p->vrtp) { 17343 if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &sin)) { 17344 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Video may not work properly on this call.\n"); 17345 } else { 17346 ast_rtp_set_alt_peer(p->vrtp, &sin); 17347 } 17348 } 17349 } 17350 transmit_response_reliable(p, "491 Request Pending", req); 17351 ast_debug(1, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 17352 /* Don't destroy dialog here */ 17353 return 0; 17354 } 17355 } 17356 17357 p_replaces = get_header(req, "Replaces"); 17358 if (!ast_strlen_zero(p_replaces)) { 17359 /* We have a replaces header */ 17360 char *ptr; 17361 char *fromtag = NULL; 17362 char *totag = NULL; 17363 char *start, *to; 17364 int error = 0; 17365 17366 if (p->owner) { 17367 ast_debug(3, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 17368 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 17369 /* Do not destroy existing call */ 17370 return -1; 17371 } 17372 17373 if (sipdebug) 17374 ast_debug(3, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 17375 /* Create a buffer we can manipulate */ 17376 replace_id = ast_strdupa(p_replaces); 17377 ast_uri_decode(replace_id); 17378 17379 if (!p->refer && !sip_refer_allocate(p)) { 17380 transmit_response_reliable(p, "500 Server Internal Error", req); 17381 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 17382 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17383 p->invitestate = INV_COMPLETED; 17384 return -1; 17385 } 17386 17387 /* Todo: (When we find phones that support this) 17388 if the replaces header contains ";early-only" 17389 we can only replace the call in early 17390 stage, not after it's up. 17391 17392 If it's not in early mode, 486 Busy. 17393 */ 17394 17395 /* Skip leading whitespace */ 17396 replace_id = ast_skip_blanks(replace_id); 17397 17398 start = replace_id; 17399 while ( (ptr = strsep(&start, ";")) ) { 17400 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 17401 if ( (to = strcasestr(ptr, "to-tag=") ) ) 17402 totag = to + 7; /* skip the keyword */ 17403 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 17404 fromtag = to + 9; /* skip the keyword */ 17405 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 17406 } 17407 } 17408 17409 if (sipdebug) 17410 ast_debug(4, "Invite/replaces: Will use Replace-Call-ID : %s Fromtag: %s Totag: %s\n", replace_id, fromtag ? fromtag : "<no from tag>", totag ? totag : "<no to tag>"); 17411 17412 17413 /* Try to find call that we are replacing 17414 If we have a Replaces header, we need to cancel that call if we succeed with this call 17415 */ 17416 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 17417 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 17418 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 17419 error = 1; 17420 } 17421 17422 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 17423 17424 /* The matched call is the call from the transferer to Asterisk . 17425 We want to bridge the bridged part of the call to the 17426 incoming invite, thus taking over the refered call */ 17427 17428 if (p->refer->refer_call == p) { 17429 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 17430 p->refer->refer_call = dialog_unref(p->refer->refer_call); 17431 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 17432 error = 1; 17433 } 17434 17435 if (!error && !p->refer->refer_call->owner) { 17436 /* Oops, someting wrong anyway, no owner, no call */ 17437 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 17438 /* Check for better return code */ 17439 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req); 17440 error = 1; 17441 } 17442 17443 if (!error && 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 ) { 17444 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 17445 transmit_response_reliable(p, "603 Declined (Replaces)", req); 17446 error = 1; 17447 } 17448 17449 if (error) { /* Give up this dialog */ 17450 append_history(p, "Xfer", "INVITE/Replace Failed."); 17451 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17452 sip_pvt_unlock(p); 17453 if (p->refer->refer_call) { 17454 sip_pvt_unlock(p->refer->refer_call); 17455 if (p->refer->refer_call->owner) { 17456 ast_channel_unlock(p->refer->refer_call->owner); 17457 } 17458 } 17459 p->invitestate = INV_COMPLETED; 17460 return -1; 17461 } 17462 } 17463 17464 /* Check if this is an INVITE that sets up a new dialog or 17465 a re-invite in an existing dialog */ 17466 17467 if (!req->ignore) { 17468 int newcall = (p->initreq.headers ? TRUE : FALSE); 17469 17470 if (sip_cancel_destroy(p)) 17471 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 17472 /* This also counts as a pending invite */ 17473 p->pendinginvite = seqno; 17474 check_via(p, req); 17475 17476 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 17477 if (sipdebug) 17478 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 17479 if (!p->owner) { /* Not a re-invite */ 17480 if (debug) 17481 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 17482 if (newcall) 17483 append_history(p, "Invite", "New call: %s", p->callid); 17484 parse_ok_contact(p, req); 17485 } else { /* Re-invite on existing call */ 17486 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 17487 /* Handle SDP here if we already have an owner */ 17488 if (find_sdp(req)) { 17489 if (process_sdp(p, req, SDP_T38_INITIATE)) { 17490 transmit_response_reliable(p, "488 Not acceptable here", req); 17491 if (!p->lastinvite) 17492 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17493 return -1; 17494 } 17495 } else { 17496 p->jointcapability = p->capability; 17497 ast_debug(1, "Hm.... No sdp for the moment\n"); 17498 } 17499 if (p->do_history) /* This is a response, note what it was for */ 17500 append_history(p, "ReInv", "Re-invite received"); 17501 } 17502 } else if (debug) 17503 ast_verbose("Ignoring this INVITE request\n"); 17504 17505 17506 if (!p->lastinvite && !req->ignore && !p->owner) { 17507 /* This is a new invite */ 17508 /* Handle authentication if this is our first invite */ 17509 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 17510 if (res == AUTH_CHALLENGE_SENT) { 17511 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 17512 return 0; 17513 } 17514 if (res < 0) { /* Something failed in authentication */ 17515 if (res == AUTH_FAKE_AUTH) { 17516 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 17517 transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE); 17518 } else { 17519 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 17520 transmit_response_reliable(p, "403 Forbidden", req); 17521 } 17522 p->invitestate = INV_COMPLETED; 17523 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17524 ast_string_field_set(p, theirtag, NULL); 17525 return 0; 17526 } 17527 17528 /* If T38 is needed but not present, then make it magically appear */ 17529 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && !p->udptl && (p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr))) { 17530 set_t38_capabilities(p); 17531 p->t38.jointcapability = p->t38.capability; 17532 } 17533 17534 /* We have a succesful authentication, process the SDP portion if there is one */ 17535 if (find_sdp(req)) { 17536 if (process_sdp(p, req, SDP_T38_INITIATE)) { 17537 /* Unacceptable codecs */ 17538 transmit_response_reliable(p, "488 Not acceptable here", req); 17539 p->invitestate = INV_COMPLETED; 17540 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17541 ast_debug(1, "No compatible codecs for this SIP call.\n"); 17542 return -1; 17543 } 17544 } else { /* No SDP in invite, call control session */ 17545 p->jointcapability = p->capability; 17546 ast_debug(2, "No SDP in Invite, third party call control\n"); 17547 } 17548 17549 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 17550 /* This seems redundant ... see !p-owner above */ 17551 if (p->owner) 17552 ast_queue_frame(p->owner, &ast_null_frame); 17553 17554 17555 /* Initialize the context if it hasn't been already */ 17556 if (ast_strlen_zero(p->context)) 17557 ast_string_field_set(p, context, default_context); 17558 17559 17560 /* Check number of concurrent calls -vs- incoming limit HERE */ 17561 ast_debug(1, "Checking SIP call limits for device %s\n", p->username); 17562 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 17563 if (res < 0) { 17564 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 17565 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 17566 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17567 p->invitestate = INV_COMPLETED; 17568 } 17569 return 0; 17570 } 17571 gotdest = get_destination(p, NULL); /* Get destination right away */ 17572 get_rdnis(p, NULL); /* Get redirect information */ 17573 extract_uri(p, req); /* Get the Contact URI */ 17574 build_contact(p); /* Build our contact header */ 17575 17576 if (p->rtp) { 17577 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 17578 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 17579 } 17580 17581 if (!replace_id && gotdest) { /* No matching extension found */ 17582 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 17583 transmit_response_reliable(p, "484 Address Incomplete", req); 17584 else { 17585 char *decoded_exten = ast_strdupa(p->exten); 17586 17587 transmit_response_reliable(p, "404 Not Found", req); 17588 ast_uri_decode(decoded_exten); 17589 ast_log(LOG_NOTICE, "Call from '%s' to extension" 17590 " '%s' rejected because extension not found.\n", 17591 S_OR(p->username, p->peername), decoded_exten); 17592 } 17593 p->invitestate = INV_COMPLETED; 17594 update_call_counter(p, DEC_CALL_LIMIT); 17595 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17596 return 0; 17597 } else { 17598 17599 /* If no extension was specified, use the s one */ 17600 /* Basically for calling to IP/Host name only */ 17601 if (ast_strlen_zero(p->exten)) 17602 ast_string_field_set(p, exten, "s"); 17603 /* Initialize our tag */ 17604 17605 make_our_tag(p->tag, sizeof(p->tag)); 17606 /* First invitation - create the channel */ 17607 c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL)); 17608 *recount = 1; 17609 17610 /* Save Record-Route for any later requests we make on this dialogue */ 17611 build_route(p, req, 0); 17612 17613 if (c) { 17614 /* Pre-lock the call */ 17615 ast_channel_lock(c); 17616 } 17617 } 17618 } else { 17619 if (sipdebug) { 17620 if (!req->ignore) 17621 ast_debug(2, "Got a SIP re-invite for call %s\n", p->callid); 17622 else 17623 ast_debug(2, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 17624 } 17625 if (!req->ignore) 17626 reinvite = 1; 17627 c = p->owner; 17628 } 17629 17630 /* Session-Timers */ 17631 if (p->sipoptions == SIP_OPT_TIMER) { 17632 /* The UAC has requested session-timers for this session. Negotiate 17633 the session refresh interval and who will be the refresher */ 17634 ast_debug(2, "Incoming INVITE with 'timer' option enabled\n"); 17635 17636 /* Allocate Session-Timers struct w/in the dialog */ 17637 if (!p->stimer) 17638 sip_st_alloc(p); 17639 17640 /* Parse the Session-Expires header */ 17641 p_uac_se_hdr = get_header(req, "Session-Expires"); 17642 if (!ast_strlen_zero(p_uac_se_hdr)) { 17643 rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref); 17644 if (rtn != 0) { 17645 transmit_response_reliable(p, "400 Session-Expires Invalid Syntax", req); 17646 p->invitestate = INV_COMPLETED; 17647 if (!p->lastinvite) { 17648 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17649 } 17650 return -1; 17651 } 17652 } 17653 17654 /* Parse the Min-SE header */ 17655 p_uac_min_se = get_header(req, "Min-SE"); 17656 if (!ast_strlen_zero(p_uac_min_se)) { 17657 rtn = parse_minse(p_uac_min_se, &uac_min_se); 17658 if (rtn != 0) { 17659 transmit_response_reliable(p, "400 Min-SE Invalid Syntax", req); 17660 p->invitestate = INV_COMPLETED; 17661 if (!p->lastinvite) { 17662 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17663 } 17664 return -1; 17665 } 17666 } 17667 17668 dlg_min_se = st_get_se(p, FALSE); 17669 switch (st_get_mode(p)) { 17670 case SESSION_TIMER_MODE_ACCEPT: 17671 case SESSION_TIMER_MODE_ORIGINATE: 17672 if (uac_max_se > 0 && uac_max_se < dlg_min_se) { 17673 transmit_response_with_minse(p, "422 Session Interval Too Small", req, dlg_min_se); 17674 p->invitestate = INV_COMPLETED; 17675 if (!p->lastinvite) { 17676 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17677 } 17678 return -1; 17679 } 17680 17681 p->stimer->st_active_peer_ua = TRUE; 17682 st_active = TRUE; 17683 if (st_ref == SESSION_TIMER_REFRESHER_AUTO) { 17684 st_ref = st_get_refresher(p); 17685 } 17686 17687 if (uac_max_se > 0) { 17688 int dlg_max_se = st_get_se(p, TRUE); 17689 if (dlg_max_se >= uac_min_se) { 17690 st_interval = (uac_max_se < dlg_max_se) ? uac_max_se : dlg_max_se; 17691 } else { 17692 st_interval = uac_max_se; 17693 } 17694 } else { 17695 st_interval = uac_min_se; 17696 } 17697 break; 17698 17699 case SESSION_TIMER_MODE_REFUSE: 17700 if (p->reqsipoptions == SIP_OPT_TIMER) { 17701 transmit_response_with_unsupported(p, "420 Option Disabled", req, required); 17702 ast_log(LOG_WARNING, "Received SIP INVITE with supported but disabled option: %s\n", required); 17703 p->invitestate = INV_COMPLETED; 17704 if (!p->lastinvite) { 17705 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17706 } 17707 return -1; 17708 } 17709 break; 17710 17711 default: 17712 ast_log(LOG_ERROR, "Internal Error %d at %s:%d\n", st_get_mode(p), __FILE__, __LINE__); 17713 break; 17714 } 17715 } else { 17716 /* The UAC did not request session-timers. Asterisk (UAS), will now decide 17717 (based on session-timer-mode in sip.conf) whether to run session-timers for 17718 this session or not. */ 17719 switch (st_get_mode(p)) { 17720 case SESSION_TIMER_MODE_ORIGINATE: 17721 st_active = TRUE; 17722 st_interval = st_get_se(p, TRUE); 17723 st_ref = SESSION_TIMER_REFRESHER_UAS; 17724 p->stimer->st_active_peer_ua = FALSE; 17725 break; 17726 17727 default: 17728 break; 17729 } 17730 } 17731 17732 if (reinvite == 0) { 17733 /* Session-Timers: Start session refresh timer based on negotiation/config */ 17734 if (st_active == TRUE) { 17735 p->stimer->st_active = TRUE; 17736 p->stimer->st_interval = st_interval; 17737 p->stimer->st_ref = st_ref; 17738 start_session_timer(p); 17739 } 17740 } else { 17741 if (p->stimer->st_active == TRUE) { 17742 /* Session-Timers: A re-invite request sent within a dialog will serve as 17743 a refresh request, no matter whether the re-invite was sent for refreshing 17744 the session or modifying it.*/ 17745 ast_debug (2, "Restarting session-timers on a refresh - %s\n", p->callid); 17746 17747 /* The UAC may be adjusting the session-timers mid-session */ 17748 if (st_interval > 0) { 17749 p->stimer->st_interval = st_interval; 17750 p->stimer->st_ref = st_ref; 17751 } 17752 17753 restart_session_timer(p); 17754 if (p->stimer->st_expirys > 0) { 17755 p->stimer->st_expirys--; 17756 } 17757 } 17758 } 17759 17760 if (!req->ignore && p) 17761 p->lastinvite = seqno; 17762 17763 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 17764 /* Go and take over the target call */ 17765 if (sipdebug) 17766 ast_debug(4, "Sending this call to the invite/replcaes handler %s\n", p->callid); 17767 return handle_invite_replaces(p, req, debug, seqno, sin); 17768 } 17769 17770 17771 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 17772 switch(c->_state) { 17773 case AST_STATE_DOWN: 17774 ast_debug(2, "%s: New call is still down.... Trying... \n", c->name); 17775 transmit_response(p, "100 Trying", req); 17776 p->invitestate = INV_PROCEEDING; 17777 ast_setstate(c, AST_STATE_RING); 17778 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 17779 enum ast_pbx_result res; 17780 17781 res = ast_pbx_start(c); 17782 17783 switch(res) { 17784 case AST_PBX_FAILED: 17785 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 17786 p->invitestate = INV_COMPLETED; 17787 transmit_response_reliable(p, "503 Unavailable", req); 17788 break; 17789 case AST_PBX_CALL_LIMIT: 17790 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 17791 p->invitestate = INV_COMPLETED; 17792 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 17793 break; 17794 case AST_PBX_SUCCESS: 17795 /* nothing to do */ 17796 break; 17797 } 17798 17799 if (res) { 17800 17801 /* Unlock locks so ast_hangup can do its magic */ 17802 ast_channel_unlock(c); 17803 sip_pvt_unlock(p); 17804 ast_hangup(c); 17805 sip_pvt_lock(p); 17806 c = NULL; 17807 } 17808 } else { /* Pickup call in call group */ 17809 ast_channel_unlock(c); 17810 *nounlock = 1; 17811 if (ast_pickup_call(c)) { 17812 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 17813 transmit_response_reliable(p, "503 Unavailable", req); 17814 sip_alreadygone(p); 17815 /* Unlock locks so ast_hangup can do its magic */ 17816 sip_pvt_unlock(p); 17817 c->hangupcause = AST_CAUSE_CALL_REJECTED; 17818 } else { 17819 sip_pvt_unlock(p); 17820 ast_setstate(c, AST_STATE_DOWN); 17821 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 17822 } 17823 p->invitestate = INV_COMPLETED; 17824 ast_hangup(c); 17825 sip_pvt_lock(p); 17826 c = NULL; 17827 } 17828 break; 17829 case AST_STATE_RING: 17830 transmit_response(p, "100 Trying", req); 17831 p->invitestate = INV_PROCEEDING; 17832 break; 17833 case AST_STATE_RINGING: 17834 if (reinvite && (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) { 17835 /* If these conditions are true, and the channel is still in the 'ringing' 17836 * state, then this likely means that we have a situation where the initial 17837 * INVITE transaction has completed *but* the channel's state has not yet been 17838 * changed to UP. The reason this could happen is if the reinvite is received 17839 * on the SIP socket prior to an application calling ast_read on this channel 17840 * to read the answer frame we earlier queued on it. In this case, the reinvite 17841 * is completely legitimate so we need to handle this the same as if the channel 17842 * were already UP. Thus we are purposely falling through to the AST_STATE_UP case. 17843 */ 17844 } else { 17845 transmit_response(p, "180 Ringing", req); 17846 p->invitestate = INV_PROCEEDING; 17847 break; 17848 } 17849 case AST_STATE_UP: 17850 ast_debug(2, "%s: This call is UP.... \n", c->name); 17851 17852 transmit_response(p, "100 Trying", req); 17853 17854 if (p->t38.state == T38_PEER_REINVITE) { 17855 p->t38id = ast_sched_add(sched, 5000, sip_t38_abort, p); 17856 } else if (p->t38.state == T38_ENABLED) { 17857 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 17858 transmit_response_with_t38_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 17859 } else if (p->t38.state == T38_DISABLED) { 17860 /* If this is not a re-invite or something to ignore - it's critical */ 17861 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 17862 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL)), p->session_modify == TRUE ? FALSE:TRUE); 17863 } 17864 17865 p->invitestate = INV_TERMINATED; 17866 break; 17867 default: 17868 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 17869 transmit_response(p, "100 Trying", req); 17870 break; 17871 } 17872 } else { 17873 if (p && (p->autokillid == -1)) { 17874 const char *msg; 17875 17876 if (!p->jointcapability) 17877 msg = "488 Not Acceptable Here (codec error)"; 17878 else { 17879 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 17880 msg = "503 Unavailable"; 17881 } 17882 transmit_response_reliable(p, msg, req); 17883 p->invitestate = INV_COMPLETED; 17884 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17885 } 17886 } 17887 return res; 17888 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 18571 of file chan_sip.c.
References ast_verbose(), sip_request::debug, sip_request::ignore, receive_message(), and transmit_response().
Referenced by handle_incoming().
18572 { 18573 if (!req->ignore) { 18574 if (req->debug) 18575 ast_verbose("Receiving message!\n"); 18576 receive_message(p, req); 18577 } else 18578 transmit_response(p, "202 Accepted", req); 18579 return 1; 18580 }
static int handle_request_notify | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
struct sockaddr_in * | sin, | |||
int | seqno, | |||
char * | e | |||
) | [static] |
Handle incoming notifications.
Definition at line 16598 of file chan_sip.c.
References ast_debug, ast_log(), ast_skip_blanks(), buf, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), get_msg_text(), sip_pvt::lastinvite, LOG_NOTICE, LOG_WARNING, sip_scheddestroy(), transmit_response(), and TRUE.
Referenced by handle_incoming().
16599 { 16600 /* This is mostly a skeleton for future improvements */ 16601 /* Mostly created to return proper answers on notifications on outbound REFER's */ 16602 int res = 0; 16603 const char *event = get_header(req, "Event"); 16604 char *eventid = NULL; 16605 char *sep; 16606 16607 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 16608 *sep++ = '\0'; 16609 eventid = sep; 16610 } 16611 16612 if (sipdebug) 16613 ast_debug(2, "Got NOTIFY Event: %s\n", event); 16614 16615 if (strcmp(event, "refer")) { 16616 /* We don't understand this event. */ 16617 /* Here's room to implement incoming voicemail notifications :-) */ 16618 transmit_response(p, "489 Bad event", req); 16619 res = -1; 16620 } else { 16621 /* Save nesting depth for now, since there might be other events we will 16622 support in the future */ 16623 16624 /* Handle REFER notifications */ 16625 16626 char buf[1024]; 16627 char *cmd, *code; 16628 int respcode; 16629 int success = TRUE; 16630 16631 /* EventID for each transfer... EventID is basically the REFER cseq 16632 16633 We are getting notifications on a call that we transfered 16634 We should hangup when we are getting a 200 OK in a sipfrag 16635 Check if we have an owner of this event */ 16636 16637 /* Check the content type */ 16638 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 16639 /* We need a sipfrag */ 16640 transmit_response(p, "400 Bad request", req); 16641 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16642 return -1; 16643 } 16644 16645 /* Get the text of the attachment */ 16646 if (get_msg_text(buf, sizeof(buf), req)) { 16647 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 16648 transmit_response(p, "400 Bad request", req); 16649 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16650 return -1; 16651 } 16652 16653 /* 16654 From the RFC... 16655 A minimal, but complete, implementation can respond with a single 16656 NOTIFY containing either the body: 16657 SIP/2.0 100 Trying 16658 16659 if the subscription is pending, the body: 16660 SIP/2.0 200 OK 16661 if the reference was successful, the body: 16662 SIP/2.0 503 Service Unavailable 16663 if the reference failed, or the body: 16664 SIP/2.0 603 Declined 16665 16666 if the REFER request was accepted before approval to follow the 16667 reference could be obtained and that approval was subsequently denied 16668 (see Section 2.4.7). 16669 16670 If there are several REFERs in the same dialog, we need to 16671 match the ID of the event header... 16672 */ 16673 ast_debug(3, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 16674 cmd = ast_skip_blanks(buf); 16675 code = cmd; 16676 /* We are at SIP/2.0 */ 16677 while(*code && (*code > 32)) { /* Search white space */ 16678 code++; 16679 } 16680 *code++ = '\0'; 16681 code = ast_skip_blanks(code); 16682 sep = code; 16683 sep++; 16684 while(*sep && (*sep > 32)) { /* Search white space */ 16685 sep++; 16686 } 16687 *sep++ = '\0'; /* Response string */ 16688 respcode = atoi(code); 16689 switch (respcode) { 16690 case 100: /* Trying: */ 16691 case 101: /* dialog establishment */ 16692 /* Don't do anything yet */ 16693 break; 16694 case 183: /* Ringing: */ 16695 /* Don't do anything yet */ 16696 break; 16697 case 200: /* OK: The new call is up, hangup this call */ 16698 /* Hangup the call that we are replacing */ 16699 break; 16700 case 301: /* Moved permenantly */ 16701 case 302: /* Moved temporarily */ 16702 /* Do we get the header in the packet in this case? */ 16703 success = FALSE; 16704 break; 16705 case 503: /* Service Unavailable: The new call failed */ 16706 /* Cancel transfer, continue the call */ 16707 success = FALSE; 16708 break; 16709 case 603: /* Declined: Not accepted */ 16710 /* Cancel transfer, continue the current call */ 16711 success = FALSE; 16712 break; 16713 } 16714 if (!success) { 16715 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 16716 } 16717 16718 /* Confirm that we received this packet */ 16719 transmit_response(p, "200 OK", req); 16720 }; 16721 16722 if (!p->lastinvite) 16723 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16724 16725 return res; 16726 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request An OPTIONS request should be answered like an INVITE from the same UA, including SDP.
XXX get_destination assumes we're already authenticated. This means that a request from a known device (peer/user) will end up in the wrong context if this is out-of-dialog. However, we want to handle OPTIONS as light as possible, so we might want to have a configuration option whether we care or not. Some devices use this for testing capabilities, which means that we need to match device to answer with proper capabilities (including SDP).
Definition at line 16731 of file chan_sip.c.
References ast_shutting_down(), ast_string_field_set, ast_strlen_zero(), build_contact(), sip_pvt::context, DEFAULT_TRANS_TIMEOUT, get_destination(), sip_pvt::lastinvite, sip_scheddestroy(), and transmit_response_with_allow().
Referenced by handle_incoming().
16732 { 16733 int res; 16734 16735 /*! XXX get_destination assumes we're already authenticated. This means that a request from 16736 a known device (peer/user) will end up in the wrong context if this is out-of-dialog. 16737 However, we want to handle OPTIONS as light as possible, so we might want to have 16738 a configuration option whether we care or not. Some devices use this for testing 16739 capabilities, which means that we need to match device to answer with proper 16740 capabilities (including SDP). 16741 \todo Fix handle_request_options device handling with optional authentication 16742 (this needs to be fixed in 1.4 as well) 16743 */ 16744 16745 if (p->lastinvite) { 16746 /* if this is a request in an active dialog, just confirm that the dialog exists. */ 16747 transmit_response_with_allow(p, "200 OK", req, 0); 16748 return 0; 16749 } 16750 16751 res = get_destination(p, req); 16752 build_contact(p); 16753 16754 if (ast_strlen_zero(p->context)) 16755 ast_string_field_set(p, context, default_context); 16756 16757 if (ast_shutting_down()) 16758 transmit_response_with_allow(p, "503 Unavailable", req, 0); 16759 else if (res < 0) 16760 transmit_response_with_allow(p, "404 Not Found", req, 0); 16761 else 16762 transmit_response_with_allow(p, "200 OK", req, 0); 16763 16764 /* Destroy if this OPTIONS was the opening request, but not if 16765 it's in the middle of a normal call flow. */ 16766 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16767 16768 return res; 16769 }
static int handle_request_refer | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug, | |||
int | seqno, | |||
int * | nounlock | |||
) | [static] |
Definition at line 18051 of file chan_sip.c.
References sip_pvt::allowtransfer, append_history, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_NORMAL_CLEARING, ast_channel_unlock, ast_clear_flag, AST_CONTROL_UNHOLD, ast_debug, AST_LIST_EMPTY, ast_parking_ext(), ast_queue_control(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_refer::attendedtransfer, sip_pvt::callid, sip_dual::chan1, sip_dual::chan2, check_sip_domain(), sip_pvt::context, copy_request(), sip_request::debug, EVENT_FLAG_CALL, FALSE, sip_pvt::flags, get_refer_info(), ast_channel::hangupcause, sip_request::ignore, local_attended_transfer(), sip_refer::localtransfer, manager_event, ast_channel::name, sip_pvt::needdestroy, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, REFER_200OK, REFER_FAILED, REFER_SENT, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::referred_by, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, sip_dual::req, sip_alreadygone(), SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_OUTGOING, sip_park(), sip_refer_allocate(), SIPBUFSIZE, sip_refer::status, TRANSFER_CLOSED, transmit_notify_with_sipfrag(), transmit_response(), TRUE, and ast_channel::uniqueid.
Referenced by handle_incoming().
18052 { 18053 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 18054 /* Chan2: Call between asterisk and transferee */ 18055 18056 int res = 0; 18057 18058 if (req->debug) 18059 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"); 18060 18061 if (!p->owner) { 18062 /* This is a REFER outside of an existing SIP dialog */ 18063 /* We can't handle that, so decline it */ 18064 ast_debug(3, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 18065 transmit_response(p, "603 Declined (No dialog)", req); 18066 if (!req->ignore) { 18067 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 18068 sip_alreadygone(p); 18069 p->needdestroy = 1; 18070 } 18071 return 0; 18072 } 18073 18074 18075 /* Check if transfer is allowed from this device */ 18076 if (p->allowtransfer == TRANSFER_CLOSED ) { 18077 /* Transfer not allowed, decline */ 18078 transmit_response(p, "603 Declined (policy)", req); 18079 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 18080 /* Do not destroy SIP session */ 18081 return 0; 18082 } 18083 18084 if (!req->ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 18085 /* Already have a pending REFER */ 18086 transmit_response(p, "491 Request pending", req); 18087 append_history(p, "Xfer", "Refer failed. Request pending."); 18088 return 0; 18089 } 18090 18091 /* Allocate memory for call transfer data */ 18092 if (!p->refer && !sip_refer_allocate(p)) { 18093 transmit_response(p, "500 Internal Server Error", req); 18094 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 18095 return -3; 18096 } 18097 18098 res = get_refer_info(p, req); /* Extract headers */ 18099 18100 p->refer->status = REFER_SENT; 18101 18102 if (res != 0) { 18103 switch (res) { 18104 case -2: /* Syntax error */ 18105 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 18106 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 18107 if (req->debug) 18108 ast_debug(1, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 18109 break; 18110 case -3: 18111 transmit_response(p, "603 Declined (Non sip: uri)", req); 18112 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 18113 if (req->debug) 18114 ast_debug(1, "SIP transfer to non-SIP uri denied\n"); 18115 break; 18116 default: 18117 /* Refer-to extension not found, fake a failed transfer */ 18118 transmit_response(p, "202 Accepted", req); 18119 append_history(p, "Xfer", "Refer failed. Bad extension."); 18120 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 18121 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 18122 if (req->debug) 18123 ast_debug(1, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 18124 break; 18125 } 18126 return 0; 18127 } 18128 if (ast_strlen_zero(p->context)) 18129 ast_string_field_set(p, context, default_context); 18130 18131 /* If we do not support SIP domains, all transfers are local */ 18132 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 18133 p->refer->localtransfer = 1; 18134 if (sipdebug) 18135 ast_debug(3, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 18136 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 18137 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 18138 p->refer->localtransfer = 1; 18139 } else if (sipdebug) 18140 ast_debug(3, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 18141 18142 /* Is this a repeat of a current request? Ignore it */ 18143 /* Don't know what else to do right now. */ 18144 if (req->ignore) 18145 return res; 18146 18147 /* If this is a blind transfer, we have the following 18148 channels to work with: 18149 - chan1, chan2: The current call between transferer and transferee (2 channels) 18150 - target_channel: A new call from the transferee to the target (1 channel) 18151 We need to stay tuned to what happens in order to be able 18152 to bring back the call to the transferer */ 18153 18154 /* If this is a attended transfer, we should have all call legs within reach: 18155 - chan1, chan2: The call between the transferer and transferee (2 channels) 18156 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 18157 We want to bridge chan2 with targetcall_pvt! 18158 18159 The replaces call id in the refer message points 18160 to the call leg between Asterisk and the transferer. 18161 So we need to connect the target and the transferee channel 18162 and hangup the two other channels silently 18163 18164 If the target is non-local, the call ID could be on a remote 18165 machine and we need to send an INVITE with replaces to the 18166 target. We basically handle this as a blind transfer 18167 and let the sip_call function catch that we need replaces 18168 header in the INVITE. 18169 */ 18170 18171 18172 /* Get the transferer's channel */ 18173 current.chan1 = p->owner; 18174 18175 /* Find the other part of the bridge (2) - transferee */ 18176 current.chan2 = ast_bridged_channel(current.chan1); 18177 18178 if (sipdebug) 18179 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>"); 18180 18181 if (!current.chan2 && !p->refer->attendedtransfer) { 18182 /* No bridged channel, propably IVR or echo or similar... */ 18183 /* Guess we should masquerade or something here */ 18184 /* Until we figure it out, refuse transfer of such calls */ 18185 if (sipdebug) 18186 ast_debug(3, "Refused SIP transfer on non-bridged channel.\n"); 18187 p->refer->status = REFER_FAILED; 18188 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 18189 transmit_response(p, "603 Declined", req); 18190 return -1; 18191 } 18192 18193 if (current.chan2) { 18194 if (sipdebug) 18195 ast_debug(4, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 18196 18197 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 18198 } 18199 18200 ast_set_flag(&p->flags[0], SIP_GOTREFER); 18201 18202 /* Attended transfer: Find all call legs and bridge transferee with target*/ 18203 if (p->refer->attendedtransfer) { 18204 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 18205 return res; /* We're done with the transfer */ 18206 /* Fall through for remote transfers that we did not find locally */ 18207 if (sipdebug) 18208 ast_debug(4, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 18209 /* Fallthrough if we can't find the call leg internally */ 18210 } 18211 18212 18213 /* Parking a call */ 18214 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 18215 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 18216 *nounlock = 1; 18217 ast_channel_unlock(current.chan1); 18218 copy_request(¤t.req, req); 18219 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 18220 p->refer->status = REFER_200OK; 18221 append_history(p, "Xfer", "REFER to call parking."); 18222 manager_event(EVENT_FLAG_CALL, "Transfer", "TransferMethod: SIP\r\nTransferType: Blind\r\nChannel: %s\r\nUniqueid: %s\r\nSIP-Callid: %s\r\nTargetChannel: %s\r\nTargetUniqueid: %s\r\nTransferExten: %s\r\nTransfer2Parking: Yes\r\n", 18223 current.chan1->name, 18224 current.chan1->uniqueid, 18225 p->callid, 18226 current.chan2->name, 18227 current.chan2->uniqueid, 18228 p->refer->refer_to); 18229 if (sipdebug) 18230 ast_debug(4, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 18231 sip_park(current.chan2, current.chan1, req, seqno); 18232 return res; 18233 } 18234 18235 /* Blind transfers and remote attended xfers */ 18236 transmit_response(p, "202 Accepted", req); 18237 18238 if (current.chan1 && current.chan2) { 18239 ast_debug(3, "chan1->name: %s\n", current.chan1->name); 18240 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 18241 } 18242 if (current.chan2) { 18243 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 18244 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 18245 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 18246 /* One for the new channel */ 18247 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 18248 /* Attended transfer to remote host, prepare headers for the INVITE */ 18249 if (p->refer->referred_by) 18250 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 18251 } 18252 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 18253 if (!ast_strlen_zero(p->refer->replaces_callid)) { 18254 char tempheader[SIPBUFSIZE]; 18255 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 18256 p->refer->replaces_callid_totag ? ";to-tag=" : "", 18257 p->refer->replaces_callid_totag, 18258 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 18259 p->refer->replaces_callid_fromtag); 18260 if (current.chan2) 18261 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 18262 } 18263 /* Must release lock now, because it will not longer 18264 be accessible after the transfer! */ 18265 *nounlock = 1; 18266 ast_channel_unlock(current.chan1); 18267 18268 /* Connect the call */ 18269 18270 /* FAKE ringing if not attended transfer */ 18271 if (!p->refer->attendedtransfer) 18272 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 18273 18274 /* For blind transfer, this will lead to a new call */ 18275 /* For attended transfer to remote host, this will lead to 18276 a new SIP call with a replaces header, if the dial plan allows it 18277 */ 18278 if (!current.chan2) { 18279 /* We have no bridge, so we're talking with Asterisk somehow */ 18280 /* We need to masquerade this call */ 18281 /* What to do to fix this situation: 18282 * Set up the new call in a new channel 18283 * Let the new channel masq into this channel 18284 Please add that code here :-) 18285 */ 18286 p->refer->status = REFER_FAILED; 18287 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 18288 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 18289 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 18290 return -1; 18291 } 18292 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 18293 18294 18295 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 18296 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 18297 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 18298 18299 if (!res) { 18300 manager_event(EVENT_FLAG_CALL, "Transfer", "TransferMethod: SIP\r\nTransferType: Blind\r\nChannel: %s\r\nUniqueid: %s\r\nSIP-Callid: %s\r\nTargetChannel: %s\r\nTargetUniqueid: %s\r\nTransferExten: %s\r\nTransferContext: %s\r\n", 18301 current.chan1->name, 18302 current.chan1->uniqueid, 18303 p->callid, 18304 current.chan2->name, 18305 current.chan2->uniqueid, 18306 p->refer->refer_to, p->refer->refer_to_context); 18307 /* Success - we have a new channel */ 18308 ast_debug(3, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 18309 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 18310 if (p->refer->localtransfer) 18311 p->refer->status = REFER_200OK; 18312 if (p->owner) 18313 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 18314 append_history(p, "Xfer", "Refer succeeded."); 18315 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 18316 /* Do not hangup call, the other side do that when we say 200 OK */ 18317 /* We could possibly implement a timer here, auto congestion */ 18318 res = 0; 18319 } else { 18320 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 18321 ast_debug(3, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 18322 append_history(p, "Xfer", "Refer failed."); 18323 /* Failure of some kind */ 18324 p->refer->status = REFER_FAILED; 18325 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 18326 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 18327 res = -1; 18328 } 18329 return res; 18330 }
static int handle_request_register | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
struct sockaddr_in * | sin, | |||
char * | e | |||
) | [static] |
Handle incoming REGISTER request.
Definition at line 18899 of file chan_sip.c.
References append_history, ast_debug, ast_inet_ntoa(), ast_log(), AUTH_ACL_FAILED, AUTH_BAD_TRANSPORT, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_pvt::callid, check_via(), copy_request(), DEFAULT_TRANS_TIMEOUT, get_header(), sip_pvt::initreq, LOG_NOTICE, sip_request::method, register_verify(), sip_methods, and sip_scheddestroy().
Referenced by handle_incoming().
18900 { 18901 enum check_auth_result res; 18902 18903 /* Use this as the basis */ 18904 copy_request(&p->initreq, req); 18905 if (sipdebug) 18906 ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 18907 check_via(p, req); 18908 if ((res = register_verify(p, sin, req, e)) < 0) { 18909 const char *reason; 18910 18911 switch (res) { 18912 case AUTH_SECRET_FAILED: 18913 reason = "Wrong password"; 18914 break; 18915 case AUTH_USERNAME_MISMATCH: 18916 reason = "Username/auth name mismatch"; 18917 break; 18918 case AUTH_NOT_FOUND: 18919 reason = "No matching peer found"; 18920 break; 18921 case AUTH_UNKNOWN_DOMAIN: 18922 reason = "Not a local domain"; 18923 break; 18924 case AUTH_PEER_NOT_DYNAMIC: 18925 reason = "Peer is not supposed to register"; 18926 break; 18927 case AUTH_ACL_FAILED: 18928 reason = "Device does not match ACL"; 18929 break; 18930 case AUTH_BAD_TRANSPORT: 18931 reason = "Device not configured to use this transport type"; 18932 break; 18933 default: 18934 reason = "Unknown failure"; 18935 break; 18936 } 18937 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 18938 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 18939 reason); 18940 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 18941 } else 18942 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 18943 18944 if (res < 1) { 18945 /* Destroy the session, but keep us around for just a bit in case they don't 18946 get our 200 OK */ 18947 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 18948 } 18949 return res; 18950 }
static int handle_request_subscribe | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
struct sockaddr_in * | sin, | |||
int | seqno, | |||
char * | e | |||
) | [static] |
Handle incoming SUBSCRIBE request.
Definition at line 18595 of file chan_sip.c.
References add_peer_mwi_subs(), append_history, ast_debug, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_extension_state_del(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), sip_pvt::callid, cb_extensionstate(), check_user_full(), check_via(), sip_pvt::context, copy_request(), CPIM_PIDF_XML, sip_request::debug, DIALOG_INFO_XML, dialoglist, dialoglist_lock(), dialoglist_unlock(), sip_pvt::dialogver, sip_pvt::expiry, sip_pvt::exten, FALSE, sip_peer::flags, sip_pvt::flags, get_destination(), get_header(), gettag(), sip_request::headers, sip_request::ignore, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, LOG_NOTICE, LOG_WARNING, sip_peer::mailboxes, make_our_tag(), sip_request::method, sip_peer::mwipvt, sip_peer::name, sip_pvt::needdestroy, sip_pvt::next, NONE, parse_ok_contact(), PIDF_XML, sip_pvt::relatedpeer, sip_pvt::sa, sip_cancel_destroy(), sip_destroy(), sip_methods, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_SUBSCRIBEMWIONLY, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sip_pvt::stateid, sip_pvt::subscribecontext, sip_pvt::subscribed, sip_pvt::subscribeuri, sip_pvt::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_state_notify(), unref_peer(), sip_pvt::useragent, sip_pvt::username, XMIT_UNRELIABLE, and XPIDF_XML.
Referenced by handle_incoming().
18596 { 18597 int gotdest = 0; 18598 int res = 0; 18599 int firststate = AST_EXTENSION_REMOVED; 18600 struct sip_peer *authpeer = NULL; 18601 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 18602 const char *accept = get_header(req, "Accept"); 18603 int resubscribe = (p->subscribed != NONE); 18604 char *temp, *event; 18605 18606 if (p->initreq.headers) { 18607 /* We already have a dialog */ 18608 if (p->initreq.method != SIP_SUBSCRIBE) { 18609 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 18610 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 18611 transmit_response(p, "403 Forbidden (within dialog)", req); 18612 /* Do not destroy session, since we will break the call if we do */ 18613 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); 18614 return 0; 18615 } else if (req->debug) { 18616 if (resubscribe) 18617 ast_debug(1, "Got a re-subscribe on existing subscription %s\n", p->callid); 18618 else 18619 ast_debug(1, "Got a new subscription %s (possibly with auth)\n", p->callid); 18620 } 18621 } 18622 18623 /* Check if we have a global disallow setting on subscriptions. 18624 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 18625 */ 18626 if (!global_allowsubscribe) { 18627 transmit_response(p, "403 Forbidden (policy)", req); 18628 p->needdestroy = 1; 18629 return 0; 18630 } 18631 18632 if (!req->ignore && !resubscribe) { /* Set up dialog, new subscription */ 18633 const char *to = get_header(req, "To"); 18634 char totag[128]; 18635 18636 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 18637 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 18638 if (req->debug) 18639 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 18640 transmit_response(p, "481 Subscription does not exist", req); 18641 p->needdestroy = 1; 18642 return 0; 18643 } 18644 18645 /* Use this as the basis */ 18646 if (req->debug) 18647 ast_verbose("Creating new subscription\n"); 18648 18649 copy_request(&p->initreq, req); 18650 if (sipdebug) 18651 ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 18652 check_via(p, req); 18653 } else if (req->debug && req->ignore) 18654 ast_verbose("Ignoring this SUBSCRIBE request\n"); 18655 18656 /* Find parameters to Event: header value and remove them for now */ 18657 if (ast_strlen_zero(eventheader)) { 18658 transmit_response(p, "489 Bad Event", req); 18659 ast_debug(2, "Received SIP subscribe for unknown event package: <none>\n"); 18660 p->needdestroy = 1; 18661 return 0; 18662 } 18663 18664 if ( (strchr(eventheader, ';'))) { 18665 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 18666 temp = strchr(event, ';'); 18667 *temp = '\0'; /* Remove any options for now */ 18668 /* We might need to use them later :-) */ 18669 } else 18670 event = (char *) eventheader; /* XXX is this legal ? */ 18671 18672 /* Handle authentication */ 18673 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 18674 /* if an authentication response was sent, we are done here */ 18675 if (res == AUTH_CHALLENGE_SENT) /* authpeer = NULL here */ 18676 return 0; 18677 if (res < 0) { 18678 if (res == AUTH_FAKE_AUTH) { 18679 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 18680 transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE); 18681 } else { 18682 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 18683 transmit_response_reliable(p, "403 Forbidden", req); 18684 } 18685 p->needdestroy = 1; 18686 return 0; 18687 } 18688 18689 /* At this point, authpeer cannot be NULL. Remember we hold a reference, 18690 * so we must release it when done. 18691 * XXX must remove all the checks for authpeer == NULL. 18692 */ 18693 18694 /* Check if this user/peer is allowed to subscribe at all */ 18695 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 18696 transmit_response(p, "403 Forbidden (policy)", req); 18697 p->needdestroy = 1; 18698 if (authpeer) 18699 unref_peer(authpeer); 18700 return 0; 18701 } 18702 18703 if (strcmp(event, "message-summary")) { 18704 /* Get destination right away */ 18705 gotdest = get_destination(p, NULL); 18706 } 18707 18708 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 18709 parse_ok_contact(p, req); 18710 18711 build_contact(p); 18712 if (gotdest) { 18713 transmit_response(p, "404 Not Found", req); 18714 p->needdestroy = 1; 18715 if (authpeer) 18716 unref_peer(authpeer); 18717 return 0; 18718 } 18719 18720 /* Initialize tag for new subscriptions */ 18721 if (ast_strlen_zero(p->tag)) 18722 make_our_tag(p->tag, sizeof(p->tag)); 18723 18724 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 18725 unsigned int pidf_xml; 18726 18727 if (authpeer) /* We do not need the authpeer any more */ 18728 unref_peer(authpeer); 18729 18730 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 18731 18732 pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0; 18733 18734 /* Older versions of Polycom firmware will claim pidf+xml, but really 18735 * they only support xpidf+xml. */ 18736 if (pidf_xml && strstr(p->useragent, "Polycom")) { 18737 p->subscribed = XPIDF_XML; 18738 } else if (pidf_xml) { 18739 p->subscribed = PIDF_XML; /* RFC 3863 format */ 18740 } else if (strstr(accept, "application/dialog-info+xml")) { 18741 p->subscribed = DIALOG_INFO_XML; 18742 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 18743 } else if (strstr(accept, "application/cpim-pidf+xml")) { 18744 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 18745 } else if (strstr(accept, "application/xpidf+xml")) { 18746 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 18747 } else if (ast_strlen_zero(accept)) { 18748 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 18749 transmit_response(p, "489 Bad Event", req); 18750 18751 ast_log(LOG_WARNING, "SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 18752 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 18753 p->needdestroy = 1; 18754 return 0; 18755 } 18756 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 18757 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 18758 } else { 18759 /* Can't find a format for events that we know about */ 18760 char mybuf[200]; 18761 snprintf(mybuf, sizeof(mybuf), "489 Bad Event (format %s)", accept); 18762 transmit_response(p, mybuf, req); 18763 18764 ast_log(LOG_WARNING, "SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 18765 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 18766 p->needdestroy = 1; 18767 return 0; 18768 } 18769 } else if (!strcmp(event, "message-summary")) { 18770 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 18771 /* Format requested that we do not support */ 18772 transmit_response(p, "406 Not Acceptable", req); 18773 ast_debug(2, "Received SIP mailbox subscription for unknown format: %s\n", accept); 18774 p->needdestroy = 1; 18775 if (authpeer) 18776 unref_peer(authpeer); 18777 return 0; 18778 } 18779 /* Looks like they actually want a mailbox status 18780 This version of Asterisk supports mailbox subscriptions 18781 The subscribed URI needs to exist in the dial plan 18782 In most devices, this is configurable to the voicemailmain extension you use 18783 */ 18784 if (!authpeer || AST_LIST_EMPTY(&authpeer->mailboxes)) { 18785 transmit_response(p, "404 Not found (no mailbox)", req); 18786 p->needdestroy = 1; 18787 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 18788 if (authpeer) 18789 unref_peer(authpeer); 18790 return 0; 18791 } 18792 18793 p->subscribed = MWI_NOTIFICATION; 18794 if (ast_test_flag(&authpeer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY)) { 18795 add_peer_mwi_subs(authpeer); 18796 } 18797 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 18798 /* We only allow one subscription per peer */ 18799 sip_destroy(authpeer->mwipvt); 18800 authpeer->mwipvt = p; /* Link from peer to pvt */ 18801 p->relatedpeer = authpeer; /* Link from pvt to peer */ 18802 /* Do not release authpeer here */ 18803 } else { /* At this point, Asterisk does not understand the specified event */ 18804 transmit_response(p, "489 Bad Event", req); 18805 ast_debug(2, "Received SIP subscribe for unknown event package: %s\n", event); 18806 p->needdestroy = 1; 18807 if (authpeer) 18808 unref_peer(authpeer); 18809 return 0; 18810 } 18811 18812 /* Add subscription for extension state from the PBX core */ 18813 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 18814 if (p->stateid > -1) 18815 ast_extension_state_del(p->stateid, cb_extensionstate); 18816 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 18817 } 18818 18819 if (!req->ignore && p) 18820 p->lastinvite = seqno; 18821 if (p && !p->needdestroy) { 18822 p->expiry = atoi(get_header(req, "Expires")); 18823 18824 /* check if the requested expiry-time is within the approved limits from sip.conf */ 18825 if (p->expiry > max_expiry) 18826 p->expiry = max_expiry; 18827 if (p->expiry < min_expiry && p->expiry > 0) 18828 p->expiry = min_expiry; 18829 18830 if (sipdebug) { 18831 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 18832 ast_debug(2, "Adding subscription for mailbox notification - peer %s\n", p->relatedpeer->name); 18833 else 18834 ast_debug(2, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 18835 } 18836 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 18837 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 18838 if (p->expiry > 0) 18839 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 18840 18841 if (p->subscribed == MWI_NOTIFICATION) { 18842 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 18843 transmit_response(p, "200 OK", req); 18844 if (p->relatedpeer) { /* Send first notification */ 18845 ASTOBJ_WRLOCK(p->relatedpeer); 18846 sip_send_mwi_to_peer(p->relatedpeer, NULL, 0); 18847 ASTOBJ_UNLOCK(p->relatedpeer); 18848 } 18849 } else { 18850 struct sip_pvt *p_old; 18851 18852 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 18853 18854 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_inet_ntoa(p->sa.sin_addr)); 18855 transmit_response(p, "404 Not found", req); 18856 p->needdestroy = 1; 18857 return 0; 18858 } 18859 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 18860 transmit_response(p, "200 OK", req); 18861 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 18862 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 18863 /* hide the 'complete' exten/context in the refer_to field for later display */ 18864 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 18865 18866 /* remove any old subscription from this peer for the same exten/context, 18867 as the peer has obviously forgotten about it and it's wasteful to wait 18868 for it to expire and send NOTIFY messages to the peer only to have them 18869 ignored (or generate errors) 18870 */ 18871 dialoglist_lock(); 18872 for (p_old = dialoglist; p_old; p_old = p_old->next) { 18873 if (p_old == p) 18874 continue; 18875 if (p_old->initreq.method != SIP_SUBSCRIBE) 18876 continue; 18877 if (p_old->subscribed == NONE) 18878 continue; 18879 sip_pvt_lock(p_old); 18880 if (!strcmp(p_old->username, p->username)) { 18881 if (!strcmp(p_old->exten, p->exten) && 18882 !strcmp(p_old->context, p->context)) { 18883 p_old->needdestroy = 1; 18884 sip_pvt_unlock(p_old); 18885 break; 18886 } 18887 } 18888 sip_pvt_unlock(p_old); 18889 } 18890 dialoglist_unlock(); 18891 } 18892 if (!p->expiry) 18893 p->needdestroy = 1; 18894 } 18895 return 1; 18896 }
static void handle_response | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Handle SIP response in dialogue.
Definition at line 15899 of file chan_sip.c.
References __sip_ack(), __sip_semi_ack(), ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_debug, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_set_flag, ast_skip_blanks(), ast_skip_nonblanks(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose(), ast_channel::call_forward, cb_extensionstate(), sip_pvt::context, sip_request::debug, do_proxy_auth(), sip_pvt::exten, FALSE, find_sdp(), find_sip_method(), sip_pvt::flags, get_header(), gettag(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, sip_request::ignore, sip_pvt::laststate, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, sip_pvt::method, msg, sip_pvt::needdestroy, NONE, sip_pvt::owner, parse_moved_contact(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_pvt::relatedpeer, SDP_T38_NONE, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_STATECHANGEQUEUE, SIP_REFER, SIP_REGISTER, SIP_SUBSCRIBE, stop_media_flows(), sip_pvt::subscribed, text, sip_pvt::theirtag, transmit_request(), and XMIT_UNRELIABLE.
15900 { 15901 struct ast_channel *owner; 15902 int sipmethod; 15903 int res = 1; 15904 const char *c = get_header(req, "Cseq"); 15905 /* 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 */ 15906 char *c_copy = ast_strdupa(c); 15907 /* Skip the Cseq and its subsequent spaces */ 15908 const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy)); 15909 15910 if (!msg) 15911 msg = ""; 15912 15913 sipmethod = find_sip_method(msg); 15914 15915 owner = p->owner; 15916 if (owner) 15917 owner->hangupcause = hangup_sip2cause(resp); 15918 15919 /* Acknowledge whatever it is destined for */ 15920 if ((resp >= 100) && (resp <= 199)) 15921 __sip_semi_ack(p, seqno, 0, sipmethod); 15922 else 15923 __sip_ack(p, seqno, 0, sipmethod); 15924 15925 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 15926 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 15927 p->pendinginvite = 0; 15928 15929 /* Get their tag if we haven't already */ 15930 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 15931 char tag[128]; 15932 15933 gettag(req, "To", tag, sizeof(tag)); 15934 ast_string_field_set(p, theirtag, tag); 15935 } 15936 /* This needs to be configurable on a channel/peer/user level, 15937 not mandatory for all communication. Sadly enough, NAT implementations 15938 are not so stable so we can always rely on these headers. 15939 Temporarily disabled, while waiting for fix. 15940 Fix assigned to Rizzo :-) 15941 */ 15942 /* check_via_response(p, req); */ 15943 15944 /* RFC 3261 Section 15 specifies that if we receive a 408 or 481 15945 * in response to a BYE, then we should end the current dialog 15946 * and session. It is known that at least one phone manufacturer 15947 * potentially will send a 404 in response to a BYE, so we'll be 15948 * liberal in what we accept and end the dialog and session if we 15949 * receive any of those responses to a BYE. 15950 */ 15951 if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) { 15952 p->needdestroy = 1; 15953 return; 15954 } 15955 15956 if (p->relatedpeer && p->method == SIP_OPTIONS) { 15957 /* We don't really care what the response is, just that it replied back. 15958 Well, as long as it's not a 100 response... since we might 15959 need to hang around for something more "definitive" */ 15960 if (resp != 100) 15961 handle_response_peerpoke(p, resp, req); 15962 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 15963 switch(resp) { 15964 case 100: /* 100 Trying */ 15965 case 101: /* 101 Dialog establishment */ 15966 if (sipmethod == SIP_INVITE) 15967 handle_response_invite(p, resp, rest, req, seqno); 15968 break; 15969 case 183: /* 183 Session Progress */ 15970 if (sipmethod == SIP_INVITE) 15971 handle_response_invite(p, resp, rest, req, seqno); 15972 break; 15973 case 180: /* 180 Ringing */ 15974 if (sipmethod == SIP_INVITE) 15975 handle_response_invite(p, resp, rest, req, seqno); 15976 break; 15977 case 182: /* 182 Queued */ 15978 if (sipmethod == SIP_INVITE) 15979 handle_response_invite(p, resp, rest, req, seqno); 15980 break; 15981 case 200: /* 200 OK */ 15982 p->authtries = 0; /* Reset authentication counter */ 15983 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 15984 /* We successfully transmitted a message 15985 or a video update request in INFO */ 15986 /* Nothing happens here - the message is inside a dialog */ 15987 } else if (sipmethod == SIP_INVITE) { 15988 handle_response_invite(p, resp, rest, req, seqno); 15989 } else if (sipmethod == SIP_NOTIFY) { 15990 /* They got the notify, this is the end */ 15991 if (p->owner) { 15992 if (!p->refer) { 15993 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 15994 ast_queue_hangup(p->owner); 15995 } else 15996 ast_debug(4, "Got OK on REFER Notify message\n"); 15997 } else { 15998 if (p->subscribed == NONE) 15999 p->needdestroy = 1; 16000 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 16001 /* Ready to send the next state we have on queue */ 16002 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 16003 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 16004 } 16005 } 16006 } else if (sipmethod == SIP_REGISTER) 16007 res = handle_response_register(p, resp, rest, req, seqno); 16008 else if (sipmethod == SIP_BYE) { /* Ok, we're ready to go */ 16009 p->needdestroy = 1; 16010 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 16011 } else if (sipmethod == SIP_SUBSCRIBE) { 16012 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 16013 } 16014 break; 16015 case 202: /* Transfer accepted */ 16016 if (sipmethod == SIP_REFER) 16017 handle_response_refer(p, resp, rest, req, seqno); 16018 break; 16019 case 401: /* Not www-authorized on SIP method */ 16020 case 407: /* Proxy auth required */ 16021 if (sipmethod == SIP_INVITE) 16022 handle_response_invite(p, resp, rest, req, seqno); 16023 else if (sipmethod == SIP_REFER) 16024 handle_response_refer(p, resp, rest, req, seqno); 16025 else if (p->registry && sipmethod == SIP_REGISTER) 16026 res = handle_response_register(p, resp, rest, req, seqno); 16027 else if (sipmethod == SIP_BYE) { 16028 if (p->options) 16029 p->options->auth_type = resp; 16030 if (ast_strlen_zero(p->authname)) { 16031 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 16032 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 16033 p->needdestroy = 1; 16034 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, sipmethod, 0)) { 16035 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 16036 p->needdestroy = 1; 16037 } 16038 } else { 16039 ast_log(LOG_WARNING, "Got authentication request (%d) on %s to '%s'\n", resp, sip_methods[sipmethod].text, get_header(req, "To")); 16040 p->needdestroy = 1; 16041 } 16042 break; 16043 case 403: /* Forbidden - we failed authentication */ 16044 if (sipmethod == SIP_INVITE) 16045 handle_response_invite(p, resp, rest, req, seqno); 16046 else if (p->registry && sipmethod == SIP_REGISTER) 16047 res = handle_response_register(p, resp, rest, req, seqno); 16048 else { 16049 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 16050 p->needdestroy = 1; 16051 } 16052 break; 16053 case 404: /* Not found */ 16054 if (p->registry && sipmethod == SIP_REGISTER) 16055 res = handle_response_register(p, resp, rest, req, seqno); 16056 else if (sipmethod == SIP_INVITE) 16057 handle_response_invite(p, resp, rest, req, seqno); 16058 else if (owner) 16059 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 16060 break; 16061 case 423: /* Interval too brief */ 16062 if (sipmethod == SIP_REGISTER) 16063 res = handle_response_register(p, resp, rest, req, seqno); 16064 break; 16065 case 408: /* Request timeout - terminate dialog */ 16066 if (sipmethod == SIP_INVITE) 16067 handle_response_invite(p, resp, rest, req, seqno); 16068 else if (sipmethod == SIP_REGISTER) 16069 res = handle_response_register(p, resp, rest, req, seqno); 16070 else if (sipmethod == SIP_BYE) { 16071 p->needdestroy = 1; 16072 ast_debug(4, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 16073 } else { 16074 if (owner) 16075 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 16076 p->needdestroy = 1; 16077 } 16078 break; 16079 16080 case 422: /* Session-Timers: Session Interval Too Small */ 16081 if (sipmethod == SIP_INVITE) { 16082 handle_response_invite(p, resp, rest, req, seqno); 16083 } 16084 break; 16085 16086 case 481: /* Call leg does not exist */ 16087 if (sipmethod == SIP_INVITE) { 16088 handle_response_invite(p, resp, rest, req, seqno); 16089 } else if (sipmethod == SIP_REFER) { 16090 handle_response_refer(p, resp, rest, req, seqno); 16091 } else if (sipmethod == SIP_BYE) { 16092 /* The other side has no transaction to bye, 16093 just assume it's all right then */ 16094 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 16095 } else if (sipmethod == SIP_CANCEL) { 16096 /* The other side has no transaction to cancel, 16097 just assume it's all right then */ 16098 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 16099 } else { 16100 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 16101 /* Guessing that this is not an important request */ 16102 } 16103 break; 16104 case 487: 16105 if (sipmethod == SIP_INVITE) 16106 handle_response_invite(p, resp, rest, req, seqno); 16107 break; 16108 case 488: /* Not acceptable here - codec error */ 16109 if (sipmethod == SIP_INVITE) 16110 handle_response_invite(p, resp, rest, req, seqno); 16111 break; 16112 case 491: /* Pending */ 16113 if (sipmethod == SIP_INVITE) 16114 handle_response_invite(p, resp, rest, req, seqno); 16115 else { 16116 ast_debug(1, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 16117 p->needdestroy = 1; 16118 } 16119 break; 16120 case 501: /* Not Implemented */ 16121 if (sipmethod == SIP_INVITE) 16122 handle_response_invite(p, resp, rest, req, seqno); 16123 else if (sipmethod == SIP_REFER) 16124 handle_response_refer(p, resp, rest, req, seqno); 16125 else 16126 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 16127 break; 16128 case 603: /* Declined transfer */ 16129 if (sipmethod == SIP_REFER) { 16130 handle_response_refer(p, resp, rest, req, seqno); 16131 break; 16132 } 16133 /* Fallthrough */ 16134 default: 16135 if ((resp >= 300) && (resp < 700)) { 16136 /* Fatal response */ 16137 if ((resp != 487)) 16138 ast_verb(3, "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 16139 16140 if (sipmethod == SIP_INVITE) 16141 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 16142 16143 /* XXX Locking issues?? XXX */ 16144 switch(resp) { 16145 case 300: /* Multiple Choices */ 16146 case 301: /* Moved permanently */ 16147 case 302: /* Moved temporarily */ 16148 case 305: /* Use Proxy */ 16149 parse_moved_contact(p, req); 16150 /* Fall through */ 16151 case 486: /* Busy here */ 16152 case 600: /* Busy everywhere */ 16153 case 603: /* Decline */ 16154 if (p->owner) 16155 ast_queue_control(p->owner, AST_CONTROL_BUSY); 16156 break; 16157 case 482: /*! 16158 \note SIP is incapable of performing a hairpin call, which 16159 is yet another failure of not having a layer 2 (again, YAY 16160 IETF for thinking ahead). So we treat this as a call 16161 forward and hope we end up at the right place... */ 16162 ast_debug(1, "Hairpin detected, setting up call forward for what it's worth\n"); 16163 if (p->owner) 16164 ast_string_field_build(p->owner, call_forward, 16165 "Local/%s@%s", p->username, p->context); 16166 /* Fall through */ 16167 case 480: /* Temporarily Unavailable */ 16168 case 404: /* Not Found */ 16169 case 410: /* Gone */ 16170 case 400: /* Bad Request */ 16171 case 500: /* Server error */ 16172 if (sipmethod == SIP_REFER) { 16173 handle_response_refer(p, resp, rest, req, seqno); 16174 break; 16175 } 16176 /* Fall through */ 16177 case 502: /* Bad gateway */ 16178 case 503: /* Service Unavailable */ 16179 case 504: /* Server Timeout */ 16180 if (owner) 16181 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 16182 break; 16183 default: 16184 /* Send hangup */ 16185 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 16186 ast_queue_hangup(p->owner); 16187 break; 16188 } 16189 /* ACK on invite */ 16190 if (sipmethod == SIP_INVITE) 16191 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 16192 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 16193 sip_alreadygone(p); 16194 if (!p->owner) 16195 p->needdestroy = 1; 16196 } else if ((resp >= 100) && (resp < 200)) { 16197 if (sipmethod == SIP_INVITE) { 16198 if (!req->ignore && sip_cancel_destroy(p)) 16199 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 16200 if (find_sdp(req)) 16201 process_sdp(p, req, SDP_T38_NONE); 16202 if (p->owner) { 16203 /* Queue a progress frame */ 16204 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 16205 } 16206 } 16207 } else 16208 ast_log(LOG_NOTICE, "Dont know how to handle a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : ast_inet_ntoa(p->sa.sin_addr)); 16209 } 16210 } else { 16211 /* Responses to OUTGOING SIP requests on INCOMING calls 16212 get handled here. As well as out-of-call message responses */ 16213 if (req->debug) 16214 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 16215 16216 if (sipmethod == SIP_INVITE && resp == 200) { 16217 /* Tags in early session is replaced by the tag in 200 OK, which is 16218 the final reply to our INVITE */ 16219 char tag[128]; 16220 16221 gettag(req, "To", tag, sizeof(tag)); 16222 ast_string_field_set(p, theirtag, tag); 16223 } 16224 16225 switch(resp) { 16226 case 200: 16227 if (sipmethod == SIP_INVITE) { 16228 handle_response_invite(p, resp, rest, req, seqno); 16229 } else if (sipmethod == SIP_CANCEL) { 16230 ast_debug(1, "Got 200 OK on CANCEL\n"); 16231 16232 /* Wait for 487, then destroy */ 16233 } else if (sipmethod == SIP_NOTIFY) { 16234 /* They got the notify, this is the end */ 16235 if (p->owner) { 16236 if (p->refer) { 16237 ast_debug(1, "Got 200 OK on NOTIFY for transfer\n"); 16238 } else 16239 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 16240 /* ast_queue_hangup(p->owner); Disabled */ 16241 } else { 16242 if (!p->subscribed && !p->refer) 16243 p->needdestroy = 1; 16244 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 16245 /* Ready to send the next state we have on queue */ 16246 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 16247 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 16248 } 16249 } 16250 } else if (sipmethod == SIP_BYE) 16251 p->needdestroy = 1; 16252 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 16253 /* We successfully transmitted a message or 16254 a video update request in INFO */ 16255 ; 16256 else if (sipmethod == SIP_BYE) 16257 /* Ok, we're ready to go */ 16258 p->needdestroy = 1; 16259 break; 16260 case 202: /* Transfer accepted */ 16261 if (sipmethod == SIP_REFER) 16262 handle_response_refer(p, resp, rest, req, seqno); 16263 break; 16264 case 401: /* www-auth */ 16265 case 407: 16266 if (sipmethod == SIP_REFER) 16267 handle_response_refer(p, resp, rest, req, seqno); 16268 else if (sipmethod == SIP_INVITE) 16269 handle_response_invite(p, resp, rest, req, seqno); 16270 else if (sipmethod == SIP_BYE) { 16271 if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, sipmethod, 0)) { 16272 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 16273 p->needdestroy = 1; 16274 } 16275 } 16276 break; 16277 case 481: /* Call leg does not exist */ 16278 if (sipmethod == SIP_INVITE) { 16279 /* Re-invite failed */ 16280 handle_response_invite(p, resp, rest, req, seqno); 16281 } else if (sipmethod == SIP_BYE) { 16282 p->needdestroy = 1; 16283 } else if (sipdebug) { 16284 ast_debug(1, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 16285 } 16286 break; 16287 case 501: /* Not Implemented */ 16288 if (sipmethod == SIP_INVITE) 16289 handle_response_invite(p, resp, rest, req, seqno); 16290 else if (sipmethod == SIP_REFER) 16291 handle_response_refer(p, resp, rest, req, seqno); 16292 break; 16293 case 603: /* Declined transfer */ 16294 if (sipmethod == SIP_REFER) { 16295 handle_response_refer(p, resp, rest, req, seqno); 16296 break; 16297 } 16298 /* Fallthrough */ 16299 default: /* Errors without handlers */ 16300 if ((resp >= 100) && (resp < 200)) { 16301 if (sipmethod == SIP_INVITE) { /* re-invite */ 16302 if (!req->ignore && sip_cancel_destroy(p)) 16303 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 16304 } 16305 } 16306 if ((resp >= 300) && (resp < 700)) { 16307 if ((resp != 487)) 16308 ast_verb(3, "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 16309 switch(resp) { 16310 case 488: /* Not acceptable here - codec error */ 16311 case 603: /* Decline */ 16312 case 500: /* Server error */ 16313 case 502: /* Bad gateway */ 16314 case 503: /* Service Unavailable */ 16315 case 504: /* Server timeout */ 16316 16317 /* re-invite failed */ 16318 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 16319 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 16320 break; 16321 } 16322 } 16323 break; 16324 } 16325 } 16326 }
static void handle_response_invite | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Handle SIP response to INVITE dialogue.
Definition at line 15333 of file chan_sip.c.
References ast_channel::_state, sip_pvt::alreadygone, append_history, AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_debug, ast_log(), ast_null_frame, ast_queue_control(), ast_queue_frame(), ast_queue_hangup(), ast_random(), ast_rtp_set_rtptimers_onhold(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_set, ast_strlen_zero(), ast_test_flag, sip_invite_param::auth_type, sip_pvt::authtries, build_route(), sip_pvt::callid, change_t38_state(), check_pendings(), DEC_CALL_LIMIT, DEC_CALL_RINGING, DEFAULT_TRANS_TIMEOUT, dialog_ref(), do_proxy_auth(), EVENT_FLAG_SYSTEM, FALSE, find_sdp(), sip_pvt::flags, sip_pvt::fullcontact, get_header(), sip_request::ignore, sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, LOG_NOTICE, LOG_WARNING, manager_event, MAX_AUTHTRIES, ast_channel::name, sip_pvt::needdestroy, sip_pvt::options, sip_pvt::outgoing_call, sip_pvt::owner, parse_ok_contact(), parse_session_expires(), sip_pvt::peername, sip_pvt::pendinginvite, proc_422_rsp(), process_sdp(), sched, SDP_T38_ACCEPT, SDP_T38_NONE, SESSION_TIMER_MODE_ORIGINATE, SESSION_TIMER_MODE_REFUSE, SESSION_TIMER_REFRESHER_AUTO, SESSION_TIMER_REFRESHER_UAC, SESSION_TIMER_REFRESHER_UAS, set_address_from_contact(), SIP_ACK, sip_alreadygone(), sip_cancel_destroy(), SIP_INVITE, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PENDINGBYE, sip_reinvite_retry(), sip_scheddestroy(), sip_st_dlg::st_active, sip_st_dlg::st_active_peer_ua, st_get_mode(), sip_st_dlg::st_interval, sip_st_dlg::st_ref, start_session_timer(), t38properties::state, sip_pvt::stimer, sip_pvt::t38, T38_DISABLED, T38_LOCAL_REINVITE, sip_pvt::theirtag, transmit_reinvite_with_sdp(), transmit_request(), TRUE, sip_pvt::udptl, ast_channel::uniqueid, update_call_counter(), sip_pvt::waitid, XMIT_ERROR, and XMIT_UNRELIABLE.
Referenced by handle_response().
15334 { 15335 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 15336 int res = 0; 15337 int xmitres = 0; 15338 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 15339 char *p_hdrval; 15340 int rtn; 15341 15342 if (reinvite) 15343 ast_debug(4, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 15344 else 15345 ast_debug(4, "SIP response %d to standard invite\n", resp); 15346 15347 if (p->alreadygone) { /* This call is already gone */ 15348 ast_debug(1, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 15349 return; 15350 } 15351 15352 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 15353 /* Don't auto congest anymore since we've gotten something useful back */ 15354 AST_SCHED_DEL(sched, p->initid); 15355 15356 /* RFC3261 says we must treat every 1xx response (but not 100) 15357 that we don't recognize as if it was 183. 15358 */ 15359 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183) 15360 resp = 183; 15361 15362 /* Any response between 100 and 199 is PROCEEDING */ 15363 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 15364 p->invitestate = INV_PROCEEDING; 15365 15366 /* Final response, not 200 ? */ 15367 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 15368 p->invitestate = INV_COMPLETED; 15369 15370 /* Final response, clear out pending invite */ 15371 if ((resp == 200 || resp >= 300) && p->pendinginvite && seqno == p->pendinginvite) 15372 p->pendinginvite = 0; 15373 15374 switch (resp) { 15375 case 100: /* Trying */ 15376 case 101: /* Dialog establishment */ 15377 if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p)) 15378 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15379 check_pendings(p); 15380 break; 15381 15382 case 180: /* 180 Ringing */ 15383 case 182: /* 182 Queued */ 15384 if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p)) 15385 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15386 if (!req->ignore && p->owner) { 15387 ast_queue_control(p->owner, AST_CONTROL_RINGING); 15388 if (p->owner->_state != AST_STATE_UP) { 15389 ast_setstate(p->owner, AST_STATE_RINGING); 15390 } 15391 } 15392 if (find_sdp(req)) { 15393 if (p->invitestate != INV_CANCELLED) 15394 p->invitestate = INV_EARLY_MEDIA; 15395 res = process_sdp(p, req, SDP_T38_NONE); 15396 if (!req->ignore && p->owner) { 15397 /* Queue a progress frame only if we have SDP in 180 or 182 */ 15398 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 15399 } 15400 } 15401 check_pendings(p); 15402 break; 15403 15404 case 183: /* Session progress */ 15405 if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 15406 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15407 /* Ignore 183 Session progress without SDP */ 15408 if (find_sdp(req)) { 15409 if (p->invitestate != INV_CANCELLED) 15410 p->invitestate = INV_EARLY_MEDIA; 15411 res = process_sdp(p, req, SDP_T38_NONE); 15412 if (!req->ignore && p->owner) { 15413 /* Queue a progress frame */ 15414 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 15415 } 15416 } 15417 check_pendings(p); 15418 break; 15419 15420 case 200: /* 200 OK on invite - someone's answering our call */ 15421 if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 15422 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15423 p->authtries = 0; 15424 if (find_sdp(req)) { 15425 if ((res = process_sdp(p, req, SDP_T38_ACCEPT)) && !req->ignore) 15426 if (!reinvite) 15427 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 15428 /* For re-invites, we try to recover */ 15429 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 15430 } 15431 15432 /* Parse contact header for continued conversation */ 15433 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 15434 /* This is important when we have a SIP proxy between us and the phone */ 15435 if (outgoing) { 15436 update_call_counter(p, DEC_CALL_RINGING); 15437 parse_ok_contact(p, req); 15438 /* Save Record-Route for any later requests we make on this dialogue */ 15439 if (!reinvite) 15440 build_route(p, req, 1); 15441 15442 if(set_address_from_contact(p)) { 15443 /* Bad contact - we don't know how to reach this device */ 15444 /* We need to ACK, but then send a bye */ 15445 if (!p->route && !req->ignore) 15446 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 15447 } 15448 15449 } 15450 15451 if (!req->ignore && p->owner) { 15452 if (!reinvite) { 15453 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 15454 if (global_callevents) 15455 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 15456 "Channel: %s\r\nChanneltype: %s\r\nUniqueid: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n", 15457 p->owner->name, "SIP", p->owner->uniqueid, p->callid, p->fullcontact, p->peername); 15458 } else { /* RE-invite */ 15459 ast_queue_frame(p->owner, &ast_null_frame); 15460 } 15461 } else { 15462 /* It's possible we're getting an 200 OK after we've tried to disconnect 15463 by sending CANCEL */ 15464 /* First send ACK, then send bye */ 15465 if (!req->ignore) 15466 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 15467 } 15468 15469 /* Check for Session-Timers related headers */ 15470 if (st_get_mode(p) != SESSION_TIMER_MODE_REFUSE && p->outgoing_call == TRUE && !reinvite) { 15471 p_hdrval = (char*)get_header(req, "Session-Expires"); 15472 if (!ast_strlen_zero(p_hdrval)) { 15473 /* UAS supports Session-Timers */ 15474 enum st_refresher tmp_st_ref = SESSION_TIMER_REFRESHER_AUTO; 15475 int tmp_st_interval = 0; 15476 rtn = parse_session_expires(p_hdrval, &tmp_st_interval, &tmp_st_ref); 15477 if (rtn != 0) { 15478 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 15479 } 15480 if (tmp_st_ref == SESSION_TIMER_REFRESHER_UAC || 15481 tmp_st_ref == SESSION_TIMER_REFRESHER_UAS) { 15482 p->stimer->st_ref = tmp_st_ref; 15483 } 15484 if (tmp_st_interval) { 15485 p->stimer->st_interval = tmp_st_interval; 15486 } 15487 p->stimer->st_active = TRUE; 15488 p->stimer->st_active_peer_ua = TRUE; 15489 start_session_timer(p); 15490 } else { 15491 /* UAS doesn't support Session-Timers */ 15492 if (st_get_mode(p) == SESSION_TIMER_MODE_ORIGINATE) { 15493 p->stimer->st_ref = SESSION_TIMER_REFRESHER_UAC; 15494 p->stimer->st_active_peer_ua = FALSE; 15495 start_session_timer(p); 15496 } 15497 } 15498 } 15499 15500 15501 /* If I understand this right, the branch is different for a non-200 ACK only */ 15502 p->invitestate = INV_TERMINATED; 15503 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15504 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 15505 check_pendings(p); 15506 break; 15507 15508 case 407: /* Proxy authentication */ 15509 case 401: /* Www auth */ 15510 /* First we ACK */ 15511 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 15512 if (p->options) 15513 p->options->auth_type = resp; 15514 15515 /* Then we AUTH */ 15516 ast_string_field_set(p, theirtag, NULL); /* forget their old tag, so we don't match tags when getting response */ 15517 if (!req->ignore) { 15518 if (p->authtries < MAX_AUTHTRIES) 15519 p->invitestate = INV_CALLING; 15520 if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, SIP_INVITE, 1)) { 15521 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 15522 p->needdestroy = 1; 15523 sip_alreadygone(p); 15524 if (p->owner) 15525 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 15526 } 15527 } 15528 break; 15529 15530 case 403: /* Forbidden */ 15531 /* First we ACK */ 15532 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 15533 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 15534 if (!req->ignore && p->owner) 15535 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 15536 p->needdestroy = 1; 15537 sip_alreadygone(p); 15538 break; 15539 15540 case 404: /* Not found */ 15541 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 15542 if (p->owner && !req->ignore) 15543 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 15544 sip_alreadygone(p); 15545 break; 15546 15547 case 408: /* Request timeout */ 15548 case 481: /* Call leg does not exist */ 15549 /* Could be REFER caused INVITE with replaces */ 15550 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 15551 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 15552 if (p->owner) 15553 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 15554 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15555 break; 15556 15557 case 422: /* Session-Timers: Session interval too small */ 15558 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 15559 ast_string_field_set(p, theirtag, NULL); 15560 proc_422_rsp(p, req); 15561 break; 15562 15563 case 487: /* Cancelled transaction */ 15564 /* We have sent CANCEL on an outbound INVITE 15565 This transaction is already scheduled to be killed by sip_hangup(). 15566 */ 15567 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 15568 if (p->owner && !req->ignore) { 15569 ast_queue_hangup(p->owner); 15570 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 15571 } else if (!req->ignore) { 15572 update_call_counter(p, DEC_CALL_LIMIT); 15573 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 15574 p->needdestroy = 1; 15575 sip_alreadygone(p); 15576 } 15577 break; 15578 case 488: /* Not acceptable here */ 15579 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 15580 if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) { 15581 change_t38_state(p, T38_DISABLED); 15582 /* Try to reset RTP timers */ 15583 ast_rtp_set_rtptimers_onhold(p->rtp); 15584 15585 /* Trigger a reinvite back to audio */ 15586 transmit_reinvite_with_sdp(p, FALSE, FALSE); 15587 } else { 15588 /* We can't set up this call, so give up */ 15589 if (p->owner && !req->ignore) 15590 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 15591 p->needdestroy = 1; 15592 /* If there's no dialog to end, then mark p as already gone */ 15593 if (!reinvite) 15594 sip_alreadygone(p); 15595 } 15596 break; 15597 case 491: /* Pending */ 15598 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 15599 if (p->owner && !req->ignore) { 15600 if (p->owner->_state != AST_STATE_UP) { 15601 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 15602 p->needdestroy = 1; 15603 } else { 15604 /* This is a re-invite that failed. */ 15605 /* Reset the flag after a while 15606 */ 15607 int wait; 15608 /* RFC 3261, if owner of call, wait between 2.1 to 4 seconds, 15609 * if not owner of call, wait 0 to 2 seconds */ 15610 if (p->outgoing_call) { 15611 wait = 2100 + ast_random() % 2000; 15612 } else { 15613 wait = ast_random() % 2000; 15614 } 15615 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, dialog_ref(p)); 15616 ast_debug(2, "Reinvite race. Waiting %d secs before retry\n", wait); 15617 } 15618 } 15619 break; 15620 15621 case 501: /* Not implemented */ 15622 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 15623 if (p->owner) 15624 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 15625 break; 15626 } 15627 if (xmitres == XMIT_ERROR) 15628 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 15629 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 15832 of file chan_sip.c.
References ast_check_realtime(), ast_device_state_changed(), ast_log(), AST_SCHED_REPLACE, ast_tvdiff_ms(), ast_tvnow(), ast_update_realtime(), sip_peer::call, DEFAULT_FREQ_NOTOK, dialog_unref(), EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event, sip_peer::maxms, sip_peer::name, sip_pvt::needdestroy, sip_settings::peer_rtupdate, sip_peer::pokeexpire, sip_peer::ps, sip_peer::qualifyfreq, register_peer_exten(), sip_pvt::relatedpeer, s, sched, sip_cfg, sip_poke_peer_s(), and TRUE.
Referenced by handle_response().
15833 { 15834 struct sip_peer *peer = p->relatedpeer; 15835 int statechanged, is_reachable, was_reachable; 15836 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 15837 15838 /* 15839 * Compute the response time to a ping (goes in peer->lastms.) 15840 * -1 means did not respond, 0 means unknown, 15841 * 1..maxms is a valid response, >maxms means late response. 15842 */ 15843 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 15844 pingtime = 1; 15845 15846 /* Now determine new state and whether it has changed. 15847 * Use some helper variables to simplify the writing 15848 * of the expressions. 15849 */ 15850 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 15851 is_reachable = pingtime <= peer->maxms; 15852 statechanged = peer->lastms == 0 /* yes, unknown before */ 15853 || was_reachable != is_reachable; 15854 15855 peer->lastms = pingtime; 15856 peer->call = dialog_unref(peer->call); 15857 if (statechanged) { 15858 const char *s = is_reachable ? "Reachable" : "Lagged"; 15859 char str_lastms[20]; 15860 snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime); 15861 15862 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 15863 peer->name, s, pingtime, peer->maxms); 15864 ast_device_state_changed("SIP/%s", peer->name); 15865 if (sip_cfg.peer_rtupdate) { 15866 ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", str_lastms, NULL); 15867 } 15868 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 15869 "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 15870 peer->name, s, pingtime); 15871 if (is_reachable && global_regextenonqualify) 15872 register_peer_exten(peer, TRUE); 15873 } 15874 15875 p->needdestroy = 1; 15876 15877 /* Try again eventually */ 15878 AST_SCHED_REPLACE(peer->pokeexpire, sched, 15879 is_reachable ? peer->qualifyfreq : DEFAULT_FREQ_NOTOK, 15880 sip_poke_peer_s, peer); 15881 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 15634 of file chan_sip.c.
References AST_CONTROL_CONGESTION, ast_debug, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_strlen_zero(), sip_pvt::authname, sip_pvt::authtries, sip_pvt::callid, do_proxy_auth(), get_header(), sip_pvt::initreq, LOG_NOTICE, LOG_WARNING, sip_pvt::needdestroy, sip_pvt::owner, sip_pvt::recv, sip_pvt::refer, REFER_ACCEPTED, REFER_FAILED, REFER_NOAUTH, sip_refer::refer_to, SIP_REFER, and sip_refer::status.
Referenced by handle_response().
15635 { 15636 /* If no refer structure exists, then do nothing */ 15637 if (!p->refer) 15638 return; 15639 15640 switch (resp) { 15641 case 202: /* Transfer accepted */ 15642 /* We need to do something here */ 15643 /* The transferee is now sending INVITE to target */ 15644 p->refer->status = REFER_ACCEPTED; 15645 /* Now wait for next message */ 15646 ast_debug(3, "Got 202 accepted on transfer\n"); 15647 /* We should hang along, waiting for NOTIFY's here */ 15648 break; 15649 15650 case 401: /* Not www-authorized on SIP method */ 15651 case 407: /* Proxy auth */ 15652 if (ast_strlen_zero(p->authname)) { 15653 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 15654 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 15655 p->needdestroy = 1; 15656 } 15657 if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_REFER, 0)) { 15658 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 15659 p->refer->status = REFER_NOAUTH; 15660 p->needdestroy = 1; 15661 } 15662 break; 15663 case 481: /* Call leg does not exist */ 15664 15665 /* A transfer with Replaces did not work */ 15666 /* OEJ: We should Set flag, cancel the REFER, go back 15667 to original call - but right now we can't */ 15668 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 15669 if (p->owner) 15670 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 15671 p->needdestroy = 1; 15672 break; 15673 15674 case 500: /* Server error */ 15675 case 501: /* Method not implemented */ 15676 /* Return to the current call onhold */ 15677 /* Status flag needed to be reset */ 15678 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 15679 p->needdestroy = 1; 15680 p->refer->status = REFER_FAILED; 15681 break; 15682 case 603: /* Transfer declined */ 15683 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 15684 p->refer->status = REFER_FAILED; 15685 p->needdestroy = 1; 15686 break; 15687 } 15688 }
static int handle_response_register | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Handle responses on REGISTER to services.
Definition at line 15691 of file chan_sip.c.
References __get_header(), ast_debug, ast_log(), ast_sched_del(), AST_SCHED_DEL, AST_SCHED_REPLACE, ast_strlen_zero(), ast_tvnow(), sip_pvt::authtries, sip_registry::call, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, sip_registry::expiry, EXPIRY_GUARD_LIMIT, EXPIRY_GUARD_MIN, EXPIRY_GUARD_PCT, EXPIRY_GUARD_SECS, get_header(), sip_registry::hostname, sip_pvt::initreq, LOG_NOTICE, LOG_WARNING, manager_event, MAX, MAX_AUTHTRIES, sip_pvt::needdestroy, sip_pvt::our_contact, sip_pvt::peername, sip_registry::refresh, REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_UNREGISTERED, sip_registry::regattempts, sip_pvt::registry, registry_unref(), sip_registry::regstate, regstate2str(), sip_registry::regtime, S_OR, sched, SIP_REGISTER, sip_reregister(), sip_scheddestroy(), strcasestr(), sip_registry::timeout, transmit_register(), sip_pvt::username, and sip_registry::username.
Referenced by handle_response().
15692 { 15693 int expires, expires_ms; 15694 struct sip_registry *r; 15695 r=p->registry; 15696 15697 switch (resp) { 15698 case 401: /* Unauthorized */ 15699 if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) { 15700 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 15701 p->needdestroy = 1; 15702 } 15703 break; 15704 case 403: /* Forbidden */ 15705 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 15706 AST_SCHED_DEL(sched, r->timeout); 15707 r->regstate = REG_STATE_NOAUTH; 15708 p->needdestroy = 1; 15709 break; 15710 case 404: /* Not found */ 15711 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username, p->registry->hostname); 15712 p->needdestroy = 1; 15713 r->call = NULL; 15714 r->regstate = REG_STATE_REJECTED; 15715 AST_SCHED_DEL(sched, r->timeout); 15716 break; 15717 case 407: /* Proxy auth */ 15718 if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) { 15719 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 15720 p->needdestroy = 1; 15721 } 15722 break; 15723 case 408: /* Request timeout */ 15724 /* Got a timeout response, so reset the counter of failed responses */ 15725 if (r) { 15726 r->regattempts = 0; 15727 } else { 15728 ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid); 15729 } 15730 break; 15731 case 423: /* Interval too brief */ 15732 r->expiry = atoi(get_header(req, "Min-Expires")); 15733 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); 15734 ast_sched_del(sched, r->timeout); 15735 r->timeout = -1; 15736 if (r->call) { 15737 r->call = NULL; 15738 p->needdestroy = 1; 15739 } 15740 if (r->expiry > max_expiry) { 15741 ast_log(LOG_WARNING, "Required expiration time from %s@%s is too high, giving up\n", p->registry->username, p->registry->hostname); 15742 r->expiry = default_expiry; 15743 r->regstate = REG_STATE_REJECTED; 15744 } else { 15745 r->regstate = REG_STATE_UNREGISTERED; 15746 transmit_register(r, SIP_REGISTER, NULL, NULL); 15747 } 15748 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)); 15749 break; 15750 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 15751 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username, p->registry->hostname); 15752 p->needdestroy = 1; 15753 r->call = NULL; 15754 r->regstate = REG_STATE_REJECTED; 15755 AST_SCHED_DEL(sched, r->timeout); 15756 break; 15757 case 200: /* 200 OK */ 15758 if (!r) { 15759 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)); 15760 p->needdestroy = 1; 15761 return 0; 15762 } 15763 15764 r->regstate = REG_STATE_REGISTERED; 15765 r->regtime = ast_tvnow(); /* Reset time of last succesful registration */ 15766 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 15767 r->regattempts = 0; 15768 ast_debug(1, "Registration successful\n"); 15769 if (r->timeout > -1) { 15770 ast_debug(1, "Cancelling timeout %d\n", r->timeout); 15771 } 15772 AST_SCHED_DEL(sched, r->timeout); 15773 r->call = NULL; 15774 p->registry = NULL; 15775 /* Let this one hang around until we have all the responses */ 15776 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15777 /* p->needdestroy = 1; */ 15778 15779 /* set us up for re-registering */ 15780 /* figure out how long we got registered for */ 15781 AST_SCHED_DEL(sched, r->expire); 15782 /* according to section 6.13 of RFC, contact headers override 15783 expires headers, so check those first */ 15784 expires = 0; 15785 15786 /* XXX todo: try to save the extra call */ 15787 if (!ast_strlen_zero(get_header(req, "Contact"))) { 15788 const char *contact = NULL; 15789 const char *tmptmp = NULL; 15790 int start = 0; 15791 for(;;) { 15792 contact = __get_header(req, "Contact", &start); 15793 /* this loop ensures we get a contact header about our register request */ 15794 if(!ast_strlen_zero(contact)) { 15795 if( (tmptmp=strstr(contact, p->our_contact))) { 15796 contact=tmptmp; 15797 break; 15798 } 15799 } else 15800 break; 15801 } 15802 tmptmp = strcasestr(contact, "expires="); 15803 if (tmptmp) { 15804 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 15805 expires = 0; 15806 } 15807 15808 } 15809 if (!expires) 15810 expires=atoi(get_header(req, "expires")); 15811 if (!expires) 15812 expires=default_expiry; 15813 15814 expires_ms = expires * 1000; 15815 if (expires <= EXPIRY_GUARD_LIMIT) 15816 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT), EXPIRY_GUARD_MIN); 15817 else 15818 expires_ms -= EXPIRY_GUARD_SECS * 1000; 15819 if (sipdebug) 15820 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 15821 15822 r->refresh= (int) expires_ms / 1000; 15823 15824 /* Schedule re-registration before we expire */ 15825 AST_SCHED_REPLACE(r->expire, sched, expires_ms, sip_reregister, r); 15826 registry_unref(r); 15827 } 15828 return 1; 15829 }
static const char * hangup_cause2sip | ( | int | cause | ) | [static] |
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 4897 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().
04898 { 04899 switch (cause) { 04900 case AST_CAUSE_UNALLOCATED: /* 1 */ 04901 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 04902 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 04903 return "404 Not Found"; 04904 case AST_CAUSE_CONGESTION: /* 34 */ 04905 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 04906 return "503 Service Unavailable"; 04907 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 04908 return "408 Request Timeout"; 04909 case AST_CAUSE_NO_ANSWER: /* 19 */ 04910 case AST_CAUSE_UNREGISTERED: /* 20 */ 04911 return "480 Temporarily unavailable"; 04912 case AST_CAUSE_CALL_REJECTED: /* 21 */ 04913 return "403 Forbidden"; 04914 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 04915 return "410 Gone"; 04916 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 04917 return "480 Temporarily unavailable"; 04918 case AST_CAUSE_INVALID_NUMBER_FORMAT: 04919 return "484 Address incomplete"; 04920 case AST_CAUSE_USER_BUSY: 04921 return "486 Busy here"; 04922 case AST_CAUSE_FAILURE: 04923 return "500 Server internal failure"; 04924 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 04925 return "501 Not Implemented"; 04926 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 04927 return "503 Service Unavailable"; 04928 /* Used in chan_iax2 */ 04929 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 04930 return "502 Bad Gateway"; 04931 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 04932 return "488 Not Acceptable Here"; 04933 04934 case AST_CAUSE_NOTDEFINED: 04935 default: 04936 ast_debug(1, "AST hangup cause %d (no match found in SIP)\n", cause); 04937 return NULL; 04938 } 04939 04940 /* Never reached */ 04941 return 0; 04942 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 4785 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 handle_response().
04786 { 04787 /* Possible values taken from causes.h */ 04788 04789 switch(cause) { 04790 case 401: /* Unauthorized */ 04791 return AST_CAUSE_CALL_REJECTED; 04792 case 403: /* Not found */ 04793 return AST_CAUSE_CALL_REJECTED; 04794 case 404: /* Not found */ 04795 return AST_CAUSE_UNALLOCATED; 04796 case 405: /* Method not allowed */ 04797 return AST_CAUSE_INTERWORKING; 04798 case 407: /* Proxy authentication required */ 04799 return AST_CAUSE_CALL_REJECTED; 04800 case 408: /* No reaction */ 04801 return AST_CAUSE_NO_USER_RESPONSE; 04802 case 409: /* Conflict */ 04803 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 04804 case 410: /* Gone */ 04805 return AST_CAUSE_NUMBER_CHANGED; 04806 case 411: /* Length required */ 04807 return AST_CAUSE_INTERWORKING; 04808 case 413: /* Request entity too large */ 04809 return AST_CAUSE_INTERWORKING; 04810 case 414: /* Request URI too large */ 04811 return AST_CAUSE_INTERWORKING; 04812 case 415: /* Unsupported media type */ 04813 return AST_CAUSE_INTERWORKING; 04814 case 420: /* Bad extension */ 04815 return AST_CAUSE_NO_ROUTE_DESTINATION; 04816 case 480: /* No answer */ 04817 return AST_CAUSE_NO_ANSWER; 04818 case 481: /* No answer */ 04819 return AST_CAUSE_INTERWORKING; 04820 case 482: /* Loop detected */ 04821 return AST_CAUSE_INTERWORKING; 04822 case 483: /* Too many hops */ 04823 return AST_CAUSE_NO_ANSWER; 04824 case 484: /* Address incomplete */ 04825 return AST_CAUSE_INVALID_NUMBER_FORMAT; 04826 case 485: /* Ambiguous */ 04827 return AST_CAUSE_UNALLOCATED; 04828 case 486: /* Busy everywhere */ 04829 return AST_CAUSE_BUSY; 04830 case 487: /* Request terminated */ 04831 return AST_CAUSE_INTERWORKING; 04832 case 488: /* No codecs approved */ 04833 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 04834 case 491: /* Request pending */ 04835 return AST_CAUSE_INTERWORKING; 04836 case 493: /* Undecipherable */ 04837 return AST_CAUSE_INTERWORKING; 04838 case 500: /* Server internal failure */ 04839 return AST_CAUSE_FAILURE; 04840 case 501: /* Call rejected */ 04841 return AST_CAUSE_FACILITY_REJECTED; 04842 case 502: 04843 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 04844 case 503: /* Service unavailable */ 04845 return AST_CAUSE_CONGESTION; 04846 case 504: /* Gateway timeout */ 04847 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 04848 case 505: /* SIP version not supported */ 04849 return AST_CAUSE_INTERWORKING; 04850 case 600: /* Busy everywhere */ 04851 return AST_CAUSE_USER_BUSY; 04852 case 603: /* Decline */ 04853 return AST_CAUSE_CALL_REJECTED; 04854 case 604: /* Does not exist anywhere */ 04855 return AST_CAUSE_UNALLOCATED; 04856 case 606: /* Not acceptable */ 04857 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 04858 default: 04859 return AST_CAUSE_NORMAL; 04860 } 04861 /* Never reached */ 04862 return 0; 04863 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 7740 of file chan_sip.c.
References sip_methods, and cfsip_methods::text.
07741 { 07742 /* Initialize a request */ 07743 memset(req, 0, sizeof(*req)); 07744 req->method = sipmethod; 07745 req->header[0] = req->data; 07746 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 07747 req->len = strlen(req->header[0]); 07748 req->headers++; 07749 return 0; 07750 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 7727 of file chan_sip.c.
References SIP_RESPONSE.
07728 { 07729 /* Initialize a response */ 07730 memset(resp, 0, sizeof(*resp)); 07731 resp->method = SIP_RESPONSE; 07732 resp->header[0] = resp->data; 07733 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 07734 resp->len = strlen(resp->header[0]); 07735 resp->headers++; 07736 return 0; 07737 }
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 2367 of file chan_sip.c.
References ast_debug, ast_verbose(), sip_pvt::callid, copy_request(), sip_request::debug, sip_request::headers, sip_pvt::initreq, sip_request::lines, sip_request::method, parse_request(), and sip_methods.
Referenced by transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_sip_request().
02368 { 02369 if (p->initreq.headers) 02370 ast_debug(1, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 02371 else 02372 ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); 02373 /* Use this as the basis */ 02374 copy_request(&p->initreq, req); 02375 parse_request(&p->initreq); 02376 if (req->debug) 02377 ast_verbose("Initreq: %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 02378 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 9073 of file chan_sip.c.
References add_header(), AST_DIGIT_ANYNUM, ast_inet_ntoa(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_str_alloca, ast_str_append(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), build_rpid(), CALLERID_UNKNOWN, sip_pvt::callid, sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, sip_pvt::fromdomain, sip_pvt::fromname, sip_pvt::fromuser, sip_pvt::fullcontact, init_req(), sip_pvt::lastmsg, sip_pvt::ocseq, sip_pvt::options, sip_pvt::our_contact, sip_pvt::ourip, ourport, sip_pvt::owner, sip_pvt::rpid, s, S_OR, sip_pvt::sa, SIP_INVITE, sip_methods, SIP_NOTIFY, SIP_SENDRPID, sip_standard_port(), SIP_USEREQPHONE, SIPBUFSIZE, sip_pvt::socket, STANDARD_SIP_PORT, ast_str::str, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, sip_pvt::todnid, sip_pvt::tohost, sip_socket::type, sip_pvt::uri, sip_invite_param::uri_options, sip_pvt::username, sip_pvt::via, and sip_invite_param::vxml_url.
Referenced by sip_notify(), transmit_invite(), and transmit_notify_with_mwi().
09074 { 09075 struct ast_str *invite = ast_str_alloca(256); 09076 char from[256]; 09077 char to[256]; 09078 char tmp_n[SIPBUFSIZE/2]; /* build a local copy of 'n' if needed */ 09079 char tmp_l[SIPBUFSIZE/2]; /* build a local copy of 'l' if needed */ 09080 const char *l = NULL; /* XXX what is this, exactly ? */ 09081 const char *n = NULL; /* XXX what is this, exactly ? */ 09082 const char *urioptions = ""; 09083 int ourport; 09084 09085 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 09086 const char *s = p->username; /* being a string field, cannot be NULL */ 09087 09088 /* Test p->username against allowed characters in AST_DIGIT_ANY 09089 If it matches the allowed characters list, then sipuser = ";user=phone" 09090 If not, then sipuser = "" 09091 */ 09092 /* + is allowed in first position in a tel: uri */ 09093 if (*s == '+') 09094 s++; 09095 for (; *s; s++) { 09096 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 09097 break; 09098 } 09099 /* If we have only digits, add ;user=phone to the uri */ 09100 if (!*s) 09101 urioptions = ";user=phone"; 09102 } 09103 09104 09105 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 09106 09107 if (p->owner) { 09108 l = p->owner->cid.cid_num; 09109 n = p->owner->cid.cid_name; 09110 } 09111 /* if we are not sending RPID and user wants his callerid restricted */ 09112 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 09113 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 09114 l = CALLERID_UNKNOWN; 09115 n = l; 09116 } 09117 if (ast_strlen_zero(l)) 09118 l = default_callerid; 09119 if (ast_strlen_zero(n)) 09120 n = l; 09121 /* Allow user to be overridden */ 09122 if (!ast_strlen_zero(p->fromuser)) 09123 l = p->fromuser; 09124 else /* Save for any further attempts */ 09125 ast_string_field_set(p, fromuser, l); 09126 09127 /* Allow user to be overridden */ 09128 if (!ast_strlen_zero(p->fromname)) 09129 n = p->fromname; 09130 else /* Save for any further attempts */ 09131 ast_string_field_set(p, fromname, n); 09132 09133 if (pedanticsipchecking) { 09134 ast_uri_encode(n, tmp_n, sizeof(tmp_n), 0); 09135 n = tmp_n; 09136 ast_uri_encode(l, tmp_l, sizeof(tmp_l), 0); 09137 l = tmp_l; 09138 } 09139 09140 ourport = ntohs(p->ourip.sin_port); 09141 if (!sip_standard_port(p->socket.type, ourport) && ast_strlen_zero(p->fromdomain)) 09142 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, ast_inet_ntoa(p->ourip.sin_addr), ourport, p->tag); 09143 else 09144 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr)), p->tag); 09145 09146 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 09147 if (!ast_strlen_zero(p->fullcontact)) { 09148 /* If we have full contact, trust it */ 09149 ast_str_append(&invite, 0, "%s", p->fullcontact); 09150 } else { 09151 /* Otherwise, use the username while waiting for registration */ 09152 ast_str_append(&invite, 0, "sip:"); 09153 if (!ast_strlen_zero(p->username)) { 09154 n = p->username; 09155 if (pedanticsipchecking) { 09156 ast_uri_encode(n, tmp_n, sizeof(tmp_n), 0); 09157 n = tmp_n; 09158 } 09159 ast_str_append(&invite, 0, "%s@", n); 09160 } 09161 ast_str_append(&invite, 0, "%s", p->tohost); 09162 if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) 09163 ast_str_append(&invite, 0, ":%d", ntohs(p->sa.sin_port)); 09164 ast_str_append(&invite, 0, "%s", urioptions); 09165 } 09166 09167 /* If custom URI options have been provided, append them */ 09168 if (p->options && !ast_strlen_zero(p->options->uri_options)) 09169 ast_str_append(&invite, 0, ";%s", p->options->uri_options); 09170 09171 /* This is the request URI, which is the next hop of the call 09172 which may or may not be the destination of the call 09173 */ 09174 ast_string_field_set(p, uri, invite->str); 09175 09176 if (!ast_strlen_zero(p->todnid)) { 09177 /*! \todo Need to add back the VXML URL here at some point, possibly use build_string for all this junk */ 09178 if (!strchr(p->todnid, '@')) { 09179 /* We have no domain in the dnid */ 09180 snprintf(to, sizeof(to), "<sip:%s@%s>%s%s", p->todnid, p->tohost, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); 09181 } else { 09182 snprintf(to, sizeof(to), "<sip:%s>%s%s", p->todnid, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); 09183 } 09184 } else { 09185 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 09186 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 09187 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (!strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); 09188 } else if (p->options && p->options->vxml_url) { 09189 /* If there is a VXML URL append it to the SIP URL */ 09190 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 09191 } else 09192 snprintf(to, sizeof(to), "<%s>", p->uri); 09193 } 09194 09195 init_req(req, sipmethod, p->uri); 09196 /* now tmp_n is available so reuse it to build the CSeq */ 09197 snprintf(tmp_n, sizeof(tmp_n), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 09198 09199 add_header(req, "Via", p->via); 09200 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 09201 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 09202 * OTOH, then we won't have anything in p->route anyway */ 09203 09204 /* Build Remote Party-ID and From */ 09205 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 09206 build_rpid(p); 09207 add_header(req, "From", p->rpid_from); 09208 } else 09209 add_header(req, "From", from); 09210 add_header(req, "To", to); 09211 ast_string_field_set(p, exten, l); 09212 build_contact(p); 09213 add_header(req, "Contact", p->our_contact); 09214 add_header(req, "Call-ID", p->callid); 09215 add_header(req, "CSeq", tmp_n); 09216 if (!ast_strlen_zero(global_useragent)) 09217 add_header(req, "User-Agent", global_useragent); 09218 if (!ast_strlen_zero(p->rpid)) 09219 add_header(req, "Remote-Party-ID", p->rpid); 09220 }
static const char * insecure2str | ( | int | mode | ) | const [static] |
Convert Insecure setting to printable string.
Definition at line 12948 of file chan_sip.c.
References insecurestr, and map_x_s().
Referenced by _sip_show_peer().
12949 { 12950 return map_x_s(insecurestr, mode, "<error>"); 12951 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 10516 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
10517 { 10518 if (!route) 10519 ast_verbose("list_route: no route\n"); 10520 else { 10521 for (;route; route = route->next) 10522 ast_verbose("list_route: hop: <%s>\n", route->hop); 10523 } 10524 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 22851 of file chan_sip.c.
References ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register, ast_log(), ast_manager_register2(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application, ast_rtp_proto_register(), ast_udptl_proto_register(), ast_verbose(), ASTOBJ_CONTAINER_INIT, CHANNEL_MODULE_LOAD, checksipdomain_function, cli_sip, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, io, io_context_create(), io_context_destroy(), LOG_ERROR, manager_show_registry(), manager_sip_show_peer(), manager_sip_show_peers(), mandescr_show_peer, peerl, regl, reload_config(), restart_monitor(), sched, sched_context_create(), sched_context_destroy(), ast_channel_tech::send_digit_begin, sip_addheader(), sip_dtmfmode(), sip_header_function, sip_poke_all_peers(), sip_rtp, sip_send_all_registers(), sip_tech, sip_tech_info, sip_udptl, sipchaninfo_function, sippeer_function, and userl.
22852 { 22853 ast_verbose("SIP channel loading...\n"); 22854 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 22855 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 22856 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 22857 22858 if (!(sched = sched_context_create())) { 22859 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 22860 return AST_MODULE_LOAD_FAILURE; 22861 } 22862 22863 if (!(io = io_context_create())) { 22864 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 22865 sched_context_destroy(sched); 22866 return AST_MODULE_LOAD_FAILURE; 22867 } 22868 22869 sip_reloadreason = CHANNEL_MODULE_LOAD; 22870 22871 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 22872 return AST_MODULE_LOAD_DECLINE; 22873 22874 /* Prepare the version that does not require DTMF BEGIN frames. 22875 * We need to use tricks such as memcpy and casts because the variable 22876 * has const fields. 22877 */ 22878 memcpy(&sip_tech_info, &sip_tech, sizeof(sip_tech)); 22879 memset((void *) &sip_tech_info.send_digit_begin, 0, sizeof(sip_tech_info.send_digit_begin)); 22880 22881 /* Make sure we can register our sip channel type */ 22882 if (ast_channel_register(&sip_tech)) { 22883 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 22884 io_context_destroy(io); 22885 sched_context_destroy(sched); 22886 return AST_MODULE_LOAD_FAILURE; 22887 } 22888 22889 /* Register all CLI functions for SIP */ 22890 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 22891 22892 /* Tell the RTP subdriver that we're here */ 22893 ast_rtp_proto_register(&sip_rtp); 22894 22895 /* Tell the UDPTL subdriver that we're here */ 22896 ast_udptl_proto_register(&sip_udptl); 22897 22898 /* Register dialplan applications */ 22899 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 22900 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 22901 22902 /* Register dialplan functions */ 22903 ast_custom_function_register(&sip_header_function); 22904 ast_custom_function_register(&sippeer_function); 22905 ast_custom_function_register(&sipchaninfo_function); 22906 ast_custom_function_register(&checksipdomain_function); 22907 22908 /* Register manager commands */ 22909 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peers, 22910 "List SIP peers (text format)", mandescr_show_peers); 22911 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peer, 22912 "Show SIP peer (text format)", mandescr_show_peer); 22913 ast_manager_register2("SIPshowregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_show_registry, 22914 "Show SIP registrations (text format)", mandescr_show_registry); 22915 sip_poke_all_peers(); 22916 sip_send_all_registers(); 22917 22918 /* And start the monitor for the first time */ 22919 restart_monitor(); 22920 22921 return AST_MODULE_LOAD_SUCCESS; 22922 }
static int local_attended_transfer | ( | struct sip_pvt * | transferer, | |
struct sip_dual * | current, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Find all call legs and bridge transferee with target called from handle_request_refer.
Definition at line 17892 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), ast_channel_unlock, ast_clear_flag, ast_debug, ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, attempt_transfer(), sip_pvt::callid, sip_dual::chan1, sip_dual::chan2, EVENT_FLAG_CALL, sip_pvt::flags, get_sip_pvt_byid_locked(), sip_refer::localtransfer, manager_event, ast_channel::name, sip_pvt::owner, sip_pvt::refer, REFER_200OK, REFER_FAILED, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, sip_pvt_unlock, sip_refer::status, transmit_notify_with_sipfrag(), transmit_response(), TRUE, and ast_channel::uniqueid.
Referenced by handle_request_refer().
17893 { 17894 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 17895 /* Chan 2: Call from Asterisk to target */ 17896 int res = 0; 17897 struct sip_pvt *targetcall_pvt; 17898 17899 /* Check if the call ID of the replaces header does exist locally */ 17900 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 17901 transferer->refer->replaces_callid_fromtag))) { 17902 if (transferer->refer->localtransfer) { 17903 /* We did not find the refered call. Sorry, can't accept then */ 17904 transmit_response(transferer, "202 Accepted", req); 17905 /* Let's fake a response from someone else in order 17906 to follow the standard */ 17907 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 17908 append_history(transferer, "Xfer", "Refer failed"); 17909 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 17910 transferer->refer->status = REFER_FAILED; 17911 return -1; 17912 } 17913 /* Fall through for remote transfers that we did not find locally */ 17914 ast_debug(3, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 17915 return 0; 17916 } 17917 17918 /* Ok, we can accept this transfer */ 17919 transmit_response(transferer, "202 Accepted", req); 17920 append_history(transferer, "Xfer", "Refer accepted"); 17921 if (!targetcall_pvt->owner) { /* No active channel */ 17922 ast_debug(4, "SIP attended transfer: Error: No owner of target call\n"); 17923 /* Cancel transfer */ 17924 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 17925 append_history(transferer, "Xfer", "Refer failed"); 17926 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 17927 transferer->refer->status = REFER_FAILED; 17928 sip_pvt_unlock(targetcall_pvt); 17929 return -1; 17930 } 17931 17932 /* We have a channel, find the bridge */ 17933 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 17934 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 17935 17936 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 17937 /* Wrong state of new channel */ 17938 if (target.chan2) 17939 ast_debug(4, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 17940 else if (target.chan1->_state != AST_STATE_RING) 17941 ast_debug(4, "SIP attended transfer: Error: No target channel\n"); 17942 else 17943 ast_debug(4, "SIP attended transfer: Attempting transfer in ringing state\n"); 17944 } 17945 17946 /* Transfer */ 17947 if (sipdebug) { 17948 if (current->chan2) /* We have two bridges */ 17949 ast_debug(4, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 17950 else /* One bridge, propably transfer of IVR/voicemail etc */ 17951 ast_debug(4, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 17952 } 17953 17954 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 17955 17956 /* Perform the transfer */ 17957 manager_event(EVENT_FLAG_CALL, "Transfer", "TransferMethod: SIP\r\nTransferType: Attended\r\nChannel: %s\r\nUniqueid: %s\r\nSIP-Callid: %s\r\nTargetChannel: %s\r\nTargetUniqueid: %s\r\n", 17958 transferer->owner->name, 17959 transferer->owner->uniqueid, 17960 transferer->callid, 17961 target.chan1->name, 17962 target.chan1->uniqueid); 17963 res = attempt_transfer(current, &target); 17964 sip_pvt_unlock(targetcall_pvt); 17965 if (res) { 17966 /* Failed transfer */ 17967 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 17968 append_history(transferer, "Xfer", "Refer failed"); 17969 if (targetcall_pvt->owner) 17970 ast_channel_unlock(targetcall_pvt->owner); 17971 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 17972 } else { 17973 /* Transfer succeeded! */ 17974 17975 /* Tell transferer that we're done. */ 17976 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 17977 append_history(transferer, "Xfer", "Refer succeeded"); 17978 transferer->refer->status = REFER_200OK; 17979 if (targetcall_pvt->owner) { 17980 ast_debug(1, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 17981 ast_channel_unlock(targetcall_pvt->owner); 17982 } 17983 } 17984 return 1; 17985 }
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 6411 of file chan_sip.c.
Referenced by handle_request_do().
06412 { 06413 int h = 0, t = 0; 06414 int lws = 0; 06415 06416 for (; h < len;) { 06417 /* Eliminate all CRs */ 06418 if (msgbuf[h] == '\r') { 06419 h++; 06420 continue; 06421 } 06422 /* Check for end-of-line */ 06423 if (msgbuf[h] == '\n') { 06424 /* Check for end-of-message */ 06425 if (h + 1 == len) 06426 break; 06427 /* Check for a continuation line */ 06428 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 06429 /* Merge continuation line */ 06430 h++; 06431 continue; 06432 } 06433 /* Propagate LF and start new line */ 06434 msgbuf[t++] = msgbuf[h++]; 06435 lws = 0; 06436 continue; 06437 } 06438 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 06439 if (lws) { 06440 h++; 06441 continue; 06442 } 06443 msgbuf[t++] = msgbuf[h++]; 06444 lws = 1; 06445 continue; 06446 } 06447 msgbuf[t++] = msgbuf[h++]; 06448 if (lws) 06449 lws = 0; 06450 } 06451 msgbuf[t] = '\0'; 06452 return t; 06453 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 6000 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().
06001 { 06002 snprintf(tagbuf, len, "as%08lx", ast_random()); 06003 }
static int manager_show_registry | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP registrations in the manager API.
Definition at line 12656 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, STANDARD_SIP_PORT, and total.
Referenced by load_module().
12657 { 12658 const char *id = astman_get_header(m, "ActionID"); 12659 char idtext[256] = ""; 12660 int total = 0; 12661 12662 if (!ast_strlen_zero(id)) 12663 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 12664 12665 astman_send_listack(s, m, "Registrations will follow", "start"); 12666 12667 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 12668 ASTOBJ_RDLOCK(iterator); 12669 astman_append(s, 12670 "Event: RegistryEntry\r\n" 12671 "Host: %s\r\n" 12672 "Port: %d\r\n" 12673 "Username: %s\r\n" 12674 "Refresh: %d\r\n" 12675 "State: %s\r\n" 12676 "RegistrationTime: %ld\r\n" 12677 "\r\n", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT, 12678 iterator->username, iterator->refresh, regstate2str(iterator->regstate), (long) iterator->regtime.tv_sec); 12679 ASTOBJ_UNLOCK(iterator); 12680 total++; 12681 } while(0)); 12682 12683 astman_append(s, 12684 "Event: RegistrationsComplete\r\n" 12685 "EventList: Complete\r\n" 12686 "ListItems: %d\r\n" 12687 "%s" 12688 "\r\n", total, idtext); 12689 12690 return 0; 12691 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 13208 of file chan_sip.c.
References _sip_show_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), and s.
Referenced by load_module().
13209 { 13210 const char *a[4]; 13211 const char *peer; 13212 13213 peer = astman_get_header(m, "Peer"); 13214 if (ast_strlen_zero(peer)) { 13215 astman_send_error(s, m, "Peer: <name> missing."); 13216 return 0; 13217 } 13218 a[0] = "sip"; 13219 a[1] = "show"; 13220 a[2] = "peer"; 13221 a[3] = peer; 13222 13223 _sip_show_peer(1, -1, s, m, 4, a); 13224 astman_append(s, "\r\n\r\n" ); 13225 return 0; 13226 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 12702 of file chan_sip.c.
References _sip_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), s, and total.
Referenced by load_module().
12703 { 12704 const char *id = astman_get_header(m, "ActionID"); 12705 const char *a[] = {"sip", "show", "peers"}; 12706 char idtext[256] = ""; 12707 int total = 0; 12708 12709 if (!ast_strlen_zero(id)) 12710 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 12711 12712 astman_send_listack(s, m, "Peer status list will follow", "start"); 12713 /* List the peers in separate manager events */ 12714 _sip_show_peers(-1, &total, s, m, 3, a); 12715 /* Send final confirmation */ 12716 astman_append(s, 12717 "Event: PeerlistComplete\r\n" 12718 "EventList: Complete\r\n" 12719 "ListItems: %d\r\n" 12720 "%s" 12721 "\r\n", total, idtext); 12722 return 0; 12723 }
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 2189 of file chan_sip.c.
References _map_x_s::s, table, and _map_x_s::x.
Referenced by str2dtmfmode(), str2stmode(), and str2strefresher().
02190 { 02191 const struct _map_x_s *cur; 02192 02193 for (cur = table; cur->s; cur++) 02194 if (!strcasecmp(cur->s, s)) 02195 return cur->x; 02196 return errorvalue; 02197 }
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 2176 of file chan_sip.c.
References _map_x_s::s, table, and _map_x_s::x.
Referenced by dtmfmode2str(), insecure2str(), nat2str(), referstatus2str(), regstate2str(), stmode2str(), and strefresher2str().
02177 { 02178 const struct _map_x_s *cur; 02179 02180 for (cur = table; cur->s; cur++) 02181 if (cur->x == x) 02182 return cur->s; 02183 return errorstring; 02184 }
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 2449 of file chan_sip.c.
References sip_request::len, sip_methods, and text.
Referenced by __sip_semi_ack(), and find_sip_method().
02450 { 02451 int len = strlen(sip_methods[id].text); 02452 int l_name = name ? strlen(name) : 0; 02453 /* true if the string is long enough, and ends with whitespace, and matches */ 02454 return (l_name >= len && name[len] < 33 && 02455 !strncasecmp(sip_methods[id].text, name, len)); 02456 }
static void mwi_event_cb | ( | const struct ast_event * | , | |
void * | ||||
) | [static] |
Receive MWI events that we have subscribed to.
Definition at line 10829 of file chan_sip.c.
References ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, and sip_send_mwi_to_peer().
10830 { 10831 struct sip_peer *peer = userdata; 10832 10833 ASTOBJ_RDLOCK(peer); 10834 sip_send_mwi_to_peer(peer, event, 0); 10835 ASTOBJ_UNLOCK(peer); 10836 }
static const char * nat2str | ( | int | nat | ) | const [static] |
Convert NAT setting to text string.
Definition at line 12470 of file chan_sip.c.
References map_x_s(), and natmodes.
Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_users().
Get default outbound proxy or global proxy.
Definition at line 2424 of file chan_sip.c.
References append_history, ast_debug, global_outboundproxy, sip_proxy::name, and sip_peer::outboundproxy.
Referenced by create_addr(), create_addr_from_peer(), and transmit_register().
02425 { 02426 if (peer && peer->outboundproxy) { 02427 if (sipdebug) 02428 ast_debug(1, "OBPROXY: Applying peer OBproxy to this call\n"); 02429 append_history(dialog, "OBproxy", "Using peer obproxy %s", peer->outboundproxy->name); 02430 return peer->outboundproxy; 02431 } 02432 if (global_outboundproxy.name[0]) { 02433 if (sipdebug) 02434 ast_debug(1, "OBPROXY: Applying global OBproxy to this call\n"); 02435 append_history(dialog, "OBproxy", "Using global obproxy %s", global_outboundproxy.name); 02436 return &global_outboundproxy; 02437 } 02438 if (sipdebug) 02439 ast_debug(1, "OBPROXY: Not applying OBproxy to this call\n"); 02440 return NULL; 02441 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 3197 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by _sip_tcp_helper_thread(), send_request(), and send_response().
03198 { 03199 memset(dst, 0, sizeof(*dst)); 03200 memcpy(dst->data, src->data, sizeof(dst->data)); 03201 dst->len = src->len; 03202 parse_request(dst); 03203 }
int parse_minse | ( | const char * | p_hdrval, | |
int *const | p_interval | |||
) | [static] |
Session-Timers: Function for parsing Min-SE header.
Definition at line 19945 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().
19946 { 19947 if (ast_strlen_zero(p_hdrval)) { 19948 ast_log(LOG_WARNING, "Null Min-SE header\n"); 19949 return -1; 19950 } 19951 19952 *p_interval = 0; 19953 p_hdrval = ast_skip_blanks(p_hdrval); 19954 if (!sscanf(p_hdrval, "%d", p_interval)) { 19955 ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval); 19956 return -1; 19957 } 19958 19959 ast_debug(2, "Received Min-SE: %d\n", *p_interval); 19960 return 0; 19961 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 15197 of file chan_sip.c.
References ao2_ref(), ast_copy_string(), ast_debug, ast_string_field_build, ast_string_field_set, ast_test_flag, sip_socket::fd, sip_pvt::flags, get_header(), get_in_brackets(), get_transport(), sip_pvt::owner, pbx_builtin_setvar_helper(), remove_uri_parameters(), s, SIP_PROMISCREDIR, SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, SIPBUFSIZE, sip_pvt::socket, strcasestr(), sip_socket::tcptls_session, and sip_socket::type.
Referenced by handle_response().
15198 { 15199 char tmp[SIPBUFSIZE]; 15200 char *s, *e, *t, *trans; 15201 char *domain; 15202 enum sip_transport transport = SIP_TRANSPORT_UDP; 15203 15204 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 15205 if ((t = strchr(tmp, ','))) 15206 *t = '\0'; 15207 15208 s = get_in_brackets(tmp); 15209 if ((trans = strcasestr(s, ";transport="))) do { 15210 trans += 11; 15211 15212 if ((e = strchr(trans, ';'))) 15213 *e = '\0'; 15214 15215 if (!strncasecmp(trans, "tcp", 3)) 15216 transport = SIP_TRANSPORT_TCP; 15217 else if (!strncasecmp(trans, "tls", 3)) 15218 transport = SIP_TRANSPORT_TLS; 15219 else { 15220 if (strncasecmp(trans, "udp", 3)) 15221 ast_debug(1, "received contact with an invalid transport, '%s'\n", s); 15222 transport = SIP_TRANSPORT_UDP; 15223 } 15224 } while(0); 15225 s = remove_uri_parameters(s); 15226 15227 if (p->socket.tcptls_session) { 15228 ao2_ref(p->socket.tcptls_session, -1); 15229 p->socket.tcptls_session = NULL; 15230 } 15231 15232 p->socket.fd = -1; 15233 p->socket.type = transport; 15234 15235 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 15236 char *host = NULL; 15237 if (!strncasecmp(s, "sip:", 4)) 15238 s += 4; 15239 else if (!strncasecmp(s, "sips:", 5)) 15240 s += 5; 15241 e = strchr(s, '/'); 15242 if (e) 15243 *e = '\0'; 15244 if ((host = strchr(s, '@'))) { 15245 *host++ = '\0'; 15246 ast_debug(2, "Found promiscuous redirection to 'SIP/%s::::%s@%s'\n", s, get_transport(transport), host); 15247 if (p->owner) 15248 ast_string_field_build(p->owner, call_forward, "SIP/%s::::%s@%s", s, get_transport(transport), host); 15249 } else { 15250 ast_debug(2, "Found promiscuous redirection to 'SIP/::::%s@%s'\n", get_transport(transport), s); 15251 if (p->owner) 15252 ast_string_field_build(p->owner, call_forward, "SIP/::::%s@%s", get_transport(transport), s); 15253 } 15254 } else { 15255 e = strchr(tmp, '@'); 15256 if (e) { 15257 *e++ = '\0'; 15258 domain = e; 15259 } else { 15260 /* No username part */ 15261 domain = tmp; 15262 } 15263 e = strchr(tmp, '/'); /* WHEN do we hae a forward slash in the URI? */ 15264 if (e) 15265 *e = '\0'; 15266 15267 if (!strncasecmp(s, "sip:", 4)) 15268 s += 4; 15269 else if (!strncasecmp(s, "sips:", 5)) 15270 s += 5; 15271 e = strchr(s, ';'); /* And username ; parameters? */ 15272 if (e) 15273 *e = '\0'; 15274 ast_debug(2, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 15275 if (p->owner) { 15276 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 15277 ast_string_field_set(p->owner, call_forward, s); 15278 } 15279 } 15280 }
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 10242 of file chan_sip.c.
References ast_copy_string(), ast_string_field_set, get_header(), get_in_brackets(), SIPBUFSIZE, and TRUE.
Referenced by handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
10243 { 10244 char contact[SIPBUFSIZE]; 10245 char *c; 10246 10247 /* Look for brackets */ 10248 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 10249 c = get_in_brackets(contact); 10250 10251 /* Save full contact to call pvt for later bye or re-invite */ 10252 ast_string_field_set(pvt, fullcontact, c); 10253 10254 /* Save URI for later ACKs, BYE or RE-invites */ 10255 ast_string_field_set(pvt, okcontacturi, c); 10256 10257 /* We should return false for URI:s we can't handle, 10258 like tel:, mailto:,ldap: etc */ 10259 return TRUE; 10260 }
static enum parse_register_result parse_register_contact | ( | struct sip_pvt * | pvt, | |
struct sip_peer * | p, | |||
struct sip_request * | req | |||
) | [static] |
Parse contact header and save registration (peer registration).
Definition at line 10320 of file chan_sip.c.
References sip_peer::addr, ahp, ast_apply_ha(), ast_copy_string(), ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_sched_when(), AST_SENSE_ALLOW, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose(), sip_peer::contactha, copy_socket_data(), sip_peer::default_outbound_transport, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, FALSE, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), get_transport_str2enum(), global_contact_ha, hp, inaddrcmp(), sip_peer::is_realtime, sip_peer::lastms, LOG_NOTICE, LOG_WARNING, manager_event, sip_peer::name, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, parse_uri(), sip_pvt::recv, register_peer_exten(), sip_peer::rt_fromcontact, s, sched, set_socket_transport(), SIP_NAT_ROUTE, SIP_PAGE2_RTCACHEFRIENDS, sip_poke_peer(), SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, SIPBUFSIZE, sip_pvt::sipoptions, sip_peer::sipoptions, sip_peer::socket, sip_request::socket, sip_pvt::socket, STANDARD_SIP_PORT, STANDARD_TLS_PORT, strcasestr(), strsep(), sip_peer::transports, sip_socket::type, sip_peer::useragent, sip_peer::username, VERBOSE_PREFIX_3, and VERBOSITY_ATLEAST.
Referenced by register_verify().
10321 { 10322 char contact[SIPBUFSIZE]; 10323 char data[SIPBUFSIZE]; 10324 const char *expires = get_header(req, "Expires"); 10325 int expiry = atoi(expires); 10326 char *curi, *host, *pt, *curi2, *transport; 10327 int port; 10328 int transport_type; 10329 const char *useragent; 10330 struct hostent *hp; 10331 struct ast_hostent ahp; 10332 struct sockaddr_in oldsin, testsin; 10333 10334 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 10335 10336 if (ast_strlen_zero(expires)) { /* No expires header, try look in Contact: */ 10337 char *s = strcasestr(contact, ";expires="); 10338 if (s) { 10339 expires = strsep(&s, ";"); /* trim ; and beyond */ 10340 if (sscanf(expires + 9, "%d", &expiry) != 1) 10341 expiry = default_expiry; 10342 } else { 10343 /* Nothing has been specified */ 10344 expiry = default_expiry; 10345 } 10346 } 10347 10348 copy_socket_data(&pvt->socket, &req->socket); 10349 10350 /* Look for brackets */ 10351 curi = contact; 10352 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 10353 strsep(&curi, ";"); /* This is Header options, not URI options */ 10354 curi = get_in_brackets(contact); 10355 curi2 = ast_strdupa(curi); 10356 10357 /* if they did not specify Contact: or Expires:, they are querying 10358 what we currently have stored as their contact address, so return 10359 it 10360 */ 10361 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 10362 /* If we have an active registration, tell them when the registration is going to expire */ 10363 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 10364 pvt->expiry = ast_sched_when(sched, peer->expire); 10365 return PARSE_REGISTER_QUERY; 10366 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 10367 /* This means remove all registrations and return OK */ 10368 memset(&peer->addr, 0, sizeof(peer->addr)); 10369 set_socket_transport(&peer->socket, peer->default_outbound_transport); 10370 AST_SCHED_DEL(sched, peer->expire); 10371 10372 destroy_association(peer); 10373 10374 register_peer_exten(peer, FALSE); /* Remove extension from regexten= setting in sip.conf */ 10375 peer->fullcontact[0] = '\0'; 10376 peer->useragent[0] = '\0'; 10377 peer->sipoptions = 0; 10378 peer->lastms = 0; 10379 pvt->expiry = 0; 10380 10381 ast_verb(3, "Unregistered SIP '%s'\n", peer->name); 10382 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 10383 return PARSE_REGISTER_UPDATE; 10384 } 10385 10386 /* Store whatever we got as a contact from the client */ 10387 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 10388 10389 /* For the 200 OK, we should use the received contact */ 10390 ast_string_field_build(pvt, our_contact, "<%s>", curi); 10391 10392 /* Make sure it's a SIP URL */ 10393 if (pvt->socket.type == SIP_TRANSPORT_TLS) { 10394 if (parse_uri(curi, "sips:", &curi, NULL, &host, &pt, NULL, &transport)) { 10395 if (parse_uri(curi2, "sip:", &curi, NULL, &host, &pt, NULL, &transport)) 10396 ast_log(LOG_NOTICE, "Not a valid SIP contact (missing sip:) trying to use anyway\n"); 10397 } 10398 port = !ast_strlen_zero(pt) ? atoi(pt) : STANDARD_TLS_PORT; 10399 } else { 10400 if (parse_uri(curi, "sip:", &curi, NULL, &host, &pt, NULL, &transport)) 10401 ast_log(LOG_NOTICE, "Not a valid SIP contact (missing sip:) trying to use anyway\n"); 10402 port = !ast_strlen_zero(pt) ? atoi(pt) : STANDARD_SIP_PORT; 10403 } 10404 10405 /* handle the transport type specified in Contact header. */ 10406 if ((transport_type = get_transport_str2enum(transport))) { 10407 /* if the port is not specified but the transport is, make sure to set the 10408 * default port to match the specified transport. This may or may not be the 10409 * same transport used by the pvt struct for the Register dialog. */ 10410 if (ast_strlen_zero(pt)) { 10411 port = (transport_type == SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT; 10412 } 10413 } else { 10414 transport_type = pvt->socket.type; 10415 } 10416 10417 /* if the peer's socket type is different than the Registration 10418 * transport type, change it. If it got this far, it is a 10419 * supported type, but check just in case */ 10420 if ((peer->socket.type != transport_type) && (peer->transports & transport_type)) { 10421 set_socket_transport(&peer->socket, transport_type); 10422 } 10423 10424 oldsin = peer->addr; 10425 10426 /* Check that they're allowed to register at this IP */ 10427 /* XXX This could block for a long time XXX */ 10428 hp = ast_gethostbyname(host, &ahp); 10429 if (!hp) { 10430 ast_log(LOG_WARNING, "Invalid host '%s'\n", host); 10431 *peer->fullcontact = '\0'; 10432 ast_string_field_set(pvt, our_contact, ""); 10433 return PARSE_REGISTER_FAILED; 10434 } 10435 memcpy(&testsin.sin_addr, hp->h_addr, sizeof(testsin.sin_addr)); 10436 if ( ast_apply_ha(global_contact_ha, &testsin) != AST_SENSE_ALLOW || 10437 ast_apply_ha(peer->contactha, &testsin) != AST_SENSE_ALLOW) { 10438 ast_log(LOG_WARNING, "Host '%s' disallowed by rule\n", host); 10439 *peer->fullcontact = '\0'; 10440 ast_string_field_set(pvt, our_contact, ""); 10441 return PARSE_REGISTER_FAILED; 10442 } 10443 10444 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 10445 peer->addr.sin_family = AF_INET; 10446 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 10447 peer->addr.sin_port = htons(port); 10448 } else { 10449 /* Don't trust the contact field. Just use what they came to us 10450 with */ 10451 peer->addr = pvt->recv; 10452 } 10453 10454 /* if the Contact header information copied into peer->addr matches the 10455 * received address, and the transport types are the same, then copy socket 10456 * data into the peer struct */ 10457 if ((peer->socket.type == pvt->socket.type) && 10458 (peer->addr.sin_addr.s_addr == pvt->recv.sin_addr.s_addr) && 10459 (peer->addr.sin_port == pvt->recv.sin_port)){ 10460 10461 copy_socket_data(&peer->socket, &pvt->socket); 10462 } 10463 10464 /* Save SIP options profile */ 10465 peer->sipoptions = pvt->sipoptions; 10466 10467 if (!ast_strlen_zero(curi) && ast_strlen_zero(peer->username)) 10468 ast_copy_string(peer->username, curi, sizeof(peer->username)); 10469 10470 AST_SCHED_DEL(sched, peer->expire); 10471 if (expiry > max_expiry) 10472 expiry = max_expiry; 10473 if (expiry < min_expiry) 10474 expiry = min_expiry; 10475 peer->expire = peer->is_realtime && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? -1 : 10476 ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 10477 pvt->expiry = expiry; 10478 snprintf(data, sizeof(data), "%s:%d:%d:%s:%s", ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port), expiry, peer->username, peer->fullcontact); 10479 /* Saving TCP connections is useless, we won't be able to reconnect 10480 XXX WHY???? XXX 10481 \todo check this 10482 */ 10483 if (!peer->rt_fromcontact && (peer->socket.type & SIP_TRANSPORT_UDP)) 10484 ast_db_put("SIP/Registry", peer->name, data); 10485 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 10486 10487 /* Is this a new IP address for us? */ 10488 if (VERBOSITY_ATLEAST(2) && inaddrcmp(&peer->addr, &oldsin)) { 10489 ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s port %d\n", peer->name, ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port)); 10490 } 10491 sip_poke_peer(peer); 10492 register_peer_exten(peer, 1); 10493 10494 /* Save User agent */ 10495 useragent = get_header(req, "User-Agent"); 10496 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 10497 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 10498 ast_verb(4, "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 10499 } 10500 return PARSE_REGISTER_UPDATE; 10501 }
static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 6458 of file chan_sip.c.
References ast_debug, ast_strlen_zero(), sip_request::data, sip_request::header, sip_request::headers, sip_request::line, SIP_MAX_HEADERS, and SIP_MAX_LINES.
Referenced by handle_request_do(), initialize_initreq(), and parse_copy().
06459 { 06460 char *c = req->data, **dst = req->header; 06461 int i = 0, lim = SIP_MAX_HEADERS - 1; 06462 unsigned int skipping_headers = 0; 06463 06464 req->header[0] = c; 06465 req->headers = -1; /* mark that we are working on the header */ 06466 for (; *c; c++) { 06467 if (*c == '\r') { /* remove \r */ 06468 *c = '\0'; 06469 } else if (*c == '\n') { /* end of this line */ 06470 *c = '\0'; 06471 if (skipping_headers) { 06472 /* check to see if this line is blank; if so, turn off 06473 the skipping flag, so the next line will be processed 06474 as a body line */ 06475 if (ast_strlen_zero(dst[i])) { 06476 skipping_headers = 0; 06477 } 06478 dst[i] = c + 1; /* record start of next line */ 06479 continue; 06480 } 06481 if (sipdebug) { 06482 ast_debug(4, "%7s %2d [%3d]: %s\n", 06483 req->headers < 0 ? "Header" : "Body", 06484 i, (int) strlen(dst[i]), dst[i]); 06485 } 06486 if (ast_strlen_zero(dst[i]) && req->headers < 0) { 06487 req->headers = i; /* record number of header lines */ 06488 dst = req->line; /* start working on the body */ 06489 i = 0; 06490 lim = SIP_MAX_LINES - 1; 06491 } else { /* move to next line, check for overflows */ 06492 if (i++ == lim) { 06493 /* if we're processing headers, then skip any remaining 06494 headers and move on to processing the body, otherwise 06495 we're done */ 06496 if (req->headers != -1) { 06497 break; 06498 } else { 06499 req->headers = i; 06500 dst = req->line; 06501 i = 0; 06502 lim = SIP_MAX_LINES - 1; 06503 skipping_headers = 1; 06504 } 06505 } 06506 } 06507 dst[i] = c + 1; /* record start of next line */ 06508 } 06509 } 06510 06511 /* Check for last header or body line without CRLF. The RFC for SDP requires CRLF, 06512 but since some devices send without, we'll be generous in what we accept. However, 06513 if we've already reached the maximum number of lines for portion of the message 06514 we were parsing, we can't accept any more, so just ignore it. 06515 */ 06516 if ((i < lim) && !ast_strlen_zero(dst[i])) { 06517 if (sipdebug) { 06518 ast_debug(4, "%7s %2d [%3d]: %s\n", 06519 req->headers < 0 ? "Header" : "Body", 06520 i, (int) strlen(dst[i]), dst[i]); 06521 } 06522 i++; 06523 } 06524 06525 /* update count of header or body lines */ 06526 if (req->headers >= 0) { /* we are in the body */ 06527 req->lines = i; 06528 } else { /* no body */ 06529 req->headers = i; 06530 req->lines = 0; 06531 req->line[0] = ""; 06532 } 06533 06534 if (*c) { 06535 ast_log(LOG_WARNING, "Too many lines, skipping <%s>\n", c); 06536 } 06537 06538 /* Split up the first line parts */ 06539 return determine_firstline_parts(req); 06540 }
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 19965 of file chan_sip.c.
References ast_debug, ast_log(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, SESSION_TIMER_REFRESHER_AUTO, SESSION_TIMER_REFRESHER_UAC, SESSION_TIMER_REFRESHER_UAS, and strsep().
Referenced by handle_request_invite(), and handle_response_invite().
19966 { 19967 char *p_token; 19968 int ref_idx; 19969 char *p_se_hdr; 19970 19971 if (ast_strlen_zero(p_hdrval)) { 19972 ast_log(LOG_WARNING, "Null Session-Expires header\n"); 19973 return -1; 19974 } 19975 19976 *p_ref = SESSION_TIMER_REFRESHER_AUTO; 19977 *p_interval = 0; 19978 19979 p_se_hdr = ast_strdupa(p_hdrval); 19980 p_se_hdr = ast_skip_blanks(p_se_hdr); 19981 19982 while ((p_token = strsep(&p_se_hdr, ";"))) { 19983 p_token = ast_skip_blanks(p_token); 19984 if (!sscanf(p_token, "%d", p_interval)) { 19985 ast_log(LOG_WARNING, "Parsing of Session-Expires failed\n"); 19986 return -1; 19987 } 19988 19989 ast_debug(2, "Session-Expires: %d\n", *p_interval); 19990 19991 if (!p_se_hdr) 19992 continue; 19993 19994 ref_idx = strlen("refresher="); 19995 if (!strncasecmp(p_se_hdr, "refresher=", ref_idx)) { 19996 p_se_hdr += ref_idx; 19997 p_se_hdr = ast_skip_blanks(p_se_hdr); 19998 19999 if (!strncasecmp(p_se_hdr, "uac", strlen("uac"))) { 20000 *p_ref = SESSION_TIMER_REFRESHER_UAC; 20001 ast_debug(2, "Refresher: UAC\n"); 20002 } else if (!strncasecmp(p_se_hdr, "uas", strlen("uas"))) { 20003 *p_ref = SESSION_TIMER_REFRESHER_UAS; 20004 ast_debug(2, "Refresher: UAS\n"); 20005 } else { 20006 ast_log(LOG_WARNING, "Invalid refresher value %s\n", p_se_hdr); 20007 return -1; 20008 } 20009 break; 20010 } 20011 } 20012 return 0; 20013 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 2473 of file chan_sip.c.
References ARRAY_LEN, ast_debug, ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), FALSE, cfsip_options::id, sip_request::next, SIP_OPT_UNKNOWN, sip_options, sip_pvt::sipoptions, text, and TRUE.
Referenced by handle_request_invite().
02474 { 02475 char *next, *sep; 02476 char *temp; 02477 unsigned int profile = 0; 02478 int i, found; 02479 02480 if (ast_strlen_zero(supported) ) 02481 return 0; 02482 temp = ast_strdupa(supported); 02483 02484 if (sipdebug) 02485 ast_debug(3, "Begin: parsing SIP \"Supported: %s\"\n", supported); 02486 02487 for (next = temp; next; next = sep) { 02488 found = FALSE; 02489 if ( (sep = strchr(next, ',')) != NULL) 02490 *sep++ = '\0'; 02491 next = ast_skip_blanks(next); 02492 if (sipdebug) 02493 ast_debug(3, "Found SIP option: -%s-\n", next); 02494 for (i = 0; i < ARRAY_LEN(sip_options); i++) { 02495 if (!strcasecmp(next, sip_options[i].text)) { 02496 profile |= sip_options[i].id; 02497 found = TRUE; 02498 if (sipdebug) 02499 ast_debug(3, "Matched SIP option: %s\n", next); 02500 break; 02501 } 02502 } 02503 02504 /* This function is used to parse both Suported: and Require: headers. 02505 Let the caller of this function know that an unknown option tag was 02506 encountered, so that if the UAC requires it then the request can be 02507 rejected with a 420 response. */ 02508 if (!found) 02509 profile |= SIP_OPT_UNKNOWN; 02510 02511 if (!found && sipdebug) { 02512 if (!strncasecmp(next, "x-", 2)) 02513 ast_debug(3, "Found private SIP option, not supported: %s\n", next); 02514 else 02515 ast_debug(3, "Found no match for SIP option: %s (Please file bug report!)\n", next); 02516 } 02517 } 02518 02519 if (pvt) 02520 pvt->sipoptions = profile; 02521 return profile; 02522 }
static int parse_uri | ( | char * | uri, | |
char * | scheme, | |||
char ** | ret_name, | |||
char ** | pass, | |||
char ** | domain, | |||
char ** | port, | |||
char ** | options, | |||
char ** | transport | |||
) | [static] |
* parses a URI in its components.
* general form we are expecting is sip[s]:username[:password][;parameter]@host[:port][;...] *
Definition at line 3399 of file chan_sip.c.
References ast_debug, name, strsep(), and type.
Referenced by __set_address_from_contact(), check_user_full(), and parse_register_contact().
03401 { 03402 char *name = NULL; 03403 int error = 0; 03404 03405 /* init field as required */ 03406 if (pass) 03407 *pass = ""; 03408 if (port) 03409 *port = ""; 03410 if (scheme) { 03411 int l = strlen(scheme); 03412 if (!strncasecmp(uri, scheme, l)) 03413 uri += l; 03414 else { 03415 ast_debug(1, "Missing scheme '%s' in '%s'\n", scheme, uri); 03416 error = -1; 03417 } 03418 } 03419 if (transport) { 03420 char *t, *type = ""; 03421 *transport = ""; 03422 if ((t = strstr(uri, "transport="))) { 03423 strsep(&t, "="); 03424 if ((type = strsep(&t, ";"))) { 03425 *transport = type; 03426 } 03427 } 03428 } 03429 03430 if (!domain) { 03431 /* if we don't want to split around domain, keep everything as a name, 03432 * so we need to do nothing here, except remember why. 03433 */ 03434 } else { 03435 /* store the result in a temp. variable to avoid it being 03436 * overwritten if arguments point to the same place. 03437 */ 03438 char *c, *dom = ""; 03439 03440 if ((c = strchr(uri, '@')) == NULL) { 03441 /* domain-only URI, according to the SIP RFC. */ 03442 dom = uri; 03443 name = ""; 03444 } else { 03445 *c++ = '\0'; 03446 dom = c; 03447 name = uri; 03448 } 03449 03450 /* Remove options in domain and name */ 03451 dom = strsep(&dom, ";"); 03452 name = strsep(&name, ";"); 03453 03454 if (port && (c = strchr(dom, ':'))) { /* Remove :port */ 03455 *c++ = '\0'; 03456 *port = c; 03457 } 03458 if (pass && (c = strchr(name, ':'))) { /* user:password */ 03459 *c++ = '\0'; 03460 *pass = c; 03461 } 03462 *domain = dom; 03463 } 03464 if (ret_name) /* same as for domain, store the result only at the end */ 03465 *ret_name = name; 03466 if (options) 03467 *options = uri ? uri : ""; 03468 03469 return error; 03470 }
static void peer_mailboxes_to_str | ( | struct ast_str ** | mailbox_str, | |
struct sip_peer * | peer | |||
) | [static] |
list peer mailboxes to CLI
Definition at line 13246 of file chan_sip.c.
References AST_LIST_NEXT, AST_LIST_TRAVERSE, ast_str_append(), ast_strlen_zero(), sip_mailbox::entry, mailbox, sip_peer::mailboxes, and S_OR.
Referenced by _sip_show_peer(), function_sippeer(), show_channels_cb(), and sip_send_mwi_to_peer().
13247 { 13248 struct sip_mailbox *mailbox; 13249 13250 AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) { 13251 ast_str_append(mailbox_str, 0, "%s%s%s%s", 13252 mailbox->mailbox, 13253 ast_strlen_zero(mailbox->context) ? "" : "@", 13254 S_OR(mailbox->context, ""), 13255 AST_LIST_NEXT(mailbox, entry) ? "," : ""); 13256 } 13257 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Definition at line 12517 of file chan_sip.c.
References ast_copy_string(), sip_peer::lastms, and sip_peer::maxms.
12518 { 12519 int res = 0; 12520 if (peer->maxms) { 12521 if (peer->lastms < 0) { 12522 ast_copy_string(status, "UNREACHABLE", statuslen); 12523 } else if (peer->lastms > peer->maxms) { 12524 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 12525 res = 1; 12526 } else if (peer->lastms) { 12527 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 12528 res = 1; 12529 } else { 12530 ast_copy_string(status, "UNKNOWN", statuslen); 12531 } 12532 } else { 12533 ast_copy_string(status, "Unmonitored", statuslen); 12534 /* Checking if port is 0 */ 12535 res = -1; 12536 } 12537 return res; 12538 }
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 13137 of file chan_sip.c.
References ast_cli(), ast_codec_pref_index(), ast_getformatname(), and ast_codec_pref::framing.
Referenced by _sip_show_peer(), handle_skinny_show_line(), sip_show_settings(), and sip_show_user().
13138 { 13139 int x, codec; 13140 13141 for(x = 0; x < 32 ; x++) { 13142 codec = ast_codec_pref_index(pref, x); 13143 if (!codec) 13144 break; 13145 ast_cli(fd, "%s", ast_getformatname(codec)); 13146 ast_cli(fd, ":%d", pref->framing[x]); 13147 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 13148 ast_cli(fd, ","); 13149 } 13150 if (!x) 13151 ast_cli(fd, "none"); 13152 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 12911 of file chan_sip.c.
References ast_cli(), ast_print_group(), and buf.
Referenced by _sip_show_peer(), and sip_show_user().
12912 { 12913 char buf[256]; 12914 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 12915 }
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 20023 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), get_header(), LOG_WARNING, parse_minse(), SIP_INVITE, sip_st_dlg::st_interval, sip_pvt::stimer, and transmit_invite().
Referenced by handle_response_invite().
20024 { 20025 int rtn; 20026 const char *p_hdrval; 20027 int minse; 20028 20029 p_hdrval = get_header(rsp, "Min-SE"); 20030 if (ast_strlen_zero(p_hdrval)) { 20031 ast_log(LOG_WARNING, "422 response without a Min-SE header %s\n", p_hdrval); 20032 return; 20033 } 20034 rtn = parse_minse(p_hdrval, &minse); 20035 if (rtn != 0) { 20036 ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval); 20037 return; 20038 } 20039 p->stimer->st_interval = minse; 20040 transmit_invite(p, SIP_INVITE, 1, 2); 20041 }
static int proc_session_timer | ( | const void * | vp | ) | [static] |
Session-Timers: Process session refresh timeout event.
Definition at line 19883 of file chan_sip.c.
References ast_channel::_state, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_log(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, sip_pvt::callid, FALSE, LOG_ERROR, LOG_WARNING, sip_pvt::outgoing_call, sip_pvt::owner, SESSION_TIMER_REFRESHER_UAC, SESSION_TIMER_REFRESHER_UAS, sip_pvt_lock, sip_pvt_unlock, sip_st_dlg::st_active, sip_st_dlg::st_expirys, sip_st_dlg::st_ref, sip_st_dlg::st_schedid, sip_pvt::stimer, stop_session_timer(), transmit_reinvite_with_sdp(), and TRUE.
Referenced by start_session_timer().
19884 { 19885 struct sip_pvt *p = (struct sip_pvt *) vp; 19886 int sendreinv = FALSE; 19887 19888 if (!p->stimer) { 19889 ast_log(LOG_WARNING, "Null stimer in proc_session_timer - %s\n", p->callid); 19890 return 0; 19891 } 19892 19893 ast_debug(2, "Session timer expired: %d - %s\n", p->stimer->st_schedid, p->callid); 19894 19895 if (!p->owner) { 19896 if (p->stimer->st_active == TRUE) { 19897 stop_session_timer(p); 19898 } 19899 return 0; 19900 } 19901 19902 if ((p->stimer->st_active != TRUE) || (p->owner->_state != AST_STATE_UP)) { 19903 return 0; 19904 } 19905 19906 switch (p->stimer->st_ref) { 19907 case SESSION_TIMER_REFRESHER_UAC: 19908 if (p->outgoing_call == TRUE) { 19909 sendreinv = TRUE; 19910 } 19911 break; 19912 case SESSION_TIMER_REFRESHER_UAS: 19913 if (p->outgoing_call != TRUE) { 19914 sendreinv = TRUE; 19915 } 19916 break; 19917 default: 19918 ast_log(LOG_ERROR, "Unknown session refresher %d\n", p->stimer->st_ref); 19919 return -1; 19920 } 19921 19922 if (sendreinv == TRUE) { 19923 transmit_reinvite_with_sdp(p, FALSE, TRUE); 19924 } else { 19925 p->stimer->st_expirys++; 19926 if (p->stimer->st_expirys >= 2) { 19927 ast_log(LOG_WARNING, "Session-Timer expired - %s\n", p->callid); 19928 stop_session_timer(p); 19929 19930 while (p->owner && ast_channel_trylock(p->owner)) { 19931 sip_pvt_unlock(p); 19932 usleep(1); 19933 sip_pvt_lock(p); 19934 } 19935 19936 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 19937 ast_channel_unlock(p->owner); 19938 } 19939 } 19940 return 1; 19941 }
static void process_request_queue | ( | struct sip_pvt * | p, | |
int * | recount, | |||
int * | nounlock | |||
) | [static] |
Definition at line 19175 of file chan_sip.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_log(), handle_incoming(), LOG_DEBUG, sip_request::next, option_debug, and sip_pvt::request_queue.
Referenced by handle_request_do().
19176 { 19177 struct sip_request *req; 19178 19179 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 19180 if (handle_incoming(p, req, &p->recv, recount, nounlock) == -1) { 19181 /* Request failed */ 19182 if (option_debug) { 19183 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 19184 } 19185 } 19186 ast_free(req); 19187 } 19188 }
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 port number
< RTP Video port number
< RTP Text port number
< media socket address
< Video socket address
< Text socket address
< RTP Audio host IP
< RTP video host IP
< RTP text host IP
Definition at line 6703 of file chan_sip.c.
References append_history, ast_clear_flag, ast_codec_choose(), ast_codec_pref_setsize(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_debug, AST_FORMAT_AUDIO_MASK, ast_getformatname_multiple(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_alloc_size(), ast_rtp_codec_getformat(), ast_rtp_codec_getpref(), ast_rtp_codec_setpref(), AST_RTP_DTMF, ast_rtp_get_current_formats(), ast_rtp_get_peer(), ast_rtp_lookup_mime_multiple(), ast_rtp_new_init(), AST_RTP_OPT_G726_NONSTANDARD, ast_rtp_pt_clear(), ast_rtp_pt_copy(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_set_rtpmap_type(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_stop(), ast_rtp_unset_m_type(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_threadstorage_get(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), ast_udptl_set_peer(), ast_udptl_stop(), ast_verbose(), sip_pvt::autoframing, buf, sip_pvt::callid, sip_pvt::capability, t38properties::capability, change_t38_state(), sip_request::data, debug, EVENT_FLAG_CALL, FALSE, sip_pvt::flags, format, get_sdp(), get_sdp_iterate(), hp, sip_pvt::jointcapability, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastinvite, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len(), LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, MAX_RTP_PT, sip_pvt::mohsuggest, ast_channel::name, ast_channel::nativeformats, sip_pvt::noncodeccapability, sip_pvt::notext, sip_pvt::novideo, option_debug, sip_pvt::owner, sip_pvt::peercapability, t38properties::peercapability, sip_pvt::prefs, ast_channel::readformat, sip_pvt::rtp, s, S_OR, SDP_MAX_RTPMAP_CODECS, sip_request::sdp_start, SDP_T38_ACCEPT, SDP_T38_INITIATE, sip_pvt::session_modify, sip_pvt::sessionversion_remote, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_G726_NONSTANDARD, SIP_NAT, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_ACTIVE, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_IGNORESDPVERSION, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_UDPTL_DESTINATION, sip_peer_hold(), SIPBUFSIZE, t38properties::state, strsep(), sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_REINVITE, T38_PEER_DIRECT, T38_PEER_REINVITE, T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_12000, T38FAX_RATE_14400, T38FAX_RATE_2400, T38FAX_RATE_4800, T38FAX_RATE_7200, T38FAX_RATE_9600, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION_0, T38FAX_VERSION_1, text, sip_pvt::trtp, TRUE, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, ast_channel::uniqueid, sip_pvt::vrtp, and ast_channel::writeformat.
06704 { 06705 const char *m; /* SDP media offer */ 06706 const char *c; 06707 const char *a; 06708 const char *o; /* Pointer to o= line */ 06709 char *o_copy; /* Copy of o= line */ 06710 char *token; 06711 char host[258]; 06712 int len = -1; 06713 int portno = -1; /*!< RTP Audio port number */ 06714 int vportno = -1; /*!< RTP Video port number */ 06715 int tportno = -1; /*!< RTP Text port number */ 06716 int udptlportno = -1; 06717 int peert38capability = 0; 06718 char s[256]; 06719 int old = 0; 06720 06721 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 06722 int peercapability = 0, peernoncodeccapability = 0; 06723 int vpeercapability = 0, vpeernoncodeccapability = 0; 06724 int tpeercapability = 0, tpeernoncodeccapability = 0; 06725 struct sockaddr_in sin; /*!< media socket address */ 06726 struct sockaddr_in vsin; /*!< Video socket address */ 06727 struct sockaddr_in tsin; /*!< Text socket address */ 06728 06729 const char *codecs; 06730 struct hostent *hp; /*!< RTP Audio host IP */ 06731 struct hostent *vhp = NULL; /*!< RTP video host IP */ 06732 struct hostent *thp = NULL; /*!< RTP text host IP */ 06733 struct ast_hostent audiohp; 06734 struct ast_hostent videohp; 06735 struct ast_hostent texthp; 06736 int codec; 06737 int destiterator = 0; 06738 int iterator; 06739 int sendonly = -1; 06740 int numberofports; 06741 struct ast_rtp *newaudiortp, *newvideortp, *newtextrtp; /* Buffers for codec handling */ 06742 int newjointcapability; /* Negotiated capability */ 06743 int newpeercapability; 06744 int newnoncodeccapability; 06745 int numberofmediastreams = 0; 06746 int debug = sip_debug_test_pvt(p); 06747 06748 int found_rtpmap_codecs[SDP_MAX_RTPMAP_CODECS]; 06749 int last_rtpmap_codec=0; 06750 06751 char buf[SIPBUFSIZE]; 06752 int64_t rua_version; 06753 06754 if (!p->rtp) { 06755 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 06756 return -1; 06757 } 06758 06759 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 06760 #ifdef LOW_MEMORY 06761 newaudiortp = ast_threadstorage_get(&ts_audio_rtp, ast_rtp_alloc_size()); 06762 #else 06763 newaudiortp = alloca(ast_rtp_alloc_size()); 06764 #endif 06765 memset(newaudiortp, 0, ast_rtp_alloc_size()); 06766 ast_rtp_new_init(newaudiortp); 06767 ast_rtp_pt_clear(newaudiortp); 06768 06769 #ifdef LOW_MEMORY 06770 newvideortp = ast_threadstorage_get(&ts_video_rtp, ast_rtp_alloc_size()); 06771 #else 06772 newvideortp = alloca(ast_rtp_alloc_size()); 06773 #endif 06774 memset(newvideortp, 0, ast_rtp_alloc_size()); 06775 ast_rtp_new_init(newvideortp); 06776 ast_rtp_pt_clear(newvideortp); 06777 06778 #ifdef LOW_MEMORY 06779 newtextrtp = ast_threadstorage_get(&ts_text_rtp, ast_rtp_alloc_size()); 06780 #else 06781 newtextrtp = alloca(ast_rtp_alloc_size()); 06782 #endif 06783 memset(newtextrtp, 0, ast_rtp_alloc_size()); 06784 ast_rtp_new_init(newtextrtp); 06785 ast_rtp_pt_clear(newtextrtp); 06786 06787 /* Update our last rtprx when we receive an SDP, too */ 06788 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 06789 06790 /* Store the SDP version number of remote UA. This will allow us to 06791 distinguish between session modifications and session refreshes. If 06792 the remote UA does not send an incremented SDP version number in a 06793 subsequent RE-INVITE then that means its not changing media session. 06794 The RE-INVITE may have been sent to update connected party, remote 06795 target or to refresh the session (Session-Timers). Asterisk must not 06796 change media session and increment its own version number in answer 06797 SDP in this case. */ 06798 06799 o = get_sdp(req, "o"); 06800 if (ast_strlen_zero(o)) { 06801 ast_log(LOG_WARNING, "SDP sytax error. SDP without an o= line\n"); 06802 return -1; 06803 } 06804 06805 o_copy = ast_strdupa(o); 06806 token = strsep(&o_copy, " "); /* Skip username */ 06807 if (!o_copy) { 06808 ast_log(LOG_WARNING, "SDP sytax error in o= line username\n"); 06809 return -1; 06810 } 06811 token = strsep(&o_copy, " "); /* Skip session-id */ 06812 if (!o_copy) { 06813 ast_log(LOG_WARNING, "SDP sytax error in o= line session-id\n"); 06814 return -1; 06815 } 06816 token = strsep(&o_copy, " "); /* Version */ 06817 if (!o_copy) { 06818 ast_log(LOG_WARNING, "SDP sytax error in o= line\n"); 06819 return -1; 06820 } 06821 if (!sscanf(token, "%" SCNd64, &rua_version)) { 06822 ast_log(LOG_WARNING, "SDP sytax error in o= line version\n"); 06823 return -1; 06824 } 06825 06826 /* we need to check the SDP version number the other end sent us; 06827 * our rules for deciding what to accept are a bit complex. 06828 * 06829 * 1) if 'ignoresdpversion' has been set for this dialog, then 06830 * we will just accept whatever they sent and assume it is 06831 * a modification of the session, even if it is not 06832 * 2) otherwise, if this is the first SDP we've seen from them 06833 * we accept it 06834 * 3) otherwise, if the new SDP version number is higher than the 06835 * old one, we accept it 06836 * 4) otherwise, if this SDP is in response to us requesting a switch 06837 * to T.38, we accept the SDP, but also generate a warning message 06838 * that this peer should have the 'ignoresdpversion' option set, 06839 * because it is not following the SDP offer/answer RFC; if we did 06840 * not request a switch to T.38, then we stop parsing the SDP, as it 06841 * has not changed from the previous version 06842 */ 06843 06844 if (ast_test_flag(&p->flags[1], SIP_PAGE2_IGNORESDPVERSION) || 06845 (p->sessionversion_remote < 0) || 06846 (p->sessionversion_remote < rua_version)) { 06847 p->sessionversion_remote = rua_version; 06848 p->session_modify = TRUE; 06849 } else { 06850 if (p->t38.state == T38_LOCAL_REINVITE) { 06851 p->sessionversion_remote = rua_version; 06852 p->session_modify = TRUE; 06853 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); 06854 } else { 06855 p->session_modify = FALSE; 06856 ast_debug(2, "Call %s responded to our reinvite without changing SDP version; ignoring SDP.\n", p->callid); 06857 return 0; 06858 } 06859 } 06860 06861 /* Try to find first media stream */ 06862 m = get_sdp(req, "m"); 06863 destiterator = req->sdp_start; 06864 c = get_sdp_iterate(&destiterator, req, "c"); 06865 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 06866 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 06867 return -1; 06868 } 06869 06870 /* Check for IPv4 address (not IPv6 yet) */ 06871 if (sscanf(c, "IN IP4 %256s", host) != 1) { 06872 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 06873 return -1; 06874 } 06875 06876 /* XXX This could block for a long time, and block the main thread! XXX */ 06877 hp = ast_gethostbyname(host, &audiohp); 06878 if (!hp) { 06879 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 06880 return -1; 06881 } 06882 vhp = hp; /* Copy to video address as default too */ 06883 thp = hp; /* Copy to text address as default too */ 06884 06885 iterator = req->sdp_start; 06886 /* default: novideo and notext set */ 06887 p->novideo = TRUE; 06888 p->notext = TRUE; 06889 06890 if (p->vrtp) 06891 ast_rtp_pt_clear(newvideortp); /* Must be cleared in case no m=video line exists */ 06892 06893 if (p->trtp) 06894 ast_rtp_pt_clear(newtextrtp); /* Must be cleared in case no m=text line exists */ 06895 06896 /* Find media streams in this SDP offer */ 06897 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 06898 int x; 06899 int audio = FALSE; 06900 int video = FALSE; 06901 int text = FALSE; 06902 06903 numberofports = 1; 06904 len = -1; 06905 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 06906 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1 && len > 0)) { 06907 audio = TRUE; 06908 numberofmediastreams++; 06909 /* Found audio stream in this media definition */ 06910 portno = x; 06911 /* Scan through the RTP payload types specified in a "m=" line: */ 06912 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 06913 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 06914 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 06915 return -1; 06916 } 06917 if (debug) 06918 ast_verbose("Found RTP audio format %d\n", codec); 06919 ast_rtp_set_m_type(newaudiortp, codec); 06920 } 06921 } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 06922 (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1 && len >= 0)) { 06923 video = TRUE; 06924 p->novideo = FALSE; 06925 numberofmediastreams++; 06926 vportno = x; 06927 /* Scan through the RTP payload types specified in a "m=" line: */ 06928 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 06929 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 06930 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 06931 return -1; 06932 } 06933 if (debug) 06934 ast_verbose("Found RTP video format %d\n", codec); 06935 ast_rtp_set_m_type(newvideortp, codec); 06936 } 06937 } else if ((sscanf(m, "text %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 06938 (sscanf(m, "text %d RTP/AVP %n", &x, &len) == 1 && len > 0)) { 06939 text = TRUE; 06940 p->notext = FALSE; 06941 numberofmediastreams++; 06942 tportno = x; 06943 /* Scan through the RTP payload types specified in a "m=" line: */ 06944 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 06945 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 06946 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 06947 return -1; 06948 } 06949 if (debug) 06950 ast_verbose("Found RTP text format %d\n", codec); 06951 ast_rtp_set_m_type(newtextrtp, codec); 06952 } 06953 } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1 && len > 0) || 06954 (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1 && len > 0) )) { 06955 if (debug) 06956 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 06957 udptlportno = x; 06958 numberofmediastreams++; 06959 } else 06960 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 06961 if (numberofports > 1) 06962 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 06963 06964 06965 /* Check for Media-description-level-address for audio */ 06966 c = get_sdp_iterate(&destiterator, req, "c"); 06967 if (!ast_strlen_zero(c)) { 06968 if (sscanf(c, "IN IP4 %256s", host) != 1) { 06969 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 06970 } else { 06971 /* XXX This could block for a long time, and block the main thread! XXX */ 06972 if (audio) { 06973 if ( !(hp = ast_gethostbyname(host, &audiohp))) { 06974 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c); 06975 return -2; 06976 } 06977 } else if (video) { 06978 if (!(vhp = ast_gethostbyname(host, &videohp))) { 06979 ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c); 06980 return -2; 06981 } 06982 } else if (text) { 06983 if (!(thp = ast_gethostbyname(host, &texthp))) { 06984 ast_log(LOG_WARNING, "Unable to lookup RTP text host in secondary c= line, '%s'\n", c); 06985 return -2; 06986 } 06987 } 06988 } 06989 06990 } 06991 } 06992 if (portno == -1 && vportno == -1 && udptlportno == -1 && tportno == -1) 06993 /* No acceptable offer found in SDP - we have no ports */ 06994 /* Do not change RTP or VRTP if this is a re-invite */ 06995 return -2; 06996 06997 if (numberofmediastreams > 3) 06998 /* We have too many fax, audio and/or video and/or text media streams, fail this offer */ 06999 return -3; 07000 07001 /* RTP addresses and ports for audio and video */ 07002 sin.sin_family = AF_INET; 07003 vsin.sin_family = AF_INET; 07004 tsin.sin_family = AF_INET; 07005 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 07006 if (vhp) 07007 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 07008 if (thp) 07009 memcpy(&tsin.sin_addr, thp->h_addr, sizeof(tsin.sin_addr)); 07010 07011 /* Setup UDPTL port number */ 07012 if (p->udptl) { 07013 if (udptlportno > 0) { 07014 sin.sin_port = htons(udptlportno); 07015 if (ast_test_flag(&p->flags[0], SIP_NAT) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 07016 struct sockaddr_in peer; 07017 ast_rtp_get_peer(p->rtp, &peer); 07018 if (peer.sin_addr.s_addr) { 07019 memcpy(&sin.sin_addr, &peer.sin_addr, sizeof(sin.sin_addr)); 07020 if (debug) { 07021 ast_log(LOG_DEBUG, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_inet_ntoa(sin.sin_addr)); 07022 } 07023 } 07024 } 07025 ast_udptl_set_peer(p->udptl, &sin); 07026 if (debug) 07027 ast_debug(1, "Peer T.38 UDPTL is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 07028 } else { 07029 ast_udptl_stop(p->udptl); 07030 if (debug) 07031 ast_debug(1, "Peer doesn't provide T.38 UDPTL\n"); 07032 } 07033 } 07034 07035 07036 if (p->rtp) { 07037 if (portno > 0) { 07038 sin.sin_port = htons(portno); 07039 ast_rtp_set_peer(p->rtp, &sin); 07040 if (debug) 07041 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 07042 } else { 07043 if (udptlportno > 0) { 07044 if (debug) 07045 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid); 07046 } else { 07047 ast_rtp_stop(p->rtp); 07048 if (debug) 07049 ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid); 07050 } 07051 } 07052 } 07053 /* Setup video port number, assumes we have audio */ 07054 if (vportno != -1) 07055 vsin.sin_port = htons(vportno); 07056 07057 /* Setup text port number, assumes we have audio */ 07058 if (tportno != -1) 07059 tsin.sin_port = htons(tportno); 07060 07061 /* Next, scan through each "a=xxxx:" line, noting each 07062 * specified RTP payload type (with corresponding MIME subtype): 07063 */ 07064 /* XXX This needs to be done per media stream, since it's media stream specific */ 07065 iterator = req->sdp_start; 07066 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 07067 char mimeSubtype[128]; 07068 if (option_debug > 1) { 07069 int breakout = FALSE; 07070 07071 /* If we're debugging, check for unsupported sdp options */ 07072 if (!strncasecmp(a, "rtcp:", (size_t) 5)) { 07073 if (debug) 07074 ast_verbose("Got unsupported a:rtcp in SDP offer \n"); 07075 breakout = TRUE; 07076 } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) { 07077 /* Format parameters: Not supported */ 07078 /* Note: This is used for codec parameters, like bitrate for 07079 G722 and video formats for H263 and H264 07080 See RFC2327 for an example */ 07081 if (debug) 07082 ast_verbose("Got unsupported a:fmtp in SDP offer \n"); 07083 breakout = TRUE; 07084 } else if (!strncasecmp(a, "framerate:", (size_t) 10)) { 07085 /* Video stuff: Not supported */ 07086 if (debug) 07087 ast_verbose("Got unsupported a:framerate in SDP offer \n"); 07088 breakout = TRUE; 07089 } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) { 07090 /* Video stuff: Not supported */ 07091 if (debug) 07092 ast_verbose("Got unsupported a:maxprate in SDP offer \n"); 07093 breakout = TRUE; 07094 } else if (!strncasecmp(a, "crypto:", (size_t) 7)) { 07095 /* SRTP stuff, not yet supported */ 07096 if (debug) 07097 ast_verbose("Got unsupported a:crypto in SDP offer \n"); 07098 breakout = TRUE; 07099 } 07100 if (breakout) /* We have a match, skip to next header */ 07101 continue; 07102 } 07103 if (!strcasecmp(a, "sendonly")) { 07104 if (sendonly == -1) 07105 sendonly = 1; 07106 continue; 07107 } else if (!strcasecmp(a, "inactive")) { 07108 if (sendonly == -1) 07109 sendonly = 2; 07110 continue; 07111 } else if (!strcasecmp(a, "sendrecv")) { 07112 if (sendonly == -1) 07113 sendonly = 0; 07114 continue; 07115 } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 07116 char *tmp = strrchr(a, ':'); 07117 long int framing = 0; 07118 if (tmp) { 07119 tmp++; 07120 framing = strtol(tmp, NULL, 10); 07121 if (framing == LONG_MIN || framing == LONG_MAX) { 07122 framing = 0; 07123 ast_debug(1, "Can't read framing from SDP: %s\n", a); 07124 } 07125 } 07126 if (framing && p->autoframing) { 07127 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 07128 int codec_n; 07129 int format = 0; 07130 for (codec_n = 0; codec_n < MAX_RTP_PT; codec_n++) { 07131 format = ast_rtp_codec_getformat(codec_n); 07132 if (!format) /* non-codec or not found */ 07133 continue; 07134 if (option_debug) 07135 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 07136 ast_codec_pref_setsize(pref, format, framing); 07137 } 07138 ast_rtp_codec_setpref(p->rtp, pref); 07139 } 07140 continue; 07141 } else if (sscanf(a, "rtpmap: %u %127[^/]/", &codec, mimeSubtype) == 2) { 07142 /* We have a rtpmap to handle */ 07143 07144 if (last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 07145 /* Note: should really look at the 'freq' and '#chans' params too */ 07146 /* Note: This should all be done in the context of the m= above */ 07147 if (!strncasecmp(mimeSubtype, "H26", 3) || !strncasecmp(mimeSubtype, "MP4", 3)) { /* Video */ 07148 if(ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) { 07149 if (debug) 07150 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 07151 found_rtpmap_codecs[last_rtpmap_codec] = codec; 07152 last_rtpmap_codec++; 07153 } else { 07154 ast_rtp_unset_m_type(newvideortp, codec); 07155 if (debug) 07156 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 07157 } 07158 } else if (!strncasecmp(mimeSubtype, "T140", 4)) { /* Text */ 07159 if (p->trtp) { 07160 /* ast_verbose("Adding t140 mimeSubtype to textrtp struct\n"); */ 07161 ast_rtp_set_rtpmap_type(newtextrtp, codec, "text", mimeSubtype, 0); 07162 } 07163 } else { /* Must be audio?? */ 07164 if(ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 07165 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) { 07166 if (debug) 07167 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 07168 found_rtpmap_codecs[last_rtpmap_codec] = codec; 07169 last_rtpmap_codec++; 07170 } else { 07171 ast_rtp_unset_m_type(newaudiortp, codec); 07172 if (debug) 07173 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 07174 } 07175 } 07176 } else { 07177 if (debug) 07178 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 07179 } 07180 07181 } 07182 } 07183 07184 if (udptlportno != -1) { 07185 int found = 0, x; 07186 07187 old = 0; 07188 07189 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 07190 iterator = req->sdp_start; 07191 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 07192 if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) { 07193 found = 1; 07194 ast_debug(3, "MaxBufferSize:%d\n", x); 07195 } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1) || (sscanf(a, "T38FaxMaxRate:%d", &x) == 1)) { 07196 found = 1; 07197 ast_debug(3, "T38MaxBitRate: %d\n", x); 07198 switch (x) { 07199 case 14400: 07200 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 07201 break; 07202 case 12000: 07203 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 07204 break; 07205 case 9600: 07206 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 07207 break; 07208 case 7200: 07209 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 07210 break; 07211 case 4800: 07212 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 07213 break; 07214 case 2400: 07215 peert38capability |= T38FAX_RATE_2400; 07216 break; 07217 } 07218 } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) { 07219 found = 1; 07220 ast_debug(3, "FaxVersion: %d\n", x); 07221 if (x == 0) 07222 peert38capability |= T38FAX_VERSION_0; 07223 else if (x == 1) 07224 peert38capability |= T38FAX_VERSION_1; 07225 } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1) || (sscanf(a, "T38MaxDatagram:%d", &x) == 1)) { 07226 found = 1; 07227 ast_debug(3, "FaxMaxDatagram: %d\n", x); 07228 ast_udptl_set_far_max_datagram(p->udptl, x); 07229 ast_udptl_set_local_max_datagram(p->udptl, x); 07230 } else if ((strncmp(a, "T38FaxFillBitRemoval", 20) == 0)) { 07231 found = 1; 07232 if(sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1) { 07233 ast_debug(3, "FillBitRemoval: %d\n", x); 07234 if(x == 1) 07235 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 07236 } else { 07237 ast_debug(3, "FillBitRemoval\n"); 07238 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 07239 } 07240 } else if ((strncmp(a, "T38FaxTranscodingMMR", 20) == 0)) { 07241 found = 1; 07242 if(sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1) { 07243 ast_debug(3, "Transcoding MMR: %d\n", x); 07244 if(x == 1) 07245 peert38capability |= T38FAX_TRANSCODING_MMR; 07246 } else { 07247 ast_debug(3, "Transcoding MMR\n"); 07248 peert38capability |= T38FAX_TRANSCODING_MMR; 07249 } 07250 } else if ((strncmp(a, "T38FaxTranscodingJBIG", 21) == 0)) { 07251 found = 1; 07252 if(sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1) { 07253 ast_debug(3, "Transcoding JBIG: %d\n", x); 07254 if(x == 1) 07255 peert38capability |= T38FAX_TRANSCODING_JBIG; 07256 } else { 07257 ast_debug(3, "Transcoding JBIG\n"); 07258 peert38capability |= T38FAX_TRANSCODING_JBIG; 07259 } 07260 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 07261 found = 1; 07262 ast_debug(3, "RateManagement: %s\n", s); 07263 if (!strcasecmp(s, "localTCF")) 07264 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 07265 else if (!strcasecmp(s, "transferredTCF")) 07266 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 07267 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 07268 found = 1; 07269 ast_debug(3, "UDP EC: %s\n", s); 07270 if (!strcasecmp(s, "t38UDPRedundancy")) { 07271 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 07272 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 07273 } else if (!strcasecmp(s, "t38UDPFEC")) { 07274 peert38capability |= T38FAX_UDP_EC_FEC; 07275 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 07276 } else { 07277 peert38capability |= T38FAX_UDP_EC_NONE; 07278 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 07279 } 07280 } 07281 } 07282 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 07283 p->t38.peercapability = peert38capability; 07284 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 07285 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 07286 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 07287 } 07288 if (debug) 07289 ast_debug(1, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 07290 p->t38.capability, 07291 p->t38.peercapability, 07292 p->t38.jointcapability); 07293 07294 /* Remote party offers T38, we need to update state */ 07295 if (t38action == SDP_T38_ACCEPT) { 07296 if (p->t38.state == T38_LOCAL_REINVITE) 07297 change_t38_state(p, T38_ENABLED); 07298 } else if (t38action == SDP_T38_INITIATE) { 07299 if (p->owner && p->lastinvite) { 07300 change_t38_state(p, T38_PEER_REINVITE); /* T38 Offered in re-invite from remote party */ 07301 } else { 07302 change_t38_state(p, T38_PEER_DIRECT); /* T38 Offered directly from peer in first invite */ 07303 } 07304 } 07305 } else { 07306 change_t38_state(p, T38_DISABLED); 07307 } 07308 07309 /* Now gather all of the codecs that we are asked for: */ 07310 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 07311 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 07312 ast_rtp_get_current_formats(newtextrtp, &tpeercapability, &tpeernoncodeccapability); 07313 07314 newjointcapability = p->capability & (peercapability | vpeercapability | tpeercapability); 07315 newpeercapability = (peercapability | vpeercapability | tpeercapability); 07316 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 07317 07318 07319 if (debug) { 07320 /* shame on whoever coded this.... */ 07321 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE], s5[SIPBUFSIZE]; 07322 07323 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s/text=%s, combined - %s\n", 07324 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 07325 ast_getformatname_multiple(s2, SIPBUFSIZE, peercapability), 07326 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 07327 ast_getformatname_multiple(s4, SIPBUFSIZE, tpeercapability), 07328 ast_getformatname_multiple(s5, SIPBUFSIZE, newjointcapability)); 07329 07330 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 07331 ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0), 07332 ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0), 07333 ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0)); 07334 } 07335 if (!newjointcapability) { 07336 /* If T.38 was not negotiated either, totally bail out... */ 07337 if (!p->t38.jointcapability || !udptlportno) { 07338 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 07339 /* Do NOT Change current setting */ 07340 return -1; 07341 } else { 07342 ast_debug(3, "Have T.38 but no audio codecs, accepting offer anyway\n"); 07343 return 0; 07344 } 07345 } 07346 07347 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 07348 they are acceptable */ 07349 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 07350 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 07351 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 07352 07353 ast_rtp_pt_copy(p->rtp, newaudiortp); 07354 if (p->vrtp) 07355 ast_rtp_pt_copy(p->vrtp, newvideortp); 07356 if (p->trtp) 07357 ast_rtp_pt_copy(p->trtp, newtextrtp); 07358 07359 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 07360 ast_clear_flag(&p->flags[0], SIP_DTMF); 07361 if (newnoncodeccapability & AST_RTP_DTMF) { 07362 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 07363 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 07364 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 07365 ast_rtp_setdtmf(p->rtp, 1); 07366 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 07367 } else { 07368 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 07369 } 07370 } 07371 07372 /* Setup audio port number */ 07373 if (p->rtp && sin.sin_port) { 07374 ast_rtp_set_peer(p->rtp, &sin); 07375 if (debug) 07376 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 07377 } 07378 07379 /* Setup video port number */ 07380 if (p->vrtp && vsin.sin_port) { 07381 ast_rtp_set_peer(p->vrtp, &vsin); 07382 if (debug) 07383 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 07384 } 07385 07386 /* Setup text port number */ 07387 if (p->trtp && tsin.sin_port) { 07388 ast_rtp_set_peer(p->trtp, &tsin); 07389 if (debug) 07390 ast_verbose("Peer text RTP is at port %s:%d\n", ast_inet_ntoa(tsin.sin_addr), ntohs(tsin.sin_port)); 07391 } 07392 07393 /* Ok, we're going with this offer */ 07394 ast_debug(2, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 07395 07396 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 07397 return 0; 07398 07399 ast_debug(4, "We have an owner, now see if we need to change this call\n"); 07400 07401 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 07402 if (debug) { 07403 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 07404 ast_debug(1, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 07405 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 07406 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 07407 } 07408 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability) | (p->capability & tpeercapability); 07409 ast_set_read_format(p->owner, p->owner->readformat); 07410 ast_set_write_format(p->owner, p->owner->writeformat); 07411 } 07412 07413 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 07414 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 07415 /* Activate a re-invite */ 07416 ast_queue_frame(p->owner, &ast_null_frame); 07417 /* Queue Manager Unhold event */ 07418 append_history(p, "Unhold", "%s", req->data); 07419 if (global_callevents) 07420 manager_event(EVENT_FLAG_CALL, "Hold", 07421 "Status: Off\r\n" 07422 "Channel: %s\r\n" 07423 "Uniqueid: %s\r\n", 07424 p->owner->name, 07425 p->owner->uniqueid); 07426 if (global_notifyhold) 07427 sip_peer_hold(p, FALSE); 07428 ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 07429 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 07430 int already_on_hold = ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); 07431 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 07432 S_OR(p->mohsuggest, NULL), 07433 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 07434 if (sendonly) 07435 ast_rtp_stop(p->rtp); 07436 /* RTCP needs to go ahead, even if we're on hold!!! */ 07437 /* Activate a re-invite */ 07438 ast_queue_frame(p->owner, &ast_null_frame); 07439 /* Queue Manager Hold event */ 07440 append_history(p, "Hold", "%s", req->data); 07441 if (global_callevents && !ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 07442 manager_event(EVENT_FLAG_CALL, "Hold", 07443 "Status: On\r\n" 07444 "Channel: %s\r\n" 07445 "Uniqueid: %s\r\n", 07446 p->owner->name, 07447 p->owner->uniqueid); 07448 } 07449 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 07450 ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 07451 else if (sendonly == 2) /* Inactive stream */ 07452 ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 07453 else 07454 ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 07455 if (global_notifyhold && !already_on_hold) 07456 sip_peer_hold(p, TRUE); 07457 } 07458 07459 return 0; 07460 }
static struct sip_proxy* proxy_allocate | ( | char * | name, | |
char * | port, | |||
int | force | |||
) | [static] |
Allocate and initialize sip proxy.
Definition at line 2405 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_strlen_zero(), proxy_update(), and STANDARD_SIP_PORT.
Referenced by build_peer().
02406 { 02407 struct sip_proxy *proxy; 02408 02409 if (ast_strlen_zero(name)) { 02410 return NULL; 02411 } 02412 02413 proxy = ast_calloc(1, sizeof(*proxy)); 02414 if (!proxy) 02415 return NULL; 02416 proxy->force = force; 02417 ast_copy_string(proxy->name, name, sizeof(proxy->name)); 02418 proxy->ip.sin_port = htons((!ast_strlen_zero(port) ? atoi(port) : STANDARD_SIP_PORT)); 02419 proxy_update(proxy); 02420 return proxy; 02421 }
static int proxy_update | ( | struct sip_proxy * | proxy | ) | [static] |
Resolve DNS srv name or host name in a sip_proxy structure
Definition at line 2388 of file chan_sip.c.
References ast_get_ip_or_srv(), ast_log(), FALSE, inet_aton(), sip_proxy::ip, sip_proxy::last_dnsupdate, LOG_WARNING, sip_proxy::name, and TRUE.
Referenced by proxy_allocate().
02389 { 02390 /* if it's actually an IP address and not a name, 02391 there's no need for a managed lookup */ 02392 if (!inet_aton(proxy->name, &proxy->ip.sin_addr)) { 02393 /* Ok, not an IP address, then let's check if it's a domain or host */ 02394 /* XXX Todo - if we have proxy port, don't do SRV */ 02395 if (ast_get_ip_or_srv(&proxy->ip, proxy->name, global_srvlookup ? "_sip._udp" : NULL) < 0) { 02396 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name); 02397 return FALSE; 02398 } 02399 } 02400 proxy->last_dnsupdate = time(NULL); 02401 return TRUE; 02402 }
static int queue_request | ( | struct sip_pvt * | p, | |
const struct sip_request * | req | |||
) | [static] |
Definition at line 19240 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, ast_sched_add(), copy_request(), sip_request::next, sip_pvt::request_queue, sip_pvt::request_queue_sched_id, sched, and scheduler_process_request_queue().
Referenced by handle_request_do().
19241 { 19242 struct sip_request *newreq; 19243 19244 if (!(newreq = ast_calloc(1, sizeof(*newreq)))) { 19245 return -1; 19246 } 19247 19248 copy_request(newreq, req); 19249 AST_LIST_INSERT_TAIL(&p->request_queue, newreq, next); 19250 if (p->request_queue_sched_id == -1) { 19251 p->request_queue_sched_id = ast_sched_add(sched, 10, scheduler_process_request_queue, p); 19252 } 19253 19254 return 0; 19255 }
static struct sip_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
int | devstate_only | |||
) | [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.
Definition at line 3731 of file chan_sip.c.
References ahp, ast_check_realtime(), ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ipaddr, ast_variable::name, ast_variable::next, ast_variable::value, and var.
03732 { 03733 struct sip_peer *peer; 03734 struct ast_variable *var = NULL; 03735 struct ast_variable *varregs = NULL; 03736 struct ast_variable *tmp; 03737 struct ast_config *peerlist = NULL; 03738 char ipaddr[INET_ADDRSTRLEN]; 03739 char portstring[6]; /*up to 5 digits plus null terminator*/ 03740 char *cat = NULL; 03741 unsigned short portnum; 03742 int realtimeregs = ast_check_realtime("sipregs"); 03743 03744 /* First check on peer name */ 03745 if (newpeername) { 03746 if (realtimeregs) 03747 varregs = ast_load_realtime("sipregs", "name", newpeername, NULL); 03748 03749 var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL); 03750 if (!var && sin) 03751 var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 03752 if (!var) { 03753 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 03754 /*!\note 03755 * If this one loaded something, then we need to ensure that the host 03756 * field matched. The only reason why we can't have this as a criteria 03757 * is because we only have the IP address and the host field might be 03758 * set as a name (and the reverse PTR might not match). 03759 */ 03760 if (var && sin) { 03761 for (tmp = var; tmp; tmp = tmp->next) { 03762 if (!strcasecmp(tmp->name, "host")) { 03763 struct hostent *hp; 03764 struct ast_hostent ahp; 03765 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 03766 /* No match */ 03767 ast_variables_destroy(var); 03768 var = NULL; 03769 } 03770 break; 03771 } 03772 } 03773 } 03774 } 03775 } 03776 03777 if (!var && sin) { /* Then check on IP address for dynamic peers */ 03778 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 03779 portnum = ntohs(sin->sin_port); 03780 sprintf(portstring, "%u", portnum); 03781 var = ast_load_realtime("sippeers", "host", ipaddr, "port", portstring, NULL); /* First check for fixed IP hosts */ 03782 if (var) { 03783 if (realtimeregs) { 03784 newpeername = get_name_from_variable(var, newpeername); 03785 varregs = ast_load_realtime("sipregs", "name", newpeername, NULL); 03786 } 03787 } else { 03788 if (realtimeregs) 03789 varregs = ast_load_realtime("sipregs", "ipaddr", ipaddr, "port", portstring, NULL); /* Then check for registered hosts */ 03790 else 03791 var = ast_load_realtime("sippeers", "ipaddr", ipaddr, "port", portstring, NULL); /* Then check for registered hosts */ 03792 if (varregs) { 03793 newpeername = get_name_from_variable(varregs, newpeername); 03794 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 03795 } 03796 } 03797 if (!var) { /*We couldn't match on ipaddress and port, so we need to check if port is insecure*/ 03798 peerlist = ast_load_realtime_multientry("sippeers", "host", ipaddr, NULL); 03799 if (peerlist) { 03800 var = get_insecure_variable_from_config(peerlist); 03801 if(var) { 03802 if (realtimeregs) { 03803 newpeername = get_name_from_variable(var, newpeername); 03804 varregs = ast_load_realtime("sipregs", "name", newpeername, NULL); 03805 } 03806 } else { /*var wasn't found in the list of "hosts", so try "ipaddr"*/ 03807 peerlist = NULL; 03808 cat = NULL; 03809 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", ipaddr, NULL); 03810 if(peerlist) { 03811 var = get_insecure_variable_from_config(peerlist); 03812 if(var) { 03813 if (realtimeregs) { 03814 newpeername = get_name_from_variable(var, newpeername); 03815 varregs = ast_load_realtime("sipregs", "name", newpeername, NULL); 03816 } 03817 } 03818 } 03819 } 03820 } else { 03821 if (realtimeregs) { 03822 peerlist = ast_load_realtime_multientry("sipregs", "ipaddr", ipaddr, NULL); 03823 if (peerlist) { 03824 varregs = get_insecure_variable_from_config(peerlist); 03825 if (varregs) { 03826 newpeername = get_name_from_variable(varregs, newpeername); 03827 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 03828 } 03829 } 03830 } else { 03831 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", ipaddr, NULL); 03832 if (peerlist) { 03833 var = get_insecure_variable_from_config(peerlist); 03834 if (var) { 03835 newpeername = get_name_from_variable(var, newpeername); 03836 varregs = ast_load_realtime("sipregs", "name", newpeername, NULL); 03837 } 03838 } 03839 } 03840 } 03841 } 03842 } 03843 03844 if (!var) { 03845 if (peerlist) 03846 ast_config_destroy(peerlist); 03847 return NULL; 03848 } 03849 03850 for (tmp = var; tmp; tmp = tmp->next) { 03851 /* If this is type=user, then skip this object. */ 03852 if (!strcasecmp(tmp->name, "type") && 03853 !strcasecmp(tmp->value, "user")) { 03854 if(peerlist) 03855 ast_config_destroy(peerlist); 03856 else { 03857 ast_variables_destroy(var); 03858 ast_variables_destroy(varregs); 03859 } 03860 return NULL; 03861 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 03862 newpeername = tmp->value; 03863 } 03864 } 03865 03866 if (!newpeername) { /* Did not find peer in realtime */ 03867 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", ipaddr); 03868 if(peerlist) 03869 ast_config_destroy(peerlist); 03870 else 03871 ast_variables_destroy(var); 03872 return NULL; 03873 } 03874 03875 03876 /* Peer found in realtime, now build it in memory */ 03877 peer = build_peer(newpeername, var, varregs, 1); 03878 if (!peer) { 03879 if(peerlist) 03880 ast_config_destroy(peerlist); 03881 else { 03882 ast_variables_destroy(var); 03883 ast_variables_destroy(varregs); 03884 } 03885 return NULL; 03886 } 03887 03888 ast_debug(3, "-REALTIME- loading peer from database to memory. Name: %s. Peer objects: %d\n", peer->name, rpeerobjs); 03889 03890 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) { 03891 /* Cache peer */ 03892 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 03893 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 03894 AST_SCHED_REPLACE(peer->expire, sched, global_rtautoclear * 1000, expire_register, (void *) peer); 03895 } 03896 ASTOBJ_CONTAINER_LINK(&peerl, peer); 03897 } 03898 peer->is_realtime = 1; 03899 if (peerlist) 03900 ast_config_destroy(peerlist); 03901 else { 03902 ast_variables_destroy(var); 03903 ast_variables_destroy(varregs); 03904 } 03905 03906 return peer; 03907 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
const char * | username, | |||
const char * | fullcontact, | |||
int | expirey, | |||
int | 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 3538 of file chan_sip.c.
References ast_check_realtime(), ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_inet_ntoa(), ast_strlen_zero(), ast_update_realtime(), ipaddr, sip_settings::rtsave_sysname, and sip_cfg.
03539 { 03540 char port[10]; 03541 char ipaddr[INET_ADDRSTRLEN]; 03542 char regseconds[20]; 03543 char *tablename = NULL; 03544 char str_lastms[20]; 03545 03546 const char *sysname = ast_config_AST_SYSTEM_NAME; 03547 char *syslabel = NULL; 03548 03549 time_t nowtime = time(NULL) + expirey; 03550 const char *fc = fullcontact ? "fullcontact" : NULL; 03551 03552 int realtimeregs = ast_check_realtime("sipregs"); 03553 03554 tablename = realtimeregs ? "sipregs" : "sippeers"; 03555 03556 03557 snprintf(str_lastms, sizeof(str_lastms), "%d", lastms); 03558 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 03559 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 03560 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 03561 03562 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 03563 sysname = NULL; 03564 else if (sip_cfg.rtsave_sysname) 03565 syslabel = "regserver"; 03566 03567 if (fc) 03568 ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr, 03569 "port", port, "regseconds", regseconds, 03570 deprecated_username ? "username" : "defaultuser", defaultuser, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 03571 else 03572 ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr, 03573 "port", port, "regseconds", regseconds, 03574 deprecated_username ? "username" : "defaultuser", defaultuser, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 03575 /* We cannot do this in the same statement as above, because the lack of 03576 * this field could cause the whole statement to fail. */ 03577 ast_update_realtime(tablename, "name", peername, "lastms", str_lastms, NULL); 03578 }
static struct sip_user * realtime_user | ( | const char * | username | ) | [static] |
Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped).
Definition at line 3960 of file chan_sip.c.
References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
03961 { 03962 struct ast_variable *var; 03963 struct ast_variable *tmp; 03964 struct sip_user *user = NULL; 03965 03966 var = ast_load_realtime("sipusers", "name", username, NULL); 03967 03968 if (!var) 03969 return NULL; 03970 03971 for (tmp = var; tmp; tmp = tmp->next) { 03972 if (!strcasecmp(tmp->name, "type") && 03973 !strcasecmp(tmp->value, "peer")) { 03974 ast_variables_destroy(var); 03975 return NULL; 03976 } 03977 } 03978 03979 user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 03980 03981 if (!user) { /* No user found */ 03982 ast_variables_destroy(var); 03983 return NULL; 03984 } 03985 03986 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 03987 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 03988 suserobjs++; 03989 ASTOBJ_CONTAINER_LINK(&userl, user); 03990 } else { 03991 /* Move counter from s to r... */ 03992 suserobjs--; 03993 ruserobjs++; 03994 user->is_realtime = 1; 03995 } 03996 ast_variables_destroy(var); 03997 return user; 03998 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 12351 of file chan_sip.c.
References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose(), buf, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, f, get_header(), get_msg_text(), LOG_WARNING, sip_pvt::owner, sip_debug_test_pvt(), sip_scheddestroy(), and transmit_response().
Referenced by handle_request_message().
12352 { 12353 char buf[1024]; 12354 struct ast_frame f; 12355 const char *content_type = get_header(req, "Content-Type"); 12356 12357 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 12358 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 12359 if (!p->owner) 12360 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12361 return; 12362 } 12363 12364 if (get_msg_text(buf, sizeof(buf), req)) { 12365 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 12366 transmit_response(p, "202 Accepted", req); 12367 if (!p->owner) 12368 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12369 return; 12370 } 12371 12372 if (p->owner) { 12373 if (sip_debug_test_pvt(p)) 12374 ast_verbose("Message received: '%s'\n", buf); 12375 memset(&f, 0, sizeof(f)); 12376 f.frametype = AST_FRAME_TEXT; 12377 f.subclass = 0; 12378 f.offset = 0; 12379 f.data = buf; 12380 f.datalen = strlen(buf); 12381 ast_queue_frame(p->owner, &f); 12382 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 12383 } else { /* Message outside of a call, we do not support that */ 12384 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); 12385 transmit_response(p, "405 Method Not Allowed", req); 12386 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12387 } 12388 return; 12389 }
static const char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 2359 of file chan_sip.c.
References map_x_s(), and referstatusstrings.
Referenced by show_channels_cb().
02360 { 02361 return map_x_s(referstatusstrings, rstatus, ""); 02362 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 10187 of file chan_sip.c.
References sip_peer::addr, ast_copy_string(), ast_db_get(), ast_debug, ast_inet_ntoa(), ast_random(), AST_SCHED_REPLACE, sip_peer::expire, expire_register(), sip_peer::fullcontact, inet_aton(), sip_peer::name, sip_peer::pokeexpire, register_peer_exten(), sip_peer::rt_fromcontact, sched, sip_poke_peer(), sip_poke_peer_s(), sipsock, strsep(), TRUE, and sip_peer::username.
10188 { 10189 char data[256]; 10190 struct in_addr in; 10191 int expiry; 10192 int port; 10193 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 10194 10195 if (peer->rt_fromcontact) 10196 return; 10197 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 10198 return; 10199 10200 scan = data; 10201 addr = strsep(&scan, ":"); 10202 port_str = strsep(&scan, ":"); 10203 expiry_str = strsep(&scan, ":"); 10204 username = strsep(&scan, ":"); 10205 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 10206 10207 if (!inet_aton(addr, &in)) 10208 return; 10209 10210 if (port_str) 10211 port = atoi(port_str); 10212 else 10213 return; 10214 10215 if (expiry_str) 10216 expiry = atoi(expiry_str); 10217 else 10218 return; 10219 10220 if (username) 10221 ast_copy_string(peer->username, username, sizeof(peer->username)); 10222 if (contact) 10223 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 10224 10225 ast_debug(2, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 10226 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 10227 10228 memset(&peer->addr, 0, sizeof(peer->addr)); 10229 peer->addr.sin_family = AF_INET; 10230 peer->addr.sin_addr = in; 10231 peer->addr.sin_port = htons(port); 10232 if (sipsock < 0) { 10233 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 10234 AST_SCHED_REPLACE(peer->pokeexpire, sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer); 10235 } else 10236 sip_poke_peer(peer); 10237 AST_SCHED_REPLACE(peer->expire, sched, (expiry + 10) * 1000, expire_register, peer); 10238 register_peer_exten(peer, TRUE); 10239 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 3581 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(), E_MATCH, ext, LOG_WARNING, sip_peer::name, pbx_find_extension(), sip_peer::regexten, S_OR, pbx_find_info::stacklen, and strsep().
03582 { 03583 char multi[256]; 03584 char *stringp, *ext, *context; 03585 struct pbx_find_info q = { .stacklen = 0 }; 03586 03587 /* XXX note that global_regcontext is both a global 'enable' flag and 03588 * the name of the global regexten context, if not specified 03589 * individually. 03590 */ 03591 if (ast_strlen_zero(global_regcontext)) 03592 return; 03593 03594 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 03595 stringp = multi; 03596 while ((ext = strsep(&stringp, "&"))) { 03597 if ((context = strchr(ext, '@'))) { 03598 *context++ = '\0'; /* split ext@context */ 03599 if (!ast_context_find(context)) { 03600 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 03601 continue; 03602 } 03603 } else { 03604 context = global_regcontext; 03605 } 03606 if (onoff) { 03607 if (!ast_exists_extension(NULL, context, ext, 1, NULL)) { 03608 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 03609 ast_strdup(peer->name), ast_free_ptr, "SIP"); 03610 } 03611 } else if (pbx_find_extension(NULL, NULL, &q, context, ext, 1, NULL, "", E_MATCH)) { 03612 ast_context_remove_extension(context, ext, 1, NULL); 03613 } 03614 } 03615 }
static enum check_auth_result register_verify | ( | struct sip_pvt * | p, | |
struct sockaddr_in * | sin, | |||
struct sip_request * | req, | |||
char * | uri | |||
) | [static] |
Verify registration of user
Definition at line 10999 of file chan_sip.c.
References ast_apply_ha(), ast_copy_flags, ast_copy_string(), ast_device_state_changed(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_rtp_codec_setpref(), ast_set_flag, ast_string_field_set, ast_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, AUTH_ACL_FAILED, AUTH_BAD_TRANSPORT, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_peer::autoframing, sip_pvt::autoframing, build_contact(), check_auth(), check_request_transport, check_sip_domain(), EVENT_FLAG_SYSTEM, exten, find_peer(), sip_peer::flags, sip_pvt::flags, get_header(), get_in_brackets(), sip_peer::ha, sip_peer::host_dynamic, sip_request::ignore, sip_pvt::initreq, sip_peer::lastmsgssent, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, sip_peer::md5secret, sip_peer::name, name, parse_register_contact(), PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, peerl, sip_peer::prefs, remove_uri_parameters(), sip_pvt::rtp, sip_peer::secret, sip_cancel_destroy(), SIP_NAT, SIP_PAGE2_REGISTERTRYING, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_PENDINGBYE, SIP_REGISTER, temp_peer(), terminate_uri(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), unref_peer(), update_peer(), and XMIT_UNRELIABLE.
11001 { 11002 enum check_auth_result res = AUTH_NOT_FOUND; 11003 struct sip_peer *peer; 11004 char tmp[256]; 11005 char *name, *c; 11006 char *domain; 11007 11008 terminate_uri(uri); /* warning, overwrite the string */ 11009 11010 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 11011 if (pedanticsipchecking) 11012 ast_uri_decode(tmp); 11013 11014 c = get_in_brackets(tmp); 11015 c = remove_uri_parameters(c); 11016 11017 if (!strncasecmp(c, "sip:", 4)) { 11018 name = c + 4; 11019 } else if (!strncasecmp(c, "sips:", 5)) { 11020 name = c + 5; 11021 } else { 11022 name = c; 11023 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 11024 } 11025 11026 /* XXX here too we interpret a missing @domain as a name-only 11027 * URI, whereas the RFC says this is a domain-only uri. 11028 */ 11029 /* Strip off the domain name */ 11030 if ((c = strchr(name, '@'))) { 11031 *c++ = '\0'; 11032 domain = c; 11033 if ((c = strchr(domain, ':'))) /* Remove :port */ 11034 *c = '\0'; 11035 if (!AST_LIST_EMPTY(&domain_list)) { 11036 if (!check_sip_domain(domain, NULL, 0)) { 11037 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 11038 return AUTH_UNKNOWN_DOMAIN; 11039 } 11040 } 11041 } 11042 c = strchr(name, ';'); /* Remove any Username parameters */ 11043 if (c) 11044 *c = '\0'; 11045 11046 ast_string_field_set(p, exten, name); 11047 build_contact(p); 11048 peer = find_peer(name, NULL, 1, 0); 11049 if (!(peer && ast_apply_ha(peer->ha, sin))) { 11050 /* Peer fails ACL check */ 11051 if (peer) { 11052 unref_peer(peer); 11053 peer = NULL; 11054 res = AUTH_ACL_FAILED; 11055 } else 11056 res = AUTH_NOT_FOUND; 11057 } 11058 11059 if (peer) { 11060 /* Set Frame packetization */ 11061 if (p->rtp) { 11062 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 11063 p->autoframing = peer->autoframing; 11064 } 11065 if (!peer->host_dynamic) { 11066 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 11067 res = AUTH_PEER_NOT_DYNAMIC; 11068 } else { 11069 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 11070 if (ast_test_flag(&p->flags[1], SIP_PAGE2_REGISTERTRYING)) 11071 transmit_response(p, "100 Trying", req); 11072 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, req->ignore))) { 11073 if (sip_cancel_destroy(p)) 11074 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 11075 11076 /* We have a successful registration attempt with proper authentication, 11077 now, update the peer */ 11078 switch (parse_register_contact(p, peer, req)) { 11079 case PARSE_REGISTER_FAILED: 11080 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 11081 transmit_response_with_date(p, "400 Bad Request", req); 11082 peer->lastmsgssent = -1; 11083 res = 0; 11084 break; 11085 case PARSE_REGISTER_QUERY: 11086 transmit_response_with_date(p, "200 OK", req); 11087 peer->lastmsgssent = -1; 11088 res = 0; 11089 break; 11090 case PARSE_REGISTER_UPDATE: 11091 update_peer(peer, p->expiry); 11092 /* Say OK and ask subsystem to retransmit msg counter */ 11093 transmit_response_with_date(p, "200 OK", req); 11094 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 11095 peer->lastmsgssent = -1; 11096 res = 0; 11097 break; 11098 } 11099 11100 if (check_request_transport(peer, req)) { 11101 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 11102 transmit_response_with_date(p, "403 Forbidden", req); 11103 res = AUTH_BAD_TRANSPORT; 11104 } 11105 } 11106 } 11107 } 11108 if (!peer && autocreatepeer) { 11109 /* Create peer if we have autocreate mode enabled */ 11110 peer = temp_peer(name); 11111 if (peer) { 11112 ASTOBJ_CONTAINER_LINK(&peerl, peer); 11113 if (sip_cancel_destroy(p)) 11114 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 11115 switch (parse_register_contact(p, peer, req)) { 11116 case PARSE_REGISTER_FAILED: 11117 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 11118 transmit_response_with_date(p, "400 Bad Request", req); 11119 peer->lastmsgssent = -1; 11120 res = 0; 11121 break; 11122 case PARSE_REGISTER_QUERY: 11123 transmit_response_with_date(p, "200 OK", req); 11124 peer->lastmsgssent = -1; 11125 res = 0; 11126 break; 11127 case PARSE_REGISTER_UPDATE: 11128 /* Say OK and ask subsystem to retransmit msg counter */ 11129 transmit_response_with_date(p, "200 OK", req); 11130 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 11131 peer->lastmsgssent = -1; 11132 res = 0; 11133 break; 11134 } 11135 } 11136 } 11137 if (!peer && global_alwaysauthreject) { 11138 /* If we found a peer, we transmit a 100 Trying. Therefore, if we're 11139 * trying to avoid leaking information, we MUST also transmit the same 11140 * response when we DON'T find a peer. */ 11141 transmit_response(p, "100 Trying", req); 11142 /* Insert a fake delay between the 100 and the subsequent failure. */ 11143 sched_yield(); 11144 } 11145 if (!res) { 11146 ast_device_state_changed("SIP/%s", peer->name); 11147 } 11148 if (res < 0) { 11149 switch (res) { 11150 case AUTH_SECRET_FAILED: 11151 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 11152 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 11153 break; 11154 case AUTH_USERNAME_MISMATCH: 11155 /* Username and digest username does not match. 11156 Asterisk uses the From: username for authentication. We need the 11157 users to use the same authentication user name until we support 11158 proper authentication by digest auth name */ 11159 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 11160 break; 11161 case AUTH_NOT_FOUND: 11162 case AUTH_PEER_NOT_DYNAMIC: 11163 case AUTH_ACL_FAILED: 11164 if (global_alwaysauthreject) { 11165 transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE); 11166 } else { 11167 /* URI not found */ 11168 if (res == AUTH_PEER_NOT_DYNAMIC) 11169 transmit_response(p, "403 Forbidden", &p->initreq); 11170 else 11171 transmit_response(p, "404 Not found", &p->initreq); 11172 } 11173 break; 11174 case AUTH_BAD_TRANSPORT: 11175 default: 11176 break; 11177 } 11178 } 11179 if (peer) 11180 unref_peer(peer); 11181 11182 return res; 11183 }
static struct sip_registry* registry_addref | ( | struct sip_registry * | reg | ) | [static] |
Add object reference to SIP registry.
Definition at line 2341 of file chan_sip.c.
References ast_debug, ASTOBJ_REF, sip_registry::hostname, and sip_registry::refcount.
Referenced by sip_reg_timeout(), sip_reregister(), and transmit_register().
02342 { 02343 ast_debug(3, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount + 1); 02344 return ASTOBJ_REF(reg); /* Add pointer to registry in packet */ 02345 }
static void* registry_unref | ( | struct sip_registry * | reg | ) | [static] |
Definition at line 2333 of file chan_sip.c.
References ast_debug, ASTOBJ_UNREF, sip_registry::hostname, sip_registry::refcount, and sip_registry_destroy().
Referenced by __sip_destroy(), handle_response_register(), sip_reg_timeout(), sip_register(), and sip_reregister().
02334 { 02335 ast_debug(3, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount - 1); 02336 ASTOBJ_UNREF(reg, sip_registry_destroy); 02337 return NULL; 02338 }
static const char * regstate2str | ( | enum sipregistrystate | regstate | ) | const [static] |
Convert registration state status to string.
Definition at line 9624 of file chan_sip.c.
References map_x_s(), and regstatestrings.
09625 { 09626 return map_x_s(regstatestrings, regstate, "Unknown"); 09627 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 22819 of file chan_sip.c.
References sip_reload().
22820 { 22821 if (sip_reload(0, 0, NULL)) 22822 return 0; 22823 return 1; 22824 }
static int reload_config | ( | enum channelreloadreason | reason | ) | [static] |
Re-read SIP.conf config file.
< Type of address: IPv4
< Don't force proxy usage, use route: headers
< Match call limit on peers only
< Keep track of hold status for a peer
< Match auth username if available instead of From: Default off.
< Default DTMF setting: RFC2833
< NAT support if requested by device with rport
< Allow re-invites
Definition at line 21565 of file chan_sip.c.
References ast_clear_flag, ast_config_load, ast_debug, ast_free_ha(), ast_log(), AST_MAX_CONTEXT, ASTOBJ_CONTAINER_DESTROYALL, ASTOBJ_CONTAINER_MARKALL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, authl, bindaddr, CHANNEL_MODULE_LOAD, clear_realm_authentication(), clear_sip_domains(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEUNCHANGED, default_tls_cfg, dummy(), ast_tls_config::enabled, FALSE, global_contact_ha, LOG_NOTICE, peerl, regl, server_args::sin, sip_destroy(), sip_destroy_user(), sip_registry_destroy(), sip_tcp_desc, sip_tls_desc, STANDARD_SIP_PORT, STANDARD_TLS_PORT, user, and userl.
21566 { 21567 struct ast_config *cfg, *ucfg; 21568 struct ast_variable *v; 21569 struct sip_peer *peer; 21570 struct sip_user *user; 21571 char *cat, *stringp, *context, *oldregcontext; 21572 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 21573 struct ast_flags dummy[2]; 21574 struct ast_flags config_flags = { reason == CHANNEL_MODULE_LOAD ? 0 : CONFIG_FLAG_FILEUNCHANGED }; 21575 int auto_sip_domains = FALSE; 21576 struct sockaddr_in old_bindaddr = bindaddr; 21577 int registry_count = 0, peer_count = 0, user_count = 0; 21578 21579 cfg = ast_config_load(config, config_flags); 21580 21581 /* We *must* have a config file otherwise stop immediately */ 21582 if (!cfg) { 21583 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 21584 return -1; 21585 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 21586 ucfg = ast_config_load("users.conf", config_flags); 21587 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) 21588 return 1; 21589 /* Must reread both files, because one changed */ 21590 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 21591 cfg = ast_config_load(config, config_flags); 21592 } else { 21593 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 21594 ucfg = ast_config_load("users.conf", config_flags); 21595 } 21596 21597 /* Initialize tcp sockets */ 21598 memset(&sip_tcp_desc.sin, 0, sizeof(sip_tcp_desc.sin)); 21599 memset(&sip_tls_desc.sin, 0, sizeof(sip_tls_desc.sin)); 21600 21601 ast_free_ha(global_contact_ha); 21602 global_contact_ha = NULL; 21603 21604 default_tls_cfg.enabled = FALSE; /* Default: Disable TLS */ 21605 21606 sip_tcp_desc.sin.sin_port = htons(STANDARD_SIP_PORT); 21607 sip_tls_desc.sin.sin_port = htons(STANDARD_TLS_PORT); 21608 21609 if (reason != CHANNEL_MODULE_LOAD) { 21610 ast_debug(4, "--------------- SIP reload started\n"); 21611 21612 clear_realm_authentication(authl); 21613 clear_sip_domains(); 21614 authl = NULL; 21615 21616 /* First, destroy all outstanding registry calls */ 21617 /* This is needed, since otherwise active registry entries will not be destroyed */ 21618 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 21619 ASTOBJ_RDLOCK(iterator); 21620 if (iterator->call) { 21621 ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 21622 /* This will also remove references to the registry */ 21623 iterator->call = sip_destroy(iterator->call); 21624 } 21625 ASTOBJ_UNLOCK(iterator); 21626 21627 } while(0)); 21628 21629 /* Then, actually destroy users and registry */ 21630 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 21631 ast_debug(4, "--------------- Done destroying user list\n"); 21632 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 21633 ast_debug(4, "--------------- Done destroying registry list\n"); 21634 ASTOBJ_CONTAINER_MARKALL(&peerl); 21635 } 21636 21637 /* Reset certificate handling for TLS sessions */ 21638 default_tls_cfg.certfile = ast_strdup(AST_CERTFILE); /*XXX Not sure if this is useful */ 21639 default_tls_cfg.cipher = ast_strdup(""); 21640 default_tls_cfg.cafile = ast_strdup(""); 21641 default_tls_cfg.capath = ast_strdup(""); 21642 21643 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 21644 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 21645 oldregcontext = oldcontexts; 21646 21647 /* Clear all flags before setting default values */ 21648 /* Preserve debugging settings for console */ 21649 sipdebug &= sip_debug_console; 21650 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 21651 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 21652 21653 /* Reset IP addresses */ 21654 memset(&bindaddr, 0, sizeof(bindaddr)); 21655 memset(&stunaddr, 0, sizeof(stunaddr)); 21656 memset(&internip, 0, sizeof(internip)); 21657 21658 /* Free memory for local network address mask */ 21659 ast_free_ha(localaddr); 21660 memset(&localaddr, 0, sizeof(localaddr)); 21661 memset(&externip, 0, sizeof(externip)); 21662 memset(&default_prefs, 0 , sizeof(default_prefs)); 21663 memset(&global_outboundproxy, 0, sizeof(struct sip_proxy)); 21664 global_outboundproxy.ip.sin_port = htons(STANDARD_SIP_PORT); 21665 global_outboundproxy.ip.sin_family = AF_INET; /*!< Type of address: IPv4 */ 21666 global_outboundproxy.force = FALSE; /*!< Don't force proxy usage, use route: headers */ 21667 ourport_tcp = STANDARD_SIP_PORT; 21668 ourport_tls = STANDARD_TLS_PORT; 21669 bindaddr.sin_port = htons(STANDARD_SIP_PORT); 21670 global_srvlookup = DEFAULT_SRVLOOKUP; 21671 global_tos_sip = DEFAULT_TOS_SIP; 21672 global_tos_audio = DEFAULT_TOS_AUDIO; 21673 global_tos_video = DEFAULT_TOS_VIDEO; 21674 global_tos_text = DEFAULT_TOS_TEXT; 21675 global_cos_sip = DEFAULT_COS_SIP; 21676 global_cos_audio = DEFAULT_COS_AUDIO; 21677 global_cos_video = DEFAULT_COS_VIDEO; 21678 global_cos_text = DEFAULT_COS_TEXT; 21679 21680 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 21681 externexpire = 0; /* Expiration for DNS re-issuing */ 21682 externrefresh = 10; 21683 21684 /* Reset channel settings to default before re-configuring */ 21685 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 21686 global_regcontext[0] = '\0'; 21687 global_regextenonqualify = DEFAULT_REGEXTENONQUALIFY; 21688 global_notifyringing = DEFAULT_NOTIFYRINGING; 21689 global_limitonpeers = FALSE; /*!< Match call limit on peers only */ 21690 global_notifyhold = FALSE; /*!< Keep track of hold status for a peer */ 21691 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 21692 global_alwaysauthreject = 0; 21693 global_allowsubscribe = FALSE; 21694 snprintf(global_useragent, sizeof(global_useragent), "%s %s", DEFAULT_USERAGENT, ast_get_version()); 21695 snprintf(global_sdpsession, sizeof(global_sdpsession), "%s %s", DEFAULT_SDPSESSION, ast_get_version()); 21696 snprintf(global_sdpowner, sizeof(global_sdpowner), "%s", DEFAULT_SDPOWNER); 21697 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 21698 ast_copy_string(global_realm, S_OR(ast_config_AST_SYSTEM_NAME, DEFAULT_REALM), sizeof(global_realm)); 21699 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 21700 compactheaders = DEFAULT_COMPACTHEADERS; 21701 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 21702 global_regattempts_max = 0; 21703 pedanticsipchecking = DEFAULT_PEDANTIC; 21704 autocreatepeer = DEFAULT_AUTOCREATEPEER; 21705 global_autoframing = 0; 21706 global_allowguest = DEFAULT_ALLOWGUEST; 21707 global_callcounter = DEFAULT_CALLCOUNTER; 21708 global_match_auth_username = FALSE; /*!< Match auth username if available instead of From: Default off. */ 21709 global_rtptimeout = 0; 21710 global_rtpholdtimeout = 0; 21711 global_rtpkeepalive = 0; 21712 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 21713 global_rtautoclear = 120; 21714 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 21715 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 21716 sip_cfg.peer_rtupdate = TRUE; 21717 21718 /* Session-Timers */ 21719 global_st_mode = SESSION_TIMER_MODE_ACCEPT; 21720 global_st_refresher = SESSION_TIMER_REFRESHER_UAS; 21721 global_min_se = DEFAULT_MIN_SE; 21722 global_max_se = DEFAULT_MAX_SE; 21723 21724 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 21725 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 21726 default_subscribecontext[0] = '\0'; 21727 default_language[0] = '\0'; 21728 default_fromdomain[0] = '\0'; 21729 default_qualify = DEFAULT_QUALIFY; 21730 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 21731 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 21732 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 21733 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 21734 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 21735 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 21736 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 21737 21738 /* Debugging settings, always default to off */ 21739 dumphistory = FALSE; 21740 recordhistory = FALSE; 21741 sipdebug &= ~sip_debug_config; 21742 21743 /* Misc settings for the channel */ 21744 global_relaxdtmf = FALSE; 21745 global_callevents = FALSE; 21746 global_t1 = SIP_TIMER_T1; 21747 global_timer_b = 64 * SIP_TIMER_T1; 21748 global_t1min = DEFAULT_T1MIN; 21749 global_qualifyfreq = DEFAULT_QUALIFYFREQ; 21750 21751 global_matchexterniplocally = FALSE; 21752 21753 /* Copy the default jb config over global_jbconf */ 21754 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 21755 21756 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 21757 ast_clear_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT); 21758 ast_clear_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION); 21759 21760 /* Read the [general] config section of sip.conf (or from realtime config) */ 21761 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 21762 if (handle_common_options(&global_flags[0], &dummy[0], v)) 21763 continue; 21764 /* handle jb conf */ 21765 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 21766 continue; 21767 21768 if (!strcasecmp(v->name, "context")) { 21769 ast_copy_string(default_context, v->value, sizeof(default_context)); 21770 } else if (!strcasecmp(v->name, "subscribecontext")) { 21771 ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext)); 21772 } else if (!strcasecmp(v->name, "callcounter")) { 21773 global_callcounter = ast_true(v->value) ? 1 : 0; 21774 } else if (!strcasecmp(v->name, "allowguest")) { 21775 global_allowguest = ast_true(v->value) ? 1 : 0; 21776 } else if (!strcasecmp(v->name, "realm")) { 21777 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 21778 } else if (!strcasecmp(v->name, "useragent")) { 21779 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 21780 ast_debug(1, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 21781 } else if (!strcasecmp(v->name, "sdpsession")) { 21782 ast_copy_string(global_sdpsession, v->value, sizeof(global_sdpsession)); 21783 } else if (!strcasecmp(v->name, "sdpowner")) { 21784 /* Field cannot contain spaces */ 21785 if (!strstr(v->value, " ")) 21786 ast_copy_string(global_sdpowner, v->value, sizeof(global_sdpowner)); 21787 else 21788 ast_log(LOG_WARNING, "'%s' must not contain spaces at line %d. Using default.\n", v->value, v->lineno); 21789 } else if (!strcasecmp(v->name, "allowtransfer")) { 21790 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 21791 } else if (!strcasecmp(v->name, "rtcachefriends")) { 21792 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 21793 } else if (!strcasecmp(v->name, "rtsavesysname")) { 21794 sip_cfg.rtsave_sysname = ast_true(v->value); 21795 } else if (!strcasecmp(v->name, "rtupdate")) { 21796 sip_cfg.peer_rtupdate = ast_true(v->value); 21797 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 21798 sip_cfg.ignore_regexpire = ast_true(v->value); 21799 } else if (!strcasecmp(v->name, "timert1")) { 21800 /* Defaults to 500ms, but RFC 3261 states that it is recommended 21801 * for the value to be set higher, though a lower value is only 21802 * allowed on private networks unconnected to the Internet. */ 21803 global_t1 = atoi(v->value); 21804 /* Note that timer B is dependent on the value of T1 */ 21805 global_timer_b = global_t1 * 64; 21806 } else if (!strcasecmp(v->name, "t1min")) { 21807 global_t1min = atoi(v->value); 21808 } else if (!strcasecmp(v->name, "tcpenable")) { 21809 sip_tcp_desc.sin.sin_family = ast_false(v->value) ? 0 : AF_INET; 21810 ast_debug(2, "Enabling TCP socket for listening\n"); 21811 } else if (!strcasecmp(v->name, "tcpbindaddr")) { 21812 int family = sip_tcp_desc.sin.sin_family; 21813 if (ast_parse_arg(v->value, PARSE_INADDR, &sip_tcp_desc.sin)) 21814 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", v->name, v->value, v->lineno, config); 21815 sip_tcp_desc.sin.sin_family = family; 21816 ast_debug(2, "Setting TCP socket address to %s\n", v->value); 21817 } else if (!strcasecmp(v->name, "tlsenable")) { 21818 default_tls_cfg.enabled = ast_true(v->value) ? TRUE : FALSE; 21819 sip_tls_desc.sin.sin_family = AF_INET; 21820 } else if (!strcasecmp(v->name, "tlscertfile")) { 21821 ast_free(default_tls_cfg.certfile); 21822 default_tls_cfg.certfile = ast_strdup(v->value); 21823 } else if (!strcasecmp(v->name, "tlscipher")) { 21824 ast_free(default_tls_cfg.cipher); 21825 default_tls_cfg.cipher = ast_strdup(v->value); 21826 } else if (!strcasecmp(v->name, "tlscafile")) { 21827 ast_free(default_tls_cfg.cafile); 21828 default_tls_cfg.cafile = ast_strdup(v->value); 21829 } else if (!strcasecmp(v->name, "tlscapath")) { 21830 ast_free(default_tls_cfg.capath); 21831 default_tls_cfg.capath = ast_strdup(v->value); 21832 } else if (!strcasecmp(v->name, "tlsverifyclient")) { 21833 ast_set2_flag(&default_tls_cfg.flags, ast_true(v->value), AST_SSL_VERIFY_CLIENT); 21834 } else if (!strcasecmp(v->name, "tlsdontverifyserver")) { 21835 ast_set2_flag(&default_tls_cfg.flags, ast_true(v->value), AST_SSL_DONT_VERIFY_SERVER); 21836 } else if (!strcasecmp(v->name, "tlsbindaddr")) { 21837 if (ast_parse_arg(v->value, PARSE_INADDR, &sip_tls_desc.sin)) 21838 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", v->name, v->value, v->lineno, config); 21839 } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) { 21840 global_dynamic_exclude_static = ast_true(v->value); 21841 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 21842 int ha_error = 0; 21843 global_contact_ha = ast_append_ha(v->name + 7, v->value, global_contact_ha, &ha_error); 21844 if (ha_error) { 21845 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 21846 } 21847 } else if (!strcasecmp(v->name, "rtautoclear")) { 21848 int i = atoi(v->value); 21849 if (i > 0) 21850 global_rtautoclear = i; 21851 else 21852 i = 0; 21853 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 21854 } else if (!strcasecmp(v->name, "usereqphone")) { 21855 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 21856 } else if (!strcasecmp(v->name, "relaxdtmf")) { 21857 global_relaxdtmf = ast_true(v->value); 21858 } else if (!strcasecmp(v->name, "vmexten")) { 21859 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 21860 } else if (!strcasecmp(v->name, "rtptimeout")) { 21861 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 21862 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 21863 global_rtptimeout = 0; 21864 } 21865 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 21866 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 21867 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 21868 global_rtpholdtimeout = 0; 21869 } 21870 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 21871 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 21872 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 21873 global_rtpkeepalive = 0; 21874 } 21875 } else if (!strcasecmp(v->name, "compactheaders")) { 21876 compactheaders = ast_true(v->value); 21877 } else if (!strcasecmp(v->name, "notifymimetype")) { 21878 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 21879 } else if (!strncasecmp(v->name, "limitonpeer", 11) || !strcasecmp(v->name, "counteronpeer")) { 21880 global_limitonpeers = ast_true(v->value); 21881 } else if (!strcasecmp(v->name, "directrtpsetup")) { 21882 global_directrtpsetup = ast_true(v->value); 21883 } else if (!strcasecmp(v->name, "notifyringing")) { 21884 global_notifyringing = ast_true(v->value); 21885 } else if (!strcasecmp(v->name, "notifyhold")) { 21886 global_notifyhold = ast_true(v->value); 21887 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 21888 global_alwaysauthreject = ast_true(v->value); 21889 } else if (!strcasecmp(v->name, "mohinterpret")) { 21890 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 21891 } else if (!strcasecmp(v->name, "mohsuggest")) { 21892 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 21893 } else if (!strcasecmp(v->name, "language")) { 21894 ast_copy_string(default_language, v->value, sizeof(default_language)); 21895 } else if (!strcasecmp(v->name, "regcontext")) { 21896 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 21897 stringp = newcontexts; 21898 /* Let's remove any contexts that are no longer defined in regcontext */ 21899 cleanup_stale_contexts(stringp, oldregcontext); 21900 /* Create contexts if they don't exist already */ 21901 while ((context = strsep(&stringp, "&"))) { 21902 ast_copy_string(used_context, context, sizeof(used_context)); 21903 ast_context_find_or_create(NULL, NULL, context, "SIP"); 21904 } 21905 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 21906 } else if (!strcasecmp(v->name, "regextenonqualify")) { 21907 global_regextenonqualify = ast_true(v->value); 21908 } else if (!strcasecmp(v->name, "callerid")) { 21909 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 21910 } else if (!strcasecmp(v->name, "fromdomain")) { 21911 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 21912 } else if (!strcasecmp(v->name, "outboundproxy")) { 21913 int portnum; 21914 char *tok, *proxyname; 21915 21916 if (ast_strlen_zero(v->value)) { 21917 ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf.", v->lineno); 21918 continue; 21919 } 21920 21921 tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ",")); 21922 21923 sip_parse_host(tok, v->lineno, &proxyname, &portnum, &global_outboundproxy.transport); 21924 21925 global_outboundproxy.ip.sin_port = htons(portnum); 21926 21927 if ((tok = strtok(NULL, ","))) { 21928 global_outboundproxy.force = !strncasecmp(ast_skip_blanks(tok), "force", 5); 21929 } else { 21930 global_outboundproxy.force = FALSE; 21931 } 21932 21933 if (ast_strlen_zero(proxyname)) { 21934 ast_log(LOG_WARNING, "you must specify a name for the outboundproxy on line %d of sip.conf.", v->lineno); 21935 global_outboundproxy.name[0] = '\0'; 21936 continue; 21937 } 21938 21939 ast_copy_string(global_outboundproxy.name, proxyname, sizeof(global_outboundproxy.name)); 21940 21941 proxy_update(&global_outboundproxy); 21942 } else if (!strcasecmp(v->name, "autocreatepeer")) { 21943 autocreatepeer = ast_true(v->value); 21944 } else if (!strcasecmp(v->name, "match_auth_username")) { 21945 global_match_auth_username = ast_true(v->value); 21946 } else if (!strcasecmp(v->name, "srvlookup")) { 21947 global_srvlookup = ast_true(v->value); 21948 } else if (!strcasecmp(v->name, "pedantic")) { 21949 pedanticsipchecking = ast_true(v->value); 21950 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 21951 max_expiry = atoi(v->value); 21952 if (max_expiry < 1) 21953 max_expiry = DEFAULT_MAX_EXPIRY; 21954 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 21955 min_expiry = atoi(v->value); 21956 if (min_expiry < 1) 21957 min_expiry = DEFAULT_MIN_EXPIRY; 21958 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 21959 default_expiry = atoi(v->value); 21960 if (default_expiry < 1) 21961 default_expiry = DEFAULT_DEFAULT_EXPIRY; 21962 } else if (!strcasecmp(v->name, "sipdebug")) { 21963 if (ast_true(v->value)) 21964 sipdebug |= sip_debug_config; 21965 } else if (!strcasecmp(v->name, "dumphistory")) { 21966 dumphistory = ast_true(v->value); 21967 } else if (!strcasecmp(v->name, "recordhistory")) { 21968 recordhistory = ast_true(v->value); 21969 } else if (!strcasecmp(v->name, "registertimeout")) { 21970 global_reg_timeout = atoi(v->value); 21971 if (global_reg_timeout < 1) 21972 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 21973 } else if (!strcasecmp(v->name, "registerattempts")) { 21974 global_regattempts_max = atoi(v->value); 21975 } else if (!strcasecmp(v->name, "stunaddr")) { 21976 stunaddr.sin_port = htons(3478); 21977 if (ast_parse_arg(v->value, PARSE_INADDR, &stunaddr)) 21978 ast_log(LOG_WARNING, "Invalid STUN server address: %s\n", v->value); 21979 externexpire = time(NULL); 21980 } else if (!strcasecmp(v->name, "bindaddr")) { 21981 if (ast_parse_arg(v->value, PARSE_INADDR, &bindaddr)) 21982 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 21983 } else if (!strcasecmp(v->name, "localnet")) { 21984 struct ast_ha *na; 21985 int ha_error = 0; 21986 21987 if (!(na = ast_append_ha("d", v->value, localaddr, &ha_error))) 21988 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 21989 else 21990 localaddr = na; 21991 if (ha_error) 21992 ast_log(LOG_ERROR, "Bad localnet configuration value line %d : %s\n", v->lineno, v->value); 21993 } else if (!strcasecmp(v->name, "externip")) { 21994 if (ast_parse_arg(v->value, PARSE_INADDR, &externip)) 21995 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 21996 externexpire = 0; 21997 /* If no port was specified use the value of bindport */ 21998 if (!externip.sin_port) 21999 externip.sin_port = bindaddr.sin_port; 22000 } else if (!strcasecmp(v->name, "externhost")) { 22001 ast_copy_string(externhost, v->value, sizeof(externhost)); 22002 if (ast_parse_arg(externhost, PARSE_INADDR, &externip)) 22003 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 22004 externexpire = time(NULL); 22005 /* If no port was specified use the value of bindport */ 22006 if (!externip.sin_port) 22007 externip.sin_port = bindaddr.sin_port; 22008 } else if (!strcasecmp(v->name, "externrefresh")) { 22009 if (sscanf(v->value, "%d", &externrefresh) != 1) { 22010 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 22011 externrefresh = 10; 22012 } 22013 } else if (!strcasecmp(v->name, "allow")) { 22014 int error = ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, TRUE); 22015 if (error) 22016 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 22017 } else if (!strcasecmp(v->name, "disallow")) { 22018 int error = ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, FALSE); 22019 if (error) 22020 ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value); 22021 } else if (!strcasecmp(v->name, "autoframing")) { 22022 global_autoframing = ast_true(v->value); 22023 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 22024 allow_external_domains = ast_true(v->value); 22025 } else if (!strcasecmp(v->name, "autodomain")) { 22026 auto_sip_domains = ast_true(v->value); 22027 } else if (!strcasecmp(v->name, "domain")) { 22028 char *domain = ast_strdupa(v->value); 22029 char *context = strchr(domain, ','); 22030 22031 if (context) 22032 *context++ = '\0'; 22033 22034 if (ast_strlen_zero(context)) 22035 ast_debug(1, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 22036 if (ast_strlen_zero(domain)) 22037 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 22038 else 22039 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 22040 } else if (!strcasecmp(v->name, "register")) { 22041 if (sip_register(v->value, v->lineno) == 0) 22042 registry_count++; 22043 } else if (!strcasecmp(v->name, "tos_sip")) { 22044 if (ast_str2tos(v->value, &global_tos_sip)) 22045 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, refer to QoS documentation\n", v->lineno); 22046 } else if (!strcasecmp(v->name, "tos_audio")) { 22047 if (ast_str2tos(v->value, &global_tos_audio)) 22048 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno); 22049 } else if (!strcasecmp(v->name, "tos_video")) { 22050 if (ast_str2tos(v->value, &global_tos_video)) 22051 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, refer to QoS documentation\n", v->lineno); 22052 } else if (!strcasecmp(v->name, "tos_text")) { 22053 if (ast_str2tos(v->value, &global_tos_text)) 22054 ast_log(LOG_WARNING, "Invalid tos_text value at line %d, refer to QoS documentation\n", v->lineno); 22055 } else if (!strcasecmp(v->name, "cos_sip")) { 22056 if (ast_str2cos(v->value, &global_cos_sip)) 22057 ast_log(LOG_WARNING, "Invalid cos_sip value at line %d, refer to QoS documentation\n", v->lineno); 22058 } else if (!strcasecmp(v->name, "cos_audio")) { 22059 if (ast_str2cos(v->value, &global_cos_audio)) 22060 ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno); 22061 } else if (!strcasecmp(v->name, "cos_video")) { 22062 if (ast_str2cos(v->value, &global_cos_video)) 22063 ast_log(LOG_WARNING, "Invalid cos_video value at line %d, refer to QoS documentation\n", v->lineno); 22064 } else if (!strcasecmp(v->name, "cos_text")) { 22065 if (ast_str2cos(v->value, &global_cos_text)) 22066 ast_log(LOG_WARNING, "Invalid cos_text value at line %d, refer to QoS documentation\n", v->lineno); 22067 } else if (!strcasecmp(v->name, "bindport")) { 22068 int i; 22069 if (sscanf(v->value, "%d", &i) == 1) { 22070 bindaddr.sin_port = htons(i); 22071 } else { 22072 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 22073 } 22074 } else if (!strcasecmp(v->name, "qualify")) { 22075 if (!strcasecmp(v->value, "no")) { 22076 default_qualify = 0; 22077 } else if (!strcasecmp(v->value, "yes")) { 22078 default_qualify = DEFAULT_MAXMS; 22079 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 22080 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 22081 default_qualify = 0; 22082 } 22083 } else if (!strcasecmp(v->name, "qualifyfreq")) { 22084 int i; 22085 if (sscanf(v->value, "%d", &i) == 1) 22086 global_qualifyfreq = i * 1000; 22087 else { 22088 ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config); 22089 global_qualifyfreq = DEFAULT_QUALIFYFREQ; 22090 } 22091 } else if (!strcasecmp(v->name, "callevents")) { 22092 global_callevents = ast_true(v->value); 22093 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 22094 default_maxcallbitrate = atoi(v->value); 22095 if (default_maxcallbitrate < 0) 22096 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 22097 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 22098 global_matchexterniplocally = ast_true(v->value); 22099 } else if (!strcasecmp(v->name, "session-timers")) { 22100 int i = (int) str2stmode(v->value); 22101 if (i < 0) { 22102 ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config); 22103 global_st_mode = SESSION_TIMER_MODE_ACCEPT; 22104 } else { 22105 global_st_mode = i; 22106 } 22107 } else if (!strcasecmp(v->name, "session-expires")) { 22108 if (sscanf(v->value, "%d", &global_max_se) != 1) { 22109 ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config); 22110 global_max_se = DEFAULT_MAX_SE; 22111 } 22112 } else if (!strcasecmp(v->name, "session-minse")) { 22113 if (sscanf(v->value, "%d", &global_min_se) != 1) { 22114 ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config); 22115 global_min_se = DEFAULT_MIN_SE; 22116 } 22117 if (global_min_se < 90) { 22118 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); 22119 global_min_se = DEFAULT_MIN_SE; 22120 } 22121 } else if (!strcasecmp(v->name, "session-refresher")) { 22122 int i = (int) str2strefresher(v->value); 22123 if (i < 0) { 22124 ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config); 22125 global_st_refresher = SESSION_TIMER_REFRESHER_UAS; 22126 } else { 22127 global_st_refresher = i; 22128 } 22129 } 22130 } 22131 22132 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 22133 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 22134 allow_external_domains = 1; 22135 } 22136 22137 /* Build list of authentication to various SIP realms, i.e. service providers */ 22138 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 22139 /* Format for authentication is auth = username:password@realm */ 22140 if (!strcasecmp(v->name, "auth")) 22141 authl = add_realm_authentication(authl, v->value, v->lineno); 22142 } 22143 22144 if (ucfg) { 22145 struct ast_variable *gen; 22146 int genhassip, genregistersip; 22147 const char *hassip, *registersip; 22148 22149 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 22150 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 22151 gen = ast_variable_browse(ucfg, "general"); 22152 cat = ast_category_browse(ucfg, NULL); 22153 while (cat) { 22154 if (strcasecmp(cat, "general")) { 22155 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 22156 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 22157 if (ast_true(hassip) || (!hassip && genhassip)) { 22158 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 22159 if (user) { 22160 ASTOBJ_CONTAINER_LINK(&userl,user); 22161 ASTOBJ_UNREF(user, sip_destroy_user); 22162 user_count++; 22163 } 22164 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 22165 if (peer) { 22166 ASTOBJ_CONTAINER_LINK(&peerl, peer); 22167 unref_peer(peer); 22168 peer_count++; 22169 } 22170 } 22171 if (ast_true(registersip) || (!registersip && genregistersip)) { 22172 char tmp[256]; 22173 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 22174 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 22175 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 22176 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 22177 if (!host) 22178 host = ast_variable_retrieve(ucfg, "general", "host"); 22179 if (!username) 22180 username = ast_variable_retrieve(ucfg, "general", "username"); 22181 if (!secret) 22182 secret = ast_variable_retrieve(ucfg, "general", "secret"); 22183 if (!contact) 22184 contact = "s"; 22185 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 22186 if (!ast_strlen_zero(secret)) 22187 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 22188 else 22189 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 22190 if (sip_register(tmp, 0) == 0) 22191 registry_count++; 22192 } 22193 } 22194 } 22195 cat = ast_category_browse(ucfg, cat); 22196 } 22197 ast_config_destroy(ucfg); 22198 } 22199 22200 22201 /* Load peers, users and friends */ 22202 cat = NULL; 22203 while ( (cat = ast_category_browse(cfg, cat)) ) { 22204 const char *utype; 22205 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 22206 continue; 22207 utype = ast_variable_retrieve(cfg, cat, "type"); 22208 if (!utype) { 22209 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 22210 continue; 22211 } else { 22212 int is_user = 0, is_peer = 0; 22213 if (!strcasecmp(utype, "user")) 22214 is_user = 1; 22215 else if (!strcasecmp(utype, "friend")) 22216 is_user = is_peer = 1; 22217 else if (!strcasecmp(utype, "peer")) 22218 is_peer = 1; 22219 else { 22220 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 22221 continue; 22222 } 22223 if (is_user) { 22224 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 22225 if (user) { 22226 ASTOBJ_CONTAINER_LINK(&userl, user); 22227 unref_user(user); 22228 user_count++; 22229 } 22230 } 22231 if (is_peer) { 22232 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 22233 if (peer) { 22234 ASTOBJ_CONTAINER_LINK(&peerl, peer); 22235 unref_peer(peer); 22236 peer_count++; 22237 } 22238 } 22239 } 22240 } 22241 /* Set UDP address and open socket */ 22242 bindaddr.sin_family = AF_INET; 22243 internip = bindaddr; 22244 if (ast_find_ourip(&internip.sin_addr, bindaddr)) { 22245 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 22246 ast_config_destroy(cfg); 22247 return 0; 22248 } 22249 ast_mutex_lock(&netlock); 22250 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 22251 close(sipsock); 22252 sipsock = -1; 22253 } 22254 if (sipsock < 0) { 22255 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 22256 if (sipsock < 0) { 22257 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 22258 ast_config_destroy(cfg); 22259 return -1; 22260 } else { 22261 /* Allow SIP clients on the same host to access us: */ 22262 const int reuseFlag = 1; 22263 22264 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 22265 (const char*)&reuseFlag, 22266 sizeof reuseFlag); 22267 22268 ast_enable_packet_fragmentation(sipsock); 22269 22270 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 22271 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 22272 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 22273 strerror(errno)); 22274 close(sipsock); 22275 sipsock = -1; 22276 } else { 22277 ast_verb(2, "SIP Listening on %s:%d\n", 22278 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 22279 ast_netsock_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP"); 22280 } 22281 } 22282 } 22283 if (stunaddr.sin_addr.s_addr != 0) { 22284 ast_debug(1, "stun to %s:%d\n", 22285 ast_inet_ntoa(stunaddr.sin_addr) , ntohs(stunaddr.sin_port)); 22286 ast_stun_request(sipsock, &stunaddr, 22287 NULL, &externip); 22288 ast_debug(1, "STUN sees us at %s:%d\n", 22289 ast_inet_ntoa(externip.sin_addr) , ntohs(externip.sin_port)); 22290 } 22291 ast_mutex_unlock(&netlock); 22292 22293 /* Start TCP server */ 22294 ast_tcptls_server_start(&sip_tcp_desc); 22295 22296 /* Start TLS server if needed */ 22297 memcpy(sip_tls_desc.tls_cfg, &default_tls_cfg, sizeof(default_tls_cfg)); 22298 22299 if (ast_ssl_setup(sip_tls_desc.tls_cfg)) 22300 ast_tcptls_server_start(&sip_tls_desc); 22301 else if (sip_tls_desc.tls_cfg->enabled) { 22302 sip_tls_desc.tls_cfg = NULL; 22303 ast_log(LOG_WARNING, "SIP TLS server did not load because of errors.\n"); 22304 } 22305 22306 22307 /* Add default domains - host name, IP address and IP:port 22308 * Only do this if user added any sip domain with "localdomains" 22309 * In order to *not* break backwards compatibility 22310 * Some phones address us at IP only, some with additional port number 22311 */ 22312 if (auto_sip_domains) { 22313 char temp[MAXHOSTNAMELEN]; 22314 22315 /* First our default IP address */ 22316 if (bindaddr.sin_addr.s_addr) 22317 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 22318 else 22319 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 22320 22321 /* If TCP is running on a different IP than UDP, then add it too */ 22322 if (sip_tcp_desc.sin.sin_addr.s_addr && !inaddrcmp(&bindaddr, &sip_tcp_desc.sin)) 22323 add_sip_domain(ast_inet_ntoa(sip_tcp_desc.sin.sin_addr), SIP_DOMAIN_AUTO, NULL); 22324 22325 /* If TLS is running on a differen IP than UDP and TCP, then add that too */ 22326 if (sip_tls_desc.sin.sin_addr.s_addr && !inaddrcmp(&bindaddr, &sip_tls_desc.sin) && inaddrcmp(&sip_tcp_desc.sin, &sip_tls_desc.sin)) 22327 add_sip_domain(ast_inet_ntoa(sip_tls_desc.sin.sin_addr), SIP_DOMAIN_AUTO, NULL); 22328 22329 /* Our extern IP address, if configured */ 22330 if (externip.sin_addr.s_addr) 22331 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 22332 22333 /* Extern host name (NAT traversal support) */ 22334 if (!ast_strlen_zero(externhost)) 22335 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 22336 22337 /* Our host name */ 22338 if (!gethostname(temp, sizeof(temp))) 22339 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 22340 } 22341 22342 /* Release configuration from memory */ 22343 ast_config_destroy(cfg); 22344 22345 /* Load the list of manual NOTIFY types to support */ 22346 if (notify_types) 22347 ast_config_destroy(notify_types); 22348 notify_types = ast_config_load(notify_config, config_flags); 22349 22350 /* Done, tell the manager */ 22351 manager_event(EVENT_FLAG_SYSTEM, "ChannelReload", "ChannelType: SIP\r\nReloadReason: %s\r\nRegistry_Count: %d\r\nPeer_Count: %d\r\nUser_Count: %d\r\n", channelreloadreason2txt(reason), registry_count, peer_count, user_count); 22352 22353 return 0; 22354 }
static char * remove_uri_parameters | ( | char * | uri | ) | [static] |
Definition at line 8948 of file chan_sip.c.
Referenced by extract_uri(), parse_moved_contact(), register_verify(), reqprep(), and transmit_state_notify().
08949 { 08950 char *atsign; 08951 atsign = strchr(uri, '@'); /* First, locate the at sign */ 08952 if (!atsign) 08953 atsign = uri; /* Ok hostname only, let's stick with the rest */ 08954 atsign = strchr(atsign, ';'); /* Locate semi colon */ 08955 if (atsign) 08956 *atsign = '\0'; /* Kill at the semi colon */ 08957 return uri; 08958 }
static void replace_cid | ( | struct sip_pvt * | p, | |
const char * | rpid_num, | |||
const char * | calleridname | |||
) | [static] |
helper function for check_{user|peer}_ok()
Definition at line 11907 of file chan_sip.c.
References ast_is_shrinkable_phonenumber(), ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, sip_pvt::flags, and SIP_TRUSTRPID.
Referenced by check_peer_ok(), check_user_full(), and check_user_ok().
11908 { 11909 /* replace callerid if rpid found, and not restricted */ 11910 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 11911 char *tmp = ast_strdupa(rpid_num); /* XXX the copy can be done later */ 11912 if (!ast_strlen_zero(calleridname)) 11913 ast_string_field_set(p, cid_name, calleridname); 11914 if (ast_is_shrinkable_phonenumber(tmp)) 11915 ast_shrink_phone_number(tmp); 11916 ast_string_field_set(p, cid_num, tmp); 11917 } 11918 }
static int reply_digest | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
char * | header, | |||
int | sipmethod, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
reply to authentication for outbound registrations
Definition at line 14771 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(), sip_pvt::domain, get_header(), LOG_WARNING, sip_registry::nonce, sip_pvt::nonce, sip_registry::noncecount, sip_pvt::noncecount, sip_registry::opaque, sip_pvt::opaque, sip_registry::qop, sip_pvt::qop, sip_registry::realm, sip_pvt::realm, sip_pvt::registry, and strsep().
Referenced by do_proxy_auth(), and do_register_auth().
14772 { 14773 char tmp[512]; 14774 char *c; 14775 char oldnonce[256]; 14776 14777 /* table of recognised keywords, and places where they should be copied */ 14778 const struct x { 14779 const char *key; 14780 const ast_string_field *field; 14781 } *i, keys[] = { 14782 { "realm=", &p->realm }, 14783 { "nonce=", &p->nonce }, 14784 { "opaque=", &p->opaque }, 14785 { "qop=", &p->qop }, 14786 { "domain=", &p->domain }, 14787 { NULL, 0 }, 14788 }; 14789 14790 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 14791 if (ast_strlen_zero(tmp)) 14792 return -1; 14793 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 14794 ast_log(LOG_WARNING, "missing Digest.\n"); 14795 return -1; 14796 } 14797 c = tmp + strlen("Digest "); 14798 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 14799 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 14800 for (i = keys; i->key != NULL; i++) { 14801 char *src, *separator; 14802 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 14803 continue; 14804 /* Found. Skip keyword, take text in quotes or up to the separator. */ 14805 c += strlen(i->key); 14806 if (*c == '"') { 14807 src = ++c; 14808 separator = "\""; 14809 } else { 14810 src = c; 14811 separator = ","; 14812 } 14813 strsep(&c, separator); /* clear separator and move ptr */ 14814 ast_string_field_ptr_set(p, i->field, src); 14815 break; 14816 } 14817 if (i->key == NULL) /* not found, try ',' */ 14818 strsep(&c, ","); 14819 } 14820 /* Reset nonce count */ 14821 if (strcmp(p->nonce, oldnonce)) 14822 p->noncecount = 0; 14823 14824 /* Save auth data for following registrations */ 14825 if (p->registry) { 14826 struct sip_registry *r = p->registry; 14827 14828 if (strcmp(r->nonce, p->nonce)) { 14829 ast_string_field_set(r, realm, p->realm); 14830 ast_string_field_set(r, nonce, p->nonce); 14831 ast_string_field_set(r, domain, p->domain); 14832 ast_string_field_set(r, opaque, p->opaque); 14833 ast_string_field_set(r, qop, p->qop); 14834 r->noncecount = 0; 14835 } 14836 } 14837 return build_reply_digest(p, sipmethod, digest, digest_len); 14838 }
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 7878 of file chan_sip.c.
References add_header(), add_route(), ast_copy_string(), ast_debug, ast_random(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, sip_invite_param::auth, sip_pvt::branch, build_via(), sip_pvt::callid, copy_header(), DEFAULT_MAX_FORWARDS, FALSE, sip_pvt::flags, get_header(), get_in_brackets(), sip_route::hop, init_req(), sip_pvt::initreq, sip_pvt::invite_branch, sip_pvt::lastmsg, sip_route::next, sip_pvt::ocseq, sip_pvt::okcontacturi, sip_pvt::options, sip_pvt::our_contact, remove_uri_parameters(), sip_request::rlPart2, sip_pvt::route, sip_pvt::rpid, set_destination(), SIP_ACK, SIP_BYE, SIP_CANCEL, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_OUTGOING, sip_st_dlg::st_active, sip_st_dlg::st_active_peer_ua, st_get_se(), sip_st_dlg::st_interval, sip_st_dlg::st_ref, sip_pvt::stimer, strcasestr(), strefresher2str(), sip_pvt::tag, text, cfsip_methods::text, sip_pvt::theirtag, TRUE, sip_pvt::uri, url, sip_pvt::url, and sip_pvt::via.
07879 { 07880 struct sip_request *orig = &p->initreq; 07881 char stripped[80]; 07882 char tmp[80]; 07883 char newto[256]; 07884 const char *c; 07885 const char *ot, *of; 07886 int is_strict = FALSE; /*!< Strict routing flag */ 07887 int is_outbound = ast_test_flag(&p->flags[0], SIP_OUTGOING); /* Session direction */ 07888 07889 memset(req, 0, sizeof(struct sip_request)); 07890 07891 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 07892 07893 if (!seqno) { 07894 p->ocseq++; 07895 seqno = p->ocseq; 07896 } 07897 07898 /* A CANCEL must have the same branch as the INVITE that it is canceling. 07899 * Similarly, if we need to re-send an INVITE with auth credentials, then we 07900 * need to use the same branch as we did the first time we sent the INVITE. 07901 */ 07902 if (sipmethod == SIP_CANCEL || (sipmethod == SIP_INVITE && p->options && !ast_strlen_zero(p->options->auth))) { 07903 p->branch = p->invite_branch; 07904 build_via(p); 07905 } else if (newbranch) { 07906 p->branch ^= ast_random(); 07907 build_via(p); 07908 } 07909 07910 /* Check for strict or loose router */ 07911 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop, ";lr") == NULL) { 07912 is_strict = TRUE; 07913 if (sipdebug) 07914 ast_debug(1, "Strict routing enforced for session %s\n", p->callid); 07915 } 07916 07917 if (sipmethod == SIP_CANCEL) 07918 c = p->initreq.rlPart2; /* Use original URI */ 07919 else if (sipmethod == SIP_ACK) { 07920 /* Use URI from Contact: in 200 OK (if INVITE) 07921 (we only have the contacturi on INVITEs) */ 07922 if (!ast_strlen_zero(p->okcontacturi)) 07923 c = is_strict ? p->route->hop : p->okcontacturi; 07924 else 07925 c = p->initreq.rlPart2; 07926 } else if (!ast_strlen_zero(p->okcontacturi)) 07927 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 07928 else if (!ast_strlen_zero(p->uri)) 07929 c = p->uri; 07930 else { 07931 char *n; 07932 /* We have no URI, use To: or From: header as URI (depending on direction) */ 07933 ast_copy_string(stripped, get_header(orig, is_outbound ? "To" : "From"), 07934 sizeof(stripped)); 07935 n = get_in_brackets(stripped); 07936 c = remove_uri_parameters(n); 07937 } 07938 init_req(req, sipmethod, c); 07939 07940 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 07941 07942 add_header(req, "Via", p->via); 07943 if (p->route) { 07944 set_destination(p, p->route->hop); 07945 add_route(req, is_strict ? p->route->next : p->route); 07946 } 07947 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07948 07949 ot = get_header(orig, "To"); 07950 of = get_header(orig, "From"); 07951 07952 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 07953 as our original request, including tag (or presumably lack thereof) */ 07954 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 07955 /* Add the proper tag if we don't have it already. If they have specified 07956 their tag, use it. Otherwise, use our own tag */ 07957 if (is_outbound && !ast_strlen_zero(p->theirtag)) 07958 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 07959 else if (!is_outbound) 07960 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 07961 else 07962 snprintf(newto, sizeof(newto), "%s", ot); 07963 ot = newto; 07964 } 07965 07966 if (is_outbound) { 07967 add_header(req, "From", of); 07968 add_header(req, "To", ot); 07969 } else { 07970 add_header(req, "From", ot); 07971 add_header(req, "To", of); 07972 } 07973 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 07974 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 07975 add_header(req, "Contact", p->our_contact); 07976 07977 copy_header(req, orig, "Call-ID"); 07978 add_header(req, "CSeq", tmp); 07979 07980 if (!ast_strlen_zero(global_useragent)) 07981 add_header(req, "User-Agent", global_useragent); 07982 07983 if (!ast_strlen_zero(p->rpid)) 07984 add_header(req, "Remote-Party-ID", p->rpid); 07985 07986 if (!ast_strlen_zero(p->url)) { 07987 add_header(req, "Access-URL", p->url); 07988 ast_string_field_set(p, url, NULL); 07989 } 07990 07991 /* Add Session-Timers related headers if the feature is active for this session. 07992 An exception to this behavior is the ACK request. Since Asterisk never requires 07993 session-timers support from a remote end-point (UAS) in an INVITE, it must 07994 not send 'Require: timer' header in the ACK request. 07995 This should only be added in the INVITE transactions, not MESSAGE or REFER or other 07996 in-dialog messages. 07997 */ 07998 if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE 07999 && sipmethod == SIP_INVITE) { 08000 char se_hdr[256]; 08001 snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval, 08002 strefresher2str(p->stimer->st_ref)); 08003 add_header(req, "Require", "timer"); 08004 add_header(req, "Session-Expires", se_hdr); 08005 snprintf(se_hdr, sizeof(se_hdr), "%d", st_get_se(p, FALSE)); 08006 add_header(req, "Min-SE", se_hdr); 08007 } 08008 08009 return 0; 08010 }
static int resp_needs_contact | ( | const char * | msg, | |
enum sipmethod | method | |||
) | [inline, static] |
Test if this response needs a contact header.
Definition at line 7753 of file chan_sip.c.
References SIP_ACK, SIP_BYE, SIP_CANCEL, SIP_INFO, SIP_INVITE, SIP_MESSAGE, SIP_NOTIFY, SIP_OPTIONS, SIP_PING, SIP_PRACK, SIP_PUBLISH, SIP_REFER, SIP_REGISTER, SIP_SUBSCRIBE, and SIP_UPDATE.
Referenced by respprep().
07753 { 07754 /* Requirements for Contact header inclusion in responses generated 07755 * from the header tables found in the following RFCs. Where the 07756 * Contact header was marked mandatory (m) or optional (o) this 07757 * function returns 1. 07758 * 07759 * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER) 07760 * - RFC 2976 (INFO) 07761 * - RFC 3262 (PRACK) 07762 * - RFC 3265 (SUBSCRIBE, NOTIFY) 07763 * - RFC 3311 (UPDATE) 07764 * - RFC 3428 (MESSAGE) 07765 * - RFC 3515 (REFER) 07766 * - RFC 3903 (PUBLISH) 07767 */ 07768 07769 switch (method) { 07770 /* 1xx, 2xx, 3xx, 485 */ 07771 case SIP_INVITE: 07772 case SIP_UPDATE: 07773 case SIP_SUBSCRIBE: 07774 case SIP_NOTIFY: 07775 if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3)) 07776 return 1; 07777 break; 07778 07779 /* 2xx, 3xx, 485 */ 07780 case SIP_REGISTER: 07781 case SIP_OPTIONS: 07782 if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3)) 07783 return 1; 07784 break; 07785 07786 /* 3xx, 485 */ 07787 case SIP_BYE: 07788 case SIP_PRACK: 07789 case SIP_MESSAGE: 07790 case SIP_PUBLISH: 07791 if (msg[0] == '3' || !strncmp(msg, "485", 3)) 07792 return 1; 07793 break; 07794 07795 /* 2xx, 3xx, 4xx, 5xx, 6xx */ 07796 case SIP_REFER: 07797 if (msg[0] >= '2' && msg[0] <= '6') 07798 return 1; 07799 break; 07800 07801 /* contact will not be included for everything else */ 07802 case SIP_ACK: 07803 case SIP_CANCEL: 07804 case SIP_INFO: 07805 case SIP_PING: 07806 default: 07807 return 0; 07808 } 07809 return 0; 07810 }
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 7814 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_copy_string(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), sip_pvt::expiry, sip_pvt::flags, get_header(), init_resp(), sip_pvt::method, sip_pvt::our_contact, resp_needs_contact(), SIP_INVITE, SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, SIPBUFSIZE, sip_st_dlg::st_active, sip_st_dlg::st_active_peer_ua, sip_st_dlg::st_interval, sip_st_dlg::st_ref, sip_pvt::stimer, strcasestr(), strefresher2str(), SUPPORTED_EXTENSIONS, sip_pvt::tag, sip_pvt::theirtag, TRUE, url, and sip_pvt::url.
07815 { 07816 char newto[256]; 07817 const char *ot; 07818 07819 init_resp(resp, msg); 07820 copy_via_headers(p, resp, req, "Via"); 07821 if (msg[0] == '1' || msg[0] == '2') 07822 copy_all_header(resp, req, "Record-Route"); 07823 copy_header(resp, req, "From"); 07824 ot = get_header(req, "To"); 07825 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 07826 /* Add the proper tag if we don't have it already. If they have specified 07827 their tag, use it. Otherwise, use our own tag */ 07828 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 07829 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 07830 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 07831 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 07832 else 07833 ast_copy_string(newto, ot, sizeof(newto)); 07834 ot = newto; 07835 } 07836 add_header(resp, "To", ot); 07837 copy_header(resp, req, "Call-ID"); 07838 copy_header(resp, req, "CSeq"); 07839 if (!ast_strlen_zero(global_useragent)) 07840 add_header(resp, "User-Agent", global_useragent); 07841 add_header(resp, "Allow", ALLOWED_METHODS); 07842 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 07843 07844 /* If this is an invite, add Session-Timers related headers if the feature is active for this session */ 07845 if (p->method == SIP_INVITE && p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE) { 07846 char se_hdr[256]; 07847 snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval, 07848 strefresher2str(p->stimer->st_ref)); 07849 add_header(resp, "Require", "timer"); 07850 add_header(resp, "Session-Expires", se_hdr); 07851 } 07852 07853 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 07854 /* For registration responses, we also need expiry and 07855 contact info */ 07856 char tmp[256]; 07857 07858 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 07859 add_header(resp, "Expires", tmp); 07860 if (p->expiry) { /* Only add contact if we have an expiry time */ 07861 char contact[SIPBUFSIZE]; 07862 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 07863 add_header(resp, "Contact", contact); /* Not when we unregister */ 07864 } 07865 } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) { 07866 add_header(resp, "Contact", p->our_contact); 07867 } 07868 07869 if (!ast_strlen_zero(p->url)) { 07870 add_header(resp, "Access-URL", p->url); 07871 ast_string_field_set(p, url, NULL); 07872 } 07873 07874 return 0; 07875 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 19804 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, and monlock.
19805 { 19806 /* If we're supposed to be stopped -- stay stopped */ 19807 if (monitor_thread == AST_PTHREADT_STOP) 19808 return 0; 19809 ast_mutex_lock(&monlock); 19810 if (monitor_thread == pthread_self()) { 19811 ast_mutex_unlock(&monlock); 19812 ast_log(LOG_WARNING, "Cannot kill myself\n"); 19813 return -1; 19814 } 19815 if (monitor_thread != AST_PTHREADT_NULL) { 19816 /* Wake up the thread */ 19817 pthread_kill(monitor_thread, SIGURG); 19818 } else { 19819 /* Start a new monitor */ 19820 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 19821 ast_mutex_unlock(&monlock); 19822 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 19823 return -1; 19824 } 19825 } 19826 ast_mutex_unlock(&monlock); 19827 return 0; 19828 }
static void restart_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Restart session timer.
Definition at line 19832 of file chan_sip.c.
References ast_debug, ast_log(), ast_sched_del(), sip_pvt::callid, LOG_WARNING, sched, sip_st_dlg::st_active, sip_st_dlg::st_schedid, start_session_timer(), sip_pvt::stimer, and TRUE.
Referenced by handle_request_invite().
19833 { 19834 if (!p->stimer) { 19835 ast_log(LOG_WARNING, "Null stimer in restart_session_timer - %s\n", p->callid); 19836 return; 19837 } 19838 19839 if (p->stimer->st_active == TRUE) { 19840 if (ast_sched_del(sched, p->stimer->st_schedid) != 0) { 19841 ast_log(LOG_WARNING, "ast_sched_del failed: %d - %s\n", p->stimer->st_schedid, p->callid); 19842 } 19843 19844 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 19845 start_session_timer(p); 19846 } 19847 }
static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 2815 of file chan_sip.c.
References __sip_xmit(), append_history, AST_CAUSE_NO_USER_RESPONSE, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_free, ast_inet_ntoa(), ast_log(), ast_queue_hangup(), ast_verbose(), sip_pvt::callid, sip_pkt::data, DEFAULT_RETRANS, ast_channel::hangupcause, sip_pkt::is_fatal, sip_pkt::is_resp, LOG_WARNING, MAX_RETRANS, sip_pkt::method, sip_pvt::needdestroy, sip_pkt::next, sip_pvt::owner, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pkt::retrans, sip_pkt::retransid, sip_pkt::seqno, sip_alreadygone(), SIP_BYE, sip_debug_test_pvt(), SIP_INVITE, sip_methods, sip_nat_mode(), SIP_OPTIONS, sip_pvt_lock, sip_pvt_unlock, sip_real_dst(), SIP_REGISTER, sip_pkt::timer_a, sip_pkt::timer_t1, UNLINK, and XMIT_ERROR.
02816 { 02817 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 02818 int reschedule = DEFAULT_RETRANS; 02819 int xmitres = 0; 02820 02821 /* Lock channel PVT */ 02822 sip_pvt_lock(pkt->owner); 02823 02824 if (pkt->retrans < MAX_RETRANS) { 02825 pkt->retrans++; 02826 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 02827 if (sipdebug) 02828 ast_debug(4, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n", pkt->retransid, sip_methods[pkt->method].text, pkt->method); 02829 } else { 02830 int siptimer_a; 02831 02832 if (sipdebug) 02833 ast_debug(4, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 02834 if (!pkt->timer_a) 02835 pkt->timer_a = 2 ; 02836 else 02837 pkt->timer_a = 2 * pkt->timer_a; 02838 02839 /* For non-invites, a maximum of 4 secs */ 02840 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 02841 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 02842 siptimer_a = 4000; 02843 02844 /* Reschedule re-transmit */ 02845 reschedule = siptimer_a; 02846 ast_debug(4, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n", pkt->retrans +1, siptimer_a, pkt->timer_t1, pkt->retransid); 02847 } 02848 02849 if (sip_debug_test_pvt(pkt->owner)) { 02850 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 02851 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 02852 pkt->retrans, sip_nat_mode(pkt->owner), 02853 ast_inet_ntoa(dst->sin_addr), 02854 ntohs(dst->sin_port), pkt->data); 02855 } 02856 02857 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 02858 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 02859 sip_pvt_unlock(pkt->owner); 02860 if (xmitres == XMIT_ERROR) 02861 ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid); 02862 else 02863 return reschedule; 02864 } 02865 /* Too many retries */ 02866 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 02867 if (pkt->is_fatal || sipdebug) /* Tell us if it's critical or if we're debugging */ 02868 ast_log(LOG_WARNING, "Maximum retries exceeded on transmission %s for seqno %d (%s %s) -- See doc/sip-retransmit.txt.\n", 02869 pkt->owner->callid, pkt->seqno, 02870 pkt->is_fatal ? "Critical" : "Non-critical", pkt->is_resp ? "Response" : "Request"); 02871 } else if (pkt->method == SIP_OPTIONS && sipdebug) { 02872 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) -- See doc/sip-retransmit.txt.\n", pkt->owner->callid); 02873 02874 } 02875 if (xmitres == XMIT_ERROR) { 02876 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission on Call ID %s\n", pkt->owner->callid); 02877 append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 02878 } else 02879 append_history(pkt->owner, "MaxRetries", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)"); 02880 02881 pkt->retransid = -1; 02882 02883 if (pkt->is_fatal) { 02884 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 02885 sip_pvt_unlock(pkt->owner); /* SIP_PVT, not channel */ 02886 usleep(1); 02887 sip_pvt_lock(pkt->owner); 02888 } 02889 02890 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 02891 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 02892 02893 if (pkt->owner->owner) { 02894 sip_alreadygone(pkt->owner); 02895 ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet (see doc/sip-retransmit.txt).\n", pkt->owner->callid); 02896 ast_queue_hangup(pkt->owner->owner); 02897 ast_channel_unlock(pkt->owner->owner); 02898 } else { 02899 /* If no channel owner, destroy now */ 02900 02901 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 02902 if (pkt->method != SIP_OPTIONS && pkt->method != SIP_REGISTER) { 02903 pkt->owner->needdestroy = 1; 02904 sip_alreadygone(pkt->owner); 02905 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 02906 } 02907 } 02908 } 02909 02910 if (pkt->method == SIP_BYE) { 02911 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 02912 if (pkt->owner->owner) 02913 ast_channel_unlock(pkt->owner->owner); 02914 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 02915 pkt->owner->needdestroy = 1; 02916 } 02917 02918 /* Remove the packet */ 02919 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 02920 if (cur == pkt) { 02921 UNLINK(cur, pkt->owner->packets, prev); 02922 sip_pvt_unlock(pkt->owner); 02923 ast_free(pkt); 02924 return 0; 02925 } 02926 } 02927 /* error case */ 02928 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 02929 sip_pvt_unlock(pkt->owner); 02930 return 0; 02931 }
static int scheduler_process_request_queue | ( | const void * | data | ) | [static] |
Definition at line 19190 of file chan_sip.c.
References ast_channel_trylock, sip_pvt::owner, sip_pvt_lock, and sip_pvt_unlock.
Referenced by queue_request().
19191 { 19192 struct sip_pvt *p = (struct sip_pvt *) data; 19193 int recount = 0; 19194 int nounlock = 0; 19195 int lockretry; 19196 19197 for (lockretry = 10; lockretry > 0; lockretry--) { 19198 sip_pvt_lock(p); 19199 19200 /* lock the owner if it has one -- we may need it */ 19201 /* because this is deadlock-prone, we need to try and unlock if failed */ 19202 if (!p->owner || !ast_channel_trylock(p->owner)) { 19203 break; /* locking succeeded */ 19204 } 19205 19206 if (lockretry != 1) { 19207 sip_pvt_unlock(p); 19208 /* Sleep for a very short amount of time */ 19209 usleep(1); 19210 } 19211 } 19212 19213 if (!lockretry) { 19214 int retry = !AST_LIST_EMPTY(&p->request_queue); 19215 19216 /* we couldn't get the owner lock, which is needed to process 19217 the queued requests, so return a non-zero value, which will 19218 cause the scheduler to run this request again later if there 19219 still requests to be processed 19220 */ 19221 sip_pvt_unlock(p); 19222 return retry; 19223 }; 19224 19225 process_request_queue(p, &recount, &nounlock); 19226 p->request_queue_sched_id = -1; 19227 19228 if (p->owner && !nounlock) { 19229 ast_channel_unlock(p->owner); 19230 } 19231 sip_pvt_unlock(p); 19232 19233 if (recount) { 19234 ast_update_use_count(); 19235 } 19236 19237 return 0; 19238 }
static int send_request | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
enum xmittype | reliable, | |||
int | seqno | |||
) | [static] |
Send SIP Request to the other part of the dialogue.
Definition at line 3244 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, sip_pvt::do_history, sip_pvt::flags, get_header(), sip_proxy::ip, sip_request::len, sip_request::method, sip_pvt::outboundproxy, parse_copy(), sip_pvt::recv, sip_pvt::sa, sip_debug_test_pvt(), sip_methods, SIP_NAT_ROUTE, and XMIT_CRITICAL.
03245 { 03246 int res; 03247 03248 /* If we have an outbound proxy, reset peer address 03249 Only do this once. 03250 */ 03251 if (p->outboundproxy) { 03252 p->sa = p->outboundproxy->ip; 03253 } 03254 03255 add_blank(req); 03256 if (sip_debug_test_pvt(p)) { 03257 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 03258 ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port), req->data); 03259 else 03260 ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port), req->data); 03261 } 03262 if (p->do_history) { 03263 struct sip_request tmp; 03264 parse_copy(&tmp, req); 03265 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 03266 } 03267 res = (reliable) ? 03268 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 03269 __sip_xmit(p, req->data, req->len); 03270 return res; 03271 }
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 3216 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_inet_ntoa(), ast_verbose(), sip_request::data, sip_pvt::do_history, get_header(), sip_request::len, sip_request::method, parse_copy(), sip_request::rlPart2, sip_debug_test_pvt(), sip_methods, sip_nat_mode(), sip_real_dst(), SIP_RESPONSE, SIP_UNKNOWN, and XMIT_CRITICAL.
03217 { 03218 int res; 03219 03220 add_blank(req); 03221 if (sip_debug_test_pvt(p)) { 03222 const struct sockaddr_in *dst = sip_real_dst(p); 03223 03224 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 03225 reliable ? "Reliably " : "", sip_nat_mode(p), 03226 ast_inet_ntoa(dst->sin_addr), 03227 ntohs(dst->sin_port), req->data); 03228 } 03229 if (p->do_history) { 03230 struct sip_request tmp; 03231 parse_copy(&tmp, req); 03232 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 03233 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 03234 } 03235 res = (reliable) ? 03236 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 03237 __sip_xmit(p, req->data, req->len); 03238 if (res > 0) 03239 return 0; 03240 return res; 03241 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 10306 of file chan_sip.c.
References __set_address_from_contact(), ast_test_flag, sip_pvt::flags, sip_pvt::fullcontact, sip_pvt::recv, sip_pvt::sa, SIP_NAT_ROUTE, SIP_TRANSPORT_TLS, sip_pvt::socket, and sip_socket::type.
Referenced by handle_response_invite().
10307 { 10308 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 10309 /* NAT: Don't trust the contact field. Just use what they came to us 10310 with. */ 10311 pvt->sa = pvt->recv; 10312 return 0; 10313 } 10314 10315 return __set_address_from_contact(pvt->fullcontact, &pvt->sa, pvt->socket.type == SIP_TRANSPORT_TLS ? 1 : 0); 10316 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 7663 of file chan_sip.c.
References ahp, ast_copy_string(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_verbose(), debug, hostname, hp, LOG_WARNING, sip_pvt::sa, sip_debug_test_pvt(), and STANDARD_SIP_PORT.
Referenced by reqprep().
07664 { 07665 char *h, *maddr, hostname[256]; 07666 int port, hn; 07667 struct hostent *hp; 07668 struct ast_hostent ahp; 07669 int debug=sip_debug_test_pvt(p); 07670 07671 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 07672 /* general form we are expecting is sip[s]:username[:password][;parameter]@host[:port][;...] */ 07673 07674 if (debug) 07675 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 07676 07677 /* Find and parse hostname */ 07678 h = strchr(uri, '@'); 07679 if (h) 07680 ++h; 07681 else { 07682 h = uri; 07683 if (!strncasecmp(h, "sip:", 4)) 07684 h += 4; 07685 else if (!strncasecmp(h, "sips:", 5)) 07686 h += 5; 07687 } 07688 hn = strcspn(h, ":;>") + 1; 07689 if (hn > sizeof(hostname)) 07690 hn = sizeof(hostname); 07691 ast_copy_string(hostname, h, hn); 07692 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 07693 h += hn - 1; 07694 07695 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 07696 if (*h == ':') { 07697 /* Parse port */ 07698 ++h; 07699 port = strtol(h, &h, 10); 07700 } 07701 else 07702 port = STANDARD_SIP_PORT; 07703 07704 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 07705 maddr = strstr(h, "maddr="); 07706 if (maddr) { 07707 maddr += 6; 07708 hn = strspn(maddr, "0123456789.") + 1; 07709 if (hn > sizeof(hostname)) 07710 hn = sizeof(hostname); 07711 ast_copy_string(hostname, maddr, hn); 07712 } 07713 07714 hp = ast_gethostbyname(hostname, &ahp); 07715 if (hp == NULL) { 07716 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 07717 return; 07718 } 07719 p->sa.sin_family = AF_INET; 07720 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 07721 p->sa.sin_port = htons(port); 07722 if (debug) 07723 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 07724 }
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 20518 of file chan_sip.c.
References ast_copy_string(), ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), buf, ast_channel::flags, LOG_WARNING, ast_channel::next, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, and strsep().
Referenced by get_insecure_variable_from_config(), and handle_common_options().
20519 { 20520 if (ast_strlen_zero(value)) 20521 return; 20522 20523 if (!ast_false(value)) { 20524 char buf[64]; 20525 char *word, *next; 20526 20527 ast_copy_string(buf, value, sizeof(buf)); 20528 next = buf; 20529 while ((word = strsep(&next, ","))) { 20530 if (!strcasecmp(word, "port")) 20531 ast_set_flag(&flags[0], SIP_INSECURE_PORT); 20532 else if (!strcasecmp(word, "invite")) 20533 ast_set_flag(&flags[0], SIP_INSECURE_INVITE); 20534 else 20535 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 20536 } 20537 } 20538 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 20989 of file chan_sip.c.
References sip_peer::addr, sip_peer::allowtransfer, ast_copy_flags, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::capability, sip_peer::cid_name, sip_peer::cid_num, clear_peer_mailboxes(), sip_peer::context, sip_peer::defaddr, default_prefs, sip_peer::expire, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, global_flags, sip_peer::language, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, sip_peer::pickupgroup, sip_peer::pokeexpire, sip_peer::prefs, sip_peer::qualifyfreq, sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, set_socket_transport(), SIP_FLAGS_TO_COPY, SIP_PAGE2_FLAGS_TO_COPY, SIP_TRANSPORT_UDP, sip_peer::socket, sip_st_cfg::st_max_se, sip_st_cfg::st_min_se, sip_st_cfg::st_mode_oper, sip_st_cfg::st_ref, STANDARD_SIP_PORT, sip_peer::stimer, sip_peer::subscribecontext, sip_peer::timer_b, sip_peer::timer_t1, and sip_peer::vmexten.
Referenced by build_peer(), and temp_peer().
20990 { 20991 if (peer->expire == 0) { 20992 /* Don't reset expire or port time during reload 20993 if we have an active registration 20994 */ 20995 peer->expire = -1; 20996 peer->pokeexpire = -1; 20997 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 20998 set_socket_transport(&peer->socket, SIP_TRANSPORT_UDP); 20999 } 21000 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 21001 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 21002 strcpy(peer->context, default_context); 21003 strcpy(peer->subscribecontext, default_subscribecontext); 21004 strcpy(peer->language, default_language); 21005 strcpy(peer->mohinterpret, default_mohinterpret); 21006 strcpy(peer->mohsuggest, default_mohsuggest); 21007 peer->addr.sin_family = AF_INET; 21008 peer->defaddr.sin_family = AF_INET; 21009 peer->capability = global_capability; 21010 peer->maxcallbitrate = default_maxcallbitrate; 21011 peer->rtptimeout = global_rtptimeout; 21012 peer->rtpholdtimeout = global_rtpholdtimeout; 21013 peer->rtpkeepalive = global_rtpkeepalive; 21014 peer->allowtransfer = global_allowtransfer; 21015 peer->autoframing = global_autoframing; 21016 peer->qualifyfreq = global_qualifyfreq; 21017 if (global_callcounter) 21018 peer->call_limit=999; 21019 strcpy(peer->vmexten, default_vmexten); 21020 peer->secret[0] = '\0'; 21021 peer->md5secret[0] = '\0'; 21022 peer->cid_num[0] = '\0'; 21023 peer->cid_name[0] = '\0'; 21024 peer->fromdomain[0] = '\0'; 21025 peer->fromuser[0] = '\0'; 21026 peer->regexten[0] = '\0'; 21027 peer->callgroup = 0; 21028 peer->pickupgroup = 0; 21029 peer->maxms = default_qualify; 21030 peer->prefs = default_prefs; 21031 peer->stimer.st_mode_oper = global_st_mode; /* Session-Timers */ 21032 peer->stimer.st_ref = global_st_refresher; 21033 peer->stimer.st_min_se = global_min_se; 21034 peer->stimer.st_max_se = global_max_se; 21035 peer->timer_t1 = global_t1; 21036 peer->timer_b = global_timer_b; 21037 clear_peer_mailboxes(peer); 21038 }
static void set_socket_transport | ( | struct sip_socket * | socket, | |
int | transport | |||
) | [static] |
Definition at line 10130 of file chan_sip.c.
References ao2_ref(), sip_socket::fd, sip_request::socket, sip_socket::tcptls_session, and sip_socket::type.
Referenced by _sip_tcp_helper_thread(), build_peer(), create_addr(), expire_register(), get_transport_pvt(), parse_register_contact(), set_peer_defaults(), sip_alloc(), sip_request_call(), sipsock_read(), and transmit_register().
10131 { 10132 /* if the transport type changes, clear all socket data */ 10133 if (socket->type != transport) { 10134 socket->fd = -1; 10135 socket->type = transport; 10136 if (socket->tcptls_session) { 10137 ao2_ref(socket->tcptls_session, -1); 10138 socket->tcptls_session = NULL; 10139 } 10140 } 10141 }
static void set_t38_capabilities | ( | struct sip_pvt * | p | ) | [static] |
Set the global T38 capabilities on a SIP dialog structure.
Definition at line 4073 of file chan_sip.c.
References ast_udptl_get_error_correction_scheme(), t38properties::capability, sip_pvt::t38, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by create_addr_from_peer(), handle_request_invite(), and sip_alloc().
04074 { 04075 p->t38.capability = global_t38_capability; 04076 if (p->udptl) { 04077 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 04078 p->t38.capability |= T38FAX_UDP_EC_FEC; 04079 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 04080 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04081 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 04082 p->t38.capability |= T38FAX_UDP_EC_NONE; 04083 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04084 } 04085 }
static int show_channels_cb | ( | void * | __cur, | |
void * | __arg, | |||
int | flags | |||
) | [static] |
callback for show channel|subscription
Definition at line 13895 of file chan_sip.c.
References ast_cli(), ast_extension_state2str(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_str_alloca, ast_test_flag, sip_pvt::callid, sip_pvt::cid_num, cli_yesno(), __show_chan_arg::fd, sip_pvt::flags, FORMAT, FORMAT3, sip_pvt::lastmsg, sip_pvt::laststate, ast_channel::nativeformats, sip_pvt::needdestroy, NONE, __show_chan_arg::numchans, sip_pvt::owner, peer_mailboxes_to_str(), sip_pvt::refer, referstatus2str(), sip_pvt::relatedpeer, S_OR, SIP_PAGE2_CALL_ONHOLD, sip_real_dst(), SIPBUFSIZE, sip_refer::status, ast_str::str, sip_pvt::subscribed, sip_pvt::subscribeuri, subscription_type2str(), __show_chan_arg::subscriptions, and sip_pvt::username.
Referenced by sip_show_channels().
13896 { 13897 struct sip_pvt *cur = __cur; 13898 struct __show_chan_arg *arg = __arg; 13899 const struct sockaddr_in *dst = sip_real_dst(cur); 13900 13901 /* XXX indentation preserved to reduce diff. Will be fixed later */ 13902 if (cur->subscribed == NONE && !arg->subscriptions) { 13903 /* set if SIP transfer in progress */ 13904 const char *referstatus = cur->refer ? referstatus2str(cur->refer->status) : ""; 13905 char formatbuf[SIPBUFSIZE/2]; 13906 13907 ast_cli(arg->fd, FORMAT, ast_inet_ntoa(dst->sin_addr), 13908 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 13909 cur->callid, 13910 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 13911 cli_yesno(ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD)), 13912 cur->needdestroy ? "(d)" : "", 13913 cur->lastmsg , 13914 referstatus 13915 ); 13916 arg->numchans++; 13917 } 13918 if (cur->subscribed != NONE && arg->subscriptions) { 13919 struct ast_str *mailbox_str = ast_str_alloca(512); 13920 if (cur->subscribed == MWI_NOTIFICATION && cur->relatedpeer) 13921 peer_mailboxes_to_str(&mailbox_str, cur->relatedpeer); 13922 ast_cli(arg->fd, FORMAT3, ast_inet_ntoa(dst->sin_addr), 13923 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 13924 cur->callid, 13925 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 13926 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 13927 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 13928 subscription_type2str(cur->subscribed), 13929 cur->subscribed == MWI_NOTIFICATION ? S_OR(mailbox_str->str, "<none>") : "<none>" 13930 ); 13931 arg->numchans++; 13932 } 13933 13934 return 0; /* don't care, we scan all channels */ 13935 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 22624 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_debug, ast_get_encoded_str(), ast_log(), ast_strlen_zero(), chan, FALSE, inbuf(), len(), LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and TRUE.
Referenced by load_module().
22625 { 22626 int no = 0; 22627 int ok = FALSE; 22628 char varbuf[30]; 22629 char *inbuf = data, *subbuf; 22630 22631 if (ast_strlen_zero(inbuf)) { 22632 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 22633 return 0; 22634 } 22635 ast_channel_lock(chan); 22636 22637 /* Check for headers */ 22638 while (!ok && no <= 50) { 22639 no++; 22640 snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no); 22641 22642 /* Compare without the leading underscores */ 22643 if ((pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL)) { 22644 ok = TRUE; 22645 } 22646 } 22647 if (ok) { 22648 size_t len = strlen(inbuf); 22649 subbuf = alloca(len + 1); 22650 ast_get_encoded_str(inbuf, subbuf, len + 1); 22651 pbx_builtin_setvar_helper(chan, varbuf, subbuf); 22652 if (sipdebug) { 22653 ast_debug(1, "SIP Header added \"%s\" as %s\n", inbuf, varbuf); 22654 } 22655 } else { 22656 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 22657 } 22658 ast_channel_unlock(chan); 22659 return 0; 22660 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 3910 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
03911 { 03912 /* We know name is the first field, so we can cast */ 03913 struct sip_peer *p = (struct sip_peer *) name; 03914 return !(!inaddrcmp(&p->addr, sin) || 03915 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 03916 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 03917 }
static struct sip_pvt * sip_alloc | ( | ast_string_field | callid, | |
struct sockaddr_in * | sin, | |||
int | useglobal_nat, | |||
const int | intended_method, | |||
struct sip_request * | req | |||
) | [static] |
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 6029 of file chan_sip.c.
References ast_calloc, ast_copy_flags, ast_debug, ast_free, AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_random(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_setqos(), ast_sip_ouraddrfor(), ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_test_flag, ast_udptl_destroy(), ast_udptl_new_with_bindaddr(), ast_udptl_setqos(), ast_variables_destroy(), bindaddr, build_callid_pvt(), build_via(), default_prefs, dialog_ref(), dialoglist, dialoglist_lock(), dialoglist_unlock(), do_setnat(), errno, global_flags, INITIAL_CSEQ, internip, io, LOG_WARNING, make_our_tag(), NONE, sched, set_socket_transport(), set_t38_capabilities(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_OPTIONS, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_REGISTER, SIP_TRANSPORT_UDP, sip_request::socket, text, TRUE, and sip_socket::type.
Referenced by sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
06031 { 06032 struct sip_pvt *p; 06033 06034 if (!(p = ast_calloc(1, sizeof(*p)))) 06035 return NULL; 06036 06037 if (ast_string_field_init(p, 512)) { 06038 ast_free(p); 06039 return NULL; 06040 } 06041 06042 ast_mutex_init(&p->pvt_lock); 06043 06044 if (req) { 06045 set_socket_transport(&p->socket, req->socket.type); /* Later in ast_sip_ouraddrfor we need this to choose the right ip and port for the specific transport */ 06046 } else { 06047 set_socket_transport(&p->socket, SIP_TRANSPORT_UDP); 06048 } 06049 06050 p->socket.fd = -1; 06051 p->method = intended_method; 06052 p->initid = -1; 06053 p->waitid = -1; 06054 p->autokillid = -1; 06055 p->request_queue_sched_id = -1; 06056 p->t38id = -1; 06057 p->subscribed = NONE; 06058 p->stateid = -1; 06059 p->sessionversion_remote = -1; 06060 p->session_modify = TRUE; 06061 p->stimer = NULL; 06062 p->prefs = default_prefs; /* Set default codecs for this call */ 06063 06064 if (intended_method != SIP_OPTIONS) { /* Peerpoke has it's own system */ 06065 p->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */ 06066 p->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */ 06067 } 06068 06069 if (!sin) 06070 p->ourip = internip; 06071 else { 06072 p->sa = *sin; 06073 ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p); 06074 } 06075 06076 /* Copy global flags to this PVT at setup. */ 06077 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 06078 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 06079 06080 p->do_history = recordhistory; 06081 06082 p->branch = ast_random(); 06083 make_our_tag(p->tag, sizeof(p->tag)); 06084 p->ocseq = INITIAL_CSEQ; 06085 06086 if (sip_methods[intended_method].need_rtp) { 06087 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 06088 /* If the global videosupport flag is on, we always create a RTP interface for video */ 06089 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 06090 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 06091 if (ast_test_flag(&p->flags[1], SIP_PAGE2_TEXTSUPPORT)) 06092 p->trtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 06093 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 06094 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 06095 if (!p->rtp|| (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp) 06096 || (ast_test_flag(&p->flags[1], SIP_PAGE2_TEXTSUPPORT) && !p->trtp)) { 06097 ast_log(LOG_WARNING, "Unable to create RTP audio %s%ssession: %s\n", 06098 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video " : "", 06099 ast_test_flag(&p->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "and text " : "", strerror(errno)); 06100 if (p->rtp) { 06101 ast_rtp_destroy(p->rtp); 06102 } 06103 if (p->vrtp) { 06104 ast_rtp_destroy(p->vrtp); 06105 } 06106 if (p->udptl) { 06107 ast_udptl_destroy(p->udptl); 06108 } 06109 ast_mutex_destroy(&p->pvt_lock); 06110 if (p->chanvars) { 06111 ast_variables_destroy(p->chanvars); 06112 p->chanvars = NULL; 06113 } 06114 ast_string_field_free_memory(p); 06115 ast_free(p); 06116 return NULL; 06117 } 06118 ast_rtp_setqos(p->rtp, global_tos_audio, global_cos_audio, "SIP RTP"); 06119 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 06120 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 06121 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 06122 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 06123 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 06124 if (p->vrtp) { 06125 ast_rtp_setqos(p->vrtp, global_tos_video, global_cos_video, "SIP VRTP"); 06126 ast_rtp_setdtmf(p->vrtp, 0); 06127 ast_rtp_setdtmfcompensate(p->vrtp, 0); 06128 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 06129 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 06130 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 06131 } 06132 if (p->trtp) { 06133 ast_rtp_setqos(p->trtp, global_tos_text, global_cos_text, "SIP TRTP"); 06134 ast_rtp_setdtmf(p->trtp, 0); 06135 ast_rtp_setdtmfcompensate(p->trtp, 0); 06136 } 06137 if (p->udptl) 06138 ast_udptl_setqos(p->udptl, global_tos_audio, global_cos_audio); 06139 p->maxcallbitrate = default_maxcallbitrate; 06140 p->autoframing = global_autoframing; 06141 ast_rtp_codec_setpref(p->rtp, &p->prefs); 06142 } 06143 06144 if (useglobal_nat && sin) { 06145 /* Setup NAT structure according to global settings if we have an address */ 06146 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 06147 p->recv = *sin; 06148 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 06149 } 06150 06151 if (p->method != SIP_REGISTER) 06152 ast_string_field_set(p, fromdomain, default_fromdomain); 06153 build_via(p); 06154 if (!callid) 06155 build_callid_pvt(p); 06156 else 06157 ast_string_field_set(p, callid, callid); 06158 /* Assign default music on hold class */ 06159 ast_string_field_set(p, mohinterpret, default_mohinterpret); 06160 ast_string_field_set(p, mohsuggest, default_mohsuggest); 06161 p->capability = global_capability; 06162 p->allowtransfer = global_allowtransfer; 06163 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 06164 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 06165 p->noncodeccapability |= AST_RTP_DTMF; 06166 if (p->udptl) { 06167 ast_copy_flags(&p->t38.t38support, &p->flags[1], SIP_PAGE2_T38SUPPORT); 06168 set_t38_capabilities(p); 06169 p->t38.jointcapability = p->t38.capability; 06170 } 06171 ast_string_field_set(p, context, default_context); 06172 06173 AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue); 06174 06175 /* Add to active dialog list */ 06176 dialoglist_lock(); 06177 p->next = dialoglist; 06178 dialoglist = dialog_ref(p); 06179 dialoglist_unlock(); 06180 ast_debug(1, "Allocating new SIP dialog for %s - %s (%s)\n", callid ? callid : "(No Call-ID)", sip_methods[intended_method].text, p->rtp ? "With RTP" : "No RTP"); 06181 return p; 06182 }
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 2381 of file chan_sip.c.
References sip_pvt::alreadygone, ast_debug, and sip_pvt::callid.
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), retrans_pkt(), sip_indicate(), and sip_sipredirect().
02382 { 02383 ast_debug(3, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 02384 dialog->alreadygone = 1; 02385 }
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 5154 of file chan_sip.c.
References ast_channel::_state, ast_debug, ast_rtp_new_source(), ast_set_flag, ast_setstate(), AST_STATE_UP, change_t38_state(), FALSE, ast_channel::name, SIP_PAGE2_DIALOG_ESTABLISHED, sip_pvt_lock, sip_pvt_unlock, T38_ENABLED, T38_PEER_DIRECT, ast_channel::tech_pvt, transmit_response_with_sdp(), try_suggested_sip_codec(), and XMIT_CRITICAL.
05155 { 05156 int res = 0; 05157 struct sip_pvt *p = ast->tech_pvt; 05158 05159 sip_pvt_lock(p); 05160 if (ast->_state != AST_STATE_UP) { 05161 try_suggested_sip_codec(p); 05162 05163 ast_setstate(ast, AST_STATE_UP); 05164 ast_debug(1, "SIP answering channel: %s\n", ast->name); 05165 if (p->t38.state == T38_PEER_DIRECT) { 05166 change_t38_state(p, T38_ENABLED); 05167 } 05168 ast_rtp_new_source(p->rtp); 05169 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 05170 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL, FALSE); 05171 } 05172 sip_pvt_unlock(p); 05173 return res; 05174 }
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 4353 of file chan_sip.c.
References ast_channel::_state, sip_invite_param::addsipheaders, AST_CAUSE_USER_BUSY, ast_debug, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), AST_SCHED_REPLACE, ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_translate_available_formats(), ast_var_name(), ast_var_value(), auto_congest(), buf, sip_pvt::callingpres, t38properties::capability, sip_pvt::capability, ast_channel::cid, sip_pvt::cid_name, ast_callerid::cid_pres, dialog_ref(), ast_var_t::entries, sip_pvt::flags, ast_channel::hangupcause, INC_CALL_RINGING, sip_pvt::initid, INV_CALLING, sip_pvt::invitestate, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, LOG_WARNING, ast_channel::name, sip_pvt::noncodeccapability, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, sched, SIP_INVITE, SIP_OUTGOING, SIPBUFSIZE, sip_pvt::t38, ast_channel::tech_pvt, sip_pvt::timer_b, sip_invite_param::transfer, transmit_invite(), update_call_counter(), sip_invite_param::uri_options, sip_pvt::username, ast_channel::varshead, sip_invite_param::vxml_url, and XMIT_ERROR.
04354 { 04355 int res; 04356 struct sip_pvt *p = ast->tech_pvt; /* chan is locked, so the reference cannot go away */ 04357 struct varshead *headp; 04358 struct ast_var_t *current; 04359 const char *referer = NULL; /* SIP referrer */ 04360 04361 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 04362 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 04363 return -1; 04364 } 04365 04366 /* Check whether there is vxml_url, distinctive ring variables */ 04367 headp=&ast->varshead; 04368 AST_LIST_TRAVERSE(headp, current, entries) { 04369 /* Check whether there is a VXML_URL variable */ 04370 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 04371 p->options->vxml_url = ast_var_value(current); 04372 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 04373 p->options->uri_options = ast_var_value(current); 04374 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 04375 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 04376 p->options->addsipheaders = 1; 04377 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 04378 /* This is a transfered call */ 04379 p->options->transfer = 1; 04380 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 04381 /* This is the referrer */ 04382 referer = ast_var_value(current); 04383 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 04384 /* We're replacing a call. */ 04385 p->options->replaces = ast_var_value(current); 04386 } 04387 } 04388 04389 res = 0; 04390 ast_set_flag(&p->flags[0], SIP_OUTGOING); 04391 04392 if (p->options->transfer) { 04393 char buf[SIPBUFSIZE/2]; 04394 04395 if (referer) { 04396 if (sipdebug) 04397 ast_debug(3, "Call for %s transfered by %s\n", p->username, referer); 04398 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 04399 } else 04400 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 04401 ast_string_field_set(p, cid_name, buf); 04402 } 04403 ast_debug(1, "Outgoing Call for %s\n", p->username); 04404 04405 res = update_call_counter(p, INC_CALL_RINGING); 04406 04407 if (res == -1) { 04408 ast->hangupcause = AST_CAUSE_USER_BUSY; 04409 return res; 04410 } 04411 p->callingpres = ast->cid.cid_pres; 04412 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 04413 p->jointnoncodeccapability = p->noncodeccapability; 04414 04415 /* If there are no audio formats left to offer, punt */ 04416 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 04417 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 04418 res = -1; 04419 } else { 04420 int xmitres; 04421 04422 p->t38.jointcapability = p->t38.capability; 04423 ast_debug(2, "Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 04424 04425 xmitres = transmit_invite(p, SIP_INVITE, 1, 2); 04426 if (xmitres == XMIT_ERROR) 04427 return -1; 04428 p->invitestate = INV_CALLING; 04429 04430 /* Initialize auto-congest time */ 04431 AST_SCHED_REPLACE(p->initid, sched, p->timer_b, auto_congest, dialog_ref(p)); 04432 } 04433 04434 return res; 04435 }
static int sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
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 3082 of file chan_sip.c.
References append_history, ast_sched_del(), sip_pvt::autokillid, dialog_unref(), and sched.
Referenced by cb_extensionstate(), check_user_ok(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), sip_hangup(), and sip_scheddestroy().
03083 { 03084 int res = 0; 03085 if (p->autokillid > -1) { 03086 if (!(res = ast_sched_del(sched, p->autokillid))) { 03087 append_history(p, "CancelDestroy", ""); 03088 p->autokillid = -1; 03089 } 03090 dialog_unref(p); 03091 } 03092 return res; 03093 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 2525 of file chan_sip.c.
References debugaddr.
Referenced by check_peer_ok(), check_user_ok(), handle_request_do(), and sip_debug_test_pvt().
02526 { 02527 if (!sipdebug) 02528 return 0; 02529 if (debugaddr.sin_addr.s_addr) { 02530 if (((ntohs(debugaddr.sin_port) != 0) 02531 && (debugaddr.sin_port != addr->sin_port)) 02532 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 02533 return 0; 02534 } 02535 return 1; 02536 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 2554 of file chan_sip.c.
References sip_debug_test_addr(), and sip_real_dst().
Referenced by __sip_destroy(), add_sdp(), build_route(), check_via(), do_register_auth(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), handle_incoming(), process_sdp(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendhtml(), sip_sendtext(), and transmit_register().
02555 { 02556 if (!sipdebug) 02557 return 0; 02558 return sip_debug_test_addr(sip_real_dst(p)); 02559 }
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 4777 of file chan_sip.c.
References __sip_destroy(), ast_debug, sip_pvt::callid, and TRUE.
Referenced by __sip_autodestruct(), handle_request_subscribe(), reload_config(), sip_destroy_peer(), sip_notify(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
04778 { 04779 ast_debug(3, "Destroying SIP dialog %s\n", p->callid); 04780 __sip_destroy(p, TRUE, TRUE); 04781 return NULL; 04782 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 3639 of file chan_sip.c.
References ao2_ref(), ast_debug, ast_dnsmgr_release(), ast_free, ast_free_ha(), AST_SCHED_DEL, ast_variables_destroy(), sip_peer::auth, sip_peer::call, sip_peer::chanvars, clear_peer_mailboxes(), clear_realm_authentication(), sip_peer::dnsmgr, sip_peer::expire, FALSE, sip_peer::ha, sip_peer::is_realtime, sip_peer::mwipvt, sip_peer::name, sip_peer::outboundproxy, sip_peer::pokeexpire, register_peer_exten(), sched, sip_peer::selfdestruct, sip_destroy(), sip_peer::socket, and sip_socket::tcptls_session.
Referenced by sip_do_reload(), sip_prune_realtime(), unload_module(), and unref_peer().
03640 { 03641 ast_debug(3, "Destroying SIP peer %s\n", peer->name); 03642 03643 if (peer->outboundproxy) 03644 ast_free(peer->outboundproxy); 03645 peer->outboundproxy = NULL; 03646 03647 /* Delete it, it needs to disappear */ 03648 if (peer->call) 03649 peer->call = sip_destroy(peer->call); 03650 03651 if (peer->mwipvt) /* We have an active subscription, delete it */ 03652 peer->mwipvt = sip_destroy(peer->mwipvt); 03653 03654 if (peer->chanvars) { 03655 ast_variables_destroy(peer->chanvars); 03656 peer->chanvars = NULL; 03657 } 03658 03659 /* If the schedule delete fails, that means the schedule is currently 03660 * running, which means we should wait for that thread to complete. 03661 * Otherwise, there's a crashable race condition. 03662 * 03663 * NOTE: once peer is refcounted, this probably is no longer necessary. 03664 */ 03665 AST_SCHED_DEL(sched, peer->expire); 03666 AST_SCHED_DEL(sched, peer->pokeexpire); 03667 03668 register_peer_exten(peer, FALSE); 03669 ast_free_ha(peer->ha); 03670 if (peer->selfdestruct) 03671 apeerobjs--; 03672 else if (peer->is_realtime) { 03673 rpeerobjs--; 03674 ast_debug(3, "-REALTIME- peer Destroyed. Name: %s. Realtime Peer objects: %d\n", peer->name, rpeerobjs); 03675 } else 03676 speerobjs--; 03677 clear_realm_authentication(peer->auth); 03678 peer->auth = NULL; 03679 if (peer->dnsmgr) 03680 ast_dnsmgr_release(peer->dnsmgr); 03681 clear_peer_mailboxes(peer); 03682 03683 if (peer->socket.tcptls_session) { 03684 ao2_ref(peer->socket.tcptls_session, -1); 03685 peer->socket.tcptls_session = NULL; 03686 } 03687 ast_free(peer); 03688 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 3941 of file chan_sip.c.
References ast_debug, ast_free, ast_free_ha(), ast_variables_destroy(), and user.
Referenced by reload_config(), unload_module(), and unref_user().
03942 { 03943 ast_debug(3, "Destroying user object from memory: %s\n", user->name); 03944 03945 ast_free_ha(user->ha); 03946 if (user->chanvars) { 03947 ast_variables_destroy(user->chanvars); 03948 user->chanvars = NULL; 03949 } 03950 if (user->is_realtime) 03951 ruserobjs--; 03952 else 03953 suserobjs--; 03954 ast_free(user); 03955 }
static int sip_devicestate | ( | void * | data | ) | [static] |
Part of PBX channel interface.
For peers with call limit:
For peers without call limit:
Peers that does not have a known call and can't be reached by OPTIONS
If we return AST_DEVICE_UNKNOWN, the device state engine will try to find out a state by walking the channel list.
The queue system (app_queue.c) treats a member as "active" if devicestate is != AST_DEVICE_UNAVAILBALE && != AST_DEVICE_INVALID
When placing a call to the queue member, queue system sets a member to busy if != AST_DEVICE_NOT_INUSE and != AST_DEVICE_UNKNOWN
Definition at line 20285 of file chan_sip.c.
References sip_peer::addr, ast_debug, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_strdupa, sip_peer::busy_level, sip_peer::call_limit, sip_peer::defaddr, find_peer(), sip_peer::inRinging, sip_peer::inUse, sip_peer::lastms, sip_peer::maxms, sip_peer::onHold, and unref_peer().
20286 { 20287 char *host; 20288 char *tmp; 20289 struct sip_peer *p; 20290 20291 int res = AST_DEVICE_INVALID; 20292 20293 /* make sure data is not null. Maybe unnecessary, but better be safe */ 20294 host = ast_strdupa(data ? data : ""); 20295 if ((tmp = strchr(host, '@'))) 20296 host = tmp + 1; 20297 20298 ast_debug(3, "Checking device state for peer %s\n", host); 20299 20300 /* If find_peer asks for a realtime peer, then this breaks rtautoclear. This 20301 * is because when a peer tries to autoexpire, the last thing it does is to 20302 * queue up an event telling the system that the devicestate has changed 20303 * (presumably to unavailable). If we ask for a realtime peer here, this would 20304 * load it BACK into memory, thus defeating the point of trying to clear dead 20305 * hosts out of memory. 20306 */ 20307 if ((p = find_peer(host, NULL, 0, 1))) { 20308 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 20309 /* we have an address for the peer */ 20310 20311 /* Check status in this order 20312 - Hold 20313 - Ringing 20314 - Busy (enforced only by call limit) 20315 - Inuse (we have a call) 20316 - Unreachable (qualify) 20317 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 20318 for registered devices */ 20319 20320 if (p->onHold) 20321 /* First check for hold or ring states */ 20322 res = AST_DEVICE_ONHOLD; 20323 else if (p->inRinging) { 20324 if (p->inRinging == p->inUse) 20325 res = AST_DEVICE_RINGING; 20326 else 20327 res = AST_DEVICE_RINGINUSE; 20328 } else if (p->call_limit && (p->inUse == p->call_limit)) 20329 /* check call limit */ 20330 res = AST_DEVICE_BUSY; 20331 else if (p->call_limit && p->busy_level && p->inUse >= p->busy_level) 20332 /* We're forcing busy before we've reached the call limit */ 20333 res = AST_DEVICE_BUSY; 20334 else if (p->call_limit && p->inUse) 20335 /* Not busy, but we do have a call */ 20336 res = AST_DEVICE_INUSE; 20337 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 20338 /* We don't have a call. Are we reachable at all? Requires qualify= */ 20339 res = AST_DEVICE_UNAVAILABLE; 20340 else /* Default reply if we're registered and have no other data */ 20341 res = AST_DEVICE_NOT_INUSE; 20342 } else { 20343 /* there is no address, it's unavailable */ 20344 res = AST_DEVICE_UNAVAILABLE; 20345 } 20346 unref_peer(p); 20347 } else { 20348 res = AST_DEVICE_UNKNOWN; 20349 } 20350 20351 return res; 20352 }
static char * sip_do_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 14546 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::line, ast_cli_args::n, ast_cli_args::pos, sip_debug_console, sip_do_debug_ip(), sip_do_debug_peer(), strcasestr(), ast_cli_entry::usage, and ast_cli_args::word.
14547 { 14548 int oldsipdebug = sipdebug & sip_debug_console; 14549 char *what; 14550 14551 if (cmd == CLI_INIT) { 14552 e->command = "sip set debug {on|off|ip|peer}"; 14553 e->usage = 14554 "Usage: sip set debug {off|on|ip addr[:port]|peer peername}\n" 14555 " Globally disables dumping of SIP packets,\n" 14556 " or enables it either globally or for a (single)\n" 14557 " IP address or registered peer.\n"; 14558 return NULL; 14559 } else if (cmd == CLI_GENERATE) { 14560 if (a->pos == 4 && strcasestr(a->line, " peer")) /* XXX should check on argv too */ 14561 return complete_sip_peer(a->word, a->n, 0); 14562 return NULL; 14563 } 14564 14565 what = a->argv[e->args-1]; /* guaranteed to exist */ 14566 if (a->argc == e->args) { /* on/off */ 14567 if (!strcasecmp(what, "on")) { 14568 sipdebug |= sip_debug_console; 14569 sipdebug_text = 1; /*! \note this can be a special debug command - "sip debug text" or something */ 14570 memset(&debugaddr, 0, sizeof(debugaddr)); 14571 ast_cli(a->fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 14572 return CLI_SUCCESS; 14573 } else if (!strcasecmp(what, "off")) { 14574 sipdebug &= ~sip_debug_console; 14575 sipdebug_text = 0; 14576 ast_cli(a->fd, "SIP Debugging Disabled\n"); 14577 return CLI_SUCCESS; 14578 } 14579 } else if (a->argc == e->args +1) {/* ip/peer */ 14580 if (!strcasecmp(what, "ip")) 14581 return sip_do_debug_ip(a->fd, a->argv[e->args]); 14582 else if (!strcasecmp(what, "peer")) 14583 return sip_do_debug_peer(a->fd, a->argv[e->args]); 14584 } 14585 return CLI_SHOWUSAGE; /* default, failure */ 14586 }
static char * sip_do_debug_ip | ( | int | fd, | |
char * | arg | |||
) | [static] |
Enable SIP Debugging for a single IP.
Definition at line 14496 of file chan_sip.c.
References ahp, ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), CLI_SHOWUSAGE, CLI_SUCCESS, debugaddr, hp, sip_debug_console, and strsep().
Referenced by sip_do_debug().
14497 { 14498 struct hostent *hp; 14499 struct ast_hostent ahp; 14500 int port = 0; 14501 char *p; 14502 14503 p = arg; 14504 strsep(&p, ":"); 14505 if (p) 14506 port = atoi(p); 14507 hp = ast_gethostbyname(arg, &ahp); 14508 if (hp == NULL) 14509 return CLI_SHOWUSAGE; 14510 14511 debugaddr.sin_family = AF_INET; 14512 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 14513 debugaddr.sin_port = htons(port); 14514 if (port == 0) 14515 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 14516 else 14517 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 14518 14519 sipdebug |= sip_debug_console; 14520 14521 return CLI_SUCCESS; 14522 }
static char * sip_do_debug_peer | ( | int | fd, | |
char * | arg | |||
) | [static] |
Turn on SIP debugging for a given peer.
Definition at line 14525 of file chan_sip.c.
References sip_peer::addr, ast_cli(), ast_inet_ntoa(), CLI_SUCCESS, debugaddr, find_peer(), sip_debug_console, and unref_peer().
Referenced by sip_do_debug().
14526 { 14527 struct sip_peer *peer = find_peer(arg, NULL, 1, 0); 14528 if (!peer) 14529 ast_cli(fd, "No such peer '%s'\n", arg); 14530 else if (peer->addr.sin_addr.s_addr == 0) 14531 ast_cli(fd, "Unable to get IP address of peer '%s'\n", arg); 14532 else { 14533 debugaddr.sin_family = AF_INET; 14534 debugaddr.sin_addr = peer->addr.sin_addr; 14535 debugaddr.sin_port = peer->addr.sin_port; 14536 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", 14537 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 14538 sipdebug |= sip_debug_console; 14539 } 14540 if (peer) 14541 unref_peer(peer); 14542 return CLI_SUCCESS; 14543 }
static char * sip_do_history_deprecated | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Enable/Disable SIP History logging (CLI) - deprecated. use sip_set_history instead.
Definition at line 14661 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, TRUE, and ast_cli_entry::usage.
14662 { 14663 switch (cmd) { 14664 case CLI_INIT: 14665 e->command = "sip history [off]"; 14666 e->usage = 14667 "Usage: sip history [off]\n" 14668 " Enables/Disables recording of SIP dialog history for debugging purposes.\n" 14669 " Use 'sip show history' to view the history of a call number.\n"; 14670 return NULL; 14671 case CLI_GENERATE: 14672 return NULL; 14673 } 14674 14675 if (a->argc < 2 || a->argc > 3) { 14676 return CLI_SHOWUSAGE; 14677 } 14678 if (a->argc == 2) { 14679 recordhistory = TRUE; 14680 ast_cli(a->fd, "SIP History Recording Enabled (use 'sip show history')\n"); 14681 } else { 14682 if (strncasecmp(a->argv[2], "off", 3)) 14683 return CLI_SHOWUSAGE; 14684 recordhistory = FALSE; 14685 ast_cli(a->fd, "SIP History Recording Disabled\n"); 14686 } 14687 return CLI_SUCCESS; 14688 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 22771 of file chan_sip.c.
References ast_debug, ASTOBJ_CONTAINER_PRUNE_MARKED, peerl, reload_config(), sip_destroy_peer(), sip_poke_all_peers(), and sip_send_all_registers().
Referenced by do_monitor().
22772 { 22773 reload_config(reason); 22774 22775 /* Prune peers who still are supposed to be deleted */ 22776 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 22777 ast_debug(4, "--------------- Done destroying pruned peers\n"); 22778 22779 /* Send qualify (OPTIONS) to all peers */ 22780 sip_poke_all_peers(); 22781 22782 /* Register with all services */ 22783 sip_send_all_registers(); 22784 22785 ast_debug(4, "--------------- SIP reload done\n"); 22786 22787 return 0; 22788 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 22566 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_features(), ast_log(), AST_RTP_DTMF, ast_rtp_setdtmf(), ast_set_flag, ast_test_flag, chan, DSP_FEATURE_DTMF_DETECT, sip_pvt::flags, IS_SIP_TECH, sip_pvt::jointnoncodeccapability, LOG_WARNING, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_DTMF_SHORTINFO, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech, ast_channel::tech_pvt, and sip_pvt::vad.
Referenced by load_module().
22567 { 22568 struct sip_pvt *p; 22569 char *mode = data; 22570 22571 if (!data) { 22572 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 22573 return 0; 22574 } 22575 ast_channel_lock(chan); 22576 if (!IS_SIP_TECH(chan->tech)) { 22577 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 22578 ast_channel_unlock(chan); 22579 return 0; 22580 } 22581 p = chan->tech_pvt; 22582 if (!p) { 22583 ast_channel_unlock(chan); 22584 return 0; 22585 } 22586 sip_pvt_lock(p); 22587 if (!strcasecmp(mode, "info")) { 22588 ast_clear_flag(&p->flags[0], SIP_DTMF); 22589 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 22590 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 22591 } else if (!strcasecmp(mode, "shortinfo")) { 22592 ast_clear_flag(&p->flags[0], SIP_DTMF); 22593 ast_set_flag(&p->flags[0], SIP_DTMF_SHORTINFO); 22594 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 22595 } else if (!strcasecmp(mode, "rfc2833")) { 22596 ast_clear_flag(&p->flags[0], SIP_DTMF); 22597 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 22598 p->jointnoncodeccapability |= AST_RTP_DTMF; 22599 } else if (!strcasecmp(mode, "inband")) { 22600 ast_clear_flag(&p->flags[0], SIP_DTMF); 22601 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 22602 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 22603 } else 22604 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n", mode); 22605 if (p->rtp) 22606 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 22607 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 22608 if (!p->vad) { 22609 p->vad = ast_dsp_new(); 22610 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 22611 } 22612 } else { 22613 if (p->vad) { 22614 ast_dsp_free(p->vad); 22615 p->vad = NULL; 22616 } 22617 } 22618 sip_pvt_unlock(p); 22619 ast_channel_unlock(chan); 22620 return 0; 22621 }
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 14281 of file chan_sip.c.
References ast_debug, AST_LIST_TRAVERSE, ast_log(), sip_pvt::callid, sip_history::event, sip_pvt::history, sip_history::list, LOG_NOTICE, option_debug, and sip_pvt::subscribed.
Referenced by __sip_destroy().
14282 { 14283 int x = 0; 14284 struct sip_history *hist; 14285 static int errmsg = 0; 14286 14287 if (!dialog) 14288 return; 14289 14290 if (!option_debug && !sipdebug) { 14291 if (!errmsg) { 14292 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 14293 errmsg = 1; 14294 } 14295 return; 14296 } 14297 14298 ast_debug(1, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 14299 if (dialog->subscribed) 14300 ast_debug(1, " * Subscription\n"); 14301 else 14302 ast_debug(1, " * SIP Call\n"); 14303 if (dialog->history) 14304 AST_LIST_TRAVERSE(dialog->history, hist, list) 14305 ast_debug(1, " %-3.3d. %s\n", ++x, hist->event); 14306 if (!x) 14307 ast_debug(1, "Call '%s' has no history\n", dialog->callid); 14308 ast_debug(1, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 14309 }
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 5287 of file chan_sip.c.
References append_history, ast_debug, AST_FLAG_ZOMBIE, ast_log(), ast_test_flag, sip_pvt::callid, LOG_WARNING, ast_channel::name, sip_pvt::owner, sip_pvt_lock, sip_pvt_unlock, sip_set_rtp_peer(), and ast_channel::tech_pvt.
05288 { 05289 int ret = -1; 05290 struct sip_pvt *p; 05291 05292 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE)) 05293 ast_debug(1, "New channel is zombie\n"); 05294 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE)) 05295 ast_debug(1, "Old channel is zombie\n"); 05296 05297 if (!newchan || !newchan->tech_pvt) { 05298 if (!newchan) 05299 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 05300 else 05301 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 05302 return -1; 05303 } 05304 p = newchan->tech_pvt; 05305 05306 sip_pvt_lock(p); 05307 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 05308 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 05309 if (p->owner != oldchan) 05310 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 05311 else { 05312 p->owner = newchan; 05313 /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native 05314 RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be 05315 able to do this if the masquerade happens before the bridge breaks (e.g., AMI 05316 redirect of both channels). Note that a channel can not be masqueraded *into* 05317 a native bridge. So there is no danger that this breaks a native bridge that 05318 should stay up. */ 05319 sip_set_rtp_peer(newchan, NULL, NULL, 0, 0, 0); 05320 ret = 0; 05321 } 05322 ast_debug(3, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 05323 05324 sip_pvt_unlock(p); 05325 return ret; 05326 }
static const char * sip_get_callid | ( | struct ast_channel * | chan | ) | [static] |
Deliver SIP call ID for the call.
Definition at line 3507 of file chan_sip.c.
References chan, and ast_channel::tech_pvt.
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 22723 of file chan_sip.c.
References sip_pvt::capability, chan, sip_pvt::peercapability, and ast_channel::tech_pvt.
22724 { 22725 struct sip_pvt *p = chan->tech_pvt; 22726 return p->peercapability ? p->peercapability : p->capability; 22727 }
static enum ast_rtp_get_result sip_get_rtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp ** | rtp | |||
) | [static] |
Returns null if we can't reinvite audio (part of RTP interface).
Definition at line 22400 of file chan_sip.c.
References AST_JB_FORCED, AST_RTP_GET_FAILED, ast_rtp_getnat(), AST_RTP_TRY_NATIVE, AST_RTP_TRY_PARTIAL, ast_test_flag, chan, sip_pvt::flags, global_jbconf, sip_pvt::rtp, SIP_CAN_REINVITE, SIP_CAN_REINVITE_NAT, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.
22401 { 22402 struct sip_pvt *p = NULL; 22403 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 22404 22405 if (!(p = chan->tech_pvt)) 22406 return AST_RTP_GET_FAILED; 22407 22408 sip_pvt_lock(p); 22409 if (!(p->rtp)) { 22410 sip_pvt_unlock(p); 22411 return AST_RTP_GET_FAILED; 22412 } 22413 22414 *rtp = p->rtp; 22415 22416 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 22417 res = AST_RTP_TRY_PARTIAL; 22418 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 22419 res = AST_RTP_TRY_NATIVE; 22420 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 22421 res = AST_RTP_GET_FAILED; 22422 22423 sip_pvt_unlock(p); 22424 22425 return res; 22426 }
static enum ast_rtp_get_result sip_get_trtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp ** | rtp | |||
) | [static] |
Returns null if we can't reinvite text (part of RTP interface).
Definition at line 22454 of file chan_sip.c.
References AST_RTP_GET_FAILED, AST_RTP_TRY_NATIVE, AST_RTP_TRY_PARTIAL, ast_test_flag, chan, sip_pvt::flags, sip_pvt::rtp, SIP_CAN_REINVITE, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and sip_pvt::trtp.
22455 { 22456 struct sip_pvt *p = NULL; 22457 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 22458 22459 if (!(p = chan->tech_pvt)) 22460 return AST_RTP_GET_FAILED; 22461 22462 sip_pvt_lock(p); 22463 if (!(p->trtp)) { 22464 sip_pvt_unlock(p); 22465 return AST_RTP_GET_FAILED; 22466 } 22467 22468 *rtp = p->trtp; 22469 22470 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 22471 res = AST_RTP_TRY_NATIVE; 22472 22473 sip_pvt_unlock(p); 22474 22475 return res; 22476 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 22356 of file chan_sip.c.
References ast_test_flag, chan, sip_pvt::flags, SIP_CAN_REINVITE, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and sip_pvt::udptl.
22357 { 22358 struct sip_pvt *p; 22359 struct ast_udptl *udptl = NULL; 22360 22361 p = chan->tech_pvt; 22362 if (!p) 22363 return NULL; 22364 22365 sip_pvt_lock(p); 22366 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 22367 udptl = p->udptl; 22368 sip_pvt_unlock(p); 22369 return udptl; 22370 }
static enum ast_rtp_get_result sip_get_vrtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp ** | rtp | |||
) | [static] |
Returns null if we can't reinvite video (part of RTP interface).
Definition at line 22429 of file chan_sip.c.
References AST_RTP_GET_FAILED, AST_RTP_TRY_NATIVE, AST_RTP_TRY_PARTIAL, ast_test_flag, chan, sip_pvt::flags, sip_pvt::rtp, SIP_CAN_REINVITE, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and sip_pvt::vrtp.
22430 { 22431 struct sip_pvt *p = NULL; 22432 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 22433 22434 if (!(p = chan->tech_pvt)) 22435 return AST_RTP_GET_FAILED; 22436 22437 sip_pvt_lock(p); 22438 if (!(p->vrtp)) { 22439 sip_pvt_unlock(p); 22440 return AST_RTP_GET_FAILED; 22441 } 22442 22443 *rtp = p->vrtp; 22444 22445 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 22446 res = AST_RTP_TRY_NATIVE; 22447 22448 sip_pvt_unlock(p); 22449 22450 return res; 22451 }
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 4947 of file chan_sip.c.
References __sip_pretend_ack(), ast_channel::_state, sip_pvt::alreadygone, sip_pvt::answered_elsewhere, append_history, ast_cause2str(), ast_clear_flag, ast_debug, ast_dsp_free(), AST_FLAG_ANSWERED_ELSEWHERE, AST_FLAG_ZOMBIE, ast_log(), ast_module_unref(), ast_rtp_get_quality(), AST_SCHED_DEL, ast_set_flag, ast_state2str(), AST_STATE_UP, ast_strlen_zero(), ast_test_flag, sip_pvt::autokillid, sip_pvt::callid, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, dialog_unref(), FALSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, sip_pvt::hangupcause, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, LOG_WARNING, ast_channel::name, sip_pvt::needdestroy, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, sched, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_DEFER_BYE_ON_TRANSFER, SIP_INC_COUNT, SIP_NEEDREINVITE, SIP_OUTGOING, SIP_PAGE2_CALL_ONHOLD, SIP_PENDINGBYE, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), stop_media_flows(), stop_session_timer(), ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, update_call_counter(), sip_pvt::username, sip_pvt::vad, and XMIT_RELIABLE.
04948 { 04949 struct sip_pvt *p = ast->tech_pvt; 04950 int needcancel = FALSE; 04951 int needdestroy = 0; 04952 struct ast_channel *oldowner = ast; 04953 04954 if (!p) { 04955 ast_debug(1, "Asked to hangup channel that was not connected\n"); 04956 return 0; 04957 } 04958 if (ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE)) { 04959 ast_debug(1, "This call was answered elsewhere"); 04960 append_history(p, "Cancel", "Call answered elsewhere"); 04961 p->answered_elsewhere = TRUE; 04962 } 04963 04964 /* Store hangupcause locally in PVT so we still have it before disconnect */ 04965 if (p->owner) 04966 p->hangupcause = p->owner->hangupcause; 04967 04968 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 04969 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 04970 if (sipdebug) 04971 ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 04972 update_call_counter(p, DEC_CALL_LIMIT); 04973 } 04974 ast_debug(4, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 04975 if (p->autokillid > -1 && sip_cancel_destroy(p)) 04976 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 04977 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 04978 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 04979 p->needdestroy = 0; 04980 p->owner->tech_pvt = dialog_unref(p->owner->tech_pvt); 04981 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 04982 return 0; 04983 } 04984 04985 if (ast_test_flag(ast, AST_FLAG_ZOMBIE)) { 04986 if (p->refer) 04987 ast_debug(1, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 04988 else 04989 ast_debug(1, "Hanging up zombie call. Be scared.\n"); 04990 } else 04991 ast_debug(1, "Hangup call %s, SIP callid %s\n", ast->name, p->callid); 04992 04993 sip_pvt_lock(p); 04994 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 04995 if (sipdebug) 04996 ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 04997 update_call_counter(p, DEC_CALL_LIMIT); 04998 } 04999 05000 /* Determine how to disconnect */ 05001 if (p->owner != ast) { 05002 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 05003 sip_pvt_unlock(p); 05004 return 0; 05005 } 05006 /* If the call is not UP, we need to send CANCEL instead of BYE */ 05007 /* In case of re-invites, the call might be UP even though we have an incomplete invite transaction */ 05008 if (p->invitestate < INV_COMPLETED && p->owner->_state != AST_STATE_UP) { 05009 needcancel = TRUE; 05010 ast_debug(4, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 05011 } 05012 05013 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 05014 05015 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->hangupcause) : "Unknown"); 05016 05017 /* Disconnect */ 05018 if (p->vad) 05019 ast_dsp_free(p->vad); 05020 05021 p->owner = NULL; 05022 ast->tech_pvt = dialog_unref(ast->tech_pvt); 05023 05024 ast_module_unref(ast_module_info->self); 05025 /* Do not destroy this pvt until we have timeout or 05026 get an answer to the BYE or INVITE/CANCEL 05027 If we get no answer during retransmit period, drop the call anyway. 05028 (Sorry, mother-in-law, you can't deny a hangup by sending 05029 603 declined to BYE...) 05030 */ 05031 if (p->alreadygone) 05032 needdestroy = 1; /* Set destroy flag at end of this function */ 05033 else if (p->invitestate != INV_CALLING) 05034 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 05035 05036 /* Start the process if it's not already started */ 05037 if (!p->alreadygone && !ast_strlen_zero(p->initreq.data)) { 05038 if (needcancel) { /* Outgoing call, not up */ 05039 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 05040 /* stop retransmitting an INVITE that has not received a response */ 05041 __sip_pretend_ack(p); 05042 05043 /* if we can't send right now, mark it pending */ 05044 if (p->invitestate == INV_CALLING) { 05045 /* We can't send anything in CALLING state */ 05046 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 05047 /* Do we need a timer here if we don't hear from them at all? */ 05048 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 05049 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 05050 } else { 05051 p->invitestate = INV_CANCELLED; 05052 /* Send a new request: CANCEL */ 05053 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 05054 /* Actually don't destroy us yet, wait for the 487 on our original 05055 INVITE, but do set an autodestruct just in case we never get it. */ 05056 needdestroy = 0; 05057 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 05058 } 05059 } else { /* Incoming call, not up */ 05060 const char *res; 05061 if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause))) 05062 transmit_response_reliable(p, res, &p->initreq); 05063 else 05064 transmit_response_reliable(p, "603 Declined", &p->initreq); 05065 p->invitestate = INV_TERMINATED; 05066 } 05067 } else { /* Call is in UP state, send BYE */ 05068 if (p->stimer->st_active == TRUE) { 05069 stop_session_timer(p); 05070 } 05071 05072 if (!p->pendinginvite) { 05073 char *audioqos = ""; 05074 char *videoqos = ""; 05075 char *textqos = ""; 05076 if (p->rtp) 05077 audioqos = ast_rtp_get_quality(p->rtp, NULL); 05078 if (p->vrtp) 05079 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 05080 if (p->trtp) 05081 textqos = ast_rtp_get_quality(p->trtp, NULL); 05082 /* Send a hangup */ 05083 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 05084 05085 /* Get RTCP quality before end of call */ 05086 if (p->do_history) { 05087 if (p->rtp) 05088 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 05089 if (p->vrtp) 05090 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 05091 if (p->trtp) 05092 append_history(p, "RTCPtext", "Quality:%s", textqos); 05093 } 05094 if (p->rtp && oldowner) 05095 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 05096 if (p->vrtp && oldowner) 05097 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 05098 if (p->trtp && oldowner) 05099 pbx_builtin_setvar_helper(oldowner, "RTPTEXTQOS", textqos); 05100 } else { 05101 /* Note we will need a BYE when this all settles out 05102 but we can't send one while we have "INVITE" outstanding. */ 05103 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 05104 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 05105 AST_SCHED_DEL(sched, p->waitid); 05106 if (sip_cancel_destroy(p)) 05107 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 05108 } 05109 } 05110 } 05111 if (needdestroy) 05112 p->needdestroy = 1; 05113 sip_pvt_unlock(p); 05114 return 0; 05115 }
static int sip_indicate | ( | struct ast_channel * | ast, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc.
Definition at line 5398 of file chan_sip.c.
References ast_channel::_state, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_rtp_new_source(), AST_SCHED_DEL, ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, AST_T38_NEGOTIATED, AST_T38_REFUSED, AST_T38_REQUEST_NEGOTIATE, AST_T38_REQUEST_TERMINATE, AST_T38_TERMINATED, ast_test_flag, change_t38_state(), FALSE, sip_pvt::flags, sip_pvt::initreq, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, LOG_ERROR, LOG_WARNING, sip_pvt::mohinterpret, sip_pvt::novideo, sip_pvt::rtp, sched, sip_alreadygone(), SIP_NEEDREINVITE, SIP_OUTGOING, SIP_PAGE2_T38SUPPORT, SIP_PENDINGBYE, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_YES, SIP_PROGRESS_SENT, sip_pvt_lock, sip_pvt_unlock, SIP_RINGING, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_REINVITE, T38_PEER_REINVITE, sip_pvt::t38id, t38properties::t38support, ast_channel::tech_pvt, transmit_info_with_vidupdate(), transmit_reinvite_with_sdp(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), TRUE, sip_pvt::vrtp, XMIT_CRITICAL, and XMIT_UNRELIABLE.
05399 { 05400 struct sip_pvt *p = ast->tech_pvt; 05401 int res = 0; 05402 05403 sip_pvt_lock(p); 05404 switch(condition) { 05405 case AST_CONTROL_RINGING: 05406 if (ast->_state == AST_STATE_RING) { 05407 p->invitestate = INV_EARLY_MEDIA; 05408 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 05409 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 05410 /* Send 180 ringing if out-of-band seems reasonable */ 05411 transmit_response(p, "180 Ringing", &p->initreq); 05412 ast_set_flag(&p->flags[0], SIP_RINGING); 05413 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 05414 break; 05415 } else { 05416 /* Well, if it's not reasonable, just send in-band */ 05417 } 05418 } 05419 res = -1; 05420 break; 05421 case AST_CONTROL_BUSY: 05422 if (ast->_state != AST_STATE_UP) { 05423 transmit_response_reliable(p, "486 Busy Here", &p->initreq); 05424 p->invitestate = INV_COMPLETED; 05425 sip_alreadygone(p); 05426 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 05427 break; 05428 } 05429 res = -1; 05430 break; 05431 case AST_CONTROL_CONGESTION: 05432 if (ast->_state != AST_STATE_UP) { 05433 transmit_response_reliable(p, "503 Service Unavailable", &p->initreq); 05434 p->invitestate = INV_COMPLETED; 05435 sip_alreadygone(p); 05436 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 05437 break; 05438 } 05439 res = -1; 05440 break; 05441 case AST_CONTROL_PROCEEDING: 05442 if ((ast->_state != AST_STATE_UP) && 05443 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 05444 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 05445 transmit_response(p, "100 Trying", &p->initreq); 05446 p->invitestate = INV_PROCEEDING; 05447 break; 05448 } 05449 res = -1; 05450 break; 05451 case AST_CONTROL_PROGRESS: 05452 if ((ast->_state != AST_STATE_UP) && 05453 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 05454 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 05455 p->invitestate = INV_EARLY_MEDIA; 05456 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE, FALSE); 05457 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 05458 break; 05459 } 05460 res = -1; 05461 break; 05462 case AST_CONTROL_HOLD: 05463 ast_rtp_new_source(p->rtp); 05464 ast_moh_start(ast, data, p->mohinterpret); 05465 break; 05466 case AST_CONTROL_UNHOLD: 05467 ast_rtp_new_source(p->rtp); 05468 ast_moh_stop(ast); 05469 break; 05470 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 05471 if (p->vrtp && !p->novideo) { 05472 transmit_info_with_vidupdate(p); 05473 /* ast_rtcp_send_h261fur(p->vrtp); */ 05474 } else 05475 res = -1; 05476 break; 05477 case AST_CONTROL_T38: /* T38 control frame */ 05478 if (datalen != sizeof(enum ast_control_t38)) { 05479 ast_log(LOG_ERROR, "Invalid datalen for AST_CONTROL_T38. Expected %d, got %d\n", (int)sizeof(enum ast_control_t38), (int)datalen); 05480 } else { 05481 switch (*((enum ast_control_t38 *) data)) { 05482 case AST_T38_NEGOTIATED: 05483 case AST_T38_REQUEST_NEGOTIATE: /* Request T38 */ 05484 if (p->t38.state == T38_PEER_REINVITE) { 05485 AST_SCHED_DEL(sched, p->t38id); 05486 change_t38_state(p, T38_ENABLED); 05487 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 05488 } else if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT) && p->t38.state != T38_ENABLED) { 05489 change_t38_state(p, T38_LOCAL_REINVITE); 05490 if (!p->pendinginvite) { 05491 transmit_reinvite_with_sdp(p, TRUE, FALSE); 05492 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 05493 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 05494 } 05495 } 05496 break; 05497 case AST_T38_TERMINATED: 05498 case AST_T38_REFUSED: 05499 case AST_T38_REQUEST_TERMINATE: /* Shutdown T38 */ 05500 if (p->t38.state == T38_PEER_REINVITE) { 05501 AST_SCHED_DEL(sched, p->t38id); 05502 change_t38_state(p, T38_DISABLED); 05503 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 05504 } else if (p->t38.state == T38_ENABLED) 05505 transmit_reinvite_with_sdp(p, FALSE, FALSE); 05506 break; 05507 default: 05508 break; 05509 } 05510 } 05511 break; 05512 case AST_CONTROL_SRCUPDATE: 05513 ast_rtp_new_source(p->rtp); 05514 break; 05515 case -1: 05516 res = -1; 05517 break; 05518 default: 05519 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 05520 res = -1; 05521 break; 05522 } 05523 sip_pvt_unlock(p); 05524 return res; 05525 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 2548 of file chan_sip.c.
References ast_test_flag, sip_pvt::flags, SIP_NAT, and SIP_NAT_ROUTE.
Referenced by check_via(), retrans_pkt(), and send_response().
02549 { 02550 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 02551 }
static struct ast_channel* sip_new | ( | struct sip_pvt * | i, | |
int | state, | |||
const char * | title | |||
) | [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 5533 of file chan_sip.c.
References sip_pvt::accountcode, ast_channel::adsicpe, ast_channel::amaflags, sip_pvt::amaflags, append_history, AST_ADSI_UNAVAILABLE, ast_best_codec(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc, ast_channel_set_fd(), ast_codec_choose(), ast_copy_string(), ast_debug, ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), 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(), buf, sip_pvt::callgroup, ast_channel::callgroup, sip_pvt::callid, sip_pvt::callingpres, sip_pvt::capability, sip_pvt::chanvars, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, sip_pvt::cid_name, sip_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, sip_pvt::context, dialog_ref(), sip_pvt::do_history, sip_pvt::domain, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, EVENT_FLAG_SYSTEM, ast_channel::exten, sip_pvt::exten, sip_pvt::flags, sip_pvt::fromdomain, sip_pvt::fullcontact, global_jbconf, ast_channel::hangupcause, sip_pvt::jointcapability, sip_pvt::language, LOG_WARNING, manager_event, ast_channel::name, ast_variable::name, ast_channel::nativeformats, ast_variable::next, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pickupgroup, ast_channel::pickupgroup, sip_pvt::prefcodec, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, sip_pvt::rdnis, ast_channel::readformat, ast_channel::rings, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_SHORTINFO, sip_pvt_lock, sip_pvt_unlock, sip_tech, sip_tech_info, SIPBUFSIZE, ast_channel::tech, ast_channel::tech_pvt, text, sip_pvt::trtp, sip_pvt::udptl, ast_channel::uniqueid, sip_pvt::uri, sip_pvt::vad, ast_variable::value, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by handle_request_invite(), and sip_request_call().
05534 { 05535 struct ast_channel *tmp; 05536 struct ast_variable *v = NULL; 05537 int fmt; 05538 int what; 05539 int video; 05540 int text; 05541 int needvideo = 0; 05542 int needtext = 0; 05543 char buf[SIPBUFSIZE]; 05544 char *decoded_exten; 05545 05546 { 05547 const char *my_name; /* pick a good name */ 05548 05549 if (title) 05550 my_name = title; 05551 else if ( (my_name = strchr(i->fromdomain, ':')) ) 05552 my_name++; /* skip ':' */ 05553 else 05554 my_name = i->fromdomain; 05555 05556 sip_pvt_unlock(i); 05557 /* Don't hold a sip pvt lock while we allocate a channel */ 05558 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "SIP/%s-%08x", my_name, (int)(long) i); 05559 05560 } 05561 if (!tmp) { 05562 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 05563 sip_pvt_lock(i); 05564 return NULL; 05565 } 05566 sip_pvt_lock(i); 05567 05568 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; 05569 05570 /* Select our native format based on codec preference until we receive 05571 something from another device to the contrary. */ 05572 if (i->jointcapability) { /* The joint capabilities of us and peer */ 05573 what = i->jointcapability; 05574 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 05575 text = i->jointcapability & AST_FORMAT_TEXT_MASK; 05576 } else if (i->capability) { /* Our configured capability for this peer */ 05577 what = i->capability; 05578 video = i->capability & AST_FORMAT_VIDEO_MASK; 05579 text = i->capability & AST_FORMAT_TEXT_MASK; 05580 } else { 05581 what = global_capability; /* Global codec support */ 05582 video = global_capability & AST_FORMAT_VIDEO_MASK; 05583 text = global_capability & AST_FORMAT_TEXT_MASK; 05584 } 05585 05586 /* Set the native formats for audio and merge in video */ 05587 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video | text; 05588 ast_debug(3, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 05589 ast_debug(3, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 05590 ast_debug(3, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 05591 ast_debug(3, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 05592 if (i->prefcodec) 05593 ast_debug(3, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 05594 05595 /* XXX Why are we choosing a codec from the native formats?? */ 05596 fmt = ast_best_codec(tmp->nativeformats); 05597 05598 /* If we have a prefcodec setting, we have an inbound channel that set a 05599 preferred format for this call. Otherwise, we check the jointcapability 05600 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 05601 */ 05602 if (i->vrtp) { 05603 if (i->prefcodec) 05604 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 05605 else 05606 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 05607 } 05608 05609 if (i->trtp) { 05610 if (i->prefcodec) 05611 needtext = i->prefcodec & AST_FORMAT_TEXT_MASK; /* Outbound call */ 05612 else 05613 needtext = i->jointcapability & AST_FORMAT_TEXT_MASK; /* Inbound call */ 05614 } 05615 05616 if (needvideo) 05617 ast_debug(3, "This channel can handle video! HOLLYWOOD next!\n"); 05618 else 05619 ast_debug(3, "This channel will not be able to handle video.\n"); 05620 05621 if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 05622 i->vad = ast_dsp_new(); 05623 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 05624 if (global_relaxdtmf) 05625 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 05626 } 05627 05628 /* Set file descriptors for audio, video, realtime text and UDPTL as needed */ 05629 if (i->rtp) { 05630 ast_channel_set_fd(tmp, 0, ast_rtp_fd(i->rtp)); 05631 ast_channel_set_fd(tmp, 1, ast_rtcp_fd(i->rtp)); 05632 } 05633 if (needvideo && i->vrtp) { 05634 ast_channel_set_fd(tmp, 2, ast_rtp_fd(i->vrtp)); 05635 ast_channel_set_fd(tmp, 3, ast_rtcp_fd(i->vrtp)); 05636 } 05637 if (needtext && i->trtp) 05638 ast_channel_set_fd(tmp, 4, ast_rtp_fd(i->trtp)); 05639 if (i->udptl) 05640 ast_channel_set_fd(tmp, 5, ast_udptl_fd(i->udptl)); 05641 05642 if (state == AST_STATE_RING) 05643 tmp->rings = 1; 05644 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05645 tmp->writeformat = fmt; 05646 tmp->rawwriteformat = fmt; 05647 tmp->readformat = fmt; 05648 tmp->rawreadformat = fmt; 05649 tmp->tech_pvt = dialog_ref(i); 05650 05651 tmp->callgroup = i->callgroup; 05652 tmp->pickupgroup = i->pickupgroup; 05653 tmp->cid.cid_pres = i->callingpres; 05654 if (!ast_strlen_zero(i->accountcode)) 05655 ast_string_field_set(tmp, accountcode, i->accountcode); 05656 if (i->amaflags) 05657 tmp->amaflags = i->amaflags; 05658 if (!ast_strlen_zero(i->language)) 05659 ast_string_field_set(tmp, language, i->language); 05660 i->owner = tmp; 05661 ast_module_ref(ast_module_info->self); 05662 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05663 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 05664 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 05665 * structure so that there aren't issues when forming URI's 05666 */ 05667 decoded_exten = ast_strdupa(i->exten); 05668 ast_uri_decode(decoded_exten); 05669 ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten)); 05670 05671 /* Don't use ast_set_callerid() here because it will 05672 * generate an unnecessary NewCallerID event */ 05673 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05674 if (!ast_strlen_zero(i->rdnis)) 05675 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 05676 05677 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 05678 tmp->cid.cid_dnid = ast_strdup(i->exten); 05679 05680 tmp->priority = 1; 05681 if (!ast_strlen_zero(i->uri)) 05682 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 05683 if (!ast_strlen_zero(i->domain)) 05684 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 05685 if (!ast_strlen_zero(i->callid)) 05686 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 05687 if (i->rtp) 05688 ast_jb_configure(tmp, &global_jbconf); 05689 05690 /* Set channel variables for this call from configuration */ 05691 for (v = i->chanvars ; v ; v = v->next) 05692 pbx_builtin_setvar_helper(tmp, v->name, v->value); 05693 05694 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 05695 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05696 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 05697 ast_hangup(tmp); 05698 tmp = NULL; 05699 } 05700 05701 if (i->do_history) 05702 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 05703 05704 /* Inform manager user about new channel and their SIP call ID */ 05705 if (global_callevents) 05706 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 05707 "Channel: %s\r\nUniqueid: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\n", 05708 tmp->name, tmp->uniqueid, "SIP", i->callid, i->fullcontact); 05709 05710 return tmp; 05711 }
static char * sip_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 14589 of file chan_sip.c.
References add_header(), ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_log(), ast_sip_ouraddrfor(), ast_unescape_semicolon(), ast_variable_browse(), buf, build_callid_pvt(), build_via(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, complete_sipnotify(), create_addr(), DEFAULT_TRANS_TIMEOUT, dialog_unref(), ast_cli_args::fd, initreqprep(), ast_cli_args::line, LOG_WARNING, ast_cli_args::n, notify_types, ast_cli_args::pos, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), ast_cli_entry::usage, var, and ast_cli_args::word.
14590 { 14591 struct ast_variable *varlist; 14592 int i; 14593 14594 switch (cmd) { 14595 case CLI_INIT: 14596 e->command = "sip notify"; 14597 e->usage = 14598 "Usage: sip notify <type> <peer> [<peer>...]\n" 14599 " Send a NOTIFY message to a SIP peer or peers\n" 14600 " Message types are defined in sip_notify.conf\n"; 14601 return NULL; 14602 case CLI_GENERATE: 14603 return complete_sipnotify(a->line, a->word, a->pos, a->n); 14604 } 14605 14606 14607 if (a->argc < 4) 14608 return CLI_SHOWUSAGE; 14609 14610 if (!notify_types) { 14611 ast_cli(a->fd, "No %s file found, or no types listed there\n", notify_config); 14612 return CLI_FAILURE; 14613 } 14614 14615 varlist = ast_variable_browse(notify_types, a->argv[2]); 14616 14617 if (!varlist) { 14618 ast_cli(a->fd, "Unable to find notify type '%s'\n", a->argv[2]); 14619 return CLI_FAILURE; 14620 } 14621 14622 for (i = 3; i < a->argc; i++) { 14623 struct sip_pvt *p; 14624 struct sip_request req; 14625 struct ast_variable *var; 14626 14627 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) { 14628 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 14629 return CLI_FAILURE; 14630 } 14631 14632 if (create_addr(p, a->argv[i], 1)) { 14633 /* Maybe they're not registered, etc. */ 14634 sip_destroy(p); 14635 ast_cli(a->fd, "Could not create address for '%s'\n", a->argv[i]); 14636 continue; 14637 } 14638 14639 initreqprep(&req, p, SIP_NOTIFY); 14640 14641 for (var = varlist; var; var = var->next) { 14642 char buf[512]; 14643 ast_copy_string(buf, var->value, sizeof(buf)); 14644 add_header(&req, var->name, ast_unescape_semicolon(buf)); 14645 } 14646 14647 /* Recalculate our side, and recalculate Call ID */ 14648 ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p); 14649 build_via(p); 14650 build_callid_pvt(p); 14651 ast_cli(a->fd, "Sending NOTIFY of type '%s' to '%s'\n", a->argv[2], a->argv[i]); 14652 transmit_sip_request(p, &req); 14653 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14654 dialog_unref(p); 14655 } 14656 14657 return CLI_SUCCESS; 14658 }
static int sip_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Park a call using the subsystem in res_features.c This is executed in a separate thread.
Definition at line 16400 of file chan_sip.c.
References ast_channel::accountcode, ast_channel::amaflags, ast_calloc, AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc, ast_channel_lock, 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_channel::context, copy_request(), ast_channel::exten, ast_channel::hangupcause, LOG_WARNING, ast_channel::name, 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().
16401 { 16402 struct sip_dual *d; 16403 struct ast_channel *transferee, *transferer; 16404 /* Chan2m: The transferer, chan1m: The transferee */ 16405 pthread_t th; 16406 16407 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 16408 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 16409 if ((!transferer) || (!transferee)) { 16410 if (transferee) { 16411 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 16412 ast_hangup(transferee); 16413 } 16414 if (transferer) { 16415 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 16416 ast_hangup(transferer); 16417 } 16418 return -1; 16419 } 16420 16421 /* Make formats okay */ 16422 transferee->readformat = chan1->readformat; 16423 transferee->writeformat = chan1->writeformat; 16424 16425 /* Prepare for taking over the channel */ 16426 ast_channel_masquerade(transferee, chan1); 16427 16428 /* Setup the extensions and such */ 16429 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 16430 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 16431 transferee->priority = chan1->priority; 16432 16433 /* We make a clone of the peer channel too, so we can play 16434 back the announcement */ 16435 16436 /* Make formats okay */ 16437 transferer->readformat = chan2->readformat; 16438 transferer->writeformat = chan2->writeformat; 16439 16440 /* Prepare for taking over the channel. Go ahead and grab this channel 16441 * lock here to avoid a deadlock with callbacks into the channel driver 16442 * that hold the channel lock and want the pvt lock. */ 16443 while (ast_channel_trylock(chan2)) { 16444 struct sip_pvt *pvt = chan2->tech_pvt; 16445 sip_pvt_unlock(pvt); 16446 usleep(1); 16447 sip_pvt_lock(pvt); 16448 } 16449 ast_channel_masquerade(transferer, chan2); 16450 ast_channel_unlock(chan2); 16451 16452 /* Setup the extensions and such */ 16453 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 16454 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 16455 transferer->priority = chan2->priority; 16456 16457 ast_channel_lock(transferer); 16458 if (ast_do_masquerade(transferer)) { 16459 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 16460 ast_channel_unlock(transferer); 16461 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 16462 ast_hangup(transferer); 16463 return -1; 16464 } 16465 ast_channel_unlock(transferer); 16466 if (!transferer || !transferee) { 16467 if (!transferer) { 16468 ast_debug(1, "No transferer channel, giving up parking\n"); 16469 } 16470 if (!transferee) { 16471 ast_debug(1, "No transferee channel, giving up parking\n"); 16472 } 16473 return -1; 16474 } 16475 if ((d = ast_calloc(1, sizeof(*d)))) { 16476 16477 /* Save original request for followup */ 16478 copy_request(&d->req, req); 16479 d->chan1 = transferee; /* Transferee */ 16480 d->chan2 = transferer; /* Transferer */ 16481 d->seqno = seqno; 16482 if (ast_pthread_create_detached_background(&th, NULL, sip_park_thread, d) < 0) { 16483 /* Could not start thread */ 16484 ast_free(d); /* We don't need it anymore. If thread is created, d will be free'd 16485 by sip_park_thread() */ 16486 return 0; 16487 } 16488 } 16489 return -1; 16490 }
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 16334 of file chan_sip.c.
References append_history, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_debug, ast_do_masquerade(), ast_hangup(), ast_log(), ast_park_call(), buf, sip_dual::chan1, sip_dual::chan2, copy_request(), ext, free, ast_channel::hangupcause, LOG_ERROR, LOG_WARNING, ast_channel::name, sip_dual::req, sip_dual::seqno, ast_channel::tech_pvt, transmit_message_with_text(), transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by sip_park().
16335 { 16336 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 16337 struct sip_dual *d; 16338 struct sip_request req; 16339 int ext; 16340 int res; 16341 16342 d = stuff; 16343 transferee = d->chan1; 16344 transferer = d->chan2; 16345 copy_request(&req, &d->req); 16346 16347 if (!transferee || !transferer) { 16348 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 16349 free(d); 16350 return NULL; 16351 } 16352 ast_debug(4, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 16353 16354 ast_channel_lock(transferee); 16355 if (ast_do_masquerade(transferee)) { 16356 ast_log(LOG_WARNING, "Masquerade failed.\n"); 16357 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 16358 ast_channel_unlock(transferee); 16359 free(d); 16360 return NULL; 16361 } 16362 ast_channel_unlock(transferee); 16363 16364 res = ast_park_call(transferee, transferer, 0, &ext); 16365 16366 16367 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 16368 if (!res) { 16369 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 16370 } else { 16371 /* Then tell the transferer what happened */ 16372 sprintf(buf, "Call parked on extension '%d'", ext); 16373 transmit_message_with_text(transferer->tech_pvt, buf); 16374 } 16375 #endif 16376 16377 /* Any way back to the current call??? */ 16378 /* Transmit response to the REFER request */ 16379 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 16380 if (!res) { 16381 /* Transfer succeeded */ 16382 append_history(transferer->tech_pvt, "SIPpark", "Parked call on %d", ext); 16383 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 16384 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 16385 ast_hangup(transferer); /* This will cause a BYE */ 16386 ast_debug(1, "SIP Call parked on extension '%d'\n", ext); 16387 } else { 16388 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 16389 append_history(transferer->tech_pvt, "SIPpark", "Parking failed\n"); 16390 ast_debug(1, "SIP Call parked failed \n"); 16391 /* Do not hangup call */ 16392 } 16393 free(d); 16394 return NULL; 16395 }
static int sip_parse_host | ( | char * | line, | |
int | lineno, | |||
char ** | hostname, | |||
int * | portnum, | |||
enum sip_transport * | transport | |||
) | [static] |
Small function to parse a config line for a host with a transport i.e. tls://www.google.com:8056.
Definition at line 19519 of file chan_sip.c.
References ast_log(), LOG_NOTICE, SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, STANDARD_SIP_PORT, and STANDARD_TLS_PORT.
Referenced by sip_register().
19520 { 19521 char *port; 19522 19523 if ((*hostname = strstr(line, "://"))) { 19524 *hostname += 3; 19525 19526 if (!strncasecmp(line, "tcp", 3)) 19527 *transport = SIP_TRANSPORT_TCP; 19528 else if (!strncasecmp(line, "tls", 3)) 19529 *transport = SIP_TRANSPORT_TLS; 19530 else if (!strncasecmp(line, "udp", 3)) 19531 *transport = SIP_TRANSPORT_UDP; 19532 else 19533 ast_log(LOG_NOTICE, "'%.3s' is not a valid transport type on line %d of sip.conf. defaulting to udp.\n", line, lineno); 19534 } else { 19535 *hostname = line; 19536 *transport = SIP_TRANSPORT_UDP; 19537 } 19538 19539 if ((line = strrchr(*hostname, '@'))) 19540 line++; 19541 else 19542 line = *hostname; 19543 19544 if ((port = strrchr(line, ':'))) { 19545 *port++ = '\0'; 19546 19547 if (!sscanf(port, "%u", portnum)) { 19548 ast_log(LOG_NOTICE, "'%s' is not a valid port number on line %d of sip.conf. using default.\n", port, lineno); 19549 port = NULL; 19550 } 19551 } 19552 19553 if (!port) { 19554 if (*transport & SIP_TRANSPORT_TLS) { 19555 *portnum = STANDARD_TLS_PORT; 19556 } else { 19557 *portnum = STANDARD_SIP_PORT; 19558 } 19559 } 19560 19561 return 0; 19562 }
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 10812 of file chan_sip.c.
References ast_atomic_fetchadd_int(), ast_device_state_changed(), find_peer(), sip_peer::name, sip_peer::onHold, and sip_pvt::peername.
Referenced by process_sdp(), and update_call_counter().
10813 { 10814 struct sip_peer *peer = find_peer(p->peername, NULL, 1, 0); 10815 10816 if (!peer) 10817 return; 10818 10819 /* If they put someone on hold, increment the value... otherwise decrement it */ 10820 ast_atomic_fetchadd_int(&peer->onHold, (hold ? +1 : -1)); 10821 10822 /* Request device state update */ 10823 ast_device_state_changed("SIP/%s", peer->name); 10824 10825 return; 10826 }
static void sip_poke_all_peers | ( | void | ) | [static] |
Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions?
Definition at line 22733 of file chan_sip.c.
References AST_SCHED_REPLACE, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, peerl, sched, and sip_poke_peer_s().
Referenced by load_module(), and sip_do_reload().
22734 { 22735 int ms = 0; 22736 22737 if (!speerobjs) /* No peers, just give up */ 22738 return; 22739 22740 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 22741 ASTOBJ_WRLOCK(iterator); 22742 ms += 100; 22743 AST_SCHED_REPLACE(iterator->pokeexpire, sched, ms, sip_poke_peer_s, iterator); 22744 ASTOBJ_UNLOCK(iterator); 22745 } while (0) 22746 ); 22747 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 20163 of file chan_sip.c.
References ast_check_realtime(), ast_device_state_changed(), ast_log(), AST_SCHED_REPLACE, ast_update_realtime(), sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, FALSE, sip_peer::lastms, LOG_NOTICE, manager_event, sip_peer::name, sip_settings::peer_rtupdate, sip_peer::pokeexpire, register_peer_exten(), sched, sip_cfg, sip_destroy(), and sip_poke_peer_s().
Referenced by sip_poke_peer().
20164 { 20165 struct sip_peer *peer = (struct sip_peer *)data; 20166 20167 peer->pokeexpire = -1; 20168 if (peer->lastms > -1) { 20169 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 20170 if (sip_cfg.peer_rtupdate) { 20171 ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", "-1", NULL); 20172 } 20173 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 20174 if (global_regextenonqualify) { 20175 register_peer_exten(peer, FALSE); 20176 } 20177 } 20178 if (peer->call) 20179 peer->call = sip_destroy(peer->call); 20180 peer->lastms = -1; 20181 ast_device_state_changed("SIP/%s", peer->name); 20182 /* Try again quickly */ 20183 AST_SCHED_REPLACE(peer->pokeexpire, sched, 20184 DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 20185 return 0; 20186 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 20191 of file chan_sip.c.
References sip_peer::addr, ast_copy_flags, ast_copy_string(), ast_inet_ntoa(), ast_log(), AST_SCHED_DEL, AST_SCHED_REPLACE, ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_set, ast_strlen_zero(), ast_tvnow(), build_callid_pvt(), build_via(), sip_peer::call, copy_socket_data(), sip_peer::flags, sip_pvt::flags, sip_peer::fullcontact, sip_peer::lastms, LOG_NOTICE, sip_peer::maxms, sip_pvt::ourip, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::recv, sip_pvt::relatedpeer, sip_pvt::sa, sched, sip_alloc(), sip_destroy(), SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_FLAGS_TO_COPY, sip_poke_noanswer(), sip_peer::socket, sip_pvt::socket, sip_peer::tohost, transmit_invite(), sip_pvt::username, and XMIT_ERROR.
Referenced by build_peer(), parse_register_contact(), reg_source_db(), and sip_poke_peer_s().
20192 { 20193 struct sip_pvt *p; 20194 int xmitres = 0; 20195 20196 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 20197 /* IF we have no IP, or this isn't to be monitored, return 20198 immediately after clearing things out */ 20199 AST_SCHED_DEL(sched, peer->pokeexpire); 20200 peer->lastms = 0; 20201 peer->call = NULL; 20202 return 0; 20203 } 20204 if (peer->call) { 20205 if (sipdebug) 20206 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 20207 peer->call = sip_destroy(peer->call); 20208 } 20209 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS, NULL))) 20210 return -1; 20211 20212 p->sa = peer->addr; 20213 p->recv = peer->addr; 20214 copy_socket_data(&p->socket, &peer->socket); 20215 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 20216 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 20217 20218 /* Send OPTIONs to peer's fullcontact */ 20219 if (!ast_strlen_zero(peer->fullcontact)) 20220 ast_string_field_set(p, fullcontact, peer->fullcontact); 20221 20222 if (!ast_strlen_zero(peer->tohost)) 20223 ast_string_field_set(p, tohost, peer->tohost); 20224 else 20225 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 20226 20227 /* Recalculate our side, and recalculate Call ID */ 20228 ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p); 20229 build_via(p); 20230 build_callid_pvt(p); 20231 20232 AST_SCHED_DEL(sched, peer->pokeexpire); 20233 p->relatedpeer = peer; 20234 ast_set_flag(&p->flags[0], SIP_OUTGOING); 20235 #ifdef VOCAL_DATA_HACK 20236 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 20237 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 20238 #else 20239 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 20240 #endif 20241 peer->ps = ast_tvnow(); 20242 if (xmitres == XMIT_ERROR) 20243 sip_poke_noanswer(peer); /* Immediately unreachable, network problems */ 20244 else { 20245 AST_SCHED_REPLACE(peer->pokeexpire, sched, 20246 peer->maxms * 2, sip_poke_noanswer, peer); 20247 } 20248 20249 return 0; 20250 }
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 10177 of file chan_sip.c.
References sip_peer::pokeexpire, and sip_poke_peer().
Referenced by handle_response_peerpoke(), reg_source_db(), sip_poke_all_peers(), and sip_poke_noanswer().
10178 { 10179 struct sip_peer *peer = (struct sip_peer *)data; 10180 10181 peer->pokeexpire = -1; 10182 sip_poke_peer(peer); 10183 return 0; 10184 }
static int sip_prepare_socket | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 19441 of file chan_sip.c.
References server_args::accept_fd, ao2_ref(), ast_calloc, ast_copy_string(), ast_debug, ast_free, ast_pthread_create_background, ast_strlen_zero(), ast_tcptls_client_start(), default_tls_cfg, ast_tcptls_session_instance::fd, server_args::hostname, server_args::master, server_args::name, name, sip_pvt::outboundproxy, s, server_args::sin, sip_real_dst(), sip_tcp_locate(), sip_tcp_worker_fn(), SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, sipsock, sip_pvt::socket, server_args::tls_cfg, sip_pvt::tohost, and sip_proxy::transport.
Referenced by __sip_xmit().
19442 { 19443 struct sip_socket *s = &p->socket; 19444 static const char name[] = "SIP socket"; 19445 struct ast_tcptls_session_instance *tcptls_session; 19446 struct server_args ca = { 19447 .name = name, 19448 .accept_fd = -1, 19449 }; 19450 19451 if (s->fd != -1) 19452 return s->fd; 19453 19454 if (p->outboundproxy && p->outboundproxy->transport) { 19455 s->type = p->outboundproxy->transport; 19456 } 19457 19458 if (s->type & SIP_TRANSPORT_UDP) { 19459 s->fd = sipsock; 19460 return s->fd; 19461 } 19462 19463 ca.sin = *(sip_real_dst(p)); 19464 19465 if ((tcptls_session = sip_tcp_locate(&ca.sin))) { 19466 s->fd = tcptls_session->fd; 19467 if (s->tcptls_session) { 19468 ao2_ref(s->tcptls_session, -1); 19469 s->tcptls_session = NULL; 19470 } 19471 s->tcptls_session = tcptls_session; 19472 return s->fd; 19473 } 19474 19475 if (s->tcptls_session && s->tcptls_session->parent->tls_cfg) { 19476 ca.tls_cfg = s->tcptls_session->parent->tls_cfg; 19477 } else { 19478 if (s->type & SIP_TRANSPORT_TLS) { 19479 ca.tls_cfg = ast_calloc(1, sizeof(*ca.tls_cfg)); 19480 if (!ca.tls_cfg) 19481 return -1; 19482 memcpy(ca.tls_cfg, &default_tls_cfg, sizeof(*ca.tls_cfg)); 19483 if (!ast_strlen_zero(p->tohost)) 19484 ast_copy_string(ca.hostname, p->tohost, sizeof(ca.hostname)); 19485 } 19486 } 19487 19488 if (s->tcptls_session) { 19489 /* the pvt socket already has a server instance ... */ 19490 } else { 19491 s->tcptls_session = ast_tcptls_client_start(&ca); /* Start a client connection to this address */ 19492 } 19493 19494 if (!s->tcptls_session) { 19495 if (ca.tls_cfg) 19496 ast_free(ca.tls_cfg); 19497 return -1; 19498 } 19499 19500 s->fd = ca.accept_fd; 19501 19502 /* Give the new thread a reference */ 19503 ao2_ref(s->tcptls_session, +1); 19504 19505 if (ast_pthread_create_background(&ca.master, NULL, sip_tcp_worker_fn, s->tcptls_session)) { 19506 ast_debug(1, "Unable to launch '%s'.", ca.name); 19507 ao2_ref(s->tcptls_session, -1); 19508 close(ca.accept_fd); 19509 s->fd = ca.accept_fd = -1; 19510 } 19511 19512 return s->fd; 19513 }
static char * sip_prune_realtime | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 12980 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, complete_sip_peer(), complete_sip_user(), FALSE, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, name, peerl, ast_cli_args::pos, sip_destroy_peer(), SIP_PAGE2_RTCACHEFRIENDS, strcasestr(), TRUE, ast_cli_entry::usage, and ast_cli_args::word.
12981 { 12982 struct sip_peer *peer; 12983 struct sip_user *user; 12984 int pruneuser = FALSE; 12985 int prunepeer = FALSE; 12986 int multi = FALSE; 12987 char *name = NULL; 12988 regex_t regexbuf; 12989 12990 if (cmd == CLI_INIT) { 12991 e->command = "sip prune realtime [peer|user|all] [all|like]"; 12992 e->usage = 12993 "Usage: sip prune realtime [peer|user] [<name>|all|like <pattern>]\n" 12994 " Prunes object(s) from the cache.\n" 12995 " Optional regular expression pattern is used to filter the objects.\n"; 12996 return NULL; 12997 } else if (cmd == CLI_GENERATE) { 12998 if (a->pos == 4) { 12999 if (strcasestr(a->line, "realtime peer")) 13000 return complete_sip_peer(a->word, a->n, SIP_PAGE2_RTCACHEFRIENDS); 13001 else if (strcasestr(a->line, "realtime user")) 13002 return complete_sip_user(a->word, a->n, SIP_PAGE2_RTCACHEFRIENDS); 13003 } 13004 return NULL; 13005 } 13006 switch (a->argc) { 13007 case 4: 13008 name = a->argv[3]; 13009 /* we accept a name in position 3, but keywords are not good. */ 13010 if (!strcasecmp(name, "user") || !strcasecmp(name, "peer") || 13011 !strcasecmp(name, "like")) 13012 return CLI_SHOWUSAGE; 13013 pruneuser = prunepeer = TRUE; 13014 if (!strcasecmp(name, "all")) { 13015 multi = TRUE; 13016 name = NULL; 13017 } 13018 /* else a single name, already set */ 13019 break; 13020 case 5: 13021 /* sip prune realtime {user|peer|like} name */ 13022 name = a->argv[4]; 13023 if (!strcasecmp(a->argv[3], "user")) 13024 pruneuser = TRUE; 13025 else if (!strcasecmp(a->argv[3], "peer")) 13026 prunepeer = TRUE; 13027 else if (!strcasecmp(a->argv[3], "like")) { 13028 pruneuser = prunepeer = TRUE; 13029 multi = TRUE; 13030 } else 13031 return CLI_SHOWUSAGE; 13032 if (!strcasecmp(a->argv[4], "like")) 13033 return CLI_SHOWUSAGE; 13034 if (!multi && !strcasecmp(a->argv[4], "all")) { 13035 multi = TRUE; 13036 name = NULL; 13037 } 13038 break; 13039 case 6: 13040 name = a->argv[5]; 13041 multi = TRUE; 13042 /* sip prune realtime {user|peer} like name */ 13043 if (strcasecmp(a->argv[4], "like")) 13044 return CLI_SHOWUSAGE; 13045 if (!strcasecmp(a->argv[3], "user")) { 13046 pruneuser = TRUE; 13047 } else if (!strcasecmp(a->argv[3], "peer")) { 13048 prunepeer = TRUE; 13049 } else 13050 return CLI_SHOWUSAGE; 13051 break; 13052 default: 13053 return CLI_SHOWUSAGE; 13054 } 13055 13056 if (multi && name) { 13057 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 13058 return CLI_SHOWUSAGE; 13059 } 13060 13061 if (multi) { 13062 if (prunepeer) { 13063 int pruned = 0; 13064 13065 ASTOBJ_CONTAINER_WRLOCK(&peerl); 13066 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 13067 ASTOBJ_RDLOCK(iterator); 13068 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 13069 ASTOBJ_UNLOCK(iterator); 13070 continue; 13071 }; 13072 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 13073 ASTOBJ_MARK(iterator); 13074 pruned++; 13075 } 13076 ASTOBJ_UNLOCK(iterator); 13077 } while (0) ); 13078 if (pruned) { 13079 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 13080 ast_cli(a->fd, "%d peers pruned.\n", pruned); 13081 } else 13082 ast_cli(a->fd, "No peers found to prune.\n"); 13083 ASTOBJ_CONTAINER_UNLOCK(&peerl); 13084 } 13085 if (pruneuser) { 13086 int pruned = 0; 13087 13088 ASTOBJ_CONTAINER_WRLOCK(&userl); 13089 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 13090 ASTOBJ_RDLOCK(iterator); 13091 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 13092 ASTOBJ_UNLOCK(iterator); 13093 continue; 13094 }; 13095 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 13096 ASTOBJ_MARK(iterator); 13097 pruned++; 13098 } 13099 ASTOBJ_UNLOCK(iterator); 13100 } while (0) ); 13101 if (pruned) { 13102 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 13103 ast_cli(a->fd, "%d users pruned.\n", pruned); 13104 } else 13105 ast_cli(a->fd, "No users found to prune.\n"); 13106 ASTOBJ_CONTAINER_UNLOCK(&userl); 13107 } 13108 } else { 13109 if (prunepeer) { 13110 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 13111 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 13112 ast_cli(a->fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 13113 ASTOBJ_CONTAINER_LINK(&peerl, peer); 13114 } else 13115 ast_cli(a->fd, "Peer '%s' pruned.\n", name); 13116 unref_peer(peer); 13117 } else 13118 ast_cli(a->fd, "Peer '%s' not found.\n", name); 13119 } 13120 if (pruneuser) { 13121 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 13122 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 13123 ast_cli(a->fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 13124 ASTOBJ_CONTAINER_LINK(&userl, user); 13125 } else 13126 ast_cli(a->fd, "User '%s' pruned.\n", name); 13127 unref_user(user); 13128 } else 13129 ast_cli(a->fd, "User '%s' not found.\n", name); 13130 } 13131 } 13132 13133 return CLI_SUCCESS; 13134 }
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 3274 of file chan_sip.c.
References ast_log(), AST_OPTION_T38_STATE, ast_test_flag, chan, LOG_ERROR, SIP_PAGE2_T38SUPPORT, sip_pvt_lock, sip_pvt_unlock, t38properties::state, sip_pvt::t38, T38_ENABLED, T38_LOCAL_REINVITE, T38_PEER_DIRECT, T38_PEER_REINVITE, T38_STATE_NEGOTIATED, T38_STATE_NEGOTIATING, T38_STATE_UNAVAILABLE, T38_STATE_UNKNOWN, t38properties::t38support, and ast_channel::tech_pvt.
03275 { 03276 int res = -1; 03277 enum ast_t38_state state = T38_STATE_UNAVAILABLE; 03278 struct sip_pvt *p = (struct sip_pvt *) chan->tech_pvt; 03279 03280 switch (option) { 03281 case AST_OPTION_T38_STATE: 03282 /* Make sure we got an ast_t38_state enum passed in */ 03283 if (*datalen != sizeof(enum ast_t38_state)) { 03284 ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option. Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen); 03285 return -1; 03286 } 03287 03288 sip_pvt_lock(p); 03289 03290 /* 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 */ 03291 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT)) { 03292 switch (p->t38.state) { 03293 case T38_LOCAL_REINVITE: 03294 case T38_PEER_DIRECT: 03295 case T38_PEER_REINVITE: 03296 state = T38_STATE_NEGOTIATING; 03297 break; 03298 case T38_ENABLED: 03299 state = T38_STATE_NEGOTIATED; 03300 break; 03301 default: 03302 state = T38_STATE_UNKNOWN; 03303 } 03304 } 03305 03306 sip_pvt_unlock(p); 03307 03308 *((enum ast_t38_state *) data) = state; 03309 res = 0; 03310 03311 break; 03312 default: 03313 break; 03314 } 03315 03316 return res; 03317 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
Read SIP RTP from channel.
Definition at line 5929 of file chan_sip.c.
References ast_channel::_state, ast_bridged_channel(), ast_debug, AST_FRAME_VOICE, ast_null_frame, ast_set_flag, AST_STATE_UP, ast_test_flag, change_t38_state(), FALSE, sip_pvt::flags, ast_frame::frametype, INV_EARLY_MEDIA, sip_pvt::invitestate, sip_pvt::lastrtprx, ast_channel::name, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PENDINGBYE, sip_pvt_lock, sip_pvt_unlock, sip_rtp_read(), t38properties::state, sip_pvt::t38, T38_DISABLED, T38_LOCAL_REINVITE, t38properties::t38support, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), and TRUE.
05930 { 05931 struct ast_frame *fr; 05932 struct sip_pvt *p = ast->tech_pvt; 05933 int faxdetected = FALSE; 05934 05935 sip_pvt_lock(p); 05936 fr = sip_rtp_read(ast, p, &faxdetected); 05937 p->lastrtprx = time(NULL); 05938 05939 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 05940 /* If we are bridged then it is the responsibility of the SIP device to issue T38 re-invite if it detects CNG or fax preamble */ 05941 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 05942 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 05943 if (!p->pendinginvite) { 05944 ast_debug(3, "Sending reinvite on SIP (%s) for T.38 negotiation.\n", ast->name); 05945 change_t38_state(p, T38_LOCAL_REINVITE); 05946 transmit_reinvite_with_sdp(p, TRUE, FALSE); 05947 } 05948 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 05949 ast_debug(3, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 05950 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 05951 } 05952 } 05953 05954 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 05955 if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 05956 fr = &ast_null_frame; 05957 } 05958 05959 sip_pvt_unlock(p); 05960 05961 return fr; 05962 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static] |
The real destination address for a write.
Definition at line 2539 of file chan_sip.c.
References ast_test_flag, sip_pvt::flags, sip_proxy::ip, sip_pvt::outboundproxy, sip_pvt::recv, sip_pvt::sa, SIP_NAT, and SIP_NAT_ROUTE.
Referenced by __sip_xmit(), check_via(), retrans_pkt(), send_response(), show_channels_cb(), sip_debug_test_pvt(), and sip_prepare_socket().
02540 { 02541 if (p->outboundproxy) 02542 return &p->outboundproxy->ip; 02543 02544 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 02545 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 9948 of file chan_sip.c.
References ast_calloc, and sip_pvt::refer.
Referenced by get_also_info(), handle_request_invite(), handle_request_refer(), and transmit_refer().
09949 { 09950 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 09951 return p->refer ? 1 : 0; 09952 }
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 9672 of file chan_sip.c.
References __sip_pretend_ack(), ast_log(), sip_registry::call, dialog_unref(), EVENT_FLAG_SYSTEM, sip_registry::hostname, LOG_NOTICE, manager_event, sip_pvt::needdestroy, REG_STATE_FAILED, REG_STATE_UNREGISTERED, sip_registry::regattempts, sip_pvt::registry, registry_addref(), registry_unref(), sip_registry::regstate, regstate2str(), sip_pvt_lock, sip_pvt_unlock, SIP_REGISTER, sip_registry::timeout, transmit_register(), and sip_registry::username.
Referenced by transmit_register().
09673 { 09674 09675 /* if we are here, our registration timed out, so we'll just do it over */ 09676 struct sip_registry *r = registry_addref((struct sip_registry *) data); 09677 struct sip_pvt *p; 09678 int res; 09679 09680 /* if we couldn't get a reference to the registry object, punt */ 09681 if (!r) 09682 return 0; 09683 09684 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 09685 /* If the initial tranmission failed, we may not have an existing dialog, 09686 * so it is possible that r->call == NULL. 09687 * Otherwise destroy it, as we have a timeout so we don't want it. 09688 */ 09689 if (r->call) { 09690 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 09691 in the single SIP manager thread. */ 09692 p = r->call; 09693 sip_pvt_lock(p); 09694 p->needdestroy = 1; 09695 /* Pretend to ACK anything just in case */ 09696 __sip_pretend_ack(p); 09697 sip_pvt_unlock(p); 09698 09699 /* decouple the two objects */ 09700 /* p->registry == r, so r has 2 refs, and the unref won't take the object away */ 09701 if (p->registry) 09702 p->registry = registry_unref(p->registry); 09703 r->call = dialog_unref(r->call); 09704 } 09705 /* If we have a limit, stop registration and give up */ 09706 if (global_regattempts_max && r->regattempts > global_regattempts_max) { 09707 /* Ok, enough is enough. Don't try any more */ 09708 /* We could add an external notification here... 09709 steal it from app_voicemail :-) */ 09710 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 09711 r->regstate = REG_STATE_FAILED; 09712 } else { 09713 r->regstate = REG_STATE_UNREGISTERED; 09714 r->timeout = -1; 09715 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 09716 } 09717 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)); 09718 registry_unref(r); 09719 return 0; 09720 }
static int sip_register | ( | const char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 6323 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_free, ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, sip_registry::authuser, buf, sip_registry::callback, FALSE, hostname, INITIAL_CSEQ, LOG_ERROR, LOG_WARNING, registry_unref(), regl, sip_parse_host(), SIP_TRANSPORT_UDP, and sip_registry::transport.
Referenced by build_peer().
06324 { 06325 struct sip_registry *reg; 06326 int portnum = 0; 06327 enum sip_transport transport = SIP_TRANSPORT_UDP; 06328 char buf[256] = ""; 06329 char *username = NULL; 06330 char *port = NULL; 06331 char *hostname=NULL, *secret=NULL, *authuser=NULL; 06332 char *callback=NULL; 06333 06334 if (!value) 06335 return -1; 06336 06337 ast_copy_string(buf, value, sizeof(buf)); 06338 06339 sip_parse_host(buf, lineno, &username, &portnum, &transport); 06340 06341 /* First split around the last '@' then parse the two components. */ 06342 hostname = strrchr(username, '@'); /* allow @ in the first part */ 06343 if (hostname) 06344 *hostname++ = '\0'; 06345 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 06346 ast_log(LOG_WARNING, "Format for registration is [transport://]user[@domain][:secret[:authuser]]@host[:port][/extension] at line %d\n", lineno); 06347 return -1; 06348 } 06349 /* split user[:secret[:authuser]] */ 06350 secret = strchr(username, ':'); 06351 if (secret) { 06352 *secret++ = '\0'; 06353 authuser = strchr(secret, ':'); 06354 if (authuser) 06355 *authuser++ = '\0'; 06356 } 06357 06358 /* split host[:port][/contact] */ 06359 callback = strchr(hostname, '/'); 06360 if (callback) 06361 *callback++ = '\0'; 06362 if (ast_strlen_zero(callback)) 06363 callback = "s"; 06364 /* Separate host from port when checking for reserved characters 06365 */ 06366 if ((port = strchr(hostname, ':'))) { 06367 *port = '\0'; 06368 } 06369 /* And then re-merge the host and port so they are stored correctly 06370 */ 06371 if (port) { 06372 *port = ':'; 06373 } 06374 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 06375 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 06376 return -1; 06377 } 06378 06379 if (ast_string_field_init(reg, 256)) { 06380 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 06381 ast_free(reg); 06382 return -1; 06383 } 06384 06385 regobjs++; 06386 ASTOBJ_INIT(reg); 06387 ast_string_field_set(reg, callback, callback); 06388 if (!ast_strlen_zero(username)) 06389 ast_string_field_set(reg, username, username); 06390 if (hostname) 06391 ast_string_field_set(reg, hostname, hostname); 06392 if (authuser) 06393 ast_string_field_set(reg, authuser, authuser); 06394 if (secret) 06395 ast_string_field_set(reg, secret, secret); 06396 reg->transport = transport; 06397 reg->expire = -1; 06398 reg->expiry = default_expiry; 06399 reg->timeout = -1; 06400 reg->refresh = default_expiry; 06401 reg->portno = portnum; 06402 reg->callid_valid = FALSE; 06403 reg->ocseq = INITIAL_CSEQ; 06404 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 06405 registry_unref(reg); /* release the reference given by ASTOBJ_INIT. The container has another reference */ 06406 return 0; 06407 }
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 4439 of file chan_sip.c.
References ast_debug, ast_free, AST_SCHED_DEL, ast_string_field_free_memory, sip_registry::call, sip_registry::expire, sip_registry::hostname, sip_pvt::registry, sched, sip_destroy(), sip_registry::timeout, and sip_registry::username.
Referenced by registry_unref(), reload_config(), and unload_module().
04440 { 04441 /* Really delete */ 04442 ast_debug(3, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 04443 04444 if (reg->call) { 04445 /* Clear registry before destroying to ensure 04446 we don't get reentered trying to grab the registry lock */ 04447 reg->call->registry = NULL; 04448 ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 04449 reg->call = sip_destroy(reg->call); 04450 } 04451 AST_SCHED_DEL(sched, reg->expire); 04452 AST_SCHED_DEL(sched, reg->timeout); 04453 ast_string_field_free_memory(reg); 04454 regobjs--; 04455 ast_free(reg); 04456 04457 }
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 15319 of file chan_sip.c.
References ast_set_flag, check_pendings(), dialog_unref(), SIP_NEEDREINVITE, sip_pvt_lock, and sip_pvt_unlock.
Referenced by handle_response_invite().
15320 { 15321 struct sip_pvt *p = (struct sip_pvt *) data; 15322 sip_pvt_lock(p); /* called from schedule thread which requires a lock */ 15323 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 15324 p->waitid = -1; 15325 check_pendings(p); 15326 sip_pvt_unlock(p); 15327 dialog_unref(p); 15328 return 0; 15329 }
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 22791 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, TRUE, and ast_cli_entry::usage.
Referenced by reload().
22792 { 22793 22794 switch (cmd) { 22795 case CLI_INIT: 22796 e->command = "sip reload"; 22797 e->usage = 22798 "Usage: sip reload\n" 22799 " Reloads SIP configuration from sip.conf\n"; 22800 return NULL; 22801 case CLI_GENERATE: 22802 return NULL; 22803 } 22804 22805 ast_mutex_lock(&sip_reload_lock); 22806 if (sip_reloading) 22807 ast_verbose("Previous SIP reload not yet done\n"); 22808 else { 22809 sip_reloading = TRUE; 22810 sip_reloadreason = (a && a->fd) ? CHANNEL_CLI_RELOAD : CHANNEL_MODULE_RELOAD; 22811 } 22812 ast_mutex_unlock(&sip_reload_lock); 22813 restart_monitor(); 22814 22815 return CLI_SUCCESS; 22816 }
static struct ast_channel * sip_request_call | ( | const char * | type, | |
int | format, | |||
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 20364 of file chan_sip.c.
References ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_string(), ast_debug, AST_FORMAT_AUDIO_MASK, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_callid_pvt(), build_via(), create_addr(), EVENT_FLAG_SYSTEM, ext, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, sip_pvt::options, sip_pvt::outgoing_call, sip_pvt::peername, restart_monitor(), set_socket_transport(), sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), sip_pvt_lock, sip_pvt_unlock, SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, sip_pvt::socket, and TRUE.
20365 { 20366 struct sip_pvt *p; 20367 struct ast_channel *tmpc = NULL; 20368 char *ext = NULL, *host; 20369 char tmp[256]; 20370 char *dest = data; 20371 char *dnid; 20372 char *secret = NULL; 20373 char *md5secret = NULL; 20374 char *authname = NULL; 20375 char *trans = NULL; 20376 enum sip_transport transport = 0; 20377 int oldformat = format; 20378 20379 /* mask request with some set of allowed formats. 20380 * XXX this needs to be fixed. 20381 * The original code uses AST_FORMAT_AUDIO_MASK, but it is 20382 * unclear what to use here. We have global_capabilities, which is 20383 * configured from sip.conf, and sip_tech.capabilities, which is 20384 * hardwired to all audio formats. 20385 */ 20386 format &= AST_FORMAT_AUDIO_MASK; 20387 if (!format) { 20388 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format %s while capability is %s\n", ast_getformatname(oldformat), ast_getformatname(global_capability)); 20389 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 20390 return NULL; 20391 } 20392 ast_debug(1, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 20393 20394 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE, NULL))) { 20395 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", dest); 20396 *cause = AST_CAUSE_SWITCH_CONGESTION; 20397 return NULL; 20398 } 20399 20400 p->outgoing_call = TRUE; 20401 20402 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 20403 sip_destroy(p); 20404 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 20405 *cause = AST_CAUSE_SWITCH_CONGESTION; 20406 return NULL; 20407 } 20408 20409 /* Save the destination, the SIP dial string */ 20410 ast_copy_string(tmp, dest, sizeof(tmp)); 20411 20412 20413 /* Find DNID and take it away */ 20414 dnid = strchr(tmp, '!'); 20415 if (dnid != NULL) { 20416 *dnid++ = '\0'; 20417 ast_string_field_set(p, todnid, dnid); 20418 } 20419 20420 /* Find at sign - @ */ 20421 host = strchr(tmp, '@'); 20422 if (host) { 20423 *host++ = '\0'; 20424 ext = tmp; 20425 secret = strchr(ext, ':'); 20426 } 20427 if (secret) { 20428 *secret++ = '\0'; 20429 md5secret = strchr(secret, ':'); 20430 } 20431 if (md5secret) { 20432 *md5secret++ = '\0'; 20433 authname = strchr(md5secret, ':'); 20434 } 20435 if (authname) { 20436 *authname++ = '\0'; 20437 trans = strchr(authname, ':'); 20438 } 20439 if (trans) { 20440 *trans++ = '\0'; 20441 if (!strcasecmp(trans, "tcp")) 20442 transport = SIP_TRANSPORT_TCP; 20443 else if (!strcasecmp(trans, "tls")) 20444 transport = SIP_TRANSPORT_TLS; 20445 else { 20446 if (strcasecmp(trans, "udp")) 20447 ast_log(LOG_WARNING, "'%s' is not a valid transport option to Dial() for SIP calls, using udp by default.\n", trans); 20448 transport = SIP_TRANSPORT_UDP; 20449 } 20450 } else { /* use default */ 20451 transport = SIP_TRANSPORT_UDP; 20452 } 20453 20454 if (!host) { 20455 ext = strchr(tmp, '/'); 20456 if (ext) 20457 *ext++ = '\0'; 20458 host = tmp; 20459 } 20460 20461 set_socket_transport(&p->socket, transport); 20462 20463 /* We now have 20464 host = peer name, DNS host name or DNS domain (for SRV) 20465 ext = extension (user part of URI) 20466 dnid = destination of the call (applies to the To: header) 20467 */ 20468 if (create_addr(p, host, 1)) { 20469 *cause = AST_CAUSE_UNREGISTERED; 20470 ast_debug(3, "Cant create SIP call - target device not registered\n"); 20471 sip_destroy(p); 20472 return NULL; 20473 } 20474 if (ast_strlen_zero(p->peername) && ext) 20475 ast_string_field_set(p, peername, ext); 20476 /* Recalculate our side, and recalculate Call ID */ 20477 ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p); 20478 build_via(p); 20479 build_callid_pvt(p); 20480 20481 /* We have an extension to call, don't use the full contact here */ 20482 /* This to enable dialing registered peers with extension dialling, 20483 like SIP/peername/extension 20484 SIP/peername will still use the full contact 20485 */ 20486 if (ext) { 20487 ast_string_field_set(p, username, ext); 20488 ast_string_field_set(p, fullcontact, NULL); 20489 } 20490 if (secret && !ast_strlen_zero(secret)) 20491 ast_string_field_set(p, peersecret, secret); 20492 20493 if (md5secret && !ast_strlen_zero(md5secret)) 20494 ast_string_field_set(p, peermd5secret, md5secret); 20495 20496 if (authname && !ast_strlen_zero(authname)) 20497 ast_string_field_set(p, authname, authname); 20498 #if 0 20499 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 20500 #endif 20501 p->prefcodec = oldformat; /* Format for this call */ 20502 p->jointcapability = oldformat; 20503 sip_pvt_lock(p); 20504 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 20505 if (global_callevents) 20506 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 20507 "Channel: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n", 20508 p->owner? p->owner->name : "", "SIP", p->callid, p->fullcontact, p->peername); 20509 sip_pvt_unlock(p); 20510 if (!tmpc) 20511 sip_destroy(p); 20512 ast_update_use_count(); 20513 restart_monitor(); 20514 return tmpc; 20515 }
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 9635 of file chan_sip.c.
References __sip_do_register(), append_history, ast_log(), sip_registry::call, sip_pvt::do_history, sip_registry::expire, sip_registry::hostname, LOG_NOTICE, registry_addref(), registry_unref(), and sip_registry::username.
Referenced by handle_response_register(), and sip_send_all_registers().
09636 { 09637 /* if we are here, we know that we need to reregister. */ 09638 struct sip_registry *r= registry_addref((struct sip_registry *) data); 09639 09640 /* if we couldn't get a reference to the registry object, punt */ 09641 if (!r) 09642 return 0; 09643 09644 if (r->call && r->call->do_history) 09645 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 09646 /* Since registry's are only added/removed by the the monitor thread, this 09647 may be overkill to reference/dereference at all here */ 09648 if (sipdebug) 09649 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 09650 09651 r->expire = -1; 09652 __sip_do_register(r); 09653 registry_unref(r); 09654 return 0; 09655 }
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 5847 of file chan_sip.c.
References ast_debug, ast_dsp_process(), 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_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), ast_verbose(), f, ast_channel::fdno, sip_pvt::flags, sip_pvt::jointcapability, ast_channel::name, ast_channel::nativeformats, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_PAGE2_T38SUPPORT_UDPTL, sip_pvt::t38, t38properties::t38support, sip_pvt::trtp, sip_pvt::udptl, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by sip_read().
05848 { 05849 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 05850 struct ast_frame *f; 05851 05852 if (!p->rtp) { 05853 /* We have no RTP allocated for this channel */ 05854 return &ast_null_frame; 05855 } 05856 05857 switch(ast->fdno) { 05858 case 0: 05859 f = ast_rtp_read(p->rtp); /* RTP Audio */ 05860 break; 05861 case 1: 05862 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 05863 break; 05864 case 2: 05865 f = ast_rtp_read(p->vrtp); /* RTP Video */ 05866 break; 05867 case 3: 05868 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 05869 break; 05870 case 4: 05871 f = ast_rtp_read(p->trtp); /* RTP Text */ 05872 if (sipdebug_text) { 05873 int i; 05874 unsigned char* arr = f->data; 05875 for (i=0; i < f->datalen; i++) 05876 ast_verbose("%c", (arr[i] > ' ' && arr[i] < '}') ? arr[i] : '.'); 05877 ast_verbose(" -> "); 05878 for (i=0; i < f->datalen; i++) 05879 ast_verbose("%02X ", arr[i]); 05880 ast_verbose("\n"); 05881 } 05882 break; 05883 case 5: 05884 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 05885 break; 05886 default: 05887 f = &ast_null_frame; 05888 } 05889 /* Don't forward RFC2833 if we're not supposed to */ 05890 if (f && (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && 05891 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) { 05892 ast_debug(1, "Ignoring DTMF (%c) RTP frame because dtmfmode is not RFC2833\n", f->subclass); 05893 return &ast_null_frame; 05894 } 05895 05896 /* We already hold the channel lock */ 05897 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 05898 return f; 05899 05900 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 05901 if (!(f->subclass & p->jointcapability)) { 05902 ast_debug(1, "Bogus frame of format '%s' received from '%s'!\n", 05903 ast_getformatname(f->subclass), p->owner->name); 05904 return &ast_null_frame; 05905 } 05906 ast_debug(1, "Oooh, format changed to %d %s\n", 05907 f->subclass, ast_getformatname(f->subclass)); 05908 p->owner->nativeformats = (p->owner->nativeformats & (AST_FORMAT_VIDEO_MASK | AST_FORMAT_TEXT_MASK)) | f->subclass; 05909 ast_set_read_format(p->owner, p->owner->readformat); 05910 ast_set_write_format(p->owner, p->owner->writeformat); 05911 } 05912 05913 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 05914 f = ast_dsp_process(p->owner, p->vad, f); 05915 if (f && f->frametype == AST_FRAME_DTMF) { 05916 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 05917 ast_debug(1, "Fax CNG detected on %s\n", ast->name); 05918 *faxdetect = 1; 05919 } else { 05920 ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass); 05921 } 05922 } 05923 } 05924 05925 return f; 05926 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 3056 of file chan_sip.c.
References __sip_autodestruct(), append_history, ast_log(), ast_sched_add(), ast_verbose(), sip_pvt::autokillid, sip_pvt::callid, dialog_ref(), sip_pvt::do_history, LOG_WARNING, sip_pvt::method, sched, sip_cancel_destroy(), sip_debug_test_pvt(), sip_methods, sip_st_dlg::st_active, sip_st_dlg::st_schedid, sip_pvt::stimer, stop_session_timer(), sip_pvt::timer_b, sip_pvt::timer_t1, and TRUE.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), sip_sipredirect(), and transmit_fake_auth_response().
03057 { 03058 if (ms < 0) { 03059 if (p->timer_t1 == 0) { 03060 p->timer_t1 = global_t1; /* Set timer T1 if not set (RFC 3261) */ 03061 p->timer_b = global_timer_b; /* Set timer B if not set (RFC 3261) */ 03062 } 03063 ms = p->timer_t1 * 64; 03064 } 03065 if (sip_debug_test_pvt(p)) 03066 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 03067 if (sip_cancel_destroy(p)) 03068 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03069 03070 if (p->do_history) 03071 append_history(p, "SchedDestroy", "%d ms", ms); 03072 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, dialog_ref(p)); 03073 03074 if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_schedid > 0) 03075 stop_session_timer(p); 03076 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 22750 of file chan_sip.c.
References AST_SCHED_REPLACE, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, regl, sched, and sip_reregister().
Referenced by load_module(), and sip_do_reload().
22751 { 22752 int ms; 22753 int regspacing; 22754 if (!regobjs) 22755 return; 22756 regspacing = default_expiry * 1000/regobjs; 22757 if (regspacing > 100) 22758 regspacing = 100; 22759 ms = regspacing; 22760 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 22761 ASTOBJ_WRLOCK(iterator); 22762 ms += regspacing; 22763 AST_SCHED_REPLACE(iterator->expire, 22764 sched, ms, sip_reregister, iterator); 22765 ASTOBJ_UNLOCK(iterator); 22766 } while (0) 22767 ); 22768 }
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 19592 of file chan_sip.c.
References sip_peer::addr, ast_app_inboxcount(), ast_event_get_ie_uint(), AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, ast_set_flag, ast_sip_ouraddrfor(), ast_str_alloca, ast_test_flag, build_callid_pvt(), build_via(), create_addr_from_peer(), sip_peer::defaddr, DEFAULT_TRANS_TIMEOUT, dialog_ref(), sip_pvt::flags, sip_peer::flags, get_cached_mwi(), sip_peer::mwipvt, sip_pvt::ourip, peer_mailboxes_to_str(), sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, SIP_OUTGOING, SIP_PAGE2_SUBSCRIBEMWIONLY, sip_scheddestroy(), ast_str::str, transmit_notify_with_mwi(), and sip_peer::vmexten.
Referenced by build_peer(), handle_request_subscribe(), and mwi_event_cb().
19593 { 19594 /* Called with peerl lock, but releases it */ 19595 struct sip_pvt *p; 19596 int newmsgs = 0, oldmsgs = 0; 19597 19598 if (ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY) && !peer->mwipvt) 19599 return 0; 19600 19601 /* Do we have an IP address? If not, skip this peer */ 19602 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 19603 return 0; 19604 19605 if (event) { 19606 newmsgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 19607 oldmsgs = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 19608 } else if (!get_cached_mwi(peer, &newmsgs, &oldmsgs)) { 19609 /* got it! Don't keep looking. */ 19610 } else if (cache_only) { 19611 return 0; 19612 } else { /* Fall back to manually checking the mailbox */ 19613 struct ast_str *mailbox_str = ast_str_alloca(512); 19614 peer_mailboxes_to_str(&mailbox_str, peer); 19615 ast_app_inboxcount(mailbox_str->str, &newmsgs, &oldmsgs); 19616 } 19617 19618 if (peer->mwipvt) { 19619 /* Base message on subscription */ 19620 p = dialog_ref(peer->mwipvt); 19621 } else { 19622 /* Build temporary dialog for this message */ 19623 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) 19624 return -1; 19625 if (create_addr_from_peer(p, peer)) { 19626 /* Maybe they're not registered, etc. */ 19627 sip_destroy(p); 19628 return 0; 19629 } 19630 /* Recalculate our side, and recalculate Call ID */ 19631 ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p); 19632 build_via(p); 19633 build_callid_pvt(p); 19634 /* Destroy this session after 32 secs */ 19635 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 19636 } 19637 19638 /* Send MWI */ 19639 ast_set_flag(&p->flags[0], SIP_OUTGOING); 19640 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 19641 19642 return 0; 19643 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 5328 of file chan_sip.c.
References ast_rtp_senddigit_begin(), ast_test_flag, sip_pvt::flags, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.
05329 { 05330 struct sip_pvt *p = ast->tech_pvt; 05331 int res = 0; 05332 05333 sip_pvt_lock(p); 05334 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 05335 case SIP_DTMF_INBAND: 05336 res = -1; /* Tell Asterisk to generate inband indications */ 05337 break; 05338 case SIP_DTMF_RFC2833: 05339 if (p->rtp) 05340 ast_rtp_senddigit_begin(p->rtp, digit); 05341 break; 05342 default: 05343 break; 05344 } 05345 sip_pvt_unlock(p); 05346 05347 return res; 05348 }
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 5352 of file chan_sip.c.
References ast_rtp_senddigit_end(), ast_test_flag, sip_pvt::flags, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_DTMF_SHORTINFO, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and transmit_info_with_digit().
05353 { 05354 struct sip_pvt *p = ast->tech_pvt; 05355 int res = 0; 05356 05357 sip_pvt_lock(p); 05358 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 05359 case SIP_DTMF_INFO: 05360 case SIP_DTMF_SHORTINFO: 05361 transmit_info_with_digit(p, digit, duration); 05362 break; 05363 case SIP_DTMF_RFC2833: 05364 if (p->rtp) 05365 ast_rtp_senddigit_end(p->rtp, digit); 05366 break; 05367 case SIP_DTMF_INBAND: 05368 res = -1; /* Tell Asterisk to stop inband indications */ 05369 break; 05370 } 05371 sip_pvt_unlock(p); 05372 05373 return res; 05374 }
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 3473 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, chan, FALSE, sip_pvt::flags, sip_pvt::initreq, LOG_WARNING, sip_pvt::pendinginvite, sip_debug_test_pvt(), SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), transmit_response(), and url.
03474 { 03475 struct sip_pvt *p = chan->tech_pvt; 03476 03477 if (subclass != AST_HTML_URL) 03478 return -1; 03479 03480 ast_string_field_build(p, url, "<%s>;mode=active", data); 03481 03482 if (sip_debug_test_pvt(p)) 03483 ast_debug(1, "Send URL %s, state = %d!\n", data, chan->_state); 03484 03485 switch (chan->_state) { 03486 case AST_STATE_RING: 03487 transmit_response(p, "100 Trying", &p->initreq); 03488 break; 03489 case AST_STATE_RINGING: 03490 transmit_response(p, "180 Ringing", &p->initreq); 03491 break; 03492 case AST_STATE_UP: 03493 if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 03494 transmit_reinvite_with_sdp(p, FALSE, FALSE); 03495 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 03496 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 03497 } 03498 break; 03499 default: 03500 ast_log(LOG_WARNING, "Don't know how to send URI when state is %d!\n", chan->_state); 03501 } 03502 03503 return 0; 03504 }
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 3514 of file chan_sip.c.
References ast_verbose(), sip_request::debug, ast_channel::name, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().
03515 { 03516 struct sip_pvt *p = ast->tech_pvt; 03517 int debug = sip_debug_test_pvt(p); 03518 03519 if (debug) 03520 ast_verbose("Sending text %s on %s\n", text, ast->name); 03521 if (!p) 03522 return -1; 03523 /* NOT ast_strlen_zero, because a zero-length message is specifically 03524 * allowed by RFC 3428 (See section 10, Examples) */ 03525 if (!text) 03526 return 0; 03527 if (debug) 03528 ast_verbose("Really sending text %s on %s\n", text, ast->name); 03529 transmit_message_with_text(p, text); 03530 return 0; 03531 }
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 14691 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, TRUE, and ast_cli_entry::usage.
14692 { 14693 switch (cmd) { 14694 case CLI_INIT: 14695 e->command = "sip set history {on|off}"; 14696 e->usage = 14697 "Usage: sip history {on|off}\n" 14698 " Enables/Disables recording of SIP dialog history for debugging purposes.\n" 14699 " Use 'sip show history' to view the history of a call number.\n"; 14700 return NULL; 14701 case CLI_GENERATE: 14702 return NULL; 14703 } 14704 14705 if (a->argc != e->args) 14706 return CLI_SHOWUSAGE; 14707 14708 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 14709 recordhistory = TRUE; 14710 ast_cli(a->fd, "SIP History Recording Enabled (use 'sip show history')\n"); 14711 } else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) { 14712 recordhistory = FALSE; 14713 ast_cli(a->fd, "SIP History Recording Disabled\n"); 14714 } else { 14715 return CLI_SHOWUSAGE; 14716 } 14717 return CLI_SUCCESS; 14718 }
static void sip_set_redirstr | ( | struct sip_pvt * | p, | |
char * | reason | |||
) | [static] |
Translate referring cause.
Definition at line 11186 of file chan_sip.c.
References ast_string_field_set.
Referenced by get_rdnis().
11186 { 11187 11188 if (!strcmp(reason, "unknown")) { 11189 ast_string_field_set(p, redircause, "UNKNOWN"); 11190 } else if (!strcmp(reason, "user-busy")) { 11191 ast_string_field_set(p, redircause, "BUSY"); 11192 } else if (!strcmp(reason, "no-answer")) { 11193 ast_string_field_set(p, redircause, "NOANSWER"); 11194 } else if (!strcmp(reason, "unavailable")) { 11195 ast_string_field_set(p, redircause, "UNREACHABLE"); 11196 } else if (!strcmp(reason, "unconditional")) { 11197 ast_string_field_set(p, redircause, "UNCONDITIONAL"); 11198 } else if (!strcmp(reason, "time-of-day")) { 11199 ast_string_field_set(p, redircause, "UNKNOWN"); 11200 } else if (!strcmp(reason, "do-not-disturb")) { 11201 ast_string_field_set(p, redircause, "UNKNOWN"); 11202 } else if (!strcmp(reason, "deflection")) { 11203 ast_string_field_set(p, redircause, "UNKNOWN"); 11204 } else if (!strcmp(reason, "follow-me")) { 11205 ast_string_field_set(p, redircause, "UNKNOWN"); 11206 } else if (!strcmp(reason, "out-of-service")) { 11207 ast_string_field_set(p, redircause, "UNREACHABLE"); 11208 } else if (!strcmp(reason, "away")) { 11209 ast_string_field_set(p, redircause, "UNREACHABLE"); 11210 } else { 11211 ast_string_field_set(p, redircause, "UNKNOWN"); 11212 } 11213 }
static int sip_set_rtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp * | rtp, | |||
struct ast_rtp * | vrtp, | |||
struct ast_rtp * | trtp, | |||
int | codecs, | |||
int | nat_active | |||
) | [static] |
Set the RTP peer for this call.
Definition at line 22479 of file chan_sip.c.
References ast_channel::_state, sip_pvt::alreadygone, append_history, ast_bridged_channel(), ast_debug, ast_inet_ntoa(), ast_rtp_get_peer(), ast_set_flag, AST_STATE_UP, ast_test_flag, sip_pvt::callid, chan, sip_pvt::do_history, FALSE, sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, SIP_CAN_REINVITE_NAT, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), sip_pvt::tredirip, sip_pvt::trtp, sip_pvt::vredirip, and sip_pvt::vrtp.
Referenced by sip_fixup().
22480 { 22481 struct sip_pvt *p; 22482 int changed = 0; 22483 22484 p = chan->tech_pvt; 22485 if (!p) 22486 return -1; 22487 22488 /* Disable early RTP bridge */ 22489 if (!ast_bridged_channel(chan) && !global_directrtpsetup) /* We are in early state */ 22490 return 0; 22491 22492 sip_pvt_lock(p); 22493 if (p->alreadygone) { 22494 /* If we're destroyed, don't bother */ 22495 sip_pvt_unlock(p); 22496 return 0; 22497 } 22498 22499 /* if this peer cannot handle reinvites of the media stream to devices 22500 that are known to be behind a NAT, then stop the process now 22501 */ 22502 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 22503 sip_pvt_unlock(p); 22504 return 0; 22505 } 22506 22507 if (rtp) { 22508 changed |= ast_rtp_get_peer(rtp, &p->redirip); 22509 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 22510 memset(&p->redirip, 0, sizeof(p->redirip)); 22511 changed = 1; 22512 } 22513 if (vrtp) { 22514 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 22515 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 22516 memset(&p->vredirip, 0, sizeof(p->vredirip)); 22517 changed = 1; 22518 } 22519 if (trtp) { 22520 changed |= ast_rtp_get_peer(trtp, &p->tredirip); 22521 } else if (p->tredirip.sin_addr.s_addr || ntohs(p->tredirip.sin_port) != 0) { 22522 memset(&p->tredirip, 0, sizeof(p->tredirip)); 22523 changed = 1; 22524 } 22525 if (codecs && (p->redircodecs != codecs)) { 22526 p->redircodecs = codecs; 22527 changed = 1; 22528 } 22529 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 22530 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 22531 if (p->do_history) 22532 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 22533 ast_debug(1, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip.sin_addr)); 22534 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 22535 ast_debug(3, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip.sin_addr)); 22536 transmit_reinvite_with_sdp(p, FALSE, FALSE); 22537 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 22538 ast_debug(3, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip.sin_addr)); 22539 /* We have a pending Invite. Send re-invite when we're done with the invite */ 22540 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 22541 } 22542 } 22543 /* Reset lastrtprx timer */ 22544 p->lastrtprx = p->lastrtptx = time(NULL); 22545 sip_pvt_unlock(p); 22546 return 0; 22547 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 22372 of file chan_sip.c.
References ast_debug, ast_inet_ntoa(), ast_set_flag, ast_test_flag, ast_udptl_get_peer(), sip_pvt::callid, chan, FALSE, sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::ourip, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), TRUE, sip_pvt::udptl, and sip_pvt::udptlredirip.
22373 { 22374 struct sip_pvt *p; 22375 22376 p = chan->tech_pvt; 22377 if (!p) 22378 return -1; 22379 sip_pvt_lock(p); 22380 if (udptl) 22381 ast_udptl_get_peer(udptl, &p->udptlredirip); 22382 else 22383 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 22384 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 22385 if (!p->pendinginvite) { 22386 ast_debug(3, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip.sin_addr), udptl ? ntohs(p->udptlredirip.sin_port) : 0); 22387 transmit_reinvite_with_sdp(p, TRUE, FALSE); 22388 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 22389 ast_debug(3, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip.sin_addr), udptl ? ntohs(p->udptlredirip.sin_port) : 0); 22390 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 22391 } 22392 } 22393 /* Reset lastrtprx timer */ 22394 p->lastrtprx = p->lastrtptx = time(NULL); 22395 sip_pvt_unlock(p); 22396 return 0; 22397 }
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 14132 of file chan_sip.c.
References sip_pvt::allowtransfer, ast_cli_args::argc, ast_cli_args::argv, ARRAY_LEN, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::capability, sip_pvt::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, cli_yesno(), ast_cli_entry::command, complete_sipch(), dialoglist, dialoglist_lock(), dtmfmode2str(), ast_cli_args::fd, sip_pvt::flags, sip_route::hop, cfsip_options::id, sip_pvt::jointcapability, sip_pvt::lastmsg, len(), ast_cli_args::line, sip_pvt::maxcallbitrate, ast_cli_args::n, ast_channel::name, nat2str(), ast_channel::nativeformats, sip_pvt::needdestroy, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::peername, ast_cli_args::pos, sip_pvt::recv, sip_pvt::redirip, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, SIPBUFSIZE, sip_pvt::sipoptions, sip_st_dlg::st_active, sip_st_dlg::st_active_peer_ua, sip_st_dlg::st_cached_max_se, sip_st_dlg::st_cached_min_se, sip_st_dlg::st_cached_mode, sip_st_dlg::st_cached_ref, sip_st_dlg::st_expirys, sip_st_dlg::st_interval, sip_st_dlg::st_ref, sip_st_dlg::st_schedid, sip_pvt::stimer, stmode2str(), strefresher2str(), sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, cfsip_options::text, sip_pvt::theirtag, transfermode2str(), TRUE, sip_pvt::udptl, sip_pvt::uri, ast_cli_entry::usage, sip_pvt::useragent, sip_pvt::username, sip_pvt::vrtp, and ast_cli_args::word.
14133 { 14134 struct sip_pvt *cur; 14135 size_t len; 14136 int found = 0; 14137 14138 switch (cmd) { 14139 case CLI_INIT: 14140 e->command = "sip show channel"; 14141 e->usage = 14142 "Usage: sip show channel <call-id>\n" 14143 " Provides detailed status on a given SIP dialog (identified by SIP call-id).\n"; 14144 return NULL; 14145 case CLI_GENERATE: 14146 return complete_sipch(a->line, a->word, a->pos, a->n); 14147 } 14148 14149 if (a->argc != 4) 14150 return CLI_SHOWUSAGE; 14151 len = strlen(a->argv[3]); 14152 dialoglist_lock(); 14153 for (cur = dialoglist; cur; cur = cur->next) { 14154 if (!strncasecmp(cur->callid, a->argv[3], len)) { 14155 char formatbuf[SIPBUFSIZE/2]; 14156 ast_cli(a->fd, "\n"); 14157 if (cur->subscribed != NONE) 14158 ast_cli(a->fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 14159 else 14160 ast_cli(a->fd, " * SIP Call\n"); 14161 ast_cli(a->fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 14162 ast_cli(a->fd, " Call-ID: %s\n", cur->callid); 14163 ast_cli(a->fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 14164 ast_cli(a->fd, " Our Codec Capability: %d\n", cur->capability); 14165 ast_cli(a->fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 14166 ast_cli(a->fd, " Their Codec Capability: %d\n", cur->peercapability); 14167 ast_cli(a->fd, " Joint Codec Capability: %d\n", cur->jointcapability); 14168 ast_cli(a->fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 14169 ast_cli(a->fd, " T.38 support %s\n", cli_yesno(cur->udptl != NULL)); 14170 ast_cli(a->fd, " Video support %s\n", cli_yesno(cur->vrtp != NULL)); 14171 ast_cli(a->fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 14172 ast_cli(a->fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 14173 ast_cli(a->fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 14174 ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 14175 ast_cli(a->fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 14176 ast_cli(a->fd, " Audio IP: %s %s\n", ast_inet_ntoa(cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip.sin_addr), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" ); 14177 ast_cli(a->fd, " Our Tag: %s\n", cur->tag); 14178 ast_cli(a->fd, " Their Tag: %s\n", cur->theirtag); 14179 ast_cli(a->fd, " SIP User agent: %s\n", cur->useragent); 14180 if (!ast_strlen_zero(cur->username)) 14181 ast_cli(a->fd, " Username: %s\n", cur->username); 14182 if (!ast_strlen_zero(cur->peername)) 14183 ast_cli(a->fd, " Peername: %s\n", cur->peername); 14184 if (!ast_strlen_zero(cur->uri)) 14185 ast_cli(a->fd, " Original uri: %s\n", cur->uri); 14186 if (!ast_strlen_zero(cur->cid_num)) 14187 ast_cli(a->fd, " Caller-ID: %s\n", cur->cid_num); 14188 ast_cli(a->fd, " Need Destroy: %s\n", cli_yesno(cur->needdestroy)); 14189 ast_cli(a->fd, " Last Message: %s\n", cur->lastmsg); 14190 ast_cli(a->fd, " Promiscuous Redir: %s\n", cli_yesno(ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR))); 14191 ast_cli(a->fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 14192 ast_cli(a->fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 14193 ast_cli(a->fd, " SIP Options: "); 14194 if (cur->sipoptions) { 14195 int x; 14196 for (x = 0 ; x < ARRAY_LEN(sip_options); x++) { 14197 if (cur->sipoptions & sip_options[x].id) 14198 ast_cli(a->fd, "%s ", sip_options[x].text); 14199 } 14200 ast_cli(a->fd, "\n"); 14201 } else 14202 ast_cli(a->fd, "(none)\n"); 14203 14204 if (!cur->stimer) 14205 ast_cli(a->fd, " Session-Timer: Uninitiallized\n"); 14206 else { 14207 ast_cli(a->fd, " Session-Timer: %s\n", cur->stimer->st_active ? "Active" : "Inactive"); 14208 if (cur->stimer->st_active == TRUE) { 14209 ast_cli(a->fd, " S-Timer Interval: %d\n", cur->stimer->st_interval); 14210 ast_cli(a->fd, " S-Timer Refresher: %s\n", strefresher2str(cur->stimer->st_ref)); 14211 ast_cli(a->fd, " S-Timer Expirys: %d\n", cur->stimer->st_expirys); 14212 ast_cli(a->fd, " S-Timer Sched Id: %d\n", cur->stimer->st_schedid); 14213 ast_cli(a->fd, " S-Timer Peer Sts: %s\n", cur->stimer->st_active_peer_ua ? "Active" : "Inactive"); 14214 ast_cli(a->fd, " S-Timer Cached Min-SE: %d\n", cur->stimer->st_cached_min_se); 14215 ast_cli(a->fd, " S-Timer Cached SE: %d\n", cur->stimer->st_cached_max_se); 14216 ast_cli(a->fd, " S-Timer Cached Ref: %s\n", strefresher2str(cur->stimer->st_cached_ref)); 14217 ast_cli(a->fd, " S-Timer Cached Mode: %s\n", stmode2str(cur->stimer->st_cached_mode)); 14218 } 14219 } 14220 14221 ast_cli(a->fd, "\n\n"); 14222 14223 found++; 14224 } 14225 } 14226 dialoglist_unlock(); 14227 if (!found) 14228 ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]); 14229 return CLI_SUCCESS; 14230 }
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 13942 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, dialoglist, dialoglist_lock(), dialoglist_unlock(), ESS, ast_cli_args::fd, __show_chan_arg::fd, FORMAT2, FORMAT3, sip_pvt::next, __show_chan_arg::numchans, show_channels_cb(), __show_chan_arg::subscriptions, and ast_cli_entry::usage.
13943 { 13944 struct sip_pvt *cur; 13945 struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 }; 13946 13947 if (cmd == CLI_INIT) { 13948 e->command = "sip show {channels|subscriptions}"; 13949 e->usage = 13950 "Usage: sip show channels\n" 13951 " Lists all currently active SIP calls (dialogs).\n" 13952 "Usage: sip show subscriptions\n" 13953 " Lists active SIP subscriptions.\n"; 13954 return NULL; 13955 } else if (cmd == CLI_GENERATE) 13956 return NULL; 13957 13958 if (a->argc != e->args) 13959 return CLI_SHOWUSAGE; 13960 arg.subscriptions = !strcasecmp(a->argv[e->args - 1], "subscriptions"); 13961 if (!arg.subscriptions) 13962 ast_cli(arg.fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Format", "Hold", "Last Message"); 13963 else 13964 ast_cli(arg.fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox"); 13965 13966 /* iterate on the container and invoke the callback on each item */ 13967 dialoglist_lock(); 13968 for (cur = dialoglist; cur; cur = cur->next) { 13969 show_channels_cb(cur, &arg, 0); 13970 } 13971 dialoglist_unlock(); 13972 13973 /* print summary information */ 13974 ast_cli(arg.fd, "%d active SIP %s%s\n", arg.numchans, 13975 (arg.subscriptions ? "subscription" : "dialog"), 13976 ESS(arg.numchans)); /* ESS(n) returns an "s" if n>1 */ 13977 return CLI_SUCCESS; 13978 #undef FORMAT 13979 #undef FORMAT2 13980 #undef FORMAT3 13981 }
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 13168 of file chan_sip.c.
References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, domain::context, domain::domain, domain_mode_to_text(), ast_cli_args::fd, FORMAT, domain::list, domain::mode, S_OR, and ast_cli_entry::usage.
13169 { 13170 struct domain *d; 13171 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 13172 13173 switch (cmd) { 13174 case CLI_INIT: 13175 e->command = "sip show domains"; 13176 e->usage = 13177 "Usage: sip show domains\n" 13178 " Lists all configured SIP local domains.\n" 13179 " Asterisk only responds to SIP messages to local domains.\n"; 13180 return NULL; 13181 case CLI_GENERATE: 13182 return NULL; 13183 } 13184 13185 if (AST_LIST_EMPTY(&domain_list)) { 13186 ast_cli(a->fd, "SIP Domain support not enabled.\n\n"); 13187 return CLI_SUCCESS; 13188 } else { 13189 ast_cli(a->fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 13190 AST_LIST_LOCK(&domain_list); 13191 AST_LIST_TRAVERSE(&domain_list, d, list) 13192 ast_cli(a->fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 13193 domain_mode_to_text(d->mode)); 13194 AST_LIST_UNLOCK(&domain_list); 13195 ast_cli(a->fd, "\n"); 13196 return CLI_SUCCESS; 13197 } 13198 }
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 14233 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_TRAVERSE, sip_pvt::callid, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, complete_sip_show_history(), dialoglist, dialoglist_lock(), ast_cli_args::fd, sip_pvt::history, len(), ast_cli_args::line, ast_cli_args::n, sip_pvt::next, NONE, ast_cli_args::pos, sip_pvt::subscribed, ast_cli_entry::usage, and ast_cli_args::word.
14234 { 14235 struct sip_pvt *cur; 14236 size_t len; 14237 int found = 0; 14238 14239 switch (cmd) { 14240 case CLI_INIT: 14241 e->command = "sip show history"; 14242 e->usage = 14243 "Usage: sip show history <call-id>\n" 14244 " Provides detailed dialog history on a given SIP call (specified by call-id).\n"; 14245 return NULL; 14246 case CLI_GENERATE: 14247 return complete_sip_show_history(a->line, a->word, a->pos, a->n); 14248 } 14249 14250 if (a->argc != 4) 14251 return CLI_SHOWUSAGE; 14252 if (!recordhistory) 14253 ast_cli(a->fd, "\n***Note: History recording is currently DISABLED. Use 'sip set history on' to ENABLE.\n"); 14254 len = strlen(a->argv[3]); 14255 dialoglist_lock(); 14256 for (cur = dialoglist; cur; cur = cur->next) { 14257 if (!strncasecmp(cur->callid, a->argv[3], len)) { 14258 struct sip_history *hist; 14259 int x = 0; 14260 14261 ast_cli(a->fd, "\n"); 14262 if (cur->subscribed != NONE) 14263 ast_cli(a->fd, " * Subscription\n"); 14264 else 14265 ast_cli(a->fd, " * SIP Call\n"); 14266 if (cur->history) 14267 AST_LIST_TRAVERSE(cur->history, hist, list) 14268 ast_cli(a->fd, "%d. %s\n", ++x, hist->event); 14269 if (x == 0) 14270 ast_cli(a->fd, "Call '%s' has no history\n", cur->callid); 14271 found++; 14272 } 14273 } 14274 dialoglist_unlock(); 14275 if (!found) 14276 ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]); 14277 return CLI_SUCCESS; 14278 }
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 12392 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, FORMAT, FORMAT2, peerl, TRUE, ast_cli_entry::usage, and userl.
12393 { 12394 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 12395 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 12396 char ilimits[40]; 12397 char iused[40]; 12398 int showall = FALSE; 12399 12400 switch (cmd) { 12401 case CLI_INIT: 12402 e->command = "sip show inuse"; 12403 e->usage = 12404 "Usage: sip show inuse [all]\n" 12405 " List all SIP users and peers usage counters and limits.\n" 12406 " Add option \"all\" to show all devices, not only those with a limit.\n"; 12407 return NULL; 12408 case CLI_GENERATE: 12409 return NULL; 12410 } 12411 12412 if (a->argc < 3) 12413 return CLI_SHOWUSAGE; 12414 12415 if (a->argc == 4 && !strcmp(a->argv[3], "all")) 12416 showall = TRUE; 12417 12418 ast_cli(a->fd, FORMAT, "* User name", "In use", "Limit"); 12419 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 12420 ASTOBJ_RDLOCK(iterator); 12421 if (iterator->call_limit) 12422 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 12423 else 12424 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 12425 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 12426 if (showall || iterator->call_limit) 12427 ast_cli(a->fd, FORMAT2, iterator->name, iused, ilimits); 12428 ASTOBJ_UNLOCK(iterator); 12429 } while (0) ); 12430 12431 ast_cli(a->fd, FORMAT, "* Peer name", "In use", "Limit"); 12432 12433 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 12434 ASTOBJ_RDLOCK(iterator); 12435 if (iterator->call_limit) 12436 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 12437 else 12438 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 12439 snprintf(iused, sizeof(iused), "%d/%d/%d", iterator->inUse, iterator->inRinging, iterator->onHold); 12440 if (showall || iterator->call_limit) 12441 ast_cli(a->fd, FORMAT2, iterator->name, iused, ilimits); 12442 ASTOBJ_UNLOCK(iterator); 12443 } while (0) ); 12444 12445 return CLI_SUCCESS; 12446 #undef FORMAT 12447 #undef FORMAT2 12448 }
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 12885 of file chan_sip.c.
References ast_cli_args::argc, ast_cli(), ASTOBJ_CONTAINER_DUMP, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, peerl, regl, ast_cli_entry::usage, and userl.
12886 { 12887 char tmp[256]; 12888 12889 switch (cmd) { 12890 case CLI_INIT: 12891 e->command = "sip show objects"; 12892 e->usage = 12893 "Usage: sip show objects\n" 12894 " Lists status of known SIP objects\n"; 12895 return NULL; 12896 case CLI_GENERATE: 12897 return NULL; 12898 } 12899 12900 if (a->argc != 3) 12901 return CLI_SHOWUSAGE; 12902 ast_cli(a->fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 12903 ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), &userl); 12904 ast_cli(a->fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 12905 ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), &peerl); 12906 ast_cli(a->fd, "-= Registry objects: %d =-\n\n", regobjs); 12907 ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), ®l); 12908 return CLI_SUCCESS; 12909 }
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 13229 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.
13230 { 13231 switch (cmd) { 13232 case CLI_INIT: 13233 e->command = "sip show peer"; 13234 e->usage = 13235 "Usage: sip show peer <name> [load]\n" 13236 " Shows all details on one SIP peer and the current status.\n" 13237 " Option \"load\" forces lookup of peer in realtime storage.\n"; 13238 return NULL; 13239 case CLI_GENERATE: 13240 return complete_sip_show_peer(a->line, a->word, a->pos, a->n); 13241 } 13242 return _sip_show_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv); 13243 }
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 12726 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.
12727 { 12728 switch (cmd) { 12729 case CLI_INIT: 12730 e->command = "sip show peers"; 12731 e->usage = 12732 "Usage: sip show peers [like <pattern>]\n" 12733 " Lists all known SIP peers.\n" 12734 " Optional regular expression pattern is used to filter the peer list.\n"; 12735 return NULL; 12736 case CLI_GENERATE: 12737 return NULL; 12738 } 12739 12740 return _sip_show_peers(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv); 12741 }
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 13573 of file chan_sip.c.
References ast_cli_args::argc, ast_cli(), ast_localtime(), ast_strftime(), 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(), STANDARD_SIP_PORT, and ast_cli_entry::usage.
13574 { 13575 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 13576 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 13577 char host[80]; 13578 char tmpdat[256]; 13579 struct ast_tm tm; 13580 int counter = 0; 13581 13582 switch (cmd) { 13583 case CLI_INIT: 13584 e->command = "sip show registry"; 13585 e->usage = 13586 "Usage: sip show registry\n" 13587 " Lists all registration requests and status.\n"; 13588 return NULL; 13589 case CLI_GENERATE: 13590 return NULL; 13591 } 13592 13593 if (a->argc != 3) 13594 return CLI_SHOWUSAGE; 13595 ast_cli(a->fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 13596 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 13597 ASTOBJ_RDLOCK(iterator); 13598 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 13599 if (iterator->regtime.tv_sec) { 13600 ast_localtime(&iterator->regtime, &tm, NULL); 13601 ast_strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 13602 } else 13603 tmpdat[0] = '\0'; 13604 ast_cli(a->fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 13605 ASTOBJ_UNLOCK(iterator); 13606 counter++; 13607 } while(0)); 13608 ast_cli(a->fd, "%d SIP registrations.\n", counter); 13609 return CLI_SUCCESS; 13610 #undef FORMAT 13611 #undef FORMAT2 13612 }
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 13653 of file chan_sip.c.
References ast_cli_args::argc, ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, AST_LIST_EMPTY, ast_strlen_zero(), ast_test_flag, ast_tos2str(), authl, bindaddr, buf, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, cli_yesno(), ast_cli_entry::command, default_prefs, default_tls_cfg, dtmfmode2str(), ast_tls_config::enabled, externhost, externip, externrefresh, FALSE, ast_cli_args::fd, sip_proxy::force, global_flags, global_jbconf, global_outboundproxy, sip_settings::ignore_regexpire, ast_jb_conf::impl, internip, localaddr, ast_jb_conf::max_size, msg, sip_proxy::name, nat2str(), ast_ha::netaddr, ast_ha::netmask, ast_ha::next, sip_settings::peer_rtupdate, prefix, print_codec_to_cli(), ast_jb_conf::resync_threshold, sip_settings::rtsave_sysname, S_OR, server_args::sin, sip_cfg, SIP_DTMF, SIP_NAT, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNORESDPVERSION, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, sip_tcp_desc, sip_tls_desc, SIP_USECLIENTCODE, SIP_USEREQPHONE, SIPBUFSIZE, stmode2str(), strefresher2str(), stunaddr, transfermode2str(), and ast_cli_entry::usage.
13654 { 13655 int realtimepeers; 13656 int realtimeusers; 13657 int realtimeregs; 13658 char codec_buf[SIPBUFSIZE]; 13659 const char *msg; /* temporary msg pointer */ 13660 13661 switch (cmd) { 13662 case CLI_INIT: 13663 e->command = "sip show settings"; 13664 e->usage = 13665 "Usage: sip show settings\n" 13666 " Provides detailed list of the configuration of the SIP channel.\n"; 13667 return NULL; 13668 case CLI_GENERATE: 13669 return NULL; 13670 } 13671 13672 13673 realtimepeers = ast_check_realtime("sippeers"); 13674 realtimeusers = ast_check_realtime("sipusers"); 13675 realtimeregs = ast_check_realtime("sipregs"); 13676 13677 if (a->argc != 3) 13678 return CLI_SHOWUSAGE; 13679 ast_cli(a->fd, "\n\nGlobal Settings:\n"); 13680 ast_cli(a->fd, "----------------\n"); 13681 ast_cli(a->fd, " UDP SIP Port: %d\n", ntohs(bindaddr.sin_port)); 13682 ast_cli(a->fd, " UDP Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 13683 ast_cli(a->fd, " TCP SIP Port: "); 13684 if (sip_tcp_desc.sin.sin_family == AF_INET) { 13685 ast_cli(a->fd, "%d\n", ntohs(sip_tcp_desc.sin.sin_port)); 13686 ast_cli(a->fd, " TCP Bindaddress: %s\n", ast_inet_ntoa(sip_tcp_desc.sin.sin_addr)); 13687 } else { 13688 ast_cli(a->fd, "Disabled\n"); 13689 } 13690 ast_cli(a->fd, " TLS SIP Port: "); 13691 if (default_tls_cfg.enabled != FALSE) { 13692 ast_cli(a->fd, "%d\n", ntohs(sip_tls_desc.sin.sin_port)); 13693 ast_cli(a->fd, " TLS Bindaddress: %s\n", ast_inet_ntoa(sip_tls_desc.sin.sin_addr)); 13694 } else { 13695 ast_cli(a->fd, "Disabled\n"); 13696 } 13697 ast_cli(a->fd, " Videosupport: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT))); 13698 ast_cli(a->fd, " Textsupport: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT))); 13699 ast_cli(a->fd, " AutoCreate Peer: %s\n", cli_yesno(autocreatepeer)); 13700 ast_cli(a->fd, " Ignore SDP sess. ver.: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION))); 13701 ast_cli(a->fd, " Match Auth Username: %s\n", cli_yesno(global_match_auth_username)); 13702 ast_cli(a->fd, " Allow unknown access: %s\n", cli_yesno(global_allowguest)); 13703 ast_cli(a->fd, " Allow subscriptions: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))); 13704 ast_cli(a->fd, " Allow overlap dialing: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP))); 13705 ast_cli(a->fd, " Allow promsic. redir: %s\n", cli_yesno(ast_test_flag(&global_flags[0], SIP_PROMISCREDIR))); 13706 ast_cli(a->fd, " Enable call counters: %s\n", cli_yesno(global_callcounter)); 13707 ast_cli(a->fd, " SIP domain support: %s\n", cli_yesno(!AST_LIST_EMPTY(&domain_list))); 13708 ast_cli(a->fd, " Realm. auth: %s\n", cli_yesno(authl != NULL)); 13709 ast_cli(a->fd, " Our auth realm %s\n", global_realm); 13710 ast_cli(a->fd, " Call to non-local dom.: %s\n", cli_yesno(allow_external_domains)); 13711 ast_cli(a->fd, " URI user is phone no: %s\n", cli_yesno(ast_test_flag(&global_flags[0], SIP_USEREQPHONE))); 13712 ast_cli(a->fd, " Always auth rejects: %s\n", cli_yesno(global_alwaysauthreject)); 13713 ast_cli(a->fd, " Call limit peers only: %s\n", cli_yesno(global_limitonpeers)); 13714 ast_cli(a->fd, " Direct RTP setup: %s\n", cli_yesno(global_directrtpsetup)); 13715 ast_cli(a->fd, " User Agent: %s\n", global_useragent); 13716 ast_cli(a->fd, " SDP Session Name: %s\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession); 13717 ast_cli(a->fd, " SDP Owner Name: %s\n", ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner); 13718 ast_cli(a->fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 13719 ast_cli(a->fd, " Regexten on Qualify: %s\n", cli_yesno(global_regextenonqualify)); 13720 ast_cli(a->fd, " Caller ID: %s\n", default_callerid); 13721 ast_cli(a->fd, " From: Domain: %s\n", default_fromdomain); 13722 ast_cli(a->fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 13723 ast_cli(a->fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 13724 13725 ast_cli(a->fd, " T38 fax pt UDPTL: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL))); 13726 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 13727 ast_cli(a->fd, " T38 fax pt RTP: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP))); 13728 ast_cli(a->fd, " T38 fax pt TCP: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP))); 13729 #endif 13730 if (!realtimepeers && !realtimeusers && !realtimeregs) 13731 ast_cli(a->fd, " SIP realtime: Disabled\n" ); 13732 else 13733 ast_cli(a->fd, " SIP realtime: Enabled\n" ); 13734 ast_cli(a->fd, " Qualify Freq : %d ms\n", global_qualifyfreq); 13735 ast_cli(a->fd, "\nNetwork QoS Settings:\n"); 13736 ast_cli(a->fd, "---------------------------\n"); 13737 ast_cli(a->fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 13738 ast_cli(a->fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 13739 ast_cli(a->fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 13740 ast_cli(a->fd, " IP ToS RTP text: %s\n", ast_tos2str(global_tos_text)); 13741 ast_cli(a->fd, " 802.1p CoS SIP: %d\n", global_cos_sip); 13742 ast_cli(a->fd, " 802.1p CoS RTP audio: %d\n", global_cos_audio); 13743 ast_cli(a->fd, " 802.1p CoS RTP video: %d\n", global_cos_video); 13744 ast_cli(a->fd, " 802.1p CoS RTP text: %d\n", global_cos_text); 13745 ast_cli(a->fd, " Jitterbuffer enabled: %s\n", cli_yesno(ast_test_flag(&global_jbconf, AST_JB_ENABLED))); 13746 ast_cli(a->fd, " Jitterbuffer forced: %s\n", cli_yesno(ast_test_flag(&global_jbconf, AST_JB_FORCED))); 13747 ast_cli(a->fd, " Jitterbuffer max size: %ld\n", global_jbconf.max_size); 13748 ast_cli(a->fd, " Jitterbuffer resync: %ld\n", global_jbconf.resync_threshold); 13749 ast_cli(a->fd, " Jitterbuffer impl: %s\n", global_jbconf.impl); 13750 ast_cli(a->fd, " Jitterbuffer log: %s\n", cli_yesno(ast_test_flag(&global_jbconf, AST_JB_LOG))); 13751 13752 ast_cli(a->fd, "\nNetwork Settings:\n"); 13753 ast_cli(a->fd, "---------------------------\n"); 13754 /* determine if/how SIP address can be remapped */ 13755 if (localaddr == NULL) 13756 msg = "Disabled, no localnet list"; 13757 else if (externip.sin_addr.s_addr == 0) 13758 msg = "Disabled, externip is 0.0.0.0"; 13759 else if (stunaddr.sin_addr.s_addr != 0) 13760 msg = "Enabled using STUN"; 13761 else if (!ast_strlen_zero(externhost)) 13762 msg = "Enabled using externhost"; 13763 else 13764 msg = "Enabled using externip"; 13765 ast_cli(a->fd, " SIP address remapping: %s\n", msg); 13766 ast_cli(a->fd, " Externhost: %s\n", S_OR(externhost, "<none>")); 13767 ast_cli(a->fd, " Externip: %s:%d\n", ast_inet_ntoa(externip.sin_addr), ntohs(externip.sin_port)); 13768 ast_cli(a->fd, " Externrefresh: %d\n", externrefresh); 13769 ast_cli(a->fd, " Internal IP: %s:%d\n", ast_inet_ntoa(internip.sin_addr), ntohs(internip.sin_port)); 13770 { 13771 struct ast_ha *d; 13772 const char *prefix = "Localnet:"; 13773 char buf[INET_ADDRSTRLEN]; /* need to print two addresses */ 13774 13775 for (d = localaddr; d ; prefix = "", d = d->next) { 13776 ast_cli(a->fd, " %-24s%s/%s\n", 13777 prefix, ast_inet_ntoa(d->netaddr), 13778 inet_ntop(AF_INET, &d->netmask, buf, sizeof(buf)) ); 13779 } 13780 } 13781 ast_cli(a->fd, " STUN server: %s:%d\n", ast_inet_ntoa(stunaddr.sin_addr), ntohs(stunaddr.sin_port)); 13782 13783 ast_cli(a->fd, "\nGlobal Signalling Settings:\n"); 13784 ast_cli(a->fd, "---------------------------\n"); 13785 ast_cli(a->fd, " Codecs: "); 13786 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 13787 ast_cli(a->fd, "%s\n", codec_buf); 13788 ast_cli(a->fd, " Codec Order: "); 13789 print_codec_to_cli(a->fd, &default_prefs); 13790 ast_cli(a->fd, "\n"); 13791 ast_cli(a->fd, " Relax DTMF: %s\n", cli_yesno(global_relaxdtmf)); 13792 ast_cli(a->fd, " RFC2833 Compensation: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE))); 13793 ast_cli(a->fd, " Compact SIP headers: %s\n", cli_yesno(compactheaders)); 13794 ast_cli(a->fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 13795 ast_cli(a->fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 13796 ast_cli(a->fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 13797 ast_cli(a->fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 13798 ast_cli(a->fd, " DNS SRV lookup: %s\n", cli_yesno(global_srvlookup)); 13799 ast_cli(a->fd, " Pedantic SIP support: %s\n", cli_yesno(pedanticsipchecking)); 13800 ast_cli(a->fd, " Reg. min duration %d secs\n", min_expiry); 13801 ast_cli(a->fd, " Reg. max duration: %d secs\n", max_expiry); 13802 ast_cli(a->fd, " Reg. default duration: %d secs\n", default_expiry); 13803 ast_cli(a->fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 13804 ast_cli(a->fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 13805 ast_cli(a->fd, " Notify ringing state: %s\n", cli_yesno(global_notifyringing)); 13806 ast_cli(a->fd, " Notify hold state: %s\n", cli_yesno(global_notifyhold)); 13807 ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 13808 ast_cli(a->fd, " Max Call Bitrate: %d kbps\n", default_maxcallbitrate); 13809 ast_cli(a->fd, " Auto-Framing: %s\n", cli_yesno(global_autoframing)); 13810 ast_cli(a->fd, " Outb. proxy: %s %s\n", ast_strlen_zero(global_outboundproxy.name) ? "<not set>" : global_outboundproxy.name, 13811 global_outboundproxy.force ? "(forced)" : ""); 13812 ast_cli(a->fd, " Session Timers: %s\n", stmode2str(global_st_mode)); 13813 ast_cli(a->fd, " Session Refresher: %s\n", strefresher2str (global_st_refresher)); 13814 ast_cli(a->fd, " Session Expires: %d secs\n", global_max_se); 13815 ast_cli(a->fd, " Session Min-SE: %d secs\n", global_min_se); 13816 ast_cli(a->fd, " Timer T1: %d\n", global_t1); 13817 ast_cli(a->fd, " Timer T1 minimum: %d\n", global_t1min); 13818 ast_cli(a->fd, " Timer B: %d\n", global_timer_b); 13819 13820 ast_cli(a->fd, "\nDefault Settings:\n"); 13821 ast_cli(a->fd, "-----------------\n"); 13822 ast_cli(a->fd, " Context: %s\n", default_context); 13823 ast_cli(a->fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 13824 ast_cli(a->fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 13825 ast_cli(a->fd, " Qualify: %d\n", default_qualify); 13826 ast_cli(a->fd, " Use ClientCode: %s\n", cli_yesno(ast_test_flag(&global_flags[0], SIP_USECLIENTCODE))); 13827 ast_cli(a->fd, " Progress inband: %s\n", (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NO) ? "No" : "Yes" ); 13828 ast_cli(a->fd, " Language: %s\n", default_language); 13829 ast_cli(a->fd, " MOH Interpret: %s\n", default_mohinterpret); 13830 ast_cli(a->fd, " MOH Suggest: %s\n", default_mohsuggest); 13831 ast_cli(a->fd, " Voice Mail Extension: %s\n", default_vmexten); 13832 13833 13834 if (realtimepeers || realtimeusers || realtimeregs) { 13835 ast_cli(a->fd, "\nRealtime SIP Settings:\n"); 13836 ast_cli(a->fd, "----------------------\n"); 13837 ast_cli(a->fd, " Realtime Peers: %s\n", cli_yesno(realtimepeers)); 13838 ast_cli(a->fd, " Realtime Users: %s\n", cli_yesno(realtimeusers)); 13839 ast_cli(a->fd, " Realtime Regs: %s\n", cli_yesno(realtimeregs)); 13840 ast_cli(a->fd, " Cache Friends: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))); 13841 ast_cli(a->fd, " Update: %s\n", cli_yesno(sip_cfg.peer_rtupdate)); 13842 ast_cli(a->fd, " Ignore Reg. Expire: %s\n", cli_yesno(sip_cfg.ignore_regexpire)); 13843 ast_cli(a->fd, " Save sys. name: %s\n", cli_yesno(sip_cfg.rtsave_sysname)); 13844 ast_cli(a->fd, " Auto Clear: %d\n", global_rtautoclear); 13845 } 13846 ast_cli(a->fd, "\n----\n"); 13847 return CLI_SUCCESS; 13848 }
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 12551 of file chan_sip.c.
References ast_cli_args::argc, ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_tcptls_session_instance::client, ast_cli_entry::command, ast_cli_args::fd, FORMAT, FORMAT2, get_transport(), sip_threadinfo::list, ast_tcptls_session_instance::requestor, sip_threadinfo::tcptls_session, sip_threadinfo::type, and ast_cli_entry::usage.
12552 { 12553 struct sip_threadinfo *th; 12554 12555 #define FORMAT2 "%-30.30s %3.6s %9.9s %6.6s\n" 12556 #define FORMAT "%-30.30s %-6d %-9.9s %-6.6s\n" 12557 12558 switch (cmd) { 12559 case CLI_INIT: 12560 e->command = "sip show tcp"; 12561 e->usage = 12562 "Usage: sip show tcp\n" 12563 " Lists all active TCP/TLS sessions.\n"; 12564 return NULL; 12565 case CLI_GENERATE: 12566 return NULL; 12567 } 12568 12569 if (a->argc != 3) 12570 return CLI_SHOWUSAGE; 12571 12572 ast_cli(a->fd, FORMAT2, "Host", "Port", "Transport", "Type"); 12573 AST_LIST_LOCK(&threadl); 12574 AST_LIST_TRAVERSE(&threadl, th, list) { 12575 ast_cli(a->fd, FORMAT, ast_inet_ntoa(th->tcptls_session->requestor.sin_addr), 12576 ntohs(th->tcptls_session->requestor.sin_port), 12577 get_transport(th->type), 12578 (th->tcptls_session->client ? "Client" : "Server")); 12579 12580 } 12581 AST_LIST_UNLOCK(&threadl); 12582 return CLI_SUCCESS; 12583 #undef FORMAT 12584 #undef FORMAT2 12585 }
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 13498 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_describe_caller_presentation(), ast_strlen_zero(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, cli_yesno(), ast_cli_entry::command, complete_sip_show_user(), FALSE, ast_cli_args::fd, find_user(), ast_cli_args::line, ast_cli_args::n, ast_variable::name, ast_variable::next, ast_cli_args::pos, print_codec_to_cli(), print_group(), SIP_PAGE2_IGNORESDPVERSION, stmode2str(), strefresher2str(), transfermode2str(), TRUE, unref_user(), ast_cli_entry::usage, user, ast_variable::value, and ast_cli_args::word.
13499 { 13500 char cbuf[256]; 13501 struct sip_user *user; 13502 struct ast_variable *v; 13503 int load_realtime; 13504 13505 switch (cmd) { 13506 case CLI_INIT: 13507 e->command = "sip show user"; 13508 e->usage = 13509 "Usage: sip show user <name> [load]\n" 13510 " Shows all details on one SIP user and the current status.\n" 13511 " Option \"load\" forces lookup of peer in realtime storage.\n"; 13512 return NULL; 13513 case CLI_GENERATE: 13514 return complete_sip_show_user(a->line, a->word, a->pos, a->n); 13515 } 13516 13517 if (a->argc < 4) 13518 return CLI_SHOWUSAGE; 13519 13520 /* Load from realtime storage? */ 13521 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? TRUE : FALSE; 13522 13523 user = find_user(a->argv[3], load_realtime); 13524 if (user) { 13525 ast_cli(a->fd, "\n\n"); 13526 ast_cli(a->fd, " * Name : %s\n", user->name); 13527 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 13528 ast_cli(a->fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 13529 ast_cli(a->fd, " Context : %s\n", user->context); 13530 ast_cli(a->fd, " Language : %s\n", user->language); 13531 if (!ast_strlen_zero(user->accountcode)) 13532 ast_cli(a->fd, " Accountcode : %s\n", user->accountcode); 13533 ast_cli(a->fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 13534 ast_cli(a->fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 13535 ast_cli(a->fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 13536 ast_cli(a->fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 13537 ast_cli(a->fd, " Call limit : %d\n", user->call_limit); 13538 ast_cli(a->fd, " Callgroup : "); 13539 print_group(a->fd, user->callgroup, 0); 13540 ast_cli(a->fd, " Pickupgroup : "); 13541 print_group(a->fd, user->pickupgroup, 0); 13542 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 13543 ast_cli(a->fd, " ACL : %s\n", cli_yesno(user->ha != NULL)); 13544 ast_cli(a->fd, " Sess-Timers : %s\n", stmode2str(user->stimer.st_mode_oper)); 13545 ast_cli(a->fd, " Sess-Refresh : %s\n", strefresher2str(user->stimer.st_ref)); 13546 ast_cli(a->fd, " Sess-Expires : %d secs\n", user->stimer.st_max_se); 13547 ast_cli(a->fd, " Sess-Min-SE : %d secs\n", user->stimer.st_min_se); 13548 ast_cli(a->fd, " Ign SDP ver : %s\n", cli_yesno(ast_test_flag(&user->flags[1], SIP_PAGE2_IGNORESDPVERSION))); 13549 13550 ast_cli(a->fd, " Codec Order : ("); 13551 print_codec_to_cli(a->fd, &user->prefs); 13552 ast_cli(a->fd, ")\n"); 13553 13554 ast_cli(a->fd, " Auto-Framing: %s \n", cli_yesno(user->autoframing)); 13555 if (user->chanvars) { 13556 ast_cli(a->fd, " Variables :\n"); 13557 for (v = user->chanvars ; v ; v = v->next) 13558 ast_cli(a->fd, " %s = %s\n", v->name, v->value); 13559 } 13560 13561 ast_cli(a->fd, "\n"); 13562 13563 unref_user(user); 13564 } else { 13565 ast_cli(a->fd, "User %s not found.\n", a->argv[3]); 13566 ast_cli(a->fd, "\n"); 13567 } 13568 13569 return CLI_SUCCESS; 13570 }
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 12588 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, cli_yesno(), ast_cli_entry::command, FALSE, ast_cli_args::fd, FORMAT, nat2str(), SIP_NAT, TRUE, ast_cli_entry::usage, and userl.
12589 { 12590 regex_t regexbuf; 12591 int havepattern = FALSE; 12592 12593 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 12594 12595 switch (cmd) { 12596 case CLI_INIT: 12597 e->command = "sip show users"; 12598 e->usage = 12599 "Usage: sip show users [like <pattern>]\n" 12600 " Lists all known SIP users.\n" 12601 " Optional regular expression pattern is used to filter the user list.\n"; 12602 return NULL; 12603 case CLI_GENERATE: 12604 return NULL; 12605 } 12606 12607 switch (a->argc) { 12608 case 5: 12609 if (!strcasecmp(a->argv[3], "like")) { 12610 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 12611 return CLI_SHOWUSAGE; 12612 havepattern = TRUE; 12613 } else 12614 return CLI_SHOWUSAGE; 12615 case 3: 12616 break; 12617 default: 12618 return CLI_SHOWUSAGE; 12619 } 12620 12621 ast_cli(a->fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 12622 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 12623 ASTOBJ_RDLOCK(iterator); 12624 12625 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 12626 ASTOBJ_UNLOCK(iterator); 12627 continue; 12628 } 12629 12630 ast_cli(a->fd, FORMAT, iterator->name, 12631 iterator->secret, 12632 iterator->accountcode, 12633 iterator->context, 12634 cli_yesno(iterator->ha != NULL), 12635 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 12636 ASTOBJ_UNLOCK(iterator); 12637 } while (0) 12638 ); 12639 12640 if (havepattern) 12641 regfree(®exbuf); 12642 12643 return CLI_SUCCESS; 12644 #undef FORMAT 12645 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 22668 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), get_header(), sip_pvt::initreq, LOG_ERROR, sip_pvt::our_contact, sip_alreadygone(), sip_scheddestroy(), SIP_TRANS_TIMEOUT, strcasestr(), strsep(), and transmit_response_reliable().
Referenced by sip_transfer().
22669 { 22670 char *cdest; 22671 char *extension, *host, *port; 22672 char tmp[80]; 22673 22674 cdest = ast_strdupa(dest); 22675 22676 extension = strsep(&cdest, "@"); 22677 host = strsep(&cdest, ":"); 22678 port = strsep(&cdest, ":"); 22679 if (ast_strlen_zero(extension)) { 22680 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 22681 return 0; 22682 } 22683 22684 /* we'll issue the redirect message here */ 22685 if (!host) { 22686 char *localtmp; 22687 22688 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 22689 if (ast_strlen_zero(tmp)) { 22690 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 22691 return 0; 22692 } 22693 if ( ( (localtmp = strcasestr(tmp, "sip:")) || (localtmp = strcasestr(tmp, "sips:")) ) 22694 && (localtmp = strchr(localtmp, '@'))) { 22695 char lhost[80], lport[80]; 22696 22697 memset(lhost, 0, sizeof(lhost)); 22698 memset(lport, 0, sizeof(lport)); 22699 localtmp++; 22700 /* This is okey because lhost and lport are as big as tmp */ 22701 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 22702 if (ast_strlen_zero(lhost)) { 22703 ast_log(LOG_ERROR, "Can't find the host address\n"); 22704 return 0; 22705 } 22706 host = ast_strdupa(lhost); 22707 if (!ast_strlen_zero(lport)) { 22708 port = ast_strdupa(lport); 22709 } 22710 } 22711 } 22712 22713 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 22714 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 22715 22716 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 22717 sip_alreadygone(p); 22718 /* hangup here */ 22719 return 0; 22720 }
static struct sip_st_dlg * sip_st_alloc | ( | struct sip_pvt *const | p | ) | [static] |
Allocate Session-Timers struct w/in dialog.
Definition at line 6006 of file chan_sip.c.
References ast_calloc, ast_log(), LOG_ERROR, sip_st_dlg::st_schedid, and sip_pvt::stimer.
Referenced by handle_request_invite(), and st_get_mode().
06007 { 06008 struct sip_st_dlg *stp; 06009 06010 if (p->stimer) { 06011 ast_log(LOG_ERROR, "Session-Timer struct already allocated\n"); 06012 return p->stimer; 06013 } 06014 06015 if (!(stp = ast_calloc(1, sizeof(struct sip_st_dlg)))) 06016 return NULL; 06017 06018 p->stimer = stp; 06019 06020 stp->st_schedid = -1; /* Session-Timers ast_sched scheduler id */ 06021 06022 return p->stimer; 06023 }
static int sip_standard_port | ( | enum sip_transport | type, | |
int | port | |||
) | [static] |
Returns the port to use for this socket.
type | The type of transport used | |
port | Port we are checking to see if it's the standard port. |
Definition at line 19408 of file chan_sip.c.
References SIP_TRANSPORT_TLS, STANDARD_SIP_PORT, and STANDARD_TLS_PORT.
Referenced by build_contact(), initreqprep(), and transmit_notify_with_mwi().
19409 { 19410 if (type & SIP_TRANSPORT_TLS) 19411 return port == STANDARD_TLS_PORT; 19412 else 19413 return port == STANDARD_SIP_PORT; 19414 }
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 17213 of file chan_sip.c.
References change_t38_state(), T38_DISABLED, and transmit_response_reliable().
Referenced by handle_request_invite().
17214 { 17215 struct sip_pvt *p = (struct sip_pvt *) data; 17216 17217 change_t38_state(p, T38_DISABLED); 17218 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 17219 p->t38id = -1; 17220 return 0; 17221 }
static struct ast_tcptls_session_instance* sip_tcp_locate | ( | struct sockaddr_in * | s | ) | [static] |
Find thread for TCP/TLS session (based on IP/Port.
Definition at line 19421 of file chan_sip.c.
References ao2_ref(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_tcptls_session_instance::requestor, and sip_threadinfo::tcptls_session.
Referenced by sip_prepare_socket().
19422 { 19423 struct sip_threadinfo *th; 19424 struct ast_tcptls_session_instance *tcptls_instance = NULL; 19425 19426 AST_LIST_LOCK(&threadl); 19427 AST_LIST_TRAVERSE(&threadl, th, list) { 19428 if ((s->sin_family == th->tcptls_session->requestor.sin_family) && 19429 (s->sin_addr.s_addr == th->tcptls_session->requestor.sin_addr.s_addr) && 19430 (s->sin_port == th->tcptls_session->requestor.sin_port)) { 19431 tcptls_instance = (ao2_ref(th->tcptls_session, +1), th->tcptls_session); 19432 break; 19433 } 19434 } 19435 AST_LIST_UNLOCK(&threadl); 19436 19437 return tcptls_instance; 19438 }
static void * sip_tcp_worker_fn | ( | void * | ) | [static] |
SIP TCP connection handler.
Definition at line 2212 of file chan_sip.c.
References _sip_tcp_helper_thread().
Referenced by sip_prepare_socket().
02213 { 02214 struct ast_tcptls_session_instance *tcptls_session = data; 02215 02216 return _sip_tcp_helper_thread(NULL, tcptls_session); 02217 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 5377 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().
05378 { 05379 struct sip_pvt *p = ast->tech_pvt; 05380 int res; 05381 05382 if (dest == NULL) /* functions below do not take a NULL */ 05383 dest = ""; 05384 sip_pvt_lock(p); 05385 if (ast->_state == AST_STATE_RING) 05386 res = sip_sipredirect(p, dest); 05387 else 05388 res = transmit_refer(p, dest); 05389 sip_pvt_unlock(p); 05390 return res; 05391 }
static char * sip_unregister | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Unregister (force expiration) a SIP peer in the registry via CLI.
Definition at line 13618 of file chan_sip.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_SCHED_DEL, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_unregister(), sip_peer::expire, expire_register(), ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, sched, ast_cli_entry::usage, and ast_cli_args::word.
13619 { 13620 struct sip_peer *peer; 13621 int load_realtime = 0; 13622 13623 switch (cmd) { 13624 case CLI_INIT: 13625 e->command = "sip unregister"; 13626 e->usage = 13627 "Usage: sip unregister <peer>\n" 13628 " Unregister (force expiration) a SIP peer from the registry\n"; 13629 return NULL; 13630 case CLI_GENERATE: 13631 return complete_sip_unregister(a->line, a->word, a->pos, a->n); 13632 } 13633 13634 if (a->argc != 3) 13635 return CLI_SHOWUSAGE; 13636 13637 if ((peer = find_peer(a->argv[2], NULL, load_realtime, 0))) { 13638 if (peer->expire > 0) { 13639 AST_SCHED_DEL(sched, peer->expire); 13640 expire_register(peer); 13641 ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]); 13642 } else { 13643 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 13644 } 13645 } else { 13646 ast_cli(a->fd, "Peer unknown: \'%s\'. Not unregistered.\n", a->argv[2]); 13647 } 13648 13649 return CLI_SUCCESS; 13650 }
static int sip_uri_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
Definition at line 17130 of file chan_sip.c.
References ast_strdupa, S_OR, sip_uri_headers_cmp(), sip_uri_params_cmp(), and strsep().
Referenced by handle_request_invite().
17131 { 17132 char *uri1 = ast_strdupa(input1); 17133 char *uri2 = ast_strdupa(input2); 17134 char *host1; 17135 char *host2; 17136 char *params1; 17137 char *params2; 17138 char *headers1; 17139 char *headers2; 17140 17141 /* Strip off "sip:" from the URI. We know this is present 17142 * because it was checked back in parse_request() 17143 */ 17144 strsep(&uri1, ":"); 17145 strsep(&uri2, ":"); 17146 17147 if ((host1 = strchr(uri1, '@'))) { 17148 *host1++ = '\0'; 17149 } 17150 if ((host2 = strchr(uri2, '@'))) { 17151 *host2++ = '\0'; 17152 } 17153 17154 /* Check for mismatched username and passwords. This is the 17155 * only case-sensitive comparison of a SIP URI 17156 */ 17157 if ((host1 && !host2) || 17158 (host2 && !host1) || 17159 (host1 && host2 && strcmp(uri1, uri2))) { 17160 return 1; 17161 } 17162 17163 if (!host1) 17164 host1 = uri1; 17165 if (!host2) 17166 host2 = uri2; 17167 17168 /* Strip off the parameters and headers so we can compare 17169 * host and port 17170 */ 17171 17172 if ((params1 = strchr(host1, ';'))) { 17173 *params1++ = '\0'; 17174 } 17175 if ((params2 = strchr(host2, ';'))) { 17176 *params2++ = '\0'; 17177 } 17178 17179 /* Headers come after parameters, but there may be headers without 17180 * parameters, thus the S_OR 17181 */ 17182 if ((headers1 = strchr(S_OR(params1, host1), '?'))) { 17183 *headers1++ = '\0'; 17184 } 17185 if ((headers2 = strchr(S_OR(params2, host2), '?'))) { 17186 *headers2++ = '\0'; 17187 } 17188 17189 /* Now the host/port are properly isolated. We can get by with a string comparison 17190 * because the SIP URI checking rules have some interesting exceptions that make 17191 * this possible. I will note 2 in particular 17192 * 1. hostnames which resolve to the same IP address as well as a hostname and its 17193 * IP address are not considered a match with SIP URI's. 17194 * 2. If one URI specifies a port and the other does not, then the URIs do not match. 17195 * This includes if one URI explicitly contains port 5060 and the other implies it 17196 * by not having a port specified. 17197 */ 17198 17199 if (strcasecmp(host1, host2)) { 17200 return 1; 17201 } 17202 17203 /* Headers have easier rules to follow, so do those first */ 17204 if (sip_uri_headers_cmp(headers1, headers2)) { 17205 return 1; 17206 } 17207 17208 /* And now the parameters. Ugh */ 17209 return sip_uri_params_cmp(params1, params2); 17210 }
static int sip_uri_headers_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
helper routine for sip_uri_cmp
This takes the "headers" from two SIP URIs and determines if the URIs match. The rules for headers is simple. If a header appears in one URI, then it must also appear in the other URI. The order in which the headers appear does not matter.
input1 | Headers from URI 1 | |
input2 | Headers from URI 2 |
Definition at line 17084 of file chan_sip.c.
References ast_strdupa, ast_strlen_zero(), strcasestr(), and strsep().
Referenced by sip_uri_cmp().
17085 { 17086 char *headers1 = NULL; 17087 char *headers2 = NULL; 17088 int zerolength1 = 0; 17089 int zerolength2 = 0; 17090 int different = 0; 17091 char *header1; 17092 17093 if (ast_strlen_zero(input1)) { 17094 zerolength1 = 1; 17095 } else { 17096 headers1 = ast_strdupa(input1); 17097 } 17098 17099 if (ast_strlen_zero(input2)) { 17100 zerolength2 = 1; 17101 } else { 17102 headers2 = ast_strdupa(input2); 17103 } 17104 17105 if ((zerolength1 && !zerolength2) || 17106 (zerolength2 && !zerolength1)) 17107 return 1; 17108 17109 if (zerolength1 && zerolength2) 17110 return 0; 17111 17112 /* At this point, we can definitively state that both inputs are 17113 * not zero-length. First, one more optimization. If the length 17114 * of the headers is not equal, then we definitely have no match 17115 */ 17116 if (strlen(headers1) != strlen(headers2)) { 17117 return 1; 17118 } 17119 17120 for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) { 17121 if (!strcasestr(headers2, header1)) { 17122 different = 1; 17123 break; 17124 } 17125 } 17126 17127 return different; 17128 }
static int sip_uri_params_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
helper routine for sip_uri_cmp
This takes the parameters from two SIP URIs and determines if the URIs match. The rules for parameters *suck*. Here's a breakdown 1. If a parameter appears in both URIs, then they must have the same value in order for the URIs to match 2. If one URI has a user, maddr, ttl, or method parameter, then the other URI must also have that parameter and must have the same value in order for the URIs to match 3. All other headers appearing in only one URI are not considered when determining if URIs match
input1 | Parameters from URI 1 | |
input2 | Parameters from URI 2 |
Definition at line 16944 of file chan_sip.c.
References ast_strdupa, and ast_strlen_zero().
Referenced by sip_uri_cmp().
16945 { 16946 char *params1 = NULL; 16947 char *params2 = NULL; 16948 char *pos1; 16949 char *pos2; 16950 int zerolength1 = 0; 16951 int zerolength2 = 0; 16952 int maddrmatch = 0; 16953 int ttlmatch = 0; 16954 int usermatch = 0; 16955 int methodmatch = 0; 16956 16957 if (ast_strlen_zero(input1)) { 16958 zerolength1 = 1; 16959 } else { 16960 params1 = ast_strdupa(input1); 16961 } 16962 if (ast_strlen_zero(input2)) { 16963 zerolength2 = 1; 16964 } else { 16965 params2 = ast_strdupa(input2); 16966 } 16967 16968 /*Quick optimization. If both params are zero-length, then 16969 * they match 16970 */ 16971 if (zerolength1 && zerolength2) { 16972 return 0; 16973 } 16974 16975 pos1 = params1; 16976 while (!ast_strlen_zero(pos1)) { 16977 char *name1 = pos1; 16978 char *value1 = strchr(pos1, '='); 16979 char *semicolon1 = strchr(pos1, ';'); 16980 int matched = 0; 16981 if (semicolon1) { 16982 *semicolon1++ = '\0'; 16983 } 16984 if (!value1) { 16985 goto fail; 16986 } 16987 *value1++ = '\0'; 16988 /* Checkpoint reached. We have the name and value parsed for param1 16989 * We have to duplicate params2 each time through the second loop 16990 * or else we can't search and replace the semicolons with \0 each 16991 * time 16992 */ 16993 pos2 = ast_strdupa(params2); 16994 while (!ast_strlen_zero(pos2)) { 16995 char *name2 = pos2; 16996 char *value2 = strchr(pos2, '='); 16997 char *semicolon2 = strchr(pos2, ';'); 16998 if (semicolon2) { 16999 *semicolon2++ = '\0'; 17000 } 17001 if (!value2) { 17002 goto fail; 17003 } 17004 *value2++ = '\0'; 17005 if (!strcasecmp(name1, name2)) { 17006 if (strcasecmp(value1, value2)) { 17007 goto fail; 17008 } else { 17009 matched = 1; 17010 break; 17011 } 17012 } 17013 pos2 = semicolon2; 17014 } 17015 /* Need to see if the parameter we're looking at is one of the 'must-match' parameters */ 17016 if (!strcasecmp(name1, "maddr")) { 17017 if (matched) { 17018 maddrmatch = 1; 17019 } else { 17020 goto fail; 17021 } 17022 } else if (!strcasecmp(name1, "ttl")) { 17023 if (matched) { 17024 ttlmatch = 1; 17025 } else { 17026 goto fail; 17027 } 17028 } else if (!strcasecmp(name1, "user")) { 17029 if (matched) { 17030 usermatch = 1; 17031 } else { 17032 goto fail; 17033 } 17034 } else if (!strcasecmp(name1, "method")) { 17035 if (matched) { 17036 methodmatch = 1; 17037 } else { 17038 goto fail; 17039 } 17040 } 17041 pos1 = semicolon1; 17042 } 17043 17044 /* We've made it out of that horrible O(m*n) construct and there are no 17045 * failures yet. We're not done yet, though, because params2 could have 17046 * an maddr, ttl, user, or method header and params1 did not. 17047 */ 17048 pos2 = params2; 17049 while (!ast_strlen_zero(pos2)) { 17050 char *name2 = pos2; 17051 char *value2 = strchr(pos2, '='); 17052 char *semicolon2 = strchr(pos2, ';'); 17053 if (semicolon2) { 17054 *semicolon2++ = '\0'; 17055 } 17056 if (!value2) { 17057 goto fail; 17058 } 17059 *value2++ = '\0'; 17060 if ((!strcasecmp(name2, "maddr") && !maddrmatch) || 17061 (!strcasecmp(name2, "ttl") && !ttlmatch) || 17062 (!strcasecmp(name2, "user") && !usermatch) || 17063 (!strcasecmp(name2, "method") && !methodmatch)) { 17064 goto fail; 17065 } 17066 } 17067 return 0; 17068 17069 fail: 17070 return 1; 17071 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 5177 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_multiple(), ast_log(), ast_rtp_new_source(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), change_t38_state(), FALSE, ast_frame::frametype, INV_EARLY_MEDIA, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, SIP_OUTGOING, SIP_PAGE2_T38SUPPORT, SIP_PROGRESS_SENT, sip_pvt_lock, sip_pvt_unlock, ast_frame::subclass, T38_DISABLED, T38_ENABLED, T38_LOCAL_REINVITE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), transmit_response_with_sdp(), TRUE, ast_channel::writeformat, and XMIT_UNRELIABLE.
05178 { 05179 struct sip_pvt *p = ast->tech_pvt; 05180 int res = 0; 05181 05182 switch (frame->frametype) { 05183 case AST_FRAME_VOICE: 05184 if (!(frame->subclass & ast->nativeformats)) { 05185 char s1[512], s2[512], s3[512]; 05186 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 05187 frame->subclass, 05188 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 05189 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 05190 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 05191 ast->readformat, 05192 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 05193 ast->writeformat); 05194 return 0; 05195 } 05196 if (p) { 05197 sip_pvt_lock(p); 05198 if (p->rtp) { 05199 /* If channel is not up, activate early media session */ 05200 if ((ast->_state != AST_STATE_UP) && 05201 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 05202 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 05203 ast_rtp_new_source(p->rtp); 05204 p->invitestate = INV_EARLY_MEDIA; 05205 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE, FALSE); 05206 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 05207 } else if (p->t38.state == T38_ENABLED && !p->t38.direct) { 05208 change_t38_state(p, T38_DISABLED); 05209 transmit_reinvite_with_sdp(p, FALSE, FALSE); 05210 } else { 05211 p->lastrtptx = time(NULL); 05212 res = ast_rtp_write(p->rtp, frame); 05213 } 05214 } 05215 sip_pvt_unlock(p); 05216 } 05217 break; 05218 case AST_FRAME_VIDEO: 05219 if (p) { 05220 sip_pvt_lock(p); 05221 if (p->vrtp) { 05222 /* Activate video early media */ 05223 if ((ast->_state != AST_STATE_UP) && 05224 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 05225 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 05226 p->invitestate = INV_EARLY_MEDIA; 05227 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE, FALSE); 05228 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 05229 } 05230 p->lastrtptx = time(NULL); 05231 res = ast_rtp_write(p->vrtp, frame); 05232 } 05233 sip_pvt_unlock(p); 05234 } 05235 break; 05236 case AST_FRAME_TEXT: 05237 if (p) { 05238 sip_pvt_lock(p); 05239 if (p->trtp) { 05240 /* Activate text early media */ 05241 if ((ast->_state != AST_STATE_UP) && 05242 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 05243 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 05244 p->invitestate = INV_EARLY_MEDIA; 05245 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE, FALSE); 05246 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 05247 } 05248 p->lastrtptx = time(NULL); 05249 res = ast_rtp_write(p->trtp, frame); 05250 } 05251 sip_pvt_unlock(p); 05252 } 05253 break; 05254 case AST_FRAME_IMAGE: 05255 return 0; 05256 break; 05257 case AST_FRAME_MODEM: 05258 if (p) { 05259 sip_pvt_lock(p); 05260 /* UDPTL requires two-way communication, so early media is not needed here. 05261 we simply forget the frames if we get modem frames before the bridge is up. 05262 Fax will re-transmit. 05263 */ 05264 if (ast->_state == AST_STATE_UP) { 05265 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->t38.state == T38_DISABLED) { 05266 if (!p->pendinginvite) { 05267 change_t38_state(p, T38_LOCAL_REINVITE); 05268 transmit_reinvite_with_sdp(p, TRUE, FALSE); 05269 } 05270 } else if (p->udptl && p->t38.state == T38_ENABLED) { 05271 res = ast_udptl_write(p->udptl, frame); 05272 } 05273 } 05274 sip_pvt_unlock(p); 05275 } 05276 break; 05277 default: 05278 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 05279 return 0; 05280 } 05281 05282 return res; 05283 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 19262 of file chan_sip.c.
References ast_debug, ast_log(), bindaddr, errno, handle_request_do(), len(), LOG_NOTICE, LOG_WARNING, set_socket_transport(), SIP_TRANSPORT_UDP, and sipsock.
Referenced by do_monitor().
19263 { 19264 struct sip_request req; 19265 struct sockaddr_in sin = { 0, }; 19266 int res; 19267 socklen_t len = sizeof(sin); 19268 19269 memset(&req, 0, sizeof(req)); 19270 res = recvfrom(fd, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 19271 if (res < 0) { 19272 #if !defined(__FreeBSD__) 19273 if (errno == EAGAIN) 19274 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 19275 else 19276 #endif 19277 if (errno != ECONNREFUSED) 19278 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 19279 return 1; 19280 } 19281 if (res == sizeof(req.data) - 1) 19282 ast_debug(1, "Received packet exceeds buffer. Data is possibly lost\n"); 19283 19284 req.data[res] = '\0'; 19285 req.len = res; 19286 19287 req.socket.fd = sipsock; 19288 set_socket_transport(&req.socket, SIP_TRANSPORT_UDP); 19289 req.socket.tcptls_session = NULL; 19290 req.socket.port = bindaddr.sin_port; 19291 19292 handle_request_do(&req, &sin); 19293 19294 return 1; 19295 }
Get the session-timer mode.
p | pointer to the SIP dialog |
Definition at line 20132 of file chan_sip.c.
References find_peer(), find_user(), sip_pvt::peername, pp, SESSION_TIMER_MODE_INVALID, sip_st_alloc(), sip_st_dlg::st_cached_mode, sip_st_cfg::st_mode_oper, sip_user::stimer, sip_pvt::stimer, unref_peer(), unref_user(), and sip_pvt::username.
Referenced by handle_request_invite(), handle_response_invite(), and transmit_invite().
20133 { 20134 if (!p->stimer) 20135 sip_st_alloc(p); 20136 20137 if (p->stimer->st_cached_mode != SESSION_TIMER_MODE_INVALID) 20138 return p->stimer->st_cached_mode; 20139 20140 if (p->username) { 20141 struct sip_user *up = find_user(p->username, 1); 20142 if (up) { 20143 p->stimer->st_cached_mode = up->stimer.st_mode_oper; 20144 unref_user(up); 20145 return p->stimer->st_cached_mode; 20146 } 20147 } 20148 if (p->peername) { 20149 struct sip_peer *pp = find_peer(p->peername, NULL, 1, 0); 20150 if (pp) { 20151 p->stimer->st_cached_mode = pp->stimer.st_mode_oper; 20152 unref_peer(pp); 20153 return p->stimer->st_cached_mode; 20154 } 20155 } 20156 20157 p->stimer->st_cached_mode = global_st_mode; 20158 return global_st_mode; 20159 }
enum st_refresher st_get_refresher | ( | struct sip_pvt * | p | ) | [static] |
Get the entity (UAC or UAS) that's acting as the session-timer refresher.
p | pointer to the SIP dialog |
Definition at line 20103 of file chan_sip.c.
References find_peer(), find_user(), sip_pvt::peername, pp, SESSION_TIMER_REFRESHER_AUTO, sip_st_dlg::st_cached_ref, sip_st_cfg::st_ref, sip_user::stimer, sip_pvt::stimer, and sip_pvt::username.
Referenced by handle_request_invite().
20104 { 20105 if (p->stimer->st_cached_ref != SESSION_TIMER_REFRESHER_AUTO) 20106 return p->stimer->st_cached_ref; 20107 20108 if (p->username) { 20109 struct sip_user *up = find_user(p->username, 1); 20110 if (up) { 20111 p->stimer->st_cached_ref = up->stimer.st_ref; 20112 return up->stimer.st_ref; 20113 } 20114 } 20115 20116 if (p->peername) { 20117 struct sip_peer *pp = find_peer(p->peername, NULL, 1, 0); 20118 if (pp) { 20119 p->stimer->st_cached_ref = pp->stimer.st_ref; 20120 return pp->stimer.st_ref; 20121 } 20122 } 20123 20124 p->stimer->st_cached_ref = global_st_refresher; 20125 return global_st_refresher; 20126 }
int st_get_se | ( | struct sip_pvt * | p, | |
int | max | |||
) | [static] |
Get Max or Min SE (session timer expiry).
p | pointer to the SIP dialog | |
max | if true, get max se, otherwise min se |
Definition at line 20048 of file chan_sip.c.
References find_peer(), find_user(), sip_pvt::peername, pp, sip_st_dlg::st_cached_max_se, sip_st_dlg::st_cached_min_se, sip_st_cfg::st_max_se, sip_st_cfg::st_min_se, sip_user::stimer, sip_pvt::stimer, TRUE, unref_peer(), unref_user(), and sip_pvt::username.
Referenced by handle_request_invite(), reqprep(), and transmit_invite().
20049 { 20050 if (max == TRUE) { 20051 if (p->stimer->st_cached_max_se) { 20052 return p->stimer->st_cached_max_se; 20053 } else { 20054 if (p->username) { 20055 struct sip_user *up = find_user(p->username, 1); 20056 if (up) { 20057 p->stimer->st_cached_max_se = up->stimer.st_max_se; 20058 unref_user(up); 20059 return (p->stimer->st_cached_max_se); 20060 } 20061 } 20062 if (p->peername) { 20063 struct sip_peer *pp = find_peer(p->peername, NULL, 1, 0); 20064 if (pp) { 20065 p->stimer->st_cached_max_se = pp->stimer.st_max_se; 20066 unref_peer(pp); 20067 return (p->stimer->st_cached_max_se); 20068 } 20069 } 20070 } 20071 p->stimer->st_cached_max_se = global_max_se; 20072 return (p->stimer->st_cached_max_se); 20073 } else { 20074 if (p->stimer->st_cached_min_se) { 20075 return p->stimer->st_cached_min_se; 20076 } else { 20077 if (p->username) { 20078 struct sip_user *up = find_user(p->username, 1); 20079 if (up) { 20080 p->stimer->st_cached_min_se = up->stimer.st_min_se; 20081 unref_user(up); 20082 return (p->stimer->st_cached_min_se); 20083 } 20084 } 20085 if (p->peername) { 20086 struct sip_peer *pp = find_peer(p->peername, NULL, 1, 0); 20087 if (pp) { 20088 p->stimer->st_cached_min_se = pp->stimer.st_min_se; 20089 unref_peer(pp); 20090 return (p->stimer->st_cached_min_se); 20091 } 20092 } 20093 } 20094 p->stimer->st_cached_min_se = global_min_se; 20095 return (p->stimer->st_cached_min_se); 20096 } 20097 }
static void start_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Start session timer.
Definition at line 19867 of file chan_sip.c.
References ast_debug, ast_log(), ast_sched_add(), sip_pvt::callid, LOG_ERROR, LOG_WARNING, proc_session_timer(), sched, sip_st_dlg::st_interval, sip_st_dlg::st_schedid, and sip_pvt::stimer.
Referenced by handle_request_invite(), handle_response_invite(), and restart_session_timer().
19868 { 19869 if (!p->stimer) { 19870 ast_log(LOG_WARNING, "Null stimer in start_session_timer - %s\n", p->callid); 19871 return; 19872 } 19873 19874 p->stimer->st_schedid = ast_sched_add(sched, p->stimer->st_interval * 1000 / 2, proc_session_timer, p); 19875 if (p->stimer->st_schedid < 0) { 19876 ast_log(LOG_ERROR, "ast_sched_add failed.\n"); 19877 } 19878 ast_debug(2, "Session timer started: %d - %s\n", p->stimer->st_schedid, p->callid); 19879 }
static const char* stmode2str | ( | enum st_mode | m | ) | [static] |
Definition at line 12488 of file chan_sip.c.
References map_x_s(), and stmodes.
Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_user().
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 15884 of file chan_sip.c.
References ast_rtp_stop(), ast_udptl_stop(), sip_pvt::rtp, sip_pvt::trtp, sip_pvt::udptl, and sip_pvt::vrtp.
Referenced by handle_request_bye(), handle_request_cancel(), handle_response(), and sip_hangup().
15885 { 15886 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 15887 if (p->rtp) 15888 ast_rtp_stop(p->rtp); 15889 if (p->vrtp) 15890 ast_rtp_stop(p->vrtp); 15891 if (p->trtp) 15892 ast_rtp_stop(p->trtp); 15893 if (p->udptl) 15894 ast_udptl_stop(p->udptl); 15895 }
static void stop_session_timer | ( | struct sip_pvt * | p | ) | [static] |
Session-Timers: Stop session timer.
Definition at line 19851 of file chan_sip.c.
References ast_debug, ast_log(), ast_sched_del(), sip_pvt::callid, FALSE, LOG_WARNING, sched, sip_st_dlg::st_active, sip_st_dlg::st_schedid, sip_pvt::stimer, and TRUE.
Referenced by handle_request_bye(), proc_session_timer(), sip_hangup(), and sip_scheddestroy().
19852 { 19853 if (!p->stimer) { 19854 ast_log(LOG_WARNING, "Null stimer in stop_session_timer - %s\n", p->callid); 19855 return; 19856 } 19857 19858 if (p->stimer->st_active == TRUE) { 19859 p->stimer->st_active = FALSE; 19860 ast_sched_del(sched, p->stimer->st_schedid); 19861 ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid); 19862 } 19863 }
static int str2dtmfmode | ( | const char * | str | ) | [static] |
static enum st_mode str2stmode | ( | const char * | s | ) | [static] |
Definition at line 12493 of file chan_sip.c.
References map_s_x(), and stmodes.
Referenced by build_peer(), and build_user().
static enum st_refresher str2strefresher | ( | const char * | s | ) | [static] |
Definition at line 12511 of file chan_sip.c.
References map_s_x(), and strefreshers.
Referenced by build_peer(), and build_user().
12512 { 12513 return map_s_x(strefreshers, s, -1); 12514 }
static const char * strefresher2str | ( | enum st_refresher | r | ) | [static] |
Definition at line 12506 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().
12507 { 12508 return map_x_s(strefreshers, r, "Unknown"); 12509 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 13851 of file chan_sip.c.
References ARRAY_LEN, subscription_types, cfsubscription_types::text, and type.
Referenced by show_channels_cb(), and sip_show_channel().
13852 { 13853 int i; 13854 13855 for (i = 1; i < ARRAY_LEN(subscription_types); i++) { 13856 if (subscription_types[i].type == subtype) { 13857 return subscription_types[i].text; 13858 } 13859 } 13860 return subscription_types[0].text; 13861 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 8352 of file chan_sip.c.
References ast_debug, T38FAX_RATE_12000, T38FAX_RATE_14400, T38FAX_RATE_2400, T38FAX_RATE_4800, T38FAX_RATE_7200, and T38FAX_RATE_9600.
Referenced by add_sdp().
08353 { 08354 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 08355 08356 if (maxrate & T38FAX_RATE_14400) { 08357 ast_debug(2, "T38MaxBitRate 14400 found\n"); 08358 return 14400; 08359 } else if (maxrate & T38FAX_RATE_12000) { 08360 ast_debug(2, "T38MaxBitRate 12000 found\n"); 08361 return 12000; 08362 } else if (maxrate & T38FAX_RATE_9600) { 08363 ast_debug(2, "T38MaxBitRate 9600 found\n"); 08364 return 9600; 08365 } else if (maxrate & T38FAX_RATE_7200) { 08366 ast_debug(2, "T38MaxBitRate 7200 found\n"); 08367 return 7200; 08368 } else if (maxrate & T38FAX_RATE_4800) { 08369 ast_debug(2, "T38MaxBitRate 4800 found\n"); 08370 return 4800; 08371 } else if (maxrate & T38FAX_RATE_2400) { 08372 ast_debug(2, "T38MaxBitRate 2400 found\n"); 08373 return 2400; 08374 } else { 08375 ast_debug(2, "Strange, T38MaxBitRate NOT found in peers T38 SDP.\n"); 08376 return 0; 08377 } 08378 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 21041 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ASTOBJ_INIT, default_prefs, reg_source_db(), set_peer_defaults(), and TRUE.
Referenced by register_verify().
21042 { 21043 struct sip_peer *peer; 21044 21045 if (!(peer = ast_calloc(1, sizeof(*peer)))) 21046 return NULL; 21047 21048 apeerobjs++; 21049 ASTOBJ_INIT(peer); 21050 set_peer_defaults(peer); 21051 21052 ast_copy_string(peer->name, name, sizeof(peer->name)); 21053 21054 peer->selfdestruct = TRUE; 21055 peer->host_dynamic = TRUE; 21056 peer->prefs = default_prefs; 21057 reg_source_db(peer); 21058 21059 return peer; 21060 }
static void temp_pvt_cleanup | ( | void * | ) | [static] |
Definition at line 8044 of file chan_sip.c.
References ast_free, and ast_string_field_free_memory.
08045 { 08046 struct sip_pvt *p = data; 08047 08048 ast_string_field_free_memory(p); 08049 08050 ast_free(data); 08051 }
static int temp_pvt_init | ( | void * | ) | [static] |
Definition at line 8036 of file chan_sip.c.
References ast_string_field_init, and sip_pvt::do_history.
08037 { 08038 struct sip_pvt *p = data; 08039 08040 p->do_history = 0; /* XXX do we need it ? isn't already all 0 ? */ 08041 return ast_string_field_init(p, 512); 08042 }
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:
* * sip:user:password@host:port;uri-parameters?headers * sips:user:password@host:port;uri-parameters?headers * *
Definition at line 10985 of file chan_sip.c.
Referenced by check_user_full(), and register_verify().
10986 { 10987 char *t = uri; 10988 while (*t && *t > ' ' && *t != ';') 10989 t++; 10990 *t = '\0'; 10991 return uri; 10992 }
static char * transfermode2str | ( | enum transfermodes | mode | ) | const [static] |
Convert transfer mode to text string.
Definition at line 12452 of file chan_sip.c.
References TRANSFER_CLOSED, and TRANSFER_OPENFORALL.
Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_user().
12453 { 12454 if (mode == TRANSFER_OPENFORALL) 12455 return "open"; 12456 else if (mode == TRANSFER_CLOSED) 12457 return "closed"; 12458 return "strict"; 12459 }
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 users/peers from fishers.
Definition at line 10882 of file chan_sip.c.
References AST_DYNSTR_BUILD_FAILED, ast_random(), ast_skip_blanks(), ast_str_set(), ast_str_thread_get(), ast_string_field_build, ast_strlen_zero(), buf, check_auth_buf, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, get_header(), sip_request::ignore, sip_pvt::initreq, sip_pvt::randdata, s, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, strsep(), transmit_response(), and transmit_response_with_auth().
Referenced by handle_request_invite(), handle_request_subscribe(), and register_verify().
10883 { 10884 /* We have to emulate EXACTLY what we'd get with a good peer 10885 * and a bad password, or else we leak information. */ 10886 const char *response = "407 Proxy Authentication Required"; 10887 const char *reqheader = "Proxy-Authorization"; 10888 const char *respheader = "Proxy-Authenticate"; 10889 const char *authtoken; 10890 struct ast_str *buf; 10891 char *c; 10892 10893 /* table of recognised keywords, and their value in the digest */ 10894 enum keys { K_NONCE, K_LAST }; 10895 struct x { 10896 const char *key; 10897 const char *s; 10898 } *i, keys[] = { 10899 [K_NONCE] = { "nonce=", "" }, 10900 [K_LAST] = { NULL, NULL} 10901 }; 10902 10903 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 10904 response = "401 Unauthorized"; 10905 reqheader = "Authorization"; 10906 respheader = "WWW-Authenticate"; 10907 } 10908 authtoken = get_header(req, reqheader); 10909 if (req->ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 10910 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 10911 * information */ 10912 transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0); 10913 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 10914 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10915 return; 10916 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 10917 /* We have no auth, so issue challenge and request authentication */ 10918 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 10919 transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0); 10920 /* Schedule auto destroy in 32 seconds */ 10921 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10922 return; 10923 } 10924 10925 if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 10926 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 10927 return; 10928 } 10929 10930 /* Make a copy of the response and parse it */ 10931 if (ast_str_set(&buf, 0, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) { 10932 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 10933 return; 10934 } 10935 10936 c = buf->str; 10937 10938 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 10939 for (i = keys; i->key != NULL; i++) { 10940 const char *separator = ","; /* default */ 10941 10942 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 10943 continue; 10944 } 10945 /* Found. Skip keyword, take text in quotes or up to the separator. */ 10946 c += strlen(i->key); 10947 if (*c == '"') { /* in quotes. Skip first and look for last */ 10948 c++; 10949 separator = "\""; 10950 } 10951 i->s = c; 10952 strsep(&c, separator); 10953 break; 10954 } 10955 if (i->key == NULL) { /* not found, jump after space or comma */ 10956 strsep(&c, " ,"); 10957 } 10958 } 10959 10960 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 10961 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { 10962 if (!req->ignore) { 10963 ast_string_field_build(p, randdata, "%08lx", ast_random()); 10964 } 10965 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 10966 10967 /* Schedule auto destroy in 32 seconds */ 10968 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10969 } else { 10970 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 10971 } 10972 }
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 10031 of file chan_sip.c.
References add_digit(), ast_test_flag, sip_pvt::flags, sip_pvt::ocseq, reqprep(), send_request(), SIP_DTMF, SIP_DTMF_SHORTINFO, SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
10032 { 10033 struct sip_request req; 10034 10035 reqprep(&req, p, SIP_INFO, 0, 1); 10036 add_digit(&req, digit, duration, (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO)); 10037 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 10038 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 10041 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
10042 { 10043 struct sip_request req; 10044 10045 reqprep(&req, p, SIP_INFO, 0, 1); 10046 add_vidupdate(&req); 10047 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 10048 }
static int transmit_invite | ( | struct sip_pvt * | p, | |
int | sipmethod, | |||
int | sdp, | |||
int | init | |||
) | [static] |
Build REFER/INVITE/OPTIONS message and transmit it.
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 | |
p | sip_pvt structure | |
sdp | unknown | |
sipmethod | unknown |
Definition at line 9229 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), ast_channel_lock, ast_channel_unlock, ast_debug, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), ast_udptl_offered_from_local(), ast_var_name(), ast_var_value(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::branch, buf, build_via(), chan, ast_var_t::entries, FALSE, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::invite_branch, sip_pvt::lastinvite, LOG_WARNING, sip_request::method, ast_channel::name, sip_pvt::ocseq, sip_pvt::options, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_refer::referred_by_name, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SESSION_TIMER_MODE_ORIGINATE, SIP_REFER, SIPBUFSIZE, sip_st_dlg::st_active, st_get_mode(), st_get_se(), sip_st_dlg::st_interval, t38properties::state, sip_pvt::stimer, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_REINVITE, TRUE, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.
Referenced by do_proxy_auth(), proc_422_rsp(), sip_call(), and sip_poke_peer().
09230 { 09231 struct sip_request req; 09232 09233 req.method = sipmethod; 09234 if (init) {/* Bump branch even on initial requests */ 09235 p->branch ^= ast_random(); 09236 p->invite_branch = p->branch; 09237 build_via(p); 09238 } 09239 if (init > 1) 09240 initreqprep(&req, p, sipmethod); 09241 else 09242 /* If init=1, we should not generate a new branch. If it's 0, we need a new branch. */ 09243 reqprep(&req, p, sipmethod, 0, init ? 0 : 1); 09244 09245 if (p->options && p->options->auth) 09246 add_header(&req, p->options->authheader, p->options->auth); 09247 append_date(&req); 09248 if (sipmethod == SIP_REFER) { /* Call transfer */ 09249 if (p->refer) { 09250 char buf[SIPBUFSIZE]; 09251 if (!ast_strlen_zero(p->refer->refer_to)) 09252 add_header(&req, "Refer-To", p->refer->refer_to); 09253 if (!ast_strlen_zero(p->refer->referred_by)) { 09254 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 09255 add_header(&req, "Referred-By", buf); 09256 } 09257 } 09258 } 09259 /* This new INVITE is part of an attended transfer. Make sure that the 09260 other end knows and replace the current call with this new call */ 09261 if (p->options && !ast_strlen_zero(p->options->replaces)) { 09262 add_header(&req, "Replaces", p->options->replaces); 09263 add_header(&req, "Require", "replaces"); 09264 } 09265 09266 /* Add Session-Timers related headers */ 09267 if (st_get_mode(p) == SESSION_TIMER_MODE_ORIGINATE) { 09268 char i2astr[10]; 09269 09270 if (!p->stimer->st_interval) 09271 p->stimer->st_interval = st_get_se(p, TRUE); 09272 09273 p->stimer->st_active = TRUE; 09274 09275 snprintf(i2astr, sizeof(i2astr), "%d", p->stimer->st_interval); 09276 add_header(&req, "Session-Expires", i2astr); 09277 snprintf(i2astr, sizeof(i2astr), "%d", st_get_se(p, FALSE)); 09278 add_header(&req, "Min-SE", i2astr); 09279 } 09280 09281 add_header(&req, "Allow", ALLOWED_METHODS); 09282 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 09283 if (p->options && p->options->addsipheaders && p->owner) { 09284 struct ast_channel *chan = p->owner; /* The owner channel */ 09285 struct varshead *headp; 09286 09287 ast_channel_lock(chan); 09288 09289 headp = &chan->varshead; 09290 09291 if (!headp) 09292 ast_log(LOG_WARNING, "No Headp for the channel...ooops!\n"); 09293 else { 09294 const struct ast_var_t *current; 09295 AST_LIST_TRAVERSE(headp, current, entries) { 09296 /* SIPADDHEADER: Add SIP header to outgoing call */ 09297 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 09298 char *content, *end; 09299 const char *header = ast_var_value(current); 09300 char *headdup = ast_strdupa(header); 09301 09302 /* Strip of the starting " (if it's there) */ 09303 if (*headdup == '"') 09304 headdup++; 09305 if ((content = strchr(headdup, ':'))) { 09306 *content++ = '\0'; 09307 content = ast_skip_blanks(content); /* Skip white space */ 09308 /* Strip the ending " (if it's there) */ 09309 end = content + strlen(content) -1; 09310 if (*end == '"') 09311 *end = '\0'; 09312 09313 add_header(&req, headdup, content); 09314 if (sipdebug) 09315 ast_debug(1, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 09316 } 09317 } 09318 } 09319 } 09320 09321 ast_channel_unlock(chan); 09322 } 09323 if (sdp) { 09324 if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) { 09325 ast_udptl_offered_from_local(p->udptl, 1); 09326 ast_debug(1, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 09327 add_sdp(&req, p, FALSE, FALSE, TRUE); 09328 } else if (p->rtp) 09329 add_sdp(&req, p, FALSE, TRUE, FALSE); 09330 } else { 09331 add_header_contentLength(&req, 0); 09332 } 09333 09334 if (!p->initreq.headers || init > 2) 09335 initialize_initreq(p, &req); 09336 p->lastinvite = p->ocseq; 09337 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 09338 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 9938 of file chan_sip.c.
References add_text(), sip_pvt::ocseq, reqprep(), send_request(), SIP_MESSAGE, and XMIT_RELIABLE.
Referenced by sip_park_thread(), and sip_sendtext().
09939 { 09940 struct sip_request req; 09941 09942 reqprep(&req, p, SIP_MESSAGE, 0, 1); 09943 add_text(&req, text); 09944 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 09945 }
static int transmit_notify_with_mwi | ( | struct sip_pvt * | p, | |
int | newmsgs, | |||
int | oldmsgs, | |||
char * | vmexten | |||
) | [static] |
Notify user of messages waiting in voicemail.
Definition at line 9529 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_inet_ntoa(), ast_str_alloca, ast_str_append(), ast_strlen_zero(), ast_test_flag, sip_pvt::expiry, exten, sip_pvt::flags, sip_pvt::fromdomain, get_transport(), sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::ocseq, sip_pvt::ourip, ourport, S_OR, send_request(), SIP_NOTIFY, SIP_PAGE2_BUGGY_MWI, sip_standard_port(), SIP_TRANSPORT_UDP, sip_pvt::socket, ast_str::str, sip_pvt::subscribed, sip_socket::type, ast_str::used, and XMIT_RELIABLE.
Referenced by sip_send_mwi_to_peer().
09530 { 09531 struct sip_request req; 09532 struct ast_str *out = ast_str_alloca(500); 09533 int ourport = ntohs(p->ourip.sin_port); 09534 const char *exten = S_OR(vmexten, default_vmexten); 09535 09536 initreqprep(&req, p, SIP_NOTIFY); 09537 add_header(&req, "Event", "message-summary"); 09538 add_header(&req, "Content-Type", default_notifymime); 09539 ast_str_append(&out, 0, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 09540 09541 if (!ast_strlen_zero(p->fromdomain)) { 09542 ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n", exten, p->fromdomain); 09543 } else if (!sip_standard_port(p->socket.type, ourport)) { 09544 if (p->socket.type == SIP_TRANSPORT_UDP) { 09545 ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d\r\n", exten, ast_inet_ntoa(p->ourip.sin_addr), ourport); 09546 } else { 09547 ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d;transport=%s\r\n", exten, ast_inet_ntoa(p->ourip.sin_addr), ourport, get_transport(p->socket.type)); 09548 } 09549 } else { 09550 if (p->socket.type == SIP_TRANSPORT_UDP) { 09551 ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n", exten, ast_inet_ntoa(p->ourip.sin_addr)); 09552 } else { 09553 ast_str_append(&out, 0, "Message-Account: sip:%s@%s;transport=%s\r\n", exten, ast_inet_ntoa(p->ourip.sin_addr), get_transport(p->socket.type)); 09554 } 09555 } 09556 /* Cisco has a bug in the SIP stack where it can't accept the 09557 (0/0) notification. This can temporarily be disabled in 09558 sip.conf with the "buggymwi" option */ 09559 ast_str_append(&out, 0, "Voice-Message: %d/%d%s\r\n", 09560 newmsgs, oldmsgs, (ast_test_flag(&p->flags[1], SIP_PAGE2_BUGGY_MWI) ? "" : " (0/0)")); 09561 09562 if (p->subscribed) { 09563 if (p->expiry) 09564 add_header(&req, "Subscription-State", "active"); 09565 else /* Expired */ 09566 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 09567 } 09568 09569 add_header_contentLength(&req, out->used); 09570 add_line(&req, out->str); 09571 09572 if (!p->initreq.headers) 09573 initialize_initreq(p, &req); 09574 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 09575 }
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.
Definition at line 9586 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ALLOWED_METHODS, sip_request::headers, initialize_initreq(), sip_pvt::initreq, sip_pvt::lastnoninvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_NOTIFY, SIPBUFSIZE, SUPPORTED_EXTENSIONS, and XMIT_RELIABLE.
Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().
09587 { 09588 struct sip_request req; 09589 char tmp[SIPBUFSIZE/2]; 09590 09591 reqprep(&req, p, SIP_NOTIFY, 0, 1); 09592 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 09593 add_header(&req, "Event", tmp); 09594 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 09595 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 09596 add_header(&req, "Allow", ALLOWED_METHODS); 09597 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 09598 09599 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 09600 add_header_contentLength(&req, strlen(tmp)); 09601 add_line(&req, tmp); 09602 09603 if (!p->initreq.headers) 09604 initialize_initreq(p, &req); 09605 09606 p->lastnoninvite = p->ocseq; 09607 09608 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 09609 }
static int transmit_refer | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transmit SIP REFER message (initiated by the transfer() dialplan application.
Definition at line 9959 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_copy_string(), ast_debug, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::flags, get_header(), get_in_brackets(), sip_request::headers, sip_pvt::initreq, LOG_NOTICE, sip_pvt::ocseq, sip_pvt::our_contact, sip_pvt::refer, REFER_SENT, sip_refer::refer_to, sip_refer::referred_by, reqprep(), send_request(), SIP_OUTGOING, SIP_REFER, sip_refer_allocate(), sip_refer::status, SUPPORTED_EXTENSIONS, sip_pvt::tag, sip_pvt::theirtag, and XMIT_RELIABLE.
Referenced by sip_transfer().
09960 { 09961 struct sip_request req = { 09962 .headers = 0, 09963 }; 09964 char from[256]; 09965 const char *of; 09966 char *c; 09967 char referto[256]; 09968 char *ttag, *ftag; 09969 char *theirtag = ast_strdupa(p->theirtag); 09970 09971 if (sipdebug) 09972 ast_debug(1, "SIP transfer of %s to %s\n", p->callid, dest); 09973 09974 /* Are we transfering an inbound or outbound call ? */ 09975 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 09976 of = get_header(&p->initreq, "To"); 09977 ttag = theirtag; 09978 ftag = p->tag; 09979 } else { 09980 of = get_header(&p->initreq, "From"); 09981 ftag = theirtag; 09982 ttag = p->tag; 09983 } 09984 09985 ast_copy_string(from, of, sizeof(from)); 09986 of = get_in_brackets(from); 09987 ast_string_field_set(p, from, of); 09988 if (!strncasecmp(of, "sip:", 4)) 09989 of += 4; 09990 else if (!strncasecmp(of, "sips:", 5)) 09991 of += 5; 09992 else 09993 ast_log(LOG_NOTICE, "From address missing 'sip(s):', using it anyway\n"); 09994 /* Get just the username part */ 09995 if ((c = strchr(dest, '@'))) 09996 c = NULL; 09997 else if ((c = strchr(of, '@'))) 09998 *c++ = '\0'; 09999 if (c) 10000 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 10001 else 10002 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 10003 10004 /* save in case we get 407 challenge */ 10005 sip_refer_allocate(p); 10006 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 10007 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 10008 p->refer->status = REFER_SENT; /* Set refer status */ 10009 10010 reqprep(&req, p, SIP_REFER, 0, 1); 10011 10012 add_header(&req, "Refer-To", referto); 10013 add_header(&req, "Allow", ALLOWED_METHODS); 10014 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 10015 if (!ast_strlen_zero(p->our_contact)) 10016 add_header(&req, "Referred-By", p->our_contact); 10017 10018 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 10019 /* We should propably wait for a NOTIFY here until we ack the transfer */ 10020 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 10021 10022 /*! \todo In theory, we should hang around and wait for a reply, before 10023 returning to the dial plan here. Don't know really how that would 10024 affect the transfer() app or the pbx, but, well, to make this 10025 useful we should have a STATUS code on transfer(). 10026 */ 10027 }
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 9725 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_history, ast_debug, ast_log(), ast_random(), ast_sched_add(), AST_SCHED_REPLACE, ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_set, ast_strlen_zero(), ast_verbose(), sip_pvt::authname, sip_registry::authuser, sip_pvt::branch, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_registry::callback, sip_pvt::callid, sip_registry::callid, sip_registry::callid_valid, create_addr(), DEFAULT_MAX_FORWARDS, dialog_ref(), sip_pvt::do_history, sip_registry::domain, sip_registry::expiry, exten, sip_pvt::flags, sip_pvt::fromdomain, sip_request::headers, sip_registry::hostname, init_req(), initialize_initreq(), sip_pvt::initreq, internip, sip_request::lines, LOG_NOTICE, LOG_WARNING, make_our_tag(), sip_registry::md5secret, sip_pvt::nonce, sip_registry::nonce, sip_registry::noncecount, sip_pvt::noncecount, obproxy_get(), sip_pvt::ocseq, sip_registry::ocseq, sip_registry::opaque, sip_pvt::opaque, sip_pvt::our_contact, sip_pvt::ourip, sip_pvt::outboundproxy, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_socket::port, sip_registry::portno, sip_registry::qop, sip_pvt::qop, sip_registry::realm, sip_pvt::realm, sip_pvt::recv, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, registry_addref(), sip_registry::regstate, sip_pvt::sa, sched, sip_registry::secret, send_request(), set_socket_transport(), server_args::sin, sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sip_tcp_desc, SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, sip_pvt::socket, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, sip_registry::timeout, sip_pvt::tohost, sip_registry::transport, TRUE, sip_pvt::uri, sip_registry::username, sip_pvt::via, and XMIT_CRITICAL.
Referenced by __sip_do_register(), do_register_auth(), handle_response_register(), and sip_reg_timeout().
09726 { 09727 struct sip_request req; 09728 char from[256]; 09729 char to[256]; 09730 char tmp[80]; 09731 char addr[80]; 09732 struct sip_pvt *p; 09733 char *fromdomain; 09734 09735 /* exit if we are already in process with this registrar ?*/ 09736 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 09737 if (r) { 09738 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 09739 } 09740 return 0; 09741 } 09742 09743 if (r->call) { /* We have a registration */ 09744 if (!auth) { 09745 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 09746 return 0; 09747 } else { 09748 p = r->call; 09749 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 09750 ast_string_field_set(p, theirtag, NULL); /* forget their old tag, so we don't match tags when getting response */ 09751 } 09752 } else { 09753 /* Build callid for registration if we haven't registered before */ 09754 if (!r->callid_valid) { 09755 build_callid_registry(r, internip.sin_addr, default_fromdomain); 09756 r->callid_valid = TRUE; 09757 } 09758 /* Allocate SIP dialog for registration */ 09759 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER, NULL))) { 09760 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 09761 return 0; 09762 } 09763 09764 if (p->do_history) 09765 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 09766 09767 p->outboundproxy = obproxy_get(p, NULL); 09768 09769 /* Find address to hostname */ 09770 if (create_addr(p, r->hostname, 0)) { 09771 /* we have what we hope is a temporary network error, 09772 * probably DNS. We need to reschedule a registration try */ 09773 sip_destroy(p); 09774 if (r->timeout > -1) { 09775 AST_SCHED_REPLACE(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r); 09776 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 09777 } else { 09778 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 09779 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); 09780 } 09781 r->regattempts++; 09782 return 0; 09783 } 09784 /* Copy back Call-ID in case create_addr changed it */ 09785 ast_string_field_set(r, callid, p->callid); 09786 if (r->portno) { 09787 p->sa.sin_port = htons(r->portno); 09788 p->recv.sin_port = htons(r->portno); 09789 } else /* Set registry port to the port set from the peer definition/srv or default */ 09790 r->portno = ntohs(p->sa.sin_port); 09791 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 09792 r->call = dialog_ref(p); /* Save pointer to SIP dialog */ 09793 p->registry = registry_addref(r); /* Add pointer to registry in packet */ 09794 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 09795 ast_string_field_set(p, peersecret, r->secret); 09796 if (!ast_strlen_zero(r->md5secret)) 09797 ast_string_field_set(p, peermd5secret, r->md5secret); 09798 /* User name in this realm 09799 - if authuser is set, use that, otherwise use username */ 09800 if (!ast_strlen_zero(r->authuser)) { 09801 ast_string_field_set(p, peername, r->authuser); 09802 ast_string_field_set(p, authname, r->authuser); 09803 } else if (!ast_strlen_zero(r->username)) { 09804 ast_string_field_set(p, peername, r->username); 09805 ast_string_field_set(p, authname, r->username); 09806 ast_string_field_set(p, fromuser, r->username); 09807 } 09808 if (!ast_strlen_zero(r->username)) 09809 ast_string_field_set(p, username, r->username); 09810 /* Save extension in packet */ 09811 if (!ast_strlen_zero(r->callback)) 09812 ast_string_field_set(p, exten, r->callback); 09813 09814 /* Set transport and port so the correct contact is built */ 09815 set_socket_transport(&p->socket, r->transport); 09816 if (r->transport == SIP_TRANSPORT_TLS || r->transport == SIP_TRANSPORT_TCP) { 09817 p->socket.port = sip_tcp_desc.sin.sin_port; 09818 } 09819 /* 09820 check which address we should use in our contact header 09821 based on whether the remote host is on the external or 09822 internal network so we can register through nat 09823 */ 09824 ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p); 09825 build_contact(p); 09826 } 09827 09828 /* set up a timeout */ 09829 if (auth == NULL) { 09830 if (r->timeout > -1) 09831 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 09832 AST_SCHED_REPLACE(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r); 09833 ast_debug(1, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 09834 } 09835 09836 if ((fromdomain = strchr(r->username, '@'))) { 09837 /* the domain name is just behind '@' */ 09838 fromdomain++ ; 09839 /* We have a domain in the username for registration */ 09840 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 09841 if (!ast_strlen_zero(p->theirtag)) 09842 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 09843 else 09844 snprintf(to, sizeof(to), "<sip:%s>", r->username); 09845 09846 /* If the registration username contains '@', then the domain should be used as 09847 the equivalent of "fromdomain" for the registration */ 09848 if (ast_strlen_zero(p->fromdomain)) { 09849 ast_string_field_set(p, fromdomain, fromdomain); 09850 } 09851 } else { 09852 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 09853 if (!ast_strlen_zero(p->theirtag)) 09854 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 09855 else 09856 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 09857 } 09858 09859 /* Fromdomain is what we are registering to, regardless of actual 09860 host name from SRV */ 09861 if (!ast_strlen_zero(p->fromdomain)) { 09862 if (r->portno && r->portno != STANDARD_SIP_PORT) 09863 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 09864 else 09865 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 09866 } else { 09867 if (r->portno && r->portno != STANDARD_SIP_PORT) 09868 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 09869 else 09870 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 09871 } 09872 ast_string_field_set(p, uri, addr); 09873 09874 p->branch ^= ast_random(); 09875 09876 init_req(&req, sipmethod, addr); 09877 09878 /* Add to CSEQ */ 09879 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 09880 p->ocseq = r->ocseq; 09881 09882 build_via(p); 09883 add_header(&req, "Via", p->via); 09884 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 09885 add_header(&req, "From", from); 09886 add_header(&req, "To", to); 09887 add_header(&req, "Call-ID", p->callid); 09888 add_header(&req, "CSeq", tmp); 09889 if (!ast_strlen_zero(global_useragent)) 09890 add_header(&req, "User-Agent", global_useragent); 09891 09892 09893 if (auth) /* Add auth header */ 09894 add_header(&req, authheader, auth); 09895 else if (!ast_strlen_zero(r->nonce)) { 09896 char digest[1024]; 09897 09898 /* We have auth data to reuse, build a digest header. 09899 * Note, this is not always useful because some parties do not 09900 * like nonces to be reused (for good reasons!) so they will 09901 * challenge us anyways. 09902 */ 09903 if (sipdebug) 09904 ast_debug(1, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 09905 ast_string_field_set(p, realm, r->realm); 09906 ast_string_field_set(p, nonce, r->nonce); 09907 ast_string_field_set(p, domain, r->domain); 09908 ast_string_field_set(p, opaque, r->opaque); 09909 ast_string_field_set(p, qop, r->qop); 09910 p->noncecount = ++r->noncecount; 09911 09912 memset(digest, 0, sizeof(digest)); 09913 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 09914 add_header(&req, "Authorization", digest); 09915 else 09916 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 09917 09918 } 09919 09920 snprintf(tmp, sizeof(tmp), "%d", r->expiry); 09921 add_header(&req, "Expires", tmp); 09922 add_header(&req, "Contact", p->our_contact); 09923 add_header(&req, "Event", "registration"); 09924 add_header_contentLength(&req, 0); 09925 09926 initialize_initreq(p, &req); 09927 if (sip_debug_test_pvt(p)) { 09928 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 09929 } 09930 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 09931 r->regattempts++; /* Another attempt */ 09932 ast_debug(4, "REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 09933 09934 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 09935 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p, | |
int | t38version, | |||
int | oldsdp | |||
) | [static] |
Transmit reinvite with SDP.
If oldsdp is TRUE then the SDP version number is not incremented. This is needed for Session-Timers so we can send a re-invite to refresh the SIP session without modifying the media session.
Definition at line 8917 of file chan_sip.c.
References add_header(), add_sdp(), ALLOWED_METHODS, append_history, ast_set_flag, ast_test_flag, sip_pvt::do_history, FALSE, sip_pvt::flags, initialize_initreq(), sip_pvt::lastinvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_INVITE, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, SUPPORTED_EXTENSIONS, TRUE, and XMIT_CRITICAL.
Referenced by check_pendings(), handle_response_invite(), proc_session_timer(), sip_indicate(), sip_read(), sip_sendhtml(), sip_set_rtp_peer(), sip_set_udptl_peer(), and sip_write().
08918 { 08919 struct sip_request req; 08920 08921 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 08922 08923 add_header(&req, "Allow", ALLOWED_METHODS); 08924 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 08925 if (sipdebug) { 08926 if (oldsdp == TRUE) 08927 add_header(&req, "X-asterisk-Info", "SIP re-invite (Session-Timers)"); 08928 else 08929 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 08930 } 08931 08932 if (p->do_history) 08933 append_history(p, "ReInv", "Re-invite sent"); 08934 if (t38version) 08935 add_sdp(&req, p, oldsdp, FALSE, TRUE); 08936 else 08937 add_sdp(&req, p, oldsdp, TRUE, FALSE); 08938 08939 /* Use this as the basis */ 08940 initialize_initreq(p, &req); 08941 p->lastinvite = p->ocseq; 08942 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 08943 08944 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 08945 }
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 10053 of file chan_sip.c.
References add_header(), add_header_contentLength(), sip_pvt::answered_elsewhere, INV_CONFIRMED, sip_pvt::invitestate, sip_pvt::ocseq, reqprep(), send_request(), SIP_ACK, and SIP_CANCEL.
Referenced by check_pendings(), handle_response(), handle_response_invite(), and sip_hangup().
10054 { 10055 struct sip_request resp; 10056 10057 if (sipmethod == SIP_ACK) 10058 p->invitestate = INV_CONFIRMED; 10059 10060 reqprep(&resp, p, sipmethod, seqno, newbranch); 10061 if (sipmethod == SIP_CANCEL && p->answered_elsewhere) 10062 add_header(&resp, "Reason", "SIP;cause=200;text=\"Call completed elsewhere\""); 10063 10064 add_header_contentLength(&resp, 0); 10065 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 10066 }
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 10084 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), ast_strlen_zero(), auth_headers(), sip_invite_param::auth_type, buf, build_reply_digest(), sip_pvt::callid, dummy(), sip_pvt::hangupcause, LOG_WARNING, sip_pvt::ocseq, sip_pvt::options, PROXY_AUTH, sip_pvt::realm, reqprep(), send_request(), and SIP_BYE.
Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().
10085 { 10086 struct sip_request resp; 10087 10088 reqprep(&resp, p, sipmethod, seqno, newbranch); 10089 if (!ast_strlen_zero(p->realm)) { 10090 char digest[1024]; 10091 10092 memset(digest, 0, sizeof(digest)); 10093 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 10094 char *dummy, *response; 10095 enum sip_auth_type code = p->options ? p->options->auth_type : PROXY_AUTH; /* XXX force 407 if unknown */ 10096 auth_headers(code, &dummy, &response); 10097 add_header(&resp, response, digest); 10098 } else 10099 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 10100 } 10101 /* If we are hanging up and know a cause for that, send it in clear text to make 10102 debugging easier. */ 10103 if (sipmethod == SIP_BYE) { 10104 char buf[10]; 10105 10106 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->hangupcause)); 10107 snprintf(buf, sizeof(buf), "%d", p->hangupcause); 10108 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 10109 } 10110 10111 add_header_contentLength(&resp, 0); 10112 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 10113 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 8106 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
08107 { 08108 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 08109 }
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 8142 of file chan_sip.c.
References __transmit_response(), sip_request::ignore, XMIT_CRITICAL, and XMIT_UNRELIABLE.
Referenced by handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_subscribe(), sip_hangup(), sip_indicate(), sip_sipredirect(), and sip_t38_abort().
08143 { 08144 return __transmit_response(p, msg, req, req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL); 08145 }
static int transmit_response_using_temp | ( | ast_string_field | callid, | |
struct sockaddr_in * | sin, | |||
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 8054 of file chan_sip.c.
References __transmit_response(), ast_copy_flags, ast_log(), ast_random(), ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_set, ast_test_flag, ast_threadstorage_get(), build_via(), copy_socket_data(), do_setnat(), global_flags, INITIAL_CSEQ, internip, LOG_NOTICE, make_our_tag(), SIP_NAT, SIP_NAT_ROUTE, sip_request::socket, ts_temp_pvt, and XMIT_UNRELIABLE.
08055 { 08056 struct sip_pvt *p = NULL; 08057 08058 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 08059 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 08060 return -1; 08061 } 08062 08063 /* XXX the structure may be dirty from previous usage. 08064 * Here we should state clearly how we should reinitialize it 08065 * before using it. 08066 * E.g. certainly the threadstorage should be left alone, 08067 * but other thihngs such as flags etc. maybe need cleanup ? 08068 */ 08069 08070 /* Initialize the bare minimum */ 08071 p->method = intended_method; 08072 08073 if (!sin) 08074 p->ourip = internip; 08075 else { 08076 p->sa = *sin; 08077 ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p); 08078 } 08079 08080 p->branch = ast_random(); 08081 make_our_tag(p->tag, sizeof(p->tag)); 08082 p->ocseq = INITIAL_CSEQ; 08083 08084 if (useglobal_nat && sin) { 08085 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 08086 p->recv = *sin; 08087 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 08088 } 08089 08090 ast_string_field_set(p, fromdomain, default_fromdomain); 08091 build_via(p); 08092 ast_string_field_set(p, callid, callid); 08093 08094 copy_socket_data(&p->socket, &req->socket); 08095 08096 /* Use this temporary pvt structure to send the message */ 08097 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 08098 08099 /* Free the string fields, but not the pool space */ 08100 ast_string_field_init(p, 0); 08101 08102 return 0; 08103 }
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 8170 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_incoming(), and handle_request_options().
08171 { 08172 struct sip_request resp; 08173 respprep(&resp, p, msg, req); 08174 add_header(&resp, "Accept", "application/sdp"); 08175 add_header_contentLength(&resp, 0); 08176 return send_response(p, &resp, reliable, 0); 08177 }
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 8180 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_history, ast_log(), get_header(), LOG_WARNING, sip_pvt::noncecount, respprep(), send_response(), and sip_pvt::username.
Referenced by check_auth(), and transmit_fake_auth_response().
08181 { 08182 struct sip_request resp; 08183 char tmp[512]; 08184 int seqno = 0; 08185 08186 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 08187 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 08188 return -1; 08189 } 08190 /* Stale means that they sent us correct authentication, but 08191 based it on an old challenge (nonce) */ 08192 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 08193 respprep(&resp, p, msg, req); 08194 add_header(&resp, header, tmp); 08195 add_header_contentLength(&resp, 0); 08196 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 08197 return send_response(p, &resp, reliable, seqno); 08198 }
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 8160 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
08161 { 08162 struct sip_request resp; 08163 respprep(&resp, p, msg, req); 08164 append_date(&resp); 08165 add_header_contentLength(&resp, 0); 08166 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 08167 }
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 8123 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
08124 { 08125 struct sip_request resp; 08126 char minse_str[20]; 08127 08128 respprep(&resp, p, msg, req); 08129 append_date(&resp); 08130 08131 snprintf(minse_str, sizeof(minse_str), "%d", minse_int); 08132 add_header(&resp, "Min-SE", minse_str); 08133 08134 add_header_contentLength(&resp, 0); 08135 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 08136 }
static int transmit_response_with_sdp | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req, | |||
enum xmittype | reliable, | |||
int | oldsdp | |||
) | [static] |
Used for 200 OK and 183 early media.
Definition at line 8836 of file chan_sip.c.
References add_sdp(), ast_debug, ast_log(), ast_rtp_codec_setpref(), ast_test_flag, sip_pvt::autoframing, sip_pvt::callid, FALSE, sip_pvt::flags, get_header(), LOG_ERROR, LOG_WARNING, sip_pvt::pendinginvite, sip_pvt::prefs, respprep(), sip_pvt::rtp, send_response(), SIP_OUTGOING, t38properties::state, sip_pvt::t38, T38_ENABLED, T38_PEER_DIRECT, TRUE, and try_suggested_sip_codec().
Referenced by handle_invite_replaces(), handle_request_invite(), sip_answer(), sip_indicate(), and sip_write().
08837 { 08838 struct sip_request resp; 08839 int seqno; 08840 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 08841 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 08842 return -1; 08843 } 08844 respprep(&resp, p, msg, req); 08845 if (p->rtp) { 08846 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 08847 ast_debug(1, "Setting framing from config on incoming call\n"); 08848 ast_rtp_codec_setpref(p->rtp, &p->prefs); 08849 } 08850 try_suggested_sip_codec(p); 08851 if (p->t38.state == T38_PEER_DIRECT || p->t38.state == T38_ENABLED) { 08852 add_sdp(&resp, p, oldsdp, TRUE, TRUE); 08853 } else { 08854 add_sdp(&resp, p, oldsdp, TRUE, FALSE); 08855 } 08856 } else 08857 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 08858 if (reliable && !p->pendinginvite) 08859 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 08860 return send_response(p, &resp, reliable, seqno); 08861 }
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 8796 of file chan_sip.c.
References add_sdp(), ast_log(), ast_udptl_offered_from_local(), sip_pvt::callid, get_header(), LOG_ERROR, LOG_WARNING, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.
Referenced by handle_request_invite(), and sip_indicate().
08797 { 08798 struct sip_request resp; 08799 int seqno; 08800 08801 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 08802 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 08803 return -1; 08804 } 08805 respprep(&resp, p, msg, req); 08806 if (p->udptl) { 08807 ast_udptl_offered_from_local(p->udptl, 0); 08808 add_sdp(&resp, p, 0, 0, 1); 08809 } else 08810 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 08811 if (retrans && !p->pendinginvite) 08812 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 08813 return send_response(p, &resp, retrans, seqno); 08814 }
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 8112 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
08113 { 08114 struct sip_request resp; 08115 respprep(&resp, p, msg, req); 08116 append_date(&resp); 08117 add_header(&resp, "Unsupported", unsupported); 08118 add_header_contentLength(&resp, 0); 08119 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 08120 }
static int transmit_sip_request | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Transmit SIP request unreliably (only used in sip_notify subsystem).
Definition at line 9578 of file chan_sip.c.
References sip_request::headers, initialize_initreq(), sip_pvt::initreq, sip_pvt::ocseq, send_request(), and XMIT_UNRELIABLE.
Referenced by sip_notify().
09579 { 09580 if (!p->initreq.headers) /* Initialize first request before sending */ 09581 initialize_initreq(p, req); 09582 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 09583 }
static int transmit_state_notify | ( | struct sip_pvt * | p, | |
int | state, | |||
int | full, | |||
int | timeout | |||
) | [static] |
Used in the SUBSCRIBE notification subsystem.
Definition at line 9341 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_copy_string(), ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, ast_str_alloca, ast_str_append(), sip_pvt::context, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, sip_pvt::exten, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, NONE, sip_pvt::ocseq, sip_pvt::pendinginvite, PIDF_XML, remove_uri_parameters(), reqprep(), send_request(), SIP_NOTIFY, ast_str::str, strsep(), sip_pvt::subscribed, ast_str::used, XMIT_RELIABLE, and XPIDF_XML.
Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe().
09342 { 09343 struct ast_str *tmp = ast_str_alloca(4000); 09344 char from[256], to[256]; 09345 char *c, *mfrom, *mto; 09346 struct sip_request req; 09347 char hint[AST_MAX_EXTENSION]; 09348 char *statestring = "terminated"; 09349 const struct cfsubscription_types *subscriptiontype; 09350 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 09351 char *pidfstate = "--"; 09352 char *pidfnote= "Ready"; 09353 09354 memset(from, 0, sizeof(from)); 09355 memset(to, 0, sizeof(to)); 09356 09357 switch (state) { 09358 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 09359 statestring = (global_notifyringing) ? "early" : "confirmed"; 09360 local_state = NOTIFY_INUSE; 09361 pidfstate = "busy"; 09362 pidfnote = "Ringing"; 09363 break; 09364 case AST_EXTENSION_RINGING: 09365 statestring = "early"; 09366 local_state = NOTIFY_INUSE; 09367 pidfstate = "busy"; 09368 pidfnote = "Ringing"; 09369 break; 09370 case AST_EXTENSION_INUSE: 09371 statestring = "confirmed"; 09372 local_state = NOTIFY_INUSE; 09373 pidfstate = "busy"; 09374 pidfnote = "On the phone"; 09375 break; 09376 case AST_EXTENSION_BUSY: 09377 statestring = "confirmed"; 09378 local_state = NOTIFY_CLOSED; 09379 pidfstate = "busy"; 09380 pidfnote = "On the phone"; 09381 break; 09382 case AST_EXTENSION_UNAVAILABLE: 09383 statestring = "terminated"; 09384 local_state = NOTIFY_CLOSED; 09385 pidfstate = "away"; 09386 pidfnote = "Unavailable"; 09387 break; 09388 case AST_EXTENSION_ONHOLD: 09389 statestring = "confirmed"; 09390 local_state = NOTIFY_CLOSED; 09391 pidfstate = "busy"; 09392 pidfnote = "On hold"; 09393 break; 09394 case AST_EXTENSION_NOT_INUSE: 09395 default: 09396 /* Default setting */ 09397 break; 09398 } 09399 09400 subscriptiontype = find_subscription_type(p->subscribed); 09401 09402 /* Check which device/devices we are watching and if they are registered */ 09403 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 09404 char *hint2 = hint, *individual_hint = NULL; 09405 int hint_count = 0, unavailable_count = 0; 09406 09407 while ((individual_hint = strsep(&hint2, "&"))) { 09408 hint_count++; 09409 09410 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 09411 unavailable_count++; 09412 } 09413 09414 /* If none of the hinted devices are registered, we will 09415 * override notification and show no availability. 09416 */ 09417 if (hint_count > 0 && hint_count == unavailable_count) { 09418 local_state = NOTIFY_CLOSED; 09419 pidfstate = "away"; 09420 pidfnote = "Not online"; 09421 } 09422 } 09423 09424 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 09425 c = get_in_brackets(from); 09426 if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) { 09427 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 09428 return -1; 09429 } 09430 09431 mfrom = remove_uri_parameters(c); 09432 09433 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 09434 c = get_in_brackets(to); 09435 if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) { 09436 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 09437 return -1; 09438 } 09439 mto = remove_uri_parameters(c); 09440 09441 reqprep(&req, p, SIP_NOTIFY, 0, 1); 09442 09443 09444 add_header(&req, "Event", subscriptiontype->event); 09445 add_header(&req, "Content-Type", subscriptiontype->mediatype); 09446 switch(state) { 09447 case AST_EXTENSION_DEACTIVATED: 09448 if (timeout) 09449 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 09450 else { 09451 add_header(&req, "Subscription-State", "terminated;reason=probation"); 09452 add_header(&req, "Retry-After", "60"); 09453 } 09454 break; 09455 case AST_EXTENSION_REMOVED: 09456 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 09457 break; 09458 default: 09459 if (p->expiry) 09460 add_header(&req, "Subscription-State", "active"); 09461 else /* Expired */ 09462 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 09463 } 09464 switch (p->subscribed) { 09465 case XPIDF_XML: 09466 case CPIM_PIDF_XML: 09467 ast_str_append(&tmp, 0, 09468 "<?xml version=\"1.0\"?>\n" 09469 "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n" 09470 "<presence>\n"); 09471 ast_str_append(&tmp, 0, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 09472 ast_str_append(&tmp, 0, "<atom id=\"%s\">\n", p->exten); 09473 ast_str_append(&tmp, 0, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 09474 ast_str_append(&tmp, 0, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 09475 ast_str_append(&tmp, 0, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 09476 ast_str_append(&tmp, 0, "</address>\n</atom>\n</presence>\n"); 09477 break; 09478 case PIDF_XML: /* Eyebeam supports this format */ 09479 ast_str_append(&tmp, 0, 09480 "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" 09481 "<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); 09482 ast_str_append(&tmp, 0, "<pp:person><status>\n"); 09483 if (pidfstate[0] != '-') 09484 ast_str_append(&tmp, 0, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 09485 ast_str_append(&tmp, 0, "</status></pp:person>\n"); 09486 ast_str_append(&tmp, 0, "<note>%s</note>\n", pidfnote); /* Note */ 09487 ast_str_append(&tmp, 0, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 09488 ast_str_append(&tmp, 0, "<contact priority=\"1\">%s</contact>\n", mto); 09489 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 09490 ast_str_append(&tmp, 0, "<status><basic>open</basic></status>\n"); 09491 else 09492 ast_str_append(&tmp, 0, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 09493 ast_str_append(&tmp, 0, "</tuple>\n</presence>\n"); 09494 break; 09495 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 09496 ast_str_append(&tmp, 0, "<?xml version=\"1.0\"?>\n"); 09497 ast_str_append(&tmp, 0, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">\n", p->dialogver++, full ? "full":"partial", mto); 09498 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 09499 ast_str_append(&tmp, 0, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 09500 else 09501 ast_str_append(&tmp, 0, "<dialog id=\"%s\">\n", p->exten); 09502 ast_str_append(&tmp, 0, "<state>%s</state>\n", statestring); 09503 if (state == AST_EXTENSION_ONHOLD) { 09504 ast_str_append(&tmp, 0, "<local>\n<target uri=\"%s\">\n" 09505 "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n" 09506 "</target>\n</local>\n", mto); 09507 } 09508 ast_str_append(&tmp, 0, "</dialog>\n</dialog-info>\n"); 09509 break; 09510 case NONE: 09511 default: 09512 break; 09513 } 09514 09515 add_header_contentLength(&req, tmp->used); 09516 add_line(&req, tmp->str); 09517 09518 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 09519 09520 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 09521 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 5118 of file chan_sip.c.
References ast_channel_trylock, ast_channel_unlock, ast_getformatbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), sip_pvt::capability, sip_pvt::jointcapability, LOG_NOTICE, sip_pvt::owner, pbx_builtin_getvar_helper(), S_OR, sip_pvt_lock, and sip_pvt_unlock.
Referenced by sip_answer(), and transmit_response_with_sdp().
05119 { 05120 int fmt; 05121 const char *codec; 05122 05123 while (p->owner && ast_channel_trylock(p->owner)) { 05124 sip_pvt_unlock(p); 05125 sched_yield(); 05126 sip_pvt_lock(p); 05127 } 05128 05129 if (!p->owner) 05130 return; 05131 05132 codec = ast_strdupa(S_OR(pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"), "")); 05133 05134 ast_channel_unlock(p->owner); 05135 05136 if (ast_strlen_zero(codec)) 05137 return; 05138 05139 fmt = ast_getformatbyname(codec); 05140 if (fmt) { 05141 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 05142 if (p->jointcapability & fmt) { 05143 p->jointcapability &= fmt; 05144 p->capability &= fmt; 05145 } else 05146 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 05147 } else 05148 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 05149 return; 05150 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 22925 of file chan_sip.c.
References __sip_destroy(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_context_find(), ast_custom_function_unregister(), ast_free, ast_free_ha(), AST_LIST_LOCK, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_tcptls_server_stop(), ast_udptl_proto_unregister(), 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, dialoglist, dialoglist_lock(), dialoglist_unlock(), localaddr, server_args::master, monlock, sip_pvt::next, sip_pvt::owner, peerl, regl, sched, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_header_function, sip_registry_destroy(), sip_rtp, sip_tcp_desc, sip_tech, sip_tls_desc, sip_udptl, sipchaninfo_function, sippeer_function, sipsock, sip_threadinfo::stop, thread, sip_threadinfo::threadid, TRUE, and userl.
22926 { 22927 struct sip_pvt *p, *pl; 22928 struct sip_threadinfo *th; 22929 struct ast_context *con; 22930 22931 /* First, take us out of the channel type list */ 22932 ast_channel_unregister(&sip_tech); 22933 22934 /* Unregister dial plan functions */ 22935 ast_custom_function_unregister(&sipchaninfo_function); 22936 ast_custom_function_unregister(&sippeer_function); 22937 ast_custom_function_unregister(&sip_header_function); 22938 ast_custom_function_unregister(&checksipdomain_function); 22939 22940 /* Unregister dial plan applications */ 22941 ast_unregister_application(app_dtmfmode); 22942 ast_unregister_application(app_sipaddheader); 22943 22944 /* Unregister CLI commands */ 22945 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 22946 22947 /* Disconnect from the RTP subsystem */ 22948 ast_rtp_proto_unregister(&sip_rtp); 22949 22950 /* Disconnect from UDPTL */ 22951 ast_udptl_proto_unregister(&sip_udptl); 22952 22953 /* Unregister AMI actions */ 22954 ast_manager_unregister("SIPpeers"); 22955 ast_manager_unregister("SIPshowpeer"); 22956 ast_manager_unregister("SIPshowregistry"); 22957 22958 /* Kill TCP/TLS server threads */ 22959 if (sip_tcp_desc.master) 22960 ast_tcptls_server_stop(&sip_tcp_desc); 22961 if (sip_tls_desc.master) 22962 ast_tcptls_server_stop(&sip_tls_desc); 22963 22964 /* Kill all existing TCP/TLS threads */ 22965 AST_LIST_LOCK(&threadl); 22966 AST_LIST_TRAVERSE_SAFE_BEGIN(&threadl, th, list) { 22967 pthread_t thread = th->threadid; 22968 th->stop = 1; 22969 AST_LIST_UNLOCK(&threadl); 22970 pthread_kill(thread, SIGURG); 22971 pthread_join(thread, NULL); 22972 AST_LIST_LOCK(&threadl); 22973 } 22974 AST_LIST_TRAVERSE_SAFE_END; 22975 AST_LIST_UNLOCK(&threadl); 22976 22977 dialoglist_lock(); 22978 /* Hangup all dialogs if they have an owner */ 22979 for (p = dialoglist; p ; p = p->next) { 22980 if (p->owner) 22981 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 22982 } 22983 dialoglist_unlock(); 22984 22985 ast_mutex_lock(&monlock); 22986 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 22987 pthread_cancel(monitor_thread); 22988 pthread_kill(monitor_thread, SIGURG); 22989 pthread_join(monitor_thread, NULL); 22990 } 22991 monitor_thread = AST_PTHREADT_STOP; 22992 ast_mutex_unlock(&monlock); 22993 22994 restartdestroy: 22995 dialoglist_lock(); 22996 /* Destroy all the dialogs and free their memory */ 22997 p = dialoglist; 22998 while (p) { 22999 pl = p; 23000 p = p->next; 23001 if (__sip_destroy(pl, TRUE, TRUE) < 0) { 23002 /* Something is still bridged, let it react to getting a hangup */ 23003 dialoglist = p; 23004 dialoglist_unlock(); 23005 usleep(1); 23006 goto restartdestroy; 23007 } 23008 } 23009 dialoglist = NULL; 23010 dialoglist_unlock(); 23011 23012 /* Free memory for local network address mask */ 23013 ast_free_ha(localaddr); 23014 23015 if (default_tls_cfg.certfile) 23016 ast_free(default_tls_cfg.certfile); 23017 if (default_tls_cfg.cipher) 23018 ast_free(default_tls_cfg.cipher); 23019 if (default_tls_cfg.cafile) 23020 ast_free(default_tls_cfg.cafile); 23021 if (default_tls_cfg.capath) 23022 ast_free(default_tls_cfg.capath); 23023 23024 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 23025 ASTOBJ_CONTAINER_DESTROY(&userl); 23026 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 23027 ASTOBJ_CONTAINER_DESTROY(&peerl); 23028 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 23029 ASTOBJ_CONTAINER_DESTROY(®l); 23030 23031 clear_realm_authentication(authl); 23032 clear_sip_domains(); 23033 close(sipsock); 23034 sched_context_destroy(sched); 23035 con = ast_context_find(used_context); 23036 if (con) 23037 ast_context_destroy(con, "SIP"); 23038 23039 return 0; 23040 }
static void unref_peer | ( | struct sip_peer * | peer | ) | [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 2323 of file chan_sip.c.
References ASTOBJ_UNREF, and sip_destroy_peer().
Referenced by __sip_autodestruct(), _sip_show_peer(), build_peer(), check_peer_ok(), create_addr(), expire_register(), function_sippeer(), handle_request_subscribe(), register_verify(), sip_devicestate(), sip_do_debug_peer(), st_get_mode(), st_get_se(), and update_call_counter().
02324 { 02325 ASTOBJ_UNREF(peer, sip_destroy_peer); 02326 }
static void unref_user | ( | struct sip_user * | user | ) | [static] |
Definition at line 2328 of file chan_sip.c.
References ASTOBJ_UNREF, sip_destroy_user(), and user.
Referenced by check_user_ok(), sip_show_user(), st_get_mode(), st_get_se(), and update_call_counter().
02329 { 02330 ASTOBJ_UNREF(user, sip_destroy_user); 02331 }
static int update_call_counter | ( | struct sip_pvt * | fup, | |
int | event | |||
) | [static] |
update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted.
Remember that for a type=friend, there's one limit for the user and another for the peer, not a combined call limit. This will cause unexpected behaviour in subscriptions, since a "friend" is *two* devices in Asterisk, not one.
Thought: For realtime, we should probably update storage with inuse counter...
Definition at line 4619 of file chan_sip.c.
References sip_peer::_lock, sip_user::_lock, ast_clear_flag, ast_copy_string(), ast_debug, ast_device_state_changed(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), ast_test_flag, sip_peer::call_limit, sip_user::call_limit, DEC_CALL_LIMIT, DEC_CALL_RINGING, FALSE, find_peer(), find_user(), sip_pvt::flags, INC_CALL_LIMIT, INC_CALL_RINGING, sip_peer::inRinging, sip_peer::inUse, sip_user::inUse, inuse, LOG_ERROR, sip_peer::name, name, sip_pvt::outgoing_call, sip_pvt::peername, SIP_CALL_LIMIT, SIP_INC_COUNT, SIP_INC_RINGING, SIP_PAGE2_CALL_ONHOLD, sip_peer_hold(), sip_pvt_lock, sip_pvt_unlock, unref_peer(), unref_user(), and sip_pvt::username.
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().
04620 { 04621 char name[256]; 04622 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 04623 int outgoing = fup->outgoing_call; 04624 struct sip_user *u = NULL; 04625 struct sip_peer *p = NULL; 04626 ast_mutex_t *pu_lock = NULL; 04627 04628 ast_debug(3, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 04629 04630 04631 /* Test if we need to check call limits, in order to avoid 04632 realtime lookups if we do not need it */ 04633 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 04634 return 0; 04635 04636 ast_copy_string(name, fup->username, sizeof(name)); 04637 04638 /* Check the list of users only for incoming calls */ 04639 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 04640 inuse = &u->inUse; 04641 call_limit = &u->call_limit; 04642 inringing = NULL; 04643 pu_lock = &u->_lock; 04644 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1, 0) ) ) { /* Try to find peer */ 04645 inuse = &p->inUse; 04646 call_limit = &p->call_limit; 04647 inringing = &p->inRinging; 04648 ast_copy_string(name, fup->peername, sizeof(name)); 04649 pu_lock = &p->_lock; 04650 } 04651 if (!p && !u) { 04652 ast_debug(2, "%s is not a local device, no call limit\n", name); 04653 return 0; 04654 } 04655 04656 switch(event) { 04657 /* incoming and outgoing affects the inUse counter */ 04658 case DEC_CALL_LIMIT: 04659 /* Decrement inuse count if applicable */ 04660 if (inuse) { 04661 sip_pvt_lock(fup); 04662 ast_mutex_lock(pu_lock); 04663 if (*inuse > 0) { 04664 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 04665 (*inuse)--; 04666 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 04667 } 04668 } else { 04669 *inuse = 0; 04670 } 04671 ast_mutex_unlock(pu_lock); 04672 sip_pvt_unlock(fup); 04673 } 04674 04675 /* Decrement ringing count if applicable */ 04676 if (inringing) { 04677 sip_pvt_lock(fup); 04678 ast_mutex_lock(pu_lock); 04679 if (*inringing > 0) { 04680 if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 04681 (*inringing)--; 04682 ast_clear_flag(&fup->flags[0], SIP_INC_RINGING); 04683 } 04684 } else { 04685 *inringing = 0; 04686 } 04687 ast_mutex_unlock(pu_lock); 04688 sip_pvt_unlock(fup); 04689 } 04690 04691 /* Decrement onhold count if applicable */ 04692 sip_pvt_lock(fup); 04693 ast_mutex_lock(pu_lock); 04694 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) { 04695 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 04696 ast_mutex_unlock(pu_lock); 04697 sip_pvt_unlock(fup); 04698 sip_peer_hold(fup, FALSE); 04699 } else { 04700 ast_mutex_unlock(pu_lock); 04701 sip_pvt_unlock(fup); 04702 } 04703 if (sipdebug) 04704 ast_debug(2, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 04705 break; 04706 04707 case INC_CALL_RINGING: 04708 case INC_CALL_LIMIT: 04709 /* If call limit is active and we have reached the limit, reject the call */ 04710 if (*call_limit > 0 ) { 04711 if (*inuse >= *call_limit) { 04712 ast_log(LOG_ERROR, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 04713 if (u) 04714 unref_user(u); 04715 else 04716 unref_peer(p); 04717 return -1; 04718 } 04719 } 04720 if (inringing && (event == INC_CALL_RINGING)) { 04721 sip_pvt_lock(fup); 04722 ast_mutex_lock(pu_lock); 04723 if (!ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 04724 (*inringing)++; 04725 ast_set_flag(&fup->flags[0], SIP_INC_RINGING); 04726 } 04727 ast_mutex_unlock(pu_lock); 04728 sip_pvt_unlock(fup); 04729 } 04730 if (inuse) { 04731 sip_pvt_lock(fup); 04732 ast_mutex_lock(pu_lock); 04733 if (!ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 04734 (*inuse)++; 04735 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 04736 } 04737 ast_mutex_unlock(pu_lock); 04738 sip_pvt_unlock(fup); 04739 } 04740 if (sipdebug) { 04741 ast_debug(2, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 04742 } 04743 break; 04744 04745 case DEC_CALL_RINGING: 04746 if (inringing) { 04747 sip_pvt_lock(fup); 04748 ast_mutex_lock(pu_lock); 04749 if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) { 04750 if (*inringing > 0) { 04751 (*inringing)--; 04752 } 04753 ast_clear_flag(&fup->flags[0], SIP_INC_RINGING); 04754 } 04755 ast_mutex_unlock(pu_lock); 04756 sip_pvt_unlock(fup); 04757 } 04758 break; 04759 04760 default: 04761 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 04762 } 04763 04764 if (p) { 04765 ast_device_state_changed("SIP/%s", p->name); 04766 unref_peer(p); 04767 } else /* u must be set */ 04768 unref_user(u); 04769 return 0; 04770 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 3691 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::deprecated_username, sip_peer::flags, sip_peer::fullcontact, sip_peer::is_realtime, sip_peer::lastms, sip_peer::name, sip_settings::peer_rtupdate, realtime_update_peer(), sip_cfg, SIP_PAGE2_RTCACHEFRIENDS, and sip_peer::username.
Referenced by register_verify().
03692 { 03693 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 03694 if (sip_cfg.peer_rtupdate && 03695 (p->is_realtime || rtcachefriends)) { 03696 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry, p->deprecated_username, p->lastms); 03697 } 03698 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 23046 of file chan_sip.c.
int allow_external_domains [static] |
Accept calls to external SIP domains?
Definition at line 716 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 749 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 22551 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 22553 of file chan_sip.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 23046 of file chan_sip.c.
Authentication list for realm authentication.
Definition at line 1625 of file chan_sip.c.
Referenced by build_reply_digest(), reload_config(), sip_show_settings(), and unload_module().
int autocreatepeer [static] |
Auto creation of peers at registration? Default off.
Definition at line 686 of file chan_sip.c.
struct sockaddr_in bindaddr [static] |
The address we bind to
Definition at line 1646 of file chan_sip.c.
struct ast_threadstorage check_auth_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_check_auth_buf , .custom_init = NULL , } [static] |
Definition at line 10629 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
struct ast_custom_function checksipdomain_function [static] |
struct ast_cli_entry cli_sip[] [static] |
SIP Cli commands definition.
Definition at line 22828 of file chan_sip.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_sip_do_history_deprecated = { .handler = sip_do_history_deprecated , .summary = "Enable/Disable SIP history" ,__VA_ARGS__ } [static] |
Definition at line 22826 of file chan_sip.c.
int compactheaders [static] |
send compact sip headers
Definition at line 708 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Main configuration file
Definition at line 259 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1691 of file chan_sip.c.
Referenced by sip_debug_test_addr(), sip_do_debug(), sip_do_debug_ip(), and sip_do_debug_peer().
char default_callerid[AST_MAX_EXTENSION] [static] |
Definition at line 652 of file chan_sip.c.
char default_context[AST_MAX_CONTEXT] [static] |
Definition at line 649 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 217 of file chan_sip.c.
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Definition at line 653 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 250 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Definition at line 651 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 660 of file chan_sip.c.
char default_mohinterpret[MAX_MUSICCLASS] [static] |
Global setting for moh class to use when put on hold
Definition at line 657 of file chan_sip.c.
char default_mohsuggest[MAX_MUSICCLASS] [static] |
Global setting for moh class to suggest when putting a bridged channel on hold
Definition at line 658 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Definition at line 654 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 661 of file chan_sip.c.
Referenced by build_device(), build_user(), reload_config(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and temp_peer().
int default_qualify [static] |
Default Qualify= setting
Definition at line 655 of file chan_sip.c.
char default_subscribecontext[AST_MAX_CONTEXT] [static] |
Definition at line 650 of file chan_sip.c.
struct ast_tls_config default_tls_cfg [static] |
Default TLS connection configuration.
Definition at line 2146 of file chan_sip.c.
Referenced by reload_config(), sip_prepare_socket(), sip_show_settings(), and unload_module().
char default_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 656 of file chan_sip.c.
char* descrip_dtmfmode = " SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static] |
Definition at line 22550 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 22556 of file chan_sip.c.
struct sip_pvt* dialoglist = NULL [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 1335 of file chan_sip.c.
Referenced by __sip_destroy(), complete_sipch(), do_monitor(), find_call(), get_sip_pvt_byid_locked(), handle_request_subscribe(), sip_alloc(), sip_show_channel(), sip_show_channels(), sip_show_history(), and unload_module().
ast_mutex_t dialoglock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Protect the SIP dialog list (of sip_pvt's).
Definition at line 1338 of file chan_sip.c.
Referenced by dialoglist_lock(), and dialoglist_unlock().
mapping between dtmf flags and strings
Definition at line 12918 of file chan_sip.c.
Referenced by conf_run(), dtmfmode2str(), send_dtmf(), and str2dtmfmode().
int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 710 of file chan_sip.c.
time_t externexpire [static] |
Expiration counter for re-resolving external host name in dynamic DNS
Definition at line 1677 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor().
char externhost[MAXHOSTNAMELEN] [static] |
External host name
Definition at line 1676 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and sip_show_settings().
struct sockaddr_in externip [static] |
our external IP address/port for SIP sessions. externip.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 "externip = 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;
+ with "stunaddr = host[:port]" we run queries every externrefresh seconds to the specified server, and store the result in externip.
Other variables (externhost, externexpire, externrefresh) are used to support the above functions. External IP address if we are behind NAT
Definition at line 1674 of file chan_sip.c.
int externrefresh = 10 [static] |
Definition at line 1678 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and sip_show_settings().
int global_allowguest [static] |
allow unauthenticated users/peers to connect?
Definition at line 694 of file chan_sip.c.
int global_allowsubscribe [static] |
Flag for disabling ALL subscriptions, this is FALSE only if all peers are FALSE the global setting is in globals_flags[1]
Definition at line 698 of file chan_sip.c.
enum transfermodes global_allowtransfer [static] |
SIP Refer restriction scheme
Definition at line 723 of file chan_sip.c.
int global_alwaysauthreject [static] |
Send 401 Unauthorized for all failing requests
Definition at line 683 of file chan_sip.c.
int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 722 of file chan_sip.c.
int global_callcounter [static] |
Enable call counters for all devices. This is currently enabled by setting the peer call-limit to 999. 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 695 of file chan_sip.c.
int global_callevents [static] |
Whether we send manager events or not
Definition at line 717 of file chan_sip.c.
int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 [static] |
struct ast_ha* global_contact_ha = NULL [static] |
Global list of addresses dynamic peers are not allowed to use.
Definition at line 739 of file chan_sip.c.
Referenced by build_peer(), parse_register_contact(), and reload_config().
unsigned int global_cos_audio [static] |
802.1p class of service for audio RTP packets
Definition at line 705 of file chan_sip.c.
unsigned int global_cos_sip [static] |
802.1p class of service for SIP packets
Definition at line 704 of file chan_sip.c.
unsigned int global_cos_text [static] |
802.1p class of service for text RTP packets
Definition at line 707 of file chan_sip.c.
unsigned int global_cos_video [static] |
802.1p class of service for video RTP packets
Definition at line 706 of file chan_sip.c.
int global_directrtpsetup [static] |
Enable support for Direct RTP setup (no re-invites)
Definition at line 678 of file chan_sip.c.
int global_dynamic_exclude_static = 0 [static] |
Definition at line 740 of file chan_sip.c.
struct ast_flags global_flags[2] = {{0}} [static] |
global SIP_ flags
Definition at line 753 of file chan_sip.c.
Referenced by build_peer(), build_radius_record(), build_user(), get_destination(), load_module(), load_moh_classes(), local_ast_moh_start(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and transmit_response_using_temp().
struct ast_jb_conf global_jbconf [static] |
Global jitterbuffer configuration
Definition at line 257 of file chan_sip.c.
int global_limitonpeers [static] |
Match call limit on peers only
Definition at line 679 of file chan_sip.c.
int global_match_auth_username [static] |
Match auth username if available instead of From: Default off.
Definition at line 687 of file chan_sip.c.
int global_matchexterniplocally [static] |
Match externip/externhost setting against localnet setting
Definition at line 725 of file chan_sip.c.
int global_max_se [static] |
Highest threshold for session refresh interval
Definition at line 734 of file chan_sip.c.
int global_min_se [static] |
Lowest threshold for session refresh interval
Definition at line 733 of file chan_sip.c.
int global_notifyhold [static] |
Send notifications on hold
Definition at line 682 of file chan_sip.c.
int global_notifyringing [static] |
Send notifications on ringing
Definition at line 681 of file chan_sip.c.
struct sip_proxy global_outboundproxy [static] |
Outbound proxy
Definition at line 724 of file chan_sip.c.
Referenced by obproxy_get(), and sip_show_settings().
int global_qualifyfreq [static] |
Qualify frequency
Definition at line 726 of file chan_sip.c.
char global_realm[MAXHOSTNAMELEN] [static] |
Default realm
Definition at line 711 of file chan_sip.c.
int global_reg_timeout [static] |
Definition at line 692 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 693 of file chan_sip.c.
char global_regcontext[AST_MAX_CONTEXT] [static] |
Context for auto-extensions
Definition at line 712 of file chan_sip.c.
int global_regextenonqualify [static] |
Whether to add/remove regexten when qualifying peers
Definition at line 721 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 688 of file chan_sip.c.
int global_rtautoclear [static] |
Realtime ??
Definition at line 680 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Time out call if no RTP during hold
Definition at line 690 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 691 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 689 of file chan_sip.c.
char global_sdpowner[AST_MAX_EXTENSION] [static] |
SDP owner name for the SIP channel
Definition at line 715 of file chan_sip.c.
char global_sdpsession[AST_MAX_EXTENSION] [static] |
SDP session name for the SIP channel
Definition at line 714 of file chan_sip.c.
int global_srvlookup [static] |
SRV Lookup on or off. Default is on
Definition at line 684 of file chan_sip.c.
enum st_mode global_st_mode [static] |
Mode of operation for Session-Timers
Definition at line 731 of file chan_sip.c.
enum st_refresher global_st_refresher [static] |
Session-Timer refresher
Definition at line 732 of file chan_sip.c.
int global_t1 [static] |
T1 time
Definition at line 718 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 719 of file chan_sip.c.
int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 [static] |
Definition at line 1036 of file chan_sip.c.
int global_timer_b [static] |
Timer B - RFC 3261 Section 17.1.1.2
Definition at line 720 of file chan_sip.c.
unsigned int global_tos_audio [static] |
IP type of service for audio RTP packets
Definition at line 701 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 700 of file chan_sip.c.
unsigned int global_tos_text [static] |
IP type of service for text RTP packets
Definition at line 703 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 702 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 713 of file chan_sip.c.
struct _map_x_s insecurestr[] [static] |
struct sockaddr_in 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 1654 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), sip_alloc(), sip_show_settings(), transmit_register(), and transmit_response_using_temp().
struct io_context* io [static] |
The IO context
Definition at line 774 of file chan_sip.c.
List of local networks We store "localnet" addresses from the config file into an access list, marked as 'DENY', so the call to ast_apply_ha() will return AST_SENSE_DENY for 'local' addresses, and AST_SENSE_ALLOW for 'non local' (i.e. presumably public) addresses.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1687 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), sip_show_settings(), and unload_module().
char mandescr_show_peer[] [static] |
Initial value:
"Description: Show one SIP peer with details on current status.\n" "Variables: \n" " Peer: <name> The peer name you want to check.\n" " ActionID: <id> Optional action ID for this AMI transaction.\n"
Definition at line 13201 of file chan_sip.c.
Referenced by load_module().
char mandescr_show_peers[] [static] |
Definition at line 12693 of file chan_sip.c.
char mandescr_show_registry[] [static] |
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 216 of file chan_sip.c.
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 215 of file chan_sip.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
This is the thread for the monitor which checks for input on the channels which are not currently in use.
Definition at line 768 of file chan_sip.c.
ast_mutex_t monlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [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 762 of file chan_sip.c.
ast_mutex_t netlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Definition at line 757 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 260 of file chan_sip.c.
struct ast_config* notify_types [static] |
The list of manual NOTIFY types we know how to send
Definition at line 1693 of file chan_sip.c.
Referenced by complete_sipnotify(), and sip_notify().
int ourport_tcp [static] |
The port used for TCP connections
Definition at line 1689 of file chan_sip.c.
Referenced by _sip_tcp_helper_thread().
int ourport_tls [static] |
The port used for TCP/TLS connections
Definition at line 1690 of file chan_sip.c.
Referenced by _sip_tcp_helper_thread().
int pedanticsipchecking [static] |
Extra checking ? Default off
Definition at line 685 of file chan_sip.c.
struct ast_peer_list peerl [static] |
The peer list: Peers and Friends.
int recordhistory [static] |
Record SIP history. Off by default
Definition at line 709 of file chan_sip.c.
struct _map_x_s referstatusstrings[] [static] |
struct ast_register_list regl [static] |
The register list: Other SIP proxies we register with and place calls to.
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 750 of file chan_sip.c.
struct _map_x_s regstatestrings[] [static] |
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 748 of file chan_sip.c.
int ruserobjs = 0 [static] |
Realtime users
Definition at line 746 of file chan_sip.c.
struct sched_context* sched [static] |
The scheduling context
Definition at line 773 of file chan_sip.c.
struct sip_settings sip_cfg [static] |
Definition at line 670 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), handle_response_peerpoke(), realtime_update_peer(), sip_poke_noanswer(), sip_show_settings(), and update_peer().
struct ast_custom_function sip_header_function [static] |
struct cfsip_methods sip_methods[] [static] |
The core structure to setup dialogs. We parse incoming messages by using structure and then route the messages according to the type.
Referenced by __sip_autodestruct(), __sip_destroy(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), 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 cfsip_options sip_options[] [static] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.
Referenced by _sip_show_peer(), parse_sip_options(), and sip_show_channel().
ast_mutex_t sip_reload_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 770 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 771 of file chan_sip.c.
struct ast_rtp_protocol sip_rtp [static] |
Interface structure with callbacks used to connect to RTP module.
Definition at line 2201 of file chan_sip.c.
Referenced by load_module(), and unload_module().
struct server_args sip_tcp_desc [static] |
The TCP server definition.
Definition at line 2149 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), sip_show_settings(), transmit_register(), and unload_module().
struct ast_channel_tech sip_tech [static] |
Definition of this channel for PBX channel registration.
Definition at line 2105 of file chan_sip.c.
Referenced by load_module(), sip_new(), and unload_module().
struct ast_channel_tech sip_tech_info [static] |
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 2139 of file chan_sip.c.
Referenced by load_module(), and sip_new().
struct ast_tls_config sip_tls_cfg [static] |
struct server_args sip_tls_desc [static] |
The TCP/TLS server definition.
Definition at line 2160 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), sip_show_settings(), and unload_module().
struct ast_udptl_protocol sip_udptl [static] |
Initial value:
{ type: "SIP", get_udptl_info: sip_get_udptl_peer, set_udptl_peer: sip_set_udptl_peer, }
Definition at line 2348 of file chan_sip.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function sipchaninfo_function [static] |
Structure to declare a dialplan function: SIPCHANINFO.
Definition at line 15181 of file chan_sip.c.
Referenced by load_module(), and unload_module().
enum sip_debug_e sipdebug [static] |
Definition at line 1051 of file chan_sip.c.
int sipdebug_text [static] |
extra debugging for 'text' related events. At thie moment this is set together with sip_debug_console. It should either go away or be implemented properly.
Definition at line 1057 of file chan_sip.c.
Structure to declare a dialplan function: SIPPEER.
Definition at line 15096 of file chan_sip.c.
Referenced by load_module(), and unload_module().
int sipsock = -1 [static] |
Main socket for SIP communication.
sipsock is shared between the SIP manager thread (which handles reload requests), the io handler (sipsock_read()) and the user routines that issue 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 1644 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), do_monitor(), 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 775 of file chan_sip.c.
int speerobjs = 0 [static] |
Static peers
Definition at line 747 of file chan_sip.c.
Report Peer status in character string.
Definition at line 12481 of file chan_sip.c.
Referenced by stmode2str(), and str2stmode().
struct _map_x_s strefreshers[] [static] |
Definition at line 12499 of file chan_sip.c.
Referenced by str2strefresher(), and strefresher2str().
struct sockaddr_in stunaddr [static] |
stun server address
Definition at line 1679 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and sip_show_settings().
struct cfsubscription_types subscription_types[] [static] |
Subscription types that we support. We support
Referenced by find_subscription_type(), and subscription_type2str().
int suserobjs = 0 [static] |
Static users
Definition at line 745 of file chan_sip.c.
char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static] |
Definition at line 22549 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 22554 of file chan_sip.c.
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] [static] |
name of automatically created context for unloading
Definition at line 754 of file chan_sip.c.
Referenced by reload_config(), and unload_module().
struct ast_user_list userl [static] |
The user list: Users and friends.