Implementation of Session Initiation Protocol. More...
#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.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/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
#include "asterisk/astobj2.h"
Go to the source code of this file.
Data Structures | |
struct | ast_peer_list |
The peer list: Peers and Friends. More... | |
struct | ast_register_list |
The register list: Other SIP proxys we register with and place calls to. More... | |
struct | ast_user_list |
The user list: Users and friends. More... | |
struct | c_referstatusstring |
struct | cfsip_methods |
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 |
struct | domain |
Domain data structure. More... | |
struct | domain_list |
struct | offered_media |
struct | provisional_keepalive_data |
provisional keep alive scheduler item data More... | |
struct | request_queue |
struct | sip_auth |
sip_auth: Credentials for authentication to other SIP services More... | |
struct | sip_dual |
structure used in transfers More... | |
struct | sip_extenstate_update |
struct | sip_extenstate_updates |
list of extension state updates for the dialog list. 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_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 More... | |
struct | sip_pvt |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe More... | |
struct | sip_refer |
Structure to handle SIP transfers. Dynamically allocated when needed. More... | |
struct | sip_registry |
Registrations with other SIP proxies. 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_user |
Structure for SIP user data. User's place calls to us. More... | |
struct | sip_via |
Structure to store Via information. More... | |
struct | t38properties |
T.38 channel settings (at some point we need to make this alloc'ed. More... | |
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 "Anonymous" |
#define | CAN_CREATE_DIALOG 1 |
#define | CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
#define | CAN_NOT_CREATE_DIALOG 0 |
#define | CHECK_AUTH_BUF_INITLEN 256 |
#define | DEC_CALL_LIMIT 0 |
#define | DEC_CALL_RINGING 2 |
#define | DEFAULT_ALLOW_EXT_DOM TRUE |
#define | DEFAULT_ALLOWGUEST TRUE |
#define | DEFAULT_AUTOCREATEPEER FALSE |
#define | DEFAULT_CALLERID "asterisk" |
#define | DEFAULT_COMPACTHEADERS FALSE |
#define | DEFAULT_CONTEXT "default" |
#define | DEFAULT_DEFAULT_EXPIRY 120 |
#define | DEFAULT_EXPIRY 900 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_CALL_BITRATE (384) |
#define | DEFAULT_MAX_EXPIRY 3600 |
#define | DEFAULT_MAX_FORWARDS "70" |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_MIN_EXPIRY 60 |
#define | DEFAULT_MOHINTERPRET "default" |
#define | DEFAULT_MOHSUGGEST "" |
#define | DEFAULT_MWITIME 10 |
#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_REGISTRATION_TIMEOUT 20 |
#define | DEFAULT_RETRANS 1000 |
#define | DEFAULT_SRVLOOKUP TRUE |
#define | DEFAULT_T1MIN 100 |
#define | DEFAULT_TOS_AUDIO 0 |
#define | DEFAULT_TOS_SIP 0 |
#define | DEFAULT_TOS_VIDEO 0 |
#define | DEFAULT_TRANS_TIMEOUT -1 |
#define | DEFAULT_USERAGENT "Asterisk PBX" |
#define | DEFAULT_VMEXTEN "asterisk" |
#define | EXPIRY_GUARD_LIMIT 30 |
#define | EXPIRY_GUARD_MIN 500 |
#define | EXPIRY_GUARD_PCT 0.20 |
#define | EXPIRY_GUARD_SECS 15 |
#define | FLAG_FATAL (1 << 1) |
#define | FLAG_RESPONSE (1 << 0) |
#define | FORMAT "%-15.15s %-15.15s %-11.11s %5.5d/%5.5d %-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 %-10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT2 "%-15.15s %-15.15s %-11.11s %-11.11s %-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 %-10s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT3H "%-15.15s %-15.15s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" |
#define | FORMAT3L "%-15.15s %-15.15s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" |
#define | FROMDOMAIN_INVALID "anonymous.invalid" |
#define | INC_CALL_LIMIT 1 |
#define | INC_CALL_RINGING 3 |
#define | INITIAL_CSEQ 101 |
#define | MAX_AUTHTRIES 3 |
#define | MAX_HISTORY_ENTRIES 50 |
#define | MAX_RETRANS 6 |
#define | NO_RTP 0 |
#define | NOT_SUPPORTED 0 |
#define | PROVIS_KEEPALIVE_TIMEOUT 60000 |
#define | RTP 1 |
#define | SDP_MAX_RTPMAP_CODECS 32 |
#define | SDP_SAMPLE_RATE(x) 8000 |
#define | SIP_ALREADYGONE (1 << 0) |
#define | SIP_CALL_LIMIT (1 << 28) |
#define | SIP_CAN_REINVITE (1 << 20) |
#define | SIP_CAN_REINVITE_NAT (2 << 20) |
#define | SIP_DEFER_BYE_ON_TRANSFER (1 << 15) |
#define | SIP_DTMF (3 << 16) |
#define | SIP_DTMF_AUTO (3 << 16) |
#define | SIP_DTMF_INBAND (1 << 16) |
#define | SIP_DTMF_INFO (2 << 16) |
#define | SIP_DTMF_RFC2833 (0 << 16) |
#define | SIP_FLAGS_TO_COPY |
#define | SIP_FREE_BIT (1 << 14) |
#define | SIP_G726_NONSTANDARD (1 << 31) |
#define | SIP_GOTREFER (1 << 7) |
#define | SIP_INC_COUNT (1 << 30) |
#define | SIP_INSECURE_INVITE (1 << 24) |
#define | SIP_INSECURE_PORT (1 << 23) |
#define | SIP_MAX_HEADERS 64 |
#define | SIP_MAX_LINES 64 |
#define | SIP_MAX_PACKET 4096 |
#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_NEEDDESTROY (1 << 1) |
#define | SIP_NEEDREINVITE (1 << 5) |
#define | SIP_NO_HISTORY (1 << 27) |
#define | SIP_NOVIDEO (1 << 2) |
#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_OUTGOING (1 << 13) |
#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_DEBUG (3 << 11) |
#define | SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
#define | SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
#define | SIP_PAGE2_DIALOG_ESTABLISHED (1 << 29) |
#define | SIP_PAGE2_DYNAMIC (1 << 13) |
#define | SIP_PAGE2_FLAGS_TO_COPY |
#define | SIP_PAGE2_FORWARD_LOOP_DETECTED (1 << 31) |
#define | SIP_PAGE2_IGNOREREGEXPIRE (1 << 10) |
#define | SIP_PAGE2_INC_RINGING (1 << 19) |
#define | SIP_PAGE2_OUTGOING_CALL (1 << 27) |
#define | SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
#define | SIP_PAGE2_RPORT_PRESENT (1 << 30) |
#define | SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
#define | SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
#define | SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
#define | SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
#define | SIP_PAGE2_RTUPDATE (1 << 1) |
#define | SIP_PAGE2_SELFDESTRUCT (1 << 14) |
#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_UDPTL_DESTINATION (1 << 28) |
#define | SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
#define | SIP_PENDINGBYE (1 << 6) |
#define | SIP_PKT_DEBUG (1 << 0) |
#define | SIP_PKT_IGNORE (1 << 2) |
#define | SIP_PKT_IGNORE_REQ (1 << 4) |
#define | SIP_PKT_WITH_TOTAG (1 << 1) |
#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 << 4) |
#define | SIP_PROMISCREDIR (1 << 8) |
#define | SIP_REALTIME (1 << 11) |
#define | SIP_REINVITE (7 << 20) |
#define | SIP_REINVITE_UPDATE (4 << 20) |
#define | SIP_RINGING (1 << 3) |
#define | SIP_SENDRPID (1 << 29) |
#define | SIP_TRANS_TIMEOUT 32000 |
#define | SIP_TRUSTRPID (1 << 9) |
#define | SIP_USECLIENTCODE (1 << 12) |
#define | SIP_USEREQPHONE (1 << 10) |
#define | SIPBUFSIZE 512 |
#define | sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
#define | sipdebug_config ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG) |
#define | sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
#define | STANDARD_SIP_PORT 5060 |
Standard SIP port from RFC 3261. DO NOT CHANGE THIS. | |
#define | SUPPORTED 1 |
#define | SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support. | |
#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) |
#define | UNLINK(element, head, prev) |
#define | VIDEO_CODEC_MASK 0x1fc0000 |
#define | XMIT_ERROR -2 |
Enumerations | |
enum | check_auth_result { 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 } |
Authentication result from check_auth* functions. More... | |
enum | domain_mode { SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG } |
Modes for SIP domain handling in the PBX. 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, SDP_IMAGE } |
enum | parse_register_result { PARSE_REGISTER_DENIED, 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, WWW_AUTH } |
Authentication types - proxy or www authentication. More... | |
enum | sip_result { AST_SUCCESS = 0, AST_FAILURE = -1 } |
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 | subscriptiontype { NONE = 0, XPIDF_XML, DIALOG_INFO_XML, CPIM_PIDF_XML, PIDF_XML, MWI_NOTIFICATION } |
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 | __reg_module (void) |
static int | __set_address_from_contact (const char *fullcontact, struct sockaddr_in *sin) |
static int | __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
Acknowledges receipt of a packet and stops retransmission called with p locked. | |
static int | __sip_autodestruct (const void *data) |
Kill a SIP dialog (called by scheduler). | |
static int | __sip_destroy (struct sip_pvt *p, int lockowner) |
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_show_channels (int fd, int argc, char *argv[], int subscriptions) |
SIP show channels CLI (main function). | |
static int | __sip_xmit (struct sip_pvt *p, char *data, int len) |
Transmit SIP message. | |
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 int | _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 int | _sip_show_peers (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
_sip_show_peers: Execute sip show peers command | |
static int | acf_channel_read (struct ast_channel *chan, 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, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug, int *min_packet_size) |
Add codec offer to SDP offer/answer body in INVITE or 200 OK. | |
static int | add_content (struct sip_request *req, const char *line) |
Add content (not header) to SIP message. | |
static int | add_digit (struct sip_request *req, char digit, unsigned int duration) |
Add DTMF INFO tone to sip message. | |
static int | add_extensionstate_update (char *context, char *exten, int state, void *data) |
static int | add_header (struct sip_request *req, const char *var, const char *value) |
Add header to SIP message. | |
static void | add_noncodec_to_sdp (const struct sip_pvt *p, int format, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug) |
Add RFC 2833 DTMF offer to SDP. | |
static struct sip_auth * | add_realm_authentication (struct sip_auth *authlist, 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 add_audio, int add_t38) |
Add Session Description Protocol message. | |
static int | add_sip_domain (const char *domain, const enum domain_mode mode, const char *context) |
Add SIP domain to list of domains we are responsible for. | |
static int | add_text (struct sip_request *req, const char *text) |
Add text body to SIP message. | |
static int | add_vidupdate (struct sip_request *req) |
add XML encoded media control with update | |
static int | addr_is_multicast (struct in_addr *addr) |
Check if an ip is an multicast IP. addr the address to check. | |
static void | append_date (struct sip_request *req) |
Append date to SIP message. | |
static void | append_history_full (struct sip_pvt *p, const char *fmt,...) |
Append to SIP dialog history with arg list. | |
static void | append_history_va (struct sip_pvt *p, const char *fmt, va_list ap) |
Append to SIP dialog history with arg list. | |
static void | ast_quiet_chan (struct ast_channel *chan) |
Turn off generator data XXX Does this function belong in the SIP channel? | |
static int | ast_sip_ouraddrfor (struct in_addr *them, struct in_addr *us) |
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 int | auto_congest (const void *nothing) |
Scheduled congestion on a call. | |
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, int devstate_only) |
Build peer from configuration (file or realtime static/dynamic). | |
static int | build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len) |
Build reply digest. | |
static void | build_route (struct sip_pvt *p, struct sip_request *req, int backwards) |
Build route list from Record-Route header. | |
static void | build_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 void | change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly) |
Change hold state for a call. | |
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 void | check_auth_buf_init (void) |
static void | check_extenstate_updates (struct sip_pvt *pvt) |
static void | check_pendings (struct sip_pvt *p) |
Check pending actions on SIP call. | |
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 void | check_via (struct sip_pvt *p, const struct sip_request *req) |
check Via: header for hostname, port and rport request/answer | |
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_extenstate_updates (struct sip_pvt *pvt) |
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 void | clearmarked_extenstate_updates (void) |
static char * | complete_sip_debug_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip debug peer' CLI. | |
static char * | complete_sip_peer (const char *word, int state, int flags2) |
Do completion on peer name. | |
static char * | complete_sip_prune_realtime_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip prune realtime peer' CLI. | |
static char * | complete_sip_prune_realtime_user (const char *line, const char *word, int pos, int state) |
Support routine for 'sip prune realtime user' 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_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' CLI. | |
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 int | copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy SIP VIA Headers from the request to the response. | |
static int | create_addr (struct sip_pvt *dialog, const char *opeer, struct sockaddr_in *sin) |
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. return -1 on error, 0 on success. | |
static void | destroy_association (struct sip_peer *peer) |
Remove registration data from realtime database or AST/DB when registration expires. | |
static int | determine_firstline_parts (struct sip_request *req) |
Parse first line of incoming SIP request. | |
static void | display_nat_warning (const char *cat, int reason, struct ast_flags *flags) |
static void * | do_monitor (void *data) |
The SIP monitoring thread. | |
static int | do_proxy_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, int sipmethod, int init) |
Add authentication on outbound SIP packet. | |
static int | do_register_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader) |
Authenticate for outbound registration. | |
static void | do_setnat (struct sip_pvt *p, int natflags) |
Set nat mode on the various data sockets. | |
static int | does_peer_need_mwi (struct sip_peer *peer) |
Check whether peer needs a new MWI notification check. | |
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 int | finalize_content (struct sip_request *req) |
Add 'Content-Length' header to 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) |
Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, 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 void | free_via (struct sip_via *v) |
static int | func_check_sipdomain (struct ast_channel *chan, 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, char *function, char *data, char *buf, size_t len) |
Read SIP header (dialplan function). | |
static int | function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
${SIPCHANINFO()} Dialplan function - reads sip channel data | |
static int | function_sippeer (struct ast_channel *chan, 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 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 INVITE uri to find out. | |
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 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 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_iterate (int *start, struct sip_request *req, const char *name) |
Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number. | |
static char | get_sdp_line (int *start, int stop, struct sip_request *req, const char **value) |
Fetches the next valid SDP line between the 'start' line (inclusive) and the 'stop' line (exclusive). Returns the type ('a', 'c', ...) and matching line in reference 'start' is updated with the next line number. | |
static struct sip_pvt * | get_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag) |
Lock interface lock and find matching pvt lock. | |
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_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin, int *nounlock) |
Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. | |
static int | handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock) |
Handle incoming SIP requests (methods). | |
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 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. | |
static int | handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, 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 port, int invite) |
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_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 void | markall_extenstate_updates (void) |
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 char * | nat2str (int nat) |
Convert NAT setting to text string. | |
static int | notify_extenstate_update (char *context, char *exten, int state, void *data) |
Callback for the devicestate notification (SUBSCRIBE) support subsystem. | |
static void | parse_copy (struct sip_request *dst, const struct sip_request *src) |
Copy SIP request, parse it. | |
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 unsigned int | parse_sip_options (struct sip_pvt *pvt, const char *supported) |
Parse supported header in incoming packet. | |
static struct sip_via * | parse_via (const char *header) |
Parse a Via header. | |
static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
Report Peer status in character string. | |
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 | process_request_queue (struct sip_pvt *p, int *recount, int *nounlock) |
static int | process_sdp (struct sip_pvt *p, struct sip_request *req) |
Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp(). | |
static int | process_sdp_a_audio (const char *a, struct sip_pvt *p, struct ast_rtp *newaudiortp, int *last_rtpmap_codec) |
static int | process_sdp_a_image (const char *a, struct sip_pvt *p) |
static int | process_sdp_a_sendonly (const char *a, int *sendonly) |
static int | process_sdp_a_video (const char *a, struct sip_pvt *p, struct ast_rtp *newvideortp, int *last_rtpmap_codec) |
static int | process_sdp_c (const char *c, struct ast_hostent *hp) |
static int | process_via (struct sip_pvt *p, const struct sip_request *req) |
Process the Via header according to RFC 3261 section 18.2.2. | |
static int | 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 | |
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey, 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 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 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 void | remove_provisional_keepalive_sched (struct sip_pvt *pvt) |
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 int | retrans_pkt (const void *data) |
Retransmit SIP message if no answer (Called from scheduler). | |
static int | scheduler_process_request_queue (const void *data) |
static int | send_provisional_keepalive (const void *data) |
static int | send_provisional_keepalive_full (struct provisional_keepalive_data *data, int with_sdp) |
This is called by the scheduler to resend the last provisional message in a dialog. | |
static int | send_provisional_keepalive_with_sdp (const void *data) |
static int | send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Send SIP Request to the other part of the dialogue. | |
static int | send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Transmit response on SIP request. | |
static 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 the "insecure" setting from sip.conf or from realtime. | |
static void | set_nonce_randdata (struct sip_pvt *p, int forceupdate) |
builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one. | |
static void | set_peer_defaults (struct sip_peer *peer) |
Set peer defaults before configuring specific configurations. | |
static 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) |
Allocate SIP_PVT structure and set defaults. | |
static void | sip_alreadygone (struct sip_pvt *dialog) |
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. | |
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 void | sip_destroy (struct sip_pvt *p) |
Destroy SIP call structure. | |
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 int | sip_do_debug (int fd, int argc, char *argv[]) |
Turn on SIP debugging (CLI command). | |
static int | sip_do_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_do_debug_ip (int fd, int argc, char *argv[]) |
Enable SIP Debugging in CLI. | |
static int | sip_do_debug_peer (int fd, int argc, char *argv[]) |
sip_do_debug_peer: Turn on SIP debugging with peer mask | |
static int | sip_do_history (int fd, int argc, char *argv[]) |
Enable SIP History logging (CLI). | |
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 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 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_handle_t38_reinvite (struct ast_channel *chan, struct sip_pvt *pvt, int reinvite) |
Handle T38 reinvite. | |
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 int | sip_no_debug (int fd, int argc, char *argv[]) |
Disable SIP Debugging in CLI. | |
static int | sip_no_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_no_history (int fd, int argc, char *argv[]) |
Disable SIP History logging (CLI). | |
static int | sip_notify (int fd, int argc, char *argv[]) |
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 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_prune_realtime (int fd, int argc, char *argv[]) |
Remove temporary realtime objects from memory (CLI). | |
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. | |
static int | sip_register (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 int | sip_reload (int fd, int argc, char *argv[]) |
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. | |
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, int force) |
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_sendtext (struct ast_channel *ast, const char *text) |
Send SIP MESSAGE text within a call Called from PBX core sendtext() application. | |
static int | sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, 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 int | sip_show_channel (int fd, int argc, char *argv[]) |
Show details of one active dialog. | |
static int | sip_show_channels (int fd, int argc, char *argv[]) |
Show active SIP channels. | |
static int | sip_show_domains (int fd, int argc, char *argv[]) |
CLI command to list local domains. | |
static int | sip_show_history (int fd, int argc, char *argv[]) |
Show history details of one dialog. | |
static int | sip_show_inuse (int fd, int argc, char *argv[]) |
CLI Command to show calls within limits set by call_limit. | |
static int | sip_show_objects (int fd, int argc, char *argv[]) |
List all allocated SIP Objects (realtime or static). | |
static int | sip_show_peer (int fd, int argc, char *argv[]) |
Show one peer in detail. | |
static int | sip_show_peers (int fd, int argc, char *argv[]) |
CLI Show Peers command. | |
static int | sip_show_registry (int fd, int argc, char *argv[]) |
Show SIP Registry (registrations with other SIP proxies. | |
static int | sip_show_settings (int fd, int argc, char *argv[]) |
List global settings for the SIP channel. | |
static int | sip_show_subscriptions (int fd, int argc, char *argv[]) |
Show active SIP subscriptions. | |
static int | sip_show_user (int fd, int argc, char *argv[]) |
Show one user in detail. | |
static int | sip_show_users (int fd, int argc, char *argv[]) |
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 int | sip_transfer (struct ast_channel *ast, const char *dest) |
Transfer SIP call. | |
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 to compare URI parameters | |
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 void | stop_media_flows (struct sip_pvt *p) |
Immediately stop RTP, VRTP and UDPTL as applicable. | |
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 void | temp_pvt_init (void) |
A per-thread temporary pvt structure. | |
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_provisional_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, int with_sdp) |
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. | |
static int | transmit_reinvite_with_sdp (struct sip_pvt *p) |
Transmit reinvite with SDP. | |
static int | transmit_reinvite_with_t38_sdp (struct sip_pvt *p) |
Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path. | |
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_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
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 | unmark_extenstate_update (struct sip_pvt *pvt) |
static void * | unref_provisional_keepalive (struct provisional_keepalive_data *data) |
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). | |
static void | update_provisional_keepalive (struct sip_pvt *pvt, int with_sdp) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, } |
static struct in_addr | __ourip |
static int | allow_external_domains |
static int | apeerobjs = 0 |
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 |
static int | autocreatepeer |
static struct sockaddr_in | bindaddr = { 0, } |
static unsigned int | chan_idx |
static struct ast_threadstorage | check_auth_buf = { .once = PTHREAD_ONCE_INIT , .key_init = check_auth_buf_init , } |
static struct ast_custom_function | checksipdomain_function |
static struct ast_cli_entry | cli_sip [] |
static struct ast_cli_entry | cli_sip_debug_deprecated |
static struct ast_cli_entry | cli_sip_no_debug_deprecated |
static int | compactheaders |
static const char | config [] = "sip.conf" |
static char | debug_usage [] |
static struct sockaddr_in | debugaddr |
static char | default_callerid [AST_MAX_EXTENSION] |
static char | default_context [AST_MAX_CONTEXT] |
static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
static char | default_fromdomain [AST_MAX_EXTENSION] |
static struct ast_jb_conf | default_jbconf |
Global jitterbuffer configuration - by default, jb is disabled. | |
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 char * | descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" |
static char * | descrip_sipaddheader |
static int | dumphistory |
static int | expiry = DEFAULT_EXPIRY |
static time_t | externexpire = 0 |
static char | externhost [MAXHOSTNAMELEN] |
static struct sockaddr_in | externip |
static int | externrefresh = 10 |
static int | global_allowguest |
static int | global_allowsubscribe |
static enum transfermodes | global_allowtransfer |
static int | global_alwaysauthreject |
static int | global_autoframing |
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 struct ast_ha * | global_contact_ha = NULL |
Global list of addresses dynamic peers are not allowed to use. | |
static int | global_directrtpsetup |
static int | global_dynamic_exclude_static = 0 |
static struct ast_flags | global_flags [2] = {{0}} |
static struct ast_jb_conf | global_jbconf |
static int | global_limitonpeers |
static int | global_matchexterniplocally |
static int | global_mwitime |
static int | global_notifyhold |
static int | global_notifyringing |
static int | global_prematuremediafilter |
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_relaxdtmf |
static int | global_rtautoclear |
static int | global_rtpholdtimeout |
static int | global_rtpkeepalive |
static int | global_rtptimeout |
static int | global_shrinkcallerid |
static int | global_t1min |
static int | global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 |
static unsigned int | global_tos_audio |
static unsigned int | global_tos_sip |
static unsigned int | global_tos_video |
static char | global_useragent [AST_MAX_EXTENSION] |
static char | history_usage [] |
static struct sip_pvt * | iflist |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe | |
static ast_mutex_t | iflock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
Protect the SIP dialog list (of sip_pvt's). | |
static struct io_context * | io |
static struct ast_ha * | localaddr |
static char | mandescr_show_peer [] |
static char | mandescr_show_peers [] |
static int | max_expiry = DEFAULT_MAX_EXPIRY |
static int | min_expiry = DEFAULT_MIN_EXPIRY |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
static ast_mutex_t | monlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static ast_mutex_t | netlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
static char | no_debug_usage [] |
static char | no_history_usage [] |
static const char | notify_config [] = "sip_notify.conf" |
static struct ast_config * | notify_types = NULL |
static char | notify_usage [] |
static int | ourport |
static struct sockaddr_in | outboundproxyip |
static int | pedanticsipchecking |
static struct ast_peer_list | peerl |
The peer list: Peers and Friends. | |
static char | prune_realtime_usage [] |
static int | recordhistory |
static struct c_referstatusstring | referstatusstrings [] |
static struct ast_register_list | regl |
The register list: Other SIP proxys we register with and place calls to. | |
static int | regobjs = 0 |
static int | rpeerobjs = 0 |
static int | ruserobjs = 0 |
static struct sched_context * | sched |
static char | seen_lastms = 0 |
static char | show_channel_usage [] |
static char | show_channels_usage [] |
static char | show_domains_usage [] |
static char | show_history_usage [] |
static char | show_inuse_usage [] |
static char | show_objects_usage [] |
static char | show_peer_usage [] |
static char | show_peers_usage [] |
static char | show_reg_usage [] |
static char | show_settings_usage [] |
static char | show_subscriptions_usage [] |
static char | show_user_usage [] |
static char | show_users_usage [] |
static struct ast_custom_function | sip_header_function |
static struct cfsip_methods | sip_methods [] |
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 ast_mutex_t | sip_reload_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static char | sip_reload_usage [] |
static int | sip_reloading = FALSE |
static enum channelreloadreason | sip_reloadreason |
static struct ast_rtp_protocol | sip_rtp |
Interface structure with callbacks used to connect to RTP module. | |
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. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames. | |
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. | |
struct ast_custom_function | sippeer_function |
Structure to declare a dialplan function: SIPPEER. | |
static int | sipsock = -1 |
static int * | sipsock_read_id |
static int | speerobjs = 0 |
static int | srvlookup |
static struct cfsubscription_types | subscription_types [] |
static int | suserobjs = 0 |
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 = temp_pvt_init , } |
static struct ast_user_list | userl |
The user list: Users and friends. |
Implementation of Session Initiation Protocol.
See Also:
Implementation of RFC 3261 - without S/MIME, TCP and TLS support Configuration file sip.conf
SIP over TCP
SIP over TLS
Better support of forking
VIA branch tag transaction checking
Transaction support
In the SIP channel, there's a list of active SIP dialogs, which includes all of these when they are active. "sip show channels" in the CLI will show most of these, excluding subscriptions which are shown by "sip show subscriptions"
sipsock_read sends the packet to handle_request(), that parses a bit more. if it's a response to an outbound request, it's sent to handle_response(). If it is a request, handle_request sends it to one of a list of functions depending on the request type - INVITE, OPTIONS, REFER, BYE, CANCEL etc sipsock_read locks the ast_channel if it exists (an active call) and unlocks it after we have processed the SIP message.
A new INVITE is sent to handle_request_invite(), that will end up starting a new channel in the PBX, the new channel after that executing in a separate channel thread. This is an incoming "call". When the call is answered, either by a bridged channel or the PBX itself the sip_answer() function is called.
The actual media - Video or Audio - is mostly handled by the RTP subsystem in rtp.c
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 483 of file chan_sip.c.
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define append_history | ( | p, | |||
event, | |||||
fmt, | |||||
args... | ) | append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history.
Definition at line 1962 of file chan_sip.c.
Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), change_hold_state(), check_auth(), do_register_auth(), handle_invite_replaces(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), handle_response_invite(), local_attended_transfer(), notify_extenstate_update(), 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(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_with_auth().
#define CALLERID_UNKNOWN "Anonymous" |
Definition at line 202 of file chan_sip.c.
Referenced by initreqprep().
#define CAN_CREATE_DIALOG 1 |
Definition at line 374 of file chan_sip.c.
Referenced by find_call().
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
Definition at line 375 of file chan_sip.c.
Referenced by find_call().
#define CAN_NOT_CREATE_DIALOG 0 |
Definition at line 373 of file chan_sip.c.
#define CHECK_AUTH_BUF_INITLEN 256 |
Definition at line 9399 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
#define DEC_CALL_LIMIT 0 |
Definition at line 622 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 624 of file chan_sip.c.
Referenced by handle_response_invite(), and update_call_counter().
#define DEFAULT_ALLOW_EXT_DOM TRUE |
Definition at line 515 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_ALLOWGUEST TRUE |
Definition at line 509 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_AUTOCREATEPEER FALSE |
Definition at line 519 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_CALLERID "asterisk" |
Definition at line 506 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_COMPACTHEADERS FALSE |
Definition at line 511 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_CONTEXT "default" |
Definition at line 502 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_DEFAULT_EXPIRY 120 |
Definition at line 173 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_EXPIRY 900 |
Expire slowly
Definition at line 190 of file chan_sip.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Qualification: How often to check, if the host is down...
Definition at line 207 of file chan_sip.c.
#define DEFAULT_FREQ_OK 60 * 1000 |
Qualification: How often to check for the host to be up
Definition at line 206 of file chan_sip.c.
#define DEFAULT_MAX_CALL_BITRATE (384) |
#define DEFAULT_MAX_EXPIRY 3600 |
Definition at line 175 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_MAX_FORWARDS "70" |
Definition at line 177 of file chan_sip.c.
Referenced by initreqprep(), reqprep(), and transmit_register().
#define DEFAULT_MAXMS 2000 |
Qualification: Must be faster than 2 seconds by default
Definition at line 205 of file chan_sip.c.
#define DEFAULT_MIN_EXPIRY 60 |
Definition at line 174 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_MOHINTERPRET "default" |
Definition at line 503 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_MOHSUGGEST "" |
Definition at line 504 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_MWITIME 10 |
Definition at line 508 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
Definition at line 507 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_NOTIFYRINGING TRUE |
Definition at line 517 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_PEDANTIC FALSE |
Definition at line 518 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_QUALIFY FALSE |
Definition at line 520 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_REALM "asterisk" |
Definition at line 516 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_REGISTRATION_TIMEOUT 20 |
Definition at line 176 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_RETRANS 1000 |
How frequently to retransmit Default: 2 * 500 ms in RFC 3261
Definition at line 209 of file chan_sip.c.
#define DEFAULT_SRVLOOKUP TRUE |
#define DEFAULT_T1MIN 100 |
100 MS for minimal roundtrip time
Definition at line 521 of file chan_sip.c.
Referenced by reload_config().
#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 513 of file chan_sip.c.
Referenced by reload_config().
#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 512 of file chan_sip.c.
Referenced by reload_config().
#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 514 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_TRANS_TIMEOUT -1 |
Definition at line 214 of file chan_sip.c.
Referenced by __sip_autodestruct(), auto_congest(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), 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(), notify_extenstate_update(), 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 524 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_VMEXTEN "asterisk" |
Definition at line 505 of file chan_sip.c.
Referenced by reload_config().
#define EXPIRY_GUARD_LIMIT 30 |
Below here, we use EXPIRY_GUARD_PCT instead of EXPIRY_GUARD_SECS
Definition at line 182 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 184 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 188 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 181 of file chan_sip.c.
Referenced by handle_response_register().
#define FLAG_FATAL (1 << 1) |
Definition at line 1092 of file chan_sip.c.
Referenced by __sip_reliable_xmit(), and retrans_pkt().
#define FLAG_RESPONSE (1 << 0) |
Definition at line 1091 of file chan_sip.c.
Referenced by __sip_ack(), __sip_pretend_ack(), __sip_reliable_xmit(), __sip_semi_ack(), handle_request(), handle_request_invite(), retrans_pkt(), and sip_hangup().
#define FORMAT "%-15.15s %-15.15s %-11.11s %5.5d/%5.5d %-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 %-10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define FORMAT2 "%-15.15s %-15.15s %-11.11s %-11.11s %-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 %-10s\n" |
#define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define FORMAT3H "%-15.15s %-15.15s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" |
Referenced by __sip_show_channels().
#define FORMAT3L "%-15.15s %-15.15s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" |
Referenced by __sip_show_channels().
#define FROMDOMAIN_INVALID "anonymous.invalid" |
Definition at line 203 of file chan_sip.c.
Referenced by initreqprep().
#define INC_CALL_LIMIT 1 |
Definition at line 623 of file chan_sip.c.
Referenced by handle_request_invite(), and update_call_counter().
#define INC_CALL_RINGING 3 |
Definition at line 625 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 224 of file chan_sip.c.
Referenced by sip_alloc(), sip_register(), and transmit_response_using_temp().
#define MAX_AUTHTRIES 3 |
Try authentication three times, then fail
Definition at line 216 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 1089 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 210 of file chan_sip.c.
#define NO_RTP 0 |
Definition at line 240 of file chan_sip.c.
#define NOT_SUPPORTED 0 |
Definition at line 416 of file chan_sip.c.
#define PROVIS_KEEPALIVE_TIMEOUT 60000 |
How long to wait before retransmitting a provisional response (rfc 3261 13.3.1.1)
Definition at line 215 of file chan_sip.c.
Referenced by send_provisional_keepalive_full(), and update_provisional_keepalive().
#define RTP 1 |
Definition at line 239 of file chan_sip.c.
#define SDP_MAX_RTPMAP_CODECS 32 |
Maximum number of codecs allowed in received SDP
Definition at line 222 of file chan_sip.c.
Referenced by process_sdp_a_audio(), and process_sdp_a_video().
#define SDP_SAMPLE_RATE | ( | x | ) | 8000 |
Definition at line 7274 of file chan_sip.c.
Referenced by add_sdp().
#define SIP_ALREADYGONE (1 << 0) |
Whether or not we've already been destroyed by our peer
Definition at line 742 of file chan_sip.c.
Referenced by __sip_autodestruct(), handle_request(), handle_response_invite(), sip_alreadygone(), sip_hangup(), and sip_set_rtp_peer().
#define SIP_CALL_LIMIT (1 << 28) |
Call limit enforced for this call
Definition at line 783 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), and update_call_counter().
#define SIP_CAN_REINVITE (1 << 20) |
allow peers to be reinvited to send media directly p2p
Definition at line 771 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), reload_config(), sip_get_rtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), and sip_handle_t38_reinvite().
#define SIP_CAN_REINVITE_NAT (2 << 20) |
allow media reinvite when new peer is behind NAT
Definition at line 772 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 << 15) |
Do not hangup at first ast_hangup
Definition at line 757 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 (3 << 16) |
DTMF Support: four settings, uses two bits
Definition at line 758 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), 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(), and sip_show_settings().
#define SIP_DTMF_AUTO (3 << 16) |
DTMF Support: AUTO switch between rfc2833 and in-band DTMF
Definition at line 762 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), sip_alloc(), and sip_new().
#define SIP_DTMF_INBAND (1 << 16) |
DTMF Support: Inband audio, only for ULAW/ALAW - "inband"
Definition at line 760 of file chan_sip.c.
Referenced by dtmfmode2str(), handle_common_options(), process_sdp(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
#define SIP_DTMF_INFO (2 << 16) |
DTMF Support: SIP Info messages - "info"
Definition at line 761 of file chan_sip.c.
Referenced by dtmfmode2str(), handle_common_options(), sip_dtmfmode(), sip_new(), and sip_senddigit_end().
#define SIP_DTMF_RFC2833 (0 << 16) |
DTMF Support: RTP DTMF - "rfc2833"
Definition at line 759 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), handle_request_invite(), process_sdp(), reload_config(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
#define SIP_FLAGS_TO_COPY |
(SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \ SIP_PROG_INBAND | SIP_USECLIENTCODE | SIP_NAT | SIP_G726_NONSTANDARD | \ SIP_USEREQPHONE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE)
Definition at line 788 of file chan_sip.c.
Referenced by build_user(), check_user_full(), create_addr_from_peer(), set_peer_defaults(), sip_alloc(), and sip_poke_peer().
#define SIP_FREE_BIT (1 << 14) |
----
Definition at line 756 of file chan_sip.c.
#define SIP_G726_NONSTANDARD (1 << 31) |
Use non-standard packing for G726-32 data
Definition at line 786 of file chan_sip.c.
Referenced by add_codec_to_sdp(), handle_common_options(), and process_sdp_a_audio().
#define SIP_GOTREFER (1 << 7) |
Got a refer?
Definition at line 749 of file chan_sip.c.
Referenced by handle_request_refer(), local_attended_transfer(), sip_handle_t38_reinvite(), sip_read(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_INC_COUNT (1 << 30) |
Did this connection increment the counter of in-use calls?
Definition at line 785 of file chan_sip.c.
Referenced by __sip_destroy(), handle_request_cancel(), sip_hangup(), and update_call_counter().
#define SIP_INSECURE_INVITE (1 << 24) |
don't require authentication for incoming INVITEs
Definition at line 776 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), handle_common_options(), and set_insecure_flags().
#define SIP_INSECURE_PORT (1 << 23) |
don't require matching port for incoming requests
Definition at line 775 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), realtime_peer(), set_insecure_flags(), and sip_addrcmp().
#define SIP_MAX_HEADERS 64 |
Max amount of SIP headers to read
Definition at line 218 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 219 of file chan_sip.c.
Referenced by parse_request().
#define SIP_MAX_PACKET 4096 |
Also from RFC 3261 (2543), should sub headers tho
Definition at line 220 of file chan_sip.c.
#define SIP_NAT (3 << 18) |
four settings, uses two bits
Definition at line 764 of file chan_sip.c.
Referenced by _sip_show_peer(), build_via(), copy_via_headers(), create_addr(), create_addr_from_peer(), display_nat_warning(), 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) |
NAT Both ROUTE and RFC3581
Definition at line 768 of file chan_sip.c.
Referenced by copy_via_headers(), handle_common_options(), nat2str(), and reload_config().
#define SIP_NAT_NEVER (0 << 18) |
No nat support
Definition at line 765 of file chan_sip.c.
Referenced by handle_common_options(), and nat2str().
#define SIP_NAT_RFC3581 (1 << 18) |
NAT RFC3581
Definition at line 766 of file chan_sip.c.
Referenced by build_via(), copy_via_headers(), handle_common_options(), nat2str(), and reload_config().
#define SIP_NAT_ROUTE (2 << 18) |
NAT Only ROUTE
Definition at line 767 of file chan_sip.c.
Referenced by _sip_show_peers(), build_peer(), check_user_full(), create_addr(), create_addr_from_peer(), handle_common_options(), nat2str(), parse_register_contact(), send_request(), set_address_from_contact(), sip_alloc(), sip_nat_mode(), sip_real_dst(), and transmit_response_using_temp().
#define SIP_NEEDDESTROY (1 << 1) |
if we need to be destroyed by the monitor thread
Definition at line 743 of file chan_sip.c.
Referenced by __sip_autodestruct(), __sip_show_channels(), do_monitor(), handle_request(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), retrans_pkt(), sip_hangup(), sip_reg_timeout(), and sip_show_channel().
#define SIP_NEEDREINVITE (1 << 5) |
Do we need to send another reinvite?
Definition at line 747 of file chan_sip.c.
Referenced by check_pendings(), sip_handle_t38_reinvite(), sip_hangup(), sip_read(), sip_reinvite_retry(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_NO_HISTORY (1 << 27) |
Suppress recording request/response history
Definition at line 782 of file chan_sip.c.
Referenced by append_history_full(), do_register_auth(), handle_request_bye(), handle_request_invite(), send_request(), send_response(), sip_alloc(), sip_hangup(), sip_new(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_using_temp().
#define SIP_NOVIDEO (1 << 2) |
Didn't get video in invite, don't offer
Definition at line 744 of file chan_sip.c.
Referenced by add_sdp(), process_sdp(), and sip_indicate().
#define SIP_OPT_100REL (1 << 1) |
Definition at line 419 of file chan_sip.c.
#define SIP_OPT_EARLY_SESSION (1 << 3) |
Definition at line 421 of file chan_sip.c.
#define SIP_OPT_EVENTLIST (1 << 11) |
Definition at line 429 of file chan_sip.c.
#define SIP_OPT_GRUU (1 << 12) |
Definition at line 430 of file chan_sip.c.
#define SIP_OPT_HISTINFO (1 << 15) |
Definition at line 433 of file chan_sip.c.
#define SIP_OPT_JOIN (1 << 4) |
Definition at line 422 of file chan_sip.c.
#define SIP_OPT_NOREFERSUB (1 << 14) |
Definition at line 432 of file chan_sip.c.
#define SIP_OPT_PATH (1 << 5) |
Definition at line 423 of file chan_sip.c.
#define SIP_OPT_PRECONDITION (1 << 7) |
Definition at line 425 of file chan_sip.c.
#define SIP_OPT_PREF (1 << 6) |
Definition at line 424 of file chan_sip.c.
#define SIP_OPT_PRIVACY (1 << 8) |
Definition at line 426 of file chan_sip.c.
#define SIP_OPT_REPLACES (1 << 0) |
Definition at line 418 of file chan_sip.c.
Referenced by handle_request_invite().
#define SIP_OPT_RESPRIORITY (1 << 16) |
Definition at line 434 of file chan_sip.c.
#define SIP_OPT_SDP_ANAT (1 << 9) |
Definition at line 427 of file chan_sip.c.
#define SIP_OPT_SEC_AGREE (1 << 10) |
Definition at line 428 of file chan_sip.c.
#define SIP_OPT_TARGET_DIALOG (1 << 13) |
Definition at line 431 of file chan_sip.c.
#define SIP_OPT_TIMER (1 << 2) |
Definition at line 420 of file chan_sip.c.
#define SIP_OUTGOING (1 << 13) |
Direction of the last transaction in this dialog
Definition at line 755 of file chan_sip.c.
Referenced by 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(), transmit_reinvite_with_t38_sdp(), and transmit_response_with_sdp().
#define SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
Allow overlap dialing ?
Definition at line 810 of file chan_sip.c.
Referenced by _sip_show_peer(), get_destination(), handle_common_options(), handle_request_invite(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
Allow subscriptions from this peer?
Definition at line 809 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), build_user(), handle_common_options(), handle_request_subscribe(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_BUGGY_MWI (1 << 26) |
26: Buggy CISCO MWI fix
Definition at line 822 of file chan_sip.c.
Referenced by handle_common_options(), and transmit_notify_with_mwi().
#define SIP_PAGE2_CALL_ONHOLD (3 << 23) |
Call states
Definition at line 817 of file chan_sip.c.
Referenced by __sip_destroy(), __sip_show_channels(), add_sdp(), change_hold_state(), do_monitor(), handle_request_cancel(), handle_request_invite(), process_sdp(), sip_hangup(), and update_call_counter().
#define SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 23) |
#define SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 23) |
23: Inactive hold
Definition at line 820 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) |
23: One directional hold
Definition at line 819 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_DEBUG (3 << 11) |
Definition at line 803 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
Definition at line 804 of file chan_sip.c.
Referenced by reload_config().
#define SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
Definition at line 805 of file chan_sip.c.
Referenced by reload_config(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), and sip_no_debug_deprecated().
#define SIP_PAGE2_DIALOG_ESTABLISHED (1 << 29) |
29: Has a dialog been established?
Definition at line 825 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_DYNAMIC (1 << 13) |
Dynamic Peers register with Asterisk
Definition at line 806 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), function_sippeer(), register_verify(), and temp_peer().
#define SIP_PAGE2_FLAGS_TO_COPY |
(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_VIDEOSUPPORT | \ SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | SIP_PAGE2_BUGGY_MWI | \ SIP_PAGE2_UDPTL_DESTINATION | SIP_PAGE2_FORWARD_LOOP_DETECTED)
Definition at line 829 of file chan_sip.c.
Referenced by build_user(), check_user_full(), create_addr_from_peer(), set_peer_defaults(), sip_alloc(), and sip_poke_peer().
#define SIP_PAGE2_FORWARD_LOOP_DETECTED (1 << 31) |
31: Do call forward when receiving 482 Loop Detected
Definition at line 827 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), handle_response(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_IGNOREREGEXPIRE (1 << 10) |
Definition at line 802 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_INC_RINGING (1 << 19) |
Did this connection increment the counter of in-use calls?
Definition at line 812 of file chan_sip.c.
Referenced by update_call_counter().
#define SIP_PAGE2_OUTGOING_CALL (1 << 27) |
27: Is this an outgoing call?
Definition at line 823 of file chan_sip.c.
Referenced by get_sip_pvt_byid_locked(), handle_response_invite(), sip_request_call(), and update_call_counter().
#define SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
25: ????
Definition at line 821 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 << 30) |
30: Was rport received in the Via header?
Definition at line 826 of file chan_sip.c.
Referenced by check_user_full(), and check_via().
#define SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
Definition at line 798 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), parse_register_contact(), and reg_source_db().
#define SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
Definition at line 797 of file chan_sip.c.
Referenced by expire_register(), realtime_peer(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
Definition at line 795 of file chan_sip.c.
Referenced by build_peer(), complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), parse_register_contact(), realtime_peer(), realtime_user(), reload_config(), sip_destroy_peer(), sip_destroy_user(), sip_prune_realtime(), sip_show_settings(), update_call_counter(), and update_peer().
#define SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
Definition at line 799 of file chan_sip.c.
Referenced by realtime_update_peer(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_RTUPDATE (1 << 1) |
Definition at line 796 of file chan_sip.c.
Referenced by destroy_association(), handle_response_peerpoke(), reload_config(), sip_poke_noanswer(), sip_show_settings(), and update_peer().
#define SIP_PAGE2_SELFDESTRUCT (1 << 14) |
Automatic peers need to destruct themselves
Definition at line 807 of file chan_sip.c.
Referenced by expire_register(), sip_destroy_peer(), and temp_peer().
#define SIP_PAGE2_STATECHANGEQUEUE (1 << 9) |
D: Unsent state pending change exists
Definition at line 801 of file chan_sip.c.
Referenced by handle_response(), and notify_extenstate_update().
#define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
Only issue MWI notification if subscribed to
Definition at line 811 of file chan_sip.c.
Referenced by build_peer(), does_peer_need_mwi(), and register_verify().
#define SIP_PAGE2_T38SUPPORT (7 << 20) |
T38 Fax Passthrough Support
Definition at line 813 of file chan_sip.c.
Referenced by create_addr_from_peer(), sip_alloc(), and sip_write().
#define SIP_PAGE2_T38SUPPORT_RTP (2 << 20) |
21: T38 Fax Passthrough Support (not implemented)
Definition at line 815 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) |
22: T38 Fax Passthrough Support (not implemented)
Definition at line 816 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and sip_show_settings().
#define SIP_PAGE2_T38SUPPORT_UDPTL (1 << 20) |
20: T38 Fax Passthrough Support
Definition at line 814 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_UDPTL_DESTINATION (1 << 28) |
28: Use source IP of RTP as destination if NAT is enabled
Definition at line 824 of file chan_sip.c.
Referenced by handle_common_options(), and process_sdp().
#define SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
Definition at line 808 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), check_user_full(), create_addr_from_peer(), handle_common_options(), reload_config(), sip_alloc(), and sip_show_settings().
#define SIP_PENDINGBYE (1 << 6) |
Need to send bye after we ack?
Definition at line 748 of file chan_sip.c.
Referenced by check_pendings(), handle_response_invite(), sip_handle_t38_reinvite(), sip_hangup(), sip_read(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_PKT_DEBUG (1 << 0) |
Debug this packet
Definition at line 835 of file chan_sip.c.
Referenced by handle_request(), handle_request_message(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), initialize_initreq(), and sipsock_read().
#define SIP_PKT_IGNORE (1 << 2) |
This is a re-transmit, ignore it
Definition at line 837 of file chan_sip.c.
Referenced by check_auth(), check_user_full(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_message(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), and transmit_fake_auth_response().
#define SIP_PKT_IGNORE_REQ (1 << 4) |
#define SIP_PKT_WITH_TOTAG (1 << 1) |
This packet has a to-tag
Definition at line 836 of file chan_sip.c.
Referenced by find_call(), and handle_request().
#define SIP_PROG_INBAND (3 << 25) |
three settings, uses two bits
Definition at line 778 of file chan_sip.c.
Referenced by handle_common_options(), sip_indicate(), and sip_show_settings().
#define SIP_PROG_INBAND_NEVER (0 << 25) |
Definition at line 779 of file chan_sip.c.
Referenced by sip_indicate(), and sip_show_settings().
#define SIP_PROG_INBAND_NO (1 << 25) |
Definition at line 780 of file chan_sip.c.
Referenced by handle_common_options(), and sip_show_settings().
#define SIP_PROG_INBAND_YES (2 << 25) |
Definition at line 781 of file chan_sip.c.
Referenced by handle_common_options(), and sip_indicate().
#define SIP_PROGRESS_SENT (1 << 4) |
Have sent 183 message progress
Definition at line 746 of file chan_sip.c.
Referenced by sip_indicate(), and sip_write().
#define SIP_PROMISCREDIR (1 << 8) |
Promiscuous redirection
Definition at line 750 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_REALTIME (1 << 11) |
Flag for realtime users
Definition at line 753 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), parse_register_contact(), realtime_peer(), realtime_user(), sip_destroy_peer(), sip_destroy_user(), sip_do_reload(), update_call_counter(), and update_peer().
#define SIP_REINVITE (7 << 20) |
#define SIP_REINVITE_UPDATE (4 << 20) |
use UPDATE (RFC3311) when reinviting this peer
Definition at line 773 of file chan_sip.c.
Referenced by handle_common_options(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define SIP_RINGING (1 << 3) |
#define SIP_SENDRPID (1 << 29) |
Remote Party-ID Support
Definition at line 784 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and initreqprep().
#define SIP_TRANS_TIMEOUT 32000 |
SIP request timeout (rfc 3261) 64*T1
Definition at line 211 of file chan_sip.c.
Referenced by sip_call(), and sip_sipredirect().
#define SIP_TRUSTRPID (1 << 9) |
Trust RPID headers?
Definition at line 751 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), and handle_common_options().
#define SIP_USECLIENTCODE (1 << 12) |
Trust X-ClientCode info message
Definition at line 754 of file chan_sip.c.
Referenced by handle_common_options(), handle_request_info(), and sip_show_settings().
#define SIP_USEREQPHONE (1 << 10) |
Add user=phone to numeric URI. Default off
Definition at line 752 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), initreqprep(), reload_config(), and sip_show_settings().
#define SIPBUFSIZE 512 |
Definition at line 162 of file chan_sip.c.
Referenced by __sip_show_channels(), add_route(), add_sdp(), build_contact(), extract_uri(), handle_request_refer(), initreqprep(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), process_sdp(), respprep(), sip_call(), sip_new(), sip_show_channel(), sip_show_settings(), transmit_invite(), and transmit_notify_with_sipfrag().
#define sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
Definition at line 866 of file chan_sip.c.
Referenced by __sip_ack(), __sip_reliable_xmit(), __sip_semi_ack(), add_sip_domain(), build_reply_digest(), check_auth(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_register(), local_attended_transfer(), parse_request(), parse_sip_options(), reqprep(), retrans_pkt(), sip_addheader(), sip_call(), sip_debug_test_addr(), sip_debug_test_pvt(), sip_dump_history(), sip_hangup(), sip_poke_peer(), sip_reregister(), transmit_invite(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), and update_call_counter().
#define sipdebug_config ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG) |
Definition at line 867 of file chan_sip.c.
#define sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
Definition at line 868 of file chan_sip.c.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
#define STANDARD_SIP_PORT 5060 |
Standard SIP port from RFC 3261. DO NOT CHANGE THIS.
Definition at line 489 of file chan_sip.c.
Referenced by __set_address_from_contact(), build_contact(), build_peer(), check_via(), create_addr(), initreqprep(), parse_register_contact(), process_via(), reload_config(), set_destination(), set_peer_defaults(), sip_show_registry(), transmit_notify_with_mwi(), and transmit_register().
#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 415 of file chan_sip.c.
#define SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support.
Definition at line 486 of file chan_sip.c.
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define T38FAX_FILL_BIT_REMOVAL (1 << 0) |
Default: 0 (unset)
Definition at line 841 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp_a_image().
#define T38FAX_RATE_12000 (1 << 12) |
12000 bps t38FaxRate
Definition at line 860 of file chan_sip.c.
Referenced by process_sdp_a_image(), and t38_get_rate().
#define T38FAX_RATE_14400 (1 << 13) |
14400 bps t38FaxRate This is default: NO MMR and JBIG trancoding, NO fill bit removal, transferredTCF TCF, UDP FEC, Version 0 and 9600 max fax rate
Definition at line 861 of file chan_sip.c.
Referenced by process_sdp_a_image(), and t38_get_rate().
#define T38FAX_RATE_2400 (1 << 8) |
2400 bps t38FaxRate
Definition at line 856 of file chan_sip.c.
Referenced by process_sdp_a_image(), and t38_get_rate().
#define T38FAX_RATE_4800 (1 << 9) |
4800 bps t38FaxRate
Definition at line 857 of file chan_sip.c.
Referenced by process_sdp_a_image(), and t38_get_rate().
#define T38FAX_RATE_7200 (1 << 10) |
7200 bps t38FaxRate
Definition at line 858 of file chan_sip.c.
Referenced by process_sdp_a_image(), and t38_get_rate().
#define T38FAX_RATE_9600 (1 << 11) |
9600 bps t38FaxRate
Definition at line 859 of file chan_sip.c.
Referenced by process_sdp_a_image(), and t38_get_rate().
#define T38FAX_RATE_MANAGEMENT_LOCAL_TCF (1 << 3) |
Unset for transferredTCF (UDPTL), set for localTCF (TPKT)
Definition at line 846 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp_a_image().
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
Definition at line 845 of file chan_sip.c.
Referenced by create_addr_from_peer(), process_sdp_a_image(), and sip_alloc().
#define T38FAX_TRANSCODING_JBIG (1 << 2) |
Default: 0 (unset)
Definition at line 843 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp_a_image().
#define T38FAX_TRANSCODING_MMR (1 << 1) |
Default: 0 (unset)
Definition at line 842 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp_a_image().
#define T38FAX_UDP_EC_FEC (1 << 4) |
Set for t38UDPFEC
Definition at line 849 of file chan_sip.c.
Referenced by create_addr_from_peer(), process_sdp_a_image(), and sip_alloc().
#define T38FAX_UDP_EC_NONE (0 << 4) |
two bits, if unset NO t38UDPEC field in T38 SDP
Definition at line 848 of file chan_sip.c.
Referenced by add_sdp(), create_addr_from_peer(), process_sdp(), process_sdp_a_image(), and sip_alloc().
#define T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
Set for t38UDPRedundancy
Definition at line 850 of file chan_sip.c.
Referenced by add_sdp(), create_addr_from_peer(), process_sdp_a_image(), and sip_alloc().
#define T38FAX_VERSION (3 << 6) |
two bits, 2 values so far, up to 4 values max
Definition at line 852 of file chan_sip.c.
Referenced by add_sdp().
#define T38FAX_VERSION_0 (0 << 6) |
Version 0
Definition at line 853 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp_a_image().
#define T38FAX_VERSION_1 (1 << 6) |
Version 1
Definition at line 854 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp_a_image().
#define UNLINK | ( | element, | |||
head, | |||||
prev | ) |
--- some list management macros.
Definition at line 1720 of file chan_sip.c.
Referenced by __sip_ack(), __sip_destroy(), and handle_request_cancel().
#define VIDEO_CODEC_MASK 0x1fc0000 |
Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO
Definition at line 166 of file chan_sip.c.
#define XMIT_ERROR -2 |
Definition at line 164 of file chan_sip.c.
Referenced by __sip_reliable_xmit(), __sip_xmit(), handle_response_invite(), retrans_pkt(), sip_call(), and sip_poke_peer().
enum check_auth_result |
Authentication result from check_auth* functions.
AUTH_SUCCESSFUL | |
AUTH_CHALLENGE_SENT | |
AUTH_SECRET_FAILED | |
AUTH_USERNAME_MISMATCH | |
AUTH_NOT_FOUND | |
AUTH_FAKE_AUTH | |
AUTH_UNKNOWN_DOMAIN | |
AUTH_PEER_NOT_DYNAMIC | |
AUTH_ACL_FAILED |
Definition at line 349 of file chan_sip.c.
00349 { 00350 AUTH_SUCCESSFUL = 0, 00351 AUTH_CHALLENGE_SENT = 1, 00352 AUTH_SECRET_FAILED = -1, 00353 AUTH_USERNAME_MISMATCH = -2, 00354 AUTH_NOT_FOUND = -3, 00355 AUTH_FAKE_AUTH = -4, 00356 AUTH_UNKNOWN_DOMAIN = -5, 00357 AUTH_PEER_NOT_DYNAMIC = -6, 00358 AUTH_ACL_FAILED = -7, 00359 };
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 705 of file chan_sip.c.
00705 { 00706 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00707 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00708 };
enum invitestates |
States for the INVITE transaction, not the dialog.
INV_NONE |
No state at all, maybe not an INVITE dialog |
INV_CALLING |
Invite sent, no answer |
INV_PROCEEDING |
We got/sent 1xx message |
INV_EARLY_MEDIA |
We got/sent 18x message with to-tag back |
INV_COMPLETED |
Got final response with error. Wait for ACK, then CONFIRMED |
INV_CONFIRMED |
Confirmed response - we've got an ack (Incoming calls only) |
INV_TERMINATED |
Transaction done - either successful (AST_STATE_UP) or failed, but done The only way out of this is a BYE from one side |
INV_CANCELLED |
Transaction cancelled by client or server in non-terminated state |
Definition at line 259 of file chan_sip.c.
00259 { 00260 INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */ 00261 INV_CALLING = 1, /*!< Invite sent, no answer */ 00262 INV_PROCEEDING = 2, /*!< We got/sent 1xx message */ 00263 INV_EARLY_MEDIA = 3, /*!< We got/sent 18x message with to-tag back */ 00264 INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */ 00265 INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */ 00266 INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 00267 The only way out of this is a BYE from one side */ 00268 INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */ 00269 };
enum media_type |
Definition at line 5643 of file chan_sip.c.
Definition at line 286 of file chan_sip.c.
00286 { 00287 PARSE_REGISTER_DENIED, 00288 PARSE_REGISTER_FAILED, 00289 PARSE_REGISTER_UPDATE, 00290 PARSE_REGISTER_QUERY, 00291 };
enum referstatus |
Parameters to know status of transfer.
REFER_IDLE |
No REFER is in progress |
REFER_SENT |
Sent REFER to transferee |
REFER_RECEIVED |
Received REFER from transferer |
REFER_CONFIRMED |
Refer confirmed with a 100 TRYING |
REFER_ACCEPTED |
Accepted by transferee |
REFER_RINGING |
Target Ringing |
REFER_200OK |
Answered by transfer target |
REFER_FAILED |
REFER declined - go on |
REFER_NOAUTH |
We had no auth for REFER |
Definition at line 896 of file chan_sip.c.
00896 { 00897 REFER_IDLE, /*!< No REFER is in progress */ 00898 REFER_SENT, /*!< Sent REFER to transferee */ 00899 REFER_RECEIVED, /*!< Received REFER from transferer */ 00900 REFER_CONFIRMED, /*!< Refer confirmed with a 100 TRYING */ 00901 REFER_ACCEPTED, /*!< Accepted by transferee */ 00902 REFER_RINGING, /*!< Target Ringing */ 00903 REFER_200OK, /*!< Answered by transfer target */ 00904 REFER_FAILED, /*!< REFER declined - go on */ 00905 REFER_NOAUTH /*!< We had no auth for REFER */ 00906 };
enum sip_auth_type |
Authentication types - proxy or www authentication.
Definition at line 343 of file chan_sip.c.
00343 { 00344 PROXY_AUTH, 00345 WWW_AUTH, 00346 };
enum sip_result |
Definition at line 251 of file chan_sip.c.
00251 { 00252 AST_SUCCESS = 0, 00253 AST_FAILURE = -1, 00254 };
enum sipmethod |
SIP Request methods known by Asterisk.
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 |
Definition at line 318 of file chan_sip.c.
00318 { 00319 SIP_UNKNOWN, /* Unknown response */ 00320 SIP_RESPONSE, /* Not request, response to outbound request */ 00321 SIP_REGISTER, 00322 SIP_OPTIONS, 00323 SIP_NOTIFY, 00324 SIP_INVITE, 00325 SIP_ACK, 00326 SIP_PRACK, /* Not supported at all */ 00327 SIP_BYE, 00328 SIP_REFER, 00329 SIP_SUBSCRIBE, 00330 SIP_MESSAGE, 00331 SIP_UPDATE, /* We can send UPDATE; but not accept it */ 00332 SIP_INFO, 00333 SIP_CANCEL, 00334 SIP_PUBLISH, /* Not supported at all */ 00335 SIP_PING, /* Not supported at all, no standard but still implemented out there */ 00336 };
enum sipregistrystate |
States for outbound registrations (with register= lines in sip.conf.
Definition at line 362 of file chan_sip.c.
00362 { 00363 REG_STATE_UNREGISTERED = 0, /*!< We are not registered */ 00364 REG_STATE_REGSENT, /*!< Registration request sent */ 00365 REG_STATE_AUTHSENT, /*!< We have tried to authenticate */ 00366 REG_STATE_REGISTERED, /*!< Registered and done */ 00367 REG_STATE_REJECTED, /*!< Registration rejected */ 00368 REG_STATE_TIMEOUT, /*!< Registration timed out */ 00369 REG_STATE_NOAUTH, /*!< We have no accepted credentials */ 00370 REG_STATE_FAILED, /*!< Registration failed after several tries */ 00371 };
enum subscriptiontype |
Definition at line 293 of file chan_sip.c.
00293 { 00294 NONE = 0, 00295 XPIDF_XML, 00296 DIALOG_INFO_XML, 00297 CPIM_PIDF_XML, 00298 PIDF_XML, 00299 MWI_NOTIFICATION 00300 };
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 877 of file chan_sip.c.
00877 { 00878 T38_DISABLED = 0, /*!< Not enabled */ 00879 T38_LOCAL_REINVITE, /*!< Offered from local - REINVITE */ 00880 T38_PEER_DIRECT, /*!< Offered from peer */ 00881 T38_PEER_REINVITE, /*!< Offered from peer - REINVITE */ 00882 T38_ENABLED /*!< Negotiated (enabled) */ 00883 };
enum transfermodes |
Authorization scheme for call transfers.
Definition at line 245 of file chan_sip.c.
00245 { 00246 TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */ 00247 TRANSFER_CLOSED, /*!< Allow no SIP transfers */ 00248 };
enum xmittype |
XMIT_CRITICAL |
Transmit critical SIP message reliably, with re-transmits. If it fails, it's critical and will cause a teardown of the session |
XMIT_RELIABLE |
Transmit SIP message reliably, with re-transmits |
XMIT_UNRELIABLE |
Transmit SIP message without bothering with re-transmits |
Definition at line 279 of file chan_sip.c.
00279 { 00280 XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits. 00281 If it fails, it's critical and will cause a teardown of the session */ 00282 XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */ 00283 XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */ 00284 };
static const char * __get_header | ( | const struct sip_request * | req, | |
const char * | name, | |||
int * | start | |||
) | [static] |
Definition at line 4675 of file chan_sip.c.
References ast_skip_blanks(), find_alias(), sip_request::header, sip_request::headers, and sip_request::len.
Referenced by build_route(), copy_all_header(), copy_via_headers(), func_header_read(), get_header(), handle_request(), handle_request_subscribe(), handle_response_register(), and parse_register_contact().
04676 { 04677 int pass; 04678 04679 /* 04680 * Technically you can place arbitrary whitespace both before and after the ':' in 04681 * a header, although RFC3261 clearly says you shouldn't before, and place just 04682 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04683 * a good idea to say you can do it, and if you can do it, why in the hell would. 04684 * you say you shouldn't. 04685 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04686 * and we always allow spaces after that for compatibility. 04687 */ 04688 for (pass = 0; name && pass < 2;pass++) { 04689 int x, len = strlen(name); 04690 for (x=*start; x<req->headers; x++) { 04691 if (!strncasecmp(req->header[x], name, len)) { 04692 char *r = req->header[x] + len; /* skip name */ 04693 if (pedanticsipchecking) 04694 r = ast_skip_blanks(r); 04695 04696 if (*r == ':') { 04697 *start = x+1; 04698 return ast_skip_blanks(r+1); 04699 } 04700 } 04701 } 04702 if (pass == 0) /* Try aliases */ 04703 name = find_alias(name, NULL); 04704 } 04705 04706 /* Don't return NULL, so get_header is always a valid pointer */ 04707 return ""; 04708 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 20483 of file chan_sip.c.
static int __set_address_from_contact | ( | const char * | fullcontact, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 8997 of file chan_sip.c.
References ast_copy_string(), ast_gethostbyname(), ast_log(), hp, LOG_NOTICE, LOG_WARNING, STANDARD_SIP_PORT, and strsep().
Referenced by build_peer(), and set_address_from_contact().
08998 { 08999 struct hostent *hp; 09000 struct ast_hostent ahp; 09001 int port; 09002 char *c, *host, *pt; 09003 char contact_buf[256]; 09004 char *contact; 09005 09006 /* Work on a copy */ 09007 ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf)); 09008 contact = contact_buf; 09009 09010 /* Make sure it's a SIP URL */ 09011 if (strncasecmp(contact, "sip:", 4)) { 09012 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 09013 } else 09014 contact += 4; 09015 09016 /* Ditch arguments */ 09017 /* XXX this code is replicated also shortly below */ 09018 09019 /* Grab host */ 09020 host = strchr(contact, '@'); 09021 if (!host) { /* No username part */ 09022 host = contact; 09023 c = NULL; 09024 } else { 09025 *host++ = '\0'; 09026 } 09027 pt = strchr(host, ':'); 09028 if (pt) { 09029 *pt++ = '\0'; 09030 port = atoi(pt); 09031 } else 09032 port = STANDARD_SIP_PORT; 09033 09034 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 09035 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 09036 09037 /* XXX This could block for a long time XXX */ 09038 /* We should only do this if it's a name, not an IP */ 09039 hp = ast_gethostbyname(host, &ahp); 09040 if (!hp) { 09041 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 09042 return -1; 09043 } 09044 sin->sin_family = AF_INET; 09045 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 09046 sin->sin_port = htons(port); 09047 09048 return 0; 09049 }
static int __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 2291 of file chan_sip.c.
References ast_log(), AST_SCHED_DEL_SPINLOCK, ast_test_flag, sip_pvt::callid, sip_pkt::data, FALSE, FLAG_RESPONSE, free, sip_pvt::lock, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::retransid, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, TRUE, and UNLINK.
Referenced by __sip_pretend_ack(), handle_request(), handle_request_invite(), and handle_response().
02292 { 02293 struct sip_pkt *cur, *prev = NULL; 02294 02295 /* Just in case... */ 02296 char *msg; 02297 int res = FALSE; 02298 02299 msg = sip_methods[sipmethod].text; 02300 02301 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02302 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02303 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02304 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02305 if (!resp && (seqno == p->pendinginvite)) { 02306 if (option_debug) 02307 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02308 p->pendinginvite = 0; 02309 } 02310 /* this is our baby */ 02311 res = TRUE; 02312 UNLINK(cur, p->packets, prev); 02313 if (cur->retransid > -1) { 02314 if (sipdebug && option_debug > 3) 02315 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02316 } 02317 /* This odd section is designed to thwart a 02318 * race condition in the packet scheduler. There are 02319 * two conditions under which deleting the packet from the 02320 * scheduler can fail. 02321 * 02322 * 1. The packet has been removed from the scheduler because retransmission 02323 * is being attempted. The problem is that if the packet is currently attempting 02324 * retransmission and we are at this point in the code, then that MUST mean 02325 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 02326 * lock temporarily to allow retransmission. 02327 * 02328 * 2. The packet has reached its maximum number of retransmissions and has 02329 * been permanently removed from the packet scheduler. If this is the case, then 02330 * the packet's retransid will be set to -1. The atomicity of the setting and checking 02331 * of the retransid to -1 is ensured since in both cases p's lock is held. 02332 */ 02333 AST_SCHED_DEL_SPINLOCK(sched, cur->retransid, &p->lock); 02334 free(cur); 02335 break; 02336 } 02337 } 02338 if (option_debug) 02339 ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res == FALSE ? "Not Found" : "Found"); 02340 return res; 02341 }
static int __sip_autodestruct | ( | const void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 2193 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, AST_EXTENSION_DEACTIVATED, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_test_flag, sip_pvt::autokillid, sip_pvt::callid, DEADLOCK_AVOIDANCE, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_pvt::lastmsg, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, sip_pvt::method, method_match(), NONE, option_debug, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_destroy(), sip_methods, SIP_NEEDDESTROY, sip_scheddestroy(), sip_pvt::subscribed, cfsip_methods::text, transmit_request_with_auth(), transmit_state_notify(), TRUE, and XMIT_RELIABLE.
Referenced by sip_scheddestroy().
02194 { 02195 struct sip_pvt *p = (struct sip_pvt *)data; 02196 02197 /* If this is a subscription, tell the phone that we got a timeout */ 02198 if (p->subscribed) { 02199 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 02200 p->subscribed = NONE; 02201 append_history(p, "Subscribestatus", "timeout"); 02202 if (option_debug > 2) 02203 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02204 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02205 } 02206 02207 /* If there are packets still waiting for delivery, delay the destruction */ 02208 /* via bug 12101, the two usages of SIP_NEEDDESTROY in the following block 02209 * of code make a sort of "safety relief valve", that allows sip channels 02210 * that were created via INVITE, then thru some sequence were CANCELED, 02211 * to die, rather than infinitely be rescheduled */ 02212 if (p->packets && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 02213 char method_str[31]; 02214 if (option_debug > 2) 02215 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 02216 append_history(p, "ReliableXmit", "timeout"); 02217 if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) { 02218 if (method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) { 02219 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 02220 } 02221 } 02222 return 10000; 02223 } 02224 02225 /* Reset schedule ID */ 02226 p->autokillid = -1; 02227 02228 if (option_debug) 02229 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02230 append_history(p, "AutoDestroy", "%s", p->callid); 02231 02232 /* 02233 * Lock both the pvt and the channel safely so that we can queue up a frame. 02234 */ 02235 ast_mutex_lock(&p->lock); 02236 while (p->owner && ast_channel_trylock(p->owner)) { 02237 DEADLOCK_AVOIDANCE(&p->lock); 02238 } 02239 02240 if (p->owner) { 02241 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02242 ast_queue_hangup(p->owner); 02243 ast_channel_unlock(p->owner); 02244 ast_mutex_unlock(&p->lock); 02245 } else if (p->refer && !ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 02246 if (option_debug > 2) 02247 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02248 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02249 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02250 ast_mutex_unlock(&p->lock); 02251 } else { 02252 ast_mutex_unlock(&p->lock); 02253 sip_destroy(p); 02254 } 02255 02256 return 0; 02257 }
static int __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 3392 of file chan_sip.c.
References ast_channel::_softhangup, ast_channel_lock, ast_channel_unlock, ast_extension_state_del(), ast_free, AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_destroy(), ast_rtp_get_bridged(), AST_SCHED_DEL, AST_SOFTHANGUP_DEV, ast_string_field_free_memory, ast_test_flag, ast_udptl_destroy(), ast_variables_destroy(), ast_verbose(), ASTOBJ_UNREF, sip_pvt::autokillid, sip_registry::call, sip_pvt::callid, sip_pvt::chanvars, clear_extenstate_updates(), DEC_CALL_LIMIT, sip_pvt::flags, free, free_old_route(), sip_pvt::history, sip_pvt::history_entries, iflist, sip_pvt::initid, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, sip_pvt::method, sip_peer::mwipvt, sip_pkt::next, sip_pvt::next, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::packets, sip_pvt::provisional_keepalive_data, sip_pvt::refer, sip_pvt::registry, sip_pvt::relatedpeer, remove_provisional_keepalive_sched(), sip_pvt::request_queue, sip_pvt::request_queue_sched_id, sip_pkt::retransid, sip_pvt::route, sip_pvt::rtp, sip_debug_test_pvt(), sip_destroy_peer(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_registry_destroy(), sip_pvt::stateid, ast_channel::tech_pvt, cfsip_methods::text, sip_pvt::udptl, UNLINK, unref_provisional_keepalive(), update_call_counter(), sip_pvt::vrtp, and sip_pvt::waitid.
Referenced by do_monitor(), sip_destroy(), and unload_module().
03393 { 03394 struct sip_pvt *cur, *prev = NULL; 03395 struct sip_pkt *cp; 03396 struct sip_request *req; 03397 03398 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 03399 if (p->rtp && ast_rtp_get_bridged(p->rtp)) { 03400 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03401 return -1; 03402 } 03403 03404 if (p->vrtp && ast_rtp_get_bridged(p->vrtp)) { 03405 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03406 return -1; 03407 } 03408 03409 if (sip_debug_test_pvt(p) || option_debug > 2) 03410 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03411 03412 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03413 update_call_counter(p, DEC_CALL_LIMIT); 03414 if (option_debug > 1) 03415 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 03416 } 03417 03418 /* Unlink us from the owner if we have one */ 03419 if (p->owner) { 03420 if (lockowner) 03421 ast_channel_lock(p->owner); 03422 if (option_debug) 03423 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 03424 p->owner->tech_pvt = NULL; 03425 /* Make sure that the channel knows its backend is going away */ 03426 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03427 if (lockowner) 03428 ast_channel_unlock(p->owner); 03429 /* Give the channel a chance to react before deallocation */ 03430 usleep(1); 03431 } 03432 03433 /* Remove link from peer to subscription of MWI */ 03434 if (p->relatedpeer) { 03435 if (p->relatedpeer->mwipvt == p) { 03436 p->relatedpeer->mwipvt = NULL; 03437 } 03438 ASTOBJ_UNREF(p->relatedpeer, sip_destroy_peer); 03439 } 03440 03441 if (dumphistory) 03442 sip_dump_history(p); 03443 03444 if (p->options) 03445 free(p->options); 03446 03447 if (p->stateid > -1) 03448 ast_extension_state_del(p->stateid, NULL); 03449 03450 /* remove any pending extension notify that could be left in 03451 * the extension update queue relating to this dialog. */ 03452 clear_extenstate_updates(p); 03453 03454 AST_SCHED_DEL(sched, p->initid); 03455 AST_SCHED_DEL(sched, p->waitid); 03456 AST_SCHED_DEL(sched, p->autokillid); 03457 AST_SCHED_DEL(sched, p->request_queue_sched_id); 03458 03459 remove_provisional_keepalive_sched(p); 03460 if (p->provisional_keepalive_data) { 03461 ast_mutex_lock(&p->lock); 03462 p->provisional_keepalive_data = unref_provisional_keepalive(p->provisional_keepalive_data); 03463 ast_mutex_unlock(&p->lock); 03464 } 03465 03466 if (p->rtp) { 03467 ast_rtp_destroy(p->rtp); 03468 } 03469 if (p->vrtp) { 03470 ast_rtp_destroy(p->vrtp); 03471 } 03472 if (p->udptl) 03473 ast_udptl_destroy(p->udptl); 03474 if (p->refer) 03475 free(p->refer); 03476 if (p->route) { 03477 free_old_route(p->route); 03478 p->route = NULL; 03479 } 03480 if (p->registry) { 03481 if (p->registry->call == p) 03482 p->registry->call = NULL; 03483 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 03484 } 03485 03486 /* Clear history */ 03487 if (p->history) { 03488 struct sip_history *hist; 03489 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 03490 free(hist); 03491 p->history_entries--; 03492 } 03493 free(p->history); 03494 p->history = NULL; 03495 } 03496 03497 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 03498 ast_free(req); 03499 } 03500 03501 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 03502 if (cur == p) { 03503 UNLINK(cur, iflist, prev); 03504 break; 03505 } 03506 } 03507 if (!cur) { 03508 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 03509 return 0; 03510 } 03511 03512 /* remove all current packets in this dialog */ 03513 while((cp = p->packets)) { 03514 p->packets = p->packets->next; 03515 AST_SCHED_DEL(sched, cp->retransid); 03516 free(cp); 03517 } 03518 if (p->chanvars) { 03519 ast_variables_destroy(p->chanvars); 03520 p->chanvars = NULL; 03521 } 03522 ast_mutex_destroy(&p->lock); 03523 03524 ast_string_field_free_memory(p); 03525 03526 free(p); 03527 return 0; 03528 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 8414 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
08415 { 08416 int res; 08417 08418 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 08419 return res; 08420 }
static void __sip_pretend_ack | ( | struct sip_pvt * | p | ) | [static] |
Pretend to ack all packets called with p locked.
Definition at line 2345 of file chan_sip.c.
References __sip_ack(), ast_log(), ast_test_flag, sip_pkt::data, find_sip_method(), FLAG_RESPONSE, LOG_WARNING, sip_pkt::method, sip_request::method, sip_pvt::packets, sip_pkt::seqno, sip_methods, and cfsip_methods::text.
Referenced by handle_request_bye(), handle_request_cancel(), and sip_reg_timeout().
02346 { 02347 struct sip_pkt *cur = NULL; 02348 02349 while (p->packets) { 02350 int method; 02351 if (cur == p->packets) { 02352 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02353 return; 02354 } 02355 cur = p->packets; 02356 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02357 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02358 } 02359 }
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 2140 of file chan_sip.c.
References __sip_xmit(), append_history, ast_calloc, AST_FAILURE, ast_log(), ast_sched_add_variable(), ast_set_flag, AST_SUCCESS, ast_test_flag, sip_pkt::data, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, LOG_DEBUG, sip_pkt::method, sip_pkt::next, option_debug, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::response_code, retrans_pkt(), sip_pkt::retransid, sip_pkt::seqno, SIP_INVITE, sipdebug, sip_pvt::timer_t1, sip_pkt::timer_t1, and XMIT_ERROR.
Referenced by send_request(), and send_response().
02141 { 02142 struct sip_pkt *pkt; 02143 int siptimer_a = DEFAULT_RETRANS; 02144 int xmitres = 0; 02145 int respid; 02146 02147 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 02148 return AST_FAILURE; 02149 memcpy(pkt->data, data, len); 02150 pkt->method = sipmethod; 02151 pkt->packetlen = len; 02152 pkt->next = p->packets; 02153 pkt->owner = p; 02154 pkt->seqno = seqno; 02155 pkt->data[len] = '\0'; 02156 if (resp) { 02157 ast_set_flag(pkt, FLAG_RESPONSE); 02158 /* Parse out the response code */ 02159 if (sscanf(pkt->data, "SIP/2.0 %30d", &respid) == 1) { 02160 pkt->response_code = respid; 02161 } 02162 } 02163 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 02164 pkt->retransid = -1; 02165 if (fatal) 02166 ast_set_flag(pkt, FLAG_FATAL); 02167 if (pkt->timer_t1) 02168 siptimer_a = pkt->timer_t1 * 2; 02169 02170 if (option_debug > 3 && sipdebug) 02171 ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 02172 pkt->retransid = -1; 02173 pkt->next = p->packets; 02174 p->packets = pkt; 02175 if (sipmethod == SIP_INVITE) { 02176 /* Note this is a pending invite */ 02177 p->pendinginvite = seqno; 02178 } 02179 02180 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 02181 02182 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02183 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02184 return AST_FAILURE; 02185 } else { 02186 /* Schedule retransmission */ 02187 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 02188 return AST_SUCCESS; 02189 } 02190 }
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 2362 of file chan_sip.c.
References ast_log(), AST_SCHED_DEL, ast_test_flag, sip_pvt::callid, sip_pkt::data, FALSE, FLAG_RESPONSE, LOG_DEBUG, method_match(), sip_pkt::next, option_debug, sip_pvt::packets, sip_pkt::retransid, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, and TRUE.
Referenced by handle_response(), and sip_hangup().
02363 { 02364 struct sip_pkt *cur; 02365 int res = FALSE; 02366 02367 for (cur = p->packets; cur; cur = cur->next) { 02368 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02369 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02370 /* this is our baby */ 02371 if (cur->retransid > -1) { 02372 if (option_debug > 3 && sipdebug) 02373 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02374 } 02375 AST_SCHED_DEL(sched, cur->retransid); 02376 res = TRUE; 02377 break; 02378 } 02379 } 02380 if (option_debug) 02381 ast_log(LOG_DEBUG, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res == -1 ? "Not Found" : "Found"); 02382 return res; 02383 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
SIP show channels CLI (main function).
Definition at line 12200 of file chan_sip.c.
References ast_cli(), ast_extension_state2str(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::callid, sip_pvt::cid_num, sip_pvt::expiry, sip_pvt::flags, FORMAT, FORMAT2, FORMAT3H, FORMAT3L, sip_pvt::icseq, iflist, iflock, sip_pvt::lastmsg, sip_pvt::laststate, sip_peer::mailbox, MWI_NOTIFICATION, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, sip_pvt::refer, referstatus2str(), sip_pvt::relatedpeer, RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, sip_pvt::sa, SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, SIPBUFSIZE, sip_refer::status, sip_pvt::subscribed, sip_pvt::subscribeuri, subscription_type2str(), and sip_pvt::username.
Referenced by sip_show_channels(), and sip_show_subscriptions().
12201 { 12202 #define FORMAT3L "%-15.15s %-15.15s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" 12203 #define FORMAT3H "%-15.15s %-15.15s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" 12204 #define FORMAT2 "%-15.15s %-15.15s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" 12205 #define FORMAT "%-15.15s %-15.15s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" 12206 struct sip_pvt *cur; 12207 int numchans = 0; 12208 int usedchans = 0; 12209 char *referstatus = NULL; 12210 12211 if (argc != 3) 12212 return RESULT_SHOWUSAGE; 12213 ast_mutex_lock(&iflock); 12214 cur = iflist; 12215 if (!subscriptions) 12216 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 12217 else 12218 ast_cli(fd, FORMAT3H, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry"); 12219 for (; cur; cur = cur->next) { 12220 referstatus = ""; 12221 if (cur->refer) { /* SIP transfer in progress */ 12222 referstatus = referstatus2str(cur->refer->status); 12223 } 12224 if (cur->subscribed == NONE && !subscriptions) { 12225 char formatbuf[SIPBUFSIZE/2]; 12226 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 12227 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 12228 cur->callid, 12229 cur->ocseq, cur->icseq, 12230 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 12231 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 12232 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 12233 cur->lastmsg , 12234 referstatus 12235 ); 12236 numchans++; 12237 } 12238 if (cur->subscribed != NONE && subscriptions) { 12239 ast_cli(fd, FORMAT3L, ast_inet_ntoa(cur->sa.sin_addr), 12240 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 12241 cur->callid, 12242 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 12243 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 12244 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 12245 subscription_type2str(cur->subscribed), 12246 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>", 12247 cur->expiry 12248 ); 12249 numchans++; 12250 } 12251 if (cur->owner) { /* Count SIP dialog owned by a real channel */ 12252 usedchans++; 12253 } 12254 } 12255 ast_mutex_unlock(&iflock); 12256 if (!subscriptions) 12257 ast_cli(fd, "%d active SIP dialog%s\n", numchans, (numchans != 1) ? "s" : ""); 12258 else 12259 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 12260 ast_cli(fd, "%d used SIP channel%s\n", usedchans, (usedchans != 1) ? "s" : ""); 12261 return RESULT_SUCCESS; 12262 #undef FORMAT 12263 #undef FORMAT2 12264 #undef FORMAT3 12265 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message.
Definition at line 1887 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), errno, LOG_WARNING, sip_real_dst(), sipsock, and XMIT_ERROR.
Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().
01888 { 01889 int res; 01890 const struct sockaddr_in *dst = sip_real_dst(p); 01891 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01892 01893 if (res == -1) { 01894 switch (errno) { 01895 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 01896 case EHOSTUNREACH: /* Host can't be reached */ 01897 case ENETDOWN: /* Inteface down */ 01898 case ENETUNREACH: /* Network failure */ 01899 case ECONNREFUSED: /* ICMP port unreachable */ 01900 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 01901 } 01902 01903 } 01904 01905 if (res != len) 01906 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)); 01907 return res; 01908 }
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 6960 of file chan_sip.c.
References add_header(), ast_cause2str(), ast_log(), 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().
06961 { 06962 struct sip_request resp; 06963 int seqno = 0; 06964 06965 if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) { 06966 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06967 return -1; 06968 } 06969 respprep(&resp, p, msg, req); 06970 /* If we are cancelling an incoming invite for some reason, add information 06971 about the reason why we are doing this in clear text */ 06972 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 06973 char buf[10]; 06974 06975 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 06976 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 06977 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 06978 } 06979 return send_response(p, &resp, reliable, seqno); 06980 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 20483 of file chan_sip.c.
static int _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 11756 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, 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_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, FALSE, find_peer(), sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, cfsip_options::id, insecure2str(), sip_peer::language, sip_peer::lastmsg, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, sip_peer::name, nat2str(), ast_variable::next, sip_auth::next, peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_auth::realm, sip_peer::regexten, RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, sip_destroy_peer(), SIP_DTMF, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, sip_options, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_FORWARD_LOOP_DETECTED, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROMISCREDIR, SIP_REALTIME, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::subscribecontext, text, sip_peer::tohost, transfermode2str(), TRUE, 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().
11757 { 11758 char status[30] = ""; 11759 char cbuf[256]; 11760 struct sip_peer *peer; 11761 char codec_buf[512]; 11762 struct ast_codec_pref *pref; 11763 struct ast_variable *v; 11764 struct sip_auth *auth; 11765 int x = 0, codec = 0, load_realtime; 11766 int realtimepeers; 11767 11768 realtimepeers = ast_check_realtime("sippeers"); 11769 11770 if (argc < 4) 11771 return RESULT_SHOWUSAGE; 11772 11773 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 11774 peer = find_peer(argv[3], NULL, load_realtime, 0); 11775 if (s) { /* Manager */ 11776 if (peer) { 11777 const char *id = astman_get_header(m,"ActionID"); 11778 11779 astman_append(s, "Response: Success\r\n"); 11780 if (!ast_strlen_zero(id)) 11781 astman_append(s, "ActionID: %s\r\n",id); 11782 } else { 11783 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]); 11784 astman_send_error(s, m, cbuf); 11785 return 0; 11786 } 11787 } 11788 if (peer && type==0 ) { /* Normal listing */ 11789 ast_cli(fd,"\n\n"); 11790 ast_cli(fd, " * Name : %s\n", peer->name); 11791 if (realtimepeers) { /* Realtime is enabled */ 11792 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 11793 } 11794 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 11795 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 11796 for (auth = peer->auth; auth; auth = auth->next) { 11797 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 11798 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 11799 } 11800 ast_cli(fd, " Context : %s\n", peer->context); 11801 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 11802 ast_cli(fd, " Language : %s\n", peer->language); 11803 if (!ast_strlen_zero(peer->accountcode)) 11804 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 11805 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 11806 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 11807 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 11808 if (!ast_strlen_zero(peer->fromuser)) 11809 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 11810 if (!ast_strlen_zero(peer->fromdomain)) 11811 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 11812 ast_cli(fd, " Callgroup : "); 11813 print_group(fd, &peer->callgroup, 0); 11814 ast_cli(fd, " Pickupgroup : "); 11815 print_group(fd, &peer->pickupgroup, 0); 11816 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 11817 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 11818 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 11819 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 11820 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 11821 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 11822 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 11823 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 11824 ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT), ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE))); 11825 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 11826 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 11827 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 11828 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 11829 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 11830 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 11831 #endif 11832 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 11833 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 11834 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 11835 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 11836 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 11837 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 11838 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 11839 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 11840 ast_cli(fd, " Forward Loop : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_FORWARD_LOOP_DETECTED) ? "Yes" : "No"); 11841 11842 /* - is enumerated */ 11843 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 11844 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 11845 ast_cli(fd, " ToHost : %s\n", peer->tohost); 11846 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)); 11847 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 11848 if (!ast_strlen_zero(global_regcontext)) 11849 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 11850 ast_cli(fd, " Def. Username: %s\n", peer->username); 11851 ast_cli(fd, " SIP Options : "); 11852 if (peer->sipoptions) { 11853 int lastoption = -1; 11854 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 11855 if (sip_options[x].id != lastoption) { 11856 if (peer->sipoptions & sip_options[x].id) 11857 ast_cli(fd, "%s ", sip_options[x].text); 11858 lastoption = x; 11859 } 11860 } 11861 } else 11862 ast_cli(fd, "(none)"); 11863 11864 ast_cli(fd, "\n"); 11865 ast_cli(fd, " Codecs : "); 11866 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 11867 ast_cli(fd, "%s\n", codec_buf); 11868 ast_cli(fd, " Codec Order : ("); 11869 print_codec_to_cli(fd, &peer->prefs); 11870 ast_cli(fd, ")\n"); 11871 11872 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 11873 ast_cli(fd, " Status : "); 11874 peer_status(peer, status, sizeof(status)); 11875 ast_cli(fd, "%s\n",status); 11876 ast_cli(fd, " Useragent : %s\n", peer->useragent); 11877 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 11878 if (peer->chanvars) { 11879 ast_cli(fd, " Variables :\n"); 11880 for (v = peer->chanvars ; v ; v = v->next) 11881 ast_cli(fd, " %s = %s\n", v->name, v->value); 11882 } 11883 ast_cli(fd,"\n"); 11884 ASTOBJ_UNREF(peer,sip_destroy_peer); 11885 } else if (peer && type == 1) { /* manager listing */ 11886 char buf[256]; 11887 astman_append(s, "Channeltype: SIP\r\n"); 11888 astman_append(s, "ObjectName: %s\r\n", peer->name); 11889 astman_append(s, "ChanObjectType: peer\r\n"); 11890 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 11891 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 11892 astman_append(s, "Context: %s\r\n", peer->context); 11893 astman_append(s, "Language: %s\r\n", peer->language); 11894 if (!ast_strlen_zero(peer->accountcode)) 11895 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 11896 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 11897 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 11898 if (!ast_strlen_zero(peer->fromuser)) 11899 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 11900 if (!ast_strlen_zero(peer->fromdomain)) 11901 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 11902 astman_append(s, "Callgroup: "); 11903 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), &peer->callgroup)); 11904 astman_append(s, "Pickupgroup: "); 11905 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), &peer->pickupgroup)); 11906 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 11907 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 11908 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 11909 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 11910 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 11911 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 11912 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 11913 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 11914 astman_append(s, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT), ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE))); 11915 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 11916 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 11917 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 11918 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 11919 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 11920 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 11921 11922 /* - is enumerated */ 11923 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 11924 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 11925 astman_append(s, "ToHost: %s\r\n", peer->tohost); 11926 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)); 11927 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)); 11928 astman_append(s, "Default-Username: %s\r\n", peer->username); 11929 if (!ast_strlen_zero(global_regcontext)) 11930 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 11931 astman_append(s, "Codecs: "); 11932 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 11933 astman_append(s, "%s\r\n", codec_buf); 11934 astman_append(s, "CodecOrder: "); 11935 pref = &peer->prefs; 11936 for(x = 0; x < 32 ; x++) { 11937 codec = ast_codec_pref_index(pref,x); 11938 if (!codec) 11939 break; 11940 astman_append(s, "%s", ast_getformatname(codec)); 11941 if (x < 31 && ast_codec_pref_index(pref,x+1)) 11942 astman_append(s, ","); 11943 } 11944 11945 astman_append(s, "\r\n"); 11946 astman_append(s, "Status: "); 11947 peer_status(peer, status, sizeof(status)); 11948 astman_append(s, "%s\r\n", status); 11949 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 11950 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 11951 if (peer->chanvars) { 11952 for (v = peer->chanvars ; v ; v = v->next) { 11953 astman_append(s, "ChanVariable:\n"); 11954 astman_append(s, " %s,%s\r\n", v->name, v->value); 11955 } 11956 } 11957 11958 ASTOBJ_UNREF(peer,sip_destroy_peer); 11959 11960 } else { 11961 ast_cli(fd,"Peer %s not found.\n", argv[3]); 11962 ast_cli(fd,"\n"); 11963 } 11964 11965 return RESULT_SUCCESS; 11966 }
static int _sip_show_peers | ( | int | fd, | |
int * | total, | |||
struct mansession * | s, | |||
const struct message * | m, | |||
int | argc, | |||
const char * | argv[] | |||
) | [static] |
_sip_show_peers: Execute sip show peers command
Definition at line 11299 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, FALSE, FORMAT, FORMAT2, id, name, peer_status(), peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_NAT_ROUTE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_VIDEOSUPPORT, SIP_REALTIME, and TRUE.
Referenced by manager_sip_show_peers(), and sip_show_peers().
11300 { 11301 regex_t regexbuf; 11302 int havepattern = FALSE; 11303 11304 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 11305 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 11306 11307 char name[256]; 11308 int total_peers = 0; 11309 int peers_mon_online = 0; 11310 int peers_mon_offline = 0; 11311 int peers_unmon_offline = 0; 11312 int peers_unmon_online = 0; 11313 const char *id; 11314 char idtext[256] = ""; 11315 int realtimepeers; 11316 11317 realtimepeers = ast_check_realtime("sippeers"); 11318 11319 if (s) { /* Manager - get ActionID */ 11320 id = astman_get_header(m,"ActionID"); 11321 if (!ast_strlen_zero(id)) 11322 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 11323 } 11324 11325 switch (argc) { 11326 case 5: 11327 if (!strcasecmp(argv[3], "like")) { 11328 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 11329 return RESULT_SHOWUSAGE; 11330 havepattern = TRUE; 11331 } else 11332 return RESULT_SHOWUSAGE; 11333 case 3: 11334 break; 11335 default: 11336 return RESULT_SHOWUSAGE; 11337 } 11338 11339 if (!s) /* Normal list */ 11340 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 11341 11342 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 11343 char status[20] = ""; 11344 char srch[2000]; 11345 char pstatus; 11346 11347 ASTOBJ_RDLOCK(iterator); 11348 11349 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 11350 ASTOBJ_UNLOCK(iterator); 11351 continue; 11352 } 11353 11354 if (!ast_strlen_zero(iterator->username) && !s) 11355 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 11356 else 11357 ast_copy_string(name, iterator->name, sizeof(name)); 11358 11359 pstatus = peer_status(iterator, status, sizeof(status)); 11360 if (pstatus == 1) 11361 peers_mon_online++; 11362 else if (pstatus == 0) 11363 peers_mon_offline++; 11364 else { 11365 if (iterator->addr.sin_port == 0) 11366 peers_unmon_offline++; 11367 else 11368 peers_unmon_online++; 11369 } 11370 11371 snprintf(srch, sizeof(srch), FORMAT, name, 11372 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 11373 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 11374 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 11375 iterator->ha ? " A " : " ", /* permit/deny */ 11376 ntohs(iterator->addr.sin_port), status, 11377 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 11378 11379 if (!s) {/* Normal CLI list */ 11380 ast_cli(fd, FORMAT, name, 11381 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 11382 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 11383 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 11384 iterator->ha ? " A " : " ", /* permit/deny */ 11385 11386 ntohs(iterator->addr.sin_port), status, 11387 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 11388 } else { /* Manager format */ 11389 /* The names here need to be the same as other channels */ 11390 astman_append(s, 11391 "Event: PeerEntry\r\n%s" 11392 "Channeltype: SIP\r\n" 11393 "ObjectName: %s\r\n" 11394 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 11395 "IPaddress: %s\r\n" 11396 "IPport: %d\r\n" 11397 "Dynamic: %s\r\n" 11398 "Natsupport: %s\r\n" 11399 "VideoSupport: %s\r\n" 11400 "ACL: %s\r\n" 11401 "Status: %s\r\n" 11402 "RealtimeDevice: %s\r\n\r\n", 11403 idtext, 11404 iterator->name, 11405 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 11406 ntohs(iterator->addr.sin_port), 11407 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 11408 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 11409 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 11410 iterator->ha ? "yes" : "no", /* permit/deny */ 11411 status, 11412 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 11413 } 11414 11415 ASTOBJ_UNLOCK(iterator); 11416 11417 total_peers++; 11418 } while(0) ); 11419 11420 if (!s) 11421 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 11422 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 11423 11424 if (havepattern) 11425 regfree(®exbuf); 11426 11427 if (total) 11428 *total = total_peers; 11429 11430 11431 return RESULT_SUCCESS; 11432 #undef FORMAT 11433 #undef FORMAT2 11434 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 16582 of file chan_sip.c.
References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), ast_rtp_get_quality(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_rtp_quality::local_count, ast_rtp_quality::local_jitter, ast_rtp_quality::local_lostpackets, ast_rtp_quality::local_ssrc, LOG_ERROR, LOG_WARNING, parse(), ast_rtp_quality::remote_count, ast_rtp_quality::remote_jitter, ast_rtp_quality::remote_lostpackets, ast_rtp_quality::remote_ssrc, sip_pvt::rtp, ast_rtp_quality::rtt, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, type, and sip_pvt::vrtp.
16583 { 16584 struct ast_rtp_quality qos; 16585 struct sip_pvt *p = chan->tech_pvt; 16586 char *all = "", *parse = ast_strdupa(preparse); 16587 AST_DECLARE_APP_ARGS(args, 16588 AST_APP_ARG(param); 16589 AST_APP_ARG(type); 16590 AST_APP_ARG(field); 16591 ); 16592 AST_STANDARD_APP_ARGS(args, parse); 16593 16594 /* Sanity check */ 16595 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 16596 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 16597 return 0; 16598 } 16599 16600 if (strcasecmp(args.param, "rtpqos")) 16601 return 0; 16602 16603 /* Default arguments of audio,all */ 16604 if (ast_strlen_zero(args.type)) 16605 args.type = "audio"; 16606 if (ast_strlen_zero(args.field)) 16607 args.field = "all"; 16608 16609 memset(buf, 0, buflen); 16610 memset(&qos, 0, sizeof(qos)); 16611 16612 if (p == NULL) { 16613 return -1; 16614 } 16615 16616 if (strcasecmp(args.type, "AUDIO") == 0) { 16617 all = ast_rtp_get_quality(p->rtp, &qos); 16618 } else if (strcasecmp(args.type, "VIDEO") == 0) { 16619 all = ast_rtp_get_quality(p->vrtp, &qos); 16620 } 16621 16622 if (strcasecmp(args.field, "local_ssrc") == 0) 16623 snprintf(buf, buflen, "%u", qos.local_ssrc); 16624 else if (strcasecmp(args.field, "local_lostpackets") == 0) 16625 snprintf(buf, buflen, "%u", qos.local_lostpackets); 16626 else if (strcasecmp(args.field, "local_jitter") == 0) 16627 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 16628 else if (strcasecmp(args.field, "local_count") == 0) 16629 snprintf(buf, buflen, "%u", qos.local_count); 16630 else if (strcasecmp(args.field, "remote_ssrc") == 0) 16631 snprintf(buf, buflen, "%u", qos.remote_ssrc); 16632 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 16633 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 16634 else if (strcasecmp(args.field, "remote_jitter") == 0) 16635 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 16636 else if (strcasecmp(args.field, "remote_count") == 0) 16637 snprintf(buf, buflen, "%u", qos.remote_count); 16638 else if (strcasecmp(args.field, "rtt") == 0) 16639 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 16640 else if (strcasecmp(args.field, "all") == 0) 16641 ast_copy_string(buf, all, buflen); 16642 else { 16643 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 16644 return -1; 16645 } 16646 return 0; 16647 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2396 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
static void add_codec_to_sdp | ( | const struct sip_pvt * | p, | |
int | codec, | |||
int | sample_rate, | |||
char ** | m_buf, | |||
size_t * | m_size, | |||
char ** | a_buf, | |||
size_t * | a_size, | |||
int | debug, | |||
int * | min_packet_size | |||
) | [static] |
Add codec offer to SDP offer/answer body in INVITE or 200 OK.
Definition at line 7170 of file chan_sip.c.
References ast_build_string(), 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_test_flag, ast_verbose(), ast_format_list::cur_ms, sip_pvt::flags, sip_pvt::rtp, and SIP_G726_NONSTANDARD.
Referenced by add_sdp().
07173 { 07174 int rtp_code; 07175 struct ast_format_list fmt; 07176 07177 07178 if (debug) 07179 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 07180 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 07181 return; 07182 07183 if (p->rtp) { 07184 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 07185 fmt = ast_codec_pref_getsize(pref, codec); 07186 } 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 */ 07187 return; 07188 ast_build_string(m_buf, m_size, " %d", rtp_code); 07189 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 07190 ast_rtp_lookup_mime_subtype(1, codec, 07191 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 07192 sample_rate); 07193 if (codec == AST_FORMAT_G729A) { 07194 /* Indicate that we don't support VAD (G.729 annex B) */ 07195 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 07196 } else if (codec == AST_FORMAT_G723_1) { 07197 /* Indicate that we don't support VAD (G.723.1 annex A) */ 07198 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 07199 } else if (codec == AST_FORMAT_ILBC) { 07200 /* Add information about us using only 20/30 ms packetization */ 07201 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 07202 } 07203 07204 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 07205 *min_packet_size = fmt.cur_ms; 07206 07207 /* Our first codec packetization processed cannot be less than zero */ 07208 if ((*min_packet_size) == 0 && fmt.cur_ms) 07209 *min_packet_size = fmt.cur_ms; 07210 }
static int add_content | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 6491 of file chan_sip.c.
References ast_log(), sip_request::content, sip_request::data, sip_request::len, sip_request::lines, and LOG_WARNING.
Referenced by add_digit(), add_sdp(), add_text(), add_vidupdate(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), and transmit_state_notify().
06492 { 06493 if (req->lines) { 06494 ast_log(LOG_WARNING, "Can't add more content when the content has been finalized\n"); 06495 return -1; 06496 } 06497 06498 if (req->len + strlen(req->content) + strlen(line) >= sizeof(req->data) - 4) { 06499 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 06500 return -1; 06501 } 06502 06503 snprintf(req->content + strlen(req->content), sizeof(req->content) - strlen(req->content), "%s", line); 06504 return 0; 06505 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 7140 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_info_with_digit().
07141 { 07142 char tmp[256]; 07143 07144 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 07145 add_header(req, "Content-Type", "application/dtmf-relay"); 07146 add_content(req, tmp); 07147 return 0; 07148 }
static int add_extensionstate_update | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Definition at line 9601 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, AST_PTHREADT_STOP, sip_extenstate_update::context, sip_extenstate_update::exten, sip_extenstate_update::pvt, sip_extenstate_update::state, and update().
Referenced by handle_request_subscribe().
09602 { 09603 struct sip_extenstate_update *update; 09604 size_t exten_len = strlen(exten); 09605 size_t context_len = strlen(context); 09606 09607 if (!(update = ast_calloc(1, sizeof(*update) + exten_len + context_len + 2))) { 09608 return -1; 09609 } 09610 09611 strcpy(update->exten, exten); 09612 09613 update->context = (char *) (update->exten + exten_len + 1); 09614 strcpy(update->context, context); 09615 09616 update->state = state; 09617 update->pvt = data; 09618 09619 AST_LIST_LOCK(&sip_extenstate_updates); 09620 AST_LIST_INSERT_TAIL(&sip_extenstate_updates, update, list); 09621 AST_LIST_UNLOCK(&sip_extenstate_updates); 09622 09623 /* Tell the do_monitor thread it has to do stuff! That thread is so lazy :( */ 09624 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 09625 pthread_kill(monitor_thread, SIGURG); 09626 } 09627 09628 return 0; 09629 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 6437 of file chan_sip.c.
References ast_log(), sip_request::content, sip_request::data, find_alias(), sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, LOG_WARNING, and SIP_MAX_HEADERS.
Referenced by __transmit_response(), add_digit(), add_route(), add_sdp(), add_text(), add_vidupdate(), append_date(), copy_all_header(), copy_header(), copy_via_headers(), finalize_content(), initreqprep(), reqprep(), respprep(), sip_notify(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_unsupported(), and transmit_state_notify().
06438 { 06439 int maxlen = sizeof(req->data) - 4 - req->len - strlen(req->content); /* 4 bytes are for two \r\n ? */ 06440 06441 if (req->headers == SIP_MAX_HEADERS) { 06442 ast_log(LOG_WARNING, "Out of SIP header space\n"); 06443 return -1; 06444 } 06445 06446 if (req->lines) { 06447 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 06448 return -1; 06449 } 06450 06451 if (maxlen <= 0) { 06452 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 06453 return -1; 06454 } 06455 06456 req->header[req->headers] = req->data + req->len; 06457 06458 if (compactheaders) 06459 var = find_alias(var, var); 06460 06461 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 06462 req->len += strlen(req->header[req->headers]); 06463 req->headers++; 06464 06465 return 0; 06466 }
static void add_noncodec_to_sdp | ( | const struct sip_pvt * | p, | |
int | format, | |||
int | sample_rate, | |||
char ** | m_buf, | |||
size_t * | m_size, | |||
char ** | a_buf, | |||
size_t * | a_size, | |||
int | debug | |||
) | [static] |
Add RFC 2833 DTMF offer to SDP.
Definition at line 7249 of file chan_sip.c.
References ast_build_string(), AST_RTP_DTMF, ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), ast_verbose(), and sip_pvt::rtp.
Referenced by add_sdp().
07252 { 07253 int rtp_code; 07254 07255 if (debug) 07256 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 07257 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 07258 return; 07259 07260 ast_build_string(m_buf, m_size, " %d", rtp_code); 07261 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 07262 ast_rtp_lookup_mime_subtype(0, format, 0), 07263 sample_rate); 07264 if (format == AST_RTP_DTMF) 07265 /* Indicate we support DTMF and FLASH... */ 07266 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 07267 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static, read] |
Add realm authentication in list.
Definition at line 18413 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_log(), ast_strlen_zero(), ast_verbose(), LOG_DEBUG, LOG_WARNING, sip_auth::md5secret, sip_auth::next, option_debug, option_verbose, sip_auth::realm, sip_auth::secret, secret, sip_auth::username, and username.
Referenced by build_peer(), and reload_config().
18414 { 18415 char authcopy[256]; 18416 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 18417 struct sip_auth *a, *b, *auth; 18418 18419 if (ast_strlen_zero(configuration)) 18420 return authlist; 18421 18422 if (option_debug) 18423 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 18424 18425 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 18426 18427 username = authcopy; 18428 /* split user[:secret] and realm */ 18429 realm = strrchr(username, '@'); 18430 if (realm) 18431 *realm++ = '\0'; 18432 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 18433 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 18434 return authlist; 18435 } 18436 18437 /* parse username at ':' for secret, or '#" for md5secret */ 18438 if ((secret = strchr(username, ':'))) { 18439 *secret++ = '\0'; 18440 } else if ((md5secret = strchr(username, '#'))) { 18441 *md5secret++ = '\0'; 18442 } 18443 18444 if (!(auth = ast_calloc(1, sizeof(*auth)))) 18445 return authlist; 18446 18447 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 18448 ast_copy_string(auth->username, username, sizeof(auth->username)); 18449 if (secret) 18450 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 18451 if (md5secret) 18452 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 18453 18454 /* find the end of the list */ 18455 for (b = NULL, a = authlist; a ; b = a, a = a->next) 18456 ; 18457 if (b) 18458 b->next = auth; /* Add structure add end of list */ 18459 else 18460 authlist = auth; 18461 18462 if (option_verbose > 2) 18463 ast_verbose("Added authentication for realm %s\n", realm); 18464 18465 return authlist; 18466 18467 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 6606 of file chan_sip.c.
References add_header(), ast_copy_string(), sip_route::hop, sip_route::next, and SIPBUFSIZE.
Referenced by initreqprep(), and reqprep().
06607 { 06608 char r[SIPBUFSIZE*2], *p; 06609 int n, rem = sizeof(r); 06610 06611 if (!route) 06612 return; 06613 06614 p = r; 06615 for (;route ; route = route->next) { 06616 n = strlen(route->hop); 06617 if (rem < n+3) /* we need room for ",<route>" */ 06618 break; 06619 if (p != r) { /* add a separator after fist route */ 06620 *p++ = ','; 06621 --rem; 06622 } 06623 *p++ = '<'; 06624 ast_copy_string(p, route->hop, rem); /* cannot fail */ 06625 p += n; 06626 *p++ = '>'; 06627 rem -= (n+2); 06628 } 06629 *p = '\0'; 06630 add_header(req, "Route", r); 06631 }
static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p, | |||
int | add_audio, | |||
int | add_t38 | |||
) | [static] |
Add Session Description Protocol message.
Definition at line 7277 of file chan_sip.c.
References add_codec_to_sdp(), add_content(), add_header(), add_noncodec_to_sdp(), ast_build_string(), ast_codec_pref_index(), AST_FAILURE, AST_FORMAT_AUDIO_MASK, AST_FORMAT_MAX_AUDIO, AST_FORMAT_MAX_VIDEO, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_inet_ntoa(), ast_internal_timing_enabled(), ast_log(), ast_rtp_get_us(), AST_RTP_MAX, AST_SUCCESS, ast_test_flag, ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), ast_verbose(), t38properties::capability, capability, debug, FALSE, sip_pvt::flags, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, sip_pvt::maxcallbitrate, offered_media::offered, sip_pvt::offered_media, option_debug, sip_pvt::ourip, sip_pvt::owner, t38properties::peercapability, sip_pvt::prefcodec, sip_pvt::prefs, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, SDP_AUDIO, SDP_IMAGE, SDP_SAMPLE_RATE, SDP_VIDEO, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_T38SUPPORT_RTP, SIPBUFSIZE, 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, offered_media::text, TRUE, sip_pvt::udptl, sip_pvt::udptlredirip, sip_pvt::vredirip, and sip_pvt::vrtp.
Referenced by transmit_invite(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), transmit_response_with_sdp(), and transmit_response_with_t38_sdp().
07278 { 07279 int alreadysent = 0; 07280 int doing_directmedia = FALSE; 07281 07282 struct sockaddr_in sin; 07283 struct sockaddr_in vsin; 07284 struct sockaddr_in dest; 07285 struct sockaddr_in vdest = { 0, }; 07286 07287 /* SDP fields */ 07288 char *version = "v=0\r\n"; /* Protocol version */ 07289 char *subject = "s=session\r\n"; /* Subject of the session */ 07290 char owner[256]; /* Session owner/creator */ 07291 char connection[256]; /* Connection data */ 07292 char *stime = "t=0 0\r\n"; /* Time the session is active */ 07293 char bandwidth[256] = ""; /* Max bitrate */ 07294 char *hold; 07295 char m_audio[256]; /* Media declaration line for audio */ 07296 char m_video[256]; /* Media declaration line for video */ 07297 char m_modem[256]; /* Media declaration line for t38 */ 07298 char a_audio[1024]; /* Attributes for audio */ 07299 char a_video[1024]; /* Attributes for video */ 07300 char a_modem[1024]; /* Attributes for t38 */ 07301 char *m_audio_next = m_audio; 07302 char *m_video_next = m_video; 07303 char *m_modem_next = m_modem; 07304 size_t m_audio_left = sizeof(m_audio); 07305 size_t m_video_left = sizeof(m_video); 07306 size_t m_modem_left = sizeof(m_modem); 07307 char *a_audio_next = a_audio; 07308 char *a_video_next = a_video; 07309 char *a_modem_next = a_modem; 07310 size_t a_audio_left = sizeof(a_audio); 07311 size_t a_video_left = sizeof(a_video); 07312 size_t a_modem_left = sizeof(a_modem); 07313 char dummy_answer[256]; 07314 07315 int x; 07316 int capability = 0; 07317 int needvideo = FALSE; 07318 int debug = sip_debug_test_pvt(p); 07319 int min_audio_packet_size = 0; 07320 int min_video_packet_size = 0; 07321 07322 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 07323 m_modem[0] = '\0'; 07324 07325 if (!p->rtp) { 07326 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 07327 return AST_FAILURE; 07328 } 07329 07330 /* Set RTP Session ID and version */ 07331 if (!p->sessionid) { 07332 p->sessionid = getpid(); 07333 p->sessionversion = p->sessionid; 07334 } else 07335 p->sessionversion++; 07336 07337 /* Get our addresses */ 07338 ast_rtp_get_us(p->rtp, &sin); 07339 if (p->vrtp) 07340 ast_rtp_get_us(p->vrtp, &vsin); 07341 07342 /* Is this a re-invite to move the media out, then use the original offer from caller */ 07343 if (p->redirip.sin_addr.s_addr) { 07344 dest.sin_port = p->redirip.sin_port; 07345 dest.sin_addr = p->redirip.sin_addr; 07346 doing_directmedia = p->redircodecs ? TRUE : FALSE; 07347 } else { 07348 dest.sin_addr = p->ourip; 07349 dest.sin_port = sin.sin_port; 07350 } 07351 07352 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 07353 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 07354 07355 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 07356 hold = "a=recvonly\r\n"; 07357 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 07358 hold = "a=inactive\r\n"; 07359 else 07360 hold = "a=sendrecv\r\n"; 07361 07362 if (add_audio) { 07363 char codecbuf[SIPBUFSIZE]; 07364 capability = p->jointcapability; 07365 07366 if (option_debug > 1) { 07367 ast_log(LOG_DEBUG, "** Our capability: %s Video flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability), ast_test_flag(&p->flags[0], SIP_NOVIDEO) ? "True" : "False"); 07368 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 07369 } 07370 07371 if (doing_directmedia) { 07372 capability &= p->redircodecs; 07373 if (option_debug > 1) { 07374 ast_log(LOG_NOTICE, "** Our native-bridge filtered capablity: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability)); 07375 } 07376 } 07377 07378 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 07379 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 07380 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 07381 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 07382 } 07383 #endif 07384 07385 /* Check if we need video in this call */ 07386 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 07387 if (p->vrtp) { 07388 needvideo = TRUE; 07389 if (option_debug > 1) 07390 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 07391 } else if (option_debug > 1) 07392 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 07393 } 07394 07395 07396 /* Ok, we need video. Let's add what we need for video and set codecs. 07397 Video is handled differently than audio since we can not transcode. */ 07398 if (needvideo) { 07399 /* Determine video destination */ 07400 if (p->vredirip.sin_addr.s_addr) { 07401 vdest.sin_addr = p->vredirip.sin_addr; 07402 vdest.sin_port = p->vredirip.sin_port; 07403 } else { 07404 vdest.sin_addr = p->ourip; 07405 vdest.sin_port = vsin.sin_port; 07406 } 07407 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vsin.sin_port)); 07408 07409 /* Build max bitrate string */ 07410 if (p->maxcallbitrate) 07411 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 07412 if (debug) 07413 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 07414 } 07415 07416 if (debug) 07417 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 07418 07419 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 07420 07421 /* Now, start adding audio codecs. These are added in this order: 07422 - First what was requested by the calling channel 07423 - Then preferences in order from sip.conf device config for this peer/user 07424 - Then other codecs in capabilities, including video 07425 */ 07426 07427 /* Prefer the audio codec we were requested to use, first, no matter what 07428 Note that p->prefcodec can include video codecs, so mask them out 07429 */ 07430 if (capability & p->prefcodec) { 07431 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 07432 07433 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 07434 &m_audio_next, &m_audio_left, 07435 &a_audio_next, &a_audio_left, 07436 debug, &min_audio_packet_size); 07437 alreadysent |= codec; 07438 } 07439 07440 /* Start by sending our preferred audio codecs */ 07441 for (x = 0; x < 32; x++) { 07442 int codec; 07443 07444 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 07445 break; 07446 07447 if (!(capability & codec)) 07448 continue; 07449 07450 if (alreadysent & codec) 07451 continue; 07452 07453 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 07454 &m_audio_next, &m_audio_left, 07455 &a_audio_next, &a_audio_left, 07456 debug, &min_audio_packet_size); 07457 alreadysent |= codec; 07458 } 07459 07460 /* Now send any other common audio and video codecs, and non-codec formats: */ 07461 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 07462 if (!(capability & x)) /* Codec not requested */ 07463 continue; 07464 07465 if (alreadysent & x) /* Already added to SDP */ 07466 continue; 07467 07468 if (x <= AST_FORMAT_MAX_AUDIO) 07469 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 07470 &m_audio_next, &m_audio_left, 07471 &a_audio_next, &a_audio_left, 07472 debug, &min_audio_packet_size); 07473 else 07474 add_codec_to_sdp(p, x, 90000, 07475 &m_video_next, &m_video_left, 07476 &a_video_next, &a_video_left, 07477 debug, &min_video_packet_size); 07478 } 07479 07480 /* Now add DTMF RFC2833 telephony-event as a codec */ 07481 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 07482 if (!(p->jointnoncodeccapability & x)) 07483 continue; 07484 07485 add_noncodec_to_sdp(p, x, 8000, 07486 &m_audio_next, &m_audio_left, 07487 &a_audio_next, &a_audio_left, 07488 debug); 07489 } 07490 07491 if (option_debug > 2) 07492 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 07493 07494 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 07495 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 07496 07497 if (min_audio_packet_size) 07498 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 07499 07500 if (min_video_packet_size) 07501 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 07502 07503 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 07504 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 07505 07506 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 07507 if (needvideo) 07508 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 07509 } 07510 07511 if (add_t38 && p->udptl) { 07512 struct sockaddr_in udptlsin; 07513 struct sockaddr_in udptldest = { 0, }; 07514 07515 ast_udptl_get_us(p->udptl, &udptlsin); 07516 07517 if (p->udptlredirip.sin_addr.s_addr) { 07518 udptldest.sin_port = p->udptlredirip.sin_port; 07519 udptldest.sin_addr = p->udptlredirip.sin_addr; 07520 } else { 07521 udptldest.sin_addr = p->ourip; 07522 udptldest.sin_port = udptlsin.sin_port; 07523 } 07524 07525 if (debug) { 07526 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 07527 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 07528 p->t38.capability, 07529 p->t38.peercapability, 07530 p->t38.jointcapability); 07531 } 07532 07533 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 07534 07535 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 07536 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 07537 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 07538 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 07539 if ((x = t38_get_rate(p->t38.jointcapability))) 07540 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 07541 if ((p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) == T38FAX_FILL_BIT_REMOVAL) 07542 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval\r\n"); 07543 if ((p->t38.jointcapability & T38FAX_TRANSCODING_MMR) == T38FAX_TRANSCODING_MMR) 07544 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR\r\n"); 07545 if ((p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) == T38FAX_TRANSCODING_JBIG) 07546 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG\r\n"); 07547 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 07548 x = ast_udptl_get_local_max_datagram(p->udptl); 07549 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 07550 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 07551 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 07552 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 07553 } 07554 07555 add_header(resp, "Content-Type", "application/sdp"); 07556 add_content(resp, version); 07557 add_content(resp, owner); 07558 add_content(resp, subject); 07559 add_content(resp, connection); 07560 if (needvideo) /* only if video response is appropriate */ 07561 add_content(resp, bandwidth); 07562 add_content(resp, stime); 07563 if (add_audio) { 07564 add_content(resp, m_audio); 07565 add_content(resp, a_audio); 07566 add_content(resp, hold); 07567 } else if (p->offered_media[SDP_AUDIO].offered) { 07568 snprintf(dummy_answer, sizeof(dummy_answer), "m=audio 0 RTP/AVP %s\r\n", p->offered_media[SDP_AUDIO].text); 07569 add_content(resp, dummy_answer); 07570 } 07571 if (needvideo) { /* only if video response is appropriate */ 07572 add_content(resp, m_video); 07573 add_content(resp, a_video); 07574 add_content(resp, hold); /* Repeat hold for the video stream */ 07575 } else if (p->offered_media[SDP_VIDEO].offered) { 07576 snprintf(dummy_answer, sizeof(dummy_answer), "m=video 0 RTP/AVP %s\r\n", p->offered_media[SDP_VIDEO].text); 07577 add_content(resp, dummy_answer); 07578 } 07579 if (add_t38) { 07580 add_content(resp, m_modem); 07581 add_content(resp, a_modem); 07582 } else if (p->offered_media[SDP_IMAGE].offered) { 07583 add_content(resp, "m=image 0 udptl t38\r\n"); 07584 } 07585 07586 /* Update lastrtprx when we send our SDP */ 07587 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 07588 07589 if (option_debug > 2) { 07590 char buf[SIPBUFSIZE]; 07591 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 07592 } 07593 07594 return AST_SUCCESS; 07595 }
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 18349 of file chan_sip.c.
References ast_calloc, ast_copy_string(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), domain::context, domain::domain, LOG_DEBUG, LOG_WARNING, domain::mode, and sipdebug.
Referenced by reload_config().
18350 { 18351 struct domain *d; 18352 18353 if (ast_strlen_zero(domain)) { 18354 ast_log(LOG_WARNING, "Zero length domain.\n"); 18355 return 1; 18356 } 18357 18358 if (!(d = ast_calloc(1, sizeof(*d)))) 18359 return 0; 18360 18361 ast_copy_string(d->domain, domain, sizeof(d->domain)); 18362 18363 if (!ast_strlen_zero(context)) 18364 ast_copy_string(d->context, context, sizeof(d->context)); 18365 18366 d->mode = mode; 18367 18368 AST_LIST_LOCK(&domain_list); 18369 AST_LIST_INSERT_TAIL(&domain_list, d, list); 18370 AST_LIST_UNLOCK(&domain_list); 18371 18372 if (sipdebug) 18373 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 18374 18375 return 1; 18376 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 7130 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_message_with_text().
07131 { 07132 /* XXX Convert \n's to \r\n's XXX */ 07133 add_header(req, "Content-Type", "text/plain"); 07134 add_content(req, text); 07135 return 0; 07136 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 7152 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_info_with_vidupdate().
07153 { 07154 const char *xml_is_a_huge_waste_of_space = 07155 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 07156 " <media_control>\r\n" 07157 " <vc_primitive>\r\n" 07158 " <to_encoder>\r\n" 07159 " <picture_fast_update>\r\n" 07160 " </picture_fast_update>\r\n" 07161 " </to_encoder>\r\n" 07162 " </vc_primitive>\r\n" 07163 " </media_control>\r\n"; 07164 add_header(req, "Content-Type", "application/media_control+xml"); 07165 add_content(req, xml_is_a_huge_waste_of_space); 07166 return 0; 07167 }
static int addr_is_multicast | ( | struct in_addr * | addr | ) | [static] |
Check if an ip is an multicast IP. addr the address to check.
This function checks if an address is in the 224.0.0.0/4 network block.
Definition at line 5132 of file chan_sip.c.
Referenced by process_via().
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 7067 of file chan_sip.c.
References add_header(), and t.
Referenced by transmit_invite(), transmit_response_with_date(), and transmit_response_with_unsupported().
07068 { 07069 char tmpdat[256]; 07070 struct tm tm; 07071 time_t t = time(NULL); 07072 07073 gmtime_r(&t, &tm); 07074 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 07075 add_header(req, "Date", tmpdat); 07076 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1995 of file chan_sip.c.
References append_history_va(), ast_test_flag, sip_pvt::flags, and SIP_NO_HISTORY.
01996 { 01997 va_list ap; 01998 01999 if (!p) 02000 return; 02001 02002 if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 02003 && !recordhistory && !dumphistory) { 02004 return; 02005 } 02006 02007 va_start(ap, fmt); 02008 append_history_va(p, fmt, ap); 02009 va_end(ap); 02010 02011 return; 02012 }
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 1968 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, sip_history::event, free, MAX_HISTORY_ENTRIES, and strsep().
Referenced by append_history_full().
01969 { 01970 char buf[80], *c = buf; /* max history length */ 01971 struct sip_history *hist; 01972 int l; 01973 01974 vsnprintf(buf, sizeof(buf), fmt, ap); 01975 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01976 l = strlen(buf) + 1; 01977 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01978 return; 01979 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01980 free(hist); 01981 return; 01982 } 01983 memcpy(hist->event, buf, l); 01984 if (p->history_entries == MAX_HISTORY_ENTRIES) { 01985 struct sip_history *oldest; 01986 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 01987 p->history_entries--; 01988 free(oldest); 01989 } 01990 AST_LIST_INSERT_TAIL(p->history, hist, list); 01991 p->history_entries++; 01992 }
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 14753 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 ast_channel::generatordata.
Referenced by attempt_transfer(), and handle_invite_replaces().
14754 { 14755 if (chan && chan->_state == AST_STATE_UP) { 14756 if (ast_test_flag(chan, AST_FLAG_MOH)) 14757 ast_moh_stop(chan); 14758 else if (chan->generatordata) 14759 ast_deactivate_generator(chan); 14760 } 14761 }
static enum sip_result ast_sip_ouraddrfor | ( | struct in_addr * | them, | |
struct in_addr * | us | |||
) | [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
Definition at line 1928 of file chan_sip.c.
References ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), AST_SUCCESS, bindaddr, externexpire, externhost, externip, externrefresh, hp, localaddr, LOG_DEBUG, LOG_NOTICE, and option_debug.
Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_register(), and transmit_response_using_temp().
01929 { 01930 struct sockaddr_in theirs, ours; 01931 01932 /* Get our local information */ 01933 ast_ouraddrfor(them, us); 01934 theirs.sin_addr = *them; 01935 ours.sin_addr = *us; 01936 01937 if (localaddr && externip.sin_addr.s_addr && 01938 (ast_apply_ha(localaddr, &theirs)) && 01939 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01940 if (externexpire && time(NULL) >= externexpire) { 01941 struct ast_hostent ahp; 01942 struct hostent *hp; 01943 01944 externexpire = time(NULL) + externrefresh; 01945 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01946 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01947 } else 01948 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01949 } 01950 *us = externip.sin_addr; 01951 if (option_debug) { 01952 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01953 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01954 } 01955 } else if (bindaddr.sin_addr.s_addr) 01956 *us = bindaddr.sin_addr; 01957 return AST_SUCCESS; 01958 }
Attempt transfer of SIP call This fix for attended transfers on a local PBX.
Definition at line 14765 of file chan_sip.c.
References ast_channel::_state, ast_channel_masquerade(), ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_state2str(), sip_dual::chan1, sip_dual::chan2, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, and option_debug.
Referenced by local_attended_transfer().
14766 { 14767 int res = 0; 14768 struct ast_channel *peera = NULL, 14769 *peerb = NULL, 14770 *peerc = NULL, 14771 *peerd = NULL; 14772 14773 14774 /* We will try to connect the transferee with the target and hangup 14775 all channels to the transferer */ 14776 if (option_debug > 3) { 14777 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 14778 if (transferer->chan1) 14779 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 14780 else 14781 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 14782 if (target->chan1) 14783 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 14784 else 14785 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 14786 if (transferer->chan2) 14787 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 14788 else 14789 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 14790 if (target->chan2) 14791 ast_log(LOG_DEBUG, "-- Bridged call to transfer target: %s State %s\n", target->chan2 ? target->chan2->name : "<none>", target->chan2 ? ast_state2str(target->chan2->_state) : "(none)"); 14792 else 14793 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 14794 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 14795 } 14796 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 14797 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 14798 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 14799 peerc = transferer->chan2; /* Asterisk to Transferee */ 14800 peerd = target->chan2; /* Asterisk to Target */ 14801 if (option_debug > 2) 14802 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 14803 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 14804 peera = target->chan1; /* Transferer to PBX -> target channel */ 14805 peerb = transferer->chan1; /* Transferer to IVR*/ 14806 peerc = target->chan2; /* Asterisk to Target */ 14807 peerd = transferer->chan2; /* Nothing */ 14808 if (option_debug > 2) 14809 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 14810 } 14811 14812 if (peera && peerb && peerc && (peerb != peerc)) { 14813 ast_quiet_chan(peera); /* Stop generators */ 14814 ast_quiet_chan(peerb); 14815 ast_quiet_chan(peerc); 14816 if (peerd) 14817 ast_quiet_chan(peerd); 14818 14819 if (option_debug > 3) 14820 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 14821 if (ast_channel_masquerade(peerb, peerc)) { 14822 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 14823 res = -1; 14824 } else 14825 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 14826 return res; 14827 } else { 14828 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 14829 if (transferer->chan1) 14830 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 14831 if (target->chan1) 14832 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 14833 return -2; 14834 } 14835 return 0; 14836 }
static int auto_congest | ( | const void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 3255 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_CONGESTION, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_control(), DEFAULT_TRANS_TIMEOUT, sip_pvt::initid, sip_pvt::lock, LOG_NOTICE, sip_pvt::owner, and sip_scheddestroy().
Referenced by sip_call().
03256 { 03257 struct sip_pvt *p = (struct sip_pvt *)nothing; 03258 03259 ast_mutex_lock(&p->lock); 03260 p->initid = -1; 03261 if (p->owner) { 03262 /* XXX fails on possible deadlock */ 03263 if (!ast_channel_trylock(p->owner)) { 03264 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 03265 append_history(p, "Cong", "Auto-congesting (timer)"); 03266 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 03267 ast_channel_unlock(p->owner); 03268 } 03269 03270 /* Give the channel a chance to act before we proceed with destruction */ 03271 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03272 } 03273 ast_mutex_unlock(&p->lock); 03274 return 0; 03275 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4843 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, 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().
04844 { 04845 char buf[33]; 04846 04847 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04848 04849 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04850 04851 }
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 4854 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, sip_pvt::callid, generate_random_string(), and S_OR.
Referenced by transmit_register().
04855 { 04856 char buf[33]; 04857 04858 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04859 04860 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04861 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 7772 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), ast_uri_encode(), sip_pvt::exten, sip_pvt::ourip, ourport, SIPBUFSIZE, and STANDARD_SIP_PORT.
Referenced by check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().
07773 { 07774 char tmp[SIPBUFSIZE]; 07775 char *user; 07776 07777 user = ast_uri_encode(p->exten, tmp, sizeof(tmp), 1); 07778 07779 /* Construct Contact: header */ 07780 if (ourport != STANDARD_SIP_PORT) 07781 ast_string_field_build(p, our_contact, "<sip:%s%s%s:%d>", user, ast_strlen_zero(user) ? "" : "@", ast_inet_ntoa(p->ourip), ourport); 07782 else 07783 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", user, ast_strlen_zero(user) ? "" : "@", ast_inet_ntoa(p->ourip)); 07784 }
static struct sip_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime, | |||
int | devstate_only | |||
) | [static, read] |
Build peer from configuration (file or realtime static/dynamic).
Definition at line 18681 of file chan_sip.c.
References __set_address_from_contact(), sip_peer::accountcode, add_realm_authentication(), sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_copy_string(), ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), ast_get_time_t(), ast_inet_ntoa(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), AST_SCHED_DEL, ast_set2_flag, ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_FLAG_MARKED, ASTOBJ_INIT, ASTOBJ_REF, ASTOBJ_UNMARK, ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, 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, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastms, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, LOG_ERROR, LOG_WARNING, sip_peer::mailbox, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, sip_peer::name, ast_variable::next, sip_peer::objflags, option_debug, peerl, sip_peer::pickupgroup, sip_peer::portinuri, sip_peer::prefs, reg_source_db(), sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, set_peer_defaults(), sip_destroy_peer(), SIP_NAT_ROUTE, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_SUBSCRIBEMWIONLY, sip_poke_peer(), SIP_REALTIME, SIP_USEREQPHONE, STANDARD_SIP_PORT, sip_peer::subscribecontext, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::useragent, sip_peer::username, ast_variable::value, and sip_peer::vmexten.
Referenced by realtime_peer(), and reload_config().
18682 { 18683 struct sip_peer *peer = NULL; 18684 struct ast_ha *oldha = NULL; 18685 int obproxyfound=0; 18686 int found=0; 18687 int firstpass=1; 18688 int format=0; /* Ama flags */ 18689 time_t regseconds = 0; 18690 char *varname = NULL, *varval = NULL; 18691 struct ast_variable *tmpvar = NULL; 18692 struct ast_flags peerflags[2] = {{(0)}}; 18693 struct ast_flags mask[2] = {{(0)}}; 18694 int alt_fullcontact = alt ? 1 : 0; 18695 char fullcontact[sizeof(peer->fullcontact)] = ""; 18696 18697 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 18698 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 18699 /* We also use a case-sensitive comparison (unlike find_peer) so 18700 that case changes made to the peer name will be properly handled 18701 during reload 18702 */ 18703 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 18704 18705 if (peer) { 18706 /* Already in the list, remove it and it will be added back (or FREE'd) */ 18707 found = 1; 18708 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 18709 firstpass = 0; 18710 } else { 18711 if (!(peer = ast_calloc(1, sizeof(*peer)))) 18712 return NULL; 18713 18714 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 18715 rpeerobjs++; 18716 else 18717 speerobjs++; 18718 ASTOBJ_INIT(peer); 18719 } 18720 /* Note that our peer HAS had its reference count incrased */ 18721 if (firstpass) { 18722 peer->lastmsgssent = -1; 18723 oldha = peer->ha; 18724 peer->ha = NULL; 18725 set_peer_defaults(peer); /* Set peer defaults */ 18726 } 18727 if (!found && name) 18728 ast_copy_string(peer->name, name, sizeof(peer->name)); 18729 18730 /* If we have channel variables, remove them (reload) */ 18731 if (peer->chanvars) { 18732 ast_variables_destroy(peer->chanvars); 18733 peer->chanvars = NULL; 18734 /* XXX should unregister ? */ 18735 } 18736 18737 if (found) 18738 peer->portinuri = 0; 18739 18740 /* If we have realm authentication information, remove them (reload) */ 18741 clear_realm_authentication(peer->auth); 18742 peer->auth = NULL; 18743 18744 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 18745 if (!devstate_only) { 18746 if (handle_common_options(&peerflags[0], &mask[0], v)) { 18747 continue; 18748 } 18749 if (realtime && !strcasecmp(v->name, "regseconds")) { 18750 ast_get_time_t(v->value, ®seconds, 0, NULL); 18751 } else if (realtime && !strcasecmp(v->name, "name")) { 18752 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 18753 } else if (realtime && !strcasecmp(v->name, "useragent")) { 18754 ast_copy_string(peer->useragent, v->value, sizeof(peer->useragent)); 18755 } else if (realtime && !strcasecmp(v->name, "fullcontact")) { 18756 if (alt_fullcontact && !alt) { 18757 /* Reset, because the alternate also has a fullcontact and we 18758 * do NOT want the field value to be doubled. It might be 18759 * tempting to skip this, but the first table might not have 18760 * fullcontact and since we're here, we know that the alternate 18761 * absolutely does. */ 18762 alt_fullcontact = 0; 18763 fullcontact[0] = '\0'; 18764 } 18765 /* Reconstruct field, because realtime separates our value at the ';' */ 18766 if (!ast_strlen_zero(fullcontact)) { 18767 strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1); 18768 strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1); 18769 } else { 18770 ast_copy_string(fullcontact, v->value, sizeof(fullcontact)); 18771 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 18772 } 18773 } else if (!strcasecmp(v->name, "secret")) { 18774 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 18775 } else if (!strcasecmp(v->name, "md5secret")) { 18776 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 18777 } else if (!strcasecmp(v->name, "auth")) { 18778 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 18779 } else if (!strcasecmp(v->name, "callerid")) { 18780 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 18781 } else if (!strcasecmp(v->name, "fullname")) { 18782 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 18783 } else if (!strcasecmp(v->name, "trunkname")) { 18784 /* This is actually for a trunk, so we don't want to override callerid */ 18785 ast_copy_string(peer->cid_name, "", sizeof(peer->cid_name)); 18786 } else if (!strcasecmp(v->name, "cid_number")) { 18787 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 18788 } else if (!strcasecmp(v->name, "context")) { 18789 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 18790 } else if (!strcasecmp(v->name, "subscribecontext")) { 18791 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 18792 } else if (!strcasecmp(v->name, "fromdomain")) { 18793 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 18794 } else if (!strcasecmp(v->name, "usereqphone")) { 18795 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 18796 } else if (!strcasecmp(v->name, "fromuser")) { 18797 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 18798 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 18799 if (!strcasecmp(v->value, "dynamic")) { 18800 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 18801 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 18802 } else { 18803 /* They'll register with us */ 18804 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 18805 /* Initialize stuff if this is a new peer, or if it used to be 18806 * non-dynamic before the reload. */ 18807 memset(&peer->addr.sin_addr, 0, 4); 18808 if (peer->addr.sin_port) { 18809 /* If we've already got a port, make it the default rather than absolute */ 18810 peer->defaddr.sin_port = peer->addr.sin_port; 18811 peer->addr.sin_port = 0; 18812 } 18813 } 18814 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 18815 } 18816 } else { 18817 /* Non-dynamic. Make sure we become that way if we're not */ 18818 if (!AST_SCHED_DEL(sched, peer->expire)) { 18819 struct sip_peer *peer_ptr = peer; 18820 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 18821 } 18822 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 18823 if (!strcasecmp(v->name, "outboundproxy")) { 18824 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 18825 ast_log(LOG_ERROR, "srvlookup failed for outboundproxy: %s, on peer %s, removing peer\n", v->value, peer->name); 18826 ASTOBJ_UNREF(peer, sip_destroy_peer); 18827 return NULL; 18828 } 18829 } 18830 if (!strcasecmp(v->name, "outboundproxy")) 18831 obproxyfound=1; 18832 else { 18833 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 18834 if (!peer->addr.sin_port) 18835 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 18836 } 18837 if (global_dynamic_exclude_static) { 18838 global_contact_ha = ast_append_ha("deny", (char *)ast_inet_ntoa(peer->addr.sin_addr), global_contact_ha); 18839 } 18840 } 18841 } else if (!strcasecmp(v->name, "defaultip")) { 18842 if (!ast_strlen_zero(v->value) && ast_get_ip(&peer->defaddr, v->value)) { 18843 ASTOBJ_UNREF(peer, sip_destroy_peer); 18844 return NULL; 18845 } 18846 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 18847 if (!ast_strlen_zero(v->value)) { 18848 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 18849 } 18850 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 18851 if (!ast_strlen_zero(v->value)) { 18852 peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha); 18853 } 18854 } else if (!strcasecmp(v->name, "port")) { 18855 peer->portinuri = 1; 18856 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 18857 peer->defaddr.sin_port = htons(atoi(v->value)); 18858 else 18859 peer->addr.sin_port = htons(atoi(v->value)); 18860 } else if (!strcasecmp(v->name, "callingpres")) { 18861 peer->callingpres = ast_parse_caller_presentation(v->value); 18862 if (peer->callingpres == -1) 18863 peer->callingpres = atoi(v->value); 18864 } else if (!strcasecmp(v->name, "username")) { 18865 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 18866 } else if (!strcasecmp(v->name, "language")) { 18867 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 18868 } else if (!strcasecmp(v->name, "regexten")) { 18869 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 18870 } else if (!strcasecmp(v->name, "amaflags")) { 18871 format = ast_cdr_amaflags2int(v->value); 18872 if (format < 0) { 18873 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 18874 } else { 18875 peer->amaflags = format; 18876 } 18877 } else if (!strcasecmp(v->name, "accountcode")) { 18878 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 18879 } else if (!strcasecmp(v->name, "mohinterpret") 18880 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 18881 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 18882 } else if (!strcasecmp(v->name, "mohsuggest")) { 18883 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 18884 } else if (!strcasecmp(v->name, "mailbox")) { 18885 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 18886 } else if (!strcasecmp(v->name, "hasvoicemail")) { 18887 /* People expect that if 'hasvoicemail' is set, that the mailbox will 18888 * be also set, even if not explicitly specified. */ 18889 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 18890 ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox)); 18891 } 18892 } else if (!strcasecmp(v->name, "subscribemwi")) { 18893 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 18894 } else if (!strcasecmp(v->name, "vmexten")) { 18895 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 18896 } else if (!strcasecmp(v->name, "callgroup")) { 18897 ast_get_group(&peer->callgroup, v->value); 18898 } else if (!strcasecmp(v->name, "allowtransfer")) { 18899 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 18900 } else if (!strcasecmp(v->name, "pickupgroup")) { 18901 ast_get_group(&peer->pickupgroup, v->value); 18902 } else if (!strcasecmp(v->name, "allow")) { 18903 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 18904 } else if (!strcasecmp(v->name, "disallow")) { 18905 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 18906 } else if (!strcasecmp(v->name, "autoframing")) { 18907 peer->autoframing = ast_true(v->value); 18908 } else if (!strcasecmp(v->name, "rtptimeout")) { 18909 if ((sscanf(v->value, "%30d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 18910 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 18911 peer->rtptimeout = global_rtptimeout; 18912 } 18913 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 18914 if ((sscanf(v->value, "%30d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 18915 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 18916 peer->rtpholdtimeout = global_rtpholdtimeout; 18917 } 18918 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 18919 if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 18920 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 18921 peer->rtpkeepalive = global_rtpkeepalive; 18922 } 18923 } else if (!strcasecmp(v->name, "setvar")) { 18924 /* Set peer channel variable */ 18925 varname = ast_strdupa(v->value); 18926 if ((varval = strchr(varname, '='))) { 18927 *varval++ = '\0'; 18928 if ((tmpvar = ast_variable_new(varname, varval))) { 18929 tmpvar->next = peer->chanvars; 18930 peer->chanvars = tmpvar; 18931 } 18932 } 18933 } 18934 } 18935 18936 /* These apply to devstate lookups */ 18937 if (realtime && !strcasecmp(v->name, "lastms")) { 18938 sscanf(v->value, "%30d", &peer->lastms); 18939 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 18940 inet_aton(v->value, &(peer->addr.sin_addr)); 18941 } else if (!strcasecmp(v->name, "qualify")) { 18942 if (!strcasecmp(v->value, "no")) { 18943 peer->maxms = 0; 18944 } else if (!strcasecmp(v->value, "yes")) { 18945 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 18946 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 18947 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); 18948 peer->maxms = 0; 18949 } 18950 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) { 18951 /* This would otherwise cause a network storm, where the 18952 * qualify response refreshes the peer from the database, 18953 * which in turn causes another qualify to be sent, ad 18954 * infinitum. */ 18955 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); 18956 peer->maxms = 0; 18957 } 18958 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 18959 peer->call_limit = atoi(v->value); 18960 if (peer->call_limit < 0) { 18961 peer->call_limit = 0; 18962 } 18963 } 18964 } 18965 18966 if (!ast_strlen_zero(fullcontact)) { 18967 ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact)); 18968 /* We have a hostname in the fullcontact, but if we don't have an 18969 * address listed on the entry (or if it's 'dynamic'), then we need to 18970 * parse the entry to obtain the IP address, so a dynamic host can be 18971 * contacted immediately after reload (as opposed to waiting for it to 18972 * register once again). But if we have an address for this peer and NAT was 18973 * specified, use that address instead. */ 18974 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE) || !peer->addr.sin_addr.s_addr) { 18975 __set_address_from_contact(fullcontact, &peer->addr); 18976 } 18977 } 18978 18979 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !obproxyfound && !ast_strlen_zero(peer->tohost)) { 18980 if (ast_get_ip_or_srv(&peer->addr, peer->tohost, srvlookup && !peer->portinuri ? "_sip._udp" : NULL)) { 18981 ast_log(LOG_ERROR, "host lookup failed for %s, on peer %s, removing peer\n", peer->tohost, peer->name); 18982 ASTOBJ_UNREF(peer, sip_destroy_peer); 18983 return NULL; 18984 } 18985 } 18986 18987 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 18988 time_t nowtime = time(NULL); 18989 18990 if ((nowtime - regseconds) > 0) { 18991 destroy_association(peer); 18992 memset(&peer->addr, 0, sizeof(peer->addr)); 18993 peer->lastms = -1; 18994 if (option_debug) 18995 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 18996 } 18997 } 18998 18999 /* Startup regular pokes */ 19000 if (realtime && peer->lastms > 0) { 19001 ASTOBJ_REF(peer); 19002 sip_poke_peer(peer); 19003 } 19004 19005 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 19006 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 19007 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 19008 global_allowsubscribe = TRUE; /* No global ban any more */ 19009 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 19010 reg_source_db(peer); 19011 ASTOBJ_UNMARK(peer); 19012 ast_free_ha(oldha); 19013 return peer; 19014 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 12971 of file chan_sip.c.
References append_history, ast_copy_string(), 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_registry::md5secret, sip_pvt::nonce, sip_pvt::noncecount, sip_pvt::opaque, sip_registry::opaque, option_debug, sip_pvt::peerauth, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_pvt::qop, sip_pvt::realm, sip_pvt::sa, sip_auth::secret, secret, sip_methods, sipdebug, text, sip_pvt::uri, sip_auth::username, sip_pvt::username, and username.
Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().
12972 { 12973 char a1[256]; 12974 char a2[256]; 12975 char a1_hash[256]; 12976 char a2_hash[256]; 12977 char resp[256]; 12978 char resp_hash[256]; 12979 char uri[256]; 12980 char opaque[256] = ""; 12981 char cnonce[80]; 12982 const char *username; 12983 const char *secret; 12984 const char *md5secret; 12985 struct sip_auth *auth = NULL; /* Realm authentication */ 12986 12987 if (!ast_strlen_zero(p->domain)) 12988 ast_copy_string(uri, p->domain, sizeof(uri)); 12989 else if (!ast_strlen_zero(p->uri)) 12990 ast_copy_string(uri, p->uri, sizeof(uri)); 12991 else 12992 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 12993 12994 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 12995 12996 /* Check if we have separate auth credentials */ 12997 if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */ 12998 auth = find_realm_authentication(authl, p->realm); /* If not, global list */ 12999 13000 if (auth) { 13001 if (sipdebug && option_debug > 1) 13002 ast_log(LOG_DEBUG, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username); 13003 username = auth->username; 13004 secret = auth->secret; 13005 md5secret = auth->md5secret; 13006 if (sipdebug) 13007 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 13008 } else { 13009 /* No authentication, use peer or register= config */ 13010 username = p->authname; 13011 secret = p->peersecret; 13012 md5secret = p->peermd5secret; 13013 } 13014 if (ast_strlen_zero(username)) /* We have no authentication */ 13015 return -1; 13016 13017 /* Calculate SIP digest response */ 13018 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 13019 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 13020 if (!ast_strlen_zero(md5secret)) 13021 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 13022 else 13023 ast_md5_hash(a1_hash,a1); 13024 ast_md5_hash(a2_hash,a2); 13025 13026 p->noncecount++; 13027 if (!ast_strlen_zero(p->qop)) 13028 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 13029 else 13030 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 13031 ast_md5_hash(resp_hash, resp); 13032 13033 /* only include the opaque string if it's set */ 13034 if (!ast_strlen_zero(p->opaque)) { 13035 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 13036 } 13037 13038 /* XXX We hard code our qop to "auth" for now. XXX */ 13039 if (!ast_strlen_zero(p->qop)) 13040 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); 13041 else 13042 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); 13043 13044 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 13045 13046 return 0; 13047 }
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 9279 of file chan_sip.c.
References __get_header(), ast_copy_string(), ast_log(), ast_malloc, ast_strlen_zero(), free_old_route(), get_header(), sip_route::hop, sip_request::len, list_route(), LOG_DEBUG, sip_route::next, option_debug, sip_pvt::route, sip_pvt::route_persistant, and sip_debug_test_pvt().
Referenced by handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
09280 { 09281 struct sip_route *thishop, *head, *tail; 09282 int start = 0; 09283 int len; 09284 const char *rr, *contact, *c; 09285 09286 /* Once a persistant route is set, don't fool with it */ 09287 if (p->route && p->route_persistant) { 09288 if (option_debug) 09289 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 09290 return; 09291 } 09292 09293 if (p->route) { 09294 free_old_route(p->route); 09295 p->route = NULL; 09296 } 09297 09298 /* We only want to create the route set the first time this is called */ 09299 p->route_persistant = 1; 09300 09301 /* Build a tailq, then assign it to p->route when done. 09302 * If backwards, we add entries from the head so they end up 09303 * in reverse order. However, we do need to maintain a correct 09304 * tail pointer because the contact is always at the end. 09305 */ 09306 head = NULL; 09307 tail = head; 09308 /* 1st we pass through all the hops in any Record-Route headers */ 09309 for (;;) { 09310 /* Each Record-Route header */ 09311 rr = __get_header(req, "Record-Route", &start); 09312 if (*rr == '\0') 09313 break; 09314 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 09315 ++rr; 09316 len = strcspn(rr, ">") + 1; 09317 /* Make a struct route */ 09318 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 09319 /* ast_calloc is not needed because all fields are initialized in this block */ 09320 ast_copy_string(thishop->hop, rr, len); 09321 if (option_debug > 1) 09322 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 09323 /* Link in */ 09324 if (backwards) { 09325 /* Link in at head so they end up in reverse order */ 09326 thishop->next = head; 09327 head = thishop; 09328 /* If this was the first then it'll be the tail */ 09329 if (!tail) 09330 tail = thishop; 09331 } else { 09332 thishop->next = NULL; 09333 /* Link in at the end */ 09334 if (tail) 09335 tail->next = thishop; 09336 else 09337 head = thishop; 09338 tail = thishop; 09339 } 09340 } 09341 } 09342 } 09343 09344 /* Only append the contact if we are dealing with a strict router */ 09345 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 09346 /* 2nd append the Contact: if there is one */ 09347 /* Can be multiple Contact headers, comma separated values - we just take the first */ 09348 contact = get_header(req, "Contact"); 09349 if (!ast_strlen_zero(contact)) { 09350 if (option_debug > 1) 09351 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 09352 /* Look for <: delimited address */ 09353 c = strchr(contact, '<'); 09354 if (c) { 09355 /* Take to > */ 09356 ++c; 09357 len = strcspn(c, ">") + 1; 09358 } else { 09359 /* No <> - just take the lot */ 09360 c = contact; 09361 len = strlen(contact) + 1; 09362 } 09363 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 09364 /* ast_calloc is not needed because all fields are initialized in this block */ 09365 ast_copy_string(thishop->hop, c, len); 09366 thishop->next = NULL; 09367 /* Goes at the end */ 09368 if (tail) 09369 tail->next = thishop; 09370 else 09371 head = thishop; 09372 } 09373 } 09374 } 09375 09376 /* Store as new route */ 09377 p->route = head; 09378 09379 /* For debugging dump what we ended up with */ 09380 if (sip_debug_test_pvt(p)) 09381 list_route(p->route); 09382 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 7787 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(), 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().
07788 { 07789 int send_pres_tags = TRUE; 07790 const char *privacy=NULL; 07791 const char *screen=NULL; 07792 char buf[256]; 07793 const char *clid = default_callerid; 07794 const char *clin = NULL; 07795 const char *fromdomain; 07796 07797 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 07798 return; 07799 07800 if (p->owner && !ast_strlen_zero(p->owner->cid.cid_num)) 07801 clid = p->owner->cid.cid_num; 07802 if (p->owner && p->owner->cid.cid_name) 07803 clin = p->owner->cid.cid_name; 07804 if (ast_strlen_zero(clin)) 07805 clin = clid; 07806 07807 switch (p->callingpres) { 07808 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 07809 privacy = "off"; 07810 screen = "no"; 07811 break; 07812 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 07813 privacy = "off"; 07814 screen = "yes"; 07815 break; 07816 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 07817 privacy = "off"; 07818 screen = "no"; 07819 break; 07820 case AST_PRES_ALLOWED_NETWORK_NUMBER: 07821 privacy = "off"; 07822 screen = "yes"; 07823 break; 07824 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 07825 privacy = "full"; 07826 screen = "no"; 07827 break; 07828 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 07829 privacy = "full"; 07830 screen = "yes"; 07831 break; 07832 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 07833 privacy = "full"; 07834 screen = "no"; 07835 break; 07836 case AST_PRES_PROHIB_NETWORK_NUMBER: 07837 privacy = "full"; 07838 screen = "yes"; 07839 break; 07840 case AST_PRES_NUMBER_NOT_AVAILABLE: 07841 send_pres_tags = FALSE; 07842 break; 07843 default: 07844 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 07845 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 07846 privacy = "full"; 07847 else 07848 privacy = "off"; 07849 screen = "no"; 07850 break; 07851 } 07852 07853 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 07854 07855 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 07856 if (send_pres_tags) 07857 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 07858 ast_string_field_set(p, rpid, buf); 07859 07860 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 07861 S_OR(p->fromuser, clid), 07862 fromdomain, p->tag); 07863 }
static struct sip_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static, read] |
Initiate a SIP user structure from configuration (configuration or realtime).
Definition at line 18498 of file chan_sip.c.
References sip_user::accountcode, sip_user::allowtransfer, sip_user::amaflags, 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_strdupa, ast_test_flag, ast_true(), ast_variable_new(), ASTOBJ_INIT, sip_user::autoframing, sip_user::call_limit, sip_user::callgroup, sip_user::callingpres, sip_user::capability, sip_user::chanvars, sip_user::cid_name, sip_user::cid_num, sip_user::context, default_prefs, ast_flags::flags, sip_user::flags, format, sip_user::ha, handle_common_options(), sip_user::language, ast_variable::lineno, LOG_WARNING, sip_user::maxcallbitrate, sip_user::md5secret, sip_user::mohinterpret, sip_user::mohsuggest, ast_variable::name, sip_user::name, ast_variable::next, sip_user::pickupgroup, sip_user::prefs, sip_user::secret, SIP_FLAGS_TO_COPY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_FLAGS_TO_COPY, sip_user::subscribecontext, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, and ast_variable::value.
Referenced by realtime_user(), and reload_config().
18499 { 18500 struct sip_user *user; 18501 int format; 18502 struct ast_ha *oldha = NULL; 18503 char *varname = NULL, *varval = NULL; 18504 struct ast_variable *tmpvar = NULL; 18505 struct ast_flags userflags[2] = {{(0)}}; 18506 struct ast_flags mask[2] = {{(0)}}; 18507 18508 18509 if (!(user = ast_calloc(1, sizeof(*user)))) 18510 return NULL; 18511 18512 suserobjs++; 18513 ASTOBJ_INIT(user); 18514 ast_copy_string(user->name, name, sizeof(user->name)); 18515 oldha = user->ha; 18516 user->ha = NULL; 18517 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 18518 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 18519 user->capability = global_capability; 18520 user->allowtransfer = global_allowtransfer; 18521 user->maxcallbitrate = default_maxcallbitrate; 18522 user->autoframing = global_autoframing; 18523 user->prefs = default_prefs; 18524 /* set default context */ 18525 strcpy(user->context, default_context); 18526 strcpy(user->language, default_language); 18527 strcpy(user->mohinterpret, default_mohinterpret); 18528 strcpy(user->mohsuggest, default_mohsuggest); 18529 /* First we walk through the v parameters list and then the alt parameters list */ 18530 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 18531 if (handle_common_options(&userflags[0], &mask[0], v)) 18532 continue; 18533 18534 if (!strcasecmp(v->name, "context")) { 18535 ast_copy_string(user->context, v->value, sizeof(user->context)); 18536 } else if (!strcasecmp(v->name, "subscribecontext")) { 18537 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 18538 } else if (!strcasecmp(v->name, "setvar")) { 18539 varname = ast_strdupa(v->value); 18540 if ((varval = strchr(varname,'='))) { 18541 *varval++ = '\0'; 18542 if ((tmpvar = ast_variable_new(varname, varval))) { 18543 tmpvar->next = user->chanvars; 18544 user->chanvars = tmpvar; 18545 } 18546 } 18547 } else if (!strcasecmp(v->name, "permit") || 18548 !strcasecmp(v->name, "deny")) { 18549 user->ha = ast_append_ha(v->name, v->value, user->ha); 18550 } else if (!strcasecmp(v->name, "allowtransfer")) { 18551 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 18552 } else if (!strcasecmp(v->name, "secret")) { 18553 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 18554 } else if (!strcasecmp(v->name, "md5secret")) { 18555 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 18556 } else if (!strcasecmp(v->name, "callerid")) { 18557 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 18558 } else if (!strcasecmp(v->name, "fullname")) { 18559 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 18560 } else if (!strcasecmp(v->name, "trunkname")) { 18561 /* This is actually for a trunk, so we don't want to override callerid */ 18562 ast_copy_string(user->cid_name, "", sizeof(user->cid_name)); 18563 } else if (!strcasecmp(v->name, "cid_number")) { 18564 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 18565 } else if (!strcasecmp(v->name, "callgroup")) { 18566 ast_get_group(&user->callgroup, v->value); 18567 } else if (!strcasecmp(v->name, "pickupgroup")) { 18568 ast_get_group(&user->pickupgroup, v->value); 18569 } else if (!strcasecmp(v->name, "language")) { 18570 ast_copy_string(user->language, v->value, sizeof(user->language)); 18571 } else if (!strcasecmp(v->name, "mohinterpret") 18572 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 18573 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 18574 } else if (!strcasecmp(v->name, "mohsuggest")) { 18575 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 18576 } else if (!strcasecmp(v->name, "accountcode")) { 18577 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 18578 } else if (!strcasecmp(v->name, "call-limit")) { 18579 user->call_limit = atoi(v->value); 18580 if (user->call_limit < 0) 18581 user->call_limit = 0; 18582 } else if (!strcasecmp(v->name, "amaflags")) { 18583 format = ast_cdr_amaflags2int(v->value); 18584 if (format < 0) { 18585 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 18586 } else { 18587 user->amaflags = format; 18588 } 18589 } else if (!strcasecmp(v->name, "allow")) { 18590 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 18591 } else if (!strcasecmp(v->name, "disallow")) { 18592 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 18593 } else if (!strcasecmp(v->name, "autoframing")) { 18594 user->autoframing = ast_true(v->value); 18595 } else if (!strcasecmp(v->name, "callingpres")) { 18596 user->callingpres = ast_parse_caller_presentation(v->value); 18597 if (user->callingpres == -1) 18598 user->callingpres = atoi(v->value); 18599 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 18600 user->maxcallbitrate = atoi(v->value); 18601 if (user->maxcallbitrate < 0) 18602 user->maxcallbitrate = default_maxcallbitrate; 18603 } 18604 /* We can't just report unknown options here because this may be a 18605 * type=friend entry. All user options are valid for a peer, but not 18606 * the other way around. */ 18607 } 18608 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 18609 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 18610 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 18611 global_allowsubscribe = TRUE; /* No global ban any more */ 18612 ast_free_ha(oldha); 18613 return user; 18614 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1912 of file chan_sip.c.
References ast_inet_ntoa(), ast_test_flag, sip_pvt::branch, sip_pvt::flags, sip_pvt::ourip, ourport, 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().
01913 { 01914 /* Work around buggy UNIDEN UIP200 firmware */ 01915 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01916 01917 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01918 snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s", 01919 ast_inet_ntoa(p->ourip), ourport, (int) p->branch, rport); 01920 }
static void change_hold_state | ( | struct sip_pvt * | dialog, | |
struct sip_request * | req, | |||
int | holdstate, | |||
int | sendonly | |||
) | [static] |
Change hold state for a call.
Definition at line 5617 of file chan_sip.c.
References append_history, ast_clear_flag, ast_set_flag, ast_test_flag, sip_request::data, EVENT_FLAG_CALL, sip_pvt::flags, manager_event(), sip_pvt::owner, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_ACTIVE, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, and sip_peer_hold().
Referenced by handle_request_invite(), and process_sdp().
05618 { 05619 if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 05620 sip_peer_hold(dialog, holdstate); 05621 if (global_callevents) 05622 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 05623 "Channel: %s\r\n" 05624 "Uniqueid: %s\r\n", 05625 dialog->owner->name, 05626 dialog->owner->uniqueid); 05627 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 05628 if (!holdstate) { /* Put off remote hold */ 05629 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 05630 return; 05631 } 05632 /* No address for RTP, we're on hold */ 05633 05634 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 05635 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 05636 else if (sendonly == 2) /* Inactive stream */ 05637 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 05638 else 05639 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 05640 return; 05641 }
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 9406 of file chan_sip.c.
References append_history, ast_copy_string(), ast_dynamic_str_thread_get(), ast_dynamic_str_thread_set(), AST_DYNSTR_BUILD_FAILED, ast_log(), ast_md5_hash(), ast_skip_blanks(), ast_strlen_zero(), ast_test_flag, AUTH_CHALLENGE_SENT, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, AUTH_USERNAME_MISMATCH, check_auth_buf, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), keys, LOG_NOTICE, LOG_WARNING, sip_pvt::randdata, s, S_OR, set_nonce_randdata(), sip_methods, SIP_PKT_IGNORE, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stalenonce, ast_dynamic_str::str, strsep(), text, transmit_response_with_auth(), and TRUE.
Referenced by check_user_full(), and register_verify().
09409 { 09410 const char *response = "407 Proxy Authentication Required"; 09411 const char *reqheader = "Proxy-Authorization"; 09412 const char *respheader = "Proxy-Authenticate"; 09413 const char *authtoken; 09414 char a1_hash[256]; 09415 char resp_hash[256]=""; 09416 char *c; 09417 int wrongnonce = FALSE; 09418 int good_response; 09419 const char *usednonce = p->randdata; 09420 struct ast_dynamic_str *buf; 09421 int res; 09422 09423 /* table of recognised keywords, and their value in the digest */ 09424 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 09425 struct x { 09426 const char *key; 09427 const char *s; 09428 } *i, keys[] = { 09429 [K_RESP] = { "response=", "" }, 09430 [K_URI] = { "uri=", "" }, 09431 [K_USER] = { "username=", "" }, 09432 [K_NONCE] = { "nonce=", "" }, 09433 [K_LAST] = { NULL, NULL} 09434 }; 09435 09436 /* Always OK if no secret */ 09437 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 09438 return AUTH_SUCCESSFUL; 09439 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 09440 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 09441 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 09442 different circumstances! What a surprise. */ 09443 response = "401 Unauthorized"; 09444 reqheader = "Authorization"; 09445 respheader = "WWW-Authenticate"; 09446 } 09447 authtoken = get_header(req, reqheader); 09448 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 09449 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 09450 information */ 09451 if (!reliable) { 09452 /* Resend message if this was NOT a reliable delivery. Otherwise the 09453 retransmission should get it */ 09454 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 09455 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 09456 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09457 } 09458 return AUTH_CHALLENGE_SENT; 09459 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 09460 /* We have no auth, so issue challenge and request authentication */ 09461 set_nonce_randdata(p, 1); /* Create nonce for challenge */ 09462 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 09463 /* Schedule auto destroy in 32 seconds */ 09464 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09465 return AUTH_CHALLENGE_SENT; 09466 } 09467 09468 /* --- We have auth, so check it */ 09469 09470 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 09471 an example in the spec of just what it is you're doing a hash on. */ 09472 09473 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) 09474 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 09475 09476 /* Make a copy of the response and parse it */ 09477 res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken); 09478 09479 if (res == AST_DYNSTR_BUILD_FAILED) 09480 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 09481 09482 c = buf->str; 09483 09484 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 09485 for (i = keys; i->key != NULL; i++) { 09486 const char *separator = ","; /* default */ 09487 09488 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 09489 continue; 09490 /* Found. Skip keyword, take text in quotes or up to the separator. */ 09491 c += strlen(i->key); 09492 if (*c == '"') { /* in quotes. Skip first and look for last */ 09493 c++; 09494 separator = "\""; 09495 } 09496 i->s = c; 09497 strsep(&c, separator); 09498 break; 09499 } 09500 if (i->key == NULL) /* not found, jump after space or comma */ 09501 strsep(&c, " ,"); 09502 } 09503 09504 /* Verify that digest username matches the username we auth as */ 09505 if (strcmp(username, keys[K_USER].s)) { 09506 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 09507 username, keys[K_USER].s); 09508 /* Oops, we're trying something here */ 09509 return AUTH_USERNAME_MISMATCH; 09510 } 09511 09512 /* Verify nonce from request matches our nonce, and the nonce has not already been responded to. 09513 * If this check fails, send 401 with new nonce */ 09514 if (strcasecmp(p->randdata, keys[K_NONCE].s) || p->stalenonce) { /* XXX it was 'n'casecmp ? */ 09515 wrongnonce = TRUE; 09516 usednonce = keys[K_NONCE].s; 09517 } else { 09518 p->stalenonce = 1; /* now, since the nonce has a response, mark it as stale so it can't be sent or responded to again */ 09519 } 09520 09521 if (!ast_strlen_zero(md5secret)) 09522 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 09523 else { 09524 char a1[256]; 09525 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 09526 ast_md5_hash(a1_hash, a1); 09527 } 09528 09529 /* compute the expected response to compare with what we received */ 09530 { 09531 char a2[256]; 09532 char a2_hash[256]; 09533 char resp[256]; 09534 09535 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 09536 S_OR(keys[K_URI].s, uri)); 09537 ast_md5_hash(a2_hash, a2); 09538 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 09539 ast_md5_hash(resp_hash, resp); 09540 } 09541 09542 good_response = keys[K_RESP].s && 09543 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 09544 if (wrongnonce) { 09545 if (good_response) { 09546 if (sipdebug) 09547 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "From")); 09548 /* We got working auth token, based on stale nonce . */ 09549 set_nonce_randdata(p, 0); 09550 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 09551 } else { 09552 /* Everything was wrong, so give the device one more try with a new challenge */ 09553 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 09554 if (sipdebug) 09555 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 09556 set_nonce_randdata(p, 1); 09557 } else { 09558 if (sipdebug) 09559 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 09560 } 09561 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 09562 } 09563 09564 /* Schedule auto destroy in 32 seconds */ 09565 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09566 return AUTH_CHALLENGE_SENT; 09567 } 09568 if (good_response) { 09569 append_history(p, "AuthOK", "Auth challenge successful for %s", username); 09570 return AUTH_SUCCESSFUL; 09571 } 09572 09573 /* Ok, we have a bad username/secret pair */ 09574 /* Tell the UAS not to re-send this authentication data, because 09575 it will continue to fail 09576 */ 09577 09578 return AUTH_SECRET_FAILED; 09579 }
static void check_auth_buf_init | ( | void | ) | [static] |
Definition at line 9398 of file chan_sip.c.
static void check_extenstate_updates | ( | struct sip_pvt * | pvt | ) | [static] |
Definition at line 9635 of file chan_sip.c.
References ast_free, AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, sip_extenstate_update::context, sip_extenstate_update::exten, notify_extenstate_update(), sip_extenstate_update::pvt, sip_extenstate_update::state, and update().
Referenced by do_monitor().
09636 { 09637 struct sip_extenstate_update *update = NULL; 09638 09639 if (AST_LIST_EMPTY(&sip_extenstate_updates)) { 09640 /* avoid holding the lock if possible */ 09641 return; 09642 } 09643 09644 do { 09645 if (update) { 09646 /* The notify can not happen while the list lock is held. */ 09647 notify_extenstate_update(update->context, update->exten, update->state, pvt); 09648 ast_free(update); 09649 } 09650 09651 AST_LIST_LOCK(&sip_extenstate_updates); 09652 AST_LIST_TRAVERSE_SAFE_BEGIN(&sip_extenstate_updates, update, list) { 09653 if (update->pvt == pvt) { 09654 AST_LIST_REMOVE_CURRENT(&sip_extenstate_updates, list); 09655 break; 09656 } 09657 } 09658 AST_LIST_TRAVERSE_SAFE_END 09659 AST_LIST_UNLOCK(&sip_extenstate_updates); 09660 } while (update); 09661 }
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 13459 of file chan_sip.c.
References ast_clear_flag, ast_log(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_test_flag, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, INV_CALLING, INV_CANCELLED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::lastinvite, LOG_DEBUG, option_debug, sip_pvt::owner, sip_pvt::pendinginvite, SIP_BYE, SIP_CANCEL, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_scheddestroy(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), TRUE, sip_pvt::waitid, and XMIT_RELIABLE.
Referenced by handle_request(), handle_response_invite(), and sip_reinvite_retry().
13460 { 13461 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 13462 /* if we can't BYE, then this is really a pending CANCEL */ 13463 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) { 13464 p->invitestate = INV_CANCELLED; 13465 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 13466 /* Actually don't destroy us yet, wait for the 487 on our original 13467 INVITE, but do set an autodestruct just in case we never get it. */ 13468 } else { 13469 /* We have a pending outbound invite, don't send someting 13470 new in-transaction */ 13471 if (p->pendinginvite) 13472 return; 13473 13474 if (p->owner) { 13475 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 13476 } 13477 /* Perhaps there is an SD change INVITE outstanding */ 13478 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 13479 } 13480 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 13481 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13482 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 13483 /* if we can't REINVITE, hold it for later */ 13484 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 13485 if (option_debug) 13486 ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 13487 } else { 13488 if (option_debug) 13489 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 13490 /* Didn't get to reinvite yet, so do it now */ 13491 transmit_reinvite_with_sdp(p); 13492 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 13493 } 13494 } 13495 }
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 18379 of file chan_sip.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, and domain::domain.
Referenced by func_check_sipdomain(), get_destination(), handle_request_refer(), and register_verify().
18380 { 18381 struct domain *d; 18382 int result = 0; 18383 18384 AST_LIST_LOCK(&domain_list); 18385 AST_LIST_TRAVERSE(&domain_list, d, list) { 18386 if (strcasecmp(d->domain, domain)) 18387 continue; 18388 18389 if (len && !ast_strlen_zero(d->context)) 18390 ast_copy_string(context, d->context, len); 18391 18392 result = 1; 18393 break; 18394 } 18395 AST_LIST_UNLOCK(&domain_list); 18396 18397 return result; 18398 }
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 11045 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
11046 { 11047 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 11048 }
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 10712 of file chan_sip.c.
References sip_peer::accountcode, sip_user::accountcode, accountcode, sip_user::allowtransfer, sip_pvt::allowtransfer, sip_peer::amaflags, sip_user::amaflags, sip_pvt::amaflags, ast_apply_ha(), ast_copy_flags, ast_copy_string(), AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_is_shrinkable_phonenumber(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_variable_new(), ast_variables_destroy(), ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, AUTH_FAKE_AUTH, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, sip_peer::autoframing, sip_user::autoframing, sip_pvt::autoframing, build_contact(), sip_peer::call_limit, sip_user::call_limit, sip_peer::callgroup, sip_user::callgroup, sip_pvt::callgroup, sip_peer::callingpres, sip_user::callingpres, sip_pvt::callingpres, sip_peer::capability, sip_user::capability, sip_pvt::capability, sip_peer::chanvars, sip_user::chanvars, sip_pvt::chanvars, check_auth(), sip_peer::cid_name, sip_user::cid_name, cid_name, sip_peer::cid_num, sip_user::cid_num, cid_num, sip_peer::context, context, sip_user::context, debug, do_setnat(), exten, sip_pvt::exten, find_peer(), find_user(), sip_peer::flags, sip_user::flags, sip_pvt::flags, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), sip_user::ha, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_peer::language, sip_user::language, language, sip_peer::lastms, LOG_NOTICE, LOG_WARNING, sip_peer::maxcallbitrate, sip_user::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_user::md5secret, sip_peer::mohinterpret, sip_user::mohinterpret, mohinterpret, sip_peer::mohsuggest, sip_user::mohsuggest, mohsuggest, sip_peer::name, sip_user::name, ast_variable::next, sip_pvt::noncodeccapability, sip_pvt::our_contact, t38properties::peercapability, sip_pvt::peercapability, sip_pvt::peermd5secret, sip_pvt::peersecret, sip_peer::pickupgroup, sip_user::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_user::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::secret, sip_user::secret, SIP_CALL_LIMIT, sip_cancel_destroy(), sip_debug_test_addr(), sip_destroy_peer(), sip_destroy_user(), 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_RPORT_PRESENT, SIP_PAGE2_VIDEOSUPPORT, SIP_PKT_IGNORE, SIP_SUBSCRIBE, SIP_TRUSTRPID, sip_peer::sipoptions, sip_user::sipoptions, sip_pvt::sipoptions, strsep(), sip_peer::subscribecontext, sip_user::subscribecontext, t, sip_pvt::t38, sip_pvt::timer_t1, sip_peer::username, username, and sip_pvt::vrtp.
Referenced by check_user(), and handle_request_subscribe().
10715 { 10716 struct sip_user *user = NULL; 10717 struct sip_peer *peer; 10718 char from[256], *c; 10719 char *of; 10720 char rpid_num[50]; 10721 const char *rpid; 10722 enum check_auth_result res = AUTH_SUCCESSFUL; 10723 char *t; 10724 char calleridname[50]; 10725 int debug=sip_debug_test_addr(sin); 10726 struct ast_variable *tmpvar = NULL, *v = NULL; 10727 char *uri2 = ast_strdupa(uri); 10728 10729 /* Terminate URI */ 10730 t = uri2; 10731 while (*t && *t > 32 && *t != ';') 10732 t++; 10733 *t = '\0'; 10734 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 10735 if (pedanticsipchecking) 10736 ast_uri_decode(from); 10737 /* XXX here tries to map the username for invite things */ 10738 memset(calleridname, 0, sizeof(calleridname)); 10739 get_calleridname(from, calleridname, sizeof(calleridname)); 10740 if (calleridname[0]) 10741 ast_string_field_set(p, cid_name, calleridname); 10742 10743 rpid = get_header(req, "Remote-Party-ID"); 10744 memset(rpid_num, 0, sizeof(rpid_num)); 10745 if (!ast_strlen_zero(rpid)) 10746 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 10747 10748 of = get_in_brackets(from); 10749 if (ast_strlen_zero(p->exten)) { 10750 t = uri2; 10751 if (!strncasecmp(t, "sip:", 4)) 10752 t+= 4; 10753 ast_string_field_set(p, exten, t); 10754 t = strchr(p->exten, '@'); 10755 if (t) 10756 *t = '\0'; 10757 if (ast_strlen_zero(p->our_contact)) 10758 build_contact(p); 10759 } 10760 /* save the URI part of the From header */ 10761 ast_string_field_set(p, from, of); 10762 if (strncasecmp(of, "sip:", 4)) { 10763 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 10764 } else 10765 of += 4; 10766 /* Get just the username part */ 10767 if ((c = strchr(of, '@'))) { 10768 char *tmp; 10769 *c = '\0'; 10770 if ((c = strchr(of, ':'))) 10771 *c = '\0'; 10772 tmp = ast_strdupa(of); 10773 /* We need to be able to handle auth-headers looking like 10774 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 10775 */ 10776 tmp = strsep(&tmp, ";"); 10777 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10778 ast_shrink_phone_number(tmp); 10779 ast_string_field_set(p, cid_num, tmp); 10780 } 10781 10782 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 10783 user = find_user(of, 1); 10784 10785 /* Find user based on user name in the from header */ 10786 if (user && ast_apply_ha(user->ha, sin)) { 10787 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 10788 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10789 if (sipmethod == SIP_INVITE) { 10790 /* destroy old channel vars and copy new channel vars */ 10791 ast_variables_destroy(p->chanvars); 10792 p->chanvars = NULL; 10793 for (v = user->chanvars ; v ; v = v->next) { 10794 if ((tmpvar = ast_variable_new(v->name, v->value))) { 10795 tmpvar->next = p->chanvars; 10796 p->chanvars = tmpvar; 10797 } 10798 } 10799 } 10800 p->prefs = user->prefs; 10801 /* Set Frame packetization */ 10802 if (p->rtp) { 10803 ast_rtp_codec_setpref(p->rtp, &p->prefs); 10804 p->autoframing = user->autoframing; 10805 } 10806 /* replace callerid if rpid found, and not restricted */ 10807 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 10808 char *tmp; 10809 if (*calleridname) 10810 ast_string_field_set(p, cid_name, calleridname); 10811 tmp = ast_strdupa(rpid_num); 10812 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10813 ast_shrink_phone_number(tmp); 10814 ast_string_field_set(p, cid_num, tmp); 10815 } 10816 10817 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 10818 10819 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 10820 if (sip_cancel_destroy(p)) 10821 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 10822 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 10823 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10824 /* Copy SIP extensions profile from INVITE */ 10825 if (p->sipoptions) 10826 user->sipoptions = p->sipoptions; 10827 10828 /* If we have a call limit, set flag */ 10829 if (user->call_limit) 10830 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 10831 if (!ast_strlen_zero(user->context)) 10832 ast_string_field_set(p, context, user->context); 10833 if (!ast_strlen_zero(user->cid_num)) { 10834 char *tmp = ast_strdupa(user->cid_num); 10835 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10836 ast_shrink_phone_number(tmp); 10837 ast_string_field_set(p, cid_num, tmp); 10838 } 10839 if (!ast_strlen_zero(user->cid_name)) 10840 ast_string_field_set(p, cid_name, user->cid_name); 10841 ast_string_field_set(p, username, user->name); 10842 ast_string_field_set(p, peername, user->name); 10843 ast_string_field_set(p, peersecret, user->secret); 10844 ast_string_field_set(p, peermd5secret, user->md5secret); 10845 ast_string_field_set(p, subscribecontext, user->subscribecontext); 10846 ast_string_field_set(p, accountcode, user->accountcode); 10847 ast_string_field_set(p, language, user->language); 10848 ast_string_field_set(p, mohsuggest, user->mohsuggest); 10849 ast_string_field_set(p, mohinterpret, user->mohinterpret); 10850 p->allowtransfer = user->allowtransfer; 10851 p->amaflags = user->amaflags; 10852 memcpy(&p->callgroup, user->callgroup, sizeof(p->callgroup)); 10853 memcpy(&p->pickupgroup, user->pickupgroup, sizeof(p->pickupgroup)); 10854 if (user->callingpres) /* User callingpres setting will override RPID header */ 10855 p->callingpres = user->callingpres; 10856 10857 /* Set default codec settings for this call */ 10858 p->capability = user->capability; /* User codec choice */ 10859 p->jointcapability = user->capability; /* Our codecs */ 10860 if (p->peercapability) /* AND with peer's codecs */ 10861 p->jointcapability &= p->peercapability; 10862 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 10863 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 10864 p->noncodeccapability |= AST_RTP_DTMF; 10865 else 10866 p->noncodeccapability &= ~AST_RTP_DTMF; 10867 p->jointnoncodeccapability = p->noncodeccapability; 10868 if (p->t38.peercapability) 10869 p->t38.jointcapability &= p->t38.peercapability; 10870 p->maxcallbitrate = user->maxcallbitrate; 10871 /* If we do not support video, remove video from call structure */ 10872 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 10873 ast_rtp_destroy(p->vrtp); 10874 p->vrtp = NULL; 10875 } 10876 } 10877 if (user && debug) 10878 ast_verbose("Found user '%s'\n", user->name); 10879 } else { 10880 if (user) { 10881 if (!authpeer && debug) 10882 ast_verbose("Found user '%s', but fails host access\n", user->name); 10883 ASTOBJ_UNREF(user,sip_destroy_user); 10884 } 10885 user = NULL; 10886 } 10887 10888 if (!user) { 10889 /* If we didn't find a user match, check for peers */ 10890 if (sipmethod == SIP_SUBSCRIBE) 10891 /* For subscribes, match on peer name only */ 10892 peer = find_peer(of, NULL, 1, 0); 10893 else 10894 /* Look for peer based on the IP address we received data from */ 10895 /* If peer is registered from this IP address or have this as a default 10896 IP address, this call is from the peer 10897 */ 10898 peer = find_peer(NULL, &p->recv, 1, 0); 10899 10900 if (peer) { 10901 /* Set Frame packetization */ 10902 if (p->rtp) { 10903 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 10904 p->autoframing = peer->autoframing; 10905 } 10906 if (debug) 10907 ast_verbose("Found peer '%s'\n", peer->name); 10908 10909 /* Take the peer */ 10910 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 10911 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10912 10913 /* Copy SIP extensions profile to peer */ 10914 if (p->sipoptions) 10915 peer->sipoptions = p->sipoptions; 10916 10917 /* replace callerid if rpid found, and not restricted */ 10918 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 10919 char *tmp = ast_strdupa(rpid_num); 10920 if (*calleridname) 10921 ast_string_field_set(p, cid_name, calleridname); 10922 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10923 ast_shrink_phone_number(tmp); 10924 ast_string_field_set(p, cid_num, tmp); 10925 } 10926 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 10927 10928 ast_string_field_set(p, peersecret, peer->secret); 10929 ast_string_field_set(p, peermd5secret, peer->md5secret); 10930 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 10931 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 10932 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 10933 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 10934 p->callingpres = peer->callingpres; 10935 if (peer->maxms && peer->lastms) 10936 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 10937 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 10938 /* Pretend there is no required authentication */ 10939 ast_string_field_free(p, peersecret); 10940 ast_string_field_free(p, peermd5secret); 10941 } 10942 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 10943 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 10944 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10945 /* If we have a call limit, set flag */ 10946 if (peer->call_limit) 10947 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 10948 ast_string_field_set(p, peername, peer->name); 10949 ast_string_field_set(p, authname, peer->name); 10950 10951 if (sipmethod == SIP_INVITE) { 10952 /* destroy old channel vars and copy new channel vars */ 10953 ast_variables_destroy(p->chanvars); 10954 p->chanvars = NULL; 10955 for (v = peer->chanvars ; v ; v = v->next) { 10956 if ((tmpvar = ast_variable_new(v->name, v->value))) { 10957 tmpvar->next = p->chanvars; 10958 p->chanvars = tmpvar; 10959 } 10960 } 10961 } 10962 if (authpeer) { 10963 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 10964 } 10965 10966 if (!ast_strlen_zero(peer->username)) { 10967 ast_string_field_set(p, username, peer->username); 10968 /* Use the default username for authentication on outbound calls */ 10969 /* XXX this takes the name from the caller... can we override ? */ 10970 ast_string_field_set(p, authname, peer->username); 10971 } 10972 if (!ast_strlen_zero(peer->cid_num)) { 10973 char *tmp = ast_strdupa(peer->cid_num); 10974 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10975 ast_shrink_phone_number(tmp); 10976 ast_string_field_set(p, cid_num, tmp); 10977 } 10978 if (!ast_strlen_zero(peer->cid_name)) 10979 ast_string_field_set(p, cid_name, peer->cid_name); 10980 ast_string_field_set(p, fullcontact, peer->fullcontact); 10981 if (!ast_strlen_zero(peer->context)) 10982 ast_string_field_set(p, context, peer->context); 10983 ast_string_field_set(p, peersecret, peer->secret); 10984 ast_string_field_set(p, peermd5secret, peer->md5secret); 10985 ast_string_field_set(p, language, peer->language); 10986 ast_string_field_set(p, accountcode, peer->accountcode); 10987 p->amaflags = peer->amaflags; 10988 memcpy(&p->callgroup, peer->callgroup, sizeof(p->callgroup)); 10989 memcpy(&p->pickupgroup, peer->pickupgroup, sizeof(p->pickupgroup)); 10990 p->capability = peer->capability; 10991 p->prefs = peer->prefs; 10992 p->jointcapability = peer->capability; 10993 if (p->peercapability) 10994 p->jointcapability &= p->peercapability; 10995 p->maxcallbitrate = peer->maxcallbitrate; 10996 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 10997 ast_rtp_destroy(p->vrtp); 10998 p->vrtp = NULL; 10999 } 11000 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 11001 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 11002 p->noncodeccapability |= AST_RTP_DTMF; 11003 else 11004 p->noncodeccapability &= ~AST_RTP_DTMF; 11005 p->jointnoncodeccapability = p->noncodeccapability; 11006 if (p->t38.peercapability) 11007 p->t38.jointcapability &= p->t38.peercapability; 11008 } 11009 ASTOBJ_UNREF(peer, sip_destroy_peer); 11010 } else { 11011 if (debug) 11012 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 11013 11014 /* do we allow guests? */ 11015 if (!global_allowguest) { 11016 if (global_alwaysauthreject) 11017 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 11018 else 11019 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 11020 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 11021 char *tmp = ast_strdupa(rpid_num); 11022 if (*calleridname) 11023 ast_string_field_set(p, cid_name, calleridname); 11024 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 11025 ast_shrink_phone_number(tmp); 11026 ast_string_field_set(p, cid_num, tmp); 11027 } 11028 } 11029 11030 } 11031 11032 if (user) 11033 ASTOBJ_UNREF(user, sip_destroy_user); 11034 11035 if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT)) { 11036 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 11037 } 11038 11039 return res; 11040 }
static void check_via | ( | struct sip_pvt * | p, | |
const struct sip_request * | req | |||
) | [static] |
check Via: header for hostname, port and rport request/answer
Definition at line 10569 of file chan_sip.c.
References 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(), handle_request_subscribe(), and transmit_response_using_temp().
10570 { 10571 char via[512]; 10572 char *c, *pt, *maddr; 10573 struct hostent *hp; 10574 struct ast_hostent ahp; 10575 10576 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 10577 10578 /* Work on the leftmost value of the topmost Via header */ 10579 c = strchr(via, ','); 10580 if (c) 10581 *c = '\0'; 10582 10583 /* Check for rport */ 10584 c = strstr(via, ";rport"); 10585 if (c && (c[6] != '=')) /* rport query, not answer */ 10586 ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT); 10587 10588 /* Check for maddr */ 10589 maddr = strstr(via, "maddr="); 10590 if (maddr) { 10591 maddr += 6; 10592 c = maddr + strspn(maddr, "0123456789."); 10593 *c = '\0'; 10594 } 10595 10596 c = strchr(via, ';'); 10597 if (c) 10598 *c = '\0'; 10599 10600 c = strchr(via, ' '); 10601 if (c) { 10602 *c = '\0'; 10603 c = ast_skip_blanks(c+1); 10604 if (strcasecmp(via, "SIP/2.0/UDP")) { 10605 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 10606 return; 10607 } 10608 pt = strchr(c, ':'); 10609 if (pt) 10610 *pt++ = '\0'; /* remember port pointer */ 10611 /* Use maddr if found */ 10612 if (maddr) 10613 c = maddr; 10614 hp = ast_gethostbyname(c, &ahp); 10615 if (!hp) { 10616 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 10617 return; 10618 } 10619 memset(&p->sa, 0, sizeof(p->sa)); 10620 p->sa.sin_family = AF_INET; 10621 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 10622 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 10623 10624 if (sip_debug_test_pvt(p)) { 10625 const struct sockaddr_in *dst = sip_real_dst(p); 10626 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 10627 } 10628 } 10629 }
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 11489 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), ast_copy_string(), AST_MAX_CONTEXT, and strsep().
Referenced by reload_config().
11490 { 11491 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 11492 11493 while ((oldcontext = strsep(&old, "&"))) { 11494 stalecontext = '\0'; 11495 ast_copy_string(newlist, new, sizeof(newlist)); 11496 stringp = newlist; 11497 while ((newcontext = strsep(&stringp, "&"))) { 11498 if (strcmp(newcontext, oldcontext) == 0) { 11499 /* This is not the context you're looking for */ 11500 stalecontext = '\0'; 11501 break; 11502 } else if (strcmp(newcontext, oldcontext)) { 11503 stalecontext = oldcontext; 11504 } 11505 11506 } 11507 if (stalecontext) 11508 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 11509 } 11510 }
static void clear_extenstate_updates | ( | struct sip_pvt * | pvt | ) | [static] |
Definition at line 9737 of file chan_sip.c.
References ast_free, AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, sip_extenstate_update::pvt, and update().
Referenced by __sip_destroy().
09738 { 09739 struct sip_extenstate_update *update = NULL; 09740 09741 if (AST_LIST_EMPTY(&sip_extenstate_updates)) { 09742 /* avoid holding the lock if possible */ 09743 return; 09744 } 09745 09746 AST_LIST_LOCK(&sip_extenstate_updates); 09747 AST_LIST_TRAVERSE_SAFE_BEGIN(&sip_extenstate_updates, update, list) { 09748 if (update->pvt == pvt) { 09749 AST_LIST_REMOVE_CURRENT(&sip_extenstate_updates, list); 09750 ast_free(update); 09751 } 09752 } 09753 AST_LIST_TRAVERSE_SAFE_END 09754 AST_LIST_UNLOCK(&sip_extenstate_updates); 09755 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 18470 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 18401 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free.
Referenced by reload_config(), and unload_module().
18402 { 18403 struct domain *d; 18404 18405 AST_LIST_LOCK(&domain_list); 18406 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 18407 free(d); 18408 AST_LIST_UNLOCK(&domain_list); 18409 }
static void clearmarked_extenstate_updates | ( | void | ) | [static] |
Definition at line 9667 of file chan_sip.c.
References ast_free, AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, sip_extenstate_update::marked, and update().
Referenced by do_monitor().
09668 { 09669 struct sip_extenstate_update *update = NULL; 09670 09671 if (AST_LIST_EMPTY(&sip_extenstate_updates)) { 09672 /* avoid holding the lock if possible */ 09673 return; 09674 } 09675 09676 AST_LIST_LOCK(&sip_extenstate_updates); 09677 AST_LIST_TRAVERSE_SAFE_BEGIN(&sip_extenstate_updates, update, list) { 09678 if (update->marked) { 09679 AST_LIST_REMOVE_CURRENT(&sip_extenstate_updates, list); 09680 ast_free(update); 09681 } 09682 } 09683 AST_LIST_TRAVERSE_SAFE_END 09684 AST_LIST_UNLOCK(&sip_extenstate_updates); 09685 09686 }
static char * complete_sip_debug_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip debug peer' CLI.
Definition at line 12317 of file chan_sip.c.
References complete_sip_peer().
12318 { 12319 if (pos == 3) 12320 return complete_sip_peer(word, state, 0); 12321 12322 return NULL; 12323 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 12291 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, and peerl.
Referenced by complete_sip_debug_peer(), complete_sip_prune_realtime_peer(), complete_sip_show_peer(), and complete_sipnotify().
12292 { 12293 char *result = NULL; 12294 int wordlen = strlen(word); 12295 int which = 0; 12296 12297 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 12298 /* locking of the object is not required because only the name and flags are being compared */ 12299 if (!strncasecmp(word, iterator->name, wordlen) && 12300 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 12301 ++which > state) 12302 result = ast_strdup(iterator->name); 12303 } while(0) ); 12304 return result; 12305 }
static char * complete_sip_prune_realtime_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip prune realtime peer' CLI.
Definition at line 12385 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
12386 { 12387 if (pos == 4) 12388 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 12389 return NULL; 12390 }
static char * complete_sip_prune_realtime_user | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip prune realtime user' CLI.
Definition at line 12393 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
12394 { 12395 if (pos == 4) 12396 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 12397 12398 return NULL; 12399 }
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 12308 of file chan_sip.c.
References complete_sip_peer().
12309 { 12310 if (pos == 3) 12311 return complete_sip_peer(word, state, 0); 12312 12313 return NULL; 12314 }
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 12346 of file chan_sip.c.
References complete_sip_user().
12347 { 12348 if (pos == 3) 12349 return complete_sip_user(word, state, 0); 12350 12351 return NULL; 12352 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 12326 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, and userl.
Referenced by complete_sip_prune_realtime_user(), and complete_sip_show_user().
12327 { 12328 char *result = NULL; 12329 int wordlen = strlen(word); 12330 int which = 0; 12331 12332 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 12333 /* locking of the object is not required because only the name and flags are being compared */ 12334 if (!strncasecmp(word, iterator->name, wordlen)) { 12335 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 12336 continue; 12337 if (++which > state) { 12338 result = ast_strdup(iterator->name); 12339 } 12340 } 12341 } while(0) ); 12342 return result; 12343 }
static char * complete_sipch | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip show channel' CLI.
Definition at line 12268 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_strdup, sip_pvt::callid, iflist, iflock, and sip_pvt::next.
12269 { 12270 int which=0; 12271 struct sip_pvt *cur; 12272 char *c = NULL; 12273 int wordlen = strlen(word); 12274 12275 if (pos != 3) { 12276 return NULL; 12277 } 12278 12279 ast_mutex_lock(&iflock); 12280 for (cur = iflist; cur; cur = cur->next) { 12281 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 12282 c = ast_strdup(cur->callid); 12283 break; 12284 } 12285 } 12286 ast_mutex_unlock(&iflock); 12287 return c; 12288 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 12355 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
12356 { 12357 char *c = NULL; 12358 12359 if (pos == 2) { 12360 int which = 0; 12361 char *cat = NULL; 12362 int wordlen = strlen(word); 12363 12364 /* do completion for notify type */ 12365 12366 if (!notify_types) 12367 return NULL; 12368 12369 while ( (cat = ast_category_browse(notify_types, cat)) ) { 12370 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 12371 c = ast_strdup(cat); 12372 break; 12373 } 12374 } 12375 return c; 12376 } 12377 12378 if (pos > 2) 12379 return complete_sip_peer(word, state, 0); 12380 12381 return NULL; 12382 }
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 6519 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
06520 { 06521 int start = 0; 06522 int copied = 0; 06523 for (;;) { 06524 const char *tmp = __get_header(orig, field, &start); 06525 06526 if (ast_strlen_zero(tmp)) 06527 break; 06528 /* Add what we're responding to */ 06529 add_header(req, field, tmp); 06530 copied++; 06531 } 06532 return copied ? 0 : -1; 06533 }
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 6508 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
06509 { 06510 const char *tmp = get_header(orig, field); 06511 06512 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 06513 return add_header(req, field, tmp); 06514 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 06515 return -1; 06516 }
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 7618 of file chan_sip.c.
References sip_request::header, sip_request::line, offset, sip_request::rlPart1, and sip_request::rlPart2.
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().
07619 { 07620 long offset; 07621 int x; 07622 offset = ((void *)dst) - ((void *)src); 07623 /* First copy stuff */ 07624 memcpy(dst, src, sizeof(*dst)); 07625 /* Now fix pointer arithmetic */ 07626 for (x=0; x < src->headers; x++) 07627 dst->header[x] += offset; 07628 for (x=0; x < src->lines; x++) 07629 dst->line[x] += offset; 07630 dst->rlPart1 += offset; 07631 dst->rlPart2 += offset; 07632 }
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.
Definition at line 6541 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().
06542 { 06543 int copied = 0; 06544 int start = 0; 06545 06546 for (;;) { 06547 char new[512]; 06548 const char *oh = __get_header(orig, field, &start); 06549 06550 if (ast_strlen_zero(oh)) 06551 break; 06552 06553 if (!copied) { /* Only check for empty rport in topmost via header */ 06554 char leftmost[512], *others, *rport; 06555 06556 /* Only work on leftmost value */ 06557 ast_copy_string(leftmost, oh, sizeof(leftmost)); 06558 others = strchr(leftmost, ','); 06559 if (others) 06560 *others++ = '\0'; 06561 06562 /* Find ;rport; (empty request) */ 06563 rport = strstr(leftmost, ";rport"); 06564 if (rport && *(rport+6) == '=') 06565 rport = NULL; /* We already have a parameter to rport */ 06566 06567 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 06568 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 06569 /* We need to add received port - rport */ 06570 char *end; 06571 06572 rport = strstr(leftmost, ";rport"); 06573 06574 if (rport) { 06575 end = strchr(rport + 1, ';'); 06576 if (end) 06577 memmove(rport, end, strlen(end) + 1); 06578 else 06579 *rport = '\0'; 06580 } 06581 06582 /* Add rport to first VIA header if requested */ 06583 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 06584 leftmost, ast_inet_ntoa(p->recv.sin_addr), 06585 ntohs(p->recv.sin_port), 06586 others ? "," : "", others ? others : ""); 06587 } else { 06588 /* We should *always* add a received to the topmost via */ 06589 snprintf(new, sizeof(new), "%s;received=%s%s%s", 06590 leftmost, ast_inet_ntoa(p->recv.sin_addr), 06591 others ? "," : "", others ? others : ""); 06592 } 06593 oh = new; /* the header to copy */ 06594 } /* else add the following via headers untouched */ 06595 add_header(req, field, oh); 06596 copied++; 06597 } 06598 if (!copied) { 06599 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 06600 return -1; 06601 } 06602 return 0; 06603 }
static int create_addr | ( | struct sip_pvt * | dialog, | |
const char * | opeer, | |||
struct sockaddr_in * | sin | |||
) | [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 3179 of file chan_sip.c.
References ast_copy_string(), ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ASTOBJ_UNREF, create_addr_from_peer(), do_setnat(), find_peer(), sip_pvt::flags, hp, LOG_WARNING, sip_pvt::portinuri, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), SIP_NAT, SIP_NAT_ROUTE, STANDARD_SIP_PORT, sip_pvt::timer_t1, and sip_peer::tohost.
Referenced by sip_notify(), sip_request_call(), and transmit_register().
03180 { 03181 struct hostent *hp; 03182 struct ast_hostent ahp; 03183 struct sip_peer *p; 03184 char *port; 03185 int portno = 0; 03186 char host[MAXHOSTNAMELEN], *hostn; 03187 char peer[256]; 03188 03189 ast_copy_string(peer, opeer, sizeof(peer)); 03190 port = strchr(peer, ':'); 03191 if (port) { 03192 *port++ = '\0'; 03193 dialog->portinuri = 1; 03194 } 03195 dialog->sa.sin_family = AF_INET; 03196 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 03197 p = find_peer(peer, NULL, 1, 0); 03198 03199 if (p) { 03200 int res = create_addr_from_peer(dialog, p); 03201 if (port) { 03202 portno = atoi(port); 03203 dialog->sa.sin_port = dialog->recv.sin_port = htons(portno); 03204 } 03205 ASTOBJ_UNREF(p, sip_destroy_peer); 03206 return res; 03207 } 03208 03209 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 03210 03211 ast_string_field_set(dialog, tohost, peer); 03212 03213 if (sin) { 03214 memcpy(&dialog->sa.sin_addr, &sin->sin_addr, sizeof(dialog->sa.sin_addr)); 03215 if (!sin->sin_port) { 03216 if (ast_strlen_zero(port) || sscanf(port, "%30u", &portno) != 1) { 03217 portno = STANDARD_SIP_PORT; 03218 } 03219 } else { 03220 portno = ntohs(sin->sin_port); 03221 } 03222 } else { 03223 hostn = peer; 03224 /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then 03225 * an A record lookup should be used instead of SRV. 03226 */ 03227 if (!port && srvlookup) { 03228 char service[MAXHOSTNAMELEN]; 03229 int tportno; 03230 int ret; 03231 03232 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 03233 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 03234 if (ret > 0) { 03235 hostn = host; 03236 portno = tportno; 03237 } 03238 } 03239 if (!portno) 03240 portno = port ? atoi(port) : STANDARD_SIP_PORT; 03241 03242 hp = ast_gethostbyname(hostn, &ahp); 03243 if (!hp) { 03244 ast_log(LOG_WARNING, "No such host: %s\n", peer); 03245 return -1; 03246 } 03247 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 03248 } 03249 dialog->sa.sin_port = htons(portno); 03250 dialog->recv = dialog->sa; 03251 return 0; 03252 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 3068 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_log(), 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_get_error_correction_scheme(), sip_peer::auth, sip_peer::autoframing, sip_pvt::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, sip_pvt::callid, t38properties::capability, sip_peer::capability, sip_pvt::capability, sip_peer::context, context, 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, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, language, sip_peer::language, sip_peer::lastms, LOG_DEBUG, sip_peer::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_pvt::maxtime, sip_peer::md5secret, sip_peer::mohinterpret, mohinterpret, sip_peer::mohsuggest, mohsuggest, sip_peer::name, sip_pvt::noncodeccapability, option_debug, sip_pvt::peerauth, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::portinuri, sip_pvt::portinuri, 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, sip_peer::secret, 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_VIDEOSUPPORT, sip_pvt::t38, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, sip_pvt::timer_t1, sip_pvt::tohost, sip_peer::tohost, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, username, sip_peer::username, and sip_pvt::vrtp.
Referenced by create_addr(), and sip_send_mwi_to_peer().
03069 { 03070 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 03071 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 03072 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 03073 dialog->recv = dialog->sa; 03074 } else 03075 return -1; 03076 03077 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 03078 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 03079 dialog->capability = peer->capability; 03080 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 03081 ast_rtp_destroy(dialog->vrtp); 03082 dialog->vrtp = NULL; 03083 } 03084 dialog->prefs = peer->prefs; 03085 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 03086 dialog->t38.capability = global_t38_capability; 03087 if (dialog->udptl) { 03088 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 03089 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 03090 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 03091 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 03092 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 03093 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 03094 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 03095 if (option_debug > 1) 03096 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 03097 } 03098 dialog->t38.jointcapability = dialog->t38.capability; 03099 } else if (dialog->udptl) { 03100 ast_udptl_destroy(dialog->udptl); 03101 dialog->udptl = NULL; 03102 } 03103 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 03104 03105 if (dialog->rtp) { 03106 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 03107 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 03108 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 03109 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 03110 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 03111 /* Set Frame packetization */ 03112 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 03113 dialog->autoframing = peer->autoframing; 03114 } 03115 if (dialog->vrtp) { 03116 ast_rtp_setdtmf(dialog->vrtp, 0); 03117 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 03118 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 03119 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 03120 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 03121 } 03122 03123 ast_string_field_set(dialog, peername, peer->name); 03124 ast_string_field_set(dialog, authname, peer->username); 03125 ast_string_field_set(dialog, username, peer->username); 03126 ast_string_field_set(dialog, peersecret, peer->secret); 03127 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 03128 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 03129 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 03130 ast_string_field_set(dialog, tohost, peer->tohost); 03131 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 03132 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 03133 char *tmpcall; 03134 char *c; 03135 tmpcall = ast_strdupa(dialog->callid); 03136 c = strchr(tmpcall, '@'); 03137 if (c) { 03138 *c = '\0'; 03139 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 03140 } 03141 } 03142 if (ast_strlen_zero(dialog->tohost)) 03143 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 03144 if (!ast_strlen_zero(peer->fromdomain)) 03145 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 03146 if (!ast_strlen_zero(peer->fromuser)) 03147 ast_string_field_set(dialog, fromuser, peer->fromuser); 03148 if (!ast_strlen_zero(peer->language)) 03149 ast_string_field_set(dialog, language, peer->language); 03150 dialog->maxtime = peer->maxms; 03151 memcpy(&dialog->callgroup, peer->callgroup, sizeof(dialog->callgroup)); 03152 memcpy(&dialog->pickupgroup, peer->pickupgroup, sizeof(dialog->pickupgroup)); 03153 dialog->peerauth = peer->auth; 03154 dialog->allowtransfer = peer->allowtransfer; 03155 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 03156 /* Minimum is settable or default to 100 ms */ 03157 if (peer->maxms && peer->lastms) 03158 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 03159 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 03160 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 03161 dialog->noncodeccapability |= AST_RTP_DTMF; 03162 else 03163 dialog->noncodeccapability &= ~AST_RTP_DTMF; 03164 dialog->jointnoncodeccapability = dialog->noncodeccapability; 03165 ast_string_field_set(dialog, context, peer->context); 03166 dialog->rtptimeout = peer->rtptimeout; 03167 if (peer->call_limit) 03168 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 03169 dialog->maxcallbitrate = peer->maxcallbitrate; 03170 if (!dialog->portinuri) 03171 dialog->portinuri = peer->portinuri; 03172 03173 return 0; 03174 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 8833 of file chan_sip.c.
References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_peer::flags, sip_peer::name, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, and SIP_PAGE2_RTUPDATE.
Referenced by build_peer(), and expire_register().
08834 { 08835 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 08836 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT) && ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) { 08837 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "regserver", "", NULL); 08838 ast_update_realtime("sippeers", "name", peer->name, "lastms", "", NULL); 08839 } else 08840 ast_db_del("SIP/Registry", peer->name); 08841 } 08842 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 7667 of file chan_sip.c.
References ast_log(), ast_skip_blanks(), ast_skip_nonblanks(), ast_trim_blanks(), sip_request::header, LOG_WARNING, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by parse_request().
07668 { 07669 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 07670 07671 if (!*e) 07672 return -1; 07673 req->rlPart1 = e; /* method or protocol */ 07674 e = ast_skip_nonblanks(e); 07675 if (*e) 07676 *e++ = '\0'; 07677 /* Get URI or status code */ 07678 e = ast_skip_blanks(e); 07679 if ( !*e ) 07680 return -1; 07681 ast_trim_blanks(e); 07682 07683 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 07684 if (strlen(e) < 3) /* status code is 3 digits */ 07685 return -1; 07686 req->rlPart2 = e; 07687 } else { /* We have a request */ 07688 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 07689 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 07690 e++; 07691 if (!*e) 07692 return -1; 07693 } 07694 req->rlPart2 = e; /* URI */ 07695 e = ast_skip_nonblanks(e); 07696 if (*e) 07697 *e++ = '\0'; 07698 e = ast_skip_blanks(e); 07699 if (strcasecmp(e, "SIP/2.0") ) { 07700 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 07701 return -1; 07702 } 07703 } 07704 return 1; 07705 }
static void display_nat_warning | ( | const char * | cat, | |
int | reason, | |||
struct ast_flags * | flags | |||
) | [static] |
Definition at line 19016 of file chan_sip.c.
References ast_log(), ast_test_flag, CHANNEL_MODULE_LOAD, LOG_WARNING, nat2str(), and SIP_NAT.
Referenced by reload_config().
19016 { 19017 int global_nat, specific_nat; 19018 19019 if (reason == CHANNEL_MODULE_LOAD && (specific_nat = ast_test_flag(&flags[0], SIP_NAT)) != (global_nat = ast_test_flag(&global_flags[0], SIP_NAT))) { 19020 ast_log(LOG_WARNING, "!!! PLEASE NOTE: Setting 'nat' for a peer/user that differs from the global setting can make\n"); 19021 ast_log(LOG_WARNING, "!!! the name of that peer/user discoverable by an attacker. Replies for non-existent peers/users\n"); 19022 ast_log(LOG_WARNING, "!!! will be sent to a different port than replies for an existing peer/user. If at all possible,\n"); 19023 ast_log(LOG_WARNING, "!!! use the global 'nat' setting and do not set 'nat' per peer/user.\n"); 19024 ast_log(LOG_WARNING, "!!! (config category='%s' global='%s' peer/user='%s')\n", cat, nat2str(global_nat), nat2str(specific_nat)); 19025 } 19026 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 17644 of file chan_sip.c.
References __sip_destroy(), ast_channel_trylock, ast_channel_unlock, ast_io_add(), ast_io_change(), AST_IO_IN, ast_io_remove(), ast_io_wait(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), 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_sched_runq(), ast_sched_wait(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, ast_verbose(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, check_extenstate_updates(), clearmarked_extenstate_updates(), DEADLOCK_AVOIDANCE, does_peer_need_mwi(), FALSE, iflist, iflock, LOG_DEBUG, LOG_NOTICE, markall_extenstate_updates(), monlock, sip_pvt::next, option_debug, option_verbose, peerl, sip_destroy_peer(), sip_do_reload(), SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, sip_reload_lock, sip_send_mwi_to_peer(), sipsock, sipsock_read(), t, T38_ENABLED, TRUE, unmark_extenstate_update(), and VERBOSE_PREFIX_1.
Referenced by restart_monitor().
17645 { 17646 int res; 17647 struct sip_pvt *sip; 17648 struct sip_peer *peer = NULL; 17649 time_t t; 17650 int fastrestart = FALSE; 17651 int lastpeernum = -1; 17652 int curpeernum; 17653 int reloading; 17654 17655 /* Add an I/O event to our SIP UDP socket */ 17656 if (sipsock > -1) 17657 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 17658 17659 /* From here on out, we die whenever asked */ 17660 for(;;) { 17661 /* Check for a reload request */ 17662 ast_mutex_lock(&sip_reload_lock); 17663 reloading = sip_reloading; 17664 sip_reloading = FALSE; 17665 ast_mutex_unlock(&sip_reload_lock); 17666 if (reloading) { 17667 if (option_verbose > 0) 17668 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 17669 sip_do_reload(sip_reloadreason); 17670 17671 /* Change the I/O fd of our UDP socket */ 17672 if (sipsock > -1) { 17673 if (sipsock_read_id) 17674 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 17675 else 17676 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 17677 } else if (sipsock_read_id) { 17678 ast_io_remove(io, sipsock_read_id); 17679 sipsock_read_id = NULL; 17680 } 17681 } 17682 17683 /* we only want to mark the extenstate updates for destruction 17684 * if the dialog list is being traversed */ 17685 if (!fastrestart) { 17686 markall_extenstate_updates(); 17687 } 17688 17689 restartsearch: 17690 /* Check for interfaces needing to be killed and for pending extension state notifications. */ 17691 ast_mutex_lock(&iflock); 17692 t = time(NULL); 17693 /* don't scan the interface list if it hasn't been a reasonable period 17694 of time since the last time we did it (when MWI is being sent, we can 17695 get back to this point every millisecond or less) 17696 */ 17697 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 17698 /*! \note If we can't get a lock on an interface, skip it and come 17699 * back later. Note that there is the possibility of a deadlock with 17700 * sip_hangup otherwise, because sip_hangup is called with the channel 17701 * locked first, and the iface lock is attempted second. 17702 */ 17703 if (ast_mutex_trylock(&sip->lock)) { 17704 /* make sure to unmark any extension state updates for this pvt so 17705 * they can be sent out when we come back to it. */ 17706 unmark_extenstate_update(sip); 17707 continue; 17708 } 17709 17710 /* since we are iterating through all the sip_pvts here, this is a good place 17711 * to send out extension state updates. */ 17712 check_extenstate_updates(sip); 17713 17714 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 17715 if (sip->rtp && sip->owner && 17716 (sip->owner->_state == AST_STATE_UP) && 17717 !sip->redirip.sin_addr.s_addr && 17718 sip->t38.state != T38_ENABLED) { 17719 if (sip->lastrtptx && 17720 ast_rtp_get_rtpkeepalive(sip->rtp) && 17721 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 17722 /* Need to send an empty RTP packet */ 17723 sip->lastrtptx = time(NULL); 17724 ast_rtp_sendcng(sip->rtp, 0); 17725 } 17726 if (sip->lastrtprx && 17727 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 17728 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 17729 /* Might be a timeout now -- see if we're on hold */ 17730 struct sockaddr_in sin = { 0, }; 17731 ast_rtp_get_peer(sip->rtp, &sin); 17732 if (!ast_test_flag(&sip->flags[1], SIP_PAGE2_CALL_ONHOLD) || 17733 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 17734 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 17735 /* Needs a hangup */ 17736 if (ast_rtp_get_rtptimeout(sip->rtp)) { 17737 while (sip->owner && ast_channel_trylock(sip->owner)) { 17738 DEADLOCK_AVOIDANCE(&sip->lock); 17739 } 17740 if (sip->owner) { 17741 ast_log(LOG_NOTICE, 17742 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 17743 sip->owner->name, 17744 (long) (t - sip->lastrtprx)); 17745 /* Issue a softhangup */ 17746 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 17747 ast_channel_unlock(sip->owner); 17748 /* forget the timeouts for this call, since a hangup 17749 has already been requested and we don't want to 17750 repeatedly request hangups 17751 */ 17752 ast_rtp_set_rtptimeout(sip->rtp, 0); 17753 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 17754 if (sip->vrtp) { 17755 ast_rtp_set_rtptimeout(sip->vrtp, 0); 17756 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 17757 } 17758 } 17759 } 17760 } 17761 } 17762 } 17763 /* If we have sessions that needs to be destroyed, do it now */ 17764 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 17765 !sip->owner) { 17766 ast_mutex_unlock(&sip->lock); 17767 __sip_destroy(sip, 1); 17768 ast_mutex_unlock(&iflock); 17769 usleep(1); 17770 goto restartsearch; 17771 } 17772 ast_mutex_unlock(&sip->lock); 17773 } 17774 ast_mutex_unlock(&iflock); 17775 17776 /* we only want to clear the extension state updates if the dialog list was traversed */ 17777 if (!fastrestart) { 17778 clearmarked_extenstate_updates(); 17779 } 17780 17781 /* XXX TODO The scheduler usage in this module does not have sufficient 17782 * synchronization being done between running the scheduler and places 17783 * scheduling tasks. As it is written, any scheduled item may not run 17784 * any sooner than about 1 second, regardless of whether a sooner time 17785 * was asked for. */ 17786 17787 pthread_testcancel(); 17788 /* Wait for sched or io */ 17789 res = ast_sched_wait(sched); 17790 if ((res < 0) || (res > 1000)) 17791 res = 1000; 17792 /* If we might need to send more mailboxes, don't wait long at all.*/ 17793 if (fastrestart) 17794 res = 1; 17795 res = ast_io_wait(io, res); 17796 if (option_debug && res > 20) 17797 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 17798 ast_mutex_lock(&monlock); 17799 res = ast_sched_runq(sched); 17800 if (option_debug && res >= 20) 17801 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 17802 17803 /* Send MWI notifications to peers - static and cached realtime peers */ 17804 t = time(NULL); 17805 fastrestart = FALSE; 17806 curpeernum = 0; 17807 peer = NULL; 17808 /* Find next peer that needs mwi */ 17809 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 17810 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 17811 fastrestart = TRUE; 17812 lastpeernum = curpeernum; 17813 peer = ASTOBJ_REF(iterator); 17814 }; 17815 curpeernum++; 17816 } while (0) 17817 ); 17818 /* Send MWI to the peer */ 17819 if (peer) { 17820 ASTOBJ_WRLOCK(peer); 17821 sip_send_mwi_to_peer(peer, FALSE); 17822 ASTOBJ_UNLOCK(peer); 17823 ASTOBJ_UNREF(peer,sip_destroy_peer); 17824 } else { 17825 /* Reset where we come from */ 17826 lastpeernum = -1; 17827 } 17828 ast_mutex_unlock(&monlock); 17829 } 17830 /* Never reached */ 17831 return NULL; 17832 17833 }
static int do_proxy_auth | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
char * | header, | |||
char * | respheader, | |||
int | sipmethod, | |||
int | init | |||
) | [static] |
Add authentication on outbound SIP packet.
Definition at line 12872 of file chan_sip.c.
References ast_calloc, ast_log(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::authtries, LOG_DEBUG, option_debug, 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().
12873 { 12874 char digest[1024]; 12875 12876 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 12877 return -2; 12878 12879 p->authtries++; 12880 if (option_debug > 1) 12881 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 12882 memset(digest, 0, sizeof(digest)); 12883 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 12884 /* No way to authenticate */ 12885 return -1; 12886 } 12887 /* Now we have a reply digest */ 12888 p->options->auth = digest; 12889 p->options->authheader = respheader; 12890 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 12891 }
static int do_register_auth | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
char * | header, | |||
char * | respheader | |||
) | [static] |
Authenticate for outbound registration.
Definition at line 12851 of file chan_sip.c.
References append_history, ast_test_flag, ast_verbose(), sip_pvt::authtries, sip_pvt::flags, sip_registry::hostname, sip_pvt::registry, reply_digest(), sip_debug_test_pvt(), SIP_NO_HISTORY, SIP_REGISTER, and transmit_register().
Referenced by handle_response_register().
12852 { 12853 char digest[1024]; 12854 p->authtries++; 12855 memset(digest,0,sizeof(digest)); 12856 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 12857 /* There's nothing to use for authentication */ 12858 /* No digest challenge in request */ 12859 if (sip_debug_test_pvt(p) && p->registry) 12860 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 12861 /* No old challenge */ 12862 return -1; 12863 } 12864 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 12865 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 12866 if (sip_debug_test_pvt(p) && p->registry) 12867 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 12868 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 12869 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 3044 of file chan_sip.c.
References ast_log(), ast_rtp_setnat(), ast_udptl_setnat(), LOG_DEBUG, option_debug, sip_pvt::rtp, sip_pvt::udptl, and sip_pvt::vrtp.
Referenced by check_user_full(), create_addr(), create_addr_from_peer(), sip_alloc(), and transmit_response_using_temp().
03045 { 03046 const char *mode = natflags ? "On" : "Off"; 03047 03048 if (p->rtp) { 03049 if (option_debug) 03050 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 03051 ast_rtp_setnat(p->rtp, natflags); 03052 } 03053 if (p->vrtp) { 03054 if (option_debug) 03055 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 03056 ast_rtp_setnat(p->vrtp, natflags); 03057 } 03058 if (p->udptl) { 03059 if (option_debug) 03060 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 03061 ast_udptl_setnat(p->udptl, natflags); 03062 } 03063 }
static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 17623 of file chan_sip.c.
References ast_strlen_zero(), ast_test_flag, FALSE, sip_peer::flags, sip_peer::lastmsgcheck, sip_peer::mailbox, sip_peer::mwipvt, SIP_PAGE2_SUBSCRIBEMWIONLY, t, and TRUE.
Referenced by do_monitor().
17624 { 17625 time_t t = time(NULL); 17626 17627 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 17628 !peer->mwipvt) { /* We don't have a subscription */ 17629 peer->lastmsgcheck = t; /* Reset timer */ 17630 return FALSE; 17631 } 17632 17633 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 17634 return TRUE; 17635 17636 return FALSE; 17637 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 11685 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
11686 { 11687 switch (mode) { 11688 case SIP_DOMAIN_AUTO: 11689 return "[Automatic]"; 11690 case SIP_DOMAIN_CONFIG: 11691 return "[Configured]"; 11692 } 11693 11694 return ""; 11695 }
static const char * dtmfmode2str | ( | int | mode | ) | [static] |
Convert DTMF mode to printable string.
Definition at line 11458 of file chan_sip.c.
References SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, and SIP_DTMF_RFC2833.
Referenced by _sip_show_peer(), sip_show_channel(), and sip_show_settings().
11459 { 11460 switch (mode) { 11461 case SIP_DTMF_RFC2833: 11462 return "rfc2833"; 11463 case SIP_DTMF_INFO: 11464 return "info"; 11465 case SIP_DTMF_INBAND: 11466 return "inband"; 11467 case SIP_DTMF_AUTO: 11468 return "auto"; 11469 } 11470 return "<error>"; 11471 }
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 8845 of file chan_sip.c.
References sip_peer::addr, ast_device_state_changed(), ast_test_flag, ASTOBJ_CONTAINER_UNLINK, ASTOBJ_UNREF, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, FALSE, sip_peer::flags, manager_event(), sip_peer::name, peerl, sip_peer::portinuri, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, and SIP_PAGE2_SELFDESTRUCT.
Referenced by parse_register_contact(), realtime_peer(), and reg_source_db().
08846 { 08847 struct sip_peer *peer = (struct sip_peer *)data; 08848 08849 if (!peer) /* Hmmm. We have no peer. Weird. */ 08850 return 0; 08851 08852 memset(&peer->addr, 0, sizeof(peer->addr)); 08853 08854 destroy_association(peer); /* remove registration data from storage */ 08855 08856 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08857 register_peer_exten(peer, FALSE); /* Remove regexten */ 08858 peer->expire = -1; 08859 peer->portinuri = 0; 08860 ast_device_state_changed("SIP/%s", peer->name); 08861 08862 /* Do we need to release this peer from memory? 08863 Only for realtime peers and autocreated peers 08864 */ 08865 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 08866 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 08867 struct sip_peer *peer_ptr = peer_ptr; 08868 peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); 08869 if (peer_ptr) { 08870 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08871 } 08872 } 08873 08874 ASTOBJ_UNREF(peer, sip_destroy_peer); 08875 08876 return 0; 08877 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 7759 of file chan_sip.c.
References ast_copy_string(), ast_string_field_set, ast_strlen_zero(), get_header(), get_in_brackets(), SIPBUFSIZE, and strsep().
Referenced by handle_request(), and handle_request_invite().
07760 { 07761 char stripped[SIPBUFSIZE]; 07762 char *c; 07763 07764 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 07765 c = get_in_brackets(stripped); 07766 c = strsep(&c, ";"); /* trim ; and beyond */ 07767 if (!ast_strlen_zero(c)) 07768 ast_string_field_set(p, uri, c); 07769 }
static int finalize_content | ( | struct sip_request * | req | ) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 6469 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), sip_request::content, sip_request::data, sip_request::len, sip_request::lines, and LOG_WARNING.
Referenced by send_request(), and send_response().
06470 { 06471 char clen[10]; 06472 06473 if (req->lines) { 06474 ast_log(LOG_WARNING, "finalize_content() called on a message that has already been finalized\n"); 06475 return -1; 06476 } 06477 06478 snprintf(clen, sizeof(clen), "%zd", strlen(req->content)); 06479 add_header(req, "Content-Length", clen); 06480 06481 if (!ast_strlen_zero(req->content)) { 06482 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n%s", req->content); 06483 req->len += strlen(req->data + req->len); 06484 } 06485 06486 req->lines = !ast_strlen_zero(req->content); 06487 return 0; 06488 }
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 4638 of file chan_sip.c.
References aliases.
Referenced by __get_header(), and add_header().
04639 { 04640 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 04641 static const struct cfalias { 04642 char * const fullname; 04643 char * const shortname; 04644 } aliases[] = { 04645 { "Content-Type", "c" }, 04646 { "Content-Encoding", "e" }, 04647 { "From", "f" }, 04648 { "Call-ID", "i" }, 04649 { "Contact", "m" }, 04650 { "Content-Length", "l" }, 04651 { "Subject", "s" }, 04652 { "To", "t" }, 04653 { "Supported", "k" }, 04654 { "Refer-To", "r" }, 04655 { "Referred-By", "b" }, 04656 { "Allow-Events", "u" }, 04657 { "Event", "o" }, 04658 { "Via", "v" }, 04659 { "Accept-Contact", "a" }, 04660 { "Reject-Contact", "j" }, 04661 { "Request-Disposition", "d" }, 04662 { "Session-Expires", "x" }, 04663 { "Identity", "y" }, 04664 { "Identity-Info", "n" }, 04665 }; 04666 int x; 04667 04668 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04669 if (!strcasecmp(aliases[x].fullname, name)) 04670 return aliases[x].shortname; 04671 04672 return _default; 04673 }
static struct sip_pvt * find_call | ( | struct sip_request * | req, | |
struct sockaddr_in * | sin, | |||
const int | intended_method | |||
) | [static, read] |
Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read.
Definition at line 5189 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), ast_test_flag, sip_pvt::callid, CAN_CREATE_DIALOG, CAN_CREATE_DIALOG_UNSUPPORTED_METHOD, FALSE, sip_pvt::flags, sip_pvt::from, get_header(), gettag(), iflist, iflock, sip_pvt::lock, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, SIP_ACK, sip_alloc(), sip_methods, SIP_NOTIFY, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, and transmit_response_using_temp().
Referenced by sipsock_read().
05190 { 05191 struct sip_pvt *p = NULL; 05192 char *tag = ""; /* note, tag is never NULL */ 05193 char totag[128]; 05194 char fromtag[128]; 05195 const char *callid = get_header(req, "Call-ID"); 05196 const char *from = get_header(req, "From"); 05197 const char *to = get_header(req, "To"); 05198 const char *cseq = get_header(req, "Cseq"); 05199 05200 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 05201 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 05202 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 05203 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 05204 return NULL; /* Invalid packet */ 05205 05206 if (pedanticsipchecking) { 05207 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 05208 we need more to identify a branch - so we have to check branch, from 05209 and to tags to identify a call leg. 05210 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 05211 in sip.conf 05212 */ 05213 if (gettag(req, "To", totag, sizeof(totag))) 05214 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 05215 gettag(req, "From", fromtag, sizeof(fromtag)); 05216 05217 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 05218 05219 if (option_debug > 4 ) 05220 ast_log(LOG_DEBUG, "= Looking for Call ID: %s (Checking %s) --From tag %s --To-tag %s \n", callid, req->method==SIP_RESPONSE ? "To" : "From", fromtag, totag); 05221 } 05222 05223 ast_mutex_lock(&iflock); 05224 for (p = iflist; p; p = p->next) { 05225 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 05226 int found = FALSE; 05227 if (ast_strlen_zero(p->callid)) 05228 continue; 05229 if (req->method == SIP_REGISTER) 05230 found = (!strcmp(p->callid, callid)); 05231 else { 05232 found = !strcmp(p->callid, callid); 05233 if (pedanticsipchecking && found) { 05234 found = ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED) || !strcmp(p->theirtag, tag); 05235 } 05236 } 05237 05238 if (option_debug > 4) 05239 ast_log(LOG_DEBUG, "= %s Their Call ID: %s Their Tag %s Our tag: %s\n", found ? "Found" : "No match", p->callid, p->theirtag, p->tag); 05240 05241 /* If we get a new request within an existing to-tag - check the to tag as well */ 05242 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 05243 if (p->tag[0] == '\0' && totag[0]) { 05244 /* We have no to tag, but they have. Wrong dialog */ 05245 found = FALSE; 05246 } else if (totag[0]) { /* Both have tags, compare them */ 05247 if (strcmp(totag, p->tag)) { 05248 found = FALSE; /* This is not our packet */ 05249 } 05250 } 05251 if (!found && option_debug > 4) 05252 ast_log(LOG_DEBUG, "= 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); 05253 } 05254 if (found) { 05255 /* Found the call */ 05256 ast_mutex_lock(&p->lock); 05257 ast_mutex_unlock(&iflock); 05258 return p; 05259 } 05260 } 05261 ast_mutex_unlock(&iflock); 05262 05263 /* See if the method is capable of creating a dialog */ 05264 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 05265 if (intended_method == SIP_REFER) { 05266 /* We do support REFER, but not outside of a dialog yet */ 05267 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 05268 } else if (intended_method == SIP_NOTIFY) { 05269 /* We do not support out-of-dialog NOTIFY either, 05270 like voicemail notification, so cancel that early */ 05271 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 No subscription"); 05272 } else { 05273 /* Ok, time to create a new SIP dialog object, a pvt */ 05274 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 05275 /* Ok, we've created a dialog, let's go and process it */ 05276 ast_mutex_lock(&p->lock); 05277 } else { 05278 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 05279 getting a dialog from sip_alloc. 05280 05281 Without a dialog we can't retransmit and handle ACKs and all that, but at least 05282 send an error message. 05283 05284 Sorry, we apologize for the inconvienience 05285 */ 05286 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 05287 if (option_debug > 3) 05288 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 05289 } 05290 } 05291 return p; 05292 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 05293 /* A method we do not support, let's take it on the volley */ 05294 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 05295 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 05296 /* This is a request outside of a dialog that we don't know about 05297 ...never reply to an ACK! 05298 */ 05299 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 05300 } 05301 /* We do not respond to responses for dialogs that we don't know about, we just drop 05302 the session quickly */ 05303 05304 return p; 05305 }
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 2594 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02595 { 02596 char last_char = '\0'; 02597 const char *s; 02598 for (s = start; *s && s != lim; last_char = *s++) { 02599 if (*s == '"' && last_char != '\\') 02600 break; 02601 } 02602 return s; 02603 }
static struct sip_peer * find_peer | ( | const char * | peer, | |
struct sockaddr_in * | sin, | |||
int | realtime, | |||
int | devstate_only | |||
) | [static, read] |
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 2956 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
Referenced by _sip_show_peer(), check_user_full(), create_addr(), function_sippeer(), register_verify(), sip_devicestate(), sip_do_debug_peer(), sip_peer_hold(), and update_call_counter().
02957 { 02958 struct sip_peer *p = NULL; 02959 02960 if (peer) 02961 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02962 else 02963 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02964 02965 if (!p && (realtime || devstate_only)) 02966 p = realtime_peer(peer, sin, devstate_only); 02967 02968 return p; 02969 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
const char * | realm | |||
) | [static, read] |
Find authentication for a specific realm.
Definition at line 18485 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
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 |
Also updates req->sdp_start and req->sdp_count to indicate where the SDP lives in the message body.
Definition at line 5525 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_count, sip_request::sdp_start, strcasestr(), and TRUE.
Referenced by handle_request(), handle_request_invite(), handle_response(), and handle_response_invite().
05526 { 05527 const char *content_type; 05528 const char *content_length; 05529 const char *search; 05530 char *boundary; 05531 unsigned int x; 05532 int boundaryisquoted = FALSE; 05533 int found_application_sdp = FALSE; 05534 int found_end_of_headers = FALSE; 05535 05536 content_length = get_header(req, "Content-Length"); 05537 05538 if (!ast_strlen_zero(content_length)) { 05539 if (sscanf(content_length, "%30u", &x) != 1) { 05540 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 05541 return 0; 05542 } 05543 05544 /* Content-Length of zero means there can't possibly be an 05545 SDP here, even if the Content-Type says there is */ 05546 if (x == 0) 05547 return 0; 05548 } 05549 05550 content_type = get_header(req, "Content-Type"); 05551 05552 /* if the body contains only SDP, this is easy */ 05553 if (!strncasecmp(content_type, "application/sdp", 15)) { 05554 req->sdp_start = 0; 05555 req->sdp_count = req->lines; 05556 return req->lines ? 1 : 0; 05557 } 05558 05559 /* if it's not multipart/mixed, there cannot be an SDP */ 05560 if (strncasecmp(content_type, "multipart/mixed", 15)) 05561 return 0; 05562 05563 /* if there is no boundary marker, it's invalid */ 05564 if ((search = strcasestr(content_type, ";boundary="))) 05565 search += 10; 05566 else if ((search = strcasestr(content_type, "; boundary="))) 05567 search += 11; 05568 else 05569 return 0; 05570 05571 if (ast_strlen_zero(search)) 05572 return 0; 05573 05574 /* If the boundary is quoted with ", remove quote */ 05575 if (*search == '\"') { 05576 search++; 05577 boundaryisquoted = TRUE; 05578 } 05579 05580 /* make a duplicate of the string, with two extra characters 05581 at the beginning */ 05582 boundary = ast_strdupa(search - 2); 05583 boundary[0] = boundary[1] = '-'; 05584 /* Remove final quote */ 05585 if (boundaryisquoted) 05586 boundary[strlen(boundary) - 1] = '\0'; 05587 05588 /* search for the boundary marker, the empty line delimiting headers from 05589 sdp part and the end boundry if it exists */ 05590 05591 for (x = 0; x < (req->lines ); x++) { 05592 if(!strncasecmp(req->line[x], boundary, strlen(boundary))){ 05593 if(found_application_sdp && found_end_of_headers){ 05594 req->sdp_count = (x - 1) - req->sdp_start; 05595 return 1; 05596 } 05597 found_application_sdp = FALSE; 05598 } 05599 if(!strcasecmp(req->line[x], "Content-Type: application/sdp")) 05600 found_application_sdp = TRUE; 05601 05602 if(strlen(req->line[x]) == 0 ){ 05603 if(found_application_sdp && !found_end_of_headers){ 05604 req->sdp_start = x; 05605 found_end_of_headers = TRUE; 05606 } 05607 } 05608 } 05609 if(found_application_sdp && found_end_of_headers) { 05610 req->sdp_count = x - req->sdp_start; 05611 return TRUE; 05612 } 05613 return FALSE; 05614 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1795 of file chan_sip.c.
References ast_strlen_zero(), method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_response(), sip_hangup(), and sipsock_read().
01796 { 01797 int i, res = 0; 01798 01799 if (ast_strlen_zero(msg)) 01800 return 0; 01801 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01802 if (method_match(i, msg)) 01803 res = sip_methods[i].id; 01804 } 01805 return res; 01806 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static, read] |
Find subscription type in array.
Definition at line 12175 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
12176 { 12177 int i; 12178 12179 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 12180 if (subscription_types[i].type == subtype) { 12181 return &subscription_types[i]; 12182 } 12183 } 12184 return &subscription_types[0]; 12185 }
static struct sip_user * find_user | ( | const char * | name, | |
int | realtime | |||
) | [static, read] |
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 3035 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
Referenced by check_user_full(), sip_show_user(), and update_call_counter().
03036 { 03037 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 03038 if (!u && realtime) 03039 u = realtime_user(name); 03040 return u; 03041 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 9256 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
static void free_via | ( | struct sip_via * | v | ) | [static] |
Definition at line 5008 of file chan_sip.c.
References ast_free, and sip_via::via.
Referenced by parse_via(), and process_via().
static int func_check_sipdomain | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Dial plan function to check if domain is local.
Definition at line 13208 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.
13209 { 13210 if (ast_strlen_zero(data)) { 13211 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 13212 return -1; 13213 } 13214 if (check_sip_domain(data, NULL, 0)) 13215 ast_copy_string(buf, data, len); 13216 else 13217 buf[0] = '\0'; 13218 return 0; 13219 }
static int func_header_read | ( | struct ast_channel * | chan, | |
char * | function, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Read SIP header (dialplan function).
Definition at line 13144 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(), sip_request::content, sip_request::header, sip_pvt::initreq, LOG_WARNING, sip_tech, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
13145 { 13146 struct sip_pvt *p; 13147 const char *content = NULL; 13148 AST_DECLARE_APP_ARGS(args, 13149 AST_APP_ARG(header); 13150 AST_APP_ARG(number); 13151 ); 13152 int i, number, start = 0; 13153 13154 if (ast_strlen_zero(data)) { 13155 ast_log(LOG_WARNING, "This function requires a header name.\n"); 13156 return -1; 13157 } 13158 13159 ast_channel_lock(chan); 13160 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 13161 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 13162 ast_channel_unlock(chan); 13163 return -1; 13164 } 13165 13166 AST_STANDARD_APP_ARGS(args, data); 13167 if (!args.number) { 13168 number = 1; 13169 } else { 13170 sscanf(args.number, "%30d", &number); 13171 if (number < 1) 13172 number = 1; 13173 } 13174 13175 p = chan->tech_pvt; 13176 13177 /* If there is no private structure, this channel is no longer alive */ 13178 if (!p) { 13179 ast_channel_unlock(chan); 13180 return -1; 13181 } 13182 13183 for (i = 0; i < number; i++) 13184 content = __get_header(&p->initreq, args.header, &start); 13185 13186 if (ast_strlen_zero(content)) { 13187 ast_channel_unlock(chan); 13188 return -1; 13189 } 13190 13191 ast_copy_string(buf, content, len); 13192 ast_channel_unlock(chan); 13193 13194 return 0; 13195 }
static int function_sipchaninfo_read | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
${SIPCHANINFO()} Dialplan function - reads sip channel data
Definition at line 13334 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_inet_ntoa(), ast_log(), sip_pvt::from, LOG_WARNING, sip_pvt::peername, sip_pvt::recv, sip_pvt::sa, sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::uri, and sip_pvt::useragent.
13335 { 13336 struct sip_pvt *p; 13337 13338 *buf = 0; 13339 13340 if (!data) { 13341 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 13342 return -1; 13343 } 13344 13345 ast_channel_lock(chan); 13346 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 13347 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 13348 ast_channel_unlock(chan); 13349 return -1; 13350 } 13351 13352 p = chan->tech_pvt; 13353 13354 /* If there is no private structure, this channel is no longer alive */ 13355 if (!p) { 13356 ast_channel_unlock(chan); 13357 return -1; 13358 } 13359 13360 if (!strcasecmp(data, "peerip")) { 13361 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 13362 } else if (!strcasecmp(data, "recvip")) { 13363 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 13364 } else if (!strcasecmp(data, "from")) { 13365 ast_copy_string(buf, p->from, len); 13366 } else if (!strcasecmp(data, "uri")) { 13367 ast_copy_string(buf, p->uri, len); 13368 } else if (!strcasecmp(data, "useragent")) { 13369 ast_copy_string(buf, p->useragent, len); 13370 } else if (!strcasecmp(data, "peername")) { 13371 ast_copy_string(buf, p->peername, len); 13372 } else if (!strcasecmp(data, "t38passthrough")) { 13373 if (p->t38.state == T38_DISABLED) { 13374 ast_copy_string(buf, "0", len); 13375 } else { /* T38 is offered or enabled in this call */ 13376 ast_copy_string(buf, "1", len); 13377 } 13378 } else { 13379 ast_channel_unlock(chan); 13380 return -1; 13381 } 13382 ast_channel_unlock(chan); 13383 13384 return 0; 13385 }
static int function_sippeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
${SIPPEER()} Dialplan function - reads peer data
Definition at line 13233 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_print_group(), ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::callgroup, sip_peer::capability, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::expire, find_peer(), sip_peer::flags, sip_peer::inUse, sip_peer::language, sip_peer::mailbox, peer_status(), sip_peer::pickupgroup, sip_peer::prefs, sip_peer::regexten, sip_destroy_peer(), SIP_PAGE2_DYNAMIC, strsep(), and sip_peer::useragent.
13234 { 13235 struct sip_peer *peer; 13236 char *colname; 13237 13238 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 13239 *colname++ = '\0'; 13240 else if ((colname = strchr(data, '|'))) 13241 *colname++ = '\0'; 13242 else 13243 colname = "ip"; 13244 13245 if (!(peer = find_peer(data, NULL, 1, 0))) 13246 return -1; 13247 13248 if (!strcasecmp(colname, "ip")) { 13249 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 13250 } else if (!strcasecmp(colname, "status")) { 13251 peer_status(peer, buf, len); 13252 } else if (!strcasecmp(colname, "language")) { 13253 ast_copy_string(buf, peer->language, len); 13254 } else if (!strcasecmp(colname, "regexten")) { 13255 ast_copy_string(buf, peer->regexten, len); 13256 } else if (!strcasecmp(colname, "limit")) { 13257 snprintf(buf, len, "%d", peer->call_limit); 13258 } else if (!strcasecmp(colname, "curcalls")) { 13259 snprintf(buf, len, "%d", peer->inUse); 13260 } else if (!strcasecmp(colname, "accountcode")) { 13261 ast_copy_string(buf, peer->accountcode, len); 13262 } else if (!strcasecmp(colname, "callgroup")) { 13263 ast_print_group(buf, len, &peer->callgroup); 13264 } else if (!strcasecmp(colname, "pickupgroup")) { 13265 ast_print_group(buf, len, &peer->pickupgroup); 13266 } else if (!strcasecmp(colname, "useragent")) { 13267 ast_copy_string(buf, peer->useragent, len); 13268 } else if (!strcasecmp(colname, "mailbox")) { 13269 ast_copy_string(buf, peer->mailbox, len); 13270 } else if (!strcasecmp(colname, "context")) { 13271 ast_copy_string(buf, peer->context, len); 13272 } else if (!strcasecmp(colname, "expire")) { 13273 snprintf(buf, len, "%d", peer->expire); 13274 } else if (!strcasecmp(colname, "dynamic")) { 13275 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 13276 } else if (!strcasecmp(colname, "callerid_name")) { 13277 ast_copy_string(buf, peer->cid_name, len); 13278 } else if (!strcasecmp(colname, "callerid_num")) { 13279 ast_copy_string(buf, peer->cid_num, len); 13280 } else if (!strcasecmp(colname, "codecs")) { 13281 ast_getformatname_multiple(buf, len -1, peer->capability); 13282 } else if (!strncasecmp(colname, "codec[", 6)) { 13283 char *codecnum; 13284 int index = 0, codec = 0; 13285 13286 codecnum = colname + 6; /* move past the '[' */ 13287 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 13288 index = atoi(codecnum); 13289 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 13290 ast_copy_string(buf, ast_getformatname(codec), len); 13291 } else { 13292 buf[0] = '\0'; 13293 } 13294 } else { 13295 buf[0] = '\0'; 13296 } 13297 13298 ASTOBJ_UNREF(peer, sip_destroy_peer); 13299 13300 return 0; 13301 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4830 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04831 { 04832 long val[4]; 04833 int x; 04834 04835 for (x=0; x<4; x++) 04836 val[x] = ast_random(); 04837 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04838 04839 return buf; 04840 }
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 10509 of file chan_sip.c.
References ast_canmatch_extension(), ast_copy_string(), ast_exists_extension(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), context, sip_pvt::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, option_debug, 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().
10510 { 10511 char tmp[256] = "", *c, *a; 10512 struct sip_request *req = oreq ? oreq : &p->initreq; 10513 struct sip_refer *referdata = NULL; 10514 const char *transfer_context = NULL; 10515 10516 if (!p->refer && !sip_refer_allocate(p)) 10517 return -1; 10518 10519 referdata = p->refer; 10520 10521 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 10522 c = get_in_brackets(tmp); 10523 10524 if (pedanticsipchecking) 10525 ast_uri_decode(c); 10526 10527 if (strncasecmp(c, "sip:", 4)) { 10528 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 10529 return -1; 10530 } 10531 c += 4; 10532 if ((a = strchr(c, ';'))) /* Remove arguments */ 10533 *a = '\0'; 10534 10535 if ((a = strchr(c, '@'))) { /* Separate Domain */ 10536 *a++ = '\0'; 10537 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 10538 } 10539 10540 if (sip_debug_test_pvt(p)) 10541 ast_verbose("Looking for %s in %s\n", c, p->context); 10542 10543 if (p->owner) /* Mimic behaviour in res_features.c */ 10544 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 10545 10546 /* By default, use the context in the channel sending the REFER */ 10547 if (ast_strlen_zero(transfer_context)) { 10548 transfer_context = S_OR(p->owner->macrocontext, 10549 S_OR(p->context, default_context)); 10550 } 10551 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 10552 /* This is a blind transfer */ 10553 if (option_debug) 10554 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 10555 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 10556 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 10557 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 10558 referdata->refer_call = NULL; 10559 /* Set new context */ 10560 ast_string_field_set(p, context, transfer_context); 10561 return 0; 10562 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 10563 return 1; 10564 } 10565 10566 return -1; 10567 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 4622 of file chan_sip.c.
References get_body_by_line(), sip_request::len, sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
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 4567 of file chan_sip.c.
References ast_skip_blanks().
Referenced by get_body(), and get_sdp_iterate().
04568 { 04569 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 04570 return ast_skip_blanks(line + nameLen + 1); 04571 04572 return ""; 04573 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 10632 of file chan_sip.c.
References ast_copy_string(), and ast_skip_blanks().
Referenced by check_user_full().
10633 { 10634 const char *end = strchr(input,'<'); /* first_bracket */ 10635 const char *tmp = strchr(input,'"'); /* first quote */ 10636 int bytes = 0; 10637 int maxbytes = outputsize - 1; 10638 10639 if (!end || end == input) /* we require a part in brackets */ 10640 return NULL; 10641 10642 end--; /* move just before "<" */ 10643 10644 if (tmp && tmp <= end) { 10645 /* The quote (tmp) precedes the bracket (end+1). 10646 * Find the matching quote and return the content. 10647 */ 10648 end = strchr(tmp+1, '"'); 10649 if (!end) 10650 return NULL; 10651 bytes = (int) (end - tmp); 10652 /* protect the output buffer */ 10653 if (bytes > maxbytes) 10654 bytes = maxbytes; 10655 ast_copy_string(output, tmp + 1, bytes); 10656 } else { 10657 /* No quoted string, or it is inside brackets. */ 10658 /* clear the empty characters in the begining*/ 10659 input = ast_skip_blanks(input); 10660 /* clear the empty characters in the end */ 10661 while(*end && *end < 33 && end > input) 10662 end--; 10663 if (end >= input) { 10664 bytes = (int) (end - input) + 2; 10665 /* protect the output buffer */ 10666 if (bytes > maxbytes) 10667 bytes = maxbytes; 10668 ast_copy_string(output, input, bytes); 10669 } else 10670 return NULL; 10671 } 10672 return output; 10673 }
static int get_destination | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Find out who the call is for We use the INVITE uri to find out.
Definition at line 10131 of file chan_sip.c.
References ast_canmatch_extension(), ast_copy_string(), 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, context, sip_pvt::domain, exten, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, sip_request::method, option_debug, sip_request::rlPart2, S_OR, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_PAGE2_ALLOWOVERLAP, SIP_REFER, SIP_SUBSCRIBE, strsep(), sip_pvt::subscribecontext, and cfsip_methods::text.
Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().
10132 { 10133 char tmp[256] = "", *uri, *a; 10134 char tmpf[256] = "", *from; 10135 struct sip_request *req; 10136 char *colon; 10137 char *decoded_uri; 10138 10139 req = oreq; 10140 if (!req) 10141 req = &p->initreq; 10142 10143 /* Find the request URI */ 10144 if (req->rlPart2) 10145 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 10146 10147 if (pedanticsipchecking) 10148 ast_uri_decode(tmp); 10149 10150 uri = get_in_brackets(tmp); 10151 10152 if (strncasecmp(uri, "sip:", 4)) { 10153 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 10154 return -1; 10155 } 10156 uri += 4; 10157 10158 /* Now find the From: caller ID and name */ 10159 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 10160 if (!ast_strlen_zero(tmpf)) { 10161 if (pedanticsipchecking) 10162 ast_uri_decode(tmpf); 10163 from = get_in_brackets(tmpf); 10164 } else { 10165 from = NULL; 10166 } 10167 10168 if (!ast_strlen_zero(from)) { 10169 if (strncasecmp(from, "sip:", 4)) { 10170 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 10171 return -1; 10172 } 10173 from += 4; 10174 if ((a = strchr(from, '@'))) 10175 *a++ = '\0'; 10176 else 10177 a = from; /* just a domain */ 10178 from = strsep(&from, ";"); /* Remove userinfo options */ 10179 a = strsep(&a, ";"); /* Remove URI options */ 10180 ast_string_field_set(p, fromdomain, a); 10181 } 10182 10183 /* Skip any options and find the domain */ 10184 10185 /* Get the target domain */ 10186 if ((a = strchr(uri, '@'))) { 10187 *a++ = '\0'; 10188 } else { /* No username part */ 10189 a = uri; 10190 uri = "s"; /* Set extension to "s" */ 10191 } 10192 colon = strchr(a, ':'); /* Remove :port */ 10193 if (colon) 10194 *colon = '\0'; 10195 10196 uri = strsep(&uri, ";"); /* Remove userinfo options */ 10197 a = strsep(&a, ";"); /* Remove URI options */ 10198 10199 ast_string_field_set(p, domain, a); 10200 10201 if (!AST_LIST_EMPTY(&domain_list)) { 10202 char domain_context[AST_MAX_EXTENSION]; 10203 10204 domain_context[0] = '\0'; 10205 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 10206 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 10207 if (option_debug) 10208 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 10209 return -2; 10210 } 10211 } 10212 /* If we have a context defined, overwrite the original context */ 10213 if (!ast_strlen_zero(domain_context)) 10214 ast_string_field_set(p, context, domain_context); 10215 } 10216 10217 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 10218 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) 10219 ast_string_field_set(p, context, p->subscribecontext); 10220 10221 if (sip_debug_test_pvt(p)) 10222 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 10223 10224 /* Since extensions.conf can have unescaped characters, try matching a 10225 * decoded uri in addition to the non-decoded uri. */ 10226 decoded_uri = ast_strdupa(uri); 10227 ast_uri_decode(decoded_uri); 10228 10229 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 10230 if (req->method == SIP_SUBSCRIBE) { 10231 char hint[AST_MAX_EXTENSION]; 10232 int which = 0; 10233 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, uri) || 10234 (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, decoded_uri) && (which = 1))) { 10235 if (!oreq) { 10236 ast_string_field_set(p, exten, which ? decoded_uri : uri); 10237 } 10238 return 0; 10239 } else { 10240 return -1; 10241 } 10242 } else { 10243 int which = 0; 10244 /* Check the dialplan for the username part of the request URI, 10245 the domain will be stored in the SIPDOMAIN variable 10246 Return 0 if we have a matching extension */ 10247 if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) || 10248 (ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) && (which = 1)) || 10249 !strcmp(decoded_uri, ast_pickup_ext())) { 10250 if (!oreq) { 10251 ast_string_field_set(p, exten, which ? decoded_uri : uri); 10252 } 10253 return 0; 10254 } 10255 } 10256 10257 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 10258 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 10259 ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))) || 10260 !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri))) { 10261 return 1; 10262 } 10263 10264 return -1; 10265 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4711 of file chan_sip.c.
References __get_header().
Referenced by __transmit_response(), build_route(), check_auth(), check_user_full(), check_via(), copy_header(), extract_uri(), find_call(), find_sdp(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), gettag(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_register(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_refer(), handle_response_register(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), process_via(), receive_message(), register_verify(), reply_digest(), reqprep(), respprep(), send_request(), send_response(), sip_sipredirect(), sipsock_read(), transmit_fake_auth_response(), transmit_refer(), transmit_response_with_auth(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), and transmit_state_notify().
04712 { 04713 int start = 0; 04714 return __get_header(req, name, &start); 04715 }
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 2616 of file chan_sip.c.
References ast_log(), find_closing_quote(), LOG_WARNING, and parse().
Referenced by 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().
02617 { 02618 const char *parse = tmp; 02619 char *first_bracket; 02620 02621 /* 02622 * Skip any quoted text until we find the part in brackets. 02623 * On any error give up and return the full string. 02624 */ 02625 while ( (first_bracket = strchr(parse, '<')) ) { 02626 char *first_quote = strchr(parse, '"'); 02627 02628 if (!first_quote || first_quote > first_bracket) 02629 break; /* no need to look at quoted part */ 02630 /* the bracket is within quotes, so ignore it */ 02631 parse = find_closing_quote(first_quote + 1, NULL); 02632 if (!*parse) { /* not found, return full string ? */ 02633 /* XXX or be robust and return in-bracket part ? */ 02634 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02635 break; 02636 } 02637 parse++; 02638 } 02639 if (first_bracket) { 02640 char *second_bracket = strchr(first_bracket + 1, '>'); 02641 if (second_bracket) { 02642 *second_bracket = '\0'; 02643 tmp = first_bracket + 1; 02644 } else { 02645 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02646 } 02647 } 02648 return tmp; 02649 }
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 5649 of file chan_sip.c.
References ast_gethostbyname(), ast_log(), ast_strlen_zero(), get_sdp_iterate(), hp, sip_request::len, LOG_WARNING, SDP_AUDIO, sip_request::sdp_start, and SDP_VIDEO.
Referenced by handle_request_invite().
05650 { 05651 const char *m; 05652 const char *c; 05653 int miterator = req->sdp_start; 05654 int citerator = req->sdp_start; 05655 int x = 0; 05656 int numberofports; 05657 int len; 05658 char host[258] = ""; /*Initialize to empty so we will know if we have any input */ 05659 struct ast_hostent audiohp; 05660 struct hostent *hp; 05661 05662 c = get_sdp_iterate(&citerator, req, "c"); 05663 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05664 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05665 /* Continue since there may be a valid host in a c= line specific to the audio stream */ 05666 } 05667 /* We only want the m and c lines for audio */ 05668 for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) { 05669 if ((media == SDP_AUDIO && ((sscanf(m, "audio %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05670 (sscanf(m, "audio %30d RTP/AVP %n", &x, &len) == 1 && len > 0))) || 05671 (media == SDP_VIDEO && ((sscanf(m, "video %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05672 (sscanf(m, "video %30d RTP/AVP %n", &x, &len) == 1 && len > 0)))) { 05673 /* See if there's a c= line for this media stream. 05674 * XXX There is no guarantee that we'll be grabbing the c= line for this 05675 * particular media stream here. However, this is the same logic used in process_sdp. 05676 */ 05677 c = get_sdp_iterate(&citerator, req, "c"); 05678 if (!ast_strlen_zero(c)) { 05679 sscanf(c, "IN IP4 %256s", host); 05680 } 05681 break; 05682 } 05683 } 05684 05685 if (ast_strlen_zero(host) || x == 0) { 05686 ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video"); 05687 return -1; 05688 } 05689 05690 hp = ast_gethostbyname(host, &audiohp); 05691 if (!hp) { 05692 ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video"); 05693 return -1; 05694 } 05695 05696 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 05697 sin->sin_port = htons(x); 05698 return 0; 05699 }
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 11051 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
11052 { 11053 int x; 11054 int y; 11055 11056 buf[0] = '\0'; 11057 y = len - strlen(buf) - 5; 11058 if (y < 0) 11059 y = 0; 11060 for (x=0;x<req->lines;x++) { 11061 strncat(buf, req->line[x], y); /* safe */ 11062 y -= strlen(req->line[x]) + 1; 11063 if (y < 0) 11064 y = 0; 11065 if (y != 0) 11066 strcat(buf, "\n"); /* safe */ 11067 } 11068 return 0; 11069 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 10102 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_verbose(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, sip_debug_test_pvt(), and strsep().
Referenced by handle_request_invite().
10103 { 10104 char tmp[256], *c, *a; 10105 struct sip_request *req; 10106 10107 req = oreq; 10108 if (!req) 10109 req = &p->initreq; 10110 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 10111 if (ast_strlen_zero(tmp)) 10112 return 0; 10113 c = get_in_brackets(tmp); 10114 if (strncasecmp(c, "sip:", 4)) { 10115 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 10116 return -1; 10117 } 10118 c += 4; 10119 a = c; 10120 strsep(&a, "@;"); /* trim anything after @ or ; */ 10121 if (sip_debug_test_pvt(p)) 10122 ast_verbose("RDNIS is %s\n", c); 10123 ast_string_field_set(p, rdnis, c); 10124 10125 return 0; 10126 }
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 10338 of file chan_sip.c.
References ast_copy_string(), ast_exists_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), sip_refer::attendedtransfer, sip_pvt::callid, sip_pvt::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_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(), strcasestr(), sip_pvt::tag, and sip_pvt::theirtag.
Referenced by handle_request_refer().
10339 { 10340 10341 const char *p_referred_by = NULL; 10342 char *h_refer_to = NULL; 10343 char *h_referred_by = NULL; 10344 char *refer_to; 10345 const char *p_refer_to; 10346 char *referred_by_uri = NULL; 10347 char *ptr; 10348 struct sip_request *req = NULL; 10349 const char *transfer_context = NULL; 10350 struct sip_refer *referdata; 10351 10352 10353 req = outgoing_req; 10354 referdata = transferer->refer; 10355 10356 if (!req) 10357 req = &transferer->initreq; 10358 10359 p_refer_to = get_header(req, "Refer-To"); 10360 if (ast_strlen_zero(p_refer_to)) { 10361 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 10362 return -2; /* Syntax error */ 10363 } 10364 h_refer_to = ast_strdupa(p_refer_to); 10365 refer_to = get_in_brackets(h_refer_to); 10366 if (pedanticsipchecking) 10367 ast_uri_decode(refer_to); 10368 10369 if (strncasecmp(refer_to, "sip:", 4)) { 10370 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 10371 return -3; 10372 } 10373 refer_to += 4; /* Skip sip: */ 10374 10375 /* Get referred by header if it exists */ 10376 p_referred_by = get_header(req, "Referred-By"); 10377 if (!ast_strlen_zero(p_referred_by)) { 10378 char *lessthan; 10379 h_referred_by = ast_strdupa(p_referred_by); 10380 if (pedanticsipchecking) 10381 ast_uri_decode(h_referred_by); 10382 10383 /* Store referrer's caller ID name */ 10384 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 10385 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 10386 *(lessthan - 1) = '\0'; /* Space */ 10387 } 10388 10389 referred_by_uri = get_in_brackets(h_referred_by); 10390 if(strncasecmp(referred_by_uri, "sip:", 4)) { 10391 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 10392 referred_by_uri = (char *) NULL; 10393 } else { 10394 referred_by_uri += 4; /* Skip sip: */ 10395 } 10396 } 10397 10398 /* Check for arguments in the refer_to header */ 10399 if ((ptr = strcasestr(refer_to, "replaces="))) { 10400 char *to = NULL, *from = NULL; 10401 10402 /* This is an attended transfer */ 10403 referdata->attendedtransfer = 1; 10404 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 10405 ast_uri_decode(referdata->replaces_callid); 10406 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 10407 *ptr++ = '\0'; 10408 } 10409 10410 if (ptr) { 10411 /* Find the different tags before we destroy the string */ 10412 to = strcasestr(ptr, "to-tag="); 10413 from = strcasestr(ptr, "from-tag="); 10414 } 10415 10416 /* Grab the to header */ 10417 if (to) { 10418 ptr = to + 7; 10419 if ((to = strchr(ptr, '&'))) 10420 *to = '\0'; 10421 if ((to = strchr(ptr, ';'))) 10422 *to = '\0'; 10423 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 10424 } 10425 10426 if (from) { 10427 ptr = from + 9; 10428 if ((to = strchr(ptr, '&'))) 10429 *to = '\0'; 10430 if ((to = strchr(ptr, ';'))) 10431 *to = '\0'; 10432 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 10433 } 10434 10435 if (!strcmp(referdata->replaces_callid, transferer->callid) && 10436 (!pedanticsipchecking || 10437 (!strcmp(referdata->replaces_callid_fromtag, transferer->theirtag) && 10438 !strcmp(referdata->replaces_callid_totag, transferer->tag)))) { 10439 ast_log(LOG_WARNING, "Got an attempt to replace own Call-ID on %s\n", transferer->callid); 10440 return -4; 10441 } 10442 10443 if (option_debug > 1) { 10444 if (!pedanticsipchecking) 10445 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 10446 else 10447 ast_log(LOG_DEBUG,"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>" ); 10448 } 10449 } 10450 10451 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 10452 char *urioption = NULL, *domain; 10453 *ptr++ = '\0'; 10454 10455 if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */ 10456 *urioption++ = '\0'; 10457 10458 domain = ptr; 10459 if ((ptr = strchr(domain, ':'))) /* Remove :port */ 10460 *ptr = '\0'; 10461 10462 /* Save the domain for the dial plan */ 10463 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 10464 if (urioption) 10465 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 10466 } 10467 10468 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 10469 *ptr = '\0'; 10470 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 10471 10472 if (referred_by_uri) { 10473 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 10474 *ptr = '\0'; 10475 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 10476 } else { 10477 referdata->referred_by[0] = '\0'; 10478 } 10479 10480 /* Determine transfer context */ 10481 if (transferer->owner) /* Mimic behaviour in res_features.c */ 10482 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 10483 10484 /* By default, use the context in the channel sending the REFER */ 10485 if (ast_strlen_zero(transfer_context)) { 10486 transfer_context = S_OR(transferer->owner->macrocontext, 10487 S_OR(transferer->context, default_context)); 10488 } 10489 10490 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 10491 10492 /* Either an existing extension or the parking extension */ 10493 if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 10494 if (sip_debug_test_pvt(transferer)) { 10495 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 10496 } 10497 /* We are ready to transfer to the extension */ 10498 return 0; 10499 } 10500 if (sip_debug_test_pvt(transferer)) 10501 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 10502 10503 /* Failure, we can't find this extension */ 10504 return -1; 10505 }
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 10679 of file chan_sip.c.
References ast_copy_string(), and AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
10680 { 10681 char *start; 10682 char *end; 10683 10684 start = strchr(input,':'); 10685 if (!start) { 10686 output[0] = '\0'; 10687 return 0; 10688 } 10689 start++; 10690 10691 /* we found "number" */ 10692 ast_copy_string(output,start,maxlen); 10693 output[maxlen-1] = '\0'; 10694 10695 end = strchr(output,'@'); 10696 if (end) 10697 *end = '\0'; 10698 else 10699 output[0] = '\0'; 10700 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 10701 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 10702 10703 return 0; 10704 }
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 4579 of file chan_sip.c.
References get_body_by_line(), sip_request::len, sip_request::line, sip_request::sdp_count, and sip_request::sdp_start.
Referenced by get_ip_and_port_from_sdp(), and process_sdp().
04580 { 04581 int len = strlen(name); 04582 04583 while (*start < (req->sdp_start + req->sdp_count)) { 04584 const char *r = get_body_by_line(req->line[(*start)++], name, len); 04585 if (r[0] != '\0') 04586 return r; 04587 } 04588 04589 /* if the line was not found, ensure that *start points past the SDP */ 04590 (*start)++; 04591 04592 return ""; 04593 }
static char get_sdp_line | ( | int * | start, | |
int | stop, | |||
struct sip_request * | req, | |||
const char ** | value | |||
) | [static] |
Fetches the next valid SDP line between the 'start' line (inclusive) and the 'stop' line (exclusive). Returns the type ('a', 'c', ...) and matching line in reference 'start' is updated with the next line number.
Definition at line 4600 of file chan_sip.c.
References ast_skip_blanks(), sip_request::line, sip_request::sdp_count, sip_request::sdp_start, and type.
Referenced by process_sdp().
04601 { 04602 char type = '\0'; 04603 const char *line = NULL; 04604 04605 if (stop > (req->sdp_start + req->sdp_count)) { 04606 stop = req->sdp_start + req->sdp_count; 04607 } 04608 04609 while (*start < stop) { 04610 line = req->line[(*start)++]; 04611 if (line[1] == '=') { 04612 type = line[0]; 04613 *value = ast_skip_blanks(line + 2); 04614 break; 04615 } 04616 } 04617 04618 return type; 04619 }
static struct sip_pvt * get_sip_pvt_byid_locked | ( | const char * | callid, | |
const char * | totag, | |||
const char * | fromtag | |||
) | [static, read] |
Lock interface lock and find matching pvt lock.
Definition at line 10269 of file chan_sip.c.
References ast_channel_trylock, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::callid, DEADLOCK_AVOIDANCE, sip_pvt::flags, iflist, iflock, sip_pvt::lock, LOG_DEBUG, match(), sip_pvt::next, option_debug, sip_pvt::owner, SIP_PAGE2_OUTGOING_CALL, sip_pvt::tag, and sip_pvt::theirtag.
Referenced by handle_request_invite(), and local_attended_transfer().
10270 { 10271 struct sip_pvt *sip_pvt_ptr; 10272 10273 ast_mutex_lock(&iflock); 10274 10275 if (option_debug > 3 && totag) { 10276 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 10277 } 10278 10279 /* Search interfaces and find the match */ 10280 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 10281 if (!strcmp(sip_pvt_ptr->callid, callid)) { 10282 int match = 1; 10283 10284 if (option_debug > 3) 10285 ast_log(LOG_DEBUG, "Found call with callid %s (ourtag=%s, theirtag=%s)\n", callid, sip_pvt_ptr->tag, sip_pvt_ptr->theirtag); 10286 10287 /* Go ahead and lock it (and its owner) before returning */ 10288 ast_mutex_lock(&sip_pvt_ptr->lock); 10289 10290 /* Check if tags match. If not, this is not the call we want 10291 * (With a forking SIP proxy, several call legs share the 10292 * call id, but have different tags) 10293 */ 10294 if (pedanticsipchecking) { 10295 /* RFC 3891 10296 * > 3. User Agent Server Behavior: Receiving a Replaces Header 10297 * > The Replaces header contains information used to match an existing 10298 * > SIP dialog (call-id, to-tag, and from-tag). Upon receiving an INVITE 10299 * > with a Replaces header, the User Agent (UA) attempts to match this 10300 * > information with a confirmed or early dialog. The User Agent Server 10301 * > (UAS) matches the to-tag and from-tag parameters as if they were tags 10302 * > present in an incoming request. In other words, the to-tag parameter 10303 * > is compared to the local tag, and the from-tag parameter is compared 10304 * > to the remote tag. 10305 * 10306 * Thus, the totag is always compared to the local tag, regardless if 10307 * this our call is an incoming or outgoing call. 10308 */ 10309 if (ast_strlen_zero(fromtag) || strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, sip_pvt_ptr->tag))) 10310 match = 0; 10311 } 10312 10313 if (!match) { 10314 ast_mutex_unlock(&sip_pvt_ptr->lock); 10315 continue; 10316 } 10317 10318 if (option_debug > 3 && totag) 10319 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 10320 ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL) ? "OUTGOING": "INCOMING", 10321 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 10322 10323 /* deadlock avoidance... */ 10324 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 10325 DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock); 10326 } 10327 break; 10328 } 10329 } 10330 ast_mutex_unlock(&iflock); 10331 if (option_debug > 3 && !sip_pvt_ptr) 10332 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 10333 return sip_pvt_ptr; 10334 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 14843 of file chan_sip.c.
References ast_copy_string(), get_header(), strcasestr(), and strsep().
Referenced by find_call(), handle_request(), handle_request_subscribe(), and handle_response().
14844 { 14845 const char *thetag; 14846 14847 if (!tagbuf) 14848 return NULL; 14849 tagbuf[0] = '\0'; /* reset the buffer */ 14850 thetag = get_header(req, header); 14851 thetag = strcasestr(thetag, ";tag="); 14852 if (thetag) { 14853 thetag += 5; 14854 ast_copy_string(tagbuf, thetag, tagbufsize); 14855 return strsep(&tagbuf, ";"); 14856 } 14857 return NULL; 14858 }
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 18234 of file chan_sip.c.
References ast_clear_flag, ast_copy_string(), ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_true(), ast_variable::lineno, LOG_WARNING, ast_variable::name, 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_G726_NONSTANDARD, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, 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_FORWARD_LOOP_DETECTED, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, 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(), build_user(), and reload_config().
18235 { 18236 int res = 1; 18237 18238 if (!strcasecmp(v->name, "trustrpid")) { 18239 ast_set_flag(&mask[0], SIP_TRUSTRPID); 18240 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 18241 } else if (!strcasecmp(v->name, "sendrpid")) { 18242 ast_set_flag(&mask[0], SIP_SENDRPID); 18243 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 18244 } else if (!strcasecmp(v->name, "g726nonstandard")) { 18245 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 18246 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 18247 } else if (!strcasecmp(v->name, "useclientcode")) { 18248 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 18249 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 18250 } else if (!strcasecmp(v->name, "dtmfmode")) { 18251 ast_set_flag(&mask[0], SIP_DTMF); 18252 ast_clear_flag(&flags[0], SIP_DTMF); 18253 if (!strcasecmp(v->value, "inband")) 18254 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 18255 else if (!strcasecmp(v->value, "rfc2833")) 18256 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 18257 else if (!strcasecmp(v->value, "info")) 18258 ast_set_flag(&flags[0], SIP_DTMF_INFO); 18259 else if (!strcasecmp(v->value, "auto")) 18260 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 18261 else { 18262 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 18263 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 18264 } 18265 } else if (!strcasecmp(v->name, "nat")) { 18266 ast_set_flag(&mask[0], SIP_NAT); 18267 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 18268 if (!strcasecmp(v->value, "never")) { 18269 ast_set_flags_to(&flags[0], SIP_NAT, SIP_NAT_NEVER); 18270 } else if (!strcasecmp(v->value, "route")) { 18271 ast_set_flags_to(&flags[0], SIP_NAT, SIP_NAT_ROUTE); 18272 } else if (ast_false(v->value)) { 18273 ast_set_flags_to(&flags[0], SIP_NAT, SIP_NAT_RFC3581); 18274 } 18275 } else if (!strcasecmp(v->name, "canreinvite")) { 18276 ast_set_flag(&mask[0], SIP_REINVITE); 18277 ast_clear_flag(&flags[0], SIP_REINVITE); 18278 if(ast_true(v->value)) { 18279 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 18280 } else if (!ast_false(v->value)) { 18281 char buf[64]; 18282 char *word, *next = buf; 18283 18284 ast_copy_string(buf, v->value, sizeof(buf)); 18285 while ((word = strsep(&next, ","))) { 18286 if(!strcasecmp(word, "update")) { 18287 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 18288 } else if(!strcasecmp(word, "nonat")) { 18289 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 18290 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 18291 } else { 18292 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 18293 } 18294 } 18295 } 18296 } else if (!strcasecmp(v->name, "insecure")) { 18297 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 18298 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 18299 set_insecure_flags(flags, v->value, v->lineno); 18300 } else if (!strcasecmp(v->name, "progressinband")) { 18301 ast_set_flag(&mask[0], SIP_PROG_INBAND); 18302 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 18303 if (ast_true(v->value)) 18304 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 18305 else if (strcasecmp(v->value, "never")) 18306 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 18307 } else if (!strcasecmp(v->name, "promiscredir")) { 18308 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 18309 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 18310 } else if (!strcasecmp(v->name, "videosupport")) { 18311 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 18312 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 18313 } else if (!strcasecmp(v->name, "allowoverlap")) { 18314 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 18315 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 18316 } else if (!strcasecmp(v->name, "allowsubscribe")) { 18317 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 18318 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 18319 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 18320 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 18321 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 18322 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 18323 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 18324 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 18325 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 18326 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 18327 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 18328 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 18329 #endif 18330 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 18331 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 18332 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 18333 } else if (!strcasecmp(v->name, "buggymwi")) { 18334 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 18335 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 18336 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 18337 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 18338 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 18339 } else if (!strcasecmp(v->name, "forwardloopdetected")) { 18340 ast_set_flag(&mask[1], SIP_PAGE2_FORWARD_LOOP_DETECTED); 18341 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_FORWARD_LOOP_DETECTED); 18342 } else 18343 res = 0; 18344 18345 return res; 18346 }
static int handle_invite_replaces | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug, | |||
int | ignore, | |||
int | seqno, | |||
struct sockaddr_in * | sin, | |||
int * | nounlock | |||
) | [static] |
Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer.
Definition at line 15033 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_do_masquerade(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_quiet_chan(), ast_set_flag, ast_setstate(), ast_state2str(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_call, SIP_DEFER_BYE_ON_TRANSFER, sip_scheddestroy(), ast_channel::tech_pvt, transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), and XMIT_RELIABLE.
Referenced by handle_request_invite().
15034 { 15035 int earlyreplace = 0; 15036 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 15037 struct ast_channel *c = p->owner; /* Our incoming call */ 15038 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 15039 struct ast_channel *targetcall; /* The bridge to the take-over target */ 15040 15041 /* Check if we're in ring state */ 15042 if (replacecall->_state == AST_STATE_RING) 15043 earlyreplace = 1; 15044 15045 /* Check if we have a bridge */ 15046 if (!(targetcall = ast_bridged_channel(replacecall))) { 15047 /* We have no bridge */ 15048 if (!earlyreplace) { 15049 if (option_debug > 1) 15050 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 15051 oneleggedreplace = 1; 15052 } 15053 } 15054 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 15055 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 15056 15057 if (option_debug > 3) { 15058 if (targetcall) 15059 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should bridge to channel %s while hanging up channel %s\n", targetcall->name, replacecall->name); 15060 else 15061 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 15062 } 15063 15064 if (ignore) { 15065 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 15066 /* We should answer something here. If we are here, the 15067 call we are replacing exists, so an accepted 15068 can't harm */ 15069 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 15070 /* Do something more clever here */ 15071 if (c) { 15072 *nounlock = 1; 15073 ast_channel_unlock(c); 15074 } 15075 ast_channel_unlock(replacecall); 15076 ast_mutex_unlock(&p->refer->refer_call->lock); 15077 return 1; 15078 } 15079 if (!c) { 15080 /* What to do if no channel ??? */ 15081 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 15082 transmit_response_reliable(p, "503 Service Unavailable", req); 15083 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 15084 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15085 ast_channel_unlock(replacecall); 15086 ast_mutex_unlock(&p->refer->refer_call->lock); 15087 return 1; 15088 } 15089 append_history(p, "Xfer", "INVITE/Replace received"); 15090 /* We have three channels to play with 15091 channel c: New incoming call 15092 targetcall: Call from PBX to target 15093 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 15094 replacecall: The owner of the previous 15095 We need to masq C into refer_call to connect to 15096 targetcall; 15097 If we are talking to internal audio stream, target call is null. 15098 */ 15099 15100 /* Fake call progress */ 15101 transmit_response(p, "100 Trying", req); 15102 ast_setstate(c, AST_STATE_RING); 15103 15104 /* Masquerade the new call into the referred call to connect to target call 15105 Targetcall is not touched by the masq */ 15106 15107 /* Answer the incoming call and set channel to UP state */ 15108 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 15109 15110 ast_setstate(c, AST_STATE_UP); 15111 15112 /* Stop music on hold and other generators */ 15113 ast_quiet_chan(replacecall); 15114 ast_quiet_chan(targetcall); 15115 if (option_debug > 3) 15116 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 15117 15118 /* Make sure that the masq does not free our PVT for the old call */ 15119 if (! earlyreplace && ! oneleggedreplace ) 15120 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 15121 15122 /* Prepare the masquerade - if this does not happen, we will be gone */ 15123 if(ast_channel_masquerade(replacecall, c)) 15124 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 15125 else if (option_debug > 3) 15126 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 15127 15128 /* C should now be in place of replacecall */ 15129 if (ast_do_masquerade(replacecall)) { 15130 ast_log(LOG_WARNING, "Failed to perform masquerade with INVITE replaces\n"); 15131 } 15132 15133 if (earlyreplace || oneleggedreplace ) { 15134 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 15135 } 15136 15137 ast_setstate(c, AST_STATE_DOWN); 15138 if (option_debug > 3) { 15139 struct ast_channel *test; 15140 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 15141 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 15142 if (replacecall) 15143 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 15144 if (p->owner) { 15145 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 15146 test = ast_bridged_channel(p->owner); 15147 if (test) 15148 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 15149 else 15150 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 15151 } else 15152 ast_log(LOG_DEBUG, " -- No channel yet \n"); 15153 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 15154 } 15155 15156 /* unlock sip pvt and owner so hangup can do its thing */ 15157 ast_channel_unlock(replacecall); 15158 ast_channel_unlock(c); 15159 ast_mutex_unlock(&p->refer->refer_call->lock); 15160 ast_mutex_unlock(&p->lock); 15161 *nounlock = 1; 15162 15163 /* The call should be down with no ast_channel, so hang it up */ 15164 c->tech_pvt = NULL; 15165 ast_hangup(c); 15166 15167 ast_mutex_lock(&p->lock); /* lock PVT structure again after hangup */ 15168 15169 return 0; 15170 }
static int handle_request | ( | 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 17125 of file chan_sip.c.
References __get_header(), __sip_ack(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_skip_blanks(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, DEFAULT_TRANS_TIMEOUT, extract_uri(), FALSE, find_sdp(), FLAG_RESPONSE, sip_pvt::flags, get_header(), gettag(), sip_pvt::glareinvite, 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::header, sip_request::headers, sip_pvt::icseq, cfsip_methods::id, sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lastinvite, sip_pvt::lastmsg, sip_request::len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_request::method, sip_pvt::method, sip_pvt::ocseq, option_debug, sip_pvt::pendinginvite, process_sdp(), sip_pvt::randdata, sip_request::rlPart1, sip_request::rlPart2, sip_pvt::sa, SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_debug_test_pvt(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_PKT_IGNORE_REQ, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_scheddestroy(), SIP_SUBSCRIBE, cfsip_methods::text, sip_pvt::theirtag, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and sip_peer::useragent.
Referenced by process_request_queue(), and sipsock_read().
17126 { 17127 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 17128 relatively static */ 17129 const char *cmd; 17130 const char *cseq; 17131 const char *useragent; 17132 const char *via; 17133 const char *callid; 17134 int via_pos = 0; 17135 int seqno; 17136 int len; 17137 int ignore = FALSE; 17138 int respid; 17139 int res = 0; 17140 int debug = sip_debug_test_pvt(p); 17141 char *e; 17142 int error = 0; 17143 int oldmethod = p->method; 17144 int acked = 0; 17145 17146 /* RFC 3261 - 8.1.1 A valid SIP request must contain To, From, CSeq, Call-ID and Via. 17147 * 8.2.6.2 Response must have To, From, Call-ID CSeq, and Via related to the request, 17148 * so we can check to make sure these fields exist for all requests and responses */ 17149 cseq = get_header(req, "Cseq"); 17150 cmd = req->header[0]; 17151 /* Save the via_pos so we can check later that responses only have 1 Via header */ 17152 via = __get_header(req, "Via", &via_pos); 17153 /* This must exist already because we've called find_call by now */ 17154 callid = get_header(req, "Call-ID"); 17155 17156 /* Must have Cseq */ 17157 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq) || ast_strlen_zero(via)) { 17158 ast_log(LOG_ERROR, "Dropping this SIP message with Call-ID '%s', it's incomplete.\n", callid); 17159 error = 1; 17160 } 17161 if (!error && sscanf(cseq, "%30d%n", &seqno, &len) != 1) { 17162 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 17163 error = 1; 17164 } 17165 if (error) { 17166 if (!p->initreq.headers) /* New call */ 17167 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 17168 return -1; 17169 } 17170 /* Get the command XXX */ 17171 17172 cmd = req->rlPart1; 17173 e = ast_skip_blanks(req->rlPart2); 17174 17175 /* Save useragent of the client */ 17176 useragent = get_header(req, "User-Agent"); 17177 if (!ast_strlen_zero(useragent)) 17178 ast_string_field_set(p, useragent, useragent); 17179 17180 /* Find out SIP method for incoming request */ 17181 if (req->method == SIP_RESPONSE) { /* Response to our request */ 17182 /* Response to our request -- Do some sanity checks */ 17183 if (ast_strlen_zero(e)) { 17184 return 0; 17185 } 17186 if (sscanf(e, "%30d %n", &respid, &len) != 1) { 17187 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 17188 return 0; 17189 } 17190 if (respid <= 0) { 17191 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 17192 return 0; 17193 } 17194 /* RFC 3261 - 8.1.3.3 If more than one Via header field value is present in a reponse 17195 * the UAC SHOULD discard the message. This is not perfect, as it will not catch multiple 17196 * headers joined with a comma. Fixing that would pretty much involve writing a new parser */ 17197 if (!ast_strlen_zero(__get_header(req, "via", &via_pos))) { 17198 ast_log(LOG_WARNING, "Misrouted SIP response '%s' with Call-ID '%s', too many vias\n", e, callid); 17199 return 0; 17200 } 17201 if (!p->initreq.headers) { 17202 if (option_debug) 17203 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we don't know about. Cseq %d Cmd %s\n", seqno, cmd); 17204 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 17205 return 0; 17206 } 17207 if (p->ocseq && (p->ocseq < seqno)) { 17208 if (option_debug) 17209 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 17210 return -1; 17211 } else { 17212 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) { 17213 extract_uri(p, req); 17214 } 17215 handle_response(p, respid, e + len, req, seqno); 17216 } 17217 return 0; 17218 } 17219 17220 /* New SIP request coming in 17221 (could be new request in existing SIP dialog as well...) 17222 */ 17223 17224 p->method = req->method; /* Find out which SIP method they are using */ 17225 if (option_debug > 3) 17226 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 17227 17228 if (p->icseq && (p->icseq > seqno) ) { 17229 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 17230 if (option_debug > 2) 17231 ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 17232 } else { 17233 if (option_debug) 17234 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 17235 if (req->method != SIP_ACK) 17236 transmit_response(p, "500 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 17237 return -1; 17238 } 17239 } else if (p->icseq && 17240 p->icseq == seqno && 17241 req->method != SIP_ACK && 17242 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 17243 /* ignore means "don't do anything with it" but still have to 17244 respond appropriately. We do this if we receive a repeat of 17245 the last sequence number */ 17246 ignore = 2; 17247 ast_set_flag(req, SIP_PKT_IGNORE); 17248 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 17249 if (option_debug > 2) 17250 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 17251 } 17252 17253 if (seqno >= p->icseq) 17254 /* Next should follow monotonically (but not necessarily 17255 incrementally -- thanks again to the genius authors of SIP -- 17256 increasing */ 17257 p->icseq = seqno; 17258 17259 /* Find their tag if we haven't got it */ 17260 if (ast_strlen_zero(p->theirtag)) { 17261 char tag[128]; 17262 17263 gettag(req, "From", tag, sizeof(tag)); 17264 ast_string_field_set(p, theirtag, tag); 17265 } 17266 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 17267 17268 if (pedanticsipchecking) { 17269 /* If this is a request packet without a from tag, it's not 17270 correct according to RFC 3261 */ 17271 /* Check if this a new request in a new dialog with a totag already attached to it, 17272 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 17273 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 17274 /* If this is a first request and it got a to-tag, it is not for us */ 17275 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 17276 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 17277 /* Will cease to exist after ACK */ 17278 } else if (req->method != SIP_ACK) { 17279 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 17280 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17281 } 17282 return res; 17283 } 17284 } 17285 17286 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 17287 transmit_response(p, "400 Bad request", req); 17288 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17289 return -1; 17290 } 17291 17292 /* Handle various incoming SIP methods in requests */ 17293 switch (p->method) { 17294 case SIP_OPTIONS: 17295 res = handle_request_options(p, req); 17296 break; 17297 case SIP_INVITE: 17298 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 17299 break; 17300 case SIP_REFER: 17301 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 17302 break; 17303 case SIP_CANCEL: 17304 res = handle_request_cancel(p, req); 17305 break; 17306 case SIP_BYE: 17307 res = handle_request_bye(p, req); 17308 break; 17309 case SIP_MESSAGE: 17310 res = handle_request_message(p, req); 17311 break; 17312 case SIP_SUBSCRIBE: 17313 res = handle_request_subscribe(p, req, sin, seqno, e); 17314 break; 17315 case SIP_REGISTER: 17316 res = handle_request_register(p, req, sin, e); 17317 break; 17318 case SIP_INFO: 17319 if (ast_test_flag(req, SIP_PKT_DEBUG)) 17320 ast_verbose("Receiving INFO!\n"); 17321 if (!ignore) 17322 handle_request_info(p, req); 17323 else /* if ignoring, transmit response */ 17324 transmit_response(p, "200 OK", req); 17325 break; 17326 case SIP_NOTIFY: 17327 res = handle_request_notify(p, req, sin, seqno, e); 17328 break; 17329 case SIP_ACK: 17330 /* Make sure we don't ignore this */ 17331 if (seqno == p->pendinginvite) { 17332 p->invitestate = INV_TERMINATED; 17333 p->pendinginvite = 0; 17334 acked = __sip_ack(p, seqno, FLAG_RESPONSE, 0); 17335 if (find_sdp(req)) { 17336 if (process_sdp(p, req)) 17337 return -1; 17338 } 17339 check_pendings(p); 17340 } else if (p->glareinvite == seqno) { 17341 /* handle ack for the 491 pending send for glareinvite */ 17342 p->glareinvite = 0; 17343 acked = __sip_ack(p, seqno, 1, 0); 17344 } 17345 if (!acked) { 17346 /* Got an ACK that did not match anything. Ignore 17347 * silently and restore previous method */ 17348 p->method = oldmethod; 17349 } 17350 /* Got an ACK that we did not match. Ignore silently */ 17351 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 17352 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 17353 break; 17354 default: 17355 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 17356 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 17357 cmd, ast_inet_ntoa(p->sa.sin_addr)); 17358 /* If this is some new method, and we don't have a call, destroy it now */ 17359 if (!p->initreq.headers) 17360 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 17361 break; 17362 } 17363 return res; 17364 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 16650 of file chan_sip.c.
References __sip_pretend_ack(), append_history, ast_async_goto(), ast_bridged_channel(), ast_clear_flag, AST_CONTROL_UNHOLD, 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, check_via(), context, sip_pvt::context, copy_request(), DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, get_also_info(), get_header(), sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, 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_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_IGNORE, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp.
Referenced by handle_request().
16651 { 16652 struct ast_channel *c=NULL; 16653 int res; 16654 struct ast_channel *bridged_to; 16655 16656 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 16657 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE)) 16658 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 16659 16660 __sip_pretend_ack(p); 16661 16662 p->invitestate = INV_TERMINATED; 16663 16664 copy_request(&p->initreq, req); 16665 check_via(p, req); 16666 sip_alreadygone(p); 16667 16668 /* Get RTCP quality before end of call */ 16669 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 16670 char *audioqos, *videoqos; 16671 if (p->rtp) { 16672 audioqos = ast_rtp_get_quality(p->rtp, NULL); 16673 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 16674 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 16675 if (p->owner) 16676 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 16677 } 16678 if (p->vrtp) { 16679 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 16680 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 16681 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 16682 if (p->owner) 16683 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 16684 } 16685 } 16686 16687 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 16688 16689 if (!ast_strlen_zero(get_header(req, "Also"))) { 16690 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 16691 ast_inet_ntoa(p->recv.sin_addr)); 16692 if (ast_strlen_zero(p->context)) 16693 ast_string_field_set(p, context, default_context); 16694 res = get_also_info(p, req); 16695 if (!res) { 16696 c = p->owner; 16697 if (c) { 16698 bridged_to = ast_bridged_channel(c); 16699 if (bridged_to) { 16700 /* Don't actually hangup here... */ 16701 ast_queue_control(c, AST_CONTROL_UNHOLD); 16702 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 16703 } else 16704 ast_queue_hangup(p->owner); 16705 } 16706 } else { 16707 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 16708 if (p->owner) 16709 ast_queue_hangup(p->owner); 16710 } 16711 } else if (p->owner) { 16712 ast_queue_hangup(p->owner); 16713 if (option_debug > 2) 16714 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 16715 } else { 16716 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16717 if (option_debug > 2) 16718 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 16719 } 16720 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 16721 transmit_response(p, "200 OK", req); 16722 16723 return 1; 16724 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 16520 of file chan_sip.c.
References __sip_pretend_ack(), ast_channel::_state, ast_free, ast_log(), ast_queue_hangup(), AST_SCHED_DEL, AST_STATE_UP, ast_test_flag, check_via(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_pvt::initreq, INV_CANCELLED, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lastinvite, sip_request::len, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::owner, sip_pvt::packets, sip_pkt::response_code, sip_pkt::retransid, sip_pkt::seqno, sip_alreadygone(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), UNLINK, and update_call_counter().
Referenced by handle_request().
16521 { 16522 16523 check_via(p, req); 16524 sip_alreadygone(p); 16525 16526 /* At this point, we could have cancelled the invite at the same time 16527 as the other side sends a CANCEL. Our final reply with error code 16528 might not have been received by the other side before the CANCEL 16529 was sent, so let's just give up retransmissions and waiting for 16530 ACK on our error code. The call is hanging up any way. */ 16531 if (p->invitestate == INV_TERMINATED) 16532 __sip_pretend_ack(p); 16533 else 16534 p->invitestate = INV_CANCELLED; 16535 16536 if (p->owner && p->owner->_state == AST_STATE_UP) { 16537 /* This call is up, cancel is ignored, we need a bye */ 16538 transmit_response(p, "200 OK", req); 16539 if (option_debug) 16540 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 16541 return 0; 16542 } 16543 16544 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 16545 update_call_counter(p, DEC_CALL_LIMIT); 16546 16547 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 16548 if (p->owner) 16549 ast_queue_hangup(p->owner); 16550 else 16551 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16552 if (p->initreq.len > 0) { 16553 struct sip_pkt *pkt, *prev_pkt; 16554 /* If the CANCEL we are receiving is a retransmission, and we already have scheduled 16555 * a reliable 487, then we don't want to schedule another one on top of the previous 16556 * one. 16557 * 16558 * As odd as this may sound, we can't rely on the previously-transmitted "reliable" 16559 * response in this situation. What if we've sent all of our reliable responses 16560 * already and now all of a sudden, we get this second CANCEL? 16561 * 16562 * The only way to do this correctly is to cancel our previously-scheduled reliably- 16563 * transmitted response and send a new one in its place. 16564 */ 16565 for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->next) { 16566 if (pkt->seqno == p->lastinvite && pkt->response_code == 487) { 16567 AST_SCHED_DEL(sched, pkt->retransid); 16568 UNLINK(pkt, p->packets, prev_pkt); 16569 ast_free(pkt); 16570 break; 16571 } 16572 } 16573 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 16574 transmit_response(p, "200 OK", req); 16575 return 1; 16576 } else { 16577 transmit_response(p, "481 Call Leg Does Not Exist", req); 16578 return 0; 16579 } 16580 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 12540 of file chan_sip.c.
References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, ast_copy_string(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), ast_queue_control(), ast_queue_frame(), ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_pvt::callid, ast_channel::cdr, DEFAULT_TRANS_TIMEOUT, sip_history::event, sip_pvt::flags, get_body(), get_header(), ast_frame::len, LOG_WARNING, sip_pvt::owner, sip_scheddestroy(), SIP_USECLIENTCODE, sipdebug, ast_frame::subclass, and transmit_response().
Referenced by handle_request().
12541 { 12542 char buf[1024]; 12543 unsigned int event; 12544 const char *c = get_header(req, "Content-Type"); 12545 12546 /* Need to check the media/type */ 12547 if (!strcasecmp(c, "application/dtmf-relay") || 12548 !strcasecmp(c, "application/DTMF") || 12549 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 12550 unsigned int duration = 0; 12551 12552 /* Try getting the "signal=" part */ 12553 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 12554 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 12555 transmit_response(p, "200 OK", req); /* Should return error */ 12556 return; 12557 } else { 12558 ast_copy_string(buf, c, sizeof(buf)); 12559 } 12560 12561 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 12562 duration = atoi(c); 12563 if (!duration) 12564 duration = 100; /* 100 ms */ 12565 12566 if (!p->owner) { /* not a PBX call */ 12567 transmit_response(p, "481 Call leg/transaction does not exist", req); 12568 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12569 return; 12570 } 12571 12572 if (ast_strlen_zero(buf)) { 12573 transmit_response(p, "200 OK", req); 12574 return; 12575 } 12576 12577 if (buf[0] == '*') 12578 event = 10; 12579 else if (buf[0] == '#') 12580 event = 11; 12581 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 12582 event = 12 + buf[0] - 'A'; 12583 else 12584 event = atoi(buf); 12585 if (event == 16) { 12586 /* send a FLASH event */ 12587 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 12588 ast_queue_frame(p->owner, &f); 12589 if (sipdebug) 12590 ast_verbose("* DTMF-relay event received: FLASH\n"); 12591 } else { 12592 /* send a DTMF event */ 12593 struct ast_frame f = { AST_FRAME_DTMF, }; 12594 if (event < 10) { 12595 f.subclass = '0' + event; 12596 } else if (event < 11) { 12597 f.subclass = '*'; 12598 } else if (event < 12) { 12599 f.subclass = '#'; 12600 } else if (event < 16) { 12601 f.subclass = 'A' + (event - 12); 12602 } 12603 f.len = duration; 12604 ast_queue_frame(p->owner, &f); 12605 if (sipdebug) 12606 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 12607 } 12608 transmit_response(p, "200 OK", req); 12609 return; 12610 } else if (!strcasecmp(c, "application/media_control+xml")) { 12611 /* Eh, we'll just assume it's a fast picture update for now */ 12612 if (p->owner) 12613 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 12614 transmit_response(p, "200 OK", req); 12615 return; 12616 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 12617 /* Client code (from SNOM phone) */ 12618 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 12619 if (p->owner && p->owner->cdr) 12620 ast_cdr_setuserfield(p->owner, c); 12621 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 12622 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 12623 transmit_response(p, "200 OK", req); 12624 } else { 12625 transmit_response(p, "403 Unauthorized", req); 12626 } 12627 return; 12628 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 12629 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 12630 transmit_response(p, "200 OK", req); 12631 return; 12632 } 12633 12634 /* Other type of INFO message, not really understood by Asterisk */ 12635 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 12636 12637 /* Nothing in the header is interesting, now check if content-length is 0 */ 12638 if (!strcasecmp(get_header(req, "Content-Length"), "0")) { 12639 transmit_response(p, "200 OK", req); 12640 return; 12641 } /* else ... there issomething in the message body, do something with it if you need to */ 12642 12643 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 12644 transmit_response(p, "415 Unsupported media type", req); 12645 return; 12646 }
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.
XXX: we should also check here does the other side supports t38 at all !!! XXX
Definition at line 15449 of file chan_sip.c.
References __sip_ack(), ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), 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_set_flag, ast_setstate(), ast_skip_blanks(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), build_route(), sip_pvt::callid, sip_pvt::capability, change_hold_state(), check_user(), check_via(), context, sip_pvt::context, copy_request(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, exten, sip_pvt::exten, extract_uri(), FALSE, find_sdp(), FLAG_RESPONSE, 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, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_CONFIRMED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::jointcapability, sip_pvt::lastinvite, ast_channel::lock, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), option_debug, sip_pvt::owner, parse_ok_contact(), parse_sip_options(), sip_pvt::peername, sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_request::rlPart2, sip_pvt::rtp, S_OR, SDP_AUDIO, SDP_VIDEO, sip_alreadygone(), sip_cancel_destroy(), SIP_DTMF, SIP_DTMF_RFC2833, sip_handle_t38_reinvite(), SIP_INVITE, sip_new(), SIP_NO_HISTORY, SIP_OPT_REPLACES, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PKT_IGNORE, sip_refer_allocate(), sip_scheddestroy(), sip_tech, sip_tech_info, sip_uri_cmp(), sipdebug, sip_pvt::sipoptions, t38properties::state, strcasestr(), strsep(), sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_PEER_REINVITE, sip_pvt::tag, ast_channel::tech, ast_channel::tech_pvt, transmit_fake_auth_response(), transmit_provisional_response(), transmit_response(), transmit_response_reliable(), 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_request().
15450 { 15451 int res = 1; 15452 int gotdest; 15453 const char *p_replaces; 15454 char *replace_id = NULL; 15455 int refer_locked = 0; 15456 const char *required; 15457 unsigned int required_profile = 0; 15458 struct ast_channel *c = NULL; /* New channel */ 15459 int reinvite = 0; 15460 15461 /* Find out what they support */ 15462 if (!p->sipoptions) { 15463 const char *supported = get_header(req, "Supported"); 15464 if (!ast_strlen_zero(supported)) 15465 parse_sip_options(p, supported); 15466 } 15467 15468 /* Find out what they require */ 15469 required = get_header(req, "Require"); 15470 if (!ast_strlen_zero(required)) { 15471 required_profile = parse_sip_options(NULL, required); 15472 if (required_profile && !(required_profile & SIP_OPT_REPLACES)) { 15473 /* At this point we only support REPLACES */ 15474 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 15475 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 15476 p->invitestate = INV_COMPLETED; 15477 if (!p->lastinvite) 15478 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15479 res = -1; 15480 goto request_invite_cleanup; 15481 } 15482 } 15483 15484 /* Check if this is a loop */ 15485 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->invitestate != INV_TERMINATED && p->invitestate != INV_CONFIRMED)) { 15486 /* This is a call to ourself. Send ourselves an error code and stop 15487 processing immediately, as SIP really has no good mechanism for 15488 being able to call yourself */ 15489 /* If pedantic is on, we need to check the tags. If they're different, this is 15490 in fact a forked call through a SIP proxy somewhere. */ 15491 int different; 15492 if (pedanticsipchecking) 15493 different = sip_uri_cmp(p->initreq.rlPart2, req->rlPart2); 15494 else 15495 different = strcmp(p->initreq.rlPart2, req->rlPart2); 15496 if (!different) { 15497 transmit_response(p, "482 Loop Detected", req); 15498 p->invitestate = INV_COMPLETED; 15499 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15500 res = 0; 15501 goto request_invite_cleanup; 15502 } else { 15503 /* This is a spiral. What we need to do is to just change the outgoing INVITE 15504 * so that it now routes to the new Request URI. Since we created the INVITE ourselves 15505 * that should be all we need to do. 15506 */ 15507 char *uri = ast_strdupa(req->rlPart2); 15508 char *at = strchr(uri, '@'); 15509 char *peerorhost; 15510 if (option_debug > 2) { 15511 ast_log(LOG_DEBUG, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", p->initreq.rlPart2, req->rlPart2); 15512 } 15513 transmit_response(p, "100 Trying", req); 15514 if (at) { 15515 *at = '\0'; 15516 } 15517 /* Parse out "sip:" */ 15518 if ((peerorhost = strchr(uri, ':'))) { 15519 *peerorhost++ = '\0'; 15520 } 15521 ast_string_field_free(p, theirtag); 15522 /* Treat this as if there were a call forward instead... 15523 */ 15524 ast_string_field_set(p->owner, call_forward, peerorhost); 15525 ast_queue_control(p->owner, AST_CONTROL_BUSY); 15526 res = 0; 15527 goto request_invite_cleanup; 15528 } 15529 } 15530 15531 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 15532 if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && (p->invitestate == INV_COMPLETED || p->invitestate == INV_TERMINATED)) { 15533 /* What do these circumstances mean? We have received an INVITE for an "incoming" dialog for which we 15534 * have sent a final response. We have not yet received an ACK, though (which is why p->pendinginvite is non-zero). 15535 * We also know that the INVITE is not a retransmission, because otherwise the "ignore" flag would be set. 15536 * This means that either we are receiving a reinvite for a terminated dialog, or we are receiving an INVITE with 15537 * credentials based on one we challenged earlier. 15538 * 15539 * The action to take in either case is to treat the INVITE as though it contains an implicit ACK for the previous 15540 * transaction. Calling __sip_ack will take care of this by clearing the p->pendinginvite and removing the response 15541 * from the previous transaction from the list of outstanding packets. 15542 */ 15543 __sip_ack(p, p->pendinginvite, FLAG_RESPONSE, 0); 15544 } else { 15545 /* We already have a pending invite. Sorry. You are on hold. */ 15546 p->glareinvite = seqno; 15547 if (p->rtp && find_sdp(req)) { 15548 struct sockaddr_in sin; 15549 if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &sin)) { 15550 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Audio may not work properly on this call.\n"); 15551 } else { 15552 ast_rtp_set_alt_peer(p->rtp, &sin); 15553 } 15554 if (p->vrtp) { 15555 if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &sin)) { 15556 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Video may not work properly on this call.\n"); 15557 } else { 15558 ast_rtp_set_alt_peer(p->vrtp, &sin); 15559 } 15560 } 15561 } 15562 transmit_response_reliable(p, "491 Request Pending", req); 15563 if (option_debug) 15564 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 15565 /* Don't destroy dialog here */ 15566 res = 0; 15567 goto request_invite_cleanup; 15568 } 15569 } 15570 15571 p_replaces = get_header(req, "Replaces"); 15572 if (!ast_strlen_zero(p_replaces)) { 15573 /* We have a replaces header */ 15574 char *ptr; 15575 char *fromtag = NULL; 15576 char *totag = NULL; 15577 char *start, *to; 15578 int error = 0; 15579 15580 if (p->owner) { 15581 if (option_debug > 2) 15582 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 15583 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 15584 /* Do not destroy existing call */ 15585 res = -1; 15586 goto request_invite_cleanup; 15587 } 15588 15589 if (sipdebug && option_debug > 2) 15590 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 15591 /* Create a buffer we can manipulate */ 15592 replace_id = ast_strdupa(p_replaces); 15593 ast_uri_decode(replace_id); 15594 15595 if (!p->refer && !sip_refer_allocate(p)) { 15596 transmit_response_reliable(p, "500 Server Internal Error", req); 15597 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 15598 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15599 p->invitestate = INV_COMPLETED; 15600 res = -1; 15601 goto request_invite_cleanup; 15602 } 15603 15604 /* Todo: (When we find phones that support this) 15605 if the replaces header contains ";early-only" 15606 we can only replace the call in early 15607 stage, not after it's up. 15608 15609 If it's not in early mode, 486 Busy. 15610 */ 15611 15612 /* Skip leading whitespace */ 15613 replace_id = ast_skip_blanks(replace_id); 15614 15615 start = replace_id; 15616 while ( (ptr = strsep(&start, ";")) ) { 15617 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 15618 if ( (to = strcasestr(ptr, "to-tag=") ) ) 15619 totag = to + 7; /* skip the keyword */ 15620 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 15621 fromtag = to + 9; /* skip the keyword */ 15622 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 15623 } 15624 } 15625 15626 if (sipdebug && option_debug > 3) 15627 ast_log(LOG_DEBUG,"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>"); 15628 15629 15630 /* Try to find call that we are replacing 15631 If we have a Replaces header, we need to cancel that call if we succeed with this call 15632 */ 15633 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 15634 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 15635 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 15636 error = 1; 15637 } else { 15638 refer_locked = 1; 15639 } 15640 15641 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 15642 15643 /* The matched call is the call from the transferer to Asterisk . 15644 We want to bridge the bridged part of the call to the 15645 incoming invite, thus taking over the refered call */ 15646 15647 if (p->refer->refer_call == p) { 15648 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 15649 p->refer->refer_call = NULL; 15650 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 15651 error = 1; 15652 } 15653 15654 if (!error && !p->refer->refer_call->owner) { 15655 /* Oops, someting wrong anyway, no owner, no call */ 15656 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 15657 /* Check for better return code */ 15658 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req); 15659 error = 1; 15660 } 15661 15662 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 ) { 15663 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 15664 transmit_response_reliable(p, "603 Declined (Replaces)", req); 15665 error = 1; 15666 } 15667 15668 if (error) { /* Give up this dialog */ 15669 append_history(p, "Xfer", "INVITE/Replace Failed."); 15670 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15671 ast_mutex_unlock(&p->lock); 15672 if (p->refer->refer_call) { 15673 ast_mutex_unlock(&p->refer->refer_call->lock); 15674 if (p->refer->refer_call->owner) { 15675 ast_channel_unlock(p->refer->refer_call->owner); 15676 } 15677 } 15678 refer_locked = 0; 15679 p->invitestate = INV_COMPLETED; 15680 res = -1; 15681 goto request_invite_cleanup; 15682 } 15683 } 15684 15685 15686 /* Check if this is an INVITE that sets up a new dialog or 15687 a re-invite in an existing dialog */ 15688 15689 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 15690 int newcall = (p->initreq.headers ? TRUE : FALSE); 15691 15692 if (sip_cancel_destroy(p)) 15693 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15694 /* This also counts as a pending invite */ 15695 p->pendinginvite = seqno; 15696 check_via(p, req); 15697 15698 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 15699 if (!p->owner) { /* Not a re-invite */ 15700 if (debug) 15701 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 15702 if (newcall) 15703 append_history(p, "Invite", "New call: %s", p->callid); 15704 parse_ok_contact(p, req); 15705 } else { /* Re-invite on existing call */ 15706 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 15707 /* Handle SDP here if we already have an owner */ 15708 if (find_sdp(req)) { 15709 if (process_sdp(p, req)) { 15710 transmit_response_reliable(p, "488 Not acceptable here", req); 15711 if (!p->lastinvite) 15712 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15713 res = -1; 15714 goto request_invite_cleanup; 15715 } 15716 ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE); 15717 } else { 15718 p->jointcapability = p->capability; 15719 if (option_debug > 2) 15720 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 15721 /* Some devices signal they want to be put off hold by sending a re-invite 15722 *without* an SDP, which is supposed to mean "Go back to your state" 15723 and since they put os on remote hold, we go back to off hold */ 15724 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 15725 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 15726 /* Activate a re-invite */ 15727 ast_queue_frame(p->owner, &ast_null_frame); 15728 change_hold_state(p, req, FALSE, 0); 15729 } 15730 } 15731 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 15732 append_history(p, "ReInv", "Re-invite received"); 15733 } 15734 } else if (debug) 15735 ast_verbose("Ignoring this INVITE request\n"); 15736 15737 15738 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 15739 /* This is a new invite */ 15740 /* Handle authentication if this is our first invite */ 15741 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 15742 if (res == AUTH_CHALLENGE_SENT) { 15743 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 15744 res = 0; 15745 goto request_invite_cleanup; 15746 } 15747 if (res < 0) { /* Something failed in authentication */ 15748 if (res == AUTH_FAKE_AUTH) { 15749 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 15750 transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE); 15751 } else { 15752 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 15753 transmit_response_reliable(p, "403 Forbidden", req); 15754 } 15755 p->invitestate = INV_COMPLETED; 15756 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15757 ast_string_field_free(p, theirtag); 15758 res = 0; 15759 goto request_invite_cleanup; 15760 15761 } 15762 15763 /* We have a succesful authentication, process the SDP portion if there is one */ 15764 if (find_sdp(req)) { 15765 if (process_sdp(p, req)) { 15766 /* Unacceptable codecs */ 15767 transmit_response_reliable(p, "488 Not acceptable here", req); 15768 p->invitestate = INV_COMPLETED; 15769 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15770 if (option_debug) 15771 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 15772 res = -1; 15773 goto request_invite_cleanup; 15774 } 15775 } else { /* No SDP in invite, call control session */ 15776 p->jointcapability = p->capability; 15777 if (option_debug > 1) 15778 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 15779 } 15780 15781 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 15782 /* This seems redundant ... see !p-owner above */ 15783 if (p->owner) 15784 ast_queue_frame(p->owner, &ast_null_frame); 15785 15786 15787 /* Initialize the context if it hasn't been already */ 15788 if (ast_strlen_zero(p->context)) 15789 ast_string_field_set(p, context, default_context); 15790 15791 15792 /* Check number of concurrent calls -vs- incoming limit HERE */ 15793 if (option_debug) 15794 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 15795 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 15796 if (res < 0) { 15797 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 15798 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 15799 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15800 p->invitestate = INV_COMPLETED; 15801 } 15802 res = 0; 15803 goto request_invite_cleanup; 15804 } 15805 gotdest = get_destination(p, NULL); /* Get destination right away */ 15806 get_rdnis(p, NULL); /* Get redirect information */ 15807 extract_uri(p, req); /* Get the Contact URI */ 15808 build_contact(p); /* Build our contact header */ 15809 15810 if (p->rtp) { 15811 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 15812 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 15813 } 15814 15815 if (!replace_id && gotdest) { /* No matching extension found */ 15816 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 15817 transmit_response_reliable(p, "484 Address Incomplete", req); 15818 else { 15819 char *decoded_exten = ast_strdupa(p->exten); 15820 15821 transmit_response_reliable(p, "404 Not Found", req); 15822 ast_uri_decode(decoded_exten); 15823 ast_log(LOG_NOTICE, "Call from '%s' to extension" 15824 " '%s' rejected because extension not found.\n", 15825 S_OR(p->username, p->peername), decoded_exten); 15826 } 15827 p->invitestate = INV_COMPLETED; 15828 update_call_counter(p, DEC_CALL_LIMIT); 15829 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15830 res = 0; 15831 goto request_invite_cleanup; 15832 } else { 15833 /* If no extension was specified, use the s one */ 15834 /* Basically for calling to IP/Host name only */ 15835 if (ast_strlen_zero(p->exten)) 15836 ast_string_field_set(p, exten, "s"); 15837 /* Initialize our tag */ 15838 15839 make_our_tag(p->tag, sizeof(p->tag)); 15840 /* First invitation - create the channel */ 15841 c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL)); 15842 *recount = 1; 15843 15844 /* Save Record-Route for any later requests we make on this dialogue */ 15845 build_route(p, req, 0); 15846 15847 if (c) { 15848 /* Pre-lock the call */ 15849 ast_channel_lock(c); 15850 } 15851 } 15852 } else { 15853 if (option_debug > 1 && sipdebug) { 15854 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 15855 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 15856 else 15857 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 15858 } 15859 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 15860 reinvite = 1; 15861 c = p->owner; 15862 } 15863 15864 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 15865 p->lastinvite = seqno; 15866 15867 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 15868 /* Go and take over the target call */ 15869 if (sipdebug && option_debug > 3) 15870 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 15871 15872 res = handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin, nounlock); 15873 refer_locked = 0; 15874 goto request_invite_cleanup; 15875 } 15876 15877 15878 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 15879 enum ast_channel_state c_state = c->_state; 15880 15881 if (c_state != AST_STATE_UP && reinvite && 15882 (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) { 15883 /* If these conditions are true, and the channel is still in the 'ringing' 15884 * state, then this likely means that we have a situation where the initial 15885 * INVITE transaction has completed *but* the channel's state has not yet been 15886 * changed to UP. The reason this could happen is if the reinvite is received 15887 * on the SIP socket prior to an application calling ast_read on this channel 15888 * to read the answer frame we earlier queued on it. In this case, the reinvite 15889 * is completely legitimate so we need to handle this the same as if the channel 15890 * were already UP. Thus we are purposely falling through to the AST_STATE_UP case. 15891 */ 15892 c_state = AST_STATE_UP; 15893 } 15894 15895 switch(c_state) { 15896 case AST_STATE_DOWN: 15897 if (option_debug > 1) 15898 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 15899 transmit_provisional_response(p, "100 Trying", req, 0); 15900 p->invitestate = INV_PROCEEDING; 15901 ast_setstate(c, AST_STATE_RING); 15902 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 15903 enum ast_pbx_result res; 15904 15905 res = ast_pbx_start(c); 15906 15907 switch(res) { 15908 case AST_PBX_FAILED: 15909 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 15910 p->invitestate = INV_COMPLETED; 15911 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15912 transmit_response(p, "503 Unavailable", req); 15913 else 15914 transmit_response_reliable(p, "503 Unavailable", req); 15915 break; 15916 case AST_PBX_CALL_LIMIT: 15917 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 15918 p->invitestate = INV_COMPLETED; 15919 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15920 transmit_response(p, "480 Temporarily Unavailable", req); 15921 else 15922 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 15923 break; 15924 case AST_PBX_SUCCESS: 15925 /* nothing to do */ 15926 break; 15927 } 15928 15929 if (res) { 15930 15931 /* Unlock locks so ast_hangup can do its magic */ 15932 ast_mutex_unlock(&c->lock); 15933 *nounlock = 1; 15934 ast_mutex_unlock(&p->lock); 15935 ast_hangup(c); 15936 ast_mutex_lock(&p->lock); 15937 c = NULL; 15938 } 15939 } else { /* Pickup call in call group */ 15940 ast_channel_unlock(c); 15941 *nounlock = 1; 15942 ast_mutex_unlock(&p->lock); 15943 if (ast_pickup_call(c)) { 15944 ast_mutex_lock(&p->lock); 15945 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 15946 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15947 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 15948 else 15949 transmit_response_reliable(p, "503 Unavailable", req); 15950 sip_alreadygone(p); 15951 /* Unlock locks so ast_hangup can do its magic */ 15952 ast_mutex_unlock(&p->lock); 15953 c->hangupcause = AST_CAUSE_CALL_REJECTED; 15954 } else { 15955 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 15956 } 15957 ast_hangup(c); 15958 ast_mutex_lock(&p->lock); 15959 p->invitestate = INV_COMPLETED; 15960 c = NULL; 15961 } 15962 break; 15963 case AST_STATE_RING: 15964 transmit_provisional_response(p, "100 Trying", req, 0); 15965 p->invitestate = INV_PROCEEDING; 15966 break; 15967 case AST_STATE_RINGING: 15968 transmit_provisional_response(p, "180 Ringing", req, 0); 15969 p->invitestate = INV_PROCEEDING; 15970 break; 15971 case AST_STATE_UP: 15972 if (option_debug > 1) 15973 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 15974 15975 transmit_response(p, "100 Trying", req); 15976 15977 if (p->t38.state == T38_PEER_REINVITE) { 15978 struct ast_channel *bridgepeer = NULL; 15979 struct sip_pvt *bridgepvt = NULL; 15980 15981 if ((bridgepeer = ast_bridged_channel(p->owner))) { 15982 /* We have a bridge, and this is re-invite to switchover to T38 so we send re-invite with T38 SDP, to other side of bridge*/ 15983 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 15984 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 15985 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 15986 if (bridgepvt->t38.state == T38_DISABLED) { 15987 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 15988 /* Send re-invite to the bridged channel */ 15989 sip_handle_t38_reinvite(bridgepeer, p, 1); 15990 } else { /* Something is wrong with peers udptl struct */ 15991 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 15992 ast_mutex_lock(&bridgepvt->lock); 15993 bridgepvt->t38.state = T38_DISABLED; 15994 ast_mutex_unlock(&bridgepvt->lock); 15995 if (option_debug > 1) 15996 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 15997 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15998 transmit_response(p, "488 Not acceptable here", req); 15999 else 16000 transmit_response_reliable(p, "488 Not acceptable here", req); 16001 16002 } 16003 } else { 16004 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 16005 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 16006 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 16007 p->t38.state = T38_ENABLED; 16008 if (option_debug) 16009 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 16010 } 16011 } else { 16012 /* Other side is not a SIP channel */ 16013 if (ast_test_flag(req, SIP_PKT_IGNORE)) 16014 transmit_response(p, "488 Not acceptable here", req); 16015 else 16016 transmit_response_reliable(p, "488 Not acceptable here", req); 16017 p->t38.state = T38_DISABLED; 16018 if (option_debug > 1) 16019 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 16020 16021 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 16022 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16023 } 16024 } else { 16025 /* we are not bridged in a call */ 16026 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 16027 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 16028 p->t38.state = T38_ENABLED; 16029 if (option_debug) 16030 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 16031 } 16032 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 16033 /* If this is not a re-invite or something to ignore - it's critical */ 16034 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 16035 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 16036 } 16037 p->invitestate = INV_TERMINATED; 16038 break; 16039 default: 16040 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 16041 transmit_response(p, "100 Trying", req); 16042 break; 16043 } 16044 } else { 16045 if (p && (p->autokillid == -1)) { 16046 const char *msg; 16047 16048 if (!p->jointcapability) 16049 msg = "488 Not Acceptable Here (codec error)"; 16050 else { 16051 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 16052 msg = "503 Unavailable"; 16053 } 16054 if (ast_test_flag(req, SIP_PKT_IGNORE)) 16055 transmit_response(p, msg, req); 16056 else 16057 transmit_response_reliable(p, msg, req); 16058 p->invitestate = INV_COMPLETED; 16059 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16060 } 16061 } 16062 return res; 16063 16064 request_invite_cleanup: 16065 16066 if (refer_locked && p->refer && p->refer->refer_call) { 16067 ast_mutex_unlock(&p->refer->refer_call->lock); 16068 if (p->refer->refer_call->owner) { 16069 ast_channel_unlock(p->refer->refer_call->owner); 16070 } 16071 } 16072 16073 return res; 16074 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 16727 of file chan_sip.c.
References ast_test_flag, ast_verbose(), receive_message(), SIP_PKT_DEBUG, SIP_PKT_IGNORE, and transmit_response().
Referenced by handle_request().
16728 { 16729 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 16730 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16731 ast_verbose("Receiving message!\n"); 16732 receive_message(p, req); 16733 } else 16734 transmit_response(p, "202 Accepted", req); 16735 return 1; 16736 }
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 14861 of file chan_sip.c.
References ast_log(), ast_skip_blanks(), sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), get_msg_text(), sip_pvt::lastinvite, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_scheddestroy(), sipdebug, transmit_response(), and TRUE.
Referenced by handle_request().
14862 { 14863 /* This is mostly a skeleton for future improvements */ 14864 /* Mostly created to return proper answers on notifications on outbound REFER's */ 14865 int res = 0; 14866 const char *event = get_header(req, "Event"); 14867 char *eventid = NULL; 14868 char *sep; 14869 14870 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 14871 *sep++ = '\0'; 14872 eventid = sep; 14873 } 14874 14875 if (option_debug > 1 && sipdebug) 14876 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 14877 14878 if (strcmp(event, "refer")) { 14879 /* We don't understand this event. */ 14880 /* Here's room to implement incoming voicemail notifications :-) */ 14881 transmit_response(p, "489 Bad event", req); 14882 res = -1; 14883 } else { 14884 /* Save nesting depth for now, since there might be other events we will 14885 support in the future */ 14886 14887 /* Handle REFER notifications */ 14888 14889 char buf[1024]; 14890 char *cmd, *code; 14891 int respcode; 14892 int success = TRUE; 14893 14894 /* EventID for each transfer... EventID is basically the REFER cseq 14895 14896 We are getting notifications on a call that we transfered 14897 We should hangup when we are getting a 200 OK in a sipfrag 14898 Check if we have an owner of this event */ 14899 14900 /* Check the content type */ 14901 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 14902 /* We need a sipfrag */ 14903 transmit_response(p, "400 Bad request", req); 14904 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14905 return -1; 14906 } 14907 14908 /* Get the text of the attachment */ 14909 if (get_msg_text(buf, sizeof(buf), req)) { 14910 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 14911 transmit_response(p, "400 Bad request", req); 14912 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14913 return -1; 14914 } 14915 14916 /* 14917 From the RFC... 14918 A minimal, but complete, implementation can respond with a single 14919 NOTIFY containing either the body: 14920 SIP/2.0 100 Trying 14921 14922 if the subscription is pending, the body: 14923 SIP/2.0 200 OK 14924 if the reference was successful, the body: 14925 SIP/2.0 503 Service Unavailable 14926 if the reference failed, or the body: 14927 SIP/2.0 603 Declined 14928 14929 if the REFER request was accepted before approval to follow the 14930 reference could be obtained and that approval was subsequently denied 14931 (see Section 2.4.7). 14932 14933 If there are several REFERs in the same dialog, we need to 14934 match the ID of the event header... 14935 */ 14936 if (option_debug > 2) 14937 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 14938 cmd = ast_skip_blanks(buf); 14939 code = cmd; 14940 /* We are at SIP/2.0 */ 14941 while(*code && (*code > 32)) { /* Search white space */ 14942 code++; 14943 } 14944 *code++ = '\0'; 14945 code = ast_skip_blanks(code); 14946 sep = code; 14947 sep++; 14948 while(*sep && (*sep > 32)) { /* Search white space */ 14949 sep++; 14950 } 14951 *sep++ = '\0'; /* Response string */ 14952 respcode = atoi(code); 14953 switch (respcode) { 14954 case 100: /* Trying: */ 14955 case 101: /* dialog establishment */ 14956 /* Don't do anything yet */ 14957 break; 14958 case 183: /* Ringing: */ 14959 /* Don't do anything yet */ 14960 break; 14961 case 200: /* OK: The new call is up, hangup this call */ 14962 /* Hangup the call that we are replacing */ 14963 break; 14964 case 301: /* Moved permenantly */ 14965 case 302: /* Moved temporarily */ 14966 /* Do we get the header in the packet in this case? */ 14967 success = FALSE; 14968 break; 14969 case 503: /* Service Unavailable: The new call failed */ 14970 /* Cancel transfer, continue the call */ 14971 success = FALSE; 14972 break; 14973 case 603: /* Declined: Not accepted */ 14974 /* Cancel transfer, continue the current call */ 14975 success = FALSE; 14976 break; 14977 } 14978 if (!success) { 14979 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 14980 } 14981 14982 /* Confirm that we received this packet */ 14983 transmit_response(p, "200 OK", req); 14984 }; 14985 14986 if (!p->lastinvite) 14987 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14988 14989 return res; 14990 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 14993 of file chan_sip.c.
References ast_shutting_down(), ast_string_field_set, ast_strlen_zero(), build_contact(), context, sip_pvt::context, DEFAULT_TRANS_TIMEOUT, get_destination(), sip_pvt::lastinvite, sip_scheddestroy(), and transmit_response_with_allow().
Referenced by handle_request().
14994 { 14995 int res; 14996 14997 14998 /* XXX Should we authenticate OPTIONS? XXX */ 14999 15000 if (p->lastinvite) { 15001 /* if this is a request in an active dialog, just confirm that the dialog exists. */ 15002 transmit_response_with_allow(p, "200 OK", req, 0); 15003 return 0; 15004 } 15005 15006 res = get_destination(p, req); 15007 build_contact(p); 15008 15009 if (ast_strlen_zero(p->context)) 15010 ast_string_field_set(p, context, default_context); 15011 15012 if (ast_shutting_down()) 15013 transmit_response_with_allow(p, "503 Unavailable", req, 0); 15014 else if (res < 0) 15015 transmit_response_with_allow(p, "404 Not Found", req, 0); 15016 else 15017 transmit_response_with_allow(p, "200 OK", req, 0); 15018 15019 /* Destroy if this OPTIONS was the opening request, but not if 15020 it's in the middle of a normal call flow. */ 15021 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15022 15023 return res; 15024 }
static int handle_request_refer | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug, | |||
int | ignore, | |||
int | seqno, | |||
int * | nounlock | |||
) | [static] |
Definition at line 16243 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_indicate(), AST_LIST_EMPTY, ast_log(), 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(), context, sip_pvt::context, copy_request(), FALSE, sip_pvt::flags, get_refer_info(), ast_channel::hangupcause, local_attended_transfer(), sip_refer::localtransfer, LOG_DEBUG, option_debug, 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_NEEDDESTROY, SIP_OUTGOING, sip_park(), SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_refer_allocate(), SIPBUFSIZE, sipdebug, sip_refer::status, TRANSFER_CLOSED, transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by handle_request().
16244 { 16245 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 16246 /* Chan2: Call between asterisk and transferee */ 16247 16248 int res = 0; 16249 16250 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16251 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"); 16252 16253 if (!p->owner) { 16254 /* This is a REFER outside of an existing SIP dialog */ 16255 /* We can't handle that, so decline it */ 16256 if (option_debug > 2) 16257 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 16258 transmit_response(p, "603 Declined (No dialog)", req); 16259 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 16260 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 16261 sip_alreadygone(p); 16262 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16263 } 16264 return 0; 16265 } 16266 16267 16268 /* Check if transfer is allowed from this device */ 16269 if (p->allowtransfer == TRANSFER_CLOSED ) { 16270 /* Transfer not allowed, decline */ 16271 transmit_response(p, "603 Declined (policy)", req); 16272 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 16273 /* Do not destroy SIP session */ 16274 return 0; 16275 } 16276 16277 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 16278 /* Already have a pending REFER */ 16279 transmit_response(p, "491 Request pending", req); 16280 append_history(p, "Xfer", "Refer failed. Request pending."); 16281 return 0; 16282 } 16283 16284 /* Allocate memory for call transfer data */ 16285 if (!p->refer && !sip_refer_allocate(p)) { 16286 transmit_response(p, "500 Internal Server Error", req); 16287 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 16288 return -3; 16289 } 16290 16291 res = get_refer_info(p, req); /* Extract headers */ 16292 16293 p->refer->status = REFER_SENT; 16294 16295 if (res != 0) { 16296 switch (res) { 16297 case -2: /* Syntax error */ 16298 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 16299 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 16300 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 16301 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 16302 break; 16303 case -3: 16304 transmit_response(p, "603 Declined (Non sip: uri)", req); 16305 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 16306 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 16307 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 16308 break; 16309 default: 16310 /* Refer-to extension not found, fake a failed transfer */ 16311 transmit_response(p, "202 Accepted", req); 16312 append_history(p, "Xfer", "Refer failed. Bad extension."); 16313 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 16314 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 16315 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 16316 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 16317 break; 16318 } 16319 return 0; 16320 } 16321 if (ast_strlen_zero(p->context)) 16322 ast_string_field_set(p, context, default_context); 16323 16324 /* If we do not support SIP domains, all transfers are local */ 16325 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 16326 p->refer->localtransfer = 1; 16327 if (sipdebug && option_debug > 2) 16328 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 16329 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 16330 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 16331 p->refer->localtransfer = 1; 16332 } else if (sipdebug && option_debug > 2) 16333 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 16334 16335 /* Is this a repeat of a current request? Ignore it */ 16336 /* Don't know what else to do right now. */ 16337 if (ignore) 16338 return res; 16339 16340 /* If this is a blind transfer, we have the following 16341 channels to work with: 16342 - chan1, chan2: The current call between transferer and transferee (2 channels) 16343 - target_channel: A new call from the transferee to the target (1 channel) 16344 We need to stay tuned to what happens in order to be able 16345 to bring back the call to the transferer */ 16346 16347 /* If this is a attended transfer, we should have all call legs within reach: 16348 - chan1, chan2: The call between the transferer and transferee (2 channels) 16349 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 16350 We want to bridge chan2 with targetcall_pvt! 16351 16352 The replaces call id in the refer message points 16353 to the call leg between Asterisk and the transferer. 16354 So we need to connect the target and the transferee channel 16355 and hangup the two other channels silently 16356 16357 If the target is non-local, the call ID could be on a remote 16358 machine and we need to send an INVITE with replaces to the 16359 target. We basically handle this as a blind transfer 16360 and let the sip_call function catch that we need replaces 16361 header in the INVITE. 16362 */ 16363 16364 16365 /* Get the transferer's channel */ 16366 current.chan1 = p->owner; 16367 16368 /* Find the other part of the bridge (2) - transferee */ 16369 current.chan2 = ast_bridged_channel(current.chan1); 16370 16371 if (sipdebug && option_debug > 2) 16372 ast_log(LOG_DEBUG, "SIP %s transfer: Transferer channel %s, transferee channel %s\n", p->refer->attendedtransfer ? "attended" : "blind", current.chan1->name, current.chan2 ? current.chan2->name : "<none>"); 16373 16374 if (!current.chan2 && !p->refer->attendedtransfer) { 16375 /* No bridged channel, propably IVR or echo or similar... */ 16376 /* Guess we should masquerade or something here */ 16377 /* Until we figure it out, refuse transfer of such calls */ 16378 if (sipdebug && option_debug > 2) 16379 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 16380 p->refer->status = REFER_FAILED; 16381 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 16382 transmit_response(p, "603 Declined", req); 16383 return -1; 16384 } 16385 16386 if (current.chan2) { 16387 if (sipdebug && option_debug > 3) 16388 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 16389 16390 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 16391 } 16392 16393 ast_set_flag(&p->flags[0], SIP_GOTREFER); 16394 16395 /* From here on failures will be indicated with NOTIFY requests */ 16396 transmit_response(p, "202 Accepted", req); 16397 16398 /* Attended transfer: Find all call legs and bridge transferee with target*/ 16399 if (p->refer->attendedtransfer) { 16400 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 16401 return res; /* We're done with the transfer */ 16402 /* Fall through for remote transfers that we did not find locally */ 16403 if (sipdebug && option_debug > 3) 16404 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 16405 /* Fallthrough if we can't find the call leg internally */ 16406 } 16407 16408 16409 /* Parking a call */ 16410 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 16411 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 16412 *nounlock = 1; 16413 ast_channel_unlock(current.chan1); 16414 copy_request(¤t.req, req); 16415 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 16416 p->refer->status = REFER_200OK; 16417 append_history(p, "Xfer", "REFER to call parking."); 16418 if (sipdebug && option_debug > 3) 16419 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 16420 if ((res = sip_park(current.chan2, current.chan1, req, seqno))) { 16421 transmit_notify_with_sipfrag(p, seqno, "500 Internal Server Error", TRUE); 16422 } 16423 return res; 16424 } 16425 16426 /* Blind transfers and remote attended xfers */ 16427 if (current.chan1 && current.chan2) { 16428 if (option_debug > 2) 16429 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 16430 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 16431 } 16432 if (current.chan2) { 16433 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 16434 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 16435 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 16436 /* One for the new channel */ 16437 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 16438 /* Attended transfer to remote host, prepare headers for the INVITE */ 16439 if (p->refer->referred_by) 16440 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 16441 } 16442 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 16443 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 16444 char tempheader[SIPBUFSIZE]; 16445 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 16446 p->refer->replaces_callid_totag ? ";to-tag=" : "", 16447 p->refer->replaces_callid_totag, 16448 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 16449 p->refer->replaces_callid_fromtag); 16450 if (current.chan2) 16451 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 16452 } 16453 /* Must release lock now, because it will not longer 16454 be accessible after the transfer! */ 16455 *nounlock = 1; 16456 ast_channel_unlock(current.chan1); 16457 16458 /* Connect the call */ 16459 16460 /* FAKE ringing if not attended transfer */ 16461 if (!p->refer->attendedtransfer) 16462 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 16463 16464 /* For blind transfer, this will lead to a new call */ 16465 /* For attended transfer to remote host, this will lead to 16466 a new SIP call with a replaces header, if the dial plan allows it 16467 */ 16468 if (!current.chan2) { 16469 /* We have no bridge, so we're talking with Asterisk somehow */ 16470 /* We need to masquerade this call */ 16471 /* What to do to fix this situation: 16472 * Set up the new call in a new channel 16473 * Let the new channel masq into this channel 16474 Please add that code here :-) 16475 */ 16476 p->refer->status = REFER_FAILED; 16477 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 16478 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 16479 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 16480 return -1; 16481 } 16482 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 16483 16484 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 16485 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 16486 /* indicate before masquerade so the indication actually makes it to the real channel 16487 when using local channels with MOH passthru */ 16488 ast_indicate(current.chan2, AST_CONTROL_UNHOLD); 16489 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 16490 16491 if (!res) { 16492 /* Success - we have a new channel */ 16493 if (option_debug > 2) 16494 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 16495 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 16496 if (p->refer->localtransfer) 16497 p->refer->status = REFER_200OK; 16498 if (p->owner) 16499 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 16500 append_history(p, "Xfer", "Refer succeeded."); 16501 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 16502 /* Do not hangup call, the other side do that when we say 200 OK */ 16503 /* We could possibly implement a timer here, auto congestion */ 16504 res = 0; 16505 } else { 16506 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 16507 if (option_debug > 2) 16508 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 16509 append_history(p, "Xfer", "Refer failed."); 16510 /* Failure of some kind */ 16511 p->refer->status = REFER_FAILED; 16512 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 16513 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 16514 res = -1; 16515 } 16516 return res; 16517 }
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 17061 of file chan_sip.c.
References append_history, ast_inet_ntoa(), ast_log(), ast_test_flag, ast_verbose(), AUTH_ACL_FAILED, 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_request::headers, sip_pvt::initreq, LOG_NOTICE, LOG_WARNING, sip_request::method, register_verify(), SIP_PKT_DEBUG, SIP_REGISTER, and sip_scheddestroy().
Referenced by handle_request().
17062 { 17063 enum check_auth_result res; 17064 17065 /* If this is not the intial request, and the initial request isn't 17066 * a register, something screwy happened, so bail */ 17067 if (p->initreq.headers && p->initreq.method != SIP_REGISTER) { 17068 ast_log(LOG_WARNING, "Ignoring spurious REGISTER with Call-ID: %s\n", p->callid); 17069 return -1; 17070 } 17071 17072 /* Use this as the basis */ 17073 if (ast_test_flag(req, SIP_PKT_DEBUG)) 17074 ast_verbose("Using latest REGISTER request as basis request\n"); 17075 copy_request(&p->initreq, req); 17076 check_via(p, req); 17077 if ((res = register_verify(p, sin, req, e)) < 0) { 17078 const char *reason; 17079 17080 switch (res) { 17081 case AUTH_SECRET_FAILED: 17082 reason = "Wrong password"; 17083 break; 17084 case AUTH_USERNAME_MISMATCH: 17085 reason = "Username/auth name mismatch"; 17086 break; 17087 case AUTH_NOT_FOUND: 17088 reason = "No matching peer found"; 17089 break; 17090 case AUTH_UNKNOWN_DOMAIN: 17091 reason = "Not a local domain"; 17092 break; 17093 case AUTH_PEER_NOT_DYNAMIC: 17094 reason = "Peer is not supposed to register"; 17095 break; 17096 case AUTH_ACL_FAILED: 17097 reason = "Device does not match ACL"; 17098 break; 17099 default: 17100 reason = "Unknown failure"; 17101 break; 17102 } 17103 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 17104 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 17105 reason); 17106 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 17107 } else 17108 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 17109 17110 if (res < 1) { 17111 /* Destroy the session, but keep us around for just a bit in case they don't 17112 get our 200 OK */ 17113 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17114 } 17115 return res; 17116 }
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 16739 of file chan_sip.c.
References __get_header(), add_extensionstate_update(), append_history, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_extension_state_del(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), build_route(), sip_pvt::callid, check_user_full(), check_via(), sip_pvt::context, copy_request(), CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, sip_pvt::exten, FALSE, sip_pvt::flags, get_destination(), get_header(), gettag(), sip_request::headers, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, sip_peer::mailbox, make_our_tag(), sip_request::method, MWI_NOTIFICATION, sip_peer::mwipvt, sip_peer::name, NONE, option_debug, parse_ok_contact(), PIDF_XML, sip_pvt::relatedpeer, sip_pvt::sa, sip_cancel_destroy(), sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sipdebug, 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(), TRUE, sip_pvt::useragent, sip_pvt::username, XMIT_UNRELIABLE, and XPIDF_XML.
Referenced by handle_request().
16740 { 16741 int gotdest = 0; 16742 int res = 0; 16743 int firststate = AST_EXTENSION_REMOVED; 16744 struct sip_peer *authpeer = NULL; 16745 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 16746 int resubscribe = (p->subscribed != NONE) && !ast_test_flag(req, SIP_PKT_IGNORE); 16747 char *temp, *event; 16748 16749 if (p->initreq.headers) { 16750 /* We already have a dialog */ 16751 if (p->initreq.method != SIP_SUBSCRIBE) { 16752 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 16753 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 16754 transmit_response(p, "403 Forbidden (within dialog)", req); 16755 /* Do not destroy session, since we will break the call if we do */ 16756 if (option_debug) 16757 ast_log(LOG_DEBUG, "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); 16758 return 0; 16759 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 16760 if (option_debug) { 16761 if (resubscribe) 16762 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 16763 else 16764 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth) or retransmission\n", p->callid); 16765 } 16766 } 16767 } 16768 16769 /* Check if we have a global disallow setting on subscriptions. 16770 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 16771 */ 16772 if (!global_allowsubscribe) { 16773 transmit_response(p, "403 Forbidden (policy)", req); 16774 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16775 return 0; 16776 } 16777 16778 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 16779 const char *to = get_header(req, "To"); 16780 char totag[128]; 16781 16782 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 16783 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 16784 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16785 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 16786 transmit_response(p, "481 Subscription does not exist", req); 16787 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16788 return 0; 16789 } 16790 16791 /* Use this as the basis */ 16792 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16793 ast_verbose("Creating new subscription\n"); 16794 16795 copy_request(&p->initreq, req); 16796 check_via(p, req); 16797 build_route(p, req, 0); 16798 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 16799 ast_verbose("Ignoring this SUBSCRIBE request\n"); 16800 16801 /* Find parameters to Event: header value and remove them for now */ 16802 if (ast_strlen_zero(eventheader)) { 16803 transmit_response(p, "489 Bad Event", req); 16804 if (option_debug > 1) 16805 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 16806 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16807 return 0; 16808 } 16809 16810 if ( (strchr(eventheader, ';'))) { 16811 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 16812 temp = strchr(event, ';'); 16813 *temp = '\0'; /* Remove any options for now */ 16814 /* We might need to use them later :-) */ 16815 } else 16816 event = (char *) eventheader; /* XXX is this legal ? */ 16817 16818 /* Handle authentication if we're new and not a retransmission. We can't just 16819 * use if !(ast_test_flag(req, SIP_PKT_IGNORE), because then we'll end up sending 16820 * a 200 OK if someone retransmits without sending auth */ 16821 if (p->subscribed == NONE || resubscribe) { 16822 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 16823 16824 /* if an authentication response was sent, we are done here */ 16825 if (res == AUTH_CHALLENGE_SENT) { 16826 if (authpeer) 16827 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16828 return 0; 16829 } 16830 if (res < 0) { 16831 if (res == AUTH_FAKE_AUTH) { 16832 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 16833 transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE); 16834 } else { 16835 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 16836 transmit_response_reliable(p, "403 Forbidden", req); 16837 } 16838 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16839 if (authpeer) 16840 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16841 return 0; 16842 } 16843 } 16844 16845 /* Check if this user/peer is allowed to subscribe at all */ 16846 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 16847 transmit_response(p, "403 Forbidden (policy)", req); 16848 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16849 if (authpeer) 16850 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16851 return 0; 16852 } 16853 16854 if (strcmp(event, "message-summary")) { 16855 /* Get destination right away */ 16856 gotdest = get_destination(p, NULL); 16857 } 16858 16859 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 16860 parse_ok_contact(p, req); 16861 16862 build_contact(p); 16863 if (gotdest) { 16864 transmit_response(p, "404 Not Found", req); 16865 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16866 if (authpeer) 16867 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16868 return 0; 16869 } 16870 16871 /* Initialize tag for new subscriptions */ 16872 if (ast_strlen_zero(p->tag)) 16873 make_our_tag(p->tag, sizeof(p->tag)); 16874 16875 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 16876 unsigned int pidf_xml; 16877 const char *accept; 16878 int start = 0; 16879 enum subscriptiontype subscribed = NONE; 16880 const char *unknown_acceptheader = NULL; 16881 16882 if (authpeer) /* No need for authpeer here */ 16883 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16884 16885 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 16886 accept = __get_header(req, "Accept", &start); 16887 while ((subscribed == NONE) && !ast_strlen_zero(accept)) { 16888 pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0; 16889 16890 /* Older versions of Polycom firmware will claim pidf+xml, but really 16891 * they only support xpidf+xml. */ 16892 if (pidf_xml && strstr(p->useragent, "Polycom")) { 16893 subscribed = XPIDF_XML; 16894 } else if (pidf_xml) { 16895 subscribed = PIDF_XML; /* RFC 3863 format */ 16896 } else if (strstr(accept, "application/dialog-info+xml")) { 16897 subscribed = DIALOG_INFO_XML; 16898 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 16899 } else if (strstr(accept, "application/cpim-pidf+xml")) { 16900 subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 16901 } else if (strstr(accept, "application/xpidf+xml")) { 16902 subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 16903 } else { 16904 unknown_acceptheader = accept; 16905 } 16906 /* check to see if there is another Accept header present */ 16907 accept = __get_header(req, "Accept", &start); 16908 } 16909 16910 if (!start) { 16911 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 16912 transmit_response(p, "489 Bad Event", req); 16913 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: " 16914 "stateid: %d, laststate: %d, dialogver: %d, subscribecont: " 16915 "'%s', subscribeuri: '%s'\n", 16916 p->stateid, 16917 p->laststate, 16918 p->dialogver, 16919 p->subscribecontext, 16920 p->subscribeuri); 16921 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16922 return 0; 16923 } 16924 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 16925 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 16926 } else if (subscribed == NONE) { 16927 /* Can't find a format for events that we know about */ 16928 char mybuf[200]; 16929 if (!ast_strlen_zero(unknown_acceptheader)) { 16930 snprintf(mybuf, sizeof(mybuf), "489 Bad Event (format %s)", unknown_acceptheader); 16931 } else { 16932 snprintf(mybuf, sizeof(mybuf), "489 Bad Event"); 16933 } 16934 transmit_response(p, mybuf, req); 16935 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format:" 16936 "'%s' pvt: subscribed: %d, stateid: %d, laststate: %d," 16937 "dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 16938 unknown_acceptheader, 16939 (int)p->subscribed, 16940 p->stateid, 16941 p->laststate, 16942 p->dialogver, 16943 p->subscribecontext, 16944 p->subscribeuri); 16945 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16946 return 0; 16947 } else { 16948 p->subscribed = subscribed; 16949 } 16950 } else if (!strcmp(event, "message-summary")) { 16951 int start = 0; 16952 int found_supported = 0; 16953 const char *acceptheader; 16954 16955 acceptheader = __get_header(req, "Accept", &start); 16956 while (!found_supported && !ast_strlen_zero(acceptheader)) { 16957 found_supported = strcmp(acceptheader, "application/simple-message-summary") ? 0 : 1; 16958 if (!found_supported && (option_debug > 2)) { 16959 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader); 16960 } 16961 acceptheader = __get_header(req, "Accept", &start); 16962 } 16963 if (start && !found_supported) { 16964 /* Format requested that we do not support */ 16965 transmit_response(p, "406 Not Acceptable", req); 16966 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16967 if (authpeer) /* No need for authpeer here */ 16968 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16969 return 0; 16970 } 16971 /* Looks like they actually want a mailbox status 16972 This version of Asterisk supports mailbox subscriptions 16973 The subscribed URI needs to exist in the dial plan 16974 In most devices, this is configurable to the voicemailmain extension you use 16975 */ 16976 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 16977 transmit_response(p, "404 Not found (no mailbox)", req); 16978 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16979 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 16980 if (authpeer) /* No need for authpeer here */ 16981 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16982 return 0; 16983 } 16984 16985 p->subscribed = MWI_NOTIFICATION; 16986 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 16987 /* We only allow one subscription per peer */ 16988 sip_destroy(authpeer->mwipvt); 16989 authpeer->mwipvt = p; /* Link from peer to pvt */ 16990 p->relatedpeer = ASTOBJ_REF(authpeer); /* Link from pvt to peer */ 16991 } else { /* At this point, Asterisk does not understand the specified event */ 16992 transmit_response(p, "489 Bad Event", req); 16993 if (option_debug > 1) 16994 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 16995 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16996 if (authpeer) /* No need for authpeer here */ 16997 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16998 return 0; 16999 } 17000 17001 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 17002 if (p->stateid > -1) 17003 ast_extension_state_del(p->stateid, add_extensionstate_update); 17004 p->stateid = ast_extension_state_add(p->context, p->exten, add_extensionstate_update, p); 17005 } 17006 17007 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 17008 p->lastinvite = seqno; 17009 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 17010 p->expiry = atoi(get_header(req, "Expires")); 17011 17012 /* check if the requested expiry-time is within the approved limits from sip.conf */ 17013 if (p->expiry > max_expiry) 17014 p->expiry = max_expiry; 17015 if (p->expiry < min_expiry && p->expiry > 0) 17016 p->expiry = min_expiry; 17017 17018 if (sipdebug || option_debug > 1) { 17019 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 17020 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 17021 else 17022 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 17023 } 17024 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 17025 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 17026 if (p->expiry > 0) 17027 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 17028 17029 if (p->subscribed == MWI_NOTIFICATION) { 17030 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 17031 transmit_response(p, "200 OK", req); 17032 if (p->relatedpeer) { /* Send first notification */ 17033 ASTOBJ_WRLOCK(p->relatedpeer); 17034 sip_send_mwi_to_peer(p->relatedpeer, TRUE); 17035 ASTOBJ_UNLOCK(p->relatedpeer); 17036 } 17037 } else { 17038 17039 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 17040 17041 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)); 17042 transmit_response(p, "404 Not found", req); 17043 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 17044 return 0; 17045 } 17046 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 17047 transmit_response(p, "200 OK", req); 17048 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 17049 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 17050 /* hide the 'complete' exten/context in the refer_to field for later display */ 17051 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 17052 17053 } 17054 if (!p->expiry) 17055 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 17056 } 17057 return 1; 17058 }
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 14121 of file chan_sip.c.
References __sip_ack(), __sip_semi_ack(), append_history, ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, 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_verbose(), sip_pvt::authname, sip_pvt::authtries, sip_pvt::callid, sip_pvt::context, 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_pvt::initreq, sip_pvt::laststate, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, sip_pvt::method, NONE, notify_extenstate_update(), option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::recv, sip_pvt::refer, sip_pvt::registry, sip_pvt::relatedpeer, sip_pvt::sa, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_FORWARD_LOOP_DETECTED, SIP_PAGE2_STATECHANGEQUEUE, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_REFER, SIP_REGISTER, SIP_SUBSCRIBE, sipdebug, stop_media_flows(), sip_pvt::subscribed, text, sip_pvt::theirtag, transmit_request(), sip_pvt::username, VERBOSE_PREFIX_3, and XMIT_UNRELIABLE.
Referenced by handle_request().
14122 { 14123 struct ast_channel *owner; 14124 int sipmethod; 14125 int res = 1; 14126 int ack_res; 14127 const char *c = get_header(req, "Cseq"); 14128 /* 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 */ 14129 char *c_copy = ast_strdupa(c); 14130 /* Skip the Cseq and its subsequent spaces */ 14131 const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy)); 14132 14133 if (!msg) 14134 msg = ""; 14135 14136 sipmethod = find_sip_method(msg); 14137 14138 owner = p->owner; 14139 if (owner) 14140 owner->hangupcause = hangup_sip2cause(resp); 14141 14142 /* Acknowledge whatever it is destined for */ 14143 if ((resp >= 100) && (resp <= 199)) { 14144 ack_res = __sip_semi_ack(p, seqno, 0, sipmethod); 14145 } else { 14146 ack_res = __sip_ack(p, seqno, 0, sipmethod); 14147 } 14148 14149 if (ack_res == FALSE) { 14150 append_history(p, "Ignore", "Ignoring this retransmit\n"); 14151 return; 14152 } 14153 14154 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 14155 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 14156 p->pendinginvite = 0; 14157 14158 /* Get their tag if we haven't already */ 14159 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 14160 char tag[128]; 14161 14162 gettag(req, "To", tag, sizeof(tag)); 14163 ast_string_field_set(p, theirtag, tag); 14164 } 14165 14166 /* RFC 3261 Section 15 specifies that if we receive a 408 or 481 14167 * in response to a BYE, then we should end the current dialog 14168 * and session. It is known that at least one phone manufacturer 14169 * potentially will send a 404 in response to a BYE, so we'll be 14170 * liberal in what we accept and end the dialog and session if we 14171 * receive any of those responses to a BYE. 14172 */ 14173 if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) { 14174 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14175 return; 14176 } 14177 14178 if (p->relatedpeer && p->method == SIP_OPTIONS) { 14179 /* We don't really care what the response is, just that it replied back. 14180 Well, as long as it's not a 100 response... since we might 14181 need to hang around for something more "definitive" */ 14182 if (resp != 100) 14183 handle_response_peerpoke(p, resp, req); 14184 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 14185 switch(resp) { 14186 case 100: /* 100 Trying */ 14187 case 101: /* 101 Dialog establishment */ 14188 if (sipmethod == SIP_INVITE) 14189 handle_response_invite(p, resp, rest, req, seqno); 14190 break; 14191 case 183: /* 183 Session Progress */ 14192 if (sipmethod == SIP_INVITE) 14193 handle_response_invite(p, resp, rest, req, seqno); 14194 break; 14195 case 180: /* 180 Ringing */ 14196 if (sipmethod == SIP_INVITE) 14197 handle_response_invite(p, resp, rest, req, seqno); 14198 break; 14199 case 182: /* 182 Queued */ 14200 if (sipmethod == SIP_INVITE) 14201 handle_response_invite(p, resp, rest, req, seqno); 14202 break; 14203 case 200: /* 200 OK */ 14204 p->authtries = 0; /* Reset authentication counter */ 14205 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 14206 /* We successfully transmitted a message 14207 or a video update request in INFO */ 14208 /* Nothing happens here - the message is inside a dialog */ 14209 } else if (sipmethod == SIP_INVITE) { 14210 handle_response_invite(p, resp, rest, req, seqno); 14211 } else if (sipmethod == SIP_NOTIFY) { 14212 /* They got the notify, this is the end */ 14213 if (p->owner) { 14214 if (!p->refer) { 14215 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 14216 ast_queue_hangup(p->owner); 14217 } else if (option_debug > 3) 14218 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 14219 } else { 14220 if (p->subscribed == NONE) 14221 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14222 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 14223 /* Ready to send the next state we have on queue */ 14224 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 14225 notify_extenstate_update((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 14226 } 14227 } 14228 } else if (sipmethod == SIP_REGISTER) 14229 res = handle_response_register(p, resp, rest, req, seqno); 14230 else if (sipmethod == SIP_BYE) { /* Ok, we're ready to go */ 14231 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14232 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 14233 } else if (sipmethod == SIP_SUBSCRIBE) 14234 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 14235 break; 14236 case 202: /* Transfer accepted */ 14237 if (sipmethod == SIP_REFER) 14238 handle_response_refer(p, resp, rest, req, seqno); 14239 break; 14240 case 401: /* Not www-authorized on SIP method */ 14241 if (sipmethod == SIP_INVITE) 14242 handle_response_invite(p, resp, rest, req, seqno); 14243 else if (sipmethod == SIP_REFER) 14244 handle_response_refer(p, resp, rest, req, seqno); 14245 else if (p->registry && sipmethod == SIP_REGISTER) 14246 res = handle_response_register(p, resp, rest, req, seqno); 14247 else if (sipmethod == SIP_BYE) { 14248 if (ast_strlen_zero(p->authname)) { 14249 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 14250 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 14251 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14252 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) { 14253 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 14254 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14255 /* We fail to auth bye on our own call, but still needs to tear down the call. 14256 Life, they call it. */ 14257 } 14258 } else { 14259 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 14260 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14261 } 14262 break; 14263 case 403: /* Forbidden - we failed authentication */ 14264 if (sipmethod == SIP_INVITE) 14265 handle_response_invite(p, resp, rest, req, seqno); 14266 else if (p->registry && sipmethod == SIP_REGISTER) 14267 res = handle_response_register(p, resp, rest, req, seqno); 14268 else { 14269 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 14270 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14271 } 14272 break; 14273 case 404: /* Not found */ 14274 if (p->registry && sipmethod == SIP_REGISTER) 14275 res = handle_response_register(p, resp, rest, req, seqno); 14276 else if (sipmethod == SIP_INVITE) 14277 handle_response_invite(p, resp, rest, req, seqno); 14278 else if (owner) 14279 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 14280 break; 14281 case 407: /* Proxy auth required */ 14282 if (sipmethod == SIP_INVITE) 14283 handle_response_invite(p, resp, rest, req, seqno); 14284 else if (sipmethod == SIP_REFER) 14285 handle_response_refer(p, resp, rest, req, seqno); 14286 else if (p->registry && sipmethod == SIP_REGISTER) 14287 res = handle_response_register(p, resp, rest, req, seqno); 14288 else if (sipmethod == SIP_BYE) { 14289 if (ast_strlen_zero(p->authname)) { 14290 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 14291 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 14292 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14293 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 14294 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 14295 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14296 } 14297 } else /* We can't handle this, giving up in a bad way */ 14298 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14299 14300 break; 14301 case 408: /* Request timeout - terminate dialog */ 14302 if (sipmethod == SIP_INVITE) 14303 handle_response_invite(p, resp, rest, req, seqno); 14304 else if (sipmethod == SIP_REGISTER) 14305 res = handle_response_register(p, resp, rest, req, seqno); 14306 else if (sipmethod == SIP_BYE) { 14307 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14308 if (option_debug) 14309 ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 14310 } else { 14311 if (owner) 14312 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 14313 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14314 } 14315 break; 14316 case 481: /* Call leg does not exist */ 14317 if (sipmethod == SIP_INVITE) { 14318 handle_response_invite(p, resp, rest, req, seqno); 14319 } else if (sipmethod == SIP_REFER) { 14320 handle_response_refer(p, resp, rest, req, seqno); 14321 } else if (sipmethod == SIP_BYE) { 14322 /* The other side has no transaction to bye, 14323 just assume it's all right then */ 14324 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 14325 } else if (sipmethod == SIP_CANCEL) { 14326 /* The other side has no transaction to cancel, 14327 just assume it's all right then */ 14328 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 14329 } else if (sipmethod == SIP_NOTIFY) { 14330 /* The other side has no active Subscribe for this Callid. 14331 * Remove this Dialog and old Subscription */ 14332 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14333 } else { 14334 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 14335 /* Guessing that this is not an important request */ 14336 } 14337 break; 14338 case 487: 14339 if (sipmethod == SIP_INVITE) 14340 handle_response_invite(p, resp, rest, req, seqno); 14341 break; 14342 case 488: /* Not acceptable here - codec error */ 14343 case 606: /* Not Acceptable */ 14344 if (sipmethod == SIP_INVITE) 14345 handle_response_invite(p, resp, rest, req, seqno); 14346 break; 14347 case 491: /* Pending */ 14348 if (sipmethod == SIP_INVITE) 14349 handle_response_invite(p, resp, rest, req, seqno); 14350 else { 14351 if (option_debug) 14352 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 14353 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14354 } 14355 break; 14356 case 501: /* Not Implemented */ 14357 if (sipmethod == SIP_INVITE) 14358 handle_response_invite(p, resp, rest, req, seqno); 14359 else if (sipmethod == SIP_REFER) 14360 handle_response_refer(p, resp, rest, req, seqno); 14361 else 14362 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 14363 break; 14364 case 603: /* Declined transfer */ 14365 if (sipmethod == SIP_REFER) { 14366 handle_response_refer(p, resp, rest, req, seqno); 14367 break; 14368 } 14369 /* Fallthrough */ 14370 default: 14371 if ((resp >= 300) && (resp < 700)) { 14372 /* Fatal response */ 14373 if ((option_verbose > 2) && (resp != 487)) 14374 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 14375 14376 if (sipmethod == SIP_INVITE) 14377 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14378 14379 /* XXX Locking issues?? XXX */ 14380 switch(resp) { 14381 case 300: /* Multiple Choices */ 14382 case 301: /* Moved permenantly */ 14383 case 302: /* Moved temporarily */ 14384 case 305: /* Use Proxy */ 14385 parse_moved_contact(p, req); 14386 /* Fall through */ 14387 case 486: /* Busy here */ 14388 case 600: /* Busy everywhere */ 14389 case 603: /* Decline */ 14390 if (p->owner) 14391 ast_queue_control(p->owner, AST_CONTROL_BUSY); 14392 break; 14393 case 482: /* Loop Detected */ 14394 /* 14395 \note Asterisk has historically tried to do a call forward when it 14396 gets a 482, but that behavior isn't necessarily the best course of 14397 action. Go ahead and do it anyway by default, but allow the option 14398 to immediately pass to the next line in the dialplan. */ 14399 if (p->owner && ast_test_flag(&p->flags[1], SIP_PAGE2_FORWARD_LOOP_DETECTED)) { 14400 if (option_debug) { 14401 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 14402 } 14403 ast_string_field_build(p->owner, call_forward, 14404 "Local/%s@%s", p->username, p->context); 14405 } 14406 /* Fall through */ 14407 case 480: /* Temporarily Unavailable */ 14408 case 404: /* Not Found */ 14409 case 410: /* Gone */ 14410 case 400: /* Bad Request */ 14411 case 500: /* Server error */ 14412 if (sipmethod == SIP_REFER) { 14413 handle_response_refer(p, resp, rest, req, seqno); 14414 break; 14415 } 14416 /* Fall through */ 14417 case 502: /* Bad gateway */ 14418 case 503: /* Service Unavailable */ 14419 case 504: /* Server Timeout */ 14420 if (owner) 14421 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 14422 break; 14423 default: 14424 /* Send hangup */ 14425 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 14426 ast_queue_hangup(p->owner); 14427 break; 14428 } 14429 /* ACK on invite */ 14430 if (sipmethod == SIP_INVITE) 14431 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 14432 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 14433 sip_alreadygone(p); 14434 if (!p->owner) 14435 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14436 } else if ((resp >= 100) && (resp < 200)) { 14437 if (sipmethod == SIP_INVITE) { 14438 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 14439 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 14440 if (find_sdp(req)) 14441 process_sdp(p, req); 14442 if (p->owner) { 14443 /* Queue a progress frame */ 14444 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 14445 } 14446 } 14447 } else 14448 ast_log(LOG_NOTICE, "Don't know how to handle a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : ast_inet_ntoa(p->sa.sin_addr)); 14449 } 14450 } else { 14451 /* Responses to OUTGOING SIP requests on INCOMING calls 14452 get handled here. As well as out-of-call message responses */ 14453 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14454 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 14455 14456 if (sipmethod == SIP_INVITE && resp == 200) { 14457 /* Tags in early session is replaced by the tag in 200 OK, which is 14458 the final reply to our INVITE */ 14459 char tag[128]; 14460 14461 gettag(req, "To", tag, sizeof(tag)); 14462 ast_string_field_set(p, theirtag, tag); 14463 } 14464 14465 switch(resp) { 14466 case 200: 14467 if (sipmethod == SIP_INVITE) { 14468 handle_response_invite(p, resp, rest, req, seqno); 14469 } else if (sipmethod == SIP_CANCEL) { 14470 if (option_debug) 14471 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 14472 14473 /* Wait for 487, then destroy */ 14474 } else if (sipmethod == SIP_NOTIFY) { 14475 /* They got the notify, this is the end */ 14476 if (p->owner) { 14477 if (p->refer) { 14478 if (option_debug) 14479 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 14480 } else 14481 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 14482 /* ast_queue_hangup(p->owner); Disabled */ 14483 } else { 14484 if (!p->subscribed && !p->refer) 14485 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14486 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 14487 /* Ready to send the next state we have on queue */ 14488 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 14489 notify_extenstate_update((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 14490 } 14491 } 14492 } else if (sipmethod == SIP_BYE) 14493 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14494 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 14495 /* We successfully transmitted a message or 14496 a video update request in INFO */ 14497 ; 14498 else if (sipmethod == SIP_BYE) 14499 /* Ok, we're ready to go */ 14500 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14501 break; 14502 case 202: /* Transfer accepted */ 14503 if (sipmethod == SIP_REFER) 14504 handle_response_refer(p, resp, rest, req, seqno); 14505 break; 14506 case 401: /* www-auth */ 14507 case 407: 14508 if (sipmethod == SIP_REFER) 14509 handle_response_refer(p, resp, rest, req, seqno); 14510 else if (sipmethod == SIP_INVITE) 14511 handle_response_invite(p, resp, rest, req, seqno); 14512 else if (sipmethod == SIP_BYE) { 14513 char *auth, *auth2; 14514 14515 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 14516 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 14517 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 14518 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 14519 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14520 } 14521 } 14522 break; 14523 case 481: /* Call leg does not exist */ 14524 if (sipmethod == SIP_INVITE) { 14525 /* Re-invite failed */ 14526 handle_response_invite(p, resp, rest, req, seqno); 14527 } else if (sipmethod == SIP_BYE) { 14528 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14529 } else if (sipmethod == SIP_NOTIFY) { 14530 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14531 } else if (sipdebug) { 14532 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 14533 } 14534 break; 14535 case 501: /* Not Implemented */ 14536 if (sipmethod == SIP_INVITE) 14537 handle_response_invite(p, resp, rest, req, seqno); 14538 else if (sipmethod == SIP_REFER) 14539 handle_response_refer(p, resp, rest, req, seqno); 14540 break; 14541 case 603: /* Declined transfer */ 14542 if (sipmethod == SIP_REFER) { 14543 handle_response_refer(p, resp, rest, req, seqno); 14544 break; 14545 } 14546 /* Fallthrough */ 14547 default: /* Errors without handlers */ 14548 if ((resp >= 100) && (resp < 200)) { 14549 if (sipmethod == SIP_INVITE) { /* re-invite */ 14550 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 14551 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 14552 } 14553 } 14554 if ((resp >= 300) && (resp < 700)) { 14555 if ((option_verbose > 2) && (resp != 487)) 14556 ast_verbose(VERBOSE_PREFIX_3 "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 14557 switch(resp) { 14558 case 488: /* Not acceptable here - codec error */ 14559 case 603: /* Decline */ 14560 case 500: /* Server error */ 14561 case 502: /* Bad gateway */ 14562 case 503: /* Service Unavailable */ 14563 case 504: /* Server timeout */ 14564 14565 /* re-invite failed */ 14566 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 14567 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 14568 break; 14569 } 14570 } 14571 break; 14572 } 14573 } 14574 }
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 13525 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), 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_free, ast_test_flag, sip_invite_param::auth_type, authenticate(), sip_pvt::authtries, build_route(), sip_pvt::callid, check_pendings(), DEC_CALL_LIMIT, DEC_CALL_RINGING, DEFAULT_TRANS_TIMEOUT, do_proxy_auth(), FALSE, find_sdp(), sip_pvt::flags, get_header(), sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, option_debug, sip_pvt::options, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, sip_pvt::route, sip_pvt::rtp, set_address_from_contact(), SIP_ACK, sip_alreadygone(), SIP_ALREADYGONE, sip_cancel_destroy(), sip_handle_t38_reinvite(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_OUTGOING_CALL, SIP_PENDINGBYE, SIP_PKT_IGNORE, sip_reinvite_retry(), sip_scheddestroy(), sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_REINVITE, T38_PEER_REINVITE, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::theirtag, transmit_reinvite_with_sdp(), transmit_request(), TRUE, ast_channel_tech::type, sip_pvt::udptl, update_call_counter(), sip_pvt::vrtp, sip_pvt::waitid, WWW_AUTH, XMIT_ERROR, and XMIT_UNRELIABLE.
Referenced by handle_response().
13526 { 13527 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 13528 int res = 0; 13529 int xmitres = 0; 13530 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 13531 struct ast_channel *bridgepeer = NULL; 13532 13533 if (option_debug > 3) { 13534 if (reinvite) 13535 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 13536 else 13537 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 13538 } 13539 13540 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 13541 if (option_debug) 13542 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 13543 return; 13544 } 13545 13546 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 13547 /* Don't auto congest anymore since we've gotten something useful back */ 13548 AST_SCHED_DEL(sched, p->initid); 13549 13550 /* RFC3261 says we must treat every 1xx response (but not 100) 13551 that we don't recognize as if it was 183. 13552 */ 13553 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183) 13554 resp = 183; 13555 13556 /* Any response between 100 and 199 is PROCEEDING */ 13557 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 13558 p->invitestate = INV_PROCEEDING; 13559 13560 /* Final response, not 200 ? */ 13561 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 13562 p->invitestate = INV_COMPLETED; 13563 13564 13565 switch (resp) { 13566 case 100: /* Trying */ 13567 case 101: /* Dialog establishment */ 13568 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 13569 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13570 check_pendings(p); 13571 break; 13572 13573 case 180: /* 180 Ringing */ 13574 case 182: /* 182 Queued */ 13575 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 13576 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13577 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 13578 ast_queue_control(p->owner, AST_CONTROL_RINGING); 13579 if (p->owner->_state != AST_STATE_UP) { 13580 ast_setstate(p->owner, AST_STATE_RINGING); 13581 } 13582 } 13583 if (find_sdp(req)) { 13584 if (p->invitestate != INV_CANCELLED) 13585 p->invitestate = INV_EARLY_MEDIA; 13586 res = process_sdp(p, req); 13587 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 13588 /* Queue a progress frame only if we have SDP in 180 or 182 */ 13589 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 13590 } 13591 } 13592 check_pendings(p); 13593 break; 13594 13595 case 183: /* Session progress */ 13596 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 13597 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13598 if (find_sdp(req)) { 13599 if (p->invitestate != INV_CANCELLED) 13600 p->invitestate = INV_EARLY_MEDIA; 13601 res = process_sdp(p, req); 13602 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 13603 /* Queue a progress frame */ 13604 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 13605 } 13606 } else { 13607 /* Alcatel PBXs are known to send 183s with no SDP after sending 13608 * a 100 Trying response. We're just going to treat this sort of thing 13609 * the same as we would treat a 180 Ringing 13610 */ 13611 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 13612 ast_queue_control(p->owner, AST_CONTROL_RINGING); 13613 } 13614 } 13615 check_pendings(p); 13616 break; 13617 13618 case 200: /* 200 OK on invite - someone's answering our call */ 13619 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 13620 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13621 p->authtries = 0; 13622 if (find_sdp(req)) { 13623 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 13624 if (!reinvite) 13625 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 13626 /* For re-invites, we try to recover */ 13627 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 13628 } 13629 13630 /* Parse contact header for continued conversation */ 13631 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 13632 /* This is important when we have a SIP proxy between us and the phone */ 13633 if (outgoing) { 13634 update_call_counter(p, DEC_CALL_RINGING); 13635 parse_ok_contact(p, req); 13636 /* Save Record-Route for any later requests we make on this dialogue */ 13637 if (!reinvite) 13638 build_route(p, req, 1); 13639 13640 if(set_address_from_contact(p)) { 13641 /* Bad contact - we don't know how to reach this device */ 13642 /* We need to ACK, but then send a bye */ 13643 if (!p->route && !ast_test_flag(req, SIP_PKT_IGNORE)) 13644 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 13645 } 13646 13647 } 13648 13649 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 13650 struct sip_pvt *bridgepvt = NULL; 13651 13652 if (!bridgepeer->tech) { 13653 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 13654 break; 13655 } 13656 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 13657 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 13658 if (bridgepvt->udptl) { 13659 if (p->t38.state == T38_PEER_REINVITE) { 13660 sip_handle_t38_reinvite(bridgepeer, p, 0); 13661 ast_rtp_set_rtptimers_onhold(p->rtp); 13662 if (p->vrtp) 13663 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 13664 } 13665 } else { 13666 if (option_debug > 1) 13667 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 13668 ast_mutex_lock(&bridgepvt->lock); 13669 bridgepvt->t38.state = T38_DISABLED; 13670 ast_mutex_unlock(&bridgepvt->lock); 13671 if (option_debug) 13672 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 13673 p->t38.state = T38_DISABLED; 13674 if (option_debug > 1) 13675 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13676 } 13677 } else { 13678 /* Other side is not a SIP channel */ 13679 if (option_debug > 1) 13680 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 13681 p->t38.state = T38_DISABLED; 13682 if (option_debug > 1) 13683 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13684 } 13685 } 13686 if (p->t38.state == T38_LOCAL_REINVITE) { 13687 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 13688 p->t38.state = T38_ENABLED; 13689 if (option_debug) 13690 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13691 } 13692 13693 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 13694 if (!reinvite) { 13695 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 13696 } else { /* RE-invite */ 13697 ast_queue_frame(p->owner, &ast_null_frame); 13698 } 13699 } else { 13700 /* It's possible we're getting an 200 OK after we've tried to disconnect 13701 by sending CANCEL */ 13702 /* First send ACK, then send bye */ 13703 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 13704 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 13705 } 13706 /* If I understand this right, the branch is different for a non-200 ACK only */ 13707 p->invitestate = INV_TERMINATED; 13708 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 13709 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 13710 check_pendings(p); 13711 break; 13712 case 407: /* Proxy authentication */ 13713 case 401: /* Www auth */ 13714 /* First we ACK */ 13715 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13716 if (p->options) 13717 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 13718 13719 /* Then we AUTH */ 13720 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 13721 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13722 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 13723 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 13724 if (p->authtries < MAX_AUTHTRIES) 13725 p->invitestate = INV_CALLING; 13726 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 13727 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 13728 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13729 sip_alreadygone(p); 13730 if (p->owner) 13731 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13732 } 13733 } 13734 break; 13735 13736 case 403: /* Forbidden */ 13737 /* First we ACK */ 13738 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13739 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 13740 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 13741 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13742 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13743 sip_alreadygone(p); 13744 break; 13745 13746 case 404: /* Not found */ 13747 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13748 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 13749 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13750 sip_alreadygone(p); 13751 break; 13752 13753 case 408: /* Request timeout */ 13754 case 481: /* Call leg does not exist */ 13755 /* Could be REFER caused INVITE with replaces */ 13756 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 13757 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13758 if (p->owner) 13759 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13760 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13761 break; 13762 case 487: /* Cancelled transaction */ 13763 /* We have sent CANCEL on an outbound INVITE 13764 This transaction is already scheduled to be killed by sip_hangup(). 13765 */ 13766 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13767 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 13768 ast_queue_hangup(p->owner); 13769 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 13770 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13771 update_call_counter(p, DEC_CALL_LIMIT); 13772 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 13773 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13774 sip_alreadygone(p); 13775 } 13776 break; 13777 case 488: /* Not acceptable here */ 13778 case 606: /* Not Acceptable */ 13779 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13780 if (reinvite && p->udptl) { 13781 p->t38.state = T38_DISABLED; 13782 /* Try to reset RTP timers */ 13783 ast_rtp_set_rtptimers_onhold(p->rtp); 13784 /* Trigger a reinvite back to audio */ 13785 transmit_reinvite_with_sdp(p); 13786 13787 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 13788 struct sip_pvt *bridgepvt = NULL; 13789 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 13790 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 13791 if (bridgepvt->udptl) { 13792 sip_handle_t38_reinvite(bridgepeer, p, 0); 13793 } 13794 } 13795 } 13796 } else { 13797 /* We can't set up this call, so give up */ 13798 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 13799 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13800 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13801 /* If there's no dialog to end, then mark p as already gone */ 13802 if (!reinvite) 13803 sip_alreadygone(p); 13804 } 13805 break; 13806 case 491: /* Pending */ 13807 /* we really should have to wait a while, then retransmit 13808 * We should support the retry-after at some point 13809 * At this point, we treat this as a congestion if the call is not in UP state 13810 */ 13811 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13812 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 13813 if (p->owner->_state != AST_STATE_UP) { 13814 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13815 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13816 } else { 13817 /* This is a re-invite that failed. 13818 * Reset the flag after a while 13819 */ 13820 int wait; 13821 /* RFC 3261, if owner of call, wait between 2.1 to 4 seconds, 13822 * if not owner of call, wait 0 to 2 seconds */ 13823 if (ast_test_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL)) { 13824 wait = 2100 + ast_random() % 2000; 13825 } else { 13826 wait = ast_random() % 2000; 13827 } 13828 13829 if (p->waitid != -1) { 13830 if (option_debug > 2) 13831 ast_log(LOG_DEBUG, "Reinvite race during existing reinvite race. Abandoning previous reinvite retry.\n"); 13832 AST_SCHED_DEL(sched, p->waitid); 13833 p->waitid = -1; 13834 } 13835 13836 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 13837 if (option_debug > 2) 13838 ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait); 13839 } 13840 } 13841 break; 13842 13843 case 501: /* Not implemented */ 13844 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13845 if (p->owner) 13846 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13847 break; 13848 } 13849 if (xmitres == XMIT_ERROR) 13850 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 13851 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 14049 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), ast_update_realtime(), ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_peer::name, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::relatedpeer, s, sip_destroy_peer(), SIP_NEEDDESTROY, SIP_PAGE2_RTUPDATE, and sip_poke_peer_s().
Referenced by handle_response().
14050 { 14051 struct sip_peer *peer = p->relatedpeer; 14052 int statechanged, is_reachable, was_reachable; 14053 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 14054 14055 /* 14056 * Compute the response time to a ping (goes in peer->lastms.) 14057 * -1 means did not respond, 0 means unknown, 14058 * 1..maxms is a valid response, >maxms means late response. 14059 */ 14060 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 14061 pingtime = 1; 14062 14063 /* Now determine new state and whether it has changed. 14064 * Use some helper variables to simplify the writing 14065 * of the expressions. 14066 */ 14067 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 14068 is_reachable = pingtime <= peer->maxms; 14069 statechanged = peer->lastms == 0 /* yes, unknown before */ 14070 || was_reachable != is_reachable; 14071 14072 peer->lastms = pingtime; 14073 peer->call = NULL; 14074 if (statechanged) { 14075 const char *s = is_reachable ? "Reachable" : "Lagged"; 14076 char str_lastms[20]; 14077 snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime); 14078 14079 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 14080 peer->name, s, pingtime, peer->maxms); 14081 ast_device_state_changed("SIP/%s", peer->name); 14082 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) { 14083 ast_update_realtime("sippeers", "name", peer->name, "lastms", str_lastms, NULL); 14084 } 14085 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 14086 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 14087 peer->name, s, pingtime); 14088 } 14089 14090 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 14091 struct sip_peer *peer_ptr = peer; 14092 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 14093 } 14094 14095 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14096 14097 /* Try again eventually */ 14098 peer->pokeexpire = ast_sched_add(sched, 14099 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 14100 sip_poke_peer_s, ASTOBJ_REF(peer)); 14101 14102 if (peer->pokeexpire == -1) { 14103 ASTOBJ_UNREF(peer, sip_destroy_peer); 14104 } 14105 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 13856 of file chan_sip.c.
References AST_CONTROL_CONGESTION, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_set_flag, ast_strlen_zero(), sip_pvt::authname, sip_pvt::authtries, sip_pvt::callid, do_proxy_auth(), sip_pvt::flags, get_header(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::owner, sip_pvt::recv, sip_pvt::refer, REFER_ACCEPTED, REFER_FAILED, REFER_NOAUTH, sip_refer::refer_to, SIP_NEEDDESTROY, SIP_REFER, and sip_refer::status.
Referenced by handle_response().
13857 { 13858 char *auth = "Proxy-Authenticate"; 13859 char *auth2 = "Proxy-Authorization"; 13860 13861 /* If no refer structure exists, then do nothing */ 13862 if (!p->refer) 13863 return; 13864 13865 switch (resp) { 13866 case 202: /* Transfer accepted */ 13867 /* We need to do something here */ 13868 /* The transferee is now sending INVITE to target */ 13869 p->refer->status = REFER_ACCEPTED; 13870 /* Now wait for next message */ 13871 if (option_debug > 2) 13872 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 13873 /* We should hang along, waiting for NOTIFY's here */ 13874 break; 13875 13876 case 401: /* Not www-authorized on SIP method */ 13877 case 407: /* Proxy auth */ 13878 if (ast_strlen_zero(p->authname)) { 13879 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 13880 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 13881 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13882 } 13883 if (resp == 401) { 13884 auth = "WWW-Authenticate"; 13885 auth2 = "Authorization"; 13886 } 13887 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 13888 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 13889 p->refer->status = REFER_NOAUTH; 13890 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13891 } 13892 break; 13893 case 481: /* Call leg does not exist */ 13894 13895 /* A transfer with Replaces did not work */ 13896 /* OEJ: We should Set flag, cancel the REFER, go back 13897 to original call - but right now we can't */ 13898 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 13899 if (p->owner) 13900 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13901 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13902 break; 13903 13904 case 500: /* Server error */ 13905 case 501: /* Method not implemented */ 13906 /* Return to the current call onhold */ 13907 /* Status flag needed to be reset */ 13908 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 13909 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13910 p->refer->status = REFER_FAILED; 13911 break; 13912 case 603: /* Transfer declined */ 13913 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 13914 p->refer->status = REFER_FAILED; 13915 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13916 break; 13917 } 13918 }
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 13921 of file chan_sip.c.
References __get_header(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_strlen_zero(), ASTOBJ_UNREF, sip_pvt::authtries, sip_registry::call, sip_pvt::callid, sip_registry::contact, DEFAULT_TRANS_TIMEOUT, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, EXPIRY_GUARD_LIMIT, EXPIRY_GUARD_MIN, EXPIRY_GUARD_PCT, EXPIRY_GUARD_SECS, sip_pvt::flags, get_header(), sip_registry::hostname, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), MAX, MAX_AUTHTRIES, option_debug, sip_pvt::our_contact, sip_pvt::peername, sip_registry::refresh, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), sip_registry::regtime, S_OR, SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, strcasestr(), sip_registry::timeout, sip_pvt::username, and sip_registry::username.
Referenced by handle_response().
13922 { 13923 int expires, expires_ms; 13924 struct sip_registry *r; 13925 r=p->registry; 13926 13927 switch (resp) { 13928 case 401: /* Unauthorized */ 13929 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 13930 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 13931 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13932 } 13933 break; 13934 case 403: /* Forbidden */ 13935 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 13936 if (global_regattempts_max) 13937 p->registry->regattempts = global_regattempts_max+1; 13938 AST_SCHED_DEL(sched, r->timeout); 13939 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13940 break; 13941 case 404: /* Not found */ 13942 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 13943 if (global_regattempts_max) 13944 p->registry->regattempts = global_regattempts_max+1; 13945 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13946 r->call = NULL; 13947 AST_SCHED_DEL(sched, r->timeout); 13948 break; 13949 case 407: /* Proxy auth */ 13950 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 13951 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 13952 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13953 } 13954 break; 13955 case 408: /* Request timeout */ 13956 /* Got a timeout response, so reset the counter of failed responses */ 13957 if (r) { 13958 r->regattempts = 0; 13959 } else { 13960 ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid); 13961 } 13962 break; 13963 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 13964 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 13965 if (global_regattempts_max) 13966 p->registry->regattempts = global_regattempts_max+1; 13967 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13968 r->call = NULL; 13969 AST_SCHED_DEL(sched, r->timeout); 13970 break; 13971 case 200: /* 200 OK */ 13972 if (!r) { 13973 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)); 13974 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13975 return 0; 13976 } 13977 13978 r->regstate = REG_STATE_REGISTERED; 13979 r->regtime = time(NULL); /* Reset time of last succesful registration */ 13980 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 13981 r->regattempts = 0; 13982 if (option_debug) 13983 ast_log(LOG_DEBUG, "Registration successful\n"); 13984 if (r->timeout > -1) { 13985 if (option_debug) 13986 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 13987 } 13988 AST_SCHED_DEL(sched, r->timeout); 13989 r->call = NULL; 13990 p->registry = NULL; 13991 /* Let this one hang around until we have all the responses */ 13992 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13993 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 13994 13995 /* set us up for re-registering */ 13996 /* figure out how long we got registered for */ 13997 AST_SCHED_DEL(sched, r->expire); 13998 /* according to section 6.13 of RFC, contact headers override 13999 expires headers, so check those first */ 14000 expires = 0; 14001 14002 /* XXX todo: try to save the extra call */ 14003 if (!ast_strlen_zero(get_header(req, "Contact"))) { 14004 const char *contact = NULL; 14005 const char *tmptmp = NULL; 14006 int start = 0; 14007 for(;;) { 14008 contact = __get_header(req, "Contact", &start); 14009 /* this loop ensures we get a contact header about our register request */ 14010 if(!ast_strlen_zero(contact)) { 14011 if( (tmptmp=strstr(contact, p->our_contact))) { 14012 contact=tmptmp; 14013 break; 14014 } 14015 } else 14016 break; 14017 } 14018 tmptmp = strcasestr(contact, "expires="); 14019 if (tmptmp) { 14020 if (sscanf(tmptmp + 8, "%30d;", &expires) != 1) 14021 expires = 0; 14022 } 14023 14024 } 14025 if (!expires) 14026 expires=atoi(get_header(req, "expires")); 14027 if (!expires) 14028 expires=default_expiry; 14029 14030 expires_ms = expires * 1000; 14031 if (expires <= EXPIRY_GUARD_LIMIT) 14032 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 14033 else 14034 expires_ms -= EXPIRY_GUARD_SECS * 1000; 14035 if (sipdebug) 14036 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 14037 14038 r->refresh= (int) expires_ms / 1000; 14039 14040 /* Schedule re-registration before we expire */ 14041 AST_SCHED_DEL(sched, r->expire); 14042 r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 14043 ASTOBJ_UNREF(r, sip_registry_destroy); 14044 } 14045 return 1; 14046 }
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 3781 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, ast_log(), LOG_DEBUG, and option_debug.
Referenced by sip_hangup().
03782 { 03783 switch (cause) { 03784 case AST_CAUSE_UNALLOCATED: /* 1 */ 03785 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03786 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03787 return "404 Not Found"; 03788 case AST_CAUSE_CONGESTION: /* 34 */ 03789 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03790 return "503 Service Unavailable"; 03791 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03792 return "408 Request Timeout"; 03793 case AST_CAUSE_NO_ANSWER: /* 19 */ 03794 case AST_CAUSE_UNREGISTERED: /* 20 */ 03795 return "480 Temporarily unavailable"; 03796 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03797 return "403 Forbidden"; 03798 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03799 return "410 Gone"; 03800 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03801 return "480 Temporarily unavailable"; 03802 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03803 return "484 Address incomplete"; 03804 case AST_CAUSE_USER_BUSY: 03805 return "486 Busy here"; 03806 case AST_CAUSE_FAILURE: 03807 return "500 Server internal failure"; 03808 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03809 return "501 Not Implemented"; 03810 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03811 return "503 Service Unavailable"; 03812 /* Used in chan_iax2 */ 03813 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03814 return "502 Bad Gateway"; 03815 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03816 return "488 Not Acceptable Here"; 03817 03818 case AST_CAUSE_NOTDEFINED: 03819 default: 03820 if (option_debug) 03821 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03822 return NULL; 03823 } 03824 03825 /* Never reached */ 03826 return 0; 03827 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3669 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().
03670 { 03671 /* Possible values taken from causes.h */ 03672 03673 switch(cause) { 03674 case 401: /* Unauthorized */ 03675 return AST_CAUSE_CALL_REJECTED; 03676 case 403: /* Not found */ 03677 return AST_CAUSE_CALL_REJECTED; 03678 case 404: /* Not found */ 03679 return AST_CAUSE_UNALLOCATED; 03680 case 405: /* Method not allowed */ 03681 return AST_CAUSE_INTERWORKING; 03682 case 407: /* Proxy authentication required */ 03683 return AST_CAUSE_CALL_REJECTED; 03684 case 408: /* No reaction */ 03685 return AST_CAUSE_NO_USER_RESPONSE; 03686 case 409: /* Conflict */ 03687 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03688 case 410: /* Gone */ 03689 return AST_CAUSE_NUMBER_CHANGED; 03690 case 411: /* Length required */ 03691 return AST_CAUSE_INTERWORKING; 03692 case 413: /* Request entity too large */ 03693 return AST_CAUSE_INTERWORKING; 03694 case 414: /* Request URI too large */ 03695 return AST_CAUSE_INTERWORKING; 03696 case 415: /* Unsupported media type */ 03697 return AST_CAUSE_INTERWORKING; 03698 case 420: /* Bad extension */ 03699 return AST_CAUSE_NO_ROUTE_DESTINATION; 03700 case 480: /* No answer */ 03701 return AST_CAUSE_NO_ANSWER; 03702 case 481: /* No answer */ 03703 return AST_CAUSE_INTERWORKING; 03704 case 482: /* Loop detected */ 03705 return AST_CAUSE_INTERWORKING; 03706 case 483: /* Too many hops */ 03707 return AST_CAUSE_NO_ANSWER; 03708 case 484: /* Address incomplete */ 03709 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03710 case 485: /* Ambigous */ 03711 return AST_CAUSE_UNALLOCATED; 03712 case 486: /* Busy everywhere */ 03713 return AST_CAUSE_BUSY; 03714 case 487: /* Request terminated */ 03715 return AST_CAUSE_INTERWORKING; 03716 case 488: /* No codecs approved */ 03717 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03718 case 491: /* Request pending */ 03719 return AST_CAUSE_INTERWORKING; 03720 case 493: /* Undecipherable */ 03721 return AST_CAUSE_INTERWORKING; 03722 case 500: /* Server internal failure */ 03723 return AST_CAUSE_FAILURE; 03724 case 501: /* Call rejected */ 03725 return AST_CAUSE_FACILITY_REJECTED; 03726 case 502: 03727 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03728 case 503: /* Service unavailable */ 03729 return AST_CAUSE_CONGESTION; 03730 case 504: /* Gateway timeout */ 03731 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03732 case 505: /* SIP version not supported */ 03733 return AST_CAUSE_INTERWORKING; 03734 case 600: /* Busy everywhere */ 03735 return AST_CAUSE_USER_BUSY; 03736 case 603: /* Decline */ 03737 return AST_CAUSE_CALL_REJECTED; 03738 case 604: /* Does not exist anywhere */ 03739 return AST_CAUSE_UNALLOCATED; 03740 case 606: /* Not acceptable */ 03741 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03742 default: 03743 return AST_CAUSE_NORMAL; 03744 } 03745 /* Never reached */ 03746 return 0; 03747 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 6711 of file chan_sip.c.
References sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::method, sip_methods, and cfsip_methods::text.
Referenced by initreqprep(), reqprep(), and transmit_register().
06712 { 06713 /* Initialize a request */ 06714 memset(req, 0, sizeof(*req)); 06715 req->method = sipmethod; 06716 req->header[0] = req->data; 06717 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 06718 req->len = strlen(req->header[0]); 06719 req->headers++; 06720 return 0; 06721 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 6698 of file chan_sip.c.
References sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::method, and SIP_RESPONSE.
Referenced by respprep().
06699 { 06700 /* Initialize a response */ 06701 memset(resp, 0, sizeof(*resp)); 06702 resp->method = SIP_RESPONSE; 06703 resp->header[0] = resp->data; 06704 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 06705 resp->len = strlen(resp->header[0]); 06706 resp->headers++; 06707 return 0; 06708 }
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 1759 of file chan_sip.c.
References ast_log(), ast_test_flag, ast_verbose(), sip_pvt::callid, copy_request(), sip_request::headers, sip_pvt::initreq, sip_request::lines, LOG_DEBUG, option_debug, parse_request(), and SIP_PKT_DEBUG.
Referenced by transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), and transmit_sip_request().
01760 { 01761 if (p->initreq.headers && option_debug) { 01762 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01763 } 01764 /* Use this as the basis */ 01765 copy_request(&p->initreq, req); 01766 parse_request(&p->initreq); 01767 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01768 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01769 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 7866 of file chan_sip.c.
References add_header(), add_route(), ast_build_string(), AST_DIGIT_ANYNUM, ast_inet_ntoa(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, 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, FROMDOMAIN_INVALID, 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::portinuri, sip_pvt::route, sip_pvt::rpid, sip_pvt::rpid_from, s, S_OR, sip_pvt::sa, SIP_INVITE, sip_methods, SIP_NOTIFY, SIP_SENDRPID, SIP_USEREQPHONE, SIPBUFSIZE, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, sip_pvt::tohost, 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().
07867 { 07868 char invite_buf[256] = ""; 07869 char *invite = invite_buf; 07870 size_t invite_max = sizeof(invite_buf); 07871 char from[256]; 07872 char to[256]; 07873 char tmp[SIPBUFSIZE/2]; 07874 char tmp2[SIPBUFSIZE/2]; 07875 const char *l = NULL, *n = NULL, *d = NULL; 07876 const char *urioptions = ""; 07877 07878 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 07879 const char *s = p->username; /* being a string field, cannot be NULL */ 07880 07881 /* Test p->username against allowed characters in AST_DIGIT_ANY 07882 If it matches the allowed characters list, then sipuser = ";user=phone" 07883 If not, then sipuser = "" 07884 */ 07885 /* + is allowed in first position in a tel: uri */ 07886 if (*s == '+') 07887 s++; 07888 for (; *s; s++) { 07889 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 07890 break; 07891 } 07892 /* If we have only digits, add ;user=phone to the uri */ 07893 if (!*s) 07894 urioptions = ";user=phone"; 07895 } 07896 07897 07898 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 07899 07900 d = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 07901 if (p->owner) { 07902 l = p->owner->cid.cid_num; 07903 n = p->owner->cid.cid_name; 07904 } 07905 /* if we are not sending RPID and user wants his callerid restricted */ 07906 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 07907 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 07908 l = CALLERID_UNKNOWN; 07909 n = l; 07910 d = FROMDOMAIN_INVALID; 07911 } 07912 if (ast_strlen_zero(l)) 07913 l = default_callerid; 07914 if (ast_strlen_zero(n)) 07915 n = l; 07916 /* Allow user to be overridden */ 07917 if (!ast_strlen_zero(p->fromuser)) 07918 l = p->fromuser; 07919 else /* Save for any further attempts */ 07920 ast_string_field_set(p, fromuser, l); 07921 07922 /* Allow user to be overridden */ 07923 if (!ast_strlen_zero(p->fromname)) 07924 n = p->fromname; 07925 else /* Save for any further attempts */ 07926 ast_string_field_set(p, fromname, n); 07927 07928 if (pedanticsipchecking) { 07929 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07930 n = tmp; 07931 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 07932 l = tmp2; 07933 } 07934 07935 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 07936 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, d, ourport, p->tag); 07937 else 07938 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, d, p->tag); 07939 07940 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 07941 if (!ast_strlen_zero(p->fullcontact)) { 07942 /* If we have full contact, trust it */ 07943 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 07944 } else { 07945 /* Otherwise, use the username while waiting for registration */ 07946 ast_build_string(&invite, &invite_max, "sip:"); 07947 if (!ast_strlen_zero(p->username)) { 07948 n = p->username; 07949 if (pedanticsipchecking) { 07950 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07951 n = tmp; 07952 } 07953 ast_build_string(&invite, &invite_max, "%s@", n); 07954 } 07955 ast_build_string(&invite, &invite_max, "%s", p->tohost); 07956 if (p->portinuri) 07957 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 07958 ast_build_string(&invite, &invite_max, "%s", urioptions); 07959 } 07960 07961 /* If custom URI options have been provided, append them */ 07962 if (p->options && !ast_strlen_zero(p->options->uri_options)) 07963 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 07964 07965 ast_string_field_set(p, uri, invite_buf); 07966 07967 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 07968 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 07969 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (!strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); 07970 } else if (p->options && p->options->vxml_url) { 07971 /* If there is a VXML URL append it to the SIP URL */ 07972 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 07973 } else 07974 snprintf(to, sizeof(to), "<%s>", p->uri); 07975 07976 init_req(req, sipmethod, p->uri); 07977 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 07978 07979 add_header(req, "Via", p->via); 07980 /* This will be a no-op most of the time. However, under certain circumstances, 07981 * NOTIFY messages will use this function for preparing the request and should 07982 * have Route headers present. 07983 */ 07984 add_route(req, p->route); 07985 /* Build Remote Party-ID and From */ 07986 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 07987 build_rpid(p); 07988 add_header(req, "From", p->rpid_from); 07989 } else 07990 add_header(req, "From", from); 07991 add_header(req, "To", to); 07992 ast_string_field_set(p, exten, l); 07993 build_contact(p); 07994 add_header(req, "Contact", p->our_contact); 07995 add_header(req, "Call-ID", p->callid); 07996 add_header(req, "CSeq", tmp); 07997 if (!ast_strlen_zero(global_useragent)) 07998 add_header(req, "User-Agent", global_useragent); 07999 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 08000 if (!ast_strlen_zero(p->rpid)) 08001 add_header(req, "Remote-Party-ID", p->rpid); 08002 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | [static] |
Convert Insecure setting to printable string.
Definition at line 11474 of file chan_sip.c.
Referenced by _sip_show_peer().
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 9268 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
09269 { 09270 if (!route) 09271 ast_verbose("list_route: no route\n"); 09272 else { 09273 for (;route; route = route->next) 09274 ast_verbose("list_route: hop: <%s>\n", route->hop); 09275 } 09276 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 20321 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(), ASTOBJ_CONTAINER_INIT, CHANNEL_MODULE_LOAD, checksipdomain_function, EVENT_FLAG_SYSTEM, io_context_create(), io_context_destroy(), LOG_ERROR, manager_sip_show_peer(), manager_sip_show_peers(), mandescr_show_peer, mandescr_show_peers, peerl, regl, reload_config(), restart_monitor(), sched_context_create(), sched_context_destroy(), sip_addheader(), sip_dtmfmode(), sip_header_function, sip_poke_all_peers(), sip_rtp, sip_send_all_registers(), sip_tech, sip_udptl, sipchaninfo_function, sippeer_function, and userl.
20322 { 20323 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 20324 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 20325 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 20326 20327 if (!(sched = sched_context_create())) { 20328 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 20329 return AST_MODULE_LOAD_FAILURE; 20330 } 20331 20332 if (!(io = io_context_create())) { 20333 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 20334 sched_context_destroy(sched); 20335 return AST_MODULE_LOAD_FAILURE; 20336 } 20337 20338 sip_reloadreason = CHANNEL_MODULE_LOAD; 20339 20340 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 20341 return AST_MODULE_LOAD_DECLINE; 20342 20343 /* Make sure we can register our sip channel type */ 20344 if (ast_channel_register(&sip_tech)) { 20345 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 20346 io_context_destroy(io); 20347 sched_context_destroy(sched); 20348 return AST_MODULE_LOAD_FAILURE; 20349 } 20350 20351 /* Register all CLI functions for SIP */ 20352 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 20353 20354 /* Tell the RTP subdriver that we're here */ 20355 ast_rtp_proto_register(&sip_rtp); 20356 20357 /* Tell the UDPTL subdriver that we're here */ 20358 ast_udptl_proto_register(&sip_udptl); 20359 20360 /* Register dialplan applications */ 20361 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 20362 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 20363 20364 /* Register dialplan functions */ 20365 ast_custom_function_register(&sip_header_function); 20366 ast_custom_function_register(&sippeer_function); 20367 ast_custom_function_register(&sipchaninfo_function); 20368 ast_custom_function_register(&checksipdomain_function); 20369 20370 /* Register manager commands */ 20371 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 20372 "List SIP peers (text format)", mandescr_show_peers); 20373 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 20374 "Show SIP peer (text format)", mandescr_show_peer); 20375 20376 sip_poke_all_peers(); 20377 sip_send_all_registers(); 20378 20379 /* And start the monitor for the first time */ 20380 restart_monitor(); 20381 20382 return AST_MODULE_LOAD_SUCCESS; 20383 }
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 16078 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), ast_channel_unlock, ast_clear_flag, AST_CONTROL_UNHOLD, ast_hangup(), ast_indicate(), ast_log(), ast_mutex_unlock(), ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, attempt_transfer(), sip_dual::chan1, sip_dual::chan2, sip_pvt::flags, get_sip_pvt_byid_locked(), sip_refer::localtransfer, sip_pvt::lock, LOG_DEBUG, option_debug, 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, sipdebug, sip_refer::status, transmit_notify_with_sipfrag(), and TRUE.
Referenced by handle_request_refer().
16079 { 16080 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 16081 /* Chan 2: Call from Asterisk to target */ 16082 int res = 0; 16083 struct sip_pvt *targetcall_pvt; 16084 16085 /* Check if the call ID of the replaces header does exist locally */ 16086 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 16087 transferer->refer->replaces_callid_fromtag))) { 16088 if (transferer->refer->localtransfer) { 16089 /* We did not find the refered call. Sorry, can't accept then */ 16090 /* Let's fake a response from someone else in order 16091 to follow the standard */ 16092 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 16093 append_history(transferer, "Xfer", "Refer failed"); 16094 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 16095 transferer->refer->status = REFER_FAILED; 16096 return -1; 16097 } 16098 /* Fall through for remote transfers that we did not find locally */ 16099 if (option_debug > 2) 16100 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 16101 return 0; 16102 } 16103 16104 /* Ok, we can accept this transfer */ 16105 append_history(transferer, "Xfer", "Refer accepted"); 16106 if (!targetcall_pvt->owner) { /* No active channel */ 16107 if (option_debug > 3) 16108 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 16109 /* Cancel transfer */ 16110 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 16111 append_history(transferer, "Xfer", "Refer failed"); 16112 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 16113 transferer->refer->status = REFER_FAILED; 16114 ast_mutex_unlock(&targetcall_pvt->lock); 16115 return -1; 16116 } 16117 16118 /* We have a channel, find the bridge */ 16119 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 16120 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 16121 16122 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 16123 /* Wrong state of new channel */ 16124 if (option_debug > 3) { 16125 if (target.chan2) 16126 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 16127 else if (target.chan1->_state != AST_STATE_RING) 16128 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 16129 else 16130 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 16131 } 16132 } 16133 16134 /* Transfer */ 16135 if (option_debug > 3 && sipdebug) { 16136 if (current->chan2) /* We have two bridges */ 16137 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 16138 else /* One bridge, propably transfer of IVR/voicemail etc */ 16139 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 16140 } 16141 16142 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 16143 16144 /* Perform the transfer */ 16145 res = attempt_transfer(current, &target); 16146 ast_mutex_unlock(&targetcall_pvt->lock); 16147 if (res) { 16148 /* Failed transfer */ 16149 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 16150 append_history(transferer, "Xfer", "Refer failed"); 16151 transferer->refer->status = REFER_FAILED; 16152 if (targetcall_pvt->owner) 16153 ast_channel_unlock(targetcall_pvt->owner); 16154 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 16155 if (res != -2) 16156 ast_hangup(transferer->owner); 16157 else 16158 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 16159 } else { 16160 /* Transfer succeeded! */ 16161 16162 /* Tell transferer that we're done. */ 16163 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 16164 append_history(transferer, "Xfer", "Refer succeeded"); 16165 transferer->refer->status = REFER_200OK; 16166 if (targetcall_pvt->owner) { 16167 if (option_debug) 16168 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 16169 ast_channel_unlock(targetcall_pvt->owner); 16170 } 16171 ast_indicate(target.chan1, AST_CONTROL_UNHOLD); 16172 if (target.chan2) { 16173 ast_indicate(target.chan2, AST_CONTROL_UNHOLD); 16174 } 16175 } 16176 return 1; 16177 }
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 5387 of file chan_sip.c.
References t.
Referenced by sipsock_read().
05388 { 05389 int h = 0, t = 0; 05390 int lws = 0; 05391 05392 for (; h < len;) { 05393 /* Eliminate all CRs */ 05394 if (msgbuf[h] == '\r') { 05395 h++; 05396 continue; 05397 } 05398 /* Check for end-of-line */ 05399 if (msgbuf[h] == '\n') { 05400 /* Check for end-of-message */ 05401 if (h + 1 == len) 05402 break; 05403 /* Check for a continuation line */ 05404 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 05405 /* Merge continuation line */ 05406 h++; 05407 continue; 05408 } 05409 /* Propagate LF and start new line */ 05410 msgbuf[t++] = msgbuf[h++]; 05411 lws = 0; 05412 continue; 05413 } 05414 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 05415 if (lws) { 05416 h++; 05417 continue; 05418 } 05419 msgbuf[t++] = msgbuf[h++]; 05420 lws = 1; 05421 continue; 05422 } 05423 msgbuf[t++] = msgbuf[h++]; 05424 if (lws) 05425 lws = 0; 05426 } 05427 msgbuf[t] = '\0'; 05428 return t; 05429 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4864 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().
04865 { 04866 snprintf(tagbuf, len, "as%08lx", ast_random()); 04867 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 11726 of file chan_sip.c.
References _sip_show_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), and astman_send_error().
Referenced by load_module().
11727 { 11728 const char *a[4]; 11729 const char *peer; 11730 int ret; 11731 11732 peer = astman_get_header(m,"Peer"); 11733 if (ast_strlen_zero(peer)) { 11734 astman_send_error(s, m, "Peer: <name> missing."); 11735 return 0; 11736 } 11737 a[0] = "sip"; 11738 a[1] = "show"; 11739 a[2] = "peer"; 11740 a[3] = peer; 11741 11742 ret = _sip_show_peer(1, -1, s, m, 4, a); 11743 astman_append(s, "\r\n\r\n" ); 11744 return ret; 11745 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 11270 of file chan_sip.c.
References _sip_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), and total.
Referenced by load_module().
11271 { 11272 const char *id = astman_get_header(m,"ActionID"); 11273 const char *a[] = {"sip", "show", "peers"}; 11274 char idtext[256] = ""; 11275 int total = 0; 11276 11277 if (!ast_strlen_zero(id)) 11278 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 11279 11280 astman_send_ack(s, m, "Peer status list will follow"); 11281 /* List the peers in separate manager events */ 11282 _sip_show_peers(-1, &total, s, m, 3, a); 11283 /* Send final confirmation */ 11284 astman_append(s, 11285 "Event: PeerlistComplete\r\n" 11286 "ListItems: %d\r\n" 11287 "%s" 11288 "\r\n", total, idtext); 11289 return 0; 11290 }
static void markall_extenstate_updates | ( | void | ) | [static] |
Definition at line 9717 of file chan_sip.c.
References AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, sip_extenstate_update::marked, and update().
Referenced by do_monitor().
09718 { 09719 struct sip_extenstate_update *update = NULL; 09720 09721 if (AST_LIST_EMPTY(&sip_extenstate_updates)) { 09722 /* avoid holding the lock if possible */ 09723 return; 09724 } 09725 09726 AST_LIST_LOCK(&sip_extenstate_updates); 09727 AST_LIST_TRAVERSE(&sip_extenstate_updates, update, list) { 09728 update->marked = 1; 09729 } 09730 AST_LIST_UNLOCK(&sip_extenstate_updates); 09731 }
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 1785 of file chan_sip.c.
References sip_request::len, sip_methods, and text.
Referenced by __sip_autodestruct(), __sip_semi_ack(), and find_sip_method().
01786 { 01787 int len = strlen(sip_methods[id].text); 01788 int l_name = name ? strlen(name) : 0; 01789 /* true if the string is long enough, and ends with whitespace, and matches */ 01790 return (l_name >= len && name[len] < 33 && 01791 !strncasecmp(sip_methods[id].text, name, len)); 01792 }
static char * nat2str | ( | int | nat | ) | [static] |
Convert NAT setting to text string.
Definition at line 11173 of file chan_sip.c.
References SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, and SIP_NAT_ROUTE.
Referenced by _sip_show_peer(), display_nat_warning(), sip_show_channel(), sip_show_settings(), and sip_show_users().
11174 { 11175 switch(nat) { 11176 case SIP_NAT_NEVER: 11177 return "No"; 11178 case SIP_NAT_ROUTE: 11179 return "Route"; 11180 case SIP_NAT_ALWAYS: 11181 return "Always"; 11182 case SIP_NAT_RFC3581: 11183 return "RFC3581"; 11184 default: 11185 return "Unknown"; 11186 } 11187 }
static int notify_extenstate_update | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 9760 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_verbose(), sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, sip_pvt::laststate, sip_pvt::lock, LOG_WARNING, NONE, option_verbose, sip_pvt::pendinginvite, sip_cancel_destroy(), SIP_PAGE2_STATECHANGEQUEUE, sip_scheddestroy(), sip_pvt::stateid, sip_pvt::subscribed, transmit_state_notify(), sip_pvt::username, VERBOSE_PREFIX_1, and VERBOSE_PREFIX_2.
Referenced by check_extenstate_updates(), and handle_response().
09761 { 09762 struct sip_pvt *p = data; 09763 09764 ast_mutex_lock(&p->lock); 09765 09766 switch(state) { 09767 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 09768 case AST_EXTENSION_REMOVED: /* Extension is gone */ 09769 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 09770 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09771 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 09772 ast_verbose(VERBOSE_PREFIX_2 "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username); 09773 p->stateid = -1; 09774 p->subscribed = NONE; 09775 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 09776 break; 09777 default: /* Tell user */ 09778 p->laststate = state; 09779 break; 09780 } 09781 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 09782 if (!p->pendinginvite) { 09783 transmit_state_notify(p, state, 1, FALSE); 09784 } else { 09785 /* We already have a NOTIFY sent that is not answered. Queue the state up. 09786 if many state changes happen meanwhile, we will only send a notification of the last one */ 09787 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 09788 } 09789 } 09790 if (option_verbose > 1) 09791 ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username, 09792 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 09793 09794 09795 ast_mutex_unlock(&p->lock); 09796 09797 return 0; 09798 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 2387 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 13404 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_test_flag, ast_uri_decode(), sip_pvt::flags, get_header(), get_in_brackets(), LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), s, SIP_PROMISCREDIR, SIPBUFSIZE, and t.
Referenced by handle_response().
13405 { 13406 char tmp[SIPBUFSIZE]; 13407 char *s, *e, *uri, *t; 13408 char *domain; 13409 13410 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 13411 if ((t = strchr(tmp, ','))) 13412 *t = '\0'; 13413 s = get_in_brackets(tmp); 13414 uri = ast_strdupa(s); 13415 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 13416 if (!strncasecmp(s, "sip:", 4)) 13417 s += 4; 13418 e = strchr(s, ';'); 13419 if (e) 13420 *e = '\0'; 13421 if (option_debug) 13422 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 13423 if (p->owner) 13424 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 13425 } else { 13426 e = strchr(tmp, '@'); 13427 if (e) { 13428 *e++ = '\0'; 13429 domain = e; 13430 } else { 13431 /* No username part */ 13432 domain = tmp; 13433 } 13434 e = strchr(s, ';'); /* Strip of parameters in the username part */ 13435 if (e) 13436 *e = '\0'; 13437 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 13438 if (e) 13439 *e = '\0'; 13440 13441 if (!strncasecmp(s, "sip:", 4)) 13442 s += 4; 13443 ast_uri_decode(s); 13444 if (option_debug > 1) 13445 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 13446 if (p->owner) { 13447 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 13448 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 13449 ast_string_field_set(p->owner, call_forward, s); 13450 } 13451 } 13452 }
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 8977 of file chan_sip.c.
References ast_copy_string(), ast_string_field_set, sip_peer::fullcontact, get_header(), get_in_brackets(), SIPBUFSIZE, and TRUE.
Referenced by handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
08978 { 08979 char contact[SIPBUFSIZE]; 08980 char *c; 08981 08982 /* Look for brackets */ 08983 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08984 c = get_in_brackets(contact); 08985 08986 /* Save full contact to call pvt for later bye or re-invite */ 08987 ast_string_field_set(pvt, fullcontact, c); 08988 08989 /* Save URI for later ACKs, BYE or RE-invites */ 08990 ast_string_field_set(pvt, okcontacturi, c); 08991 08992 /* We should return false for URI:s we can't handle, 08993 like sips:, tel:, mailto:,ldap: etc */ 08994 return TRUE; 08995 }
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 9066 of file chan_sip.c.
References __get_header(), sip_peer::addr, 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_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::contactha, sip_request::data, EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), hp, inaddrcmp(), LOG_NOTICE, LOG_WARNING, manager_event(), sip_peer::name, option_verbose, PARSE_REGISTER_DENIED, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_peer::portinuri, sip_pvt::recv, register_peer_exten(), sip_destroy_peer(), SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_RTCACHEFRIENDS, sip_poke_peer(), SIP_REALTIME, SIPBUFSIZE, sip_pvt::sipoptions, sip_peer::sipoptions, STANDARD_SIP_PORT, strcasestr(), strsep(), sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.
Referenced by register_verify().
09067 { 09068 char contact[SIPBUFSIZE]; 09069 char data[SIPBUFSIZE]; 09070 const char *expires = get_header(req, "Expires"); 09071 int expiry = atoi(expires); 09072 char *curi, *n, *pt; 09073 int port; 09074 const char *useragent; 09075 struct hostent *hp; 09076 struct ast_hostent ahp; 09077 struct sockaddr_in oldsin, testsin; 09078 char *firstcuri = NULL; 09079 int start = 0; 09080 int wildcard_found = 0; 09081 int single_binding_found = 0; 09082 09083 ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact)); 09084 09085 if (ast_strlen_zero(expires)) { /* No expires header */ 09086 expires = strcasestr(contact, ";expires="); 09087 if (expires) { 09088 /* XXX bug here, we overwrite the string */ 09089 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 09090 if (sscanf(expires + 9, "%30d", &expiry) != 1) 09091 expiry = default_expiry; 09092 } else { 09093 /* Nothing has been specified */ 09094 expiry = default_expiry; 09095 } 09096 } 09097 09098 do { 09099 /* Look for brackets */ 09100 curi = contact; 09101 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 09102 strsep(&curi, ";"); /* This is Header options, not URI options */ 09103 curi = get_in_brackets(contact); 09104 if (!firstcuri) { 09105 firstcuri = ast_strdupa(curi); 09106 } 09107 09108 if (!strcasecmp(curi, "*")) { 09109 wildcard_found = 1; 09110 } else { 09111 single_binding_found = 1; 09112 } 09113 09114 if (wildcard_found && (ast_strlen_zero(expires) || expiry != 0 || single_binding_found)) { 09115 /* Contact header parameter "*" detected, so punt if: Expires header is missing, 09116 * Expires value is not zero, or another Contact header is present. */ 09117 return PARSE_REGISTER_FAILED; 09118 } 09119 09120 ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact)); 09121 } while (!ast_strlen_zero(contact)); 09122 curi = firstcuri; 09123 09124 /* if they did not specify Contact: or Expires:, they are querying 09125 what we currently have stored as their contact address, so return 09126 it 09127 */ 09128 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 09129 /* If we have an active registration, tell them when the registration is going to expire */ 09130 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 09131 pvt->expiry = ast_sched_when(sched, peer->expire); 09132 return PARSE_REGISTER_QUERY; 09133 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 09134 /* This means remove all registrations and return OK */ 09135 if (!AST_SCHED_DEL(sched, peer->expire)) { 09136 struct sip_peer *peer_ptr = peer; 09137 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 09138 } 09139 09140 expire_register(ASTOBJ_REF(peer)); 09141 09142 if (option_verbose > 2) 09143 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 09144 09145 return PARSE_REGISTER_UPDATE; 09146 } 09147 09148 /* Store whatever we got as a contact from the client */ 09149 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 09150 09151 /* For the 200 OK, we should use the received contact */ 09152 ast_string_field_build(pvt, our_contact, "<%s>", curi); 09153 09154 /* Make sure it's a SIP URL */ 09155 if (strncasecmp(curi, "sip:", 4)) { 09156 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 09157 } else 09158 curi += 4; 09159 /* Ditch q */ 09160 curi = strsep(&curi, ";"); 09161 /* Grab host */ 09162 n = strchr(curi, '@'); 09163 if (!n) { 09164 n = curi; 09165 curi = NULL; 09166 } else 09167 *n++ = '\0'; 09168 pt = strchr(n, ':'); 09169 if (pt) { 09170 *pt++ = '\0'; 09171 port = atoi(pt); 09172 peer->portinuri = 1; 09173 } else { 09174 port = STANDARD_SIP_PORT; 09175 peer->portinuri = 0; 09176 } 09177 oldsin = peer->addr; 09178 09179 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 09180 /* use the data provided in the Contact header for call routing */ 09181 /* XXX This could block for a long time XXX */ 09182 hp = ast_gethostbyname(n, &ahp); 09183 if (!hp) { 09184 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 09185 *peer->fullcontact = '\0'; 09186 ast_string_field_set(pvt, our_contact, ""); 09187 return PARSE_REGISTER_FAILED; 09188 } 09189 09190 peer->addr.sin_family = AF_INET; 09191 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 09192 peer->addr.sin_port = htons(port); 09193 } else { 09194 /* Don't trust the contact field. Just use what they came to us 09195 with */ 09196 peer->addr = pvt->recv; 09197 } 09198 09199 /* Check that they're allowed to register at this IP */ 09200 memcpy(&testsin.sin_addr, &peer->addr.sin_addr, sizeof(testsin.sin_addr)); 09201 if (ast_apply_ha(global_contact_ha, &testsin) != AST_SENSE_ALLOW || 09202 ast_apply_ha(peer->contactha, &testsin) != AST_SENSE_ALLOW) { 09203 ast_log(LOG_WARNING, "Host '%s' disallowed by contact ACL (violating IP %s)\n", n, ast_inet_ntoa(testsin.sin_addr)); 09204 *peer->fullcontact = '\0'; 09205 ast_string_field_set(pvt, our_contact, ""); 09206 return PARSE_REGISTER_DENIED; 09207 } 09208 09209 /* Save SIP options profile */ 09210 peer->sipoptions = pvt->sipoptions; 09211 09212 if (curi && ast_strlen_zero(peer->username)) 09213 ast_copy_string(peer->username, curi, sizeof(peer->username)); 09214 09215 if (!AST_SCHED_DEL(sched, peer->expire)) { 09216 struct sip_peer *peer_ptr = peer; 09217 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 09218 } 09219 if (expiry > max_expiry) 09220 expiry = max_expiry; 09221 if (expiry < min_expiry) 09222 expiry = min_expiry; 09223 if (ast_test_flag(&peer->flags[0], SIP_REALTIME) && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 09224 peer->expire = -1; 09225 } else { 09226 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 09227 if (peer->expire == -1) { 09228 struct sip_peer *peer_ptr = peer; 09229 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 09230 } 09231 } 09232 pvt->expiry = expiry; 09233 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); 09234 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 09235 ast_db_put("SIP/Registry", peer->name, data); 09236 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 09237 09238 /* Is this a new IP address for us? */ 09239 if (option_verbose > 2 && inaddrcmp(&peer->addr, &oldsin)) { 09240 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)); 09241 } 09242 sip_poke_peer(peer); 09243 register_peer_exten(peer, 1); 09244 09245 /* Save User agent */ 09246 useragent = get_header(req, "User-Agent"); 09247 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 09248 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 09249 if (option_verbose > 3) 09250 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 09251 } 09252 return PARSE_REGISTER_UPDATE; 09253 }
static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 5434 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), sip_request::data, determine_firstline_parts(), f, sip_request::header, sip_request::headers, sip_request::line, sip_request::lines, LOG_DEBUG, LOG_WARNING, option_debug, SIP_MAX_HEADERS, SIP_MAX_LINES, and sipdebug.
Referenced by initialize_initreq(), parse_copy(), and sipsock_read().
05435 { 05436 /* Divide fields by NULL's */ 05437 char *c; 05438 int f = 0; 05439 05440 c = req->data; 05441 05442 /* First header starts immediately */ 05443 req->header[f] = c; 05444 while(*c) { 05445 if (*c == '\n') { 05446 /* We've got a new header */ 05447 *c = 0; 05448 05449 if (sipdebug && option_debug > 3) 05450 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 05451 if (ast_strlen_zero(req->header[f])) { 05452 /* Line by itself means we're now in content */ 05453 c++; 05454 break; 05455 } 05456 if (f >= SIP_MAX_HEADERS - 1) { 05457 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 05458 } else { 05459 f++; 05460 req->header[f] = c + 1; 05461 } 05462 } else if (*c == '\r') { 05463 /* Ignore but eliminate \r's */ 05464 *c = 0; 05465 } 05466 c++; 05467 } 05468 05469 req->headers = f; 05470 05471 /* Check a non-newline-terminated last header */ 05472 if (!ast_strlen_zero(req->header[f])) { 05473 if (sipdebug && option_debug > 3) 05474 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 05475 req->headers++; 05476 } 05477 05478 /* Now we process any body content */ 05479 f = 0; 05480 req->line[f] = c; 05481 while (*c) { 05482 if (*c == '\n') { 05483 /* We've got a new line */ 05484 *c = 0; 05485 if (sipdebug && option_debug > 3) 05486 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 05487 if (f == SIP_MAX_LINES - 1) { 05488 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 05489 break; 05490 } else { 05491 f++; 05492 req->line[f] = c + 1; 05493 } 05494 } else if (*c == '\r') { 05495 /* Ignore and eliminate \r's */ 05496 *c = 0; 05497 } 05498 c++; 05499 } 05500 05501 req->lines = f; 05502 05503 /* Check a non-newline-terminated last line */ 05504 if (!ast_strlen_zero(req->line[f])) { 05505 if (sipdebug && option_debug > 3) 05506 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 05507 req->lines++; 05508 } 05509 05510 if (*c) 05511 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 05512 05513 /* Split up the first line parts */ 05514 return determine_firstline_parts(req); 05515 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 1809 of file chan_sip.c.
References ast_log(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), FALSE, cfsip_options::id, LOG_DEBUG, option_debug, sip_options, sipdebug, sip_pvt::sipoptions, text, and TRUE.
Referenced by handle_request_invite().
01810 { 01811 char *next, *sep; 01812 char *temp; 01813 unsigned int profile = 0; 01814 int i, found; 01815 01816 if (ast_strlen_zero(supported) ) 01817 return 0; 01818 temp = ast_strdupa(supported); 01819 01820 if (option_debug > 2 && sipdebug) 01821 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01822 01823 for (next = temp; next; next = sep) { 01824 found = FALSE; 01825 if ( (sep = strchr(next, ',')) != NULL) 01826 *sep++ = '\0'; 01827 next = ast_skip_blanks(next); 01828 if (option_debug > 2 && sipdebug) 01829 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01830 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01831 if (!strcasecmp(next, sip_options[i].text)) { 01832 profile |= sip_options[i].id; 01833 found = TRUE; 01834 if (option_debug > 2 && sipdebug) 01835 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01836 break; 01837 } 01838 } 01839 if (!found && option_debug > 2 && sipdebug) { 01840 if (!strncasecmp(next, "x-", 2)) 01841 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01842 else 01843 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01844 } 01845 } 01846 01847 if (pvt) 01848 pvt->sipoptions = profile; 01849 return profile; 01850 }
static struct sip_via * parse_via | ( | const char * | header | ) | [static, read] |
Parse a Via header.
This function parses the Via header and processes it according to section 18.2 of RFC 3261 and RFC 3581. Since we don't have a transport layer, we only care about the maddr and ttl parms. The received and rport params are not parsed.
VIA syntax. RFC 3261 section 25.1 Via = ( "Via" / "v" ) HCOLON via-parm *(COMMA via-parm) via-parm = sent-protocol LWS sent-by *( SEMI via-params ) via-params = via-ttl / via-maddr / via-received / via-branch / via-extension via-ttl = "ttl" EQUAL ttl via-maddr = "maddr" EQUAL host via-received = "received" EQUAL (IPv4address / IPv6address) via-branch = "branch" EQUAL token via-extension = generic-param sent-protocol = protocol-name SLASH protocol-version SLASH transport protocol-name = "SIP" / token protocol-version = token transport = "UDP" / "TCP" / "TLS" / "SCTP" / other-transport sent-by = host [ COLON port ] ttl = 1*3DIGIT ; 0 to 255
Definition at line 5051 of file chan_sip.c.
References ast_calloc, ast_log(), ast_skip_blanks(), ast_strdup, ast_strlen_zero(), sip_via::branch, free_via(), LOG_ERROR, sip_via::maddr, sip_via::port, sip_via::protocol, sip_via::sent_by, strsep(), sip_via::ttl, and sip_via::via.
Referenced by process_via().
05052 { 05053 struct sip_via *v = ast_calloc(1, sizeof(*v)); 05054 char *via, *parm; 05055 05056 if (!v) { 05057 return NULL; 05058 } 05059 05060 v->via = ast_strdup(header); 05061 v->ttl = 1; 05062 05063 via = v->via; 05064 05065 if (ast_strlen_zero(via)) { 05066 ast_log(LOG_ERROR, "received request without a Via header\n"); 05067 free_via(v); 05068 return NULL; 05069 } 05070 05071 /* seperate the first via-parm */ 05072 via = strsep(&via, ","); 05073 05074 /* chop off sent-protocol */ 05075 v->protocol = strsep(&via, " \t\r\n"); 05076 if (ast_strlen_zero(v->protocol)) { 05077 ast_log(LOG_ERROR, "missing sent-protocol in Via header\n"); 05078 free_via(v); 05079 return NULL; 05080 } 05081 v->protocol = ast_skip_blanks(v->protocol); 05082 05083 if (via) { 05084 via = ast_skip_blanks(via); 05085 } 05086 05087 /* chop off sent-by */ 05088 v->sent_by = strsep(&via, "; \t\r\n"); 05089 if (ast_strlen_zero(v->sent_by)) { 05090 ast_log(LOG_ERROR, "missing sent-by in Via header\n"); 05091 free_via(v); 05092 return NULL; 05093 } 05094 v->sent_by = ast_skip_blanks(v->sent_by); 05095 05096 /* store the port */ 05097 if ((parm = strchr(v->sent_by, ':'))) { 05098 char *endptr; 05099 05100 v->port = strtol(++parm, &endptr, 10); 05101 } 05102 05103 /* evaluate any via-parms */ 05104 while ((parm = strsep(&via, "; \t\r\n"))) { 05105 char *c; 05106 if ((c = strstr(parm, "maddr="))) { 05107 v->maddr = ast_skip_blanks(c + sizeof("maddr=") - 1); 05108 } else if ((c = strstr(parm, "branch="))) { 05109 v->branch = ast_skip_blanks(c + sizeof("branch=") - 1); 05110 } else if ((c = strstr(parm, "ttl="))) { 05111 char *endptr; 05112 c = ast_skip_blanks(c + sizeof("ttl=") - 1); 05113 v->ttl = strtol(c, &endptr, 10); 05114 05115 /* make sure we got a valid ttl value */ 05116 if (c == endptr) { 05117 v->ttl = 1; 05118 } 05119 } 05120 } 05121 05122 return v; 05123 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Report Peer status in character string.
Definition at line 11192 of file chan_sip.c.
References ast_copy_string(), sip_peer::lastms, and sip_peer::maxms.
Referenced by _sip_show_peer(), _sip_show_peers(), and function_sippeer().
11193 { 11194 int res = 0; 11195 if (peer->maxms) { 11196 if (peer->lastms < 0) { 11197 ast_copy_string(status, "UNREACHABLE", statuslen); 11198 } else if (peer->lastms > peer->maxms) { 11199 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 11200 res = 1; 11201 } else if (peer->lastms) { 11202 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 11203 res = 1; 11204 } else { 11205 ast_copy_string(status, "UNKNOWN", statuslen); 11206 } 11207 } else { 11208 ast_copy_string(status, "Unmonitored", statuslen); 11209 /* Checking if port is 0 */ 11210 res = -1; 11211 } 11212 return res; 11213 }
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 11667 of file chan_sip.c.
References ast_cli(), ast_codec_pref_index(), ast_getformatname(), and ast_codec_pref::framing.
Referenced by _sip_show_peer(), sip_show_settings(), and sip_show_user().
11668 { 11669 int x, codec; 11670 11671 for(x = 0; x < 32 ; x++) { 11672 codec = ast_codec_pref_index(pref, x); 11673 if (!codec) 11674 break; 11675 ast_cli(fd, "%s", ast_getformatname(codec)); 11676 ast_cli(fd, ":%d", pref->framing[x]); 11677 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 11678 ast_cli(fd, ","); 11679 } 11680 if (!x) 11681 ast_cli(fd, "none"); 11682 }
static void print_group | ( | int | fd, | |
ast_group_t * | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 11451 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
11452 { 11453 char buf[256]; 11454 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 11455 }
static void process_request_queue | ( | struct sip_pvt * | p, | |
int * | recount, | |||
int * | nounlock | |||
) | [static] |
Definition at line 17366 of file chan_sip.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_log(), sip_pvt::callid, handle_request(), LOG_DEBUG, option_debug, sip_pvt::recv, and sip_pvt::request_queue.
Referenced by scheduler_process_request_queue(), and sipsock_read().
17367 { 17368 struct sip_request *req; 17369 17370 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 17371 if (handle_request(p, req, &p->recv, recount, nounlock) == -1) { 17372 /* Request failed */ 17373 if (option_debug) { 17374 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 17375 } 17376 } 17377 ast_free(req); 17378 } 17379 }
static int process_sdp | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp().
< RTP Audio host IP
< RTP video host IP
< UDPTL host IP
< RTP Audio port number
< RTP Video port number
< UDPTL Image port number
< media socket address
< video socket address
< image socket address
< Buffers for codec handling
< Negotiated capability
Definition at line 5706 of file chan_sip.c.
References ast_clear_flag, ast_codec_choose(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_copy_string(), AST_FORMAT_AUDIO_MASK, ast_getformatname_multiple(), ast_inet_ntoa(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_alloc_size(), AST_RTP_DTMF, ast_rtp_get_current_formats(), ast_rtp_get_peer(), ast_rtp_lookup_mime_multiple(), ast_rtp_new_init(), ast_rtp_pt_clear(), ast_rtp_pt_copy(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_stop(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_skip_blanks(), ast_strlen_zero(), ast_test_flag, ast_threadstorage_get(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_peer(), ast_udptl_stop(), ast_verbose(), sip_pvt::callid, t38properties::capability, sip_pvt::capability, change_hold_state(), debug, t38properties::direct, FALSE, sip_pvt::flags, get_sdp_iterate(), get_sdp_line(), ast_hostent::hp, hp, sip_pvt::jointcapability, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastinvite, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_request::len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_pvt::mohsuggest, ast_channel::nativeformats, sip_pvt::noncodeccapability, offered_media::offered, sip_pvt::offered_media, option_debug, sip_pvt::owner, sip_pvt::peercapability, t38properties::peercapability, portno, sip_pvt::prefs, process_sdp_a_audio(), process_sdp_a_image(), process_sdp_a_sendonly(), process_sdp_a_video(), process_sdp_c(), ast_channel::readformat, sip_pvt::rtp, S_OR, SDP_AUDIO, SDP_IMAGE, sip_request::sdp_start, SDP_VIDEO, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_NAT, SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_UDPTL_DESTINATION, SIPBUFSIZE, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_LOCAL_REINVITE, T38_PEER_DIRECT, T38_PEER_REINVITE, T38FAX_UDP_EC_NONE, offered_media::text, TRUE, type, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_NONE, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by handle_request(), handle_request_invite(), handle_response(), and handle_response_invite().
05707 { 05708 /* Iterators for SDP parsing */ 05709 int start = req->sdp_start; 05710 int next = start; 05711 int iterator = start; 05712 05713 /* Temporary vars for SDP parsing */ 05714 char type = '\0'; 05715 const char *value = NULL; 05716 const char *m = NULL; /* SDP media offer */ 05717 const char *nextm = NULL; 05718 int len = -1; 05719 05720 /* Host information */ 05721 struct ast_hostent audiohp; 05722 struct ast_hostent videohp; 05723 struct ast_hostent imagehp; 05724 struct ast_hostent sessionhp; 05725 struct hostent *hp = NULL; /*!< RTP Audio host IP */ 05726 struct hostent *vhp = NULL; /*!< RTP video host IP */ 05727 struct hostent *ihp = NULL; /*!< UDPTL host IP */ 05728 int portno = -1; /*!< RTP Audio port number */ 05729 int vportno = -1; /*!< RTP Video port number */ 05730 int udptlportno = -1; /*!< UDPTL Image port number */ 05731 struct sockaddr_in sin = { 0, }; /*!< media socket address */ 05732 struct sockaddr_in vsin = { 0, }; /*!< video socket address */ 05733 struct sockaddr_in isin = { 0, }; /*!< image socket address */ 05734 05735 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 05736 int peercapability = 0, peernoncodeccapability = 0; 05737 int vpeercapability = 0, vpeernoncodeccapability = 0; 05738 struct ast_rtp *newaudiortp, *newvideortp; /*!< Buffers for codec handling */ 05739 int newjointcapability; /*!< Negotiated capability */ 05740 int newpeercapability; 05741 int newnoncodeccapability; 05742 const char *codecs; 05743 int codec; 05744 05745 /* Others */ 05746 int sendonly = -1; 05747 int vsendonly = -1; 05748 int numberofports; 05749 int numberofmediastreams = 0; 05750 int last_rtpmap_codec = 0; 05751 int debug = sip_debug_test_pvt(p); 05752 05753 /* Initial check */ 05754 if (!p->rtp) { 05755 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 05756 return -1; 05757 } 05758 05759 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 05760 #ifdef LOW_MEMORY 05761 newaudiortp = ast_threadstorage_get(&ts_audio_rtp, ast_rtp_alloc_size()); 05762 #else 05763 newaudiortp = alloca(ast_rtp_alloc_size()); 05764 #endif 05765 memset(newaudiortp, 0, ast_rtp_alloc_size()); 05766 ast_rtp_new_init(newaudiortp); 05767 ast_rtp_pt_clear(newaudiortp); 05768 05769 #ifdef LOW_MEMORY 05770 newvideortp = ast_threadstorage_get(&ts_video_rtp, ast_rtp_alloc_size()); 05771 #else 05772 newvideortp = alloca(ast_rtp_alloc_size()); 05773 #endif 05774 memset(newvideortp, 0, ast_rtp_alloc_size()); 05775 ast_rtp_new_init(newvideortp); 05776 ast_rtp_pt_clear(newvideortp); 05777 05778 05779 /* Update our last rtprx when we receive an SDP, too */ 05780 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 05781 05782 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 05783 05784 memset(p->offered_media, 0, sizeof(p->offered_media)); 05785 05786 05787 /* Scan for the first media stream (m=) line to limit scanning of globals */ 05788 nextm = get_sdp_iterate(&next, req, "m"); 05789 if (ast_strlen_zero(nextm)) { 05790 ast_log(LOG_WARNING, "Insufficient information for SDP (m= not found)\n"); 05791 return -1; 05792 } 05793 05794 /* Scan session level SDP parameters (lines before first media stream) */ 05795 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 05796 int processed = FALSE; 05797 switch (type) { 05798 case 'c': 05799 if (process_sdp_c(value, &sessionhp)) { 05800 processed = TRUE; 05801 hp = &sessionhp.hp; 05802 vhp = hp; 05803 ihp = hp; 05804 } 05805 break; 05806 case 'a': 05807 if (process_sdp_a_sendonly(value, &sendonly)) { 05808 processed = TRUE; 05809 vsendonly = sendonly; 05810 } 05811 else if (process_sdp_a_audio(value, p, newaudiortp, &last_rtpmap_codec)) 05812 processed = TRUE; 05813 else if (process_sdp_a_video(value, p, newvideortp, &last_rtpmap_codec)) 05814 processed = TRUE; 05815 else if (process_sdp_a_image(value, p)) 05816 processed = TRUE; 05817 break; 05818 } 05819 05820 if (option_debug > 2) 05821 ast_log(LOG_DEBUG, "Processing session-level SDP %c=%s... %s\n", type, value, (processed == TRUE)? "OK." : "UNSUPPORTED."); 05822 } 05823 05824 05825 /* Scan media stream (m=) specific parameters loop */ 05826 while (!ast_strlen_zero(nextm)) { 05827 int audio = FALSE; 05828 int video = FALSE; 05829 int image = FALSE; 05830 int x; 05831 05832 numberofports = 1; 05833 len = -1; 05834 start = next; 05835 m = nextm; 05836 iterator = next; 05837 nextm = get_sdp_iterate(&next, req, "m"); 05838 05839 /* Search for audio media definition */ 05840 if ((sscanf(m, "audio %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05841 (sscanf(m, "audio %30d RTP/AVP %n", &x, &len) == 1 && len > 0)) { 05842 /* Found audio stream in this media definition */ 05843 audio = TRUE; 05844 p->offered_media[SDP_AUDIO].offered = TRUE; 05845 numberofmediastreams++; 05846 portno = x; 05847 05848 /* Scan through the RTP payload types specified in a "m=" line: */ 05849 codecs = m + len; 05850 ast_copy_string(p->offered_media[SDP_AUDIO].text, codecs, sizeof(p->offered_media[SDP_AUDIO].text)); 05851 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05852 if (sscanf(codecs, "%30d%n", &codec, &len) != 1) { 05853 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05854 return -1; 05855 } 05856 if (debug) 05857 ast_verbose("Found RTP audio format %d\n", codec); 05858 ast_rtp_set_m_type(newaudiortp, codec); 05859 } 05860 /* Search for video media definition */ 05861 } else if ((sscanf(m, "video %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05862 (sscanf(m, "video %30d RTP/AVP %n", &x, &len) == 1 && len >= 0)) { 05863 /* Found video stream in this media definition */ 05864 video = TRUE; 05865 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 05866 p->offered_media[SDP_VIDEO].offered = TRUE; 05867 numberofmediastreams++; 05868 vportno = x; 05869 05870 /* Scan through the RTP payload types specified in a "m=" line: */ 05871 codecs = m + len; 05872 ast_copy_string(p->offered_media[SDP_VIDEO].text, codecs, sizeof(p->offered_media[SDP_VIDEO].text)); 05873 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05874 if (sscanf(codecs, "%30d%n", &codec, &len) != 1) { 05875 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05876 return -1; 05877 } 05878 if (debug) 05879 ast_verbose("Found RTP video format %d\n", codec); 05880 ast_rtp_set_m_type(newvideortp, codec); 05881 } 05882 /* Search for image media definition */ 05883 } else if (p->udptl && ((sscanf(m, "image %30d udptl t38%n", &x, &len) == 1 && len > 0) || 05884 (sscanf(m, "image %30d UDPTL t38%n", &x, &len) == 1 && len >= 0))) { 05885 /* Found image stream in this media definition */ 05886 image = TRUE; 05887 if (debug) 05888 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 05889 p->offered_media[SDP_IMAGE].offered = TRUE; 05890 udptlportno = x; 05891 numberofmediastreams++; 05892 05893 if (p->owner && p->lastinvite) { 05894 if (p->t38.state != T38_LOCAL_REINVITE) { 05895 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 05896 if (option_debug > 1) 05897 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 05898 } 05899 } else { 05900 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 05901 p->t38.direct = 1; 05902 if (option_debug > 1) 05903 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05904 } 05905 05906 /* default EC to none, the remote end should respond 05907 * with the EC they want to use */ 05908 p->t38.peercapability &= ~T38FAX_UDP_EC_NONE; 05909 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05910 } else { 05911 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 05912 continue; 05913 } 05914 05915 /* Check for number of ports */ 05916 if (numberofports > 1) 05917 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 05918 05919 05920 05921 /* Media stream specific parameters */ 05922 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 05923 int processed = FALSE; 05924 05925 switch (type) { 05926 case 'c': 05927 if (audio) { 05928 if (process_sdp_c(value, &audiohp)) { 05929 processed = TRUE; 05930 hp = &audiohp.hp; 05931 } 05932 } 05933 else if (video) { 05934 if (process_sdp_c(value, &videohp)) { 05935 processed = TRUE; 05936 vhp = &videohp.hp; 05937 } 05938 } else if (image) { 05939 if (process_sdp_c(value, &imagehp)) { 05940 processed = TRUE; 05941 ihp = &imagehp.hp; 05942 } 05943 } 05944 break; 05945 case 'a': 05946 /* Audio specific scanning */ 05947 if (audio) { 05948 if (process_sdp_a_sendonly(value, &sendonly)) 05949 processed = TRUE; 05950 else if (process_sdp_a_audio(value, p, newaudiortp, &last_rtpmap_codec)) 05951 processed = TRUE; 05952 } 05953 /* Video specific scanning */ 05954 else if (video) { 05955 if (process_sdp_a_sendonly(value, &vsendonly)) 05956 processed = TRUE; 05957 else if (process_sdp_a_video(value, p, newvideortp, &last_rtpmap_codec)) 05958 processed = TRUE; 05959 } 05960 /* Image (T.38 FAX) specific scanning */ 05961 else if (image) { 05962 if (process_sdp_a_image(value, p)) 05963 processed = TRUE; 05964 } 05965 break; 05966 } 05967 05968 if (option_debug > 2) 05969 ast_log(LOG_DEBUG, "Processing media-level (%s) SDP %c=%s... %s\n", 05970 (audio == TRUE)? "audio" : (video == TRUE)? "video" : "image", 05971 type, value, 05972 (processed == TRUE)? "OK." : "UNSUPPORTED."); 05973 } 05974 } 05975 05976 /* Sanity checks */ 05977 if (!hp && !vhp && !ihp) { 05978 ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n"); 05979 return -1; 05980 } 05981 05982 if (portno == -1 && vportno == -1 && udptlportno == -1) 05983 /* No acceptable offer found in SDP - we have no ports */ 05984 /* Do not change RTP or VRTP if this is a re-invite */ 05985 return -2; 05986 05987 if (numberofmediastreams > 2) 05988 /* We have too many fax, audio and/or video media streams, fail this offer */ 05989 return -3; 05990 05991 if (udptlportno == -1) { 05992 p->t38.state = T38_DISABLED; 05993 if (option_debug > 2) 05994 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05995 } 05996 05997 05998 /* Now gather all of the codecs that we are asked for: */ 05999 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 06000 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 06001 06002 newjointcapability = p->capability & (peercapability | vpeercapability); 06003 newpeercapability = (peercapability | vpeercapability); 06004 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 06005 06006 06007 if (debug) { 06008 /* shame on whoever coded this.... */ 06009 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE]; 06010 06011 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 06012 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 06013 ast_getformatname_multiple(s2, SIPBUFSIZE, newpeercapability), 06014 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 06015 ast_getformatname_multiple(s4, SIPBUFSIZE, newjointcapability)); 06016 06017 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 06018 ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0), 06019 ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0), 06020 ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0)); 06021 06022 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 06023 p->t38.capability, 06024 p->t38.peercapability, 06025 p->t38.jointcapability); 06026 06027 } 06028 if (!newjointcapability) { 06029 /* If T.38 was not negotiated either, totally bail out... */ 06030 if (!p->t38.jointcapability || !udptlportno) { 06031 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 06032 /* Do NOT Change current setting */ 06033 return -1; 06034 } else { 06035 if (option_debug > 2) 06036 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 06037 } 06038 } 06039 06040 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 06041 they are acceptable */ 06042 p->jointcapability = newjointcapability; /* Our joint codec profile */ 06043 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 06044 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 06045 06046 ast_rtp_pt_copy(p->rtp, newaudiortp); 06047 if (p->vrtp) 06048 ast_rtp_pt_copy(p->vrtp, newvideortp); 06049 06050 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 06051 ast_clear_flag(&p->flags[0], SIP_DTMF); 06052 if (newnoncodeccapability & AST_RTP_DTMF) { 06053 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 06054 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 06055 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 06056 ast_rtp_setdtmf(p->rtp, 1); 06057 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 06058 } else { 06059 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 06060 } 06061 } 06062 06063 /* Setup audio port number */ 06064 if (p->rtp) { 06065 if (portno > 0) { 06066 sin.sin_family = AF_INET; 06067 sin.sin_port = htons(portno); 06068 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 06069 ast_rtp_set_peer(p->rtp, &sin); 06070 if (debug) 06071 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 06072 } else if (udptlportno > 0) { 06073 if (debug) 06074 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n"); 06075 } else { 06076 ast_rtp_stop(p->rtp); 06077 if (debug) 06078 ast_verbose("Peer doesn't provide audio\n"); 06079 } 06080 } 06081 06082 /* Setup video port number */ 06083 if (p->vrtp) { 06084 if (vportno > 0) { 06085 vsin.sin_family = AF_INET; 06086 vsin.sin_port = htons(vportno); 06087 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 06088 ast_rtp_set_peer(p->vrtp, &vsin); 06089 if (debug) 06090 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 06091 } else { 06092 ast_rtp_stop(p->vrtp); 06093 if (debug) 06094 ast_verbose("Peer doesn't provide video\n"); 06095 } 06096 } 06097 06098 /* Setup image port number */ 06099 if (p->udptl) { 06100 if (udptlportno > 0) { 06101 isin.sin_family = AF_INET; 06102 isin.sin_port = htons(udptlportno); 06103 if (ast_test_flag(&p->flags[0], SIP_NAT) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 06104 struct sockaddr_in peer = { 0, }; 06105 ast_rtp_get_peer(p->rtp, &peer); 06106 if (peer.sin_addr.s_addr) { 06107 memcpy(&isin.sin_addr, &peer.sin_addr, sizeof(isin.sin_addr)); 06108 if (debug) 06109 ast_log(LOG_DEBUG, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_inet_ntoa(isin.sin_addr)); 06110 } 06111 } else 06112 memcpy(&isin.sin_addr, ihp->h_addr, sizeof(isin.sin_addr)); 06113 ast_udptl_set_peer(p->udptl, &isin); 06114 if (debug) 06115 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(isin.sin_addr), ntohs(isin.sin_port)); 06116 } else { 06117 ast_udptl_stop(p->udptl); 06118 if (debug) 06119 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 06120 } 06121 } 06122 06123 06124 /* Ok, we're going with this offer */ 06125 if (option_debug > 1) { 06126 char buf[SIPBUFSIZE]; 06127 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 06128 } 06129 06130 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 06131 return 0; 06132 06133 if (option_debug > 3) 06134 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 06135 06136 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 06137 if (debug) { 06138 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 06139 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 06140 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 06141 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 06142 } 06143 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 06144 ast_set_read_format(p->owner, p->owner->readformat); 06145 ast_set_write_format(p->owner, p->owner->writeformat); 06146 } 06147 06148 /* sendonly processing */ 06149 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && (sin.sin_addr.s_addr || vsin.sin_addr.s_addr || isin.sin_addr.s_addr) && (!sendonly || sendonly == -1)) { 06150 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 06151 /* Activate a re-invite */ 06152 ast_queue_frame(p->owner, &ast_null_frame); 06153 } else if (!(sin.sin_addr.s_addr || vsin.sin_addr.s_addr || isin.sin_addr.s_addr) || (sendonly && sendonly != -1)) { 06154 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 06155 S_OR(p->mohsuggest, NULL), 06156 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 06157 if (sendonly) 06158 ast_rtp_stop(p->rtp); 06159 /* RTCP needs to go ahead, even if we're on hold!!! */ 06160 /* Activate a re-invite */ 06161 ast_queue_frame(p->owner, &ast_null_frame); 06162 } 06163 06164 /* Manager Hold and Unhold events must be generated, if necessary */ 06165 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && (sin.sin_addr.s_addr || vsin.sin_addr.s_addr || isin.sin_addr.s_addr) && (!sendonly || sendonly == -1)) 06166 change_hold_state(p, req, FALSE, sendonly); 06167 else if (!(sin.sin_addr.s_addr || vsin.sin_addr.s_addr || isin.sin_addr.s_addr) || (sendonly && sendonly != -1)) 06168 change_hold_state(p, req, TRUE, sendonly); 06169 06170 return 0; 06171 }
static int process_sdp_a_audio | ( | const char * | a, | |
struct sip_pvt * | p, | |||
struct ast_rtp * | newaudiortp, | |||
int * | last_rtpmap_codec | |||
) | [static] |
Definition at line 6213 of file chan_sip.c.
References ast_codec_pref_setsize(), ast_log(), ast_rtp_codec_getformat(), ast_rtp_codec_getpref(), ast_rtp_codec_setpref(), AST_RTP_OPT_G726_NONSTANDARD, ast_rtp_set_rtpmap_type(), ast_rtp_unset_m_type(), ast_strdupa, ast_test_flag, ast_verbose(), sip_pvt::autoframing, debug, FALSE, sip_pvt::flags, format, LOG_DEBUG, LONG_MAX, LONG_MIN, MAX_RTP_PT, option_debug, sip_pvt::rtp, SDP_MAX_RTPMAP_CODECS, sip_debug_test_pvt(), SIP_G726_NONSTANDARD, and TRUE.
Referenced by process_sdp().
06214 { 06215 int found = FALSE; 06216 int codec; 06217 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 06218 int debug = sip_debug_test_pvt(p); 06219 06220 if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 06221 char *tmp = strrchr(a, ':'); 06222 long int framing = 0; 06223 if (tmp) { 06224 tmp++; 06225 framing = strtol(tmp, NULL, 10); 06226 if (framing == LONG_MIN || framing == LONG_MAX) { 06227 framing = 0; 06228 if (option_debug) 06229 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 06230 } 06231 } 06232 if (framing && p->autoframing) { 06233 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06234 int codec_n; 06235 int format = 0; 06236 for (codec_n = 0; codec_n < MAX_RTP_PT; codec_n++) { 06237 format = ast_rtp_codec_getformat(codec_n); 06238 if (!format) /* non-codec or not found */ 06239 continue; 06240 if (option_debug) 06241 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 06242 ast_codec_pref_setsize(pref, format, framing); 06243 } 06244 ast_rtp_codec_setpref(p->rtp, pref); 06245 } 06246 found = TRUE; 06247 } else if (sscanf(a, "rtpmap: %30u %[^/]/", &codec, mimeSubtype) == 2) { 06248 /* We have a rtpmap to handle */ 06249 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 06250 /* Note: should really look at the 'freq' and '#chans' params too */ 06251 if (ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 06252 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) { 06253 if (debug) 06254 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 06255 (*last_rtpmap_codec)++; 06256 found = TRUE; 06257 } 06258 } else { 06259 if (debug) 06260 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 06261 } 06262 06263 if (!found) { 06264 /* Remove this codec since it's an unknown media type for us */ 06265 ast_rtp_unset_m_type(newaudiortp, codec); 06266 if (debug) 06267 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 06268 } 06269 } 06270 06271 return found; 06272 }
static int process_sdp_a_image | ( | const char * | a, | |
struct sip_pvt * | p | |||
) | [static] |
Definition at line 6307 of file chan_sip.c.
References ast_log(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), t38properties::capability, FALSE, t38properties::jointcapability, LOG_DEBUG, option_debug, t38properties::peercapability, s, sip_pvt::t38, 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, TRUE, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by process_sdp().
06308 { 06309 int found = FALSE; 06310 char s[256]; 06311 int x; 06312 06313 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 06314 if ((sscanf(a, "T38FaxMaxBuffer:%30d", &x) == 1)) { 06315 found = TRUE; 06316 if (option_debug > 2) 06317 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 06318 } else if ((sscanf(a, "T38MaxBitRate:%30d", &x) == 1) || (sscanf(a, "T38FaxMaxRate:%30d", &x) == 1)) { 06319 found = TRUE; 06320 if (option_debug > 2) 06321 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 06322 switch (x) { 06323 case 14400: 06324 p->t38.peercapability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 06325 break; 06326 case 12000: 06327 p->t38.peercapability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 06328 break; 06329 case 9600: 06330 p->t38.peercapability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 06331 break; 06332 case 7200: 06333 p->t38.peercapability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 06334 break; 06335 case 4800: 06336 p->t38.peercapability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 06337 break; 06338 case 2400: 06339 p->t38.peercapability |= T38FAX_RATE_2400; 06340 break; 06341 } 06342 } else if ((sscanf(a, "T38FaxVersion:%30d", &x) == 1)) { 06343 found = TRUE; 06344 if (option_debug > 2) 06345 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 06346 if (x == 0) 06347 p->t38.peercapability |= T38FAX_VERSION_0; 06348 else if (x == 1) 06349 p->t38.peercapability |= T38FAX_VERSION_1; 06350 } else if ((sscanf(a, "T38FaxMaxDatagram:%30d", &x) == 1) || (sscanf(a, "T38MaxDatagram:%30d", &x) == 1)) { 06351 found = TRUE; 06352 if (option_debug > 2) 06353 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 06354 ast_udptl_set_far_max_datagram(p->udptl, x); 06355 ast_udptl_set_local_max_datagram(p->udptl, x); 06356 } else if ((strncmp(a, "T38FaxFillBitRemoval", 20) == 0)) { 06357 found = TRUE; 06358 if ((sscanf(a, "T38FaxFillBitRemoval:%30d", &x) == 1)) { 06359 if (option_debug > 2) 06360 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 06361 if (x == 1) 06362 p->t38.peercapability |= T38FAX_FILL_BIT_REMOVAL; 06363 } else { 06364 if (option_debug > 2) 06365 ast_log(LOG_DEBUG, "FillBitRemoval\n"); 06366 p->t38.peercapability |= T38FAX_FILL_BIT_REMOVAL; 06367 } 06368 } else if ((strncmp(a, "T38FaxTranscodingMMR", 20) == 0)) { 06369 found = TRUE; 06370 if ((sscanf(a, "T38FaxTranscodingMMR:%30d", &x) == 1)) { 06371 if (option_debug > 2) 06372 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 06373 if (x == 1) 06374 p->t38.peercapability |= T38FAX_TRANSCODING_MMR; 06375 } else { 06376 if (option_debug > 2) 06377 ast_log(LOG_DEBUG, "Transcoding MMR\n"); 06378 p->t38.peercapability |= T38FAX_TRANSCODING_MMR; 06379 } 06380 } else if ((strncmp(a, "T38FaxTranscodingJBIG", 21) == 0)) { 06381 found = TRUE; 06382 if ((sscanf(a, "T38FaxTranscodingJBIG:%30d", &x) == 1)) { 06383 if (option_debug > 2) 06384 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 06385 if (x == 1) 06386 p->t38.peercapability |= T38FAX_TRANSCODING_JBIG; 06387 } else { 06388 if (option_debug > 2) 06389 ast_log(LOG_DEBUG, "Transcoding JBIG\n"); 06390 p->t38.peercapability |= T38FAX_TRANSCODING_JBIG; 06391 } 06392 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 06393 found = TRUE; 06394 if (option_debug > 2) 06395 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 06396 if (!strcasecmp(s, "localTCF")) 06397 p->t38.peercapability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 06398 else if (!strcasecmp(s, "transferredTCF")) 06399 p->t38.peercapability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 06400 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 06401 found = TRUE; 06402 if (option_debug > 2) 06403 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 06404 if (!strcasecmp(s, "t38UDPRedundancy")) { 06405 p->t38.peercapability |= T38FAX_UDP_EC_REDUNDANCY; 06406 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 06407 } else if (!strcasecmp(s, "t38UDPFEC")) { 06408 p->t38.peercapability |= T38FAX_UDP_EC_FEC; 06409 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 06410 } else { 06411 p->t38.peercapability |= T38FAX_UDP_EC_NONE; 06412 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 06413 } 06414 } 06415 06416 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 06417 int t38speed = p->t38.peercapability & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 06418 06419 p->t38.jointcapability = (p->t38.peercapability & 255); /* Put everything beside supported speeds settings */ 06420 p->t38.jointcapability |= (t38speed & p->t38.capability); /* Put the lower of our's and peer's speed */ 06421 } 06422 06423 return found; 06424 }
static int process_sdp_a_sendonly | ( | const char * | a, | |
int * | sendonly | |||
) | [static] |
Definition at line 6193 of file chan_sip.c.
Referenced by process_sdp().
06194 { 06195 int found = FALSE; 06196 06197 if (!strcasecmp(a, "sendonly")) { 06198 if (*sendonly == -1) 06199 *sendonly = 1; 06200 found = TRUE; 06201 } else if (!strcasecmp(a, "inactive")) { 06202 if (*sendonly == -1) 06203 *sendonly = 2; 06204 found = TRUE; 06205 } else if (!strcasecmp(a, "sendrecv")) { 06206 if (*sendonly == -1) 06207 *sendonly = 0; 06208 found = TRUE; 06209 } 06210 return found; 06211 }
static int process_sdp_a_video | ( | const char * | a, | |
struct sip_pvt * | p, | |||
struct ast_rtp * | newvideortp, | |||
int * | last_rtpmap_codec | |||
) | [static] |
Definition at line 6274 of file chan_sip.c.
References ast_rtp_set_rtpmap_type(), ast_rtp_unset_m_type(), ast_strdupa, ast_verbose(), debug, FALSE, SDP_MAX_RTPMAP_CODECS, sip_debug_test_pvt(), TRUE, and sip_pvt::vrtp.
Referenced by process_sdp().
06275 { 06276 int found = FALSE; 06277 int codec; 06278 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 06279 int debug = sip_debug_test_pvt(p); 06280 06281 if (sscanf(a, "rtpmap: %30u %[^/]/", &codec, mimeSubtype) == 2) { 06282 /* We have a rtpmap to handle */ 06283 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 06284 /* Note: should really look at the 'freq' and '#chans' params too */ 06285 if (p->vrtp && ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) { 06286 if (debug) 06287 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 06288 (*last_rtpmap_codec)++; 06289 found = TRUE; 06290 } 06291 } else { 06292 if (debug) 06293 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 06294 } 06295 06296 if (!found) { 06297 /* Remove this codec since it's an unknown media type for us */ 06298 ast_rtp_unset_m_type(newvideortp, codec); 06299 if (debug) 06300 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 06301 } 06302 } 06303 06304 return found; 06305 }
static int process_sdp_c | ( | const char * | c, | |
struct ast_hostent * | hp | |||
) | [static] |
Definition at line 6174 of file chan_sip.c.
References ast_gethostbyname(), ast_log(), FALSE, hp, LOG_WARNING, and TRUE.
Referenced by process_sdp().
06175 { 06176 char host[258]; 06177 struct hostent *hp; 06178 06179 /* Check for Media-description-level-address */ 06180 if (sscanf(c, "IN IP4 %255s", host) != 1) { 06181 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 06182 return FALSE; 06183 } else { 06184 if (!(hp = ast_gethostbyname(host, ast_hp))) { 06185 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in c= line, '%s'\n", c); 06186 return FALSE; 06187 } 06188 return TRUE; 06189 } 06190 return FALSE; 06191 }
static int process_via | ( | struct sip_pvt * | p, | |
const struct sip_request * | req | |||
) | [static] |
Process the Via header according to RFC 3261 section 18.2.2.
p | a sip_pvt structure that will be modified according to the received header | |
req | a sip request with a Via header to process |
This function will update the destination of the response according to the Via header in the request and RFC 3261 section 18.2.2. We do not have a transport layer so we ignore certain values like the 'received' param (we set the destination address to the addres the request came from in the respprep() function).
-1 | error | |
0 | success |
Definition at line 5152 of file chan_sip.c.
References addr_is_multicast(), ast_gethostbyname(), ast_log(), free_via(), get_header(), hp, LOG_ERROR, LOG_WARNING, sip_via::maddr, parse_via(), sip_via::port, sip_pvt::sa, sipsock, STANDARD_SIP_PORT, sip_via::ttl, and sip_via::via.
Referenced by respprep().
05153 { 05154 struct sip_via *via = parse_via(get_header(req, "Via")); 05155 05156 if (!via) { 05157 ast_log(LOG_ERROR, "error processing via header\n"); 05158 return -1; 05159 } 05160 05161 if (via->maddr) { 05162 struct hostent *hp; 05163 struct ast_hostent ahp; 05164 05165 hp = ast_gethostbyname(via->maddr, &ahp); 05166 if (hp == NULL) { 05167 ast_log(LOG_WARNING, "Can't find address for maddr '%s'\n", via->maddr); 05168 ast_log(LOG_ERROR, "error processing via header\n"); 05169 free_via(via); 05170 return -1; 05171 } 05172 05173 p->sa.sin_family = AF_INET; 05174 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 05175 05176 if (addr_is_multicast(&p->sa.sin_addr)) { 05177 setsockopt(sipsock, IPPROTO_IP, IP_MULTICAST_TTL, &via->ttl, sizeof(via->ttl)); 05178 } 05179 } 05180 05181 p->sa.sin_port = htons(via->port ? via->port : STANDARD_SIP_PORT); 05182 05183 free_via(via); 05184 return 0; 05185 }
static int queue_request | ( | struct sip_pvt * | p, | |
const struct sip_request * | req | |||
) | [static] |
Definition at line 17431 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, ast_sched_add(), copy_request(), sip_pvt::request_queue, sip_pvt::request_queue_sched_id, and scheduler_process_request_queue().
Referenced by sipsock_read().
17432 { 17433 struct sip_request *newreq; 17434 17435 if (!(newreq = ast_calloc(1, sizeof(*newreq)))) { 17436 return -1; 17437 } 17438 17439 copy_request(newreq, req); 17440 AST_LIST_INSERT_TAIL(&p->request_queue, newreq, next); 17441 if (p->request_queue_sched_id == -1) { 17442 p->request_queue_sched_id = ast_sched_add(sched, 10, scheduler_process_request_queue, p); 17443 } 17444 17445 return 0; 17446 }
static struct sip_peer * realtime_peer | ( | const char * | newpeername, | |
struct sockaddr_in * | sin, | |||
int | devstate_only | |||
) | [static, read] |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
Definition at line 2798 of file chan_sip.c.
References ast_category_browse(), ast_category_root(), ast_config_destroy(), ast_copy_flags, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_load_realtime_multientry(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_test_flag, ast_variable_retrieve(), ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, ASTOBJ_REF, ASTOBJ_UNREF, build_peer(), sip_peer::expire, expire_register(), sip_peer::flags, hp, LOG_WARNING, ast_variable::name, ast_variable::next, peerl, set_insecure_flags(), sip_destroy_peer(), SIP_INSECURE_PORT, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, ast_variable::value, and var.
Referenced by find_peer().
02799 { 02800 struct sip_peer *peer=NULL; 02801 struct ast_variable *var = NULL; 02802 struct ast_config *peerlist = NULL; 02803 struct ast_variable *tmp; 02804 struct ast_flags flags = {0}; 02805 const char *iabuf = NULL; 02806 char portstring[6]; /*up to five digits plus null terminator*/ 02807 const char *insecure; 02808 char *cat = NULL; 02809 unsigned short portnum; 02810 02811 /* First check on peer name */ 02812 if (newpeername) { 02813 var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL); 02814 if (!var && sin) 02815 var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02816 if (!var) { 02817 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02818 /*!\note 02819 * If this one loaded something, then we need to ensure that the host 02820 * field matched. The only reason why we can't have this as a criteria 02821 * is because we only have the IP address and the host field might be 02822 * set as a name (and the reverse PTR might not match). 02823 */ 02824 if (var && sin) { 02825 for (tmp = var; tmp; tmp = tmp->next) { 02826 if (!strcasecmp(tmp->name, "host")) { 02827 struct hostent *hp; 02828 struct ast_hostent ahp; 02829 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02830 /* No match */ 02831 ast_variables_destroy(var); 02832 var = NULL; 02833 } 02834 break; 02835 } 02836 } 02837 } 02838 } 02839 } 02840 02841 if (!var && sin) { /* Then check on IP address */ 02842 iabuf = ast_inet_ntoa(sin->sin_addr); 02843 portnum = ntohs(sin->sin_port); 02844 sprintf(portstring, "%d", portnum); 02845 var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */ 02846 if (!var) 02847 var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL); /* Then check for registered hosts */ 02848 if (!var) { 02849 peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/ 02850 if(peerlist){ 02851 while((cat = ast_category_browse(peerlist, cat))) 02852 { 02853 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02854 set_insecure_flags(&flags, insecure, -1); 02855 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02856 var = ast_category_root(peerlist, cat); 02857 break; 02858 } 02859 } 02860 } 02861 if(!var) { 02862 ast_config_destroy(peerlist); 02863 peerlist = NULL; /*for safety's sake*/ 02864 cat = NULL; 02865 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/ 02866 if(peerlist) { 02867 while((cat = ast_category_browse(peerlist, cat))) 02868 { 02869 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02870 set_insecure_flags(&flags, insecure, -1); 02871 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02872 var = ast_category_root(peerlist, cat); 02873 break; 02874 } 02875 } 02876 } 02877 } 02878 } 02879 } 02880 02881 if (!var) { 02882 if(peerlist) 02883 ast_config_destroy(peerlist); 02884 return NULL; 02885 } 02886 02887 for (tmp = var; tmp; tmp = tmp->next) { 02888 /* If this is type=user, then skip this object. */ 02889 if (!strcasecmp(tmp->name, "type") && 02890 !strcasecmp(tmp->value, "user")) { 02891 ast_variables_destroy(var); 02892 return NULL; 02893 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02894 newpeername = tmp->value; 02895 } else if (!strcasecmp(tmp->name, "lastms")) { 02896 seen_lastms = 1; 02897 } 02898 } 02899 02900 if (!newpeername) { /* Did not find peer in realtime */ 02901 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 02902 if(peerlist) 02903 ast_config_destroy(peerlist); 02904 else 02905 ast_variables_destroy(var); 02906 return NULL; 02907 } 02908 02909 /* Peer found in realtime, now build it in memory */ 02910 peer = build_peer(newpeername, var, NULL, 1, devstate_only); 02911 if (!peer) { 02912 if(peerlist) 02913 ast_config_destroy(peerlist); 02914 else 02915 ast_variables_destroy(var); 02916 return NULL; 02917 } 02918 02919 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) { 02920 /* Cache peer */ 02921 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02922 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02923 if (!AST_SCHED_DEL(sched, peer->expire)) { 02924 struct sip_peer *peer_ptr = peer; 02925 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02926 } 02927 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, ASTOBJ_REF(peer)); 02928 if (peer->expire == -1) { 02929 struct sip_peer *peer_ptr = peer; 02930 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02931 } 02932 } 02933 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02934 } 02935 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02936 if(peerlist) 02937 ast_config_destroy(peerlist); 02938 else 02939 ast_variables_destroy(var); 02940 return peer; 02941 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
const char * | username, | |||
const char * | fullcontact, | |||
int | expirey, | |||
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 2677 of file chan_sip.c.
References ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, ast_update_realtime(), ipaddr, and SIP_PAGE2_RTSAVE_SYSNAME.
Referenced by update_peer().
02678 { 02679 char port[10]; 02680 char ipaddr[INET_ADDRSTRLEN]; 02681 char regseconds[20]; 02682 char str_lastms[20]; 02683 02684 char *sysname = ast_config_AST_SYSTEM_NAME; 02685 char *syslabel = NULL; 02686 02687 time_t nowtime = time(NULL) + expirey; 02688 const char *fc = fullcontact ? "fullcontact" : NULL; 02689 02690 snprintf(str_lastms, sizeof(str_lastms), "%d", lastms); 02691 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02692 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02693 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02694 02695 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02696 sysname = NULL; 02697 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02698 syslabel = "regserver"; 02699 02700 if (fc) 02701 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02702 "port", port, "regseconds", regseconds, 02703 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02704 else 02705 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02706 "port", port, "regseconds", regseconds, 02707 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02708 if (seen_lastms) { 02709 /* We cannot do this in the same statement as above, because the lack of 02710 * this field could cause the whole statement to fail. */ 02711 ast_update_realtime("sippeers", "name", peername, "lastms", str_lastms, NULL); 02712 } 02713 }
static struct sip_user * realtime_user | ( | const char * | username | ) | [static, read] |
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 2991 of file chan_sip.c.
References ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, build_user(), sip_user::flags, ast_variable::name, ast_variable::next, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, userl, ast_variable::value, and var.
Referenced by find_user().
02992 { 02993 struct ast_variable *var; 02994 struct ast_variable *tmp; 02995 struct sip_user *user = NULL; 02996 02997 var = ast_load_realtime("sipusers", "name", username, NULL); 02998 02999 if (!var) 03000 return NULL; 03001 03002 for (tmp = var; tmp; tmp = tmp->next) { 03003 if (!strcasecmp(tmp->name, "type") && 03004 !strcasecmp(tmp->value, "peer")) { 03005 ast_variables_destroy(var); 03006 return NULL; 03007 } 03008 } 03009 03010 user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 03011 03012 if (!user) { /* No user found */ 03013 ast_variables_destroy(var); 03014 return NULL; 03015 } 03016 03017 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 03018 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 03019 suserobjs++; 03020 ASTOBJ_CONTAINER_LINK(&userl,user); 03021 } else { 03022 /* Move counter from s to r... */ 03023 suserobjs--; 03024 ruserobjs++; 03025 } 03026 ast_set_flag(&user->flags[0], SIP_REALTIME); 03027 ast_variables_destroy(var); 03028 return user; 03029 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 11075 of file chan_sip.c.
References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose(), sip_pvt::callid, ast_frame::data, ast_frame::datalen, DEFAULT_TRANS_TIMEOUT, ast_frame::frametype, get_header(), get_msg_text(), LOG_WARNING, ast_frame::offset, sip_pvt::owner, sip_debug_test_pvt(), sip_scheddestroy(), ast_frame::subclass, and transmit_response().
Referenced by handle_request_message().
11076 { 11077 char buf[1024]; 11078 struct ast_frame f; 11079 const char *content_type = get_header(req, "Content-Type"); 11080 11081 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 11082 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 11083 if (!p->owner) 11084 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11085 return; 11086 } 11087 11088 if (get_msg_text(buf, sizeof(buf), req)) { 11089 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 11090 transmit_response(p, "202 Accepted", req); 11091 if (!p->owner) 11092 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11093 return; 11094 } 11095 11096 if (p->owner) { 11097 if (sip_debug_test_pvt(p)) 11098 ast_verbose("Message received: '%s'\n", buf); 11099 memset(&f, 0, sizeof(f)); 11100 f.frametype = AST_FRAME_TEXT; 11101 f.subclass = 0; 11102 f.offset = 0; 11103 f.data = buf; 11104 f.datalen = strlen(buf) + 1; 11105 ast_queue_frame(p->owner, &f); 11106 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 11107 } else { /* Message outside of a call, we do not support that */ 11108 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); 11109 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 11110 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11111 } 11112 return; 11113 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1744 of file chan_sip.c.
References referstatusstrings, and c_referstatusstring::text.
Referenced by __sip_show_channels().
01745 { 01746 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01747 int x; 01748 01749 for (x = 0; x < i; x++) { 01750 if (referstatusstrings[x].status == rstatus) 01751 return (char *) referstatusstrings[x].text; 01752 } 01753 return ""; 01754 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 8905 of file chan_sip.c.
References sip_peer::addr, ast_copy_string(), ast_db_get(), ast_inet_ntoa(), ast_log(), ast_random(), ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_request::data, sip_peer::expire, expire_register(), sip_peer::flags, sip_peer::fullcontact, LOG_DEBUG, sip_peer::name, option_debug, sip_peer::pokeexpire, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, strsep(), TRUE, sip_peer::username, and username.
Referenced by build_peer(), and temp_peer().
08906 { 08907 char data[256]; 08908 struct in_addr in; 08909 int expiry; 08910 int port; 08911 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 08912 08913 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08914 return; 08915 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 08916 return; 08917 08918 scan = data; 08919 addr = strsep(&scan, ":"); 08920 port_str = strsep(&scan, ":"); 08921 expiry_str = strsep(&scan, ":"); 08922 username = strsep(&scan, ":"); 08923 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 08924 08925 if (!inet_aton(addr, &in)) 08926 return; 08927 08928 if (port_str) 08929 port = atoi(port_str); 08930 else 08931 return; 08932 08933 if (expiry_str) 08934 expiry = atoi(expiry_str); 08935 else 08936 return; 08937 08938 if (username) 08939 ast_copy_string(peer->username, username, sizeof(peer->username)); 08940 if (contact) 08941 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 08942 08943 if (option_debug > 1) 08944 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 08945 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 08946 08947 memset(&peer->addr, 0, sizeof(peer->addr)); 08948 peer->addr.sin_family = AF_INET; 08949 peer->addr.sin_addr = in; 08950 peer->addr.sin_port = htons(port); 08951 if (sipsock < 0) { 08952 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 08953 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 08954 struct sip_peer *peer_ptr = peer; 08955 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08956 } 08957 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer)); 08958 if (peer->pokeexpire == -1) { 08959 struct sip_peer *peer_ptr = peer; 08960 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08961 } 08962 } else 08963 sip_poke_peer(peer); 08964 if (!AST_SCHED_DEL(sched, peer->expire)) { 08965 struct sip_peer *peer_ptr = peer; 08966 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08967 } 08968 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08969 if (peer->expire == -1) { 08970 struct sip_peer *peer_ptr = peer; 08971 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08972 } 08973 register_peer_exten(peer, TRUE); 08974 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2716 of file chan_sip.c.
References ast_add_extension(), ast_context_find(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr(), ast_log(), ast_strdup, ast_strlen_zero(), context, ext, LOG_WARNING, sip_peer::name, sip_peer::regexten, S_OR, and strsep().
Referenced by expire_register(), parse_register_contact(), reg_source_db(), and sip_destroy_peer().
02717 { 02718 char multi[256]; 02719 char *stringp, *ext, *context; 02720 02721 /* XXX note that global_regcontext is both a global 'enable' flag and 02722 * the name of the global regexten context, if not specified 02723 * individually. 02724 */ 02725 if (ast_strlen_zero(global_regcontext)) 02726 return; 02727 02728 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02729 stringp = multi; 02730 while ((ext = strsep(&stringp, "&"))) { 02731 if ((context = strchr(ext, '@'))) { 02732 *context++ = '\0'; /* split ext@context */ 02733 if (!ast_context_find(context)) { 02734 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02735 continue; 02736 } 02737 } else { 02738 context = global_regcontext; 02739 } 02740 if (onoff) { 02741 if (!ast_exists_extension(NULL, context, ext, 1, NULL)) { 02742 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02743 ast_strdup(peer->name), ast_free_ptr, "SIP"); 02744 } 02745 } else { 02746 ast_context_remove_extension(context, ext, 1, NULL); 02747 } 02748 } 02749 }
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 9900 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_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, AUTH_ACL_FAILED, 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_sip_domain(), EVENT_FLAG_SYSTEM, sip_peer::expire, sip_pvt::expiry, exten, find_peer(), sip_pvt::flags, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), sip_peer::ha, 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_DENIED, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, peerl, sip_peer::prefs, sip_pvt::rtp, sip_peer::secret, sip_cancel_destroy(), sip_destroy_peer(), SIP_NAT, SIP_PAGE2_DYNAMIC, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_PKT_IGNORE, SIP_REGISTER, strcasestr(), strsep(), t, temp_peer(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), update_peer(), and XMIT_UNRELIABLE.
Referenced by handle_request_register().
09902 { 09903 enum check_auth_result res = AUTH_NOT_FOUND; 09904 struct sip_peer *peer; 09905 char tmp[256]; 09906 char *name, *c; 09907 char *t; 09908 char *domain; 09909 09910 /* Terminate URI */ 09911 t = uri; 09912 while(*t && (*t > 32) && (*t != ';')) 09913 t++; 09914 *t = '\0'; 09915 09916 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 09917 if (pedanticsipchecking) 09918 ast_uri_decode(tmp); 09919 09920 c = get_in_brackets(tmp); 09921 c = strsep(&c, ";"); /* Ditch ;user=phone */ 09922 09923 if (!strncasecmp(c, "sip:", 4)) { 09924 name = c + 4; 09925 } else { 09926 name = c; 09927 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 09928 } 09929 09930 /* Strip off the domain name */ 09931 if ((c = strchr(name, '@'))) { 09932 *c++ = '\0'; 09933 domain = c; 09934 if ((c = strchr(domain, ':'))) /* Remove :port */ 09935 *c = '\0'; 09936 if (!AST_LIST_EMPTY(&domain_list)) { 09937 if (!check_sip_domain(domain, NULL, 0)) { 09938 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 09939 return AUTH_UNKNOWN_DOMAIN; 09940 } 09941 } 09942 } 09943 09944 ast_string_field_set(p, exten, name); 09945 build_contact(p); 09946 if (ast_test_flag(req, SIP_PKT_IGNORE)) { 09947 /* Expires is a special case, where we only want to load the peer if this isn't a deregistration attempt */ 09948 const char *expires = get_header(req, "Expires"); 09949 int expire = atoi(expires); 09950 09951 if (ast_strlen_zero(expires)) { /* No expires header; look in Contact */ 09952 if ((expires = strcasestr(get_header(req, "Contact"), ";expires="))) { 09953 expire = atoi(expires + 9); 09954 } 09955 } 09956 if (!ast_strlen_zero(expires) && expire == 0) { 09957 transmit_response_with_date(p, "200 OK", req); 09958 return 0; 09959 } 09960 } 09961 peer = find_peer(name, NULL, 1, 0); 09962 if (!(peer && ast_apply_ha(peer->ha, sin))) { 09963 /* Peer fails ACL check */ 09964 if (peer) { 09965 ASTOBJ_UNREF(peer, sip_destroy_peer); 09966 res = AUTH_ACL_FAILED; 09967 } else 09968 res = AUTH_NOT_FOUND; 09969 } 09970 if (peer) { 09971 /* Set Frame packetization */ 09972 if (p->rtp) { 09973 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09974 p->autoframing = peer->autoframing; 09975 } 09976 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 09977 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 09978 res = AUTH_PEER_NOT_DYNAMIC; 09979 } else { 09980 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 09981 transmit_response(p, "100 Trying", req); 09982 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09983 if (sip_cancel_destroy(p)) 09984 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09985 09986 /* We have a succesful registration attemp with proper authentication, 09987 now, update the peer */ 09988 switch (parse_register_contact(p, peer, req)) { 09989 case PARSE_REGISTER_DENIED: 09990 transmit_response_with_date(p, "603 Denied", req); 09991 peer->lastmsgssent = -1; 09992 res = 0; 09993 break; 09994 case PARSE_REGISTER_FAILED: 09995 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 09996 transmit_response_with_date(p, "400 Bad Request", req); 09997 peer->lastmsgssent = -1; 09998 res = 0; 09999 break; 10000 case PARSE_REGISTER_QUERY: 10001 ast_string_field_set(p, fullcontact, peer->fullcontact); 10002 transmit_response_with_date(p, "200 OK", req); 10003 peer->lastmsgssent = -1; 10004 res = 0; 10005 break; 10006 case PARSE_REGISTER_UPDATE: 10007 ast_string_field_set(p, fullcontact, peer->fullcontact); 10008 update_peer(peer, p->expiry); 10009 /* Say OK and ask subsystem to retransmit msg counter */ 10010 transmit_response_with_date(p, "200 OK", req); 10011 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 10012 peer->lastmsgssent = -1; 10013 res = 0; 10014 break; 10015 } 10016 } 10017 } 10018 } 10019 if (!peer && autocreatepeer) { 10020 /* Create peer if we have autocreate mode enabled */ 10021 peer = temp_peer(name); 10022 if (peer) { 10023 ASTOBJ_CONTAINER_LINK(&peerl, peer); 10024 if (sip_cancel_destroy(p)) 10025 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 10026 switch (parse_register_contact(p, peer, req)) { 10027 case PARSE_REGISTER_DENIED: 10028 ast_log(LOG_WARNING, "Registration denied because of contact ACL\n"); 10029 transmit_response_with_date(p, "403 Forbidden (ACL)", req); 10030 peer->lastmsgssent = -1; 10031 res = 0; 10032 break; 10033 case PARSE_REGISTER_FAILED: 10034 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 10035 transmit_response_with_date(p, "400 Bad Request", req); 10036 peer->lastmsgssent = -1; 10037 res = 0; 10038 break; 10039 case PARSE_REGISTER_QUERY: 10040 ast_string_field_set(p, fullcontact, peer->fullcontact); 10041 transmit_response_with_date(p, "200 OK", req); 10042 peer->lastmsgssent = -1; 10043 res = 0; 10044 break; 10045 case PARSE_REGISTER_UPDATE: 10046 ast_string_field_set(p, fullcontact, peer->fullcontact); 10047 /* Say OK and ask subsystem to retransmit msg counter */ 10048 transmit_response_with_date(p, "200 OK", req); 10049 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 10050 peer->lastmsgssent = -1; 10051 res = 0; 10052 break; 10053 } 10054 } 10055 } 10056 if (!peer && global_alwaysauthreject) { 10057 /* If we found a peer, we transmit a 100 Trying. Therefore, if we're 10058 * trying to avoid leaking information, we MUST also transmit the same 10059 * response when we DON'T find a peer. */ 10060 transmit_response(p, "100 Trying", req); 10061 /* Insert a fake delay between the 100 and the subsequent failure. */ 10062 sched_yield(); 10063 } 10064 if (!res) { 10065 ast_device_state_changed("SIP/%s", peer->name); 10066 } 10067 if (res < 0) { 10068 switch (res) { 10069 case AUTH_SECRET_FAILED: 10070 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 10071 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 10072 break; 10073 case AUTH_USERNAME_MISMATCH: 10074 /* Username and digest username does not match. 10075 Asterisk uses the From: username for authentication. We need the 10076 users to use the same authentication user name until we support 10077 proper authentication by digest auth name */ 10078 case AUTH_NOT_FOUND: 10079 case AUTH_PEER_NOT_DYNAMIC: 10080 case AUTH_ACL_FAILED: 10081 if (global_alwaysauthreject) { 10082 transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE); 10083 } else { 10084 /* URI not found */ 10085 if (res == AUTH_PEER_NOT_DYNAMIC) 10086 transmit_response(p, "403 Forbidden", &p->initreq); 10087 else 10088 transmit_response(p, "404 Not found", &p->initreq); 10089 } 10090 break; 10091 default: 10092 break; 10093 } 10094 } 10095 if (peer) 10096 ASTOBJ_UNREF(peer, sip_destroy_peer); 10097 10098 return res; 10099 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | [static] |
Convert registration state status to string.
Definition at line 8366 of file chan_sip.c.
References REG_STATE_AUTHSENT, REG_STATE_FAILED, REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.
Referenced by handle_response_register(), sip_reg_timeout(), and sip_show_registry().
08367 { 08368 switch(regstate) { 08369 case REG_STATE_FAILED: 08370 return "Failed"; 08371 case REG_STATE_UNREGISTERED: 08372 return "Unregistered"; 08373 case REG_STATE_REGSENT: 08374 return "Request Sent"; 08375 case REG_STATE_AUTHSENT: 08376 return "Auth. Sent"; 08377 case REG_STATE_REGISTERED: 08378 return "Registered"; 08379 case REG_STATE_REJECTED: 08380 return "Rejected"; 08381 case REG_STATE_TIMEOUT: 08382 return "Timeout"; 08383 case REG_STATE_NOAUTH: 08384 return "No Authentication"; 08385 default: 08386 return "Unknown"; 08387 } 08388 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 20207 of file chan_sip.c.
References sip_reload().
20208 { 20209 return sip_reload(0, 0, NULL); 20210 }
static int reload_config | ( | enum channelreloadreason | reason | ) | [static] |
Re-read SIP.conf config file.
< Default DTMF setting: RFC2833
< NAT support if requested by device with rport
< Allow re-invites
< Default to nat=yes
< Set up call forward on 482 Loop Detected
Definition at line 19034 of file chan_sip.c.
References __ourip, add_realm_authentication(), add_sip_domain(), ast_append_ha(), ast_category_browse(), ast_clear_flag, ast_config_AST_SYSTEM_NAME, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), ast_copy_flags, ast_copy_string(), ast_device_state_changed(), ast_enable_packet_fragmentation(), ast_false(), ast_find_ourip(), AST_FLAGS_ALL, ast_free_ha(), ast_get_ip_or_srv(), ast_gethostbyname(), ast_inet_ntoa(), ast_jb_read_conf(), AST_LIST_EMPTY, ast_log(), AST_MAX_CONTEXT, ast_mutex_lock(), ast_mutex_unlock(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_str2tos(), ast_strdupa, ast_strip(), ast_strlen_zero(), ast_tos2str(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), ASTOBJ_CONTAINER_DESTROYALL, ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_MARKALL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, ASTOBJ_UNREF, authl, bindaddr, build_peer(), build_user(), channelreloadreason2txt(), cleanup_stale_contexts(), clear_realm_authentication(), clear_sip_domains(), context, DEFAULT_ALLOW_EXT_DOM, DEFAULT_ALLOWGUEST, DEFAULT_AUTOCREATEPEER, DEFAULT_CALLERID, DEFAULT_COMPACTHEADERS, DEFAULT_CONTEXT, DEFAULT_DEFAULT_EXPIRY, DEFAULT_EXPIRY, DEFAULT_MAX_CALL_BITRATE, DEFAULT_MAX_EXPIRY, DEFAULT_MAXMS, DEFAULT_MIN_EXPIRY, DEFAULT_MOHINTERPRET, DEFAULT_MOHSUGGEST, DEFAULT_MWITIME, DEFAULT_NOTIFYMIME, DEFAULT_NOTIFYRINGING, DEFAULT_PEDANTIC, default_prefs, DEFAULT_QUALIFY, DEFAULT_REALM, DEFAULT_REGISTRATION_TIMEOUT, DEFAULT_SRVLOOKUP, DEFAULT_T1MIN, DEFAULT_TOS_AUDIO, DEFAULT_TOS_SIP, DEFAULT_TOS_VIDEO, DEFAULT_USERAGENT, DEFAULT_VMEXTEN, display_nat_warning(), errno, EVENT_FLAG_SYSTEM, externexpire, externhost, externip, externrefresh, FALSE, sip_peer::flags, sip_user::flags, gen, global_jbconf, handle_common_options(), hp, ast_variable::lineno, localaddr, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), sip_peer::name, ast_variable::name, netlock, ast_variable::next, notify_types, option_debug, option_verbose, ourport, outboundproxyip, peerl, regl, secret, SIP_CAN_REINVITE, sip_destroy(), sip_destroy_peer(), sip_destroy_user(), SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG, SIP_DTMF_RFC2833, SIP_NAT_ALWAYS, SIP_NAT_RFC3581, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DEBUG_CONFIG, SIP_PAGE2_DEBUG_CONSOLE, SIP_PAGE2_FORWARD_LOOP_DETECTED, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_VIDEOSUPPORT, sip_register(), sip_registry_destroy(), SIP_USEREQPHONE, sipsock, STANDARD_SIP_PORT, strsep(), TRANSFER_CLOSED, TRANSFER_OPENFORALL, userl, username, ast_variable::value, and VERBOSE_PREFIX_2.
Referenced by load_module(), and sip_do_reload().
19035 { 19036 struct ast_config *cfg, *ucfg; 19037 struct ast_variable *v; 19038 struct sip_peer *peer; 19039 struct sip_user *user; 19040 struct ast_hostent ahp; 19041 char *cat, *stringp, *context, *oldregcontext; 19042 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 19043 struct hostent *hp; 19044 int format; 19045 struct ast_flags dummy[2]; 19046 int auto_sip_domains = FALSE; 19047 struct sockaddr_in old_bindaddr = bindaddr; 19048 int registry_count = 0, peer_count = 0, user_count = 0; 19049 unsigned int temp_tos = 0; 19050 struct ast_flags debugflag = {0}; 19051 19052 cfg = ast_config_load(config); 19053 19054 /* We *must* have a config file otherwise stop immediately */ 19055 if (!cfg) { 19056 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 19057 return -1; 19058 } 19059 19060 if (option_debug > 3) 19061 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 19062 19063 clear_realm_authentication(authl); 19064 clear_sip_domains(); 19065 authl = NULL; 19066 19067 ast_free_ha(global_contact_ha); 19068 global_contact_ha = NULL; 19069 19070 /* First, destroy all outstanding registry calls */ 19071 /* This is needed, since otherwise active registry entries will not be destroyed */ 19072 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 19073 ASTOBJ_RDLOCK(iterator); 19074 if (iterator->call) { 19075 if (option_debug > 2) 19076 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 19077 /* This will also remove references to the registry */ 19078 sip_destroy(iterator->call); 19079 } 19080 ASTOBJ_UNLOCK(iterator); 19081 19082 } while(0)); 19083 19084 /* Then, actually destroy users and registry */ 19085 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 19086 if (option_debug > 3) 19087 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 19088 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 19089 if (option_debug > 3) 19090 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 19091 ASTOBJ_CONTAINER_MARKALL(&peerl); 19092 19093 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 19094 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 19095 oldregcontext = oldcontexts; 19096 19097 /* Clear all flags before setting default values */ 19098 /* Preserve debugging settings for console */ 19099 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 19100 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 19101 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 19102 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 19103 19104 /* Reset IP addresses */ 19105 memset(&bindaddr, 0, sizeof(bindaddr)); 19106 ast_free_ha(localaddr); 19107 memset(&localaddr, 0, sizeof(localaddr)); 19108 memset(&externip, 0, sizeof(externip)); 19109 memset(&default_prefs, 0 , sizeof(default_prefs)); 19110 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 19111 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 19112 ourport = STANDARD_SIP_PORT; 19113 srvlookup = DEFAULT_SRVLOOKUP; 19114 global_tos_sip = DEFAULT_TOS_SIP; 19115 global_tos_audio = DEFAULT_TOS_AUDIO; 19116 global_tos_video = DEFAULT_TOS_VIDEO; 19117 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 19118 externexpire = 0; /* Expiration for DNS re-issuing */ 19119 externrefresh = 10; 19120 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 19121 19122 /* Reset channel settings to default before re-configuring */ 19123 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 19124 global_regcontext[0] = '\0'; 19125 expiry = DEFAULT_EXPIRY; 19126 global_notifyringing = DEFAULT_NOTIFYRINGING; 19127 global_limitonpeers = FALSE; 19128 global_prematuremediafilter = FALSE; 19129 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 19130 global_notifyhold = FALSE; 19131 global_alwaysauthreject = 0; 19132 global_allowsubscribe = FALSE; 19133 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 19134 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 19135 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 19136 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 19137 else 19138 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 19139 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 19140 compactheaders = DEFAULT_COMPACTHEADERS; 19141 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 19142 global_regattempts_max = 0; 19143 pedanticsipchecking = DEFAULT_PEDANTIC; 19144 global_mwitime = DEFAULT_MWITIME; 19145 autocreatepeer = DEFAULT_AUTOCREATEPEER; 19146 global_autoframing = 0; 19147 global_allowguest = DEFAULT_ALLOWGUEST; 19148 global_rtptimeout = 0; 19149 global_rtpholdtimeout = 0; 19150 global_rtpkeepalive = 0; 19151 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 19152 global_rtautoclear = 120; 19153 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 19154 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 19155 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 19156 19157 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 19158 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 19159 default_subscribecontext[0] = '\0'; 19160 default_language[0] = '\0'; 19161 default_fromdomain[0] = '\0'; 19162 default_qualify = DEFAULT_QUALIFY; 19163 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 19164 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 19165 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 19166 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 19167 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 19168 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 19169 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 19170 ast_set_flag(&global_flags[0], SIP_NAT_ALWAYS); /*!< Default to nat=yes */ 19171 ast_set_flag(&global_flags[1], SIP_PAGE2_FORWARD_LOOP_DETECTED); /*!< Set up call forward on 482 Loop Detected */ 19172 19173 /* Debugging settings, always default to off */ 19174 dumphistory = FALSE; 19175 recordhistory = FALSE; 19176 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 19177 19178 /* Misc settings for the channel */ 19179 global_relaxdtmf = FALSE; 19180 global_callevents = FALSE; 19181 global_t1min = DEFAULT_T1MIN; 19182 global_shrinkcallerid = 1; 19183 19184 global_matchexterniplocally = FALSE; 19185 19186 /* Copy the default jb config over global_jbconf */ 19187 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 19188 19189 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 19190 19191 /* Read the [general] config section of sip.conf (or from realtime config) */ 19192 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 19193 if (handle_common_options(&global_flags[0], &dummy[0], v)) 19194 continue; 19195 /* handle jb conf */ 19196 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 19197 continue; 19198 19199 /* Create the interface list */ 19200 if (!strcasecmp(v->name, "context")) { 19201 ast_copy_string(default_context, v->value, sizeof(default_context)); 19202 } else if (!strcasecmp(v->name, "subscribecontext")) { 19203 ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext)); 19204 } else if (!strcasecmp(v->name, "allowguest")) { 19205 global_allowguest = ast_true(v->value) ? 1 : 0; 19206 } else if (!strcasecmp(v->name, "realm")) { 19207 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 19208 } else if (!strcasecmp(v->name, "useragent")) { 19209 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 19210 if (option_debug) 19211 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 19212 } else if (!strcasecmp(v->name, "allowtransfer")) { 19213 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 19214 } else if (!strcasecmp(v->name, "rtcachefriends")) { 19215 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 19216 } else if (!strcasecmp(v->name, "rtsavesysname")) { 19217 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 19218 } else if (!strcasecmp(v->name, "rtupdate")) { 19219 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 19220 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 19221 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 19222 } else if (!strcasecmp(v->name, "t1min")) { 19223 global_t1min = atoi(v->value); 19224 } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) { 19225 global_dynamic_exclude_static = ast_true(v->value); 19226 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 19227 global_contact_ha = ast_append_ha(v->name + 7, v->value, global_contact_ha); 19228 } else if (!strcasecmp(v->name, "rtautoclear")) { 19229 int i = atoi(v->value); 19230 if (i > 0) 19231 global_rtautoclear = i; 19232 else 19233 i = 0; 19234 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 19235 } else if (!strcasecmp(v->name, "usereqphone")) { 19236 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 19237 } else if (!strcasecmp(v->name, "prematuremedia")) { 19238 global_prematuremediafilter = ast_true(v->value); 19239 } else if (!strcasecmp(v->name, "relaxdtmf")) { 19240 global_relaxdtmf = ast_true(v->value); 19241 } else if (!strcasecmp(v->name, "checkmwi")) { 19242 if ((sscanf(v->value, "%30d", &global_mwitime) != 1) || (global_mwitime < 0)) { 19243 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 19244 global_mwitime = DEFAULT_MWITIME; 19245 } 19246 } else if (!strcasecmp(v->name, "vmexten")) { 19247 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 19248 } else if (!strcasecmp(v->name, "rtptimeout")) { 19249 if ((sscanf(v->value, "%30d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 19250 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 19251 global_rtptimeout = 0; 19252 } 19253 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 19254 if ((sscanf(v->value, "%30d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 19255 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 19256 global_rtpholdtimeout = 0; 19257 } 19258 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 19259 if ((sscanf(v->value, "%30d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 19260 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 19261 global_rtpkeepalive = 0; 19262 } 19263 } else if (!strcasecmp(v->name, "compactheaders")) { 19264 compactheaders = ast_true(v->value); 19265 } else if (!strcasecmp(v->name, "notifymimetype")) { 19266 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 19267 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 19268 global_limitonpeers = ast_true(v->value); 19269 } else if (!strcasecmp(v->name, "directrtpsetup")) { 19270 global_directrtpsetup = ast_true(v->value); 19271 } else if (!strcasecmp(v->name, "notifyringing")) { 19272 global_notifyringing = ast_true(v->value); 19273 } else if (!strcasecmp(v->name, "notifyhold")) { 19274 global_notifyhold = ast_true(v->value); 19275 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 19276 global_alwaysauthreject = ast_true(v->value); 19277 } else if (!strcasecmp(v->name, "mohinterpret") 19278 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 19279 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 19280 } else if (!strcasecmp(v->name, "mohsuggest")) { 19281 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 19282 } else if (!strcasecmp(v->name, "language")) { 19283 ast_copy_string(default_language, v->value, sizeof(default_language)); 19284 } else if (!strcasecmp(v->name, "regcontext")) { 19285 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 19286 stringp = newcontexts; 19287 /* Let's remove any contexts that are no longer defined in regcontext */ 19288 cleanup_stale_contexts(stringp, oldregcontext); 19289 /* Create contexts if they don't exist already */ 19290 while ((context = strsep(&stringp, "&"))) { 19291 if (!ast_context_find(context)) 19292 ast_context_create(NULL, context,"SIP"); 19293 } 19294 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 19295 } else if (!strcasecmp(v->name, "callerid")) { 19296 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 19297 } else if (!strcasecmp(v->name, "fromdomain")) { 19298 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 19299 } else if (!strcasecmp(v->name, "outboundproxy")) { 19300 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 19301 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 19302 } else if (!strcasecmp(v->name, "outboundproxyport")) { 19303 /* Port needs to be after IP */ 19304 sscanf(v->value, "%30d", &format); 19305 outboundproxyip.sin_port = htons(format); 19306 } else if (!strcasecmp(v->name, "autocreatepeer")) { 19307 autocreatepeer = ast_true(v->value); 19308 } else if (!strcasecmp(v->name, "srvlookup")) { 19309 srvlookup = ast_true(v->value); 19310 } else if (!strcasecmp(v->name, "pedantic")) { 19311 pedanticsipchecking = ast_true(v->value); 19312 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 19313 max_expiry = atoi(v->value); 19314 if (max_expiry < 1) 19315 max_expiry = DEFAULT_MAX_EXPIRY; 19316 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 19317 min_expiry = atoi(v->value); 19318 if (min_expiry < 1) 19319 min_expiry = DEFAULT_MIN_EXPIRY; 19320 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 19321 default_expiry = atoi(v->value); 19322 if (default_expiry < 1) 19323 default_expiry = DEFAULT_DEFAULT_EXPIRY; 19324 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 19325 if (ast_true(v->value)) 19326 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 19327 } else if (!strcasecmp(v->name, "dumphistory")) { 19328 dumphistory = ast_true(v->value); 19329 } else if (!strcasecmp(v->name, "recordhistory")) { 19330 recordhistory = ast_true(v->value); 19331 } else if (!strcasecmp(v->name, "registertimeout")) { 19332 global_reg_timeout = atoi(v->value); 19333 if (global_reg_timeout < 1) 19334 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 19335 } else if (!strcasecmp(v->name, "registerattempts")) { 19336 global_regattempts_max = atoi(v->value); 19337 } else if (!strcasecmp(v->name, "bindaddr")) { 19338 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 19339 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 19340 } else { 19341 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 19342 } 19343 } else if (!strcasecmp(v->name, "localnet")) { 19344 struct ast_ha *na; 19345 if (!(na = ast_append_ha("d", v->value, localaddr))) 19346 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 19347 else 19348 localaddr = na; 19349 } else if (!strcasecmp(v->name, "localmask")) { 19350 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 19351 } else if (!strcasecmp(v->name, "externip")) { 19352 if (!(hp = ast_gethostbyname(v->value, &ahp))) 19353 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 19354 else 19355 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 19356 externexpire = 0; 19357 } else if (!strcasecmp(v->name, "externhost")) { 19358 ast_copy_string(externhost, v->value, sizeof(externhost)); 19359 if (!(hp = ast_gethostbyname(externhost, &ahp))) 19360 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 19361 else 19362 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 19363 externexpire = time(NULL); 19364 } else if (!strcasecmp(v->name, "externrefresh")) { 19365 if (sscanf(v->value, "%30d", &externrefresh) != 1) { 19366 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 19367 externrefresh = 10; 19368 } 19369 } else if (!strcasecmp(v->name, "allow")) { 19370 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 19371 } else if (!strcasecmp(v->name, "disallow")) { 19372 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 19373 } else if (!strcasecmp(v->name, "autoframing")) { 19374 global_autoframing = ast_true(v->value); 19375 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 19376 allow_external_domains = ast_true(v->value); 19377 } else if (!strcasecmp(v->name, "autodomain")) { 19378 auto_sip_domains = ast_true(v->value); 19379 } else if (!strcasecmp(v->name, "domain")) { 19380 char *domain = ast_strdupa(v->value); 19381 char *context = strchr(domain, ','); 19382 19383 if (context) 19384 *context++ = '\0'; 19385 19386 if (option_debug && ast_strlen_zero(context)) 19387 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 19388 if (ast_strlen_zero(domain)) 19389 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 19390 else 19391 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 19392 } else if (!strcasecmp(v->name, "register")) { 19393 if (sip_register(v->value, v->lineno) == 0) 19394 registry_count++; 19395 } else if (!strcasecmp(v->name, "tos")) { 19396 if (!ast_str2tos(v->value, &temp_tos)) { 19397 global_tos_sip = temp_tos; 19398 global_tos_audio = temp_tos; 19399 global_tos_video = temp_tos; 19400 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 19401 } else 19402 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 19403 } else if (!strcasecmp(v->name, "tos_sip")) { 19404 if (ast_str2tos(v->value, &global_tos_sip)) 19405 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 19406 } else if (!strcasecmp(v->name, "tos_audio")) { 19407 if (ast_str2tos(v->value, &global_tos_audio)) 19408 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 19409 } else if (!strcasecmp(v->name, "tos_video")) { 19410 if (ast_str2tos(v->value, &global_tos_video)) 19411 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 19412 } else if (!strcasecmp(v->name, "bindport")) { 19413 if (sscanf(v->value, "%5d", &ourport) == 1) { 19414 bindaddr.sin_port = htons(ourport); 19415 } else { 19416 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 19417 } 19418 } else if (!strcasecmp(v->name, "qualify")) { 19419 if (!strcasecmp(v->value, "no")) { 19420 default_qualify = 0; 19421 } else if (!strcasecmp(v->value, "yes")) { 19422 default_qualify = DEFAULT_MAXMS; 19423 } else if (sscanf(v->value, "%30d", &default_qualify) != 1) { 19424 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 19425 default_qualify = 0; 19426 } 19427 } else if (!strcasecmp(v->name, "callevents")) { 19428 global_callevents = ast_true(v->value); 19429 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 19430 default_maxcallbitrate = atoi(v->value); 19431 if (default_maxcallbitrate < 0) 19432 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 19433 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 19434 global_matchexterniplocally = ast_true(v->value); 19435 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 19436 if (ast_true(v->value)) { 19437 global_shrinkcallerid = 1; 19438 } else if (ast_false(v->value)) { 19439 global_shrinkcallerid = 0; 19440 } else { 19441 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 19442 } 19443 } 19444 } 19445 19446 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 19447 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 19448 allow_external_domains = 1; 19449 } 19450 19451 /* Build list of authentication to various SIP realms, i.e. service providers */ 19452 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 19453 /* Format for authentication is auth = username:password@realm */ 19454 if (!strcasecmp(v->name, "auth")) 19455 authl = add_realm_authentication(authl, v->value, v->lineno); 19456 } 19457 19458 ucfg = ast_config_load("users.conf"); 19459 if (ucfg) { 19460 struct ast_variable *gen; 19461 int genhassip, genregistersip; 19462 const char *hassip, *registersip; 19463 19464 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 19465 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 19466 gen = ast_variable_browse(ucfg, "general"); 19467 cat = ast_category_browse(ucfg, NULL); 19468 while (cat) { 19469 if (strcasecmp(cat, "general")) { 19470 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 19471 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 19472 if (ast_true(hassip) || (!hassip && genhassip)) { 19473 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 19474 if (user) { 19475 ASTOBJ_CONTAINER_LINK(&userl,user); 19476 ASTOBJ_UNREF(user, sip_destroy_user); 19477 user_count++; 19478 } 19479 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, 0); 19480 if (peer) { 19481 ast_device_state_changed("SIP/%s", peer->name); 19482 ASTOBJ_CONTAINER_LINK(&peerl,peer); 19483 ASTOBJ_UNREF(peer, sip_destroy_peer); 19484 peer_count++; 19485 } 19486 } 19487 if (ast_true(registersip) || (!registersip && genregistersip)) { 19488 char tmp[256]; 19489 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 19490 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 19491 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 19492 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 19493 const char *authuser = ast_variable_retrieve(ucfg, cat, "authuser"); 19494 if (!host) 19495 host = ast_variable_retrieve(ucfg, "general", "host"); 19496 if (!username) 19497 username = ast_variable_retrieve(ucfg, "general", "username"); 19498 if (!secret) 19499 secret = ast_variable_retrieve(ucfg, "general", "secret"); 19500 if (!contact) 19501 contact = "s"; 19502 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 19503 if (!ast_strlen_zero(secret)) { 19504 if (!ast_strlen_zero(authuser)) { 19505 snprintf(tmp, sizeof(tmp), "%s:%s:%s@%s/%s", username, secret, authuser, host, contact); 19506 } else { 19507 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 19508 } 19509 } else if (!ast_strlen_zero(authuser)) { 19510 snprintf(tmp, sizeof(tmp), "%s::%s@%s/%s", username, authuser, host, contact); 19511 } else { 19512 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 19513 } 19514 if (sip_register(tmp, 0) == 0) 19515 registry_count++; 19516 } 19517 } 19518 } 19519 cat = ast_category_browse(ucfg, cat); 19520 } 19521 ast_config_destroy(ucfg); 19522 } 19523 19524 19525 /* Load peers, users and friends */ 19526 cat = NULL; 19527 while ( (cat = ast_category_browse(cfg, cat)) ) { 19528 const char *utype; 19529 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 19530 continue; 19531 utype = ast_variable_retrieve(cfg, cat, "type"); 19532 if (!utype) { 19533 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 19534 continue; 19535 } else { 19536 int is_user = 0, is_peer = 0; 19537 if (!strcasecmp(utype, "user")) 19538 is_user = 1; 19539 else if (!strcasecmp(utype, "friend")) 19540 is_user = is_peer = 1; 19541 else if (!strcasecmp(utype, "peer")) 19542 is_peer = 1; 19543 else { 19544 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 19545 continue; 19546 } 19547 if (is_user) { 19548 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 19549 if (user) { 19550 display_nat_warning(cat, reason, &user->flags[0]); 19551 ASTOBJ_CONTAINER_LINK(&userl,user); 19552 ASTOBJ_UNREF(user, sip_destroy_user); 19553 user_count++; 19554 } 19555 } 19556 if (is_peer) { 19557 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0); 19558 if (peer) { 19559 if (!is_user) { 19560 display_nat_warning(cat, reason, &peer->flags[0]); 19561 } 19562 ASTOBJ_CONTAINER_LINK(&peerl,peer); 19563 ASTOBJ_UNREF(peer, sip_destroy_peer); 19564 peer_count++; 19565 } 19566 } 19567 } 19568 } 19569 19570 if (ast_find_ourip(&__ourip, bindaddr)) { 19571 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 19572 ast_config_destroy(cfg); 19573 return 0; 19574 } 19575 if (!ntohs(bindaddr.sin_port)) 19576 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 19577 bindaddr.sin_family = AF_INET; 19578 ast_mutex_lock(&netlock); 19579 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 19580 close(sipsock); 19581 sipsock = -1; 19582 } 19583 if (sipsock < 0) { 19584 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 19585 if (sipsock < 0) { 19586 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 19587 ast_config_destroy(cfg); 19588 ast_mutex_unlock(&netlock); 19589 return -1; 19590 } else { 19591 /* Allow SIP clients on the same host to access us: */ 19592 const int reuseFlag = 1; 19593 19594 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 19595 (const char*)&reuseFlag, 19596 sizeof reuseFlag); 19597 19598 ast_enable_packet_fragmentation(sipsock); 19599 19600 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 19601 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 19602 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 19603 strerror(errno)); 19604 close(sipsock); 19605 sipsock = -1; 19606 } else { 19607 if (option_verbose > 1) { 19608 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 19609 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 19610 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); 19611 } 19612 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 19613 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 19614 } 19615 } 19616 } else if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) { 19617 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 19618 } 19619 ast_mutex_unlock(&netlock); 19620 19621 /* Add default domains - host name, IP address and IP:port */ 19622 /* Only do this if user added any sip domain with "localdomains" */ 19623 /* In order to *not* break backwards compatibility */ 19624 /* Some phones address us at IP only, some with additional port number */ 19625 if (auto_sip_domains) { 19626 char temp[MAXHOSTNAMELEN]; 19627 19628 /* First our default IP address */ 19629 if (bindaddr.sin_addr.s_addr) 19630 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 19631 else 19632 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 19633 19634 /* Our extern IP address, if configured */ 19635 if (externip.sin_addr.s_addr) 19636 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 19637 19638 /* Extern host name (NAT traversal support) */ 19639 if (!ast_strlen_zero(externhost)) 19640 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 19641 19642 /* Our host name */ 19643 if (!gethostname(temp, sizeof(temp))) 19644 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 19645 } 19646 19647 /* Release configuration from memory */ 19648 ast_config_destroy(cfg); 19649 19650 /* Load the list of manual NOTIFY types to support */ 19651 if (notify_types) 19652 ast_config_destroy(notify_types); 19653 notify_types = ast_config_load(notify_config); 19654 19655 /* Done, tell the manager */ 19656 manager_event(EVENT_FLAG_SYSTEM, "ChannelReload", "Channel: 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); 19657 19658 return 0; 19659 }
static void remove_provisional_keepalive_sched | ( | struct sip_pvt * | pvt | ) | [static] |
Definition at line 2483 of file chan_sip.c.
References ao2_ref(), AST_SCHED_DEL, sip_pvt::provisional_keepalive_data, provisional_keepalive_data::sched_id, and unref_provisional_keepalive().
Referenced by __sip_destroy(), send_response(), sip_hangup(), and update_provisional_keepalive().
02484 { 02485 int res; 02486 if (!pvt->provisional_keepalive_data) { 02487 return; 02488 } 02489 res = AST_SCHED_DEL(sched, pvt->provisional_keepalive_data->sched_id); 02490 if (res == -1) { 02491 /* If we could not remove this item. remove pvt's reference 02492 * this data and mark it for removal for the next time the 02493 * scheduler uses it. The scheduler has it's own ref to this 02494 * data and will detect it should not reschedule the event 02495 * since the sched_id is -1 and pvt == NULL */ 02496 pvt->provisional_keepalive_data = unref_provisional_keepalive(pvt->provisional_keepalive_data); 02497 } else { 02498 /* If we successfully canceled the scheduler entry, we need to 02499 * remove its reference to the data. */ 02500 ao2_ref(pvt->provisional_keepalive_data, -1); 02501 } 02502 }
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 12897 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_skip_blanks(), ast_string_field_index, ast_string_field_index_set, ast_string_field_set, ast_strlen_zero(), build_reply_digest(), sip_pvt::domain, get_header(), keys, LOG_WARNING, sip_registry::nonce, sip_pvt::nonce, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::opaque, sip_registry::opaque, sip_pvt::qop, sip_registry::qop, sip_pvt::realm, sip_registry::realm, sip_pvt::registry, and strsep().
Referenced by do_proxy_auth(), and do_register_auth().
12898 { 12899 char tmp[512]; 12900 char *c; 12901 char oldnonce[256]; 12902 12903 /* table of recognised keywords, and places where they should be copied */ 12904 const struct x { 12905 const char *key; 12906 int field_index; 12907 } *i, keys[] = { 12908 { "realm=", ast_string_field_index(p, realm) }, 12909 { "nonce=", ast_string_field_index(p, nonce) }, 12910 { "opaque=", ast_string_field_index(p, opaque) }, 12911 { "qop=", ast_string_field_index(p, qop) }, 12912 { "domain=", ast_string_field_index(p, domain) }, 12913 { NULL, 0 }, 12914 }; 12915 12916 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 12917 if (ast_strlen_zero(tmp)) 12918 return -1; 12919 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 12920 ast_log(LOG_WARNING, "missing Digest.\n"); 12921 return -1; 12922 } 12923 c = tmp + strlen("Digest "); 12924 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 12925 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 12926 for (i = keys; i->key != NULL; i++) { 12927 char *src, *separator; 12928 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 12929 continue; 12930 /* Found. Skip keyword, take text in quotes or up to the separator. */ 12931 c += strlen(i->key); 12932 if (*c == '"') { 12933 src = ++c; 12934 separator = "\""; 12935 } else { 12936 src = c; 12937 separator = ","; 12938 } 12939 strsep(&c, separator); /* clear separator and move ptr */ 12940 ast_string_field_index_set(p, i->field_index, src); 12941 break; 12942 } 12943 if (i->key == NULL) /* not found, try ',' */ 12944 strsep(&c, ","); 12945 } 12946 /* Reset nonce count */ 12947 if (strcmp(p->nonce, oldnonce)) 12948 p->noncecount = 0; 12949 12950 /* Save auth data for following registrations */ 12951 if (p->registry) { 12952 struct sip_registry *r = p->registry; 12953 12954 if (strcmp(r->nonce, p->nonce)) { 12955 ast_string_field_set(r, realm, p->realm); 12956 ast_string_field_set(r, nonce, p->nonce); 12957 ast_string_field_set(r, domain, p->domain); 12958 ast_string_field_set(r, opaque, p->opaque); 12959 ast_string_field_set(r, qop, p->qop); 12960 r->noncecount = 0; 12961 } 12962 } 12963 return build_reply_digest(p, sipmethod, digest, digest_len); 12964 }
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 6848 of file chan_sip.c.
References add_header(), add_route(), ast_copy_string(), ast_log(), ast_random(), ast_strlen_zero(), ast_test_flag, 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, LOG_DEBUG, sip_route::next, sip_pvt::ocseq, sip_pvt::okcontacturi, sip_pvt::our_contact, 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, sipdebug, strcasestr(), strsep(), sip_pvt::tag, text, cfsip_methods::text, sip_pvt::theirtag, TRUE, sip_pvt::uri, and sip_pvt::via.
Referenced by transmit_info_with_digit(), transmit_info_with_vidupdate(), transmit_invite(), transmit_message_with_text(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), transmit_request(), transmit_request_with_auth(), and transmit_state_notify().
06849 { 06850 struct sip_request *orig = &p->initreq; 06851 char stripped[80]; 06852 char tmp[80]; 06853 char newto[256]; 06854 const char *c; 06855 const char *ot, *of; 06856 int is_strict = FALSE; /*!< Strict routing flag */ 06857 06858 memset(req, 0, sizeof(struct sip_request)); 06859 06860 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 06861 06862 if (!seqno) { 06863 p->ocseq++; 06864 seqno = p->ocseq; 06865 } 06866 06867 /* A CANCEL must have the same branch as the INVITE that it is canceling. */ 06868 if (sipmethod == SIP_CANCEL) { 06869 p->branch = p->invite_branch; 06870 build_via(p); 06871 } else if (newbranch && (sipmethod == SIP_INVITE)) { 06872 p->branch ^= ast_random(); 06873 p->invite_branch = p->branch; 06874 build_via(p); 06875 } else if (newbranch) { 06876 p->branch ^= ast_random(); 06877 build_via(p); 06878 } 06879 06880 /* Check for strict or loose router */ 06881 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 06882 is_strict = TRUE; 06883 if (sipdebug) 06884 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 06885 } 06886 06887 if (sipmethod == SIP_CANCEL) 06888 c = p->initreq.rlPart2; /* Use original URI */ 06889 else if (sipmethod == SIP_ACK) { 06890 /* Use URI from Contact: in 200 OK (if INVITE) 06891 (we only have the contacturi on INVITEs) */ 06892 if (!ast_strlen_zero(p->okcontacturi)) 06893 c = is_strict ? p->route->hop : p->okcontacturi; 06894 else 06895 c = p->initreq.rlPart2; 06896 } else if (!ast_strlen_zero(p->okcontacturi)) 06897 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 06898 else if (!ast_strlen_zero(p->uri)) 06899 c = p->uri; 06900 else { 06901 char *n; 06902 /* We have no URI, use To: or From: header as URI (depending on direction) */ 06903 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 06904 sizeof(stripped)); 06905 n = get_in_brackets(stripped); 06906 c = strsep(&n, ";"); /* trim ; and beyond */ 06907 } 06908 init_req(req, sipmethod, c); 06909 06910 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 06911 06912 add_header(req, "Via", p->via); 06913 if (p->route) { 06914 set_destination(p, p->route->hop); 06915 add_route(req, is_strict ? p->route->next : p->route); 06916 } 06917 06918 ot = get_header(orig, "To"); 06919 of = get_header(orig, "From"); 06920 06921 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 06922 as our original request, including tag (or presumably lack thereof) */ 06923 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 06924 /* Add the proper tag if we don't have it already. If they have specified 06925 their tag, use it. Otherwise, use our own tag */ 06926 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 06927 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06928 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06929 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06930 else 06931 snprintf(newto, sizeof(newto), "%s", ot); 06932 ot = newto; 06933 } 06934 06935 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06936 add_header(req, "From", of); 06937 add_header(req, "To", ot); 06938 } else { 06939 add_header(req, "From", ot); 06940 add_header(req, "To", of); 06941 } 06942 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 06943 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 06944 add_header(req, "Contact", p->our_contact); 06945 06946 copy_header(req, orig, "Call-ID"); 06947 add_header(req, "CSeq", tmp); 06948 06949 if (!ast_strlen_zero(global_useragent)) 06950 add_header(req, "User-Agent", global_useragent); 06951 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06952 06953 if (!ast_strlen_zero(p->rpid)) 06954 add_header(req, "Remote-Party-ID", p->rpid); 06955 06956 return 0; 06957 }
static int resp_needs_contact | ( | const char * | msg, | |
enum sipmethod | method | |||
) | [inline, static] |
Test if this response needs a contact header.
Definition at line 6724 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().
06724 { 06725 /* Requirements for Contact header inclusion in responses generated 06726 * from the header tables found in the following RFCs. Where the 06727 * Contact header was marked mandatory (m) or optional (o) this 06728 * function returns 1. 06729 * 06730 * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER) 06731 * - RFC 2976 (INFO) 06732 * - RFC 3262 (PRACK) 06733 * - RFC 3265 (SUBSCRIBE, NOTIFY) 06734 * - RFC 3311 (UPDATE) 06735 * - RFC 3428 (MESSAGE) 06736 * - RFC 3515 (REFER) 06737 * - RFC 3903 (PUBLISH) 06738 */ 06739 06740 switch (method) { 06741 /* 1xx, 2xx, 3xx, 485 */ 06742 case SIP_INVITE: 06743 case SIP_UPDATE: 06744 case SIP_SUBSCRIBE: 06745 case SIP_NOTIFY: 06746 if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3)) 06747 return 1; 06748 break; 06749 06750 /* 2xx, 3xx, 485 */ 06751 case SIP_REGISTER: 06752 case SIP_OPTIONS: 06753 if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3)) 06754 return 1; 06755 break; 06756 06757 /* 3xx, 485 */ 06758 case SIP_BYE: 06759 case SIP_PRACK: 06760 case SIP_MESSAGE: 06761 case SIP_PUBLISH: 06762 if (msg[0] == '3' || !strncmp(msg, "485", 3)) 06763 return 1; 06764 break; 06765 06766 /* 2xx, 3xx, 4xx, 5xx, 6xx */ 06767 case SIP_REFER: 06768 if (msg[0] >= '2' && msg[0] <= '6') 06769 return 1; 06770 break; 06771 06772 /* contact will not be included for everything else */ 06773 case SIP_ACK: 06774 case SIP_CANCEL: 06775 case SIP_INFO: 06776 case SIP_PING: 06777 default: 06778 return 0; 06779 } 06780 return 0; 06781 }
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 6785 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_copy_string(), ast_log(), ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), sip_pvt::expiry, sip_pvt::flags, sip_pvt::fullcontact, get_header(), init_resp(), LOG_WARNING, sip_pvt::method, sip_pvt::our_contact, process_via(), sip_pvt::recv, resp_needs_contact(), sip_pvt::sa, SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, SIPBUFSIZE, strcasestr(), SUPPORTED_EXTENSIONS, sip_pvt::tag, and sip_pvt::theirtag.
Referenced by __transmit_response(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), and transmit_response_with_unsupported().
06786 { 06787 char newto[256]; 06788 const char *ot; 06789 06790 init_resp(resp, msg); 06791 copy_via_headers(p, resp, req, "Via"); 06792 if (msg[0] == '1' || msg[0] == '2') 06793 copy_all_header(resp, req, "Record-Route"); 06794 copy_header(resp, req, "From"); 06795 ot = get_header(req, "To"); 06796 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 06797 /* Add the proper tag if we don't have it already. If they have specified 06798 their tag, use it. Otherwise, use our own tag */ 06799 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06800 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06801 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06802 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06803 else 06804 ast_copy_string(newto, ot, sizeof(newto)); 06805 ot = newto; 06806 } 06807 add_header(resp, "To", ot); 06808 copy_header(resp, req, "Call-ID"); 06809 copy_header(resp, req, "CSeq"); 06810 if (!ast_strlen_zero(global_useragent)) 06811 add_header(resp, "User-Agent", global_useragent); 06812 add_header(resp, "Allow", ALLOWED_METHODS); 06813 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 06814 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 06815 /* For registration responses, we also need expiry and 06816 contact info */ 06817 char tmp[256]; 06818 06819 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 06820 add_header(resp, "Expires", tmp); 06821 if (p->expiry) { /* Only add contact if we have an expiry time */ 06822 char contact[SIPBUFSIZE]; 06823 const char *contact_uri = p->method == SIP_SUBSCRIBE ? p->our_contact : p->fullcontact; 06824 char *brackets = strchr(contact_uri, '<'); 06825 snprintf(contact, sizeof(contact), "%s%s%s;expires=%d", brackets ? "" : "<", contact_uri, brackets ? "" : ">", p->expiry); 06826 add_header(resp, "Contact", contact); /* Not when we unregister */ 06827 } 06828 } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) { 06829 add_header(resp, "Contact", p->our_contact); 06830 } 06831 06832 /* default to routing the response to the address where the request 06833 * came from. Since we don't have a transport layer, we do this here. 06834 * The process_via() function will update the port to either the port 06835 * specified in the via header or the default port later on (per RFC 06836 * 3261 section 18.2.2). 06837 */ 06838 p->sa = p->recv; 06839 06840 if (process_via(p, req)) { 06841 ast_log(LOG_WARNING, "error processing via header, will send response to originating address\n"); 06842 } 06843 06844 return 0; 06845 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 17836 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.
Referenced by load_module(), sip_reload(), and sip_request_call().
17837 { 17838 /* If we're supposed to be stopped -- stay stopped */ 17839 if (monitor_thread == AST_PTHREADT_STOP) 17840 return 0; 17841 ast_mutex_lock(&monlock); 17842 if (monitor_thread == pthread_self()) { 17843 ast_mutex_unlock(&monlock); 17844 ast_log(LOG_WARNING, "Cannot kill myself\n"); 17845 return -1; 17846 } 17847 if (monitor_thread != AST_PTHREADT_NULL) { 17848 /* Wake up the thread */ 17849 pthread_kill(monitor_thread, SIGURG); 17850 } else { 17851 /* Start a new monitor */ 17852 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 17853 ast_mutex_unlock(&monlock); 17854 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 17855 return -1; 17856 } 17857 } 17858 ast_mutex_unlock(&monlock); 17859 return 0; 17860 }
static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 2015 of file chan_sip.c.
References __sip_xmit(), append_history, AST_CAUSE_NO_USER_RESPONSE, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_test_flag, ast_verbose(), sip_pvt::callid, sip_pkt::data, DEADLOCK_AVOIDANCE, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, sip_pvt::flags, free, sip_pvt::from, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, MAX_RETRANS, sip_pkt::method, sip_pkt::next, option_debug, 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_NEEDDESTROY, SIP_OPTIONS, sip_real_dst(), sipdebug, cfsip_methods::text, sip_pkt::timer_a, sip_pkt::timer_t1, and XMIT_ERROR.
Referenced by __sip_reliable_xmit().
02016 { 02017 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 02018 int reschedule = DEFAULT_RETRANS; 02019 int xmitres = 0; 02020 02021 /* Lock channel PVT */ 02022 ast_mutex_lock(&pkt->owner->lock); 02023 02024 if (pkt->retrans < MAX_RETRANS) { 02025 pkt->retrans++; 02026 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 02027 if (sipdebug && option_debug > 3) 02028 ast_log(LOG_DEBUG, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n", pkt->retransid, sip_methods[pkt->method].text, pkt->method); 02029 } else { 02030 int siptimer_a; 02031 02032 if (sipdebug && option_debug > 3) 02033 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 02034 if (!pkt->timer_a) 02035 pkt->timer_a = 2 ; 02036 else 02037 pkt->timer_a = 2 * pkt->timer_a; 02038 02039 /* For non-invites, a maximum of 4 secs */ 02040 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 02041 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 02042 siptimer_a = 4000; 02043 02044 /* Reschedule re-transmit */ 02045 reschedule = siptimer_a; 02046 if (option_debug > 3) 02047 ast_log(LOG_DEBUG, "** 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); 02048 } 02049 02050 if (sip_debug_test_pvt(pkt->owner)) { 02051 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 02052 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 02053 pkt->retrans, sip_nat_mode(pkt->owner), 02054 ast_inet_ntoa(dst->sin_addr), 02055 ntohs(dst->sin_port), pkt->data); 02056 } 02057 02058 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 02059 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 02060 if (xmitres == XMIT_ERROR) { 02061 ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid); 02062 } else { 02063 ast_mutex_unlock(&pkt->owner->lock); 02064 return reschedule; 02065 } 02066 } 02067 /* Too many retries */ 02068 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 02069 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 02070 ast_log(LOG_WARNING, "Maximum retries exceeded on transmission %s from %s for packet seqno %d (%s %s %s)\n", pkt->owner->callid, pkt->owner->from, pkt->seqno, (ast_test_flag(pkt, FLAG_FATAL)) ? "Critical" : "Non-critical", (ast_test_flag(pkt, FLAG_RESPONSE)) ? "Response: " : "Request: ", sip_methods[pkt->method].text); 02071 } else if ((pkt->method == SIP_OPTIONS) && sipdebug) { 02072 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) -- See doc/sip-retransmit.txt.\n", pkt->owner->callid); 02073 } 02074 if (xmitres == XMIT_ERROR) { 02075 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid); 02076 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02077 } else 02078 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02079 02080 pkt->retransid = -1; 02081 02082 if (ast_test_flag(pkt, FLAG_FATAL)) { 02083 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 02084 DEADLOCK_AVOIDANCE(&pkt->owner->lock); /* SIP_PVT, not channel */ 02085 } 02086 02087 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 02088 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 02089 02090 if (pkt->owner->owner) { 02091 sip_alreadygone(pkt->owner); 02092 ast_log(LOG_WARNING, "Hanging up call %s from channel %s . No reply to our critical packet after %d retries (see doc/sip-retransmit.txt).\n", pkt->owner->callid, pkt->owner->owner->name, pkt->retrans); 02093 ast_queue_hangup(pkt->owner->owner); 02094 ast_channel_unlock(pkt->owner->owner); 02095 } else { 02096 /* If no channel owner, destroy now */ 02097 02098 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 02099 if (pkt->method != SIP_OPTIONS) { 02100 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02101 sip_alreadygone(pkt->owner); 02102 if (option_debug) 02103 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 02104 } 02105 } 02106 } 02107 02108 if (pkt->method == SIP_BYE) { 02109 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 02110 sip_alreadygone(pkt->owner); 02111 if (pkt->owner->owner) 02112 ast_channel_unlock(pkt->owner->owner); 02113 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 02114 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02115 } 02116 02117 /* In any case, go ahead and remove the packet */ 02118 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 02119 if (cur == pkt) 02120 break; 02121 } 02122 if (cur) { 02123 if (prev) 02124 prev->next = cur->next; 02125 else 02126 pkt->owner->packets = cur->next; 02127 ast_mutex_unlock(&pkt->owner->lock); 02128 free(cur); 02129 pkt = NULL; 02130 } else 02131 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 02132 if (pkt) 02133 ast_mutex_unlock(&pkt->owner->lock); 02134 return 0; 02135 }
static int scheduler_process_request_queue | ( | const void * | data | ) | [static] |
Definition at line 17381 of file chan_sip.c.
References ast_channel_trylock, ast_channel_unlock, AST_LIST_EMPTY, ast_mutex_lock(), ast_mutex_unlock(), ast_update_use_count(), sip_pvt::lock, sip_pvt::owner, process_request_queue(), sip_pvt::request_queue, and sip_pvt::request_queue_sched_id.
Referenced by queue_request().
17382 { 17383 struct sip_pvt *p = (struct sip_pvt *) data; 17384 int recount = 0; 17385 int nounlock = 0; 17386 int lockretry; 17387 17388 for (lockretry = 10; lockretry > 0; lockretry--) { 17389 ast_mutex_lock(&p->lock); 17390 17391 /* lock the owner if it has one -- we may need it */ 17392 /* because this is deadlock-prone, we need to try and unlock if failed */ 17393 if (!p->owner || !ast_channel_trylock(p->owner)) { 17394 break; /* locking succeeded */ 17395 } 17396 17397 if (lockretry != 1) { 17398 ast_mutex_unlock(&p->lock); 17399 /* Sleep for a very short amount of time */ 17400 usleep(1); 17401 } 17402 } 17403 17404 if (!lockretry) { 17405 int retry = !AST_LIST_EMPTY(&p->request_queue); 17406 17407 /* we couldn't get the owner lock, which is needed to process 17408 the queued requests, so return a non-zero value, which will 17409 cause the scheduler to run this request again later if there 17410 still requests to be processed 17411 */ 17412 ast_mutex_unlock(&p->lock); 17413 return retry; 17414 }; 17415 17416 process_request_queue(p, &recount, &nounlock); 17417 p->request_queue_sched_id = -1; 17418 17419 if (p->owner && !nounlock) { 17420 ast_channel_unlock(p->owner); 17421 } 17422 ast_mutex_unlock(&p->lock); 17423 17424 if (recount) { 17425 ast_update_use_count(); 17426 } 17427 17428 return 0; 17429 }
static int send_provisional_keepalive | ( | const void * | data | ) | [static] |
Definition at line 2459 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
02460 { 02461 struct provisional_keepalive_data *d = (struct provisional_keepalive_data *) data; 02462 02463 return send_provisional_keepalive_full(d, 0); 02464 }
static int send_provisional_keepalive_full | ( | struct provisional_keepalive_data * | data, | |
int | with_sdp | |||
) | [static] |
This is called by the scheduler to resend the last provisional message in a dialog.
Definition at line 2406 of file chan_sip.c.
References ao2_ref(), ast_channel_trylock, ast_channel_unlock, ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::initreq, INV_COMPLETED, sip_pvt::invitestate, sip_pvt::last_provisional, sip_pvt::lock, sip_pvt::owner, PROVIS_KEEPALIVE_TIMEOUT, provisional_keepalive_data::pvt, S_OR, provisional_keepalive_data::sched_id, transmit_response(), transmit_response_with_sdp(), and XMIT_UNRELIABLE.
Referenced by send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().
02407 { 02408 const char *msg = NULL; 02409 int res = 0; 02410 struct sip_pvt *pvt = data->pvt; 02411 02412 if (!pvt) { 02413 ao2_ref(data, -1); /* not rescheduling so drop ref. in this case the dialog has already dropped this ref */ 02414 return res; 02415 } 02416 02417 ast_mutex_lock(&pvt->lock); 02418 while (pvt->owner && ast_channel_trylock(pvt->owner)) { 02419 ast_mutex_unlock(&pvt->lock); 02420 sched_yield(); 02421 if ((pvt = data->pvt)) { 02422 ast_mutex_lock(&pvt->lock); 02423 } else { 02424 ao2_ref(data, -1); 02425 return res; 02426 } 02427 } 02428 02429 if (data->sched_id == -1 || pvt->invitestate >= INV_COMPLETED) { 02430 goto provisional_keepalive_cleanup; 02431 } 02432 02433 if (!pvt->last_provisional || !strncasecmp(pvt->last_provisional, "100", 3)) { 02434 msg = "183 Session Progress"; 02435 } 02436 02437 if (with_sdp) { 02438 transmit_response_with_sdp(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq, XMIT_UNRELIABLE); 02439 } else { 02440 transmit_response(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq); 02441 } 02442 02443 res = PROVIS_KEEPALIVE_TIMEOUT; /* reschedule the keepalive event */ 02444 02445 provisional_keepalive_cleanup: 02446 if (!res) { /* not rescheduling, so drop ref */ 02447 data->sched_id = -1; /* if we don't re-schedule, make sure to remove the sched id */ 02448 ao2_ref(data, -1); /* release the scheduler's reference to this data */ 02449 } 02450 02451 if (pvt->owner) { 02452 ast_channel_unlock(pvt->owner); 02453 } 02454 ast_mutex_unlock(&pvt->lock); 02455 02456 return res; 02457 }
static int send_provisional_keepalive_with_sdp | ( | const void * | data | ) | [static] |
Definition at line 2466 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
02467 { 02468 struct provisional_keepalive_data *d = (struct provisional_keepalive_data *) data; 02469 02470 return send_provisional_keepalive_full(d, 1); 02471 }
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 2567 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, finalize_content(), sip_pvt::flags, get_header(), sip_request::len, sip_request::method, parse_copy(), sip_pvt::recv, sip_pvt::sa, sip_debug_test_pvt(), sip_methods, SIP_NAT_ROUTE, SIP_NO_HISTORY, cfsip_methods::text, and XMIT_CRITICAL.
Referenced by transmit_info_with_digit(), transmit_info_with_vidupdate(), transmit_invite(), transmit_message_with_text(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), transmit_request(), transmit_request_with_auth(), transmit_sip_request(), and transmit_state_notify().
02568 { 02569 int res; 02570 02571 finalize_content(req); 02572 add_blank(req); 02573 if (sip_debug_test_pvt(p)) { 02574 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02575 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); 02576 else 02577 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); 02578 } 02579 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02580 struct sip_request tmp; 02581 parse_copy(&tmp, req); 02582 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02583 } 02584 res = (reliable) ? 02585 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02586 __sip_xmit(p, req->data, req->len); 02587 return res; 02588 }
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 2532 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, finalize_content(), sip_pvt::flags, get_header(), sip_pvt::initreq, sip_request::len, sip_request::method, parse_copy(), remove_provisional_keepalive_sched(), sip_request::rlPart2, sip_debug_test_pvt(), SIP_INVITE, sip_methods, sip_nat_mode(), SIP_NO_HISTORY, sip_real_dst(), SIP_RESPONSE, SIP_UNKNOWN, cfsip_methods::text, and XMIT_CRITICAL.
Referenced by __transmit_response(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), and transmit_response_with_unsupported().
02533 { 02534 int res; 02535 02536 finalize_content(req); 02537 add_blank(req); 02538 if (sip_debug_test_pvt(p)) { 02539 const struct sockaddr_in *dst = sip_real_dst(p); 02540 02541 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02542 reliable ? "Reliably " : "", sip_nat_mode(p), 02543 ast_inet_ntoa(dst->sin_addr), 02544 ntohs(dst->sin_port), req->data); 02545 } 02546 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02547 struct sip_request tmp; 02548 parse_copy(&tmp, req); 02549 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02550 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02551 } 02552 02553 /* If we are sending a final response to an INVITE, stop retransmitting provisional responses */ 02554 if (p->initreq.method == SIP_INVITE && reliable == XMIT_CRITICAL) { 02555 remove_provisional_keepalive_sched(p); 02556 } 02557 02558 res = (reliable) ? 02559 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02560 __sip_xmit(p, req->data, req->len); 02561 if (res > 0) 02562 return 0; 02563 return res; 02564 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 9052 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, and SIP_NAT_ROUTE.
Referenced by handle_response_invite().
09053 { 09054 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 09055 /* NAT: Don't trust the contact field. Just use what they came to us 09056 with. */ 09057 pvt->sa = pvt->recv; 09058 return 0; 09059 } 09060 09061 return __set_address_from_contact(pvt->fullcontact, &pvt->sa); 09062 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 6634 of file chan_sip.c.
References 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().
06635 { 06636 char *h, *maddr, hostname[256]; 06637 int port, hn; 06638 struct hostent *hp; 06639 struct ast_hostent ahp; 06640 int debug=sip_debug_test_pvt(p); 06641 06642 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 06643 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 06644 06645 if (debug) 06646 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 06647 06648 /* Find and parse hostname */ 06649 h = strchr(uri, '@'); 06650 if (h) 06651 ++h; 06652 else { 06653 h = uri; 06654 if (strncasecmp(h, "sip:", 4) == 0) 06655 h += 4; 06656 else if (strncasecmp(h, "sips:", 5) == 0) 06657 h += 5; 06658 } 06659 hn = strcspn(h, ":;>") + 1; 06660 if (hn > sizeof(hostname)) 06661 hn = sizeof(hostname); 06662 ast_copy_string(hostname, h, hn); 06663 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 06664 h += hn - 1; 06665 06666 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 06667 if (*h == ':') { 06668 /* Parse port */ 06669 ++h; 06670 port = strtol(h, &h, 10); 06671 } 06672 else 06673 port = STANDARD_SIP_PORT; 06674 06675 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 06676 maddr = strstr(h, "maddr="); 06677 if (maddr) { 06678 maddr += 6; 06679 hn = strspn(maddr, "0123456789.") + 1; 06680 if (hn > sizeof(hostname)) 06681 hn = sizeof(hostname); 06682 ast_copy_string(hostname, maddr, hn); 06683 } 06684 06685 hp = ast_gethostbyname(hostname, &ahp); 06686 if (hp == NULL) { 06687 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 06688 return; 06689 } 06690 p->sa.sin_family = AF_INET; 06691 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 06692 p->sa.sin_port = htons(port); 06693 if (debug) 06694 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 06695 }
static void set_insecure_flags | ( | struct ast_flags * | flags, | |
const char * | value, | |||
int | lineno | |||
) | [static] |
Parse the "insecure" setting from sip.conf or from realtime.
flags | a pointer to an ast_flags structure | |
value | the value of the SIP insecure setting | |
lineno | linenumber in sip.conf or -1 for realtime |
Definition at line 18183 of file chan_sip.c.
References ast_copy_string(), ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_true(), LOG_WARNING, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, and strsep().
Referenced by handle_common_options(), and realtime_peer().
18184 { 18185 static int dep_insecure_very = 0; 18186 static int dep_insecure_yes = 0; 18187 18188 if (ast_strlen_zero(value)) 18189 return; 18190 18191 if (!strcasecmp(value, "very")) { 18192 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 18193 if(!dep_insecure_very) { 18194 if(lineno != -1) 18195 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno); 18196 else 18197 ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n"); 18198 dep_insecure_very = 1; 18199 } 18200 } 18201 else if (ast_true(value)) { 18202 ast_set_flag(flags, SIP_INSECURE_PORT); 18203 if(!dep_insecure_yes) { 18204 if(lineno != -1) 18205 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno); 18206 else 18207 ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value); 18208 dep_insecure_yes = 1; 18209 } 18210 } 18211 else if (!ast_false(value)) { 18212 char buf[64]; 18213 char *word, *next; 18214 ast_copy_string(buf, value, sizeof(buf)); 18215 next = buf; 18216 while ((word = strsep(&next, ","))) { 18217 if (!strcasecmp(word, "port")) 18218 ast_set_flag(flags, SIP_INSECURE_PORT); 18219 else if (!strcasecmp(word, "invite")) 18220 ast_set_flag(flags, SIP_INSECURE_INVITE); 18221 else 18222 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 18223 } 18224 } 18225 }
static void set_nonce_randdata | ( | struct sip_pvt * | p, | |
int | forceupdate | |||
) | [static] |
builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one.
Definition at line 9390 of file chan_sip.c.
References ast_random(), ast_string_field_build, ast_strlen_zero(), sip_pvt::randdata, and sip_pvt::stalenonce.
Referenced by check_auth(), and transmit_fake_auth_response().
09391 { 09392 if (p->stalenonce || forceupdate || ast_strlen_zero(p->randdata)) { 09393 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 09394 p->stalenonce = 0; 09395 } 09396 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 18617 of file chan_sip.c.
References sip_peer::addr, sip_peer::allowtransfer, ast_copy_flags, sip_peer::autoframing, sip_peer::callgroup, sip_peer::capability, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, default_prefs, sip_peer::expire, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::language, sip_peer::mailbox, 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::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, SIP_FLAGS_TO_COPY, SIP_PAGE2_FLAGS_TO_COPY, STANDARD_SIP_PORT, sip_peer::subscribecontext, and sip_peer::vmexten.
Referenced by build_peer(), and temp_peer().
18618 { 18619 if (peer->expire == 0) { 18620 /* Don't reset expire or port time during reload 18621 if we have an active registration 18622 */ 18623 peer->expire = -1; 18624 peer->pokeexpire = -1; 18625 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 18626 } 18627 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 18628 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 18629 strcpy(peer->context, default_context); 18630 strcpy(peer->subscribecontext, default_subscribecontext); 18631 strcpy(peer->language, default_language); 18632 strcpy(peer->mohinterpret, default_mohinterpret); 18633 strcpy(peer->mohsuggest, default_mohsuggest); 18634 peer->addr.sin_family = AF_INET; 18635 peer->defaddr.sin_family = AF_INET; 18636 peer->capability = global_capability; 18637 peer->maxcallbitrate = default_maxcallbitrate; 18638 peer->rtptimeout = global_rtptimeout; 18639 peer->rtpholdtimeout = global_rtpholdtimeout; 18640 peer->rtpkeepalive = global_rtpkeepalive; 18641 peer->allowtransfer = global_allowtransfer; 18642 peer->autoframing = global_autoframing; 18643 strcpy(peer->vmexten, default_vmexten); 18644 peer->secret[0] = '\0'; 18645 peer->md5secret[0] = '\0'; 18646 peer->cid_num[0] = '\0'; 18647 peer->cid_name[0] = '\0'; 18648 peer->fromdomain[0] = '\0'; 18649 peer->fromuser[0] = '\0'; 18650 peer->regexten[0] = '\0'; 18651 peer->mailbox[0] = '\0'; 18652 memset(&peer->callgroup, 0, sizeof(peer->callgroup)); 18653 memset(&peer->pickupgroup, 0, sizeof(peer->pickupgroup)); 18654 peer->maxms = default_qualify; 18655 peer->prefs = default_prefs; 18656 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 20008 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), ast_strlen_zero(), FALSE, inbuf(), LOG_DEBUG, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), sipdebug, and TRUE.
Referenced by load_module().
20009 { 20010 int no = 0; 20011 int ok = FALSE; 20012 char varbuf[30]; 20013 char *inbuf = (char *) data; 20014 20015 if (ast_strlen_zero(inbuf)) { 20016 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 20017 return 0; 20018 } 20019 ast_channel_lock(chan); 20020 20021 /* Check for headers */ 20022 while (!ok && no <= 50) { 20023 no++; 20024 snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no); 20025 20026 /* Compare without the leading underscores */ 20027 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL) ) 20028 ok = TRUE; 20029 } 20030 if (ok) { 20031 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 20032 if (sipdebug) 20033 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 20034 } else { 20035 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 20036 } 20037 ast_channel_unlock(chan); 20038 return 0; 20039 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 2944 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02945 { 02946 /* We know name is the first field, so we can cast */ 02947 struct sip_peer *p = (struct sip_peer *) name; 02948 return !(!inaddrcmp(&p->addr, sin) || 02949 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02950 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02951 }
static struct sip_pvt * sip_alloc | ( | ast_string_field | callid, | |
struct sockaddr_in * | sin, | |||
int | useglobal_nat, | |||
const int | intended_method | |||
) | [static, read] |
Allocate SIP_PVT structure and set defaults.
Definition at line 4870 of file chan_sip.c.
References __ourip, sip_pvt::allowtransfer, ast_calloc, ast_copy_flags, AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), 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_settos(), ast_set2_flag, ast_sip_ouraddrfor(), ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_test_flag, ast_udptl_destroy(), ast_udptl_get_error_correction_scheme(), ast_udptl_new_with_bindaddr(), ast_udptl_settos(), ast_variables_destroy(), sip_pvt::autoframing, sip_pvt::autokillid, bindaddr, sip_pvt::branch, build_callid_pvt(), build_via(), t38properties::capability, sip_pvt::capability, sip_pvt::chanvars, context, default_prefs, do_setnat(), errno, sip_pvt::flags, free, sip_pvt::fromdomain, iflist, iflock, INITIAL_CSEQ, sip_pvt::initid, t38properties::jointcapability, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, make_our_tag(), sip_pvt::maxcallbitrate, sip_pvt::method, mohinterpret, mohsuggest, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ocseq, option_debug, sip_pvt::ourip, sip_pvt::prefs, sip_pvt::recv, sip_pvt::request_queue, sip_pvt::request_queue_sched_id, sip_pvt::rtp, sip_pvt::sa, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, SIP_OPTIONS, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_REGISTER, sip_pvt::stateid, sip_pvt::subscribed, sip_pvt::t38, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, sip_pvt::tag, text, sip_pvt::timer_t1, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, sip_pvt::vrtp, and sip_pvt::waitid.
Referenced by find_call(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
04872 { 04873 struct sip_pvt *p; 04874 04875 if (!(p = ast_calloc(1, sizeof(*p)))) 04876 return NULL; 04877 04878 if (ast_string_field_init(p, 512)) { 04879 free(p); 04880 return NULL; 04881 } 04882 04883 ast_mutex_init(&p->lock); 04884 04885 p->method = intended_method; 04886 p->initid = -1; 04887 p->waitid = -1; 04888 p->autokillid = -1; 04889 p->request_queue_sched_id = -1; 04890 p->subscribed = NONE; 04891 p->stateid = -1; 04892 p->prefs = default_prefs; /* Set default codecs for this call */ 04893 04894 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04895 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04896 04897 if (sin) { 04898 p->sa = *sin; 04899 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04900 p->ourip = __ourip; 04901 } else 04902 p->ourip = __ourip; 04903 04904 /* Copy global flags to this PVT at setup. */ 04905 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04906 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04907 04908 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04909 04910 p->branch = ast_random(); 04911 make_our_tag(p->tag, sizeof(p->tag)); 04912 p->ocseq = INITIAL_CSEQ; 04913 04914 if (sip_methods[intended_method].need_rtp) { 04915 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04916 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04917 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04918 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04919 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04920 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04921 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04922 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04923 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04924 /* If rtp was successfully allocated, but vrtp was not, then we need to be sure to free rtp here */ 04925 if (p->rtp) { 04926 ast_rtp_destroy(p->rtp); 04927 } 04928 if (p->udptl) { 04929 ast_udptl_destroy(p->udptl); 04930 } 04931 ast_mutex_destroy(&p->lock); 04932 if (p->chanvars) { 04933 ast_variables_destroy(p->chanvars); 04934 p->chanvars = NULL; 04935 } 04936 ast_string_field_free_memory(p); 04937 free(p); 04938 return NULL; 04939 } 04940 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04941 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04942 ast_rtp_settos(p->rtp, global_tos_audio); 04943 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04944 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04945 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04946 if (p->vrtp) { 04947 ast_rtp_settos(p->vrtp, global_tos_video); 04948 ast_rtp_setdtmf(p->vrtp, 0); 04949 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04950 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04951 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04952 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04953 } 04954 if (p->udptl) 04955 ast_udptl_settos(p->udptl, global_tos_audio); 04956 p->maxcallbitrate = default_maxcallbitrate; 04957 p->autoframing = global_autoframing; 04958 ast_rtp_codec_setpref(p->rtp, &p->prefs); 04959 } 04960 04961 if (useglobal_nat && sin) { 04962 /* Setup NAT structure according to global settings if we have an address */ 04963 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04964 p->recv = *sin; 04965 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04966 } 04967 04968 if (p->method != SIP_REGISTER) 04969 ast_string_field_set(p, fromdomain, default_fromdomain); 04970 build_via(p); 04971 if (!callid) 04972 build_callid_pvt(p); 04973 else 04974 ast_string_field_set(p, callid, callid); 04975 /* Assign default music on hold class */ 04976 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04977 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04978 p->capability = global_capability; 04979 p->allowtransfer = global_allowtransfer; 04980 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04981 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04982 p->noncodeccapability |= AST_RTP_DTMF; 04983 if (p->udptl) { 04984 p->t38.capability = global_t38_capability; 04985 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04986 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04987 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04988 p->t38.capability |= T38FAX_UDP_EC_FEC; 04989 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04990 p->t38.capability |= T38FAX_UDP_EC_NONE; 04991 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04992 p->t38.jointcapability = p->t38.capability; 04993 } 04994 ast_string_field_set(p, context, default_context); 04995 04996 AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue); 04997 04998 /* Add to active dialog list */ 04999 ast_mutex_lock(&iflock); 05000 p->next = iflist; 05001 iflist = p; 05002 ast_mutex_unlock(&iflock); 05003 if (option_debug) 05004 ast_log(LOG_DEBUG, "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"); 05005 return p; 05006 }
static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1771 of file chan_sip.c.
References ast_log(), ast_set_flag, sip_pvt::callid, sip_pvt::flags, LOG_DEBUG, option_debug, and SIP_ALREADYGONE.
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().
01772 { 01773 if (option_debug > 2) 01774 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01775 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01776 }
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 4023 of file chan_sip.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_new_source(), ast_set_flag, ast_setstate(), AST_STATE_UP, sip_pvt::flags, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::rtp, SIP_PAGE2_DIALOG_ESTABLISHED, ast_channel::tech_pvt, transmit_response_with_sdp(), try_suggested_sip_codec(), and XMIT_CRITICAL.
04024 { 04025 int res = 0; 04026 struct sip_pvt *p = ast->tech_pvt; 04027 04028 ast_mutex_lock(&p->lock); 04029 if (ast->_state != AST_STATE_UP) { 04030 try_suggested_sip_codec(p); 04031 04032 ast_setstate(ast, AST_STATE_UP); 04033 if (option_debug) 04034 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 04035 04036 ast_rtp_new_source(p->rtp); 04037 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 04038 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 04039 } 04040 ast_mutex_unlock(&p->lock); 04041 return res; 04042 }
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 3280 of file chan_sip.c.
References ast_channel::_state, sip_invite_param::addsipheaders, AST_CAUSE_USER_BUSY, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), ast_sched_add(), AST_SCHED_DEL, 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(), sip_pvt::callingpres, t38properties::capability, sip_pvt::capability, ast_channel::cid, cid_name, sip_pvt::cid_name, ast_callerid::cid_pres, sip_invite_param::distinctive_ring, 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_DEBUG, LOG_WARNING, sip_pvt::maxtime, sip_pvt::noncodeccapability, option_debug, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, SIP_INVITE, SIP_OUTGOING, SIP_TRANS_TIMEOUT, SIPBUFSIZE, sipdebug, sip_pvt::t38, ast_channel::tech_pvt, 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.
03281 { 03282 int res, xmitres = 0; 03283 struct sip_pvt *p; 03284 struct varshead *headp; 03285 struct ast_var_t *current; 03286 const char *referer = NULL; /* SIP refererer */ 03287 03288 p = ast->tech_pvt; 03289 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 03290 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 03291 return -1; 03292 } 03293 03294 /* Check whether there is vxml_url, distinctive ring variables */ 03295 headp=&ast->varshead; 03296 AST_LIST_TRAVERSE(headp,current,entries) { 03297 /* Check whether there is a VXML_URL variable */ 03298 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 03299 p->options->vxml_url = ast_var_value(current); 03300 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 03301 p->options->uri_options = ast_var_value(current); 03302 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 03303 /* Check whether there is a ALERT_INFO variable */ 03304 p->options->distinctive_ring = ast_var_value(current); 03305 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 03306 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 03307 p->options->addsipheaders = 1; 03308 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 03309 /* This is a transfered call */ 03310 p->options->transfer = 1; 03311 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 03312 /* This is the referer */ 03313 referer = ast_var_value(current); 03314 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 03315 /* We're replacing a call. */ 03316 p->options->replaces = ast_var_value(current); 03317 } 03318 } 03319 03320 res = 0; 03321 ast_set_flag(&p->flags[0], SIP_OUTGOING); 03322 03323 if (p->options->transfer) { 03324 char buf[SIPBUFSIZE/2]; 03325 03326 if (referer) { 03327 if (sipdebug && option_debug > 2) 03328 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 03329 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 03330 } else 03331 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 03332 ast_string_field_set(p, cid_name, buf); 03333 } 03334 if (option_debug) 03335 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 03336 03337 res = update_call_counter(p, INC_CALL_RINGING); 03338 if ( res != -1 ) { 03339 p->callingpres = ast->cid.cid_pres; 03340 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 03341 p->jointnoncodeccapability = p->noncodeccapability; 03342 03343 /* If there are no audio formats left to offer, punt */ 03344 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 03345 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 03346 res = -1; 03347 } else { 03348 p->t38.jointcapability = p->t38.capability; 03349 if (option_debug > 1) 03350 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 03351 xmitres = transmit_invite(p, SIP_INVITE, 1, 2); 03352 if (xmitres == XMIT_ERROR) 03353 return -1; /* Transmission error */ 03354 03355 p->invitestate = INV_CALLING; 03356 03357 /* Initialize auto-congest time */ 03358 AST_SCHED_DEL(sched, p->initid); 03359 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 03360 } 03361 } else { 03362 ast->hangupcause = AST_CAUSE_USER_BUSY; 03363 } 03364 return res; 03365 }
static int sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2277 of file chan_sip.c.
References append_history, ast_sched_del(), and sip_pvt::autokillid.
Referenced by check_user_full(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), notify_extenstate_update(), register_verify(), and sip_hangup().
02278 { 02279 int res = 0; 02280 if (p->autokillid > -1) { 02281 if (!(res = ast_sched_del(sched, p->autokillid))) { 02282 append_history(p, "CancelDestroy", ""); 02283 p->autokillid = -1; 02284 } 02285 } 02286 return res; 02287 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1853 of file chan_sip.c.
References debugaddr, and sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1879 of file chan_sip.c.
References sip_debug_test_addr(), sip_real_dst(), and sipdebug.
Referenced by __sip_destroy(), add_sdp(), build_route(), check_via(), do_register_auth(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), handle_request(), process_sdp(), process_sdp_a_audio(), process_sdp_a_video(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendtext(), and transmit_register().
01880 { 01881 if (!sipdebug) 01882 return 0; 01883 return sip_debug_test_addr(sip_real_dst(p)); 01884 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3659 of file chan_sip.c.
References __sip_destroy(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::callid, iflock, LOG_DEBUG, and option_debug.
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().
03660 { 03661 ast_mutex_lock(&iflock); 03662 if (option_debug > 2) 03663 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03664 __sip_destroy(p, 1); 03665 ast_mutex_unlock(&iflock); 03666 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2752 of file chan_sip.c.
References ast_free_ha(), ast_log(), ast_test_flag, ast_variables_destroy(), sip_peer::auth, sip_peer::call, sip_peer::chanvars, clear_realm_authentication(), FALSE, sip_peer::flags, free, sip_peer::ha, LOG_DEBUG, sip_peer::mwipvt, sip_peer::name, option_debug, register_peer_exten(), sip_destroy(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_SELFDESTRUCT, and SIP_REALTIME.
Referenced by __sip_destroy(), _sip_show_peer(), build_peer(), check_user_full(), create_addr(), do_monitor(), expire_register(), function_sippeer(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), realtime_peer(), reg_source_db(), register_verify(), reload_config(), sip_devicestate(), sip_do_debug_peer(), sip_do_reload(), sip_poke_all_peers(), sip_poke_noanswer(), sip_poke_peer(), sip_poke_peer_s(), sip_prune_realtime(), unload_module(), and update_call_counter().
02753 { 02754 if (option_debug > 2) 02755 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02756 02757 /* Delete it, it needs to disappear */ 02758 if (peer->call) 02759 sip_destroy(peer->call); 02760 02761 if (peer->mwipvt) /* We have an active subscription, delete it */ 02762 sip_destroy(peer->mwipvt); 02763 02764 if (peer->chanvars) { 02765 ast_variables_destroy(peer->chanvars); 02766 peer->chanvars = NULL; 02767 } 02768 02769 register_peer_exten(peer, FALSE); 02770 ast_free_ha(peer->ha); 02771 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02772 apeerobjs--; 02773 else if (!ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02774 rpeerobjs--; 02775 else 02776 speerobjs--; 02777 clear_realm_authentication(peer->auth); 02778 peer->auth = NULL; 02779 free(peer); 02780 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2972 of file chan_sip.c.
References ast_free_ha(), ast_log(), ast_test_flag, ast_variables_destroy(), sip_user::chanvars, sip_user::flags, free, sip_user::ha, LOG_DEBUG, sip_user::name, option_debug, SIP_PAGE2_RTCACHEFRIENDS, and SIP_REALTIME.
Referenced by check_user_full(), reload_config(), sip_prune_realtime(), sip_show_user(), unload_module(), and update_call_counter().
02973 { 02974 if (option_debug > 2) 02975 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02976 ast_free_ha(user->ha); 02977 if (user->chanvars) { 02978 ast_variables_destroy(user->chanvars); 02979 user->chanvars = NULL; 02980 } 02981 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && ast_test_flag(&user->flags[0], SIP_REALTIME)) 02982 ruserobjs--; 02983 else 02984 suserobjs--; 02985 free(user); 02986 }
static int sip_devicestate | ( | void * | data | ) | [static] |
Part of PBX channel interface.
If we have qualify on and the device is not reachable, regardless of registration state we return AST_DEVICE_UNAVAILABLE
For peers with call limit:
For peers without call limit:
Peers that does not have a known call and can't be reached by OPTIONS
If we return AST_DEVICE_UNKNOWN, the device state engine will try to find out a state by walking the channel list.
The queue system (app_queue.c) treats a member as "active" if devicestate is != AST_DEVICE_UNAVAILBALE && != AST_DEVICE_INVALID
When placing a call to the queue member, queue system sets a member to busy if != AST_DEVICE_NOT_INUSE and != AST_DEVICE_UNKNOWN
Definition at line 18012 of file chan_sip.c.
References sip_peer::addr, 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_gethostbyname(), ast_log(), ast_strdupa, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::defaddr, find_peer(), hp, sip_peer::inRinging, sip_peer::inUse, sip_peer::lastms, LOG_DEBUG, sip_peer::maxms, sip_peer::onHold, option_debug, and sip_destroy_peer().
18013 { 18014 char *host; 18015 char *tmp; 18016 18017 struct hostent *hp; 18018 struct ast_hostent ahp; 18019 struct sip_peer *p; 18020 18021 int res = AST_DEVICE_INVALID; 18022 18023 /* make sure data is not null. Maybe unnecessary, but better be safe */ 18024 host = ast_strdupa(data ? data : ""); 18025 if ((tmp = strchr(host, '@'))) 18026 host = tmp + 1; 18027 18028 if (option_debug > 2) 18029 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 18030 18031 /* If find_peer asks for a realtime peer, then this breaks rtautoclear. This 18032 * is because when a peer tries to autoexpire, the last thing it does is to 18033 * queue up an event telling the system that the devicestate has changed 18034 * (presumably to unavailable). If we ask for a realtime peer here, this would 18035 * load it BACK into memory, thus defeating the point of trying to trying to 18036 * clear dead hosts out of memory. 18037 */ 18038 if ((p = find_peer(host, NULL, 0, 1))) { 18039 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 18040 /* we have an address for the peer */ 18041 18042 /* Check status in this order 18043 - Hold 18044 - Ringing 18045 - Busy (enforced only by call limit) 18046 - Inuse (we have a call) 18047 - Unreachable (qualify) 18048 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 18049 for registered devices */ 18050 18051 if (p->onHold) 18052 /* First check for hold or ring states */ 18053 res = AST_DEVICE_ONHOLD; 18054 else if (p->inRinging) { 18055 if (p->inRinging == p->inUse) 18056 res = AST_DEVICE_RINGING; 18057 else 18058 res = AST_DEVICE_RINGINUSE; 18059 } else if (p->call_limit && (p->inUse == p->call_limit)) 18060 /* check call limit */ 18061 res = AST_DEVICE_BUSY; 18062 else if (p->call_limit && p->inUse) 18063 /* Not busy, but we do have a call */ 18064 res = AST_DEVICE_INUSE; 18065 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 18066 /* We don't have a call. Are we reachable at all? Requires qualify= */ 18067 res = AST_DEVICE_UNAVAILABLE; 18068 else /* Default reply if we're registered and have no other data */ 18069 res = AST_DEVICE_NOT_INUSE; 18070 } else { 18071 /* there is no address, it's unavailable */ 18072 res = AST_DEVICE_UNAVAILABLE; 18073 } 18074 ASTOBJ_UNREF(p,sip_destroy_peer); 18075 } else { 18076 char *port = strchr(host, ':'); 18077 if (port) 18078 *port = '\0'; 18079 hp = ast_gethostbyname(host, &ahp); 18080 if (hp) 18081 res = AST_DEVICE_UNKNOWN; 18082 } 18083 18084 return res; 18085 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 12703 of file chan_sip.c.
References ast_cli(), ast_set_flag, debugaddr, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.
12704 { 12705 int oldsipdebug = sipdebug_console; 12706 if (argc != 3) { 12707 if (argc != 5) 12708 return RESULT_SHOWUSAGE; 12709 else if (strcmp(argv[3], "ip") == 0) 12710 return sip_do_debug_ip(fd, argc, argv); 12711 else if (strcmp(argv[3], "peer") == 0) 12712 return sip_do_debug_peer(fd, argc, argv); 12713 else 12714 return RESULT_SHOWUSAGE; 12715 } 12716 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12717 memset(&debugaddr, 0, sizeof(debugaddr)); 12718 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 12719 return RESULT_SUCCESS; 12720 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 12722 of file chan_sip.c.
References ast_cli(), ast_set_flag, debugaddr, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.
12723 { 12724 int oldsipdebug = sipdebug_console; 12725 char *newargv[6] = { "sip", "set", "debug", NULL }; 12726 if (argc != 2) { 12727 if (argc != 4) 12728 return RESULT_SHOWUSAGE; 12729 else if (strcmp(argv[2], "ip") == 0) { 12730 newargv[3] = argv[2]; 12731 newargv[4] = argv[3]; 12732 return sip_do_debug_ip(fd, argc + 1, newargv); 12733 } else if (strcmp(argv[2], "peer") == 0) { 12734 newargv[3] = argv[2]; 12735 newargv[4] = argv[3]; 12736 return sip_do_debug_peer(fd, argc + 1, newargv); 12737 } else 12738 return RESULT_SHOWUSAGE; 12739 } 12740 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12741 memset(&debugaddr, 0, sizeof(debugaddr)); 12742 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 12743 return RESULT_SUCCESS; 12744 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 12649 of file chan_sip.c.
References ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), ast_set_flag, debugaddr, hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_PAGE2_DEBUG_CONSOLE, and strsep().
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
12650 { 12651 struct hostent *hp; 12652 struct ast_hostent ahp; 12653 int port = 0; 12654 char *p, *arg; 12655 12656 /* sip set debug ip <ip> */ 12657 if (argc != 5) 12658 return RESULT_SHOWUSAGE; 12659 p = arg = argv[4]; 12660 strsep(&p, ":"); 12661 if (p) 12662 port = atoi(p); 12663 hp = ast_gethostbyname(arg, &ahp); 12664 if (hp == NULL) 12665 return RESULT_SHOWUSAGE; 12666 12667 debugaddr.sin_family = AF_INET; 12668 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 12669 debugaddr.sin_port = htons(port); 12670 if (port == 0) 12671 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 12672 else 12673 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 12674 12675 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12676 12677 return RESULT_SUCCESS; 12678 }
static int sip_do_debug_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_do_debug_peer: Turn on SIP debugging with peer mask
Definition at line 12681 of file chan_sip.c.
References sip_peer::addr, ast_cli(), ast_inet_ntoa(), ast_set_flag, ASTOBJ_UNREF, debugaddr, find_peer(), RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_destroy_peer(), and SIP_PAGE2_DEBUG_CONSOLE.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
12682 { 12683 struct sip_peer *peer; 12684 if (argc != 5) 12685 return RESULT_SHOWUSAGE; 12686 peer = find_peer(argv[4], NULL, 1, 0); 12687 if (peer) { 12688 if (peer->addr.sin_addr.s_addr) { 12689 debugaddr.sin_family = AF_INET; 12690 debugaddr.sin_addr = peer->addr.sin_addr; 12691 debugaddr.sin_port = peer->addr.sin_port; 12692 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 12693 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12694 } else 12695 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 12696 ASTOBJ_UNREF(peer,sip_destroy_peer); 12697 } else 12698 ast_cli(fd, "No such peer '%s'\n", argv[4]); 12699 return RESULT_SUCCESS; 12700 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 12829 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
12830 { 12831 if (argc != 2) { 12832 return RESULT_SHOWUSAGE; 12833 } 12834 recordhistory = TRUE; 12835 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 12836 return RESULT_SUCCESS; 12837 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 20154 of file chan_sip.c.
References ast_log(), AST_SCHED_DEL, ast_test_flag, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, ASTOBJ_UNREF, LOG_DEBUG, option_debug, peerl, reload_config(), sip_destroy_peer(), sip_poke_all_peers(), SIP_REALTIME, and sip_send_all_registers().
Referenced by do_monitor().
20155 { 20156 reload_config(reason); 20157 20158 /* before peers are removed from the peer container, cancel any scheduled pokes */ 20159 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 20160 ASTOBJ_RDLOCK(iterator); 20161 if (ast_test_flag(&iterator->flags[0], SIP_REALTIME)) { 20162 if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) { 20163 struct sip_peer *peer_ptr = iterator; 20164 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 20165 } 20166 } 20167 ASTOBJ_UNLOCK(iterator); 20168 } while (0) ); 20169 20170 /* Prune peers who still are supposed to be deleted */ 20171 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 20172 if (option_debug > 3) 20173 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 20174 20175 /* Send qualify (OPTIONS) to all peers */ 20176 sip_poke_all_peers(); 20177 20178 /* Register with all services */ 20179 sip_send_all_registers(); 20180 20181 if (option_debug > 3) 20182 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 20183 20184 return 0; 20185 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 19953 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_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_setdtmf(), ast_set_flag, ast_test_flag, DSP_FEATURE_DTMF_DETECT, sip_pvt::flags, sip_pvt::jointnoncodeccapability, sip_pvt::lock, LOG_WARNING, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, and sip_pvt::vad.
Referenced by load_module().
19954 { 19955 struct sip_pvt *p; 19956 char *mode; 19957 if (data) 19958 mode = (char *)data; 19959 else { 19960 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 19961 return 0; 19962 } 19963 ast_channel_lock(chan); 19964 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 19965 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 19966 ast_channel_unlock(chan); 19967 return 0; 19968 } 19969 p = chan->tech_pvt; 19970 if (!p) { 19971 ast_channel_unlock(chan); 19972 return 0; 19973 } 19974 ast_mutex_lock(&p->lock); 19975 if (!strcasecmp(mode,"info")) { 19976 ast_clear_flag(&p->flags[0], SIP_DTMF); 19977 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 19978 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 19979 } else if (!strcasecmp(mode,"rfc2833")) { 19980 ast_clear_flag(&p->flags[0], SIP_DTMF); 19981 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 19982 p->jointnoncodeccapability |= AST_RTP_DTMF; 19983 } else if (!strcasecmp(mode,"inband")) { 19984 ast_clear_flag(&p->flags[0], SIP_DTMF); 19985 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 19986 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 19987 } else 19988 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 19989 if (p->rtp) 19990 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 19991 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 19992 if (!p->vad) { 19993 p->vad = ast_dsp_new(); 19994 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 19995 } 19996 } else { 19997 if (p->vad) { 19998 ast_dsp_free(p->vad); 19999 p->vad = NULL; 20000 } 20001 } 20002 ast_mutex_unlock(&p->lock); 20003 ast_channel_unlock(chan); 20004 return 0; 20005 }
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 12507 of file chan_sip.c.
References AST_LIST_TRAVERSE, ast_log(), sip_pvt::callid, sip_history::event, sip_pvt::history, LOG_DEBUG, LOG_NOTICE, option_debug, sipdebug, and sip_pvt::subscribed.
Referenced by __sip_destroy().
12508 { 12509 int x = 0; 12510 struct sip_history *hist; 12511 static int errmsg = 0; 12512 12513 if (!dialog) 12514 return; 12515 12516 if (!option_debug && !sipdebug) { 12517 if (!errmsg) { 12518 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 12519 errmsg = 1; 12520 } 12521 return; 12522 } 12523 12524 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 12525 if (dialog->subscribed) 12526 ast_log(LOG_DEBUG, " * Subscription\n"); 12527 else 12528 ast_log(LOG_DEBUG, " * SIP Call\n"); 12529 if (dialog->history) 12530 AST_LIST_TRAVERSE(dialog->history, hist, list) 12531 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 12532 if (!x) 12533 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 12534 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 12535 }
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 4139 of file chan_sip.c.
References append_history, AST_FLAG_ZOMBIE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::callid, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, option_debug, sip_pvt::owner, sip_set_rtp_peer(), and ast_channel::tech_pvt.
04140 { 04141 int ret = -1; 04142 struct sip_pvt *p; 04143 04144 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 04145 ast_log(LOG_DEBUG, "New channel is zombie\n"); 04146 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 04147 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 04148 04149 if (!newchan || !newchan->tech_pvt) { 04150 if (!newchan) 04151 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 04152 else 04153 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 04154 return -1; 04155 } 04156 p = newchan->tech_pvt; 04157 04158 if (!p) { 04159 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 04160 return -1; 04161 } 04162 04163 ast_mutex_lock(&p->lock); 04164 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 04165 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 04166 if (p->owner != oldchan) 04167 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 04168 else { 04169 p->owner = newchan; 04170 /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native 04171 RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be 04172 able to do this if the masquerade happens before the bridge breaks (e.g., AMI 04173 redirect of both channels). Note that a channel can not be masqueraded *into* 04174 a native bridge. So there is no danger that this breaks a native bridge that 04175 should stay up. */ 04176 sip_set_rtp_peer(newchan, NULL, NULL, 0, 0); 04177 ret = 0; 04178 } 04179 if (option_debug > 2) 04180 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 04181 04182 ast_mutex_unlock(&p->lock); 04183 return ret; 04184 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 20098 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::jointcapability, and ast_channel::tech_pvt.
20099 { 20100 struct sip_pvt *p = chan->tech_pvt; 20101 return p->jointcapability ? p->jointcapability : p->capability; 20102 }
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 19809 of file chan_sip.c.
References AST_JB_FORCED, ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_GET_FAILED, ast_rtp_getnat(), AST_RTP_TRY_NATIVE, AST_RTP_TRY_PARTIAL, ast_test_flag, sip_pvt::flags, global_jbconf, sip_pvt::lock, sip_pvt::rtp, SIP_CAN_REINVITE, SIP_CAN_REINVITE_NAT, and ast_channel::tech_pvt.
19810 { 19811 struct sip_pvt *p = NULL; 19812 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 19813 19814 if (!(p = chan->tech_pvt)) 19815 return AST_RTP_GET_FAILED; 19816 19817 ast_mutex_lock(&p->lock); 19818 if (!(p->rtp)) { 19819 ast_mutex_unlock(&p->lock); 19820 return AST_RTP_GET_FAILED; 19821 } 19822 19823 *rtp = p->rtp; 19824 19825 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 19826 res = AST_RTP_TRY_PARTIAL; 19827 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 19828 res = AST_RTP_TRY_NATIVE; 19829 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 19830 res = AST_RTP_GET_FAILED; 19831 19832 ast_mutex_unlock(&p->lock); 19833 19834 return res; 19835 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static, read] |
Definition at line 19661 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::flags, sip_pvt::lock, SIP_CAN_REINVITE, ast_channel::tech_pvt, and sip_pvt::udptl.
19662 { 19663 struct sip_pvt *p; 19664 struct ast_udptl *udptl = NULL; 19665 19666 p = chan->tech_pvt; 19667 if (!p) 19668 return NULL; 19669 19670 ast_mutex_lock(&p->lock); 19671 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 19672 udptl = p->udptl; 19673 ast_mutex_unlock(&p->lock); 19674 return udptl; 19675 }
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 19838 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_GET_FAILED, AST_RTP_TRY_NATIVE, AST_RTP_TRY_PARTIAL, ast_test_flag, sip_pvt::flags, sip_pvt::lock, SIP_CAN_REINVITE, ast_channel::tech_pvt, and sip_pvt::vrtp.
19839 { 19840 struct sip_pvt *p = NULL; 19841 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 19842 19843 if (!(p = chan->tech_pvt)) 19844 return AST_RTP_GET_FAILED; 19845 19846 ast_mutex_lock(&p->lock); 19847 if (!(p->vrtp)) { 19848 ast_mutex_unlock(&p->lock); 19849 return AST_RTP_GET_FAILED; 19850 } 19851 19852 *rtp = p->vrtp; 19853 19854 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 19855 res = AST_RTP_TRY_NATIVE; 19856 19857 ast_mutex_unlock(&p->lock); 19858 19859 return res; 19860 }
static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
struct sip_pvt * | pvt, | |||
int | reinvite | |||
) | [static] |
Handle T38 reinvite.
T38 negotiation helper function
Definition at line 19713 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_get_local_max_datagram(), ast_udptl_get_peer(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), sip_pvt::callid, sip_pvt::flags, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, option_debug, sip_pvt::ourip, sip_pvt::owner, t38properties::peercapability, sip_pvt::pendinginvite, SIP_CAN_REINVITE, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), transmit_response_reliable(), transmit_response_with_t38_sdp(), sip_pvt::udptl, sip_pvt::udptlredirip, and XMIT_CRITICAL.
Referenced by handle_request_invite(), and handle_response_invite().
19714 { 19715 struct sip_pvt *p; 19716 int flag = 0; 19717 19718 p = chan->tech_pvt; 19719 if (!p || !pvt->udptl) 19720 return -1; 19721 19722 /* Setup everything on the other side like offered/responded from first side */ 19723 ast_mutex_lock(&p->lock); 19724 19725 /*! \todo check if this is not set earlier when setting up the PVT. If not 19726 maybe it should move there. */ 19727 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 19728 19729 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 19730 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 19731 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 19732 19733 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 19734 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 19735 not really T38 re-invites which are different. In this 19736 case it's used properly, to see if we can reinvite over 19737 NAT 19738 */ 19739 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 19740 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 19741 flag =1; 19742 } else { 19743 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 19744 } 19745 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 19746 if (!p->pendinginvite) { 19747 if (option_debug > 2) { 19748 if (flag) 19749 ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port)); 19750 else 19751 ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip)); 19752 } 19753 transmit_reinvite_with_t38_sdp(p); 19754 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 19755 if (option_debug > 2) { 19756 if (flag) 19757 ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port)); 19758 else 19759 ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip)); 19760 } 19761 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 19762 } 19763 } 19764 /* Reset lastrtprx timer */ 19765 p->lastrtprx = p->lastrtptx = time(NULL); 19766 ast_mutex_unlock(&p->lock); 19767 return 0; 19768 } else if (pvt->t38.state != T38_DISABLED) { /* If we are handling sending 200 OK to the other side of the bridge */ 19769 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 19770 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 19771 flag = 1; 19772 } else { 19773 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 19774 } 19775 if (option_debug > 2) { 19776 if (flag) 19777 ast_log(LOG_DEBUG, "Responding 200 OK on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port)); 19778 else 19779 ast_log(LOG_DEBUG, "Responding 200 OK on SIP '%s' - It's UDPTL soon redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip)); 19780 } 19781 pvt->t38.state = T38_ENABLED; 19782 p->t38.state = T38_ENABLED; 19783 if (option_debug > 1) { 19784 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 19785 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 19786 } 19787 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 19788 p->lastrtprx = p->lastrtptx = time(NULL); 19789 ast_mutex_unlock(&p->lock); 19790 return 0; 19791 } else if (pvt->t38.state == T38_DISABLED) { /* The other side can not talk T.38 with us. We tell it to the the originating T.38 party with a 488 */ 19792 p->t38.state = T38_DISABLED; 19793 if (option_debug > 1) { 19794 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 19795 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 19796 } 19797 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 19798 p->lastrtprx = p->lastrtptx = time(NULL); 19799 ast_mutex_unlock(&p->lock); 19800 return 0; 19801 } else { 19802 ast_log(LOG_ERROR, "Something went wrong with T.38. State is:%d on channel %s and %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>", p->t38.state, chan ? chan->name : "<none>"); 19803 ast_mutex_unlock(&p->lock); 19804 return 0; 19805 } 19806 }
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 3832 of file chan_sip.c.
References __sip_semi_ack(), ast_channel::_state, append_history, ast_cause2str(), ast_clear_flag, ast_dsp_free(), AST_FLAG_ZOMBIE, ast_log(), ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_quality(), AST_SCHED_DEL, ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, sip_pvt::autokillid, sip_pvt::callid, sip_pkt::data, sip_request::data, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, find_sip_method(), FLAG_RESPONSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, sip_pvt::hangupcause, sip_pvt::initreq, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lastinvite, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, sip_pkt::method, sip_pkt::next, option_debug, sip_pvt::owner, sip_pvt::packets, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_pvt::refer, remove_provisional_keepalive_sched(), sip_pvt::rtp, sip_pkt::seqno, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_DEFER_BYE_ON_TRANSFER, SIP_INC_COUNT, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_CALL_ONHOLD, SIP_PENDINGBYE, sip_scheddestroy(), sipdebug, stop_media_flows(), ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, update_call_counter(), sip_pvt::username, sip_pvt::vad, sip_pvt::vrtp, sip_pvt::waitid, and XMIT_RELIABLE.
03833 { 03834 struct sip_pvt *p = ast->tech_pvt; 03835 int needcancel = FALSE; 03836 int needdestroy = 0; 03837 struct ast_channel *oldowner = ast; 03838 03839 if (!p) { 03840 if (option_debug) 03841 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03842 return 0; 03843 } 03844 03845 /* Store hangupcause locally in PVT so we still have it before disconnect */ 03846 if (p->owner) 03847 p->hangupcause = p->owner->hangupcause; 03848 03849 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03850 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03851 if (option_debug && sipdebug) 03852 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03853 update_call_counter(p, DEC_CALL_LIMIT); 03854 } 03855 if (option_debug >3) 03856 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03857 if (p->autokillid > -1 && sip_cancel_destroy(p)) 03858 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03859 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03860 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03861 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03862 p->owner->tech_pvt = NULL; 03863 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03864 ast_module_unref(ast_module_info->self); 03865 return 0; 03866 } 03867 if (option_debug) { 03868 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03869 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03870 else { 03871 if (option_debug) 03872 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03873 } 03874 } 03875 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03876 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03877 03878 ast_mutex_lock(&p->lock); 03879 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03880 if (option_debug && sipdebug) 03881 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03882 update_call_counter(p, DEC_CALL_LIMIT); 03883 } 03884 03885 /* Determine how to disconnect */ 03886 if (p->owner != ast) { 03887 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03888 ast_mutex_unlock(&p->lock); 03889 return 0; 03890 } 03891 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03892 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03893 needcancel = TRUE; 03894 if (option_debug > 3) 03895 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03896 } 03897 03898 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 03899 03900 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->hangupcause) : "Unknown"); 03901 03902 /* Disconnect */ 03903 if (p->vad) 03904 ast_dsp_free(p->vad); 03905 03906 p->owner = NULL; 03907 ast->tech_pvt = NULL; 03908 03909 ast_module_unref(ast_module_info->self); 03910 03911 /* Do not destroy this pvt until we have timeout or 03912 get an answer to the BYE or INVITE/CANCEL 03913 If we get no answer during retransmit period, drop the call anyway. 03914 (Sorry, mother-in-law, you can't deny a hangup by sending 03915 603 declined to BYE...) 03916 */ 03917 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03918 needdestroy = 1; /* Set destroy flag at end of this function */ 03919 else if (p->invitestate != INV_CALLING) 03920 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03921 03922 /* Start the process if it's not already started */ 03923 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03924 if (needcancel) { /* Outgoing call, not up */ 03925 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03926 /* stop retransmitting an INVITE that has not received a response */ 03927 struct sip_pkt *cur; 03928 03929 /* if we can't send right now, mark it pending */ 03930 if (p->invitestate == INV_CALLING) { 03931 /* We can't send anything in CALLING state */ 03932 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03933 /* Do we need a timer here if we don't hear from them at all? Yes we do or else we will get hung dialogs and those are no fun. */ 03934 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03935 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 03936 } else { 03937 for (cur = p->packets; cur; cur = cur->next) { 03938 __sip_semi_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), cur->method ? cur->method : find_sip_method(cur->data)); 03939 } 03940 p->invitestate = INV_CANCELLED; 03941 /* Send a new request: CANCEL */ 03942 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 03943 /* Actually don't destroy us yet, wait for the 487 on our original 03944 INVITE, but do set an autodestruct just in case we never get it. */ 03945 needdestroy = 0; 03946 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03947 } 03948 } else { /* Incoming call, not up */ 03949 const char *res; 03950 remove_provisional_keepalive_sched(p); 03951 if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause))) 03952 transmit_response_reliable(p, res, &p->initreq); 03953 else 03954 transmit_response_reliable(p, "603 Declined", &p->initreq); 03955 p->invitestate = INV_TERMINATED; 03956 } 03957 } else { /* Call is in UP state, send BYE */ 03958 if (!p->pendinginvite) { 03959 char *audioqos = ""; 03960 char *videoqos = ""; 03961 if (p->rtp) 03962 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03963 if (p->vrtp) 03964 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03965 /* Send a hangup */ 03966 if (oldowner->_state == AST_STATE_UP) { 03967 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03968 } 03969 03970 /* Get RTCP quality before end of call */ 03971 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03972 if (p->rtp) 03973 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03974 if (p->vrtp) 03975 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03976 } 03977 if (p->rtp && oldowner) 03978 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03979 if (p->vrtp && oldowner) 03980 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03981 } else { 03982 /* Note we will need a BYE when this all settles out 03983 but we can't send one while we have "INVITE" outstanding. */ 03984 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03985 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03986 AST_SCHED_DEL(sched, p->waitid); 03987 if (sip_cancel_destroy(p)) 03988 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03989 } 03990 } 03991 } 03992 if (needdestroy) 03993 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03994 ast_mutex_unlock(&p->lock); 03995 return 0; 03996 }
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 4255 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_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_change_source(), ast_rtp_new_source(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, sip_pvt::flags, sip_pvt::initreq, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::lock, LOG_WARNING, sip_pvt::mohinterpret, sip_pvt::rtp, sip_alreadygone(), SIP_NOVIDEO, SIP_OUTGOING, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_YES, SIP_PROGRESS_SENT, SIP_RINGING, ast_channel::tech_pvt, transmit_info_with_vidupdate(), transmit_provisional_response(), transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp.
04256 { 04257 struct sip_pvt *p = ast->tech_pvt; 04258 int res = 0; 04259 04260 ast_mutex_lock(&p->lock); 04261 switch(condition) { 04262 case AST_CONTROL_RINGING: 04263 if (ast->_state == AST_STATE_RING) { 04264 p->invitestate = INV_EARLY_MEDIA; 04265 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 04266 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 04267 /* Send 180 ringing if out-of-band seems reasonable */ 04268 transmit_provisional_response(p, "180 Ringing", &p->initreq, 0); 04269 ast_set_flag(&p->flags[0], SIP_RINGING); 04270 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 04271 break; 04272 } else { 04273 /* Well, if it's not reasonable, just send in-band */ 04274 } 04275 } 04276 res = -1; 04277 break; 04278 case AST_CONTROL_BUSY: 04279 if (ast->_state != AST_STATE_UP) { 04280 transmit_response_reliable(p, "486 Busy Here", &p->initreq); 04281 p->invitestate = INV_COMPLETED; 04282 sip_alreadygone(p); 04283 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 04284 break; 04285 } 04286 res = -1; 04287 break; 04288 case AST_CONTROL_CONGESTION: 04289 if (ast->_state != AST_STATE_UP) { 04290 transmit_response_reliable(p, "503 Service Unavailable", &p->initreq); 04291 p->invitestate = INV_COMPLETED; 04292 sip_alreadygone(p); 04293 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 04294 break; 04295 } 04296 res = -1; 04297 break; 04298 case AST_CONTROL_PROCEEDING: 04299 if ((ast->_state != AST_STATE_UP) && 04300 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04301 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04302 transmit_response(p, "100 Trying", &p->initreq); 04303 p->invitestate = INV_PROCEEDING; 04304 break; 04305 } 04306 res = -1; 04307 break; 04308 case AST_CONTROL_PROGRESS: 04309 if ((ast->_state != AST_STATE_UP) && 04310 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04311 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04312 p->invitestate = INV_EARLY_MEDIA; 04313 transmit_provisional_response(p, "183 Session Progress", &p->initreq, 1); 04314 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 04315 break; 04316 } 04317 res = -1; 04318 break; 04319 case AST_CONTROL_HOLD: 04320 ast_rtp_new_source(p->rtp); 04321 ast_moh_start(ast, data, p->mohinterpret); 04322 break; 04323 case AST_CONTROL_UNHOLD: 04324 ast_rtp_new_source(p->rtp); 04325 ast_moh_stop(ast); 04326 break; 04327 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 04328 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 04329 transmit_info_with_vidupdate(p); 04330 /* ast_rtcp_send_h261fur(p->vrtp); */ 04331 } else 04332 res = -1; 04333 break; 04334 case AST_CONTROL_SRCUPDATE: 04335 ast_rtp_new_source(p->rtp); 04336 break; 04337 case AST_CONTROL_SRCCHANGE: 04338 ast_rtp_change_source(p->rtp); 04339 break; 04340 case -1: 04341 res = -1; 04342 break; 04343 default: 04344 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 04345 res = -1; 04346 break; 04347 } 04348 ast_mutex_unlock(&p->lock); 04349 return res; 04350 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1873 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().
01874 { 01875 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01876 }
static struct ast_channel* sip_new | ( | struct sip_pvt * | i, | |
int | state, | |||
const char * | title | |||
) | [static, read] |
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 4358 of file chan_sip.c.
References accountcode, sip_pvt::accountcode, ast_channel::adsicpe, ast_channel::amaflags, sip_pvt::amaflags, append_history, AST_ADSI_UNAVAILABLE, ast_atomic_fetchadd_int(), ast_best_codec(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_codec_choose(), ast_copy_string(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), ast_exists_extension(), AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), 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(), ast_verbose(), 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, sip_pvt::domain, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, sip_pvt::exten, f, ast_channel::fds, sip_pvt::flags, sip_pvt::from, sip_pvt::fromdomain, sip_pvt::fromname, sip_pvt::fromuser, sip_pvt::fullcontact, global_jbconf, ast_channel::hangupcause, sip_pvt::jointcapability, language, sip_pvt::language, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::peername, 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_NO_HISTORY, sip_tech, sip_tech_info, SIPBUFSIZE, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::udptl, sip_pvt::uri, sip_pvt::useragent, sip_pvt::username, sip_pvt::vad, ast_variable::value, VERBOSE_PREFIX_3, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by handle_request_invite(), and sip_request_call().
04359 { 04360 struct ast_channel *tmp; 04361 struct ast_variable *v = NULL; 04362 int fmt; 04363 int what; 04364 int needvideo = 0, video = 0; 04365 char *decoded_exten; 04366 04367 if (option_debug != 0) { 04368 ast_verbose(VERBOSE_PREFIX_3 "NEW SIP CHANNEL, title: <%s>\n", title?title:"Null"); 04369 ast_verbose(VERBOSE_PREFIX_3 "from: %s\n", i->from); 04370 ast_verbose(VERBOSE_PREFIX_3 "username: <%s>\n", i->username); 04371 ast_verbose(VERBOSE_PREFIX_3 "peername: <%s>\n", i->peername); 04372 ast_verbose(VERBOSE_PREFIX_3 "fromdomain: %s\n", i->fromdomain); 04373 ast_verbose(VERBOSE_PREFIX_3 "fromuser: %s\n", i->fromuser); 04374 ast_verbose(VERBOSE_PREFIX_3 "fromname: %s\n", i->fromname); 04375 ast_verbose(VERBOSE_PREFIX_3 "fullcontact: %s\n", i->fullcontact); 04376 } 04377 04378 { 04379 char my_name[128]; /* pick a good name */ 04380 const char *f, *fromdomain = NULL; 04381 04382 if (!ast_strlen_zero(i->fromdomain) && strchr(i->fromdomain,':')) 04383 fromdomain = strchr(i->fromdomain,':') + 1; /* skip ':' */ 04384 else 04385 fromdomain = i->fromdomain; 04386 04387 if (!ast_strlen_zero(i->username)) { 04388 if (!ast_strlen_zero(title) && strcmp(i->username, title)) { 04389 /* title not empty and different from username */ 04390 snprintf(my_name, sizeof(my_name), "%s@%s", i->username, title); 04391 } else { 04392 /* username not empty, title is empty or equal to username */ 04393 snprintf(my_name, sizeof(my_name), "%s", i->username); 04394 } 04395 } else { /* username empty */ 04396 if (!ast_strlen_zero(i->peername)) { 04397 /* call from unregisted peer */ 04398 snprintf(my_name, sizeof(my_name), "%s", i->peername); 04399 } else { /* username and peername empty */ 04400 if (!ast_strlen_zero(title)) { /* title not empty */ 04401 snprintf(my_name, sizeof(my_name), "%s", title); 04402 } else if (!ast_strlen_zero(i->from)) { /* title empty, From: not empty */ 04403 f = i->from; 04404 if (!strncmp(f, "sip:", 4)) 04405 f += 4; 04406 snprintf(my_name, sizeof(my_name), "%s", f); 04407 } else { /* fallback to fromdomain */ 04408 snprintf(my_name, sizeof(my_name), "%s", fromdomain); 04409 } 04410 } 04411 } 04412 ast_mutex_unlock(&i->lock); 04413 /* Don't hold a sip pvt lock while we allocate a channel */ 04414 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, ast_atomic_fetchadd_int((int *)&chan_idx, +1)); 04415 04416 } 04417 if (!tmp) { 04418 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 04419 ast_mutex_lock(&i->lock); 04420 return NULL; 04421 } 04422 ast_mutex_lock(&i->lock); 04423 04424 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 04425 tmp->tech = &sip_tech_info; 04426 else 04427 tmp->tech = &sip_tech; 04428 04429 /* Select our native format based on codec preference until we receive 04430 something from another device to the contrary. */ 04431 if (i->jointcapability) { /* The joint capabilities of us and peer */ 04432 what = i->jointcapability; 04433 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 04434 } else if (i->capability) { /* Our configured capability for this peer */ 04435 what = i->capability; 04436 video = i->capability & AST_FORMAT_VIDEO_MASK; 04437 } else { 04438 what = global_capability; /* Global codec support */ 04439 video = global_capability & AST_FORMAT_VIDEO_MASK; 04440 } 04441 04442 /* Set the native formats for audio and merge in video */ 04443 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video; 04444 if (option_debug > 2) { 04445 char buf[SIPBUFSIZE]; 04446 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 04447 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 04448 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 04449 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 04450 if (i->prefcodec) 04451 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 04452 } 04453 04454 /* XXX Why are we choosing a codec from the native formats?? */ 04455 fmt = ast_best_codec(tmp->nativeformats); 04456 04457 /* If we have a prefcodec setting, we have an inbound channel that set a 04458 preferred format for this call. Otherwise, we check the jointcapability 04459 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 04460 */ 04461 if (i->vrtp) { 04462 if (i->prefcodec) 04463 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 04464 else 04465 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 04466 } 04467 04468 if (option_debug > 2) { 04469 if (needvideo) 04470 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 04471 else 04472 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 04473 } 04474 04475 04476 04477 if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 04478 i->vad = ast_dsp_new(); 04479 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 04480 if (global_relaxdtmf) 04481 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04482 } 04483 if (i->rtp) { 04484 tmp->fds[0] = ast_rtp_fd(i->rtp); 04485 tmp->fds[1] = ast_rtcp_fd(i->rtp); 04486 } 04487 if (needvideo && i->vrtp) { 04488 tmp->fds[2] = ast_rtp_fd(i->vrtp); 04489 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 04490 } 04491 if (i->udptl) { 04492 tmp->fds[5] = ast_udptl_fd(i->udptl); 04493 } 04494 if (state == AST_STATE_RING) 04495 tmp->rings = 1; 04496 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04497 tmp->writeformat = fmt; 04498 tmp->rawwriteformat = fmt; 04499 tmp->readformat = fmt; 04500 tmp->rawreadformat = fmt; 04501 tmp->tech_pvt = i; 04502 04503 memcpy(&tmp->callgroup, i->callgroup, sizeof(tmp->callgroup)); 04504 memcpy(&tmp->pickupgroup, i->pickupgroup, sizeof(tmp->pickupgroup)); 04505 tmp->cid.cid_pres = i->callingpres; 04506 if (!ast_strlen_zero(i->accountcode)) 04507 ast_string_field_set(tmp, accountcode, i->accountcode); 04508 if (i->amaflags) 04509 tmp->amaflags = i->amaflags; 04510 if (!ast_strlen_zero(i->language)) 04511 ast_string_field_set(tmp, language, i->language); 04512 i->owner = tmp; 04513 ast_module_ref(ast_module_info->self); 04514 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04515 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 04516 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 04517 * structure so that there aren't issues when forming URI's 04518 */ 04519 if (ast_exists_extension(NULL, i->context, i->exten, 1, i->cid_num)) { 04520 /* encoded in dialplan, so keep extension encoded */ 04521 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 04522 } else { 04523 decoded_exten = ast_strdupa(i->exten); 04524 ast_uri_decode(decoded_exten); 04525 ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten)); 04526 } 04527 04528 /* Don't use ast_set_callerid() here because it will 04529 * generate an unnecessary NewCallerID event */ 04530 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04531 if (!ast_strlen_zero(i->rdnis)) 04532 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04533 04534 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 04535 tmp->cid.cid_dnid = ast_strdup(i->exten); 04536 04537 tmp->priority = 1; 04538 if (!ast_strlen_zero(i->uri)) 04539 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 04540 if (!ast_strlen_zero(i->domain)) 04541 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 04542 if (!ast_strlen_zero(i->useragent)) 04543 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 04544 if (!ast_strlen_zero(i->callid)) 04545 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 04546 if (i->rtp) 04547 ast_jb_configure(tmp, &global_jbconf); 04548 04549 /* Set channel variables for this call from configuration */ 04550 for (v = i->chanvars ; v ; v = v->next) 04551 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04552 04553 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 04554 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04555 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04556 ast_hangup(tmp); 04557 tmp = NULL; 04558 } 04559 04560 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 04561 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 04562 04563 return tmp; 04564 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 12810 of file chan_sip.c.
References ast_clear_flag, ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
12811 { 12812 if (argc != 4) 12813 return RESULT_SHOWUSAGE; 12814 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12815 ast_cli(fd, "SIP Debugging Disabled\n"); 12816 return RESULT_SUCCESS; 12817 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 12819 of file chan_sip.c.
References ast_clear_flag, ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
12820 { 12821 if (argc != 3) 12822 return RESULT_SHOWUSAGE; 12823 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12824 ast_cli(fd, "SIP Debugging Disabled\n"); 12825 return RESULT_SUCCESS; 12826 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 12840 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
12841 { 12842 if (argc != 3) { 12843 return RESULT_SHOWUSAGE; 12844 } 12845 recordhistory = FALSE; 12846 ast_cli(fd, "SIP History Recording Disabled\n"); 12847 return RESULT_SUCCESS; 12848 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 12747 of file chan_sip.c.
References __ourip, add_header(), ast_cli(), ast_log(), ast_sip_ouraddrfor(), ast_unescape_semicolon(), ast_variable_browse(), build_callid_pvt(), build_via(), create_addr(), DEFAULT_TRANS_TIMEOUT, initreqprep(), LOG_DEBUG, LOG_WARNING, ast_variable::name, ast_variable::next, notify_types, option_debug, sip_pvt::ourip, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), ast_variable::value, and var.
12748 { 12749 struct ast_variable *varlist; 12750 int i; 12751 12752 if (argc < 4) 12753 return RESULT_SHOWUSAGE; 12754 12755 if (!notify_types) { 12756 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 12757 return RESULT_FAILURE; 12758 } 12759 12760 varlist = ast_variable_browse(notify_types, argv[2]); 12761 12762 if (!varlist) { 12763 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 12764 return RESULT_FAILURE; 12765 } 12766 12767 for (i = 3; i < argc; i++) { 12768 struct sip_pvt *p; 12769 struct sip_request req; 12770 struct ast_variable *var; 12771 12772 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 12773 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 12774 return RESULT_FAILURE; 12775 } 12776 12777 if (create_addr(p, argv[i], NULL)) { 12778 /* Maybe they're not registered, etc. */ 12779 sip_destroy(p); 12780 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 12781 continue; 12782 } 12783 12784 initreqprep(&req, p, SIP_NOTIFY); 12785 12786 for (var = varlist; var; var = var->next) { 12787 if (!strcasecmp(var->name, "Content-Length")) { 12788 if (option_debug >= 2) { 12789 ast_log(LOG_DEBUG, "Ignoring pair %s=%s\n", var->name, var->value); 12790 } 12791 continue; /* ignore content-length, it is calculated automatically */ 12792 } 12793 add_header(&req, var->name, ast_unescape_semicolon(var->value)); 12794 } 12795 12796 /* Recalculate our side, and recalculate Call ID */ 12797 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 12798 p->ourip = __ourip; 12799 build_via(p); 12800 build_callid_pvt(p); 12801 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 12802 transmit_sip_request(p, &req); 12803 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12804 } 12805 12806 return RESULT_SUCCESS; 12807 }
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 14650 of file chan_sip.c.
References 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_do_masquerade(), ast_free, ast_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, sip_dual::chan1, sip_dual::chan2, ast_channel::context, copy_request(), DEADLOCK_AVOIDANCE, ast_channel::exten, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, option_debug, ast_channel::priority, ast_channel::readformat, sip_dual::req, sip_dual::seqno, sip_park_thread(), ast_channel::tech_pvt, and ast_channel::writeformat.
Referenced by handle_request_refer().
14651 { 14652 struct sip_dual *d; 14653 struct ast_channel *transferee, *transferer; 14654 /* Chan2m: The transferer, chan1m: The transferee */ 14655 pthread_t th; 14656 pthread_attr_t attr; 14657 14658 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 14659 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 14660 if ((!transferer) || (!transferee)) { 14661 if (transferee) { 14662 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 14663 ast_hangup(transferee); 14664 } 14665 if (transferer) { 14666 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 14667 ast_hangup(transferer); 14668 } 14669 return -1; 14670 } 14671 14672 /* Make formats okay */ 14673 transferee->readformat = chan1->readformat; 14674 transferee->writeformat = chan1->writeformat; 14675 14676 /* Prepare for taking over the channel */ 14677 ast_channel_masquerade(transferee, chan1); 14678 14679 /* Setup the extensions and such */ 14680 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 14681 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 14682 transferee->priority = chan1->priority; 14683 14684 /* We make a clone of the peer channel too, so we can play 14685 back the announcement */ 14686 14687 /* Make formats okay */ 14688 transferer->readformat = chan2->readformat; 14689 transferer->writeformat = chan2->writeformat; 14690 14691 /* Prepare for taking over the channel. Go ahead and grab this channel 14692 * lock here to avoid a deadlock with callbacks into the channel driver 14693 * that hold the channel lock and want the pvt lock. */ 14694 while (ast_channel_trylock(chan2)) { 14695 struct sip_pvt *pvt = chan2->tech_pvt; 14696 DEADLOCK_AVOIDANCE(&pvt->lock); 14697 } 14698 ast_channel_masquerade(transferer, chan2); 14699 ast_channel_unlock(chan2); 14700 14701 /* Setup the extensions and such */ 14702 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 14703 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 14704 transferer->priority = chan2->priority; 14705 14706 ast_channel_lock(transferer); 14707 if (ast_do_masquerade(transferer)) { 14708 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 14709 ast_channel_unlock(transferer); 14710 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 14711 ast_hangup(transferer); 14712 return -1; 14713 } 14714 ast_channel_unlock(transferer); 14715 if (!transferer || !transferee) { 14716 if (!transferer) { 14717 if (option_debug) 14718 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 14719 } 14720 if (!transferee) { 14721 if (option_debug) 14722 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 14723 } 14724 return -1; 14725 } 14726 if (!(d = ast_calloc(1, sizeof(*d)))) { 14727 return -1; 14728 } 14729 14730 pthread_attr_init(&attr); 14731 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 14732 14733 /* Save original request for followup */ 14734 copy_request(&d->req, req); 14735 d->chan1 = transferee; /* Transferee */ 14736 d->chan2 = transferer; /* Transferer */ 14737 d->seqno = seqno; 14738 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 14739 /* Could not start thread */ 14740 ast_free(d); /* We don't need it anymore. If thread is created, d will be free'd 14741 by sip_park_thread() */ 14742 pthread_attr_destroy(&attr); 14743 return -1; 14744 } 14745 pthread_attr_destroy(&attr); 14746 14747 return 0; 14748 }
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 14582 of file chan_sip.c.
References append_history, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_do_masquerade(), ast_free, ast_hangup(), ast_log(), ast_park_call(), sip_dual::chan1, sip_dual::chan2, copy_request(), ext, ast_channel::hangupcause, LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, 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().
14583 { 14584 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 14585 struct sip_dual *d; 14586 struct sip_request req; 14587 int ext; 14588 int res; 14589 14590 d = stuff; 14591 transferee = d->chan1; 14592 transferer = d->chan2; 14593 copy_request(&req, &d->req); 14594 14595 if (!transferee || !transferer) { 14596 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 14597 ast_free(d); 14598 return NULL; 14599 } 14600 if (option_debug > 3) 14601 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 14602 14603 ast_channel_lock(transferee); 14604 if (ast_do_masquerade(transferee)) { 14605 ast_log(LOG_WARNING, "Masquerade failed.\n"); 14606 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 14607 ast_channel_unlock(transferee); 14608 ast_free(d); 14609 return NULL; 14610 } 14611 ast_channel_unlock(transferee); 14612 14613 res = ast_park_call(transferee, transferer, 0, &ext); 14614 14615 14616 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 14617 if (!res) { 14618 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 14619 } else { 14620 /* Then tell the transferer what happened */ 14621 sprintf(buf, "Call parked on extension '%d'", ext); 14622 transmit_message_with_text(transferer->tech_pvt, buf); 14623 } 14624 #endif 14625 14626 /* Any way back to the current call??? */ 14627 /* Transmit response to the REFER request */ 14628 if (!res) { 14629 /* Transfer succeeded */ 14630 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 14631 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 14632 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14633 ast_hangup(transferer); /* This will cause a BYE */ 14634 if (option_debug) 14635 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 14636 } else { 14637 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 14638 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 14639 if (option_debug) 14640 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 14641 /* Do not hangup call */ 14642 } 14643 ast_free(d); 14644 return NULL; 14645 }
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 9582 of file chan_sip.c.
References ast_device_state_changed(), find_peer(), sip_peer::name, sip_peer::onHold, and sip_pvt::peername.
Referenced by change_hold_state(), and update_call_counter().
09583 { 09584 struct sip_peer *peer = find_peer(p->peername, NULL, 1, 0); 09585 09586 if (!peer) 09587 return; 09588 09589 /* If they put someone on hold, increment the value... otherwise decrement it */ 09590 if (hold) 09591 peer->onHold++; 09592 else 09593 peer->onHold--; 09594 09595 /* Request device state update */ 09596 ast_device_state_changed("SIP/%s", peer->name); 09597 09598 return; 09599 }
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 20108 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, peerl, sip_destroy_peer(), and sip_poke_peer_s().
Referenced by load_module(), and sip_do_reload().
20109 { 20110 int ms = 0; 20111 20112 if (!speerobjs) /* No peers, just give up */ 20113 return; 20114 20115 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 20116 ASTOBJ_WRLOCK(iterator); 20117 if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) { 20118 struct sip_peer *peer_ptr = iterator; 20119 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 20120 } 20121 ms += 100; 20122 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator)); 20123 if (iterator->pokeexpire == -1) { 20124 struct sip_peer *peer_ptr = iterator; 20125 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 20126 } 20127 ASTOBJ_UNLOCK(iterator); 20128 } while (0) 20129 ); 20130 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 17863 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ast_update_realtime(), ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::name, sip_peer::pokeexpire, sip_destroy(), sip_destroy_peer(), SIP_PAGE2_RTUPDATE, and sip_poke_peer_s().
Referenced by sip_poke_peer().
17864 { 17865 struct sip_peer *peer = (struct sip_peer *)data; 17866 17867 peer->pokeexpire = -1; 17868 if (peer->lastms > -1) { 17869 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 17870 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) { 17871 ast_update_realtime("sippeers", "name", peer->name, "lastms", "-1", NULL); 17872 } 17873 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 17874 } 17875 if (peer->call) 17876 sip_destroy(peer->call); 17877 peer->call = NULL; 17878 17879 /* Don't send a devstate change if nothing changed. */ 17880 if (peer->lastms > -1) { 17881 peer->lastms = -1; 17882 ast_device_state_changed("SIP/%s", peer->name); 17883 } 17884 17885 /* This function gets called one place outside of the scheduler ... */ 17886 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 17887 struct sip_peer *peer_ptr = peer; 17888 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17889 } 17890 17891 /* There is no need to ASTOBJ_REF() here. Just let the scheduled callback 17892 * inherit the reference that the current callback already has. */ 17893 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 17894 if (peer->pokeexpire == -1) { 17895 ASTOBJ_UNREF(peer, sip_destroy_peer); 17896 } 17897 17898 return 0; 17899 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 17904 of file chan_sip.c.
References __ourip, sip_peer::addr, ast_copy_flags, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_set, ast_strlen_zero(), ASTOBJ_REF, ASTOBJ_UNREF, build_callid_pvt(), build_via(), sip_peer::call, 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, sip_alloc(), sip_destroy(), sip_destroy_peer(), SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_FLAGS_TO_COPY, sip_poke_noanswer(), sipdebug, 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().
17905 { 17906 struct sip_pvt *p; 17907 int xmitres = 0; 17908 17909 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 17910 /* IF we have no IP, or this isn't to be monitored, return 17911 imeediately after clearing things out */ 17912 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 17913 struct sip_peer *peer_ptr = peer; 17914 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17915 } 17916 peer->lastms = 0; 17917 peer->call = NULL; 17918 return 0; 17919 } 17920 if (peer->call) { 17921 if (sipdebug) 17922 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 17923 sip_destroy(peer->call); 17924 } 17925 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 17926 return -1; 17927 17928 p->sa = peer->addr; 17929 p->recv = peer->addr; 17930 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 17931 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 17932 17933 /* Send OPTIONs to peer's fullcontact */ 17934 if (!ast_strlen_zero(peer->fullcontact)) 17935 ast_string_field_set(p, fullcontact, peer->fullcontact); 17936 17937 if (!ast_strlen_zero(peer->tohost)) 17938 ast_string_field_set(p, tohost, peer->tohost); 17939 else 17940 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 17941 17942 /* Recalculate our side, and recalculate Call ID */ 17943 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 17944 p->ourip = __ourip; 17945 build_via(p); 17946 build_callid_pvt(p); 17947 17948 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 17949 struct sip_peer *peer_ptr = peer; 17950 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17951 } 17952 17953 p->relatedpeer = ASTOBJ_REF(peer); 17954 ast_set_flag(&p->flags[0], SIP_OUTGOING); 17955 #ifdef VOCAL_DATA_HACK 17956 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 17957 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 17958 #else 17959 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 17960 #endif 17961 gettimeofday(&peer->ps, NULL); 17962 if (xmitres == XMIT_ERROR) { 17963 sip_poke_noanswer(ASTOBJ_REF(peer)); /* Immediately unreachable, network problems */ 17964 } else { 17965 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 17966 struct sip_peer *peer_ptr = peer; 17967 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17968 } 17969 peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer)); 17970 if (peer->pokeexpire == -1) { 17971 struct sip_peer *peer_ptr = peer; 17972 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17973 } 17974 } 17975 17976 return 0; 17977 }
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 8880 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_UNREF, sip_peer::name, peerl, sip_peer::pokeexpire, sip_destroy_peer(), and sip_poke_peer().
Referenced by handle_response_peerpoke(), reg_source_db(), sip_poke_all_peers(), and sip_poke_noanswer().
08881 { 08882 struct sip_peer *peer = (struct sip_peer *) data; 08883 struct sip_peer *foundpeer; 08884 08885 peer->pokeexpire = -1; 08886 08887 foundpeer = ASTOBJ_CONTAINER_FIND(&peerl, peer->name); 08888 if (!foundpeer) { 08889 ASTOBJ_UNREF(peer, sip_destroy_peer); 08890 return 0; 08891 } else if (foundpeer->name != peer->name) { 08892 ASTOBJ_UNREF(foundpeer, sip_destroy_peer); 08893 ASTOBJ_UNREF(peer, sip_destroy_peer); 08894 return 0; 08895 } 08896 08897 ASTOBJ_UNREF(foundpeer, sip_destroy_peer); 08898 sip_poke_peer(peer); 08899 ASTOBJ_UNREF(peer, sip_destroy_peer); 08900 08901 return 0; 08902 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 11513 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_FIND_UNLINK, ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, ASTOBJ_UNREF, FALSE, sip_user::flags, sip_peer::flags, name, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_destroy_peer(), sip_destroy_user(), SIP_PAGE2_RTCACHEFRIENDS, TRUE, and userl.
11514 { 11515 struct sip_peer *peer; 11516 struct sip_user *user; 11517 int pruneuser = FALSE; 11518 int prunepeer = FALSE; 11519 int multi = FALSE; 11520 char *name = NULL; 11521 regex_t regexbuf; 11522 int havepattern = 0; 11523 11524 switch (argc) { 11525 case 4: 11526 if (!strcasecmp(argv[3], "user")) 11527 return RESULT_SHOWUSAGE; 11528 if (!strcasecmp(argv[3], "peer")) 11529 return RESULT_SHOWUSAGE; 11530 if (!strcasecmp(argv[3], "like")) 11531 return RESULT_SHOWUSAGE; 11532 if (!strcasecmp(argv[3], "all")) { 11533 multi = TRUE; 11534 pruneuser = prunepeer = TRUE; 11535 } else { 11536 pruneuser = prunepeer = TRUE; 11537 name = argv[3]; 11538 } 11539 break; 11540 case 5: 11541 if (!strcasecmp(argv[4], "like")) 11542 return RESULT_SHOWUSAGE; 11543 if (!strcasecmp(argv[3], "all")) 11544 return RESULT_SHOWUSAGE; 11545 if (!strcasecmp(argv[3], "like")) { 11546 multi = TRUE; 11547 name = argv[4]; 11548 pruneuser = prunepeer = TRUE; 11549 } else if (!strcasecmp(argv[3], "user")) { 11550 pruneuser = TRUE; 11551 if (!strcasecmp(argv[4], "all")) 11552 multi = TRUE; 11553 else 11554 name = argv[4]; 11555 } else if (!strcasecmp(argv[3], "peer")) { 11556 prunepeer = TRUE; 11557 if (!strcasecmp(argv[4], "all")) 11558 multi = TRUE; 11559 else 11560 name = argv[4]; 11561 } else 11562 return RESULT_SHOWUSAGE; 11563 break; 11564 case 6: 11565 if (strcasecmp(argv[4], "like")) 11566 return RESULT_SHOWUSAGE; 11567 if (!strcasecmp(argv[3], "user")) { 11568 pruneuser = TRUE; 11569 name = argv[5]; 11570 } else if (!strcasecmp(argv[3], "peer")) { 11571 prunepeer = TRUE; 11572 name = argv[5]; 11573 } else 11574 return RESULT_SHOWUSAGE; 11575 break; 11576 default: 11577 return RESULT_SHOWUSAGE; 11578 } 11579 11580 if (multi && name) { 11581 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) { 11582 return RESULT_SHOWUSAGE; 11583 } 11584 havepattern = 1; 11585 } 11586 11587 if (multi) { 11588 if (prunepeer) { 11589 int pruned = 0; 11590 11591 ASTOBJ_CONTAINER_WRLOCK(&peerl); 11592 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 11593 ASTOBJ_RDLOCK(iterator); 11594 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 11595 ASTOBJ_UNLOCK(iterator); 11596 continue; 11597 }; 11598 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 11599 ASTOBJ_MARK(iterator); 11600 pruned++; 11601 } 11602 ASTOBJ_UNLOCK(iterator); 11603 } while (0) ); 11604 if (pruned) { 11605 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 11606 ast_cli(fd, "%d peers pruned.\n", pruned); 11607 } else 11608 ast_cli(fd, "No peers found to prune.\n"); 11609 ASTOBJ_CONTAINER_UNLOCK(&peerl); 11610 } 11611 if (pruneuser) { 11612 int pruned = 0; 11613 11614 ASTOBJ_CONTAINER_WRLOCK(&userl); 11615 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 11616 ASTOBJ_RDLOCK(iterator); 11617 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 11618 ASTOBJ_UNLOCK(iterator); 11619 continue; 11620 }; 11621 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 11622 ASTOBJ_MARK(iterator); 11623 pruned++; 11624 } 11625 ASTOBJ_UNLOCK(iterator); 11626 } while (0) ); 11627 if (pruned) { 11628 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 11629 ast_cli(fd, "%d users pruned.\n", pruned); 11630 } else 11631 ast_cli(fd, "No users found to prune.\n"); 11632 ASTOBJ_CONTAINER_UNLOCK(&userl); 11633 } 11634 } else { 11635 if (prunepeer) { 11636 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 11637 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 11638 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 11639 ASTOBJ_CONTAINER_LINK(&peerl, peer); 11640 } else 11641 ast_cli(fd, "Peer '%s' pruned.\n", name); 11642 ASTOBJ_UNREF(peer, sip_destroy_peer); 11643 } else 11644 ast_cli(fd, "Peer '%s' not found.\n", name); 11645 } 11646 if (pruneuser) { 11647 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 11648 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 11649 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 11650 ASTOBJ_CONTAINER_LINK(&userl, user); 11651 } else 11652 ast_cli(fd, "User '%s' pruned.\n", name); 11653 ASTOBJ_UNREF(user, sip_destroy_user); 11654 } else 11655 ast_cli(fd, "User '%s' not found.\n", name); 11656 } 11657 } 11658 11659 if (havepattern) { 11660 regfree(®exbuf); 11661 } 11662 11663 return RESULT_SUCCESS; 11664 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static, read] |
Read SIP RTP from channel.
Definition at line 4790 of file chan_sip.c.
References ast_channel::_state, ast_bridged_channel(), AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, ast_set_flag, AST_STATE_UP, ast_test_flag, FALSE, sip_pvt::flags, ast_frame::frametype, INV_EARLY_MEDIA, sip_pvt::invitestate, sip_pvt::lastrtprx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PENDINGBYE, sip_rtp_read(), t38properties::state, sip_pvt::t38, T38_DISABLED, T38_LOCAL_REINVITE, t38properties::t38support, ast_channel::tech_pvt, and transmit_reinvite_with_t38_sdp().
04791 { 04792 struct ast_frame *fr; 04793 struct sip_pvt *p = ast->tech_pvt; 04794 int faxdetected = FALSE; 04795 04796 ast_mutex_lock(&p->lock); 04797 fr = sip_rtp_read(ast, p, &faxdetected); 04798 p->lastrtprx = time(NULL); 04799 04800 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04801 /* 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 */ 04802 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04803 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04804 if (!p->pendinginvite) { 04805 if (option_debug > 2) 04806 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04807 p->t38.state = T38_LOCAL_REINVITE; 04808 transmit_reinvite_with_t38_sdp(p); 04809 if (option_debug > 1) 04810 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04811 } 04812 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04813 if (option_debug > 2) 04814 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04815 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04816 } 04817 } 04818 04819 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 04820 if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 04821 fr = &ast_null_frame; 04822 } 04823 04824 ast_mutex_unlock(&p->lock); 04825 return fr; 04826 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static, read] |
The real destination address for a write.
Definition at line 1867 of file chan_sip.c.
References ast_test_flag, sip_pvt::flags, sip_pvt::recv, sip_pvt::sa, SIP_NAT, and SIP_NAT_ROUTE.
Referenced by __sip_xmit(), check_via(), retrans_pkt(), send_response(), and sip_debug_test_pvt().
01868 { 01869 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01870 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 8685 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().
08686 { 08687 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 08688 return p->refer ? 1 : 0; 08689 }
static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 8423 of file chan_sip.c.
References __sip_pretend_ack(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_registry::hostname, sip_pvt::lock, LOG_NOTICE, manager_event(), sip_registry::needdns, REG_STATE_FAILED, REG_STATE_UNREGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, SIP_REGISTER, sip_registry_destroy(), sip_registry::timeout, transmit_register(), TRUE, and sip_registry::username.
Referenced by transmit_register().
08424 { 08425 08426 /* if we are here, our registration timed out, so we'll just do it over */ 08427 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 08428 struct sip_pvt *p; 08429 int res; 08430 08431 /* if we couldn't get a reference to the registry object, punt */ 08432 if (!r) 08433 return 0; 08434 08435 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 08436 if (r->call) { 08437 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 08438 in the single SIP manager thread. */ 08439 p = r->call; 08440 ast_mutex_lock(&p->lock); 08441 if (p->registry) 08442 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 08443 r->call = NULL; 08444 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 08445 /* Pretend to ACK anything just in case */ 08446 __sip_pretend_ack(p); 08447 ast_mutex_unlock(&p->lock); 08448 } 08449 /* If we have a limit, stop registration and give up */ 08450 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 08451 /* Ok, enough is enough. Don't try any more */ 08452 /* We could add an external notification here... 08453 steal it from app_voicemail :-) */ 08454 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 08455 r->regstate = REG_STATE_FAILED; 08456 } else { 08457 r->regstate = REG_STATE_UNREGISTERED; 08458 r->timeout = -1; 08459 r->needdns = TRUE; 08460 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 08461 } 08462 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate)); 08463 ASTOBJ_UNREF(r, sip_registry_destroy); 08464 return 0; 08465 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 5308 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, sip_registry::authuser, sip_registry::callid_valid, sip_registry::contact, sip_registry::expire, FALSE, free, hostname, INITIAL_CSEQ, LOG_ERROR, LOG_WARNING, sip_registry::needdns, sip_registry::ocseq, sip_registry::portno, sip_registry::refresh, regl, secret, sip_registry_destroy(), sip_registry::timeout, TRUE, and username.
Referenced by reload_config().
05309 { 05310 struct sip_registry *reg; 05311 int portnum = 0; 05312 char username[256] = ""; 05313 char *hostname=NULL, *secret=NULL, *authuser=NULL; 05314 char *porta=NULL; 05315 char *contact=NULL; 05316 05317 if (!value) 05318 return -1; 05319 ast_copy_string(username, value, sizeof(username)); 05320 /* First split around the last '@' then parse the two components. */ 05321 hostname = strrchr(username, '@'); /* allow @ in the first part */ 05322 if (hostname) 05323 *hostname++ = '\0'; 05324 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 05325 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 05326 return -1; 05327 } 05328 /* split user[:secret[:authuser]] */ 05329 secret = strchr(username, ':'); 05330 if (secret) { 05331 *secret++ = '\0'; 05332 authuser = strchr(secret, ':'); 05333 if (authuser) 05334 *authuser++ = '\0'; 05335 } 05336 /* split host[:port][/contact] */ 05337 contact = strchr(hostname, '/'); 05338 if (contact) 05339 *contact++ = '\0'; 05340 if (ast_strlen_zero(contact)) 05341 contact = "s"; 05342 porta = strchr(hostname, ':'); 05343 if (porta) { 05344 *porta++ = '\0'; 05345 portnum = atoi(porta); 05346 if (portnum == 0) { 05347 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 05348 return -1; 05349 } 05350 } 05351 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 05352 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 05353 return -1; 05354 } 05355 05356 if (ast_string_field_init(reg, 256)) { 05357 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 05358 free(reg); 05359 return -1; 05360 } 05361 05362 regobjs++; 05363 ASTOBJ_INIT(reg); 05364 ast_string_field_set(reg, contact, contact); 05365 if (!ast_strlen_zero(username)) 05366 ast_string_field_set(reg, username, username); 05367 if (hostname) 05368 ast_string_field_set(reg, hostname, hostname); 05369 if (authuser) 05370 ast_string_field_set(reg, authuser, authuser); 05371 if (secret) 05372 ast_string_field_set(reg, secret, secret); 05373 reg->expire = -1; 05374 reg->timeout = -1; 05375 reg->refresh = default_expiry; 05376 reg->portno = portnum; 05377 reg->callid_valid = FALSE; 05378 reg->ocseq = INITIAL_CSEQ; 05379 reg->needdns = TRUE; 05380 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 05381 ASTOBJ_UNREF(reg,sip_registry_destroy); 05382 return 0; 05383 }
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 3369 of file chan_sip.c.
References ast_log(), AST_SCHED_DEL, ast_string_field_free_memory, sip_registry::call, sip_registry::expire, free, sip_registry::hostname, LOG_DEBUG, option_debug, sip_pvt::registry, sip_destroy(), sip_registry::timeout, and sip_registry::username.
Referenced by __sip_destroy(), handle_response_register(), reload_config(), sip_reg_timeout(), sip_register(), sip_reregister(), and unload_module().
03370 { 03371 /* Really delete */ 03372 if (option_debug > 2) 03373 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 03374 03375 if (reg->call) { 03376 /* Clear registry before destroying to ensure 03377 we don't get reentered trying to grab the registry lock */ 03378 reg->call->registry = NULL; 03379 if (option_debug > 2) 03380 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 03381 sip_destroy(reg->call); 03382 } 03383 AST_SCHED_DEL(sched, reg->expire); 03384 AST_SCHED_DEL(sched, reg->timeout); 03385 ast_string_field_free_memory(reg); 03386 regobjs--; 03387 free(reg); 03388 03389 }
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 13501 of file chan_sip.c.
References ast_channel_trylock, ast_channel_unlock, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, check_pendings(), sip_pvt::flags, sip_pvt::lock, sip_pvt::owner, SIP_NEEDREINVITE, and sip_pvt::waitid.
Referenced by handle_response_invite().
13502 { 13503 struct sip_pvt *p = (struct sip_pvt *) data; 13504 struct ast_channel *owner; 13505 13506 ast_mutex_lock(&p->lock); /* called from schedule thread which requires a lock */ 13507 while ((owner = p->owner) && ast_channel_trylock(owner)) { 13508 ast_mutex_unlock(&p->lock); 13509 usleep(1); 13510 ast_mutex_lock(&p->lock); 13511 } 13512 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 13513 p->waitid = -1; 13514 check_pendings(p); 13515 ast_mutex_unlock(&p->lock); 13516 if (owner) { 13517 ast_channel_unlock(owner); 13518 } 13519 13520 return 0; 13521 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 20188 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), CHANNEL_CLI_RELOAD, CHANNEL_MODULE_RELOAD, restart_monitor(), sip_reload_lock, and TRUE.
Referenced by reload().
20189 { 20190 ast_mutex_lock(&sip_reload_lock); 20191 if (sip_reloading) 20192 ast_verbose("Previous SIP reload not yet done\n"); 20193 else { 20194 sip_reloading = TRUE; 20195 if (fd) 20196 sip_reloadreason = CHANNEL_CLI_RELOAD; 20197 else 20198 sip_reloadreason = CHANNEL_MODULE_RELOAD; 20199 } 20200 ast_mutex_unlock(&sip_reload_lock); 20201 restart_monitor(); 20202 20203 return 0; 20204 }
static struct ast_channel * sip_request_call | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static, read] |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
Definition at line 18089 of file chan_sip.c.
References __ourip, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CHANNEL_UNACCEPTABLE, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_string(), AST_FORMAT_MAX_AUDIO, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_callid_pvt(), build_via(), create_addr(), ext, sip_pvt::flags, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::options, sip_pvt::ourip, sip_pvt::peername, sip_pvt::prefcodec, restart_monitor(), sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), SIP_PAGE2_OUTGOING_CALL, and username.
18090 { 18091 int oldformat; 18092 struct sip_pvt *p; 18093 struct ast_channel *tmpc = NULL; 18094 char *ext, *host; 18095 char tmp[256]; 18096 char *dest = data; 18097 18098 oldformat = format; 18099 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 18100 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)); 18101 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 18102 return NULL; 18103 } 18104 if (option_debug) 18105 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 18106 18107 if (ast_strlen_zero(dest)) { 18108 ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n"); 18109 *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE; 18110 return NULL; 18111 } 18112 18113 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 18114 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 18115 *cause = AST_CAUSE_SWITCH_CONGESTION; 18116 return NULL; 18117 } 18118 18119 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 18120 18121 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 18122 sip_destroy(p); 18123 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 18124 *cause = AST_CAUSE_SWITCH_CONGESTION; 18125 return NULL; 18126 } 18127 18128 ast_copy_string(tmp, dest, sizeof(tmp)); 18129 host = strchr(tmp, '@'); 18130 if (host) { 18131 *host++ = '\0'; 18132 ext = tmp; 18133 } else { 18134 ext = strchr(tmp, '/'); 18135 if (ext) 18136 *ext++ = '\0'; 18137 host = tmp; 18138 } 18139 18140 if (create_addr(p, host, NULL)) { 18141 *cause = AST_CAUSE_UNREGISTERED; 18142 if (option_debug > 2) 18143 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registered\n"); 18144 sip_destroy(p); 18145 return NULL; 18146 } 18147 if (ast_strlen_zero(p->peername) && ext) 18148 ast_string_field_set(p, peername, ext); 18149 /* Recalculate our side, and recalculate Call ID */ 18150 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 18151 p->ourip = __ourip; 18152 build_via(p); 18153 build_callid_pvt(p); 18154 18155 /* We have an extension to call, don't use the full contact here */ 18156 /* This to enable dialing registered peers with extension dialling, 18157 like SIP/peername/extension 18158 SIP/peername will still use the full contact */ 18159 if (ext) { 18160 ast_string_field_set(p, username, ext); 18161 ast_string_field_free(p, fullcontact); 18162 } 18163 #if 0 18164 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 18165 #endif 18166 p->prefcodec = oldformat; /* Format for this call */ 18167 ast_mutex_lock(&p->lock); 18168 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 18169 ast_mutex_unlock(&p->lock); 18170 if (!tmpc) 18171 sip_destroy(p); 18172 ast_update_use_count(); 18173 restart_monitor(); 18174 return tmpc; 18175 }
static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 8391 of file chan_sip.c.
References __sip_do_register(), append_history, ast_log(), ast_test_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, sip_registry::expire, sip_pvt::flags, sip_registry::hostname, LOG_NOTICE, SIP_NO_HISTORY, sip_registry_destroy(), sipdebug, and sip_registry::username.
Referenced by handle_response_register(), and sip_send_all_registers().
08392 { 08393 /* if we are here, we know that we need to reregister. */ 08394 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 08395 08396 /* if we couldn't get a reference to the registry object, punt */ 08397 if (!r) 08398 return 0; 08399 08400 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 08401 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 08402 /* Since registry's are only added/removed by the the monitor thread, this 08403 may be overkill to reference/dereference at all here */ 08404 if (sipdebug) 08405 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 08406 08407 r->expire = -1; 08408 __sip_do_register(r); 08409 ASTOBJ_UNREF(r, sip_registry_destroy); 08410 return 0; 08411 }
static struct ast_frame * sip_rtp_read | ( | struct ast_channel * | ast, | |
struct sip_pvt * | p, | |||
int * | faxdetect | |||
) | [static, read] |
Read RTP from network.
Definition at line 4718 of file chan_sip.c.
References ast_dsp_process(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_null_frame, ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), f, ast_channel::fdno, sip_pvt::flags, ast_frame::frametype, sip_pvt::jointcapability, LOG_DEBUG, ast_channel::nativeformats, option_debug, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_PAGE2_T38SUPPORT_UDPTL, ast_frame::subclass, sip_pvt::t38, t38properties::t38support, sip_pvt::udptl, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by sip_read().
04719 { 04720 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04721 struct ast_frame *f; 04722 04723 if (!p->rtp) { 04724 /* We have no RTP allocated for this channel */ 04725 return &ast_null_frame; 04726 } 04727 04728 switch(ast->fdno) { 04729 case 0: 04730 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04731 break; 04732 case 1: 04733 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04734 break; 04735 case 2: 04736 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04737 break; 04738 case 3: 04739 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04740 break; 04741 case 5: 04742 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04743 break; 04744 default: 04745 f = &ast_null_frame; 04746 } 04747 /* Don't forward RFC2833 if we're not supposed to */ 04748 if (f && (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && 04749 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) { 04750 ast_log(LOG_DEBUG,"Ignoring DTMF (%c) RTP frame because dtmfmode is not RFC2833\n", f->subclass); 04751 return &ast_null_frame; 04752 } 04753 04754 /* We already hold the channel lock */ 04755 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 04756 return f; 04757 04758 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04759 if (!(f->subclass & p->jointcapability)) { 04760 if (option_debug) { 04761 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04762 ast_getformatname(f->subclass), p->owner->name); 04763 } 04764 return &ast_null_frame; 04765 } 04766 if (option_debug) 04767 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04768 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04769 ast_set_read_format(p->owner, p->owner->readformat); 04770 ast_set_write_format(p->owner, p->owner->writeformat); 04771 } 04772 04773 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04774 f = ast_dsp_process(p->owner, p->vad, f); 04775 if (f && f->frametype == AST_FRAME_DTMF) { 04776 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04777 if (option_debug) 04778 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04779 *faxdetect = 1; 04780 } else if (option_debug) { 04781 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04782 } 04783 } 04784 } 04785 04786 return f; 04787 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2260 of file chan_sip.c.
References __sip_autodestruct(), append_history, ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ast_verbose(), sip_pvt::autokillid, sip_pvt::callid, sip_pvt::flags, sip_pvt::method, sip_debug_test_pvt(), sip_methods, SIP_NO_HISTORY, cfsip_methods::text, and sip_pvt::timer_t1.
Referenced by __sip_autodestruct(), auto_congest(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), 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(), notify_extenstate_update(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), sip_sipredirect(), and transmit_fake_auth_response().
02261 { 02262 if (ms < 0) { 02263 if (p->timer_t1 == 0) 02264 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02265 ms = p->timer_t1 * 64; 02266 } 02267 if (sip_debug_test_pvt(p)) 02268 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02269 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02270 append_history(p, "SchedDestroy", "%d ms", ms); 02271 02272 AST_SCHED_DEL(sched, p->autokillid); 02273 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02274 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 20133 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, regl, and sip_reregister().
Referenced by load_module(), and sip_do_reload().
20134 { 20135 int ms; 20136 int regspacing; 20137 if (!regobjs) 20138 return; 20139 regspacing = default_expiry * 1000/regobjs; 20140 if (regspacing > 100) 20141 regspacing = 100; 20142 ms = regspacing; 20143 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 20144 ASTOBJ_WRLOCK(iterator); 20145 AST_SCHED_DEL(sched, iterator->expire); 20146 ms += regspacing; 20147 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 20148 ASTOBJ_UNLOCK(iterator); 20149 } while (0) 20150 ); 20151 }
static int sip_send_mwi_to_peer | ( | struct sip_peer * | peer, | |
int | force | |||
) | [static] |
Send message waiting indication to alert peer that they've got voicemail.
Definition at line 17573 of file chan_sip.c.
References __ourip, sip_peer::addr, ast_app_inboxcount(), ast_set_flag, ast_sip_ouraddrfor(), build_callid_pvt(), build_via(), create_addr_from_peer(), sip_peer::defaddr, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_peer::lastmsgcheck, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::mwipvt, sip_pvt::ourip, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), transmit_notify_with_mwi(), and sip_peer::vmexten.
Referenced by do_monitor(), and handle_request_subscribe().
17574 { 17575 /* Called with peerl lock, but releases it */ 17576 struct sip_pvt *p; 17577 int newmsgs, oldmsgs; 17578 17579 /* Do we have an IP address? If not, skip this peer */ 17580 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 17581 return 0; 17582 17583 /* Check for messages */ 17584 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 17585 17586 peer->lastmsgcheck = time(NULL); 17587 17588 /* Return now if it's the same thing we told them last time */ 17589 if (!force && ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 17590 return 0; 17591 } 17592 17593 17594 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 17595 17596 if (peer->mwipvt) { 17597 /* Base message on subscription */ 17598 p = peer->mwipvt; 17599 } else { 17600 /* Build temporary dialog for this message */ 17601 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 17602 return -1; 17603 if (create_addr_from_peer(p, peer)) { 17604 /* Maybe they're not registered, etc. */ 17605 sip_destroy(p); 17606 return 0; 17607 } 17608 /* Recalculate our side, and recalculate Call ID */ 17609 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 17610 p->ourip = __ourip; 17611 build_via(p); 17612 build_callid_pvt(p); 17613 /* Destroy this session after 32 secs */ 17614 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17615 } 17616 /* Send MWI */ 17617 ast_set_flag(&p->flags[0], SIP_OUTGOING); 17618 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 17619 return 0; 17620 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 4186 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit_begin(), ast_test_flag, sip_pvt::flags, sip_pvt::lock, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, and ast_channel::tech_pvt.
04187 { 04188 struct sip_pvt *p = ast->tech_pvt; 04189 int res = 0; 04190 04191 ast_mutex_lock(&p->lock); 04192 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 04193 case SIP_DTMF_INBAND: 04194 res = -1; /* Tell Asterisk to generate inband indications */ 04195 break; 04196 case SIP_DTMF_RFC2833: 04197 if (p->rtp) 04198 ast_rtp_senddigit_begin(p->rtp, digit); 04199 break; 04200 default: 04201 break; 04202 } 04203 ast_mutex_unlock(&p->lock); 04204 04205 return res; 04206 }
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 4210 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit_end_with_duration(), ast_test_flag, sip_pvt::flags, sip_pvt::lock, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, and transmit_info_with_digit().
04211 { 04212 struct sip_pvt *p = ast->tech_pvt; 04213 int res = 0; 04214 04215 ast_mutex_lock(&p->lock); 04216 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 04217 case SIP_DTMF_INFO: 04218 transmit_info_with_digit(p, digit, duration); 04219 break; 04220 case SIP_DTMF_RFC2833: 04221 if (p->rtp) 04222 ast_rtp_senddigit_end_with_duration(p->rtp, digit, duration); 04223 break; 04224 case SIP_DTMF_INBAND: 04225 res = -1; /* Tell Asterisk to stop inband indications */ 04226 break; 04227 } 04228 ast_mutex_unlock(&p->lock); 04229 04230 return res; 04231 }
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 2653 of file chan_sip.c.
References ast_verbose(), debug, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().
02654 { 02655 struct sip_pvt *p = ast->tech_pvt; 02656 int debug = sip_debug_test_pvt(p); 02657 02658 if (debug) 02659 ast_verbose("Sending text %s on %s\n", text, ast->name); 02660 if (!p) 02661 return -1; 02662 /* NOT ast_strlen_zero, because a zero-length message is specifically 02663 * allowed by RFC 3428 (See section 10, Examples) */ 02664 if (!text) 02665 return 0; 02666 if (debug) 02667 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02668 transmit_message_with_text(p, text); 02669 return 0; 02670 }
static int sip_set_rtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp * | rtp, | |||
struct ast_rtp * | vrtp, | |||
int | codecs, | |||
int | nat_active | |||
) | [static] |
Set the RTP peer for this call.
Definition at line 19863 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_set_flag, AST_STATE_UP, ast_test_flag, sip_pvt::callid, sip_pvt::capability, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, SIP_ALREADYGONE, SIP_CAN_REINVITE_NAT, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), and sip_pvt::vredirip.
Referenced by sip_fixup().
19864 { 19865 struct sip_pvt *p; 19866 int changed = 0; 19867 19868 p = chan->tech_pvt; 19869 if (!p) 19870 return -1; 19871 19872 /* Disable early RTP bridge */ 19873 if (!ast_bridged_channel(chan) && !global_directrtpsetup) /* We are in early state */ 19874 return 0; 19875 19876 ast_mutex_lock(&p->lock); 19877 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 19878 /* If we're destroyed, don't bother */ 19879 ast_mutex_unlock(&p->lock); 19880 return 0; 19881 } 19882 19883 /* if this peer cannot handle reinvites of the media stream to devices 19884 that are known to be behind a NAT, then stop the process now 19885 */ 19886 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 19887 ast_mutex_unlock(&p->lock); 19888 return 0; 19889 } 19890 19891 if (rtp) { 19892 changed |= ast_rtp_get_peer(rtp, &p->redirip); 19893 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 19894 memset(&p->redirip, 0, sizeof(p->redirip)); 19895 changed = 1; 19896 } 19897 if (vrtp) { 19898 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 19899 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 19900 memset(&p->vredirip, 0, sizeof(p->vredirip)); 19901 changed = 1; 19902 } 19903 if (codecs) { 19904 if (p->redircodecs != codecs && (p->jointcapability & codecs) != p->jointcapability) { 19905 p->redircodecs = codecs; 19906 p->jointcapability &= codecs; 19907 p->capability &= codecs; 19908 changed = 1; 19909 } 19910 } 19911 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 19912 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 19913 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 19914 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 19915 if (option_debug) 19916 ast_log(LOG_DEBUG, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip)); 19917 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 19918 if (option_debug > 2) { 19919 ast_log(LOG_DEBUG, "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)); 19920 } 19921 transmit_reinvite_with_sdp(p); 19922 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 19923 if (option_debug > 2) { 19924 ast_log(LOG_DEBUG, "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)); 19925 } 19926 /* We have a pending Invite. Send re-invite when we're done with the invite */ 19927 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 19928 } 19929 } 19930 /* Reset lastrtprx timer */ 19931 p->lastrtprx = p->lastrtptx = time(NULL); 19932 ast_mutex_unlock(&p->lock); 19933 return 0; 19934 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 19677 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_peer(), sip_pvt::callid, sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), and sip_pvt::udptlredirip.
19678 { 19679 struct sip_pvt *p; 19680 19681 p = chan->tech_pvt; 19682 if (!p) 19683 return -1; 19684 ast_mutex_lock(&p->lock); 19685 if (udptl) 19686 ast_udptl_get_peer(udptl, &p->udptlredirip); 19687 else 19688 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 19689 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 19690 if (!p->pendinginvite) { 19691 if (option_debug > 2) { 19692 ast_log(LOG_DEBUG, "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), udptl ? ntohs(p->udptlredirip.sin_port) : 0); 19693 } 19694 transmit_reinvite_with_t38_sdp(p); 19695 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 19696 if (option_debug > 2) { 19697 ast_log(LOG_DEBUG, "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), udptl ? ntohs(p->udptlredirip.sin_port) : 0); 19698 } 19699 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 19700 } 19701 } 19702 /* Reset lastrtprx timer */ 19703 p->lastrtprx = p->lastrtptx = time(NULL); 19704 ast_mutex_unlock(&p->lock); 19705 return 0; 19706 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 12402 of file chan_sip.c.
References sip_pvt::allowtransfer, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::capability, sip_pvt::cid_num, dtmfmode2str(), sip_pvt::flags, sip_route::hop, cfsip_options::id, iflist, iflock, sip_pvt::jointcapability, sip_pvt::lastmsg, sip_request::len, sip_pvt::maxcallbitrate, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::peername, sip_pvt::recv, sip_pvt::redirip, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, SIP_NEEDDESTROY, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, SIPBUFSIZE, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, sip_pvt::theirtag, transfermode2str(), sip_pvt::uri, sip_pvt::useragent, and sip_pvt::username.
12403 { 12404 struct sip_pvt *cur; 12405 size_t len; 12406 int found = 0; 12407 12408 if (argc != 4) 12409 return RESULT_SHOWUSAGE; 12410 len = strlen(argv[3]); 12411 ast_mutex_lock(&iflock); 12412 for (cur = iflist; cur; cur = cur->next) { 12413 if (!strncasecmp(cur->callid, argv[3], len)) { 12414 char formatbuf[SIPBUFSIZE/2]; 12415 ast_cli(fd,"\n"); 12416 if (cur->subscribed != NONE) 12417 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 12418 else 12419 ast_cli(fd, " * SIP Call\n"); 12420 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 12421 ast_cli(fd, " Call-ID: %s\n", cur->callid); 12422 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 12423 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 12424 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 12425 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 12426 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 12427 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 12428 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 12429 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 12430 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 12431 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 12432 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 12433 ast_cli(fd, " Audio IP: %s %s\n", ast_inet_ntoa(cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" ); 12434 ast_cli(fd, " Our Tag: %s\n", cur->tag); 12435 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 12436 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 12437 if (!ast_strlen_zero(cur->username)) 12438 ast_cli(fd, " Username: %s\n", cur->username); 12439 if (!ast_strlen_zero(cur->peername)) 12440 ast_cli(fd, " Peername: %s\n", cur->peername); 12441 if (!ast_strlen_zero(cur->uri)) 12442 ast_cli(fd, " Original uri: %s\n", cur->uri); 12443 if (!ast_strlen_zero(cur->cid_num)) 12444 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 12445 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 12446 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 12447 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 12448 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 12449 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 12450 ast_cli(fd, " SIP Options: "); 12451 if (cur->sipoptions) { 12452 int x; 12453 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 12454 if (cur->sipoptions & sip_options[x].id) 12455 ast_cli(fd, "%s ", sip_options[x].text); 12456 } 12457 } else 12458 ast_cli(fd, "(none)\n"); 12459 ast_cli(fd, "\n\n"); 12460 found++; 12461 } 12462 } 12463 ast_mutex_unlock(&iflock); 12464 if (!found) 12465 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 12466 return RESULT_SUCCESS; 12467 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 12188 of file chan_sip.c.
References __sip_show_channels().
12189 { 12190 return __sip_show_channels(fd, argc, argv, 0); 12191 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 11698 of file chan_sip.c.
References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, domain::context, domain::domain, domain_mode_to_text(), FORMAT, domain::mode, RESULT_SUCCESS, and S_OR.
11699 { 11700 struct domain *d; 11701 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 11702 11703 if (AST_LIST_EMPTY(&domain_list)) { 11704 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 11705 return RESULT_SUCCESS; 11706 } else { 11707 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 11708 AST_LIST_LOCK(&domain_list); 11709 AST_LIST_TRAVERSE(&domain_list, d, list) 11710 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 11711 domain_mode_to_text(d->mode)); 11712 AST_LIST_UNLOCK(&domain_list); 11713 ast_cli(fd, "\n"); 11714 return RESULT_SUCCESS; 11715 } 11716 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 12470 of file chan_sip.c.
References ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::callid, sip_history::event, sip_pvt::history, iflist, iflock, sip_request::len, sip_pvt::next, NONE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and sip_pvt::subscribed.
12471 { 12472 struct sip_pvt *cur; 12473 size_t len; 12474 int found = 0; 12475 12476 if (argc != 4) 12477 return RESULT_SHOWUSAGE; 12478 if (!recordhistory) 12479 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 12480 len = strlen(argv[3]); 12481 ast_mutex_lock(&iflock); 12482 for (cur = iflist; cur; cur = cur->next) { 12483 if (!strncasecmp(cur->callid, argv[3], len)) { 12484 struct sip_history *hist; 12485 int x = 0; 12486 12487 ast_cli(fd,"\n"); 12488 if (cur->subscribed != NONE) 12489 ast_cli(fd, " * Subscription\n"); 12490 else 12491 ast_cli(fd, " * SIP Call\n"); 12492 if (cur->history) 12493 AST_LIST_TRAVERSE(cur->history, hist, list) 12494 ast_cli(fd, "%d. %s\n", ++x, hist->event); 12495 if (x == 0) 12496 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 12497 found++; 12498 } 12499 } 12500 ast_mutex_unlock(&iflock); 12501 if (!found) 12502 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 12503 return RESULT_SUCCESS; 12504 }
static int sip_show_inuse | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command to show calls within limits set by call_limit.
Definition at line 11116 of file chan_sip.c.
References ast_cli(), ast_copy_string(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, FORMAT2, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, TRUE, and userl.
11117 { 11118 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 11119 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 11120 char ilimits[40]; 11121 char iused[40]; 11122 int showall = FALSE; 11123 11124 if (argc < 3) 11125 return RESULT_SHOWUSAGE; 11126 11127 if (argc == 4 && !strcmp(argv[3],"all")) 11128 showall = TRUE; 11129 11130 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 11131 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 11132 ASTOBJ_RDLOCK(iterator); 11133 if (iterator->call_limit) 11134 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 11135 else 11136 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 11137 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 11138 if (showall || iterator->call_limit) 11139 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 11140 ASTOBJ_UNLOCK(iterator); 11141 } while (0) ); 11142 11143 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 11144 11145 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 11146 ASTOBJ_RDLOCK(iterator); 11147 if (iterator->call_limit) 11148 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 11149 else 11150 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 11151 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 11152 if (showall || iterator->call_limit) 11153 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 11154 ASTOBJ_UNLOCK(iterator); 11155 } while (0) ); 11156 11157 return RESULT_SUCCESS; 11158 #undef FORMAT 11159 #undef FORMAT2 11160 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 11437 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
11438 { 11439 char tmp[256]; 11440 if (argc != 3) 11441 return RESULT_SHOWUSAGE; 11442 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 11443 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 11444 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 11445 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 11446 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 11447 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 11448 return RESULT_SUCCESS; 11449 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 11750 of file chan_sip.c.
References _sip_show_peer().
11751 { 11752 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 11753 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 11293 of file chan_sip.c.
References _sip_show_peers().
11294 { 11295 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 11296 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 12024 of file chan_sip.c.
References ast_cli(), ast_localtime(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, FORMAT2, regl, regstate2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and STANDARD_SIP_PORT.
12025 { 12026 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 12027 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 12028 char host[80]; 12029 char tmpdat[256]; 12030 struct tm tm; 12031 12032 12033 if (argc != 3) 12034 return RESULT_SHOWUSAGE; 12035 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 12036 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 12037 ASTOBJ_RDLOCK(iterator); 12038 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 12039 if (iterator->regtime) { 12040 ast_localtime(&iterator->regtime, &tm, NULL); 12041 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 12042 } else { 12043 tmpdat[0] = 0; 12044 } 12045 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 12046 ASTOBJ_UNLOCK(iterator); 12047 } while(0)); 12048 return RESULT_SUCCESS; 12049 #undef FORMAT 12050 #undef FORMAT2 12051 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 12054 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_test_flag, ast_tos2str(), authl, bindaddr, default_prefs, dtmfmode2str(), nat2str(), print_codec_to_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, SIP_DTMF, SIP_NAT, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_FORWARD_LOOP_DETECTED, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, SIPBUFSIZE, and transfermode2str().
12055 { 12056 int realtimepeers; 12057 int realtimeusers; 12058 char codec_buf[SIPBUFSIZE]; 12059 12060 realtimepeers = ast_check_realtime("sippeers"); 12061 realtimeusers = ast_check_realtime("sipusers"); 12062 12063 if (argc != 3) 12064 return RESULT_SHOWUSAGE; 12065 ast_cli(fd, "\n\nGlobal Settings:\n"); 12066 ast_cli(fd, "----------------\n"); 12067 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 12068 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 12069 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 12070 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 12071 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 12072 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 12073 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 12074 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 12075 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 12076 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 12077 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 12078 ast_cli(fd, " Our auth realm %s\n", global_realm); 12079 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 12080 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 12081 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 12082 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 12083 ast_cli(fd, " User Agent: %s\n", global_useragent); 12084 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 12085 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 12086 ast_cli(fd, " Caller ID: %s\n", default_callerid); 12087 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 12088 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 12089 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 12090 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 12091 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 12092 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 12093 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 12094 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 12095 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 12096 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 12097 #endif 12098 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 12099 if (!realtimepeers && !realtimeusers) 12100 ast_cli(fd, " SIP realtime: Disabled\n" ); 12101 else 12102 ast_cli(fd, " SIP realtime: Enabled\n" ); 12103 12104 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 12105 ast_cli(fd, "---------------------------\n"); 12106 ast_cli(fd, " Codecs: "); 12107 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 12108 ast_cli(fd, "%s\n", codec_buf); 12109 ast_cli(fd, " Codec Order: "); 12110 print_codec_to_cli(fd, &default_prefs); 12111 ast_cli(fd, "\n"); 12112 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 12113 ast_cli(fd, " No premature media: %s\n", global_prematuremediafilter ? "Yes" : "No"); 12114 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 12115 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 12116 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 12117 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 12118 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 12119 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 12120 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 12121 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 12122 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 12123 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 12124 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 12125 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 12126 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 12127 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 12128 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 12129 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 12130 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 12131 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 12132 ast_cli(fd, "\nDefault Settings:\n"); 12133 ast_cli(fd, "-----------------\n"); 12134 ast_cli(fd, " Context: %s\n", default_context); 12135 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 12136 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 12137 ast_cli(fd, " Qualify: %d\n", default_qualify); 12138 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 12139 ast_cli(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" ); 12140 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 12141 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 12142 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 12143 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 12144 ast_cli(fd, " Forward Detected Loops: %s\n", (ast_test_flag(&global_flags[1], SIP_PAGE2_FORWARD_LOOP_DETECTED) ? "Yes" : "No")); 12145 12146 if (realtimepeers || realtimeusers) { 12147 ast_cli(fd, "\nRealtime SIP Settings:\n"); 12148 ast_cli(fd, "----------------------\n"); 12149 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 12150 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 12151 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 12152 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 12153 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 12154 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 12155 ast_cli(fd, " Auto Clear: %d (%s)", global_rtautoclear, ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR) ? "Enabled" : "Disabled"); 12156 } 12157 ast_cli(fd, "\n----\n"); 12158 return RESULT_SUCCESS; 12159 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 12194 of file chan_sip.c.
References __sip_show_channels().
12195 { 12196 return __sip_show_channels(fd, argc, argv, 1); 12197 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 11969 of file chan_sip.c.
References sip_user::accountcode, sip_user::allowtransfer, sip_user::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_describe_caller_presentation(), ast_strlen_zero(), ASTOBJ_UNREF, sip_user::autoframing, sip_user::call_limit, sip_user::callgroup, sip_user::callingpres, sip_user::chanvars, sip_user::cid_name, sip_user::cid_num, sip_user::context, FALSE, find_user(), sip_user::ha, sip_user::language, sip_user::maxcallbitrate, sip_user::md5secret, ast_variable::name, sip_user::name, ast_variable::next, sip_user::pickupgroup, sip_user::prefs, print_codec_to_cli(), print_group(), RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_user::secret, sip_destroy_user(), transfermode2str(), TRUE, and ast_variable::value.
11970 { 11971 char cbuf[256]; 11972 struct sip_user *user; 11973 struct ast_variable *v; 11974 int load_realtime; 11975 11976 if (argc < 4) 11977 return RESULT_SHOWUSAGE; 11978 11979 /* Load from realtime storage? */ 11980 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 11981 11982 user = find_user(argv[3], load_realtime); 11983 if (user) { 11984 ast_cli(fd,"\n\n"); 11985 ast_cli(fd, " * Name : %s\n", user->name); 11986 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 11987 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 11988 ast_cli(fd, " Context : %s\n", user->context); 11989 ast_cli(fd, " Language : %s\n", user->language); 11990 if (!ast_strlen_zero(user->accountcode)) 11991 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 11992 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 11993 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 11994 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 11995 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 11996 ast_cli(fd, " Call limit : %d\n", user->call_limit); 11997 ast_cli(fd, " Callgroup : "); 11998 print_group(fd, &user->callgroup, 0); 11999 ast_cli(fd, " Pickupgroup : "); 12000 print_group(fd, &user->pickupgroup, 0); 12001 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 12002 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 12003 ast_cli(fd, " Codec Order : ("); 12004 print_codec_to_cli(fd, &user->prefs); 12005 ast_cli(fd, ")\n"); 12006 12007 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 12008 if (user->chanvars) { 12009 ast_cli(fd, " Variables :\n"); 12010 for (v = user->chanvars ; v ; v = v->next) 12011 ast_cli(fd, " %s = %s\n", v->name, v->value); 12012 } 12013 ast_cli(fd,"\n"); 12014 ASTOBJ_UNREF(user,sip_destroy_user); 12015 } else { 12016 ast_cli(fd,"User %s not found.\n", argv[3]); 12017 ast_cli(fd,"\n"); 12018 } 12019 12020 return RESULT_SUCCESS; 12021 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 11216 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, nat2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_NAT, TRUE, and userl.
11217 { 11218 regex_t regexbuf; 11219 int havepattern = FALSE; 11220 11221 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 11222 11223 switch (argc) { 11224 case 5: 11225 if (!strcasecmp(argv[3], "like")) { 11226 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 11227 return RESULT_SHOWUSAGE; 11228 havepattern = TRUE; 11229 } else 11230 return RESULT_SHOWUSAGE; 11231 case 3: 11232 break; 11233 default: 11234 return RESULT_SHOWUSAGE; 11235 } 11236 11237 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 11238 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 11239 ASTOBJ_RDLOCK(iterator); 11240 11241 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 11242 ASTOBJ_UNLOCK(iterator); 11243 continue; 11244 } 11245 11246 ast_cli(fd, FORMAT, iterator->name, 11247 iterator->secret, 11248 iterator->accountcode, 11249 iterator->context, 11250 iterator->ha ? "Yes" : "No", 11251 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 11252 ASTOBJ_UNLOCK(iterator); 11253 } while (0) 11254 ); 11255 11256 if (havepattern) 11257 regfree(®exbuf); 11258 11259 return RESULT_SUCCESS; 11260 #undef FORMAT 11261 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 20047 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().
20048 { 20049 char *cdest; 20050 char *extension, *host, *port; 20051 char tmp[80]; 20052 20053 cdest = ast_strdupa(dest); 20054 20055 extension = strsep(&cdest, "@"); 20056 host = strsep(&cdest, ":"); 20057 port = strsep(&cdest, ":"); 20058 if (ast_strlen_zero(extension)) { 20059 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 20060 return 0; 20061 } 20062 20063 /* we'll issue the redirect message here */ 20064 if (!host) { 20065 char *localtmp; 20066 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 20067 if (ast_strlen_zero(tmp)) { 20068 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 20069 return 0; 20070 } 20071 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 20072 char lhost[80], lport[80]; 20073 memset(lhost, 0, sizeof(lhost)); 20074 memset(lport, 0, sizeof(lport)); 20075 localtmp++; 20076 /* This is okey because lhost and lport are as big as tmp */ 20077 sscanf(localtmp, "%80[^<>:; ]:%80[^<>:; ]", lhost, lport); 20078 if (ast_strlen_zero(lhost)) { 20079 ast_log(LOG_ERROR, "Can't find the host address\n"); 20080 return 0; 20081 } 20082 host = ast_strdupa(lhost); 20083 if (!ast_strlen_zero(lport)) { 20084 port = ast_strdupa(lport); 20085 } 20086 } 20087 } 20088 20089 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 20090 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 20091 20092 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 20093 sip_alreadygone(p); 20094 return 0; 20095 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 4234 of file chan_sip.c.
References ast_channel::_state, ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_RING, sip_pvt::lock, sip_sipredirect(), ast_channel::tech_pvt, and transmit_refer().
04235 { 04236 struct sip_pvt *p = ast->tech_pvt; 04237 int res; 04238 04239 if (dest == NULL) /* functions below do not take a NULL */ 04240 dest = ""; 04241 ast_mutex_lock(&p->lock); 04242 if (ast->_state == AST_STATE_RING) 04243 res = sip_sipredirect(p, dest); 04244 else 04245 res = transmit_refer(p, dest); 04246 ast_mutex_unlock(&p->lock); 04247 return res; 04248 }
static int sip_uri_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
Definition at line 15360 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().
15361 { 15362 char *uri1 = ast_strdupa(input1); 15363 char *uri2 = ast_strdupa(input2); 15364 char *host1; 15365 char *host2; 15366 char *params1; 15367 char *params2; 15368 char *headers1; 15369 char *headers2; 15370 15371 /* Strip off "sip:" from the URI. We know this is present 15372 * because it was checked back in parse_request() 15373 */ 15374 strsep(&uri1, ":"); 15375 strsep(&uri2, ":"); 15376 15377 if ((host1 = strchr(uri1, '@'))) { 15378 *host1++ = '\0'; 15379 } 15380 if ((host2 = strchr(uri2, '@'))) { 15381 *host2++ = '\0'; 15382 } 15383 15384 /* Check for mismatched username and passwords. This is the 15385 * only case-sensitive comparison of a SIP URI 15386 */ 15387 if ((host1 && !host2) || 15388 (host2 && !host1) || 15389 (host1 && host2 && strcmp(uri1, uri2))) { 15390 return 1; 15391 } 15392 15393 if (!host1) 15394 host1 = uri1; 15395 if (!host2) 15396 host2 = uri2; 15397 15398 /* Strip off the parameters and headers so we can compare 15399 * host and port 15400 */ 15401 15402 if ((params1 = strchr(host1, ';'))) { 15403 *params1++ = '\0'; 15404 } 15405 if ((params2 = strchr(host2, ';'))) { 15406 *params2++ = '\0'; 15407 } 15408 15409 /* Headers come after parameters, but there may be headers without 15410 * parameters, thus the S_OR 15411 */ 15412 if ((headers1 = strchr(S_OR(params1, host1), '?'))) { 15413 *headers1++ = '\0'; 15414 } 15415 if ((headers2 = strchr(S_OR(params2, host2), '?'))) { 15416 *headers2++ = '\0'; 15417 } 15418 15419 /* Now the host/port are properly isolated. We can get by with a string comparison 15420 * because the SIP URI checking rules have some interesting exceptions that make 15421 * this possible. I will note 2 in particular 15422 * 1. hostnames which resolve to the same IP address as well as a hostname and its 15423 * IP address are not considered a match with SIP URI's. 15424 * 2. If one URI specifies a port and the other does not, then the URIs do not match. 15425 * This includes if one URI explicitly contains port 5060 and the other implies it 15426 * by not having a port specified. 15427 */ 15428 15429 if (strcasecmp(host1, host2)) { 15430 return 1; 15431 } 15432 15433 /* Headers have easier rules to follow, so do those first */ 15434 if (sip_uri_headers_cmp(headers1, headers2)) { 15435 return 1; 15436 } 15437 15438 /* And now the parameters. Ugh */ 15439 return sip_uri_params_cmp(params1, params2); 15440 }
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 15314 of file chan_sip.c.
References ast_strdupa, ast_strlen_zero(), strcasestr(), and strsep().
Referenced by sip_uri_cmp().
15315 { 15316 char *headers1 = NULL; 15317 char *headers2 = NULL; 15318 int zerolength1 = 0; 15319 int zerolength2 = 0; 15320 int different = 0; 15321 char *header1; 15322 15323 if (ast_strlen_zero(input1)) { 15324 zerolength1 = 1; 15325 } else { 15326 headers1 = ast_strdupa(input1); 15327 } 15328 15329 if (ast_strlen_zero(input2)) { 15330 zerolength2 = 1; 15331 } else { 15332 headers2 = ast_strdupa(input2); 15333 } 15334 15335 if ((zerolength1 && !zerolength2) || 15336 (zerolength2 && !zerolength1)) 15337 return 1; 15338 15339 if (zerolength1 && zerolength2) 15340 return 0; 15341 15342 /* At this point, we can definitively state that both inputs are 15343 * not zero-length. First, one more optimization. If the length 15344 * of the headers is not equal, then we definitely have no match 15345 */ 15346 if (strlen(headers1) != strlen(headers2)) { 15347 return 1; 15348 } 15349 15350 for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) { 15351 if (!strcasestr(headers2, header1)) { 15352 different = 1; 15353 break; 15354 } 15355 } 15356 15357 return different; 15358 }
static int sip_uri_params_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
helper routine for sip_uri_cmp to compare URI parameters
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 |
0 | URIs' parameters match | |
nonzero | URIs' parameters do not match |
Definition at line 15189 of file chan_sip.c.
References ast_strdupa, ast_strlen_zero(), and strsep().
Referenced by sip_uri_cmp().
15190 { 15191 char *params1 = NULL; 15192 char *params2 = NULL; 15193 char *pos1; 15194 char *pos2; 15195 int zerolength1 = 0; 15196 int zerolength2 = 0; 15197 int maddrmatch = 0; 15198 int ttlmatch = 0; 15199 int usermatch = 0; 15200 int methodmatch = 0; 15201 15202 if (ast_strlen_zero(input1)) { 15203 zerolength1 = 1; 15204 } else { 15205 params1 = ast_strdupa(input1); 15206 } 15207 if (ast_strlen_zero(input2)) { 15208 zerolength2 = 1; 15209 } else { 15210 params2 = ast_strdupa(input2); 15211 } 15212 15213 /* Quick optimization. If both params are zero-length, then 15214 * they match 15215 */ 15216 if (zerolength1 && zerolength2) { 15217 return 0; 15218 } 15219 15220 for (pos1 = strsep(¶ms1, ";"); pos1; pos1 = strsep(¶ms1, ";")) { 15221 char *value1 = pos1; 15222 char *name1 = strsep(&value1, "="); 15223 char *params2dup = NULL; 15224 int matched = 0; 15225 if (!value1) { 15226 value1 = ""; 15227 } 15228 /* Checkpoint reached. We have the name and value parsed for param1 15229 * We have to duplicate params2 each time through this loop 15230 * or else the inner loop below will not work properly. 15231 */ 15232 if (!zerolength2) { 15233 params2dup = ast_strdupa(params2); 15234 } 15235 for (pos2 = strsep(¶ms2dup, ";"); pos2; pos2 = strsep(¶ms2dup, ";")) { 15236 char *name2 = pos2; 15237 char *value2 = strchr(pos2, '='); 15238 if (!value2) { 15239 value2 = ""; 15240 } else { 15241 *value2++ = '\0'; 15242 } 15243 if (!strcasecmp(name1, name2)) { 15244 if (strcasecmp(value1, value2)) { 15245 goto fail; 15246 } else { 15247 matched = 1; 15248 break; 15249 } 15250 } 15251 } 15252 /* Check to see if the parameter is one of the 'must-match' parameters */ 15253 if (!strcasecmp(name1, "maddr")) { 15254 if (matched) { 15255 maddrmatch = 1; 15256 } else { 15257 goto fail; 15258 } 15259 } else if (!strcasecmp(name1, "ttl")) { 15260 if (matched) { 15261 ttlmatch = 1; 15262 } else { 15263 goto fail; 15264 } 15265 } else if (!strcasecmp(name1, "user")) { 15266 if (matched) { 15267 usermatch = 1; 15268 } else { 15269 goto fail; 15270 } 15271 } else if (!strcasecmp(name1, "method")) { 15272 if (matched) { 15273 methodmatch = 1; 15274 } else { 15275 goto fail; 15276 } 15277 } 15278 } 15279 15280 /* We've made it out of that horrible O(m*n) construct and there are no 15281 * failures yet. We're not done yet, though, because params2 could have 15282 * an maddr, ttl, user, or method header and params1 did not. 15283 */ 15284 for (pos2 = strsep(¶ms2, ";"); pos2; pos2 = strsep(¶ms2, ";")) { 15285 char *value2 = pos2; 15286 char *name2 = strsep(&value2, "="); 15287 if (!value2) { 15288 value2 = ""; 15289 } 15290 if ((!strcasecmp(name2, "maddr") && !maddrmatch) || 15291 (!strcasecmp(name2, "ttl") && !ttlmatch) || 15292 (!strcasecmp(name2, "user") && !usermatch) || 15293 (!strcasecmp(name2, "method") && !methodmatch)) { 15294 goto fail; 15295 } 15296 } 15297 return 0; 15298 15299 fail: 15300 return 1; 15301 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 4045 of file chan_sip.c.
References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_new_source(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), t38properties::direct, sip_pvt::flags, ast_frame::frametype, sip_pvt::initreq, INV_EARLY_MEDIA, sip_pvt::invitestate, sip_pvt::lastrtptx, sip_pvt::lock, LOG_WARNING, ast_channel::nativeformats, sip_pvt::pendinginvite, ast_channel::readformat, sip_pvt::rtp, SIP_OUTGOING, SIP_PAGE2_T38SUPPORT, SIP_PROGRESS_SENT, t38properties::state, ast_frame::subclass, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_REINVITE, ast_channel::tech_pvt, transmit_provisional_response(), transmit_reinvite_with_t38_sdp(), sip_pvt::udptl, sip_pvt::vrtp, and ast_channel::writeformat.
04046 { 04047 struct sip_pvt *p = ast->tech_pvt; 04048 int res = 0; 04049 04050 switch (frame->frametype) { 04051 case AST_FRAME_VOICE: 04052 if (!(frame->subclass & ast->nativeformats)) { 04053 char s1[512], s2[512], s3[512]; 04054 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 04055 frame->subclass, 04056 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 04057 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 04058 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 04059 ast->readformat, 04060 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 04061 ast->writeformat); 04062 return 0; 04063 } 04064 if (p) { 04065 ast_mutex_lock(&p->lock); 04066 if (p->t38.state == T38_ENABLED && !p->t38.direct) { 04067 /* drop frame, can't sent VOICE frames while in T.38 mode */ 04068 ast_mutex_unlock(&p->lock); 04069 break; 04070 } else if (p->rtp) { 04071 /* If channel is not up, activate early media session */ 04072 if ((ast->_state != AST_STATE_UP) && 04073 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04074 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04075 ast_rtp_new_source(p->rtp); 04076 if (!global_prematuremediafilter) { 04077 p->invitestate = INV_EARLY_MEDIA; 04078 transmit_provisional_response(p, "183 Session Progress", &p->initreq, 1); 04079 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 04080 } 04081 } 04082 p->lastrtptx = time(NULL); 04083 res = ast_rtp_write(p->rtp, frame); 04084 } 04085 ast_mutex_unlock(&p->lock); 04086 } 04087 break; 04088 case AST_FRAME_VIDEO: 04089 if (p) { 04090 ast_mutex_lock(&p->lock); 04091 if (p->vrtp) { 04092 /* Activate video early media */ 04093 if ((ast->_state != AST_STATE_UP) && 04094 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04095 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04096 p->invitestate = INV_EARLY_MEDIA; 04097 transmit_provisional_response(p, "183 Session Progress", &p->initreq, 1); 04098 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 04099 } 04100 p->lastrtptx = time(NULL); 04101 res = ast_rtp_write(p->vrtp, frame); 04102 } 04103 ast_mutex_unlock(&p->lock); 04104 } 04105 break; 04106 case AST_FRAME_IMAGE: 04107 return 0; 04108 break; 04109 case AST_FRAME_MODEM: 04110 if (p) { 04111 ast_mutex_lock(&p->lock); 04112 /* UDPTL requires two-way communication, so early media is not needed here. 04113 we simply forget the frames if we get modem frames before the bridge is up. 04114 Fax will re-transmit. 04115 */ 04116 if (ast->_state == AST_STATE_UP) { 04117 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->t38.state == T38_DISABLED) { 04118 if (!p->pendinginvite) { 04119 p->t38.state = T38_LOCAL_REINVITE; 04120 transmit_reinvite_with_t38_sdp(p); 04121 } 04122 } else if (p->t38.state == T38_ENABLED) { 04123 res = ast_udptl_write(p->udptl, frame); 04124 } 04125 } 04126 ast_mutex_unlock(&p->lock); 04127 } 04128 break; 04129 default: 04130 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 04131 return 0; 04132 } 04133 04134 return res; 04135 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 17453 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), sip_pvt::callid, sip_request::data, errno, find_call(), find_sip_method(), sip_pvt::flags, get_header(), handle_request(), sip_request::headers, sip_request::len, sip_request::lines, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, lws2sws(), sip_request::method, netlock, option_debug, 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, SIP_ACK, sip_debug_test_addr(), SIP_NO_HISTORY, SIP_PKT_DEBUG, sipsock, and transmit_response().
Referenced by do_monitor().
17454 { 17455 struct sip_request req; 17456 struct sockaddr_in sin = { 0, }; 17457 struct sip_pvt *p; 17458 int res; 17459 socklen_t len = sizeof(sin); 17460 int nounlock = 0; 17461 int recount = 0; 17462 int lockretry; 17463 17464 memset(&req, 0, sizeof(req)); 17465 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 17466 if (res < 0) { 17467 #if !defined(__FreeBSD__) 17468 if (errno == EAGAIN) 17469 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 17470 else 17471 #endif 17472 if (errno != ECONNREFUSED) 17473 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 17474 return 1; 17475 } 17476 if (option_debug && res == sizeof(req.data) - 1) 17477 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 17478 17479 req.data[res] = '\0'; 17480 req.len = res; 17481 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 17482 ast_set_flag(&req, SIP_PKT_DEBUG); 17483 if (pedanticsipchecking) 17484 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 17485 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 17486 ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); 17487 17488 if(parse_request(&req) == -1) /* Bad packet, can't parse */ 17489 return 1; 17490 17491 req.method = find_sip_method(req.rlPart1); 17492 17493 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 17494 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 17495 17496 if (req.headers < 2) /* Must have at least two headers */ 17497 return 1; 17498 17499 /* Process request, with netlock held, and with usual deadlock avoidance */ 17500 for (lockretry = 10; lockretry > 0; lockretry--) { 17501 ast_mutex_lock(&netlock); 17502 17503 /* Find the active SIP dialog or create a new one */ 17504 p = find_call(&req, &sin, req.method); /* returns p locked */ 17505 if (p == NULL) { 17506 if (option_debug) 17507 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 17508 ast_mutex_unlock(&netlock); 17509 return 1; 17510 } 17511 /* Go ahead and lock the owner if it has one -- we may need it */ 17512 /* because this is deadlock-prone, we need to try and unlock if failed */ 17513 if (!p->owner || !ast_channel_trylock(p->owner)) 17514 break; /* locking succeeded */ 17515 if (lockretry != 1) { 17516 ast_mutex_unlock(&p->lock); 17517 ast_mutex_unlock(&netlock); 17518 /* Sleep for a very short amount of time */ 17519 usleep(1); 17520 } 17521 } 17522 p->recv = sin; 17523 17524 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 17525 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 17526 17527 if (!lockretry) { 17528 if (!queue_request(p, &req)) { 17529 /* the request has been queued for later handling */ 17530 ast_mutex_unlock(&p->lock); 17531 ast_mutex_unlock(&netlock); 17532 return 1; 17533 } 17534 17535 /* This is unsafe, since p->owner is not locked. */ 17536 if (p->owner) 17537 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 ??? - ")); 17538 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 17539 if (req.method != SIP_ACK) 17540 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 17541 /* XXX We could add retry-after to make sure they come back */ 17542 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 17543 ast_mutex_unlock(&p->lock); 17544 ast_mutex_unlock(&netlock); 17545 return 1; 17546 } 17547 17548 /* if there are queued requests on this sip_pvt, process them first, so that everything is 17549 handled in order 17550 */ 17551 if (!AST_LIST_EMPTY(&p->request_queue)) { 17552 AST_SCHED_DEL(sched, p->request_queue_sched_id); 17553 process_request_queue(p, &recount, &nounlock); 17554 } 17555 17556 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 17557 /* Request failed */ 17558 if (option_debug) 17559 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 17560 } 17561 17562 if (p->owner && !nounlock) 17563 ast_channel_unlock(p->owner); 17564 ast_mutex_unlock(&p->lock); 17565 ast_mutex_unlock(&netlock); 17566 if (recount) 17567 ast_update_use_count(); 17568 17569 return 1; 17570 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 14108 of file chan_sip.c.
References ast_rtp_stop(), ast_udptl_stop(), sip_pvt::rtp, sip_pvt::udptl, and sip_pvt::vrtp.
Referenced by handle_request_bye(), handle_request_cancel(), handle_response(), and sip_hangup().
14109 { 14110 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14111 if (p->rtp) 14112 ast_rtp_stop(p->rtp); 14113 if (p->vrtp) 14114 ast_rtp_stop(p->vrtp); 14115 if (p->udptl) 14116 ast_udptl_stop(p->udptl); 14117 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 12162 of file chan_sip.c.
References subscription_types, cfsubscription_types::text, and type.
Referenced by __sip_show_channels(), and sip_show_channel().
12163 { 12164 int i; 12165 12166 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 12167 if (subscription_types[i].type == subtype) { 12168 return subscription_types[i].text; 12169 } 12170 } 12171 return subscription_types[0].text; 12172 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 7213 of file chan_sip.c.
References ast_log(), LOG_DEBUG, option_debug, T38FAX_RATE_12000, T38FAX_RATE_14400, T38FAX_RATE_2400, T38FAX_RATE_4800, T38FAX_RATE_7200, and T38FAX_RATE_9600.
Referenced by add_sdp().
07214 { 07215 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 07216 07217 if (maxrate & T38FAX_RATE_14400) { 07218 if (option_debug > 1) 07219 ast_log(LOG_DEBUG, "T38MaxBitRate 14400 found\n"); 07220 return 14400; 07221 } else if (maxrate & T38FAX_RATE_12000) { 07222 if (option_debug > 1) 07223 ast_log(LOG_DEBUG, "T38MaxBitRate 12000 found\n"); 07224 return 12000; 07225 } else if (maxrate & T38FAX_RATE_9600) { 07226 if (option_debug > 1) 07227 ast_log(LOG_DEBUG, "T38MaxBitRate 9600 found\n"); 07228 return 9600; 07229 } else if (maxrate & T38FAX_RATE_7200) { 07230 if (option_debug > 1) 07231 ast_log(LOG_DEBUG, "T38MaxBitRate 7200 found\n"); 07232 return 7200; 07233 } else if (maxrate & T38FAX_RATE_4800) { 07234 if (option_debug > 1) 07235 ast_log(LOG_DEBUG, "T38MaxBitRate 4800 found\n"); 07236 return 4800; 07237 } else if (maxrate & T38FAX_RATE_2400) { 07238 if (option_debug > 1) 07239 ast_log(LOG_DEBUG, "T38MaxBitRate 2400 found\n"); 07240 return 2400; 07241 } else { 07242 if (option_debug > 1) 07243 ast_log(LOG_DEBUG, "Strange, T38MaxBitRate NOT found in peers T38 SDP.\n"); 07244 return 0; 07245 } 07246 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static, read] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 18659 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_set_flag, ASTOBJ_INIT, default_prefs, sip_peer::flags, sip_peer::name, sip_peer::prefs, reg_source_db(), set_peer_defaults(), SIP_PAGE2_DYNAMIC, and SIP_PAGE2_SELFDESTRUCT.
Referenced by register_verify().
18660 { 18661 struct sip_peer *peer; 18662 18663 if (!(peer = ast_calloc(1, sizeof(*peer)))) 18664 return NULL; 18665 18666 apeerobjs++; 18667 ASTOBJ_INIT(peer); 18668 set_peer_defaults(peer); 18669 18670 ast_copy_string(peer->name, name, sizeof(peer->name)); 18671 18672 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 18673 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 18674 peer->prefs = default_prefs; 18675 reg_source_db(peer); 18676 18677 return peer; 18678 }
static void temp_pvt_cleanup | ( | void * | data | ) | [static] |
Definition at line 6982 of file chan_sip.c.
References ast_string_field_free_memory, and free.
06983 { 06984 struct sip_pvt *p = data; 06985 06986 ast_string_field_free_memory(p); 06987 06988 free(data); 06989 }
static void temp_pvt_init | ( | void | ) | [static] |
static char * transfermode2str | ( | enum transfermodes | mode | ) | [static] |
Convert transfer mode to text string.
Definition at line 11163 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().
11164 { 11165 if (mode == TRANSFER_OPENFORALL) 11166 return "open"; 11167 else if (mode == TRANSFER_CLOSED) 11168 return "closed"; 11169 return "strict"; 11170 }
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 9803 of file chan_sip.c.
References ast_dynamic_str_thread_get(), ast_dynamic_str_thread_set(), AST_DYNSTR_BUILD_FAILED, ast_skip_blanks(), ast_strlen_zero(), ast_test_flag, check_auth_buf, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), sip_pvt::initreq, keys, sip_pvt::randdata, s, set_nonce_randdata(), SIP_PKT_IGNORE, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, ast_dynamic_str::str, strsep(), transmit_response(), and transmit_response_with_auth().
Referenced by handle_request_invite(), handle_request_subscribe(), and register_verify().
09804 { 09805 /* We have to emulate EXACTLY what we'd get with a good peer 09806 * and a bad password, or else we leak information. */ 09807 const char *response = "407 Proxy Authentication Required"; 09808 const char *reqheader = "Proxy-Authorization"; 09809 const char *respheader = "Proxy-Authenticate"; 09810 const char *authtoken; 09811 struct ast_dynamic_str *buf; 09812 char *c; 09813 09814 /* table of recognised keywords, and their value in the digest */ 09815 enum keys { K_NONCE, K_LAST }; 09816 struct x { 09817 const char *key; 09818 const char *s; 09819 } *i, keys[] = { 09820 [K_NONCE] = { "nonce=", "" }, 09821 [K_LAST] = { NULL, NULL} 09822 }; 09823 09824 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 09825 response = "401 Unauthorized"; 09826 reqheader = "Authorization"; 09827 respheader = "WWW-Authenticate"; 09828 } 09829 authtoken = get_header(req, reqheader); 09830 if (ast_test_flag(req, SIP_PKT_IGNORE) && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 09831 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 09832 * information */ 09833 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 09834 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 09835 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09836 return; 09837 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 09838 /* We have no auth, so issue challenge and request authentication */ 09839 set_nonce_randdata(p, 1); 09840 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 09841 /* Schedule auto destroy in 32 seconds */ 09842 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09843 return; 09844 } 09845 09846 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 09847 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09848 return; 09849 } 09850 09851 /* Make a copy of the response and parse it */ 09852 if (ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) { 09853 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09854 return; 09855 } 09856 09857 c = buf->str; 09858 09859 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 09860 for (i = keys; i->key != NULL; i++) { 09861 const char *separator = ","; /* default */ 09862 09863 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 09864 continue; 09865 } 09866 /* Found. Skip keyword, take text in quotes or up to the separator. */ 09867 c += strlen(i->key); 09868 if (*c == '"') { /* in quotes. Skip first and look for last */ 09869 c++; 09870 separator = "\""; 09871 } 09872 i->s = c; 09873 strsep(&c, separator); 09874 break; 09875 } 09876 if (i->key == NULL) { /* not found, jump after space or comma */ 09877 strsep(&c, " ,"); 09878 } 09879 } 09880 09881 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 09882 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { 09883 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 09884 set_nonce_randdata(p, 1); 09885 } 09886 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 09887 09888 /* Schedule auto destroy in 32 seconds */ 09889 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09890 } else { 09891 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09892 } 09893 }
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 8766 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
08767 { 08768 struct sip_request req; 08769 08770 reqprep(&req, p, SIP_INFO, 0, 1); 08771 add_digit(&req, digit, duration); 08772 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08773 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 8776 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
08777 { 08778 struct sip_request req; 08779 08780 reqprep(&req, p, SIP_INFO, 0, 1); 08781 add_vidupdate(&req); 08782 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08783 }
static int transmit_invite | ( | struct sip_pvt * | p, | |
int | sipmethod, | |||
int | sdp, | |||
int | init | |||
) | [static] |
Build REFER/INVITE/OPTIONS message and transmit it.
Definition at line 8005 of file chan_sip.c.
References add_header(), add_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), ast_channel_lock, ast_channel_unlock, 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, build_via(), sip_request::content, sip_request::header, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::invite_branch, sip_pvt::lastinvite, LOG_DEBUG, LOG_WARNING, sip_request::method, sip_pvt::ocseq, sip_pvt::offered_media, option_debug, 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(), SIP_REFER, SIPBUFSIZE, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_REINVITE, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.
Referenced by do_proxy_auth(), sip_call(), and sip_poke_peer().
08006 { 08007 struct sip_request req; 08008 08009 req.method = sipmethod; 08010 if (init) { /* Seems like init always is 2 */ 08011 /* Bump branch even on initial requests */ 08012 p->branch ^= ast_random(); 08013 p->invite_branch = p->branch; 08014 build_via(p); 08015 if (init > 1) 08016 initreqprep(&req, p, sipmethod); 08017 else 08018 reqprep(&req, p, sipmethod, 0, 0); 08019 } else 08020 reqprep(&req, p, sipmethod, 0, 1); 08021 08022 if (p->options && p->options->auth) 08023 add_header(&req, p->options->authheader, p->options->auth); 08024 append_date(&req); 08025 if (sipmethod == SIP_REFER) { /* Call transfer */ 08026 if (p->refer) { 08027 char buf[SIPBUFSIZE]; 08028 if (!ast_strlen_zero(p->refer->refer_to)) 08029 add_header(&req, "Refer-To", p->refer->refer_to); 08030 if (!ast_strlen_zero(p->refer->referred_by)) { 08031 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 08032 add_header(&req, "Referred-By", buf); 08033 } 08034 } 08035 } 08036 /* This new INVITE is part of an attended transfer. Make sure that the 08037 other end knows and replace the current call with this new call */ 08038 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 08039 add_header(&req, "Replaces", p->options->replaces); 08040 add_header(&req, "Require", "replaces"); 08041 } 08042 08043 add_header(&req, "Allow", ALLOWED_METHODS); 08044 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 08045 if (p->options && p->options->addsipheaders && p->owner) { 08046 struct ast_channel *chan = p->owner; /* The owner channel */ 08047 struct varshead *headp; 08048 08049 ast_channel_lock(chan); 08050 08051 headp = &chan->varshead; 08052 08053 if (!headp) 08054 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 08055 else { 08056 const struct ast_var_t *current; 08057 AST_LIST_TRAVERSE(headp, current, entries) { 08058 /* SIPADDHEADER: Add SIP header to outgoing call */ 08059 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 08060 char *content, *end; 08061 const char *header = ast_var_value(current); 08062 char *headdup = ast_strdupa(header); 08063 08064 /* Strip of the starting " (if it's there) */ 08065 if (*headdup == '"') 08066 headdup++; 08067 if ((content = strchr(headdup, ':'))) { 08068 *content++ = '\0'; 08069 content = ast_skip_blanks(content); /* Skip white space */ 08070 /* Strip the ending " (if it's there) */ 08071 end = content + strlen(content) -1; 08072 if (*end == '"') 08073 *end = '\0'; 08074 08075 add_header(&req, headdup, content); 08076 if (sipdebug) 08077 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 08078 } 08079 } 08080 } 08081 } 08082 08083 ast_channel_unlock(chan); 08084 } 08085 if (sdp) { 08086 memset(p->offered_media, 0, sizeof(p->offered_media)); 08087 if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) { 08088 ast_udptl_offered_from_local(p->udptl, 1); 08089 if (option_debug) 08090 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 08091 add_sdp(&req, p, 0, 1); 08092 } else if (p->rtp) 08093 add_sdp(&req, p, 1, 0); 08094 } 08095 08096 if (!p->initreq.headers || init > 2) 08097 initialize_initreq(p, &req); 08098 p->lastinvite = p->ocseq; 08099 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 08100 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 8675 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().
08676 { 08677 struct sip_request req; 08678 08679 reqprep(&req, p, SIP_MESSAGE, 0, 1); 08680 add_text(&req, text); 08681 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08682 }
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 8290 of file chan_sip.c.
References add_content(), add_header(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_test_flag, sip_pvt::expiry, sip_pvt::flags, sip_pvt::fromdomain, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), LOG_WARNING, sip_pvt::ocseq, sip_pvt::ourip, ourport, S_OR, send_request(), SIP_NOTIFY, SIP_PAGE2_BUGGY_MWI, STANDARD_SIP_PORT, sip_pvt::subscribed, t, and XMIT_RELIABLE.
Referenced by sip_send_mwi_to_peer().
08291 { 08292 struct sip_request req; 08293 char tmp[500]; 08294 char *t = tmp; 08295 size_t maxbytes = sizeof(tmp); 08296 08297 initreqprep(&req, p, SIP_NOTIFY); 08298 add_header(&req, "Event", "message-summary"); 08299 add_header(&req, "Content-Type", default_notifymime); 08300 08301 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 08302 /* if we listen to non-standard SIP port we have to specify the SIP port 08303 in the URI, except domains are used - in this case the SRV records should be 08304 used to redirect the client to the non-standard SIP port */ 08305 if ((ourport != STANDARD_SIP_PORT) && ast_strlen_zero(p->fromdomain)) { 08306 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s:%d\r\n", 08307 S_OR(vmexten, default_vmexten), ast_inet_ntoa(p->ourip), ourport); 08308 } else { 08309 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 08310 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 08311 } 08312 /* Cisco has a bug in the SIP stack where it can't accept the 08313 (0/0) notification. This can temporarily be disabled in 08314 sip.conf with the "buggymwi" option */ 08315 ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d%s\r\n", newmsgs, oldmsgs, (ast_test_flag(&p->flags[1], SIP_PAGE2_BUGGY_MWI) ? "" : " (0/0)")); 08316 08317 if (p->subscribed) { 08318 if (p->expiry) 08319 add_header(&req, "Subscription-State", "active"); 08320 else /* Expired */ 08321 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 08322 } 08323 08324 if (t > tmp + sizeof(tmp)) 08325 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 08326 08327 add_content(&req, tmp); 08328 08329 if (!p->initreq.headers) 08330 initialize_initreq(p, &req); 08331 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08332 }
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 8343 of file chan_sip.c.
References add_content(), add_header(), ALLOWED_METHODS, sip_request::headers, initialize_initreq(), sip_pvt::initreq, 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().
08344 { 08345 struct sip_request req; 08346 char tmp[SIPBUFSIZE/2]; 08347 08348 reqprep(&req, p, SIP_NOTIFY, 0, 1); 08349 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 08350 add_header(&req, "Event", tmp); 08351 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 08352 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 08353 add_header(&req, "Allow", ALLOWED_METHODS); 08354 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 08355 08356 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 08357 add_content(&req, tmp); 08358 08359 if (!p->initreq.headers) 08360 initialize_initreq(p, &req); 08361 08362 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08363 }
static int transmit_provisional_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req, | |||
int | with_sdp | |||
) | [static] |
Definition at line 7117 of file chan_sip.c.
References sip_pvt::last_provisional, transmit_response(), transmit_response_with_sdp(), update_provisional_keepalive(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite(), sip_indicate(), and sip_write().
07118 { 07119 int res; 07120 07121 if (!(res = with_sdp ? transmit_response_with_sdp(p, msg, req, XMIT_UNRELIABLE) : transmit_response(p, msg, req))) { 07122 p->last_provisional = msg; 07123 update_provisional_keepalive(p, with_sdp); 07124 } 07125 07126 return res; 07127 }
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 8696 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_copy_string(), 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_DEBUG, LOG_NOTICE, sip_pvt::ocseq, option_debug, 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(), sipdebug, sip_refer::status, SUPPORTED_EXTENSIONS, sip_pvt::tag, sip_pvt::theirtag, and XMIT_RELIABLE.
Referenced by sip_transfer().
08697 { 08698 struct sip_request req = { 08699 .headers = 0, 08700 }; 08701 char from[256]; 08702 const char *of; 08703 char *c; 08704 char referto[256]; 08705 char *ttag, *ftag; 08706 char *theirtag = ast_strdupa(p->theirtag); 08707 08708 if (option_debug || sipdebug) 08709 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 08710 08711 /* Are we transfering an inbound or outbound call ? */ 08712 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 08713 of = get_header(&p->initreq, "To"); 08714 ttag = theirtag; 08715 ftag = p->tag; 08716 } else { 08717 of = get_header(&p->initreq, "From"); 08718 ftag = theirtag; 08719 ttag = p->tag; 08720 } 08721 08722 ast_copy_string(from, of, sizeof(from)); 08723 of = get_in_brackets(from); 08724 ast_string_field_set(p, from, of); 08725 if (strncasecmp(of, "sip:", 4)) 08726 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 08727 else 08728 of += 4; 08729 /* Get just the username part */ 08730 if ((c = strchr(dest, '@'))) 08731 c = NULL; 08732 else if ((c = strchr(of, '@'))) 08733 *c++ = '\0'; 08734 if (c) 08735 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 08736 else 08737 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 08738 08739 /* save in case we get 407 challenge */ 08740 sip_refer_allocate(p); 08741 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 08742 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 08743 p->refer->status = REFER_SENT; /* Set refer status */ 08744 08745 reqprep(&req, p, SIP_REFER, 0, 1); 08746 08747 add_header(&req, "Refer-To", referto); 08748 add_header(&req, "Allow", ALLOWED_METHODS); 08749 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 08750 if (!ast_strlen_zero(p->our_contact)) 08751 add_header(&req, "Referred-By", p->our_contact); 08752 08753 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08754 /* We should propably wait for a NOTIFY here until we ack the transfer */ 08755 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 08756 08757 /*! \todo In theory, we should hang around and wait for a reply, before 08758 returning to the dial plan here. Don't know really how that would 08759 affect the transfer() app or the pbx, but, well, to make this 08760 useful we should have a STATUS code on transfer(). 08761 */ 08762 }
static int transmit_register | ( | struct sip_registry * | r, | |
int | sipmethod, | |||
const char * | auth, | |||
const char * | authheader | |||
) | [static] |
Transmit register to SIP proxy or UA.
Definition at line 8468 of file chan_sip.c.
References __ourip, add_header(), append_history, ast_log(), ast_random(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, sip_pvt::authname, sip_registry::authuser, bindaddr, sip_pvt::branch, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_pvt::callid, sip_registry::callid, sip_registry::callid_valid, sip_registry::contact, create_addr(), DEFAULT_MAX_FORWARDS, sip_registry::domain, exten, FALSE, sip_pvt::flags, sip_pvt::fromdomain, sip_pvt::fromuser, sip_request::headers, sip_registry::hostname, init_req(), initialize_initreq(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), sip_registry::md5secret, sip_registry::needdns, sip_pvt::nonce, sip_registry::nonce, sip_pvt::noncecount, sip_registry::noncecount, sip_pvt::ocseq, sip_registry::ocseq, sip_registry::opaque, sip_pvt::opaque, option_debug, sip_pvt::our_contact, sip_pvt::ourip, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, 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, sip_registry::regstate, sip_pvt::sa, sip_registry::secret, send_request(), sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_NO_HISTORY, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sipdebug, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, sip_registry::timeout, sip_pvt::tohost, TRUE, sip_pvt::uri, sip_registry::us, username, sip_registry::username, sip_pvt::via, and XMIT_CRITICAL.
Referenced by __sip_do_register(), do_register_auth(), and sip_reg_timeout().
08469 { 08470 struct sip_request req; 08471 char from[256]; 08472 char to[256]; 08473 char tmp[80]; 08474 char addr[80]; 08475 struct sip_pvt *p; 08476 char *fromdomain; 08477 08478 /* exit if we are already in process with this registrar ?*/ 08479 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 08480 if (r) { 08481 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 08482 } 08483 return 0; 08484 } 08485 08486 if (r->call) { /* We have a registration */ 08487 if (!auth) { 08488 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 08489 return 0; 08490 } else { 08491 p = r->call; 08492 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 08493 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 08494 } 08495 } else { 08496 /* Build callid for registration if we haven't registered before */ 08497 if (!r->callid_valid) { 08498 build_callid_registry(r, __ourip, default_fromdomain); 08499 r->callid_valid = TRUE; 08500 } 08501 /* Allocate SIP packet for registration */ 08502 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 08503 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 08504 return 0; 08505 } 08506 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 08507 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 08508 /* Find address to hostname if we haven't tried to connect 08509 * or a connection error has occurred */ 08510 if (create_addr(p, r->hostname, r->needdns ? NULL : &r->us)) { 08511 /* we have what we hope is a temporary network error, 08512 * probably DNS. We need to reschedule a registration try */ 08513 sip_destroy(p); 08514 08515 if (r->timeout > -1) 08516 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 08517 else 08518 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); 08519 08520 AST_SCHED_DEL(sched, r->timeout); 08521 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 08522 r->regattempts++; 08523 return 0; 08524 } 08525 if (r->needdns) { 08526 memcpy(&r->us, &p->sa, sizeof(r->us)); 08527 } 08528 r->needdns = FALSE; 08529 /* Copy back Call-ID in case create_addr changed it */ 08530 ast_string_field_set(r, callid, p->callid); 08531 if (r->portno) { 08532 p->sa.sin_port = htons(r->portno); 08533 p->recv.sin_port = htons(r->portno); 08534 } else /* Set registry port to the port set from the peer definition/srv or default */ 08535 r->portno = ntohs(p->sa.sin_port); 08536 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 08537 r->call=p; /* Save pointer to SIP packet */ 08538 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 08539 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 08540 ast_string_field_set(p, peersecret, r->secret); 08541 if (!ast_strlen_zero(r->md5secret)) 08542 ast_string_field_set(p, peermd5secret, r->md5secret); 08543 /* User name in this realm 08544 - if authuser is set, use that, otherwise use username */ 08545 if (!ast_strlen_zero(r->authuser)) { 08546 ast_string_field_set(p, peername, r->authuser); 08547 ast_string_field_set(p, authname, r->authuser); 08548 } else if (!ast_strlen_zero(r->username)) { 08549 ast_string_field_set(p, peername, r->username); 08550 ast_string_field_set(p, authname, r->username); 08551 ast_string_field_set(p, fromuser, r->username); 08552 } 08553 if (!ast_strlen_zero(r->username)) 08554 ast_string_field_set(p, username, r->username); 08555 /* Save extension in packet */ 08556 ast_string_field_set(p, exten, r->contact); 08557 08558 /* 08559 check which address we should use in our contact header 08560 based on whether the remote host is on the external or 08561 internal network so we can register through nat 08562 */ 08563 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 08564 p->ourip = bindaddr.sin_addr; 08565 build_contact(p); 08566 } 08567 08568 /* set up a timeout */ 08569 if (auth == NULL) { 08570 if (r->timeout > -1) 08571 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 08572 AST_SCHED_DEL(sched, r->timeout); 08573 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 08574 if (option_debug) 08575 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 08576 } 08577 08578 if ((fromdomain = strchr(r->username, '@'))) { 08579 /* the domain name is just behind '@' */ 08580 fromdomain++ ; 08581 /* We have a domain in the username for registration */ 08582 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 08583 if (!ast_strlen_zero(p->theirtag)) 08584 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 08585 else 08586 snprintf(to, sizeof(to), "<sip:%s>", r->username); 08587 08588 /* If the registration username contains '@', then the domain should be used as 08589 the equivalent of "fromdomain" for the registration */ 08590 if (ast_strlen_zero(p->fromdomain)) { 08591 ast_string_field_set(p, fromdomain, fromdomain); 08592 } 08593 } else { 08594 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 08595 if (!ast_strlen_zero(p->theirtag)) 08596 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 08597 else 08598 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 08599 } 08600 08601 /* Fromdomain is what we are registering to, regardless of actual 08602 host name from SRV */ 08603 if (!ast_strlen_zero(p->fromdomain)) { 08604 if (r->portno && r->portno != STANDARD_SIP_PORT) 08605 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 08606 else 08607 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 08608 } else { 08609 if (r->portno && r->portno != STANDARD_SIP_PORT) 08610 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 08611 else 08612 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 08613 } 08614 ast_string_field_set(p, uri, addr); 08615 08616 p->branch ^= ast_random(); 08617 08618 init_req(&req, sipmethod, addr); 08619 08620 /* Add to CSEQ */ 08621 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 08622 p->ocseq = r->ocseq; 08623 08624 build_via(p); 08625 add_header(&req, "Via", p->via); 08626 add_header(&req, "From", from); 08627 add_header(&req, "To", to); 08628 add_header(&req, "Call-ID", p->callid); 08629 add_header(&req, "CSeq", tmp); 08630 if (!ast_strlen_zero(global_useragent)) 08631 add_header(&req, "User-Agent", global_useragent); 08632 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 08633 08634 08635 if (auth) /* Add auth header */ 08636 add_header(&req, authheader, auth); 08637 else if (!ast_strlen_zero(r->nonce)) { 08638 char digest[1024]; 08639 08640 /* We have auth data to reuse, build a digest header! */ 08641 if (sipdebug) 08642 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 08643 ast_string_field_set(p, realm, r->realm); 08644 ast_string_field_set(p, nonce, r->nonce); 08645 ast_string_field_set(p, domain, r->domain); 08646 ast_string_field_set(p, opaque, r->opaque); 08647 ast_string_field_set(p, qop, r->qop); 08648 r->noncecount++; 08649 p->noncecount = r->noncecount; 08650 08651 memset(digest,0,sizeof(digest)); 08652 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 08653 add_header(&req, "Authorization", digest); 08654 else 08655 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 08656 08657 } 08658 08659 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 08660 add_header(&req, "Expires", tmp); 08661 add_header(&req, "Contact", p->our_contact); 08662 add_header(&req, "Event", "registration"); 08663 08664 initialize_initreq(p, &req); 08665 if (sip_debug_test_pvt(p)) 08666 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 08667 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 08668 r->regattempts++; /* Another attempt */ 08669 if (option_debug > 3) 08670 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 08671 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 08672 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 7713 of file chan_sip.c.
References add_header(), add_sdp(), ALLOWED_METHODS, append_history, ast_set_flag, ast_test_flag, sip_pvt::flags, initialize_initreq(), sip_pvt::lastinvite, sip_pvt::ocseq, sip_pvt::offered_media, reqprep(), send_request(), SIP_INVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, and XMIT_CRITICAL.
Referenced by check_pendings(), handle_response_invite(), and sip_set_rtp_peer().
07714 { 07715 struct sip_request req; 07716 07717 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 07718 07719 add_header(&req, "Allow", ALLOWED_METHODS); 07720 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07721 if (sipdebug) 07722 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 07723 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07724 append_history(p, "ReInv", "Re-invite sent"); 07725 memset(p->offered_media, 0, sizeof(p->offered_media)); 07726 add_sdp(&req, p, 1, 0); 07727 /* Use this as the basis */ 07728 initialize_initreq(p, &req); 07729 p->lastinvite = p->ocseq; 07730 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 07731 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07732 }
static int transmit_reinvite_with_t38_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path.
Definition at line 7738 of file chan_sip.c.
References add_header(), add_sdp(), ALLOWED_METHODS, ast_set_flag, ast_test_flag, sip_pvt::flags, initialize_initreq(), sip_pvt::lastinvite, sip_pvt::ocseq, sip_pvt::offered_media, reqprep(), send_request(), SIP_INVITE, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, and XMIT_CRITICAL.
Referenced by sip_handle_t38_reinvite(), sip_read(), sip_set_udptl_peer(), and sip_write().
07739 { 07740 struct sip_request req; 07741 07742 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 07743 07744 add_header(&req, "Allow", ALLOWED_METHODS); 07745 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07746 if (sipdebug) 07747 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 07748 memset(p->offered_media, 0, sizeof(p->offered_media)); 07749 add_sdp(&req, p, 0, 1); 07750 07751 /* Use this as the basis */ 07752 initialize_initreq(p, &req); 07753 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 07754 p->lastinvite = p->ocseq; 07755 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07756 }
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 8788 of file chan_sip.c.
References INV_CONFIRMED, sip_pvt::invitestate, sip_pvt::ocseq, reqprep(), send_request(), and SIP_ACK.
Referenced by check_pendings(), handle_response(), handle_response_invite(), and sip_hangup().
08789 { 08790 struct sip_request resp; 08791 08792 if (sipmethod == SIP_ACK) 08793 p->invitestate = INV_CONFIRMED; 08794 08795 reqprep(&resp, p, sipmethod, seqno, newbranch); 08796 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 08797 }
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 8800 of file chan_sip.c.
References add_header(), ast_cause2str(), ast_log(), ast_strlen_zero(), sip_invite_param::auth_type, build_reply_digest(), sip_pvt::callid, sip_pvt::hangupcause, LOG_WARNING, sip_pvt::ocseq, sip_pvt::options, PROXY_AUTH, sip_pvt::realm, reqprep(), send_request(), SIP_BYE, and WWW_AUTH.
Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().
08801 { 08802 struct sip_request resp; 08803 08804 reqprep(&resp, p, sipmethod, seqno, newbranch); 08805 if (!ast_strlen_zero(p->realm)) { 08806 char digest[1024]; 08807 08808 memset(digest, 0, sizeof(digest)); 08809 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 08810 if (p->options && p->options->auth_type == PROXY_AUTH) 08811 add_header(&resp, "Proxy-Authorization", digest); 08812 else if (p->options && p->options->auth_type == WWW_AUTH) 08813 add_header(&resp, "Authorization", digest); 08814 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 08815 add_header(&resp, "Proxy-Authorization", digest); 08816 } else 08817 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 08818 } 08819 /* If we are hanging up and know a cause for that, send it in clear text to make 08820 debugging easier. */ 08821 if (sipmethod == SIP_BYE) { 08822 char buf[10]; 08823 08824 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->hangupcause)); 08825 snprintf(buf, sizeof(buf), "%d", p->hangupcause); 08826 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 08827 } 08828 08829 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 08830 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 7043 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
Referenced by handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_refer(), handle_request_subscribe(), receive_message(), register_verify(), send_provisional_keepalive_full(), sip_indicate(), sip_park_thread(), sipsock_read(), transmit_fake_auth_response(), and transmit_provisional_response().
07044 { 07045 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 07046 }
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 7061 of file chan_sip.c.
References __transmit_response(), and XMIT_CRITICAL.
Referenced by handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_subscribe(), sip_handle_t38_reinvite(), sip_hangup(), sip_indicate(), and sip_sipredirect().
07062 { 07063 return __transmit_response(p, msg, req, XMIT_CRITICAL); 07064 }
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 6992 of file chan_sip.c.
References __ourip, __transmit_response(), ast_copy_flags, ast_log(), ast_random(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_reset_all, ast_string_field_set, ast_test_flag, ast_threadstorage_get(), sip_pvt::branch, build_via(), check_via(), do_setnat(), sip_pvt::flags, sip_pvt::fromdomain, INITIAL_CSEQ, LOG_NOTICE, make_our_tag(), sip_pvt::method, sip_pvt::ocseq, sip_pvt::ourip, sip_pvt::recv, sip_pvt::sa, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, sip_pvt::tag, ts_temp_pvt, and XMIT_UNRELIABLE.
Referenced by find_call().
06993 { 06994 struct sip_pvt *p = NULL; 06995 06996 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 06997 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 06998 return -1; 06999 } 07000 07001 /* if the structure was just allocated, initialize it */ 07002 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 07003 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 07004 if (ast_string_field_init(p, 512)) 07005 return -1; 07006 } 07007 07008 /* Initialize the bare minimum */ 07009 p->method = intended_method; 07010 07011 if (sin) { 07012 p->sa = *sin; 07013 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07014 p->ourip = __ourip; 07015 } else 07016 p->ourip = __ourip; 07017 07018 p->branch = ast_random(); 07019 make_our_tag(p->tag, sizeof(p->tag)); 07020 p->ocseq = INITIAL_CSEQ; 07021 07022 if (useglobal_nat && sin) { 07023 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 07024 p->recv = *sin; 07025 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 07026 } 07027 check_via(p, req); 07028 07029 ast_string_field_set(p, fromdomain, default_fromdomain); 07030 build_via(p); 07031 ast_string_field_set(p, callid, callid); 07032 07033 /* Use this temporary pvt structure to send the message */ 07034 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 07035 07036 /* Free the string fields, but not the pool space */ 07037 ast_string_field_reset_all(p); 07038 07039 return 0; 07040 }
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 7088 of file chan_sip.c.
References add_header(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
07089 { 07090 struct sip_request resp; 07091 respprep(&resp, p, msg, req); 07092 add_header(&resp, "Accept", "application/sdp"); 07093 return send_response(p, &resp, reliable, 0); 07094 }
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 7097 of file chan_sip.c.
References add_header(), 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().
07098 { 07099 struct sip_request resp; 07100 char tmp[512]; 07101 int seqno = 0; 07102 07103 if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) { 07104 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 07105 return -1; 07106 } 07107 /* Stale means that they sent us correct authentication, but 07108 based it on an old challenge (nonce) */ 07109 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 07110 respprep(&resp, p, msg, req); 07111 add_header(&resp, header, tmp); 07112 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 07113 return send_response(p, &resp, reliable, seqno); 07114 }
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 7079 of file chan_sip.c.
References append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
07080 { 07081 struct sip_request resp; 07082 respprep(&resp, p, msg, req); 07083 append_date(&resp); 07084 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 07085 }
static int transmit_response_with_sdp | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req, | |||
enum xmittype | reliable | |||
) | [static] |
Used for 200 OK and 183 early media.
Definition at line 7637 of file chan_sip.c.
References add_sdp(), ast_log(), ast_rtp_codec_setpref(), ast_test_flag, sip_pvt::autoframing, sip_pvt::callid, sip_pvt::flags, get_header(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, sip_pvt::pendinginvite, sip_pvt::prefs, respprep(), sip_pvt::rtp, send_response(), SIP_OUTGOING, t38properties::state, sip_pvt::t38, T38_ENABLED, T38_PEER_DIRECT, and try_suggested_sip_codec().
Referenced by handle_invite_replaces(), handle_request_invite(), send_provisional_keepalive_full(), sip_answer(), and transmit_provisional_response().
07638 { 07639 struct sip_request resp; 07640 int seqno; 07641 if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) { 07642 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 07643 return -1; 07644 } 07645 respprep(&resp, p, msg, req); 07646 if (p->rtp) { 07647 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07648 if (option_debug) 07649 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 07650 ast_rtp_codec_setpref(p->rtp, &p->prefs); 07651 } 07652 try_suggested_sip_codec(p); 07653 if (p->t38.state == T38_PEER_DIRECT || p->t38.state == T38_ENABLED) { 07654 p->t38.state = T38_ENABLED; 07655 add_sdp(&resp, p, 1, 1); 07656 } else { 07657 add_sdp(&resp, p, 1, 0); 07658 } 07659 } else 07660 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 07661 if (reliable && !p->pendinginvite) 07662 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 07663 return send_response(p, &resp, reliable, seqno); 07664 }
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 7598 of file chan_sip.c.
References add_sdp(), ast_log(), 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_handle_t38_reinvite().
07599 { 07600 struct sip_request resp; 07601 int seqno; 07602 07603 if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) { 07604 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 07605 return -1; 07606 } 07607 respprep(&resp, p, msg, req); 07608 if (p->udptl) { 07609 add_sdp(&resp, p, 0, 1); 07610 } else 07611 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 07612 if (retrans && !p->pendinginvite) 07613 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 07614 return send_response(p, &resp, retrans, seqno); 07615 }
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 7049 of file chan_sip.c.
References add_header(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
07050 { 07051 struct sip_request resp; 07052 respprep(&resp, p, msg, req); 07053 append_date(&resp); 07054 add_header(&resp, "Unsupported", unsupported); 07055 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 07056 }
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 8335 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().
08336 { 08337 if (!p->initreq.headers) /* Initialize first request before sending */ 08338 initialize_initreq(p, req); 08339 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 08340 }
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 8103 of file chan_sip.c.
References add_content(), add_header(), ast_build_string(), ast_copy_string(), 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, sip_pvt::context, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, cfsubscription_types::event, sip_pvt::expiry, sip_pvt::exten, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, cfsubscription_types::mediatype, NONE, sip_pvt::ocseq, sip_pvt::pendinginvite, PIDF_XML, reqprep(), send_request(), SIP_NOTIFY, strsep(), sip_pvt::subscribed, t, XMIT_RELIABLE, and XPIDF_XML.
Referenced by __sip_autodestruct(), handle_request_subscribe(), and notify_extenstate_update().
08104 { 08105 char tmp[4000], from[256], to[256]; 08106 char *t = tmp, *c, *mfrom, *mto; 08107 size_t maxbytes = sizeof(tmp); 08108 struct sip_request req; 08109 char hint[AST_MAX_EXTENSION]; 08110 char *statestring = "terminated"; 08111 const struct cfsubscription_types *subscriptiontype; 08112 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 08113 char *pidfstate = "--"; 08114 char *pidfnote= "Ready"; 08115 08116 memset(from, 0, sizeof(from)); 08117 memset(to, 0, sizeof(to)); 08118 memset(tmp, 0, sizeof(tmp)); 08119 08120 switch (state) { 08121 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 08122 statestring = (global_notifyringing) ? "early" : "confirmed"; 08123 local_state = NOTIFY_INUSE; 08124 pidfstate = "busy"; 08125 pidfnote = "Ringing"; 08126 break; 08127 case AST_EXTENSION_RINGING: 08128 statestring = "early"; 08129 local_state = NOTIFY_INUSE; 08130 pidfstate = "busy"; 08131 pidfnote = "Ringing"; 08132 break; 08133 case AST_EXTENSION_INUSE: 08134 statestring = "confirmed"; 08135 local_state = NOTIFY_INUSE; 08136 pidfstate = "busy"; 08137 pidfnote = "On the phone"; 08138 break; 08139 case AST_EXTENSION_BUSY: 08140 statestring = "confirmed"; 08141 local_state = NOTIFY_CLOSED; 08142 pidfstate = "busy"; 08143 pidfnote = "On the phone"; 08144 break; 08145 case AST_EXTENSION_UNAVAILABLE: 08146 statestring = "terminated"; 08147 local_state = NOTIFY_CLOSED; 08148 pidfstate = "away"; 08149 pidfnote = "Unavailable"; 08150 break; 08151 case AST_EXTENSION_ONHOLD: 08152 statestring = "confirmed"; 08153 local_state = NOTIFY_CLOSED; 08154 pidfstate = "busy"; 08155 pidfnote = "On Hold"; 08156 break; 08157 case AST_EXTENSION_NOT_INUSE: 08158 default: 08159 /* Default setting */ 08160 break; 08161 } 08162 08163 subscriptiontype = find_subscription_type(p->subscribed); 08164 08165 /* Check which device/devices we are watching and if they are registered */ 08166 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 08167 char *hint2 = hint, *individual_hint = NULL; 08168 int hint_count = 0, unavailable_count = 0; 08169 08170 while ((individual_hint = strsep(&hint2, "&"))) { 08171 hint_count++; 08172 08173 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 08174 unavailable_count++; 08175 } 08176 08177 /* If none of the hinted devices are registered, we will 08178 * override notification and show no availability. 08179 */ 08180 if (hint_count > 0 && hint_count == unavailable_count) { 08181 local_state = NOTIFY_CLOSED; 08182 pidfstate = "away"; 08183 pidfnote = "Not online"; 08184 } 08185 } 08186 08187 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 08188 c = get_in_brackets(from); 08189 if (strncasecmp(c, "sip:", 4)) { 08190 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 08191 return -1; 08192 } 08193 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 08194 08195 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 08196 c = get_in_brackets(to); 08197 if (strncasecmp(c, "sip:", 4)) { 08198 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 08199 return -1; 08200 } 08201 mto = strsep(&c, ";"); /* trim ; and beyond */ 08202 08203 reqprep(&req, p, SIP_NOTIFY, 0, 1); 08204 08205 08206 add_header(&req, "Event", subscriptiontype->event); 08207 add_header(&req, "Content-Type", subscriptiontype->mediatype); 08208 switch(state) { 08209 case AST_EXTENSION_DEACTIVATED: 08210 if (timeout) 08211 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 08212 else { 08213 add_header(&req, "Subscription-State", "terminated;reason=probation"); 08214 add_header(&req, "Retry-After", "60"); 08215 } 08216 break; 08217 case AST_EXTENSION_REMOVED: 08218 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 08219 break; 08220 default: 08221 if (p->expiry) 08222 add_header(&req, "Subscription-State", "active"); 08223 else /* Expired */ 08224 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 08225 } 08226 switch (p->subscribed) { 08227 case XPIDF_XML: 08228 case CPIM_PIDF_XML: 08229 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 08230 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 08231 ast_build_string(&t, &maxbytes, "<presence>\n"); 08232 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 08233 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 08234 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 08235 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 08236 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 08237 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 08238 break; 08239 case PIDF_XML: /* Eyebeam supports this format */ 08240 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 08241 ast_build_string(&t, &maxbytes, "<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); 08242 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 08243 if (pidfstate[0] != '-') 08244 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 08245 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 08246 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 08247 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 08248 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 08249 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 08250 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 08251 else 08252 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 08253 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 08254 break; 08255 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 08256 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 08257 ast_build_string(&t, &maxbytes, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">\n", p->dialogver++, full ? "full":"partial", mto); 08258 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 08259 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 08260 else 08261 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 08262 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 08263 if (state == AST_EXTENSION_ONHOLD) { 08264 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 08265 "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n" 08266 "</target>\n</local>\n", mto); 08267 } 08268 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 08269 break; 08270 case NONE: 08271 default: 08272 break; 08273 } 08274 08275 if (t > tmp + sizeof(tmp)) 08276 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 08277 08278 add_content(&req, tmp); 08279 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 08280 08281 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08282 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3999 of file chan_sip.c.
References ast_getformatbyname(), ast_log(), sip_pvt::capability, sip_pvt::jointcapability, LOG_NOTICE, sip_pvt::owner, and pbx_builtin_getvar_helper().
Referenced by sip_answer(), and transmit_response_with_sdp().
04000 { 04001 int fmt; 04002 const char *codec; 04003 04004 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 04005 if (!codec) 04006 return; 04007 04008 fmt = ast_getformatbyname(codec); 04009 if (fmt) { 04010 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 04011 if (p->jointcapability & fmt) { 04012 p->jointcapability &= fmt; 04013 p->capability &= fmt; 04014 } else 04015 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 04016 } else 04017 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 04018 return; 04019 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 20386 of file chan_sip.c.
References __sip_destroy(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free, ast_free_ha(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, 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_udptl_proto_unregister(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, checksipdomain_function, clear_realm_authentication(), clear_sip_domains(), iflist, iflock, localaddr, monlock, sip_pvt::next, sip_pvt::owner, peerl, regl, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_header_function, sip_registry_destroy(), sip_rtp, sip_tech, sip_udptl, sipchaninfo_function, sippeer_function, sipsock, TRUE, update(), and userl.
20387 { 20388 struct sip_pvt *p, *pl; 20389 struct sip_extenstate_update *update; 20390 20391 /* First, take us out of the channel type list */ 20392 ast_channel_unregister(&sip_tech); 20393 20394 /* Unregister dial plan functions */ 20395 ast_custom_function_unregister(&sipchaninfo_function); 20396 ast_custom_function_unregister(&sippeer_function); 20397 ast_custom_function_unregister(&sip_header_function); 20398 ast_custom_function_unregister(&checksipdomain_function); 20399 20400 /* Unregister dial plan applications */ 20401 ast_unregister_application(app_dtmfmode); 20402 ast_unregister_application(app_sipaddheader); 20403 20404 /* Unregister CLI commands */ 20405 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 20406 20407 /* Disconnect from the RTP subsystem */ 20408 ast_rtp_proto_unregister(&sip_rtp); 20409 20410 /* Disconnect from UDPTL */ 20411 ast_udptl_proto_unregister(&sip_udptl); 20412 20413 /* Unregister AMI actions */ 20414 ast_manager_unregister("SIPpeers"); 20415 ast_manager_unregister("SIPshowpeer"); 20416 20417 ast_mutex_lock(&iflock); 20418 /* Hangup all interfaces if they have an owner */ 20419 for (p = iflist; p ; p = p->next) { 20420 if (p->owner) 20421 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 20422 } 20423 ast_mutex_unlock(&iflock); 20424 20425 ast_mutex_lock(&monlock); 20426 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 20427 pthread_cancel(monitor_thread); 20428 pthread_kill(monitor_thread, SIGURG); 20429 pthread_join(monitor_thread, NULL); 20430 } 20431 monitor_thread = AST_PTHREADT_STOP; 20432 ast_mutex_unlock(&monlock); 20433 20434 restartdestroy: 20435 ast_mutex_lock(&iflock); 20436 /* Destroy all the interfaces and free their memory */ 20437 p = iflist; 20438 while (p) { 20439 pl = p; 20440 p = p->next; 20441 if (__sip_destroy(pl, TRUE) < 0) { 20442 /* Something is still bridged, let it react to getting a hangup */ 20443 iflist = p; 20444 ast_mutex_unlock(&iflock); 20445 usleep(1); 20446 goto restartdestroy; 20447 } 20448 } 20449 iflist = NULL; 20450 ast_mutex_unlock(&iflock); 20451 20452 /* Free memory for local network address mask */ 20453 ast_free_ha(localaddr); 20454 20455 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 20456 ASTOBJ_CONTAINER_DESTROY(&userl); 20457 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 20458 ASTOBJ_CONTAINER_DESTROY(&peerl); 20459 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 20460 ASTOBJ_CONTAINER_DESTROY(®l); 20461 20462 AST_LIST_LOCK(&sip_extenstate_updates); 20463 AST_LIST_TRAVERSE_SAFE_BEGIN(&sip_extenstate_updates, update, list) { 20464 AST_LIST_REMOVE_CURRENT(&sip_extenstate_updates, list); 20465 ast_free(update); 20466 } 20467 AST_LIST_TRAVERSE_SAFE_END 20468 AST_LIST_UNLOCK(&sip_extenstate_updates); 20469 20470 clear_realm_authentication(authl); 20471 clear_sip_domains(); 20472 ast_free_ha(global_contact_ha); 20473 close(sipsock); 20474 sched_context_destroy(sched); 20475 20476 return 0; 20477 }
static void unmark_extenstate_update | ( | struct sip_pvt * | pvt | ) | [static] |
Definition at line 9695 of file chan_sip.c.
References AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, sip_extenstate_update::marked, sip_extenstate_update::pvt, and update().
Referenced by do_monitor().
09696 { 09697 struct sip_extenstate_update *update = NULL; 09698 09699 if (AST_LIST_EMPTY(&sip_extenstate_updates)) { 09700 /* avoid holding the lock if possible */ 09701 return; 09702 } 09703 09704 AST_LIST_LOCK(&sip_extenstate_updates); 09705 AST_LIST_TRAVERSE(&sip_extenstate_updates, update, list) { 09706 if (update->pvt == pvt) { 09707 update->marked = 0; 09708 } 09709 } 09710 AST_LIST_UNLOCK(&sip_extenstate_updates); 09711 }
static void* unref_provisional_keepalive | ( | struct provisional_keepalive_data * | data | ) | [static] |
Definition at line 2473 of file chan_sip.c.
References ao2_ref(), provisional_keepalive_data::pvt, and provisional_keepalive_data::sched_id.
Referenced by __sip_destroy(), and remove_provisional_keepalive_sched().
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 propably update storage with inuse counter...
Definition at line 3544 of file chan_sip.c.
References ast_clear_flag, ast_copy_string(), ast_device_state_changed(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_user::call_limit, DEC_CALL_LIMIT, DEC_CALL_RINGING, FALSE, find_peer(), find_user(), sip_peer::flags, sip_pvt::flags, INC_CALL_LIMIT, INC_CALL_RINGING, sip_peer::inRinging, sip_peer::inUse, sip_user::inUse, inuse, LOG_DEBUG, LOG_ERROR, LOG_WARNING, sip_peer::name, name, option_debug, sip_pvt::peername, SIP_CALL_LIMIT, sip_destroy_peer(), sip_destroy_user(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_INC_RINGING, SIP_PAGE2_OUTGOING_CALL, SIP_PAGE2_RTCACHEFRIENDS, sip_peer_hold(), SIP_REALTIME, sipdebug, and sip_pvt::username.
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().
03545 { 03546 char name[256]; 03547 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 03548 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03549 struct sip_user *u = NULL; 03550 struct sip_peer *p = NULL; 03551 03552 if (option_debug > 2) 03553 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03554 03555 /* Test if we need to check call limits, in order to avoid 03556 realtime lookups if we do not need it */ 03557 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 03558 return 0; 03559 03560 ast_copy_string(name, fup->username, sizeof(name)); 03561 03562 /* Check the list of users only for incoming calls */ 03563 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03564 inuse = &u->inUse; 03565 call_limit = &u->call_limit; 03566 inringing = NULL; 03567 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1, 0) ) ) { /* Try to find peer */ 03568 inuse = &p->inUse; 03569 call_limit = &p->call_limit; 03570 inringing = &p->inRinging; 03571 ast_copy_string(name, fup->peername, sizeof(name)); 03572 } 03573 if (!p && !u) { 03574 if (option_debug > 1) 03575 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03576 return 0; 03577 } 03578 03579 switch(event) { 03580 /* incoming and outgoing affects the inUse counter */ 03581 case DEC_CALL_LIMIT: 03582 if ( *inuse > 0 ) { 03583 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03584 (*inuse)--; 03585 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03586 } 03587 } else { 03588 *inuse = 0; 03589 } 03590 if (inringing) { 03591 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03592 if (*inringing > 0) 03593 (*inringing)--; 03594 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03595 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03596 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03597 } 03598 } 03599 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) { 03600 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 03601 sip_peer_hold(fup, 0); 03602 } 03603 if (option_debug > 1 || sipdebug) { 03604 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03605 } 03606 break; 03607 03608 case INC_CALL_RINGING: 03609 case INC_CALL_LIMIT: 03610 if (*call_limit > 0 ) { 03611 /* Let call limit affect only outgoing calls */ 03612 if (outgoing && (*inuse >= *call_limit)) { 03613 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); 03614 if (u) 03615 ASTOBJ_UNREF(u, sip_destroy_user); 03616 else 03617 ASTOBJ_UNREF(p, sip_destroy_peer); 03618 return -1; 03619 } 03620 } 03621 if (inringing && (event == INC_CALL_RINGING)) { 03622 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03623 (*inringing)++; 03624 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03625 } 03626 } 03627 /* Continue */ 03628 (*inuse)++; 03629 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03630 if (option_debug > 1 || sipdebug) { 03631 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03632 } 03633 break; 03634 03635 case DEC_CALL_RINGING: 03636 if (inringing) { 03637 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03638 if (*inringing > 0) 03639 (*inringing)--; 03640 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03641 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03642 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03643 } 03644 } 03645 break; 03646 03647 default: 03648 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03649 } 03650 if (p) { 03651 ast_device_state_changed("SIP/%s", p->name); 03652 ASTOBJ_UNREF(p, sip_destroy_peer); 03653 } else /* u must be set */ 03654 ASTOBJ_UNREF(u, sip_destroy_user); 03655 return 0; 03656 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 2783 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, sip_peer::fullcontact, sip_peer::lastms, sip_peer::name, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username.
Referenced by register_verify().
02784 { 02785 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02786 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02787 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02788 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry, p->lastms); 02789 } 02790 }
static void update_provisional_keepalive | ( | struct sip_pvt * | pvt, | |
int | with_sdp | |||
) | [static] |
Definition at line 2504 of file chan_sip.c.
References ao2_alloc(), ao2_ref(), ast_sched_add(), PROVIS_KEEPALIVE_TIMEOUT, sip_pvt::provisional_keepalive_data, provisional_keepalive_data::pvt, remove_provisional_keepalive_sched(), provisional_keepalive_data::sched_id, send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().
Referenced by transmit_provisional_response().
02505 { 02506 remove_provisional_keepalive_sched(pvt); 02507 02508 if (!pvt->provisional_keepalive_data) { 02509 if (!(pvt->provisional_keepalive_data = ao2_alloc(sizeof(*pvt->provisional_keepalive_data), NULL))) { 02510 return; /* alloc error, can not recover */ 02511 } 02512 pvt->provisional_keepalive_data->sched_id = -1; 02513 pvt->provisional_keepalive_data->pvt = pvt; 02514 } 02515 02516 /* give the scheduler a ref */ 02517 ao2_ref(pvt->provisional_keepalive_data, +1); 02518 02519 /* schedule the provisional keepalive */ 02520 pvt->provisional_keepalive_data->sched_id = ast_sched_add(sched, 02521 PROVIS_KEEPALIVE_TIMEOUT, 02522 with_sdp ? send_provisional_keepalive_with_sdp : send_provisional_keepalive, 02523 pvt->provisional_keepalive_data); 02524 02525 /* if schedule was unsuccessful, remove the scheduler's ref */ 02526 if (pvt->provisional_keepalive_data->sched_id == -1) { 02527 ao2_ref(pvt->provisional_keepalive_data, -1); 02528 } 02529 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 20483 of file chan_sip.c.
struct in_addr __ourip [static] |
Definition at line 1317 of file chan_sip.c.
Referenced by reload_config(), sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_register(), and transmit_response_using_temp().
int allow_external_domains [static] |
Accept calls to external SIP domains?
Definition at line 575 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 595 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 19938 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 19940 of file chan_sip.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 20483 of file chan_sip.c.
Authentication list for realm authentication
Definition at line 1306 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 554 of file chan_sip.c.
struct sockaddr_in bindaddr = { 0, } [static] |
The address we bind to
Definition at line 1311 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), sip_alloc(), sip_show_settings(), and transmit_register().
unsigned int chan_idx [static] |
Definition at line 403 of file chan_sip.c.
struct ast_threadstorage check_auth_buf = { .once = PTHREAD_ONCE_INIT , .key_init = check_auth_buf_init , } [static] |
Definition at line 9398 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
struct ast_custom_function checksipdomain_function [static] |
Definition at line 13221 of file chan_sip.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_sip[] [static] |
Definition at line 20222 of file chan_sip.c.
struct ast_cli_entry cli_sip_debug_deprecated [static] |
{ { "sip", "debug", NULL }, sip_do_debug_deprecated, "Enable SIP debugging", debug_usage }
Definition at line 20212 of file chan_sip.c.
struct ast_cli_entry cli_sip_no_debug_deprecated [static] |
{ { "sip", "no", "debug", NULL }, sip_no_debug_deprecated, "Disable SIP debugging", debug_usage }
Definition at line 20217 of file chan_sip.c.
int compactheaders [static] |
send compact sip headers
Definition at line 569 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Definition at line 236 of file chan_sip.c.
char debug_usage[] [static] |
Definition at line 13105 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1320 of file chan_sip.c.
Referenced by sip_debug_test_addr(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), and sip_do_debug_peer().
char default_callerid[AST_MAX_EXTENSION] [static] |
Definition at line 533 of file chan_sip.c.
char default_context[AST_MAX_CONTEXT] [static] |
Definition at line 530 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 194 of file chan_sip.c.
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Definition at line 534 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 227 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Definition at line 532 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 541 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 538 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 539 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Definition at line 535 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 542 of file chan_sip.c.
Referenced by 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 536 of file chan_sip.c.
char default_subscribecontext[AST_MAX_CONTEXT] [static] |
Definition at line 531 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 537 of file chan_sip.c.
char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static] |
Definition at line 19937 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 19943 of file chan_sip.c.
int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 571 of file chan_sip.c.
int expiry = DEFAULT_EXPIRY [static] |
Definition at line 195 of file chan_sip.c.
Referenced by complete_dpreply(), process_clearcache(), and register_verify().
time_t externexpire = 0 [static] |
Expiration counter for re-resolving external host name in dynamic DNS
Definition at line 1314 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
char externhost[MAXHOSTNAMELEN] [static] |
External host name (possibly with dynamic DNS and DHCP
Definition at line 1313 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
struct sockaddr_in externip [static] |
External IP address if we are behind NAT
Definition at line 1312 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
int externrefresh = 10 [static] |
Definition at line 1315 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
int global_allowguest [static] |
allow unauthenticated users/peers to connect?
Definition at line 562 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 563 of file chan_sip.c.
enum transfermodes global_allowtransfer [static] |
SIP Refer restriction scheme
Definition at line 579 of file chan_sip.c.
int global_alwaysauthreject [static] |
Send 401 Unauthorized for all failing requests
Definition at line 551 of file chan_sip.c.
int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 578 of file chan_sip.c.
int global_callevents [static] |
Whether we send manager events or not
Definition at line 576 of file chan_sip.c.
int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 [static] |
Codecs that we support by default:.
Definition at line 584 of file chan_sip.c.
struct ast_ha* global_contact_ha = NULL [static] |
Global list of addresses dynamic peers are not allowed to use.
Definition at line 587 of file chan_sip.c.
int global_directrtpsetup [static] |
Enable support for Direct RTP setup (no re-invites)
Definition at line 545 of file chan_sip.c.
int global_dynamic_exclude_static = 0 [static] |
Definition at line 588 of file chan_sip.c.
struct ast_flags global_flags[2] = {{0}} [static] |
global SIP_ flags
Definition at line 598 of file chan_sip.c.
struct ast_jb_conf global_jbconf [static] |
Definition at line 234 of file chan_sip.c.
Referenced by reload_config(), sip_get_rtp_peer(), and sip_new().
int global_limitonpeers [static] |
Match call limit on peers only
Definition at line 547 of file chan_sip.c.
int global_matchexterniplocally [static] |
Match externip/externhost setting against localnet setting
Definition at line 581 of file chan_sip.c.
int global_mwitime [static] |
Time between MWI checks for peers
Definition at line 565 of file chan_sip.c.
int global_notifyhold [static] |
Send notifications on hold
Definition at line 550 of file chan_sip.c.
int global_notifyringing [static] |
Send notifications on ringing
Definition at line 549 of file chan_sip.c.
int global_prematuremediafilter [static] |
Enable/disable premature frames in a call (causing 183 early media)
Definition at line 546 of file chan_sip.c.
char global_realm[MAXHOSTNAMELEN] [static] |
Default realm
Definition at line 572 of file chan_sip.c.
int global_reg_timeout [static] |
Definition at line 559 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 560 of file chan_sip.c.
char global_regcontext[AST_MAX_CONTEXT] [static] |
Context for auto-extensions
Definition at line 573 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 555 of file chan_sip.c.
int global_rtautoclear [static] |
Definition at line 548 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Definition at line 557 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 558 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 556 of file chan_sip.c.
int global_shrinkcallerid [static] |
enable or disable shrinking of caller id
Definition at line 561 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 577 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 864 of file chan_sip.c.
unsigned int global_tos_audio [static] |
IP type of service for audio RTP packets
Definition at line 567 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 566 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 568 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 574 of file chan_sip.c.
char history_usage[] [static] |
"Usage: sip history\n" " Enables recording of SIP dialog history for debugging purposes.\n" "Use 'sip show history' to view the history of a call number.\n"
Definition at line 13122 of file chan_sip.c.
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe
ast_mutex_t iflock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Protect the SIP dialog list (of sip_pvt's).
Definition at line 601 of file chan_sip.c.
Referenced by __sip_show_channels(), complete_sipch(), do_monitor(), find_call(), get_sip_pvt_byid_locked(), sip_alloc(), sip_destroy(), sip_show_channel(), sip_show_history(), and unload_module().
struct io_context* io [static] |
The IO context
Definition at line 619 of file chan_sip.c.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1316 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), and unload_module().
char mandescr_show_peer[] [static] |
"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 11719 of file chan_sip.c.
Referenced by load_module().
char mandescr_show_peers[] [static] |
"Description: Lists SIP peers in text format with details on current status.\n" "Variables: \n" " ActionID: <id> Action ID for this transaction. Will be returned.\n"
Definition at line 11263 of file chan_sip.c.
Referenced by load_module().
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 193 of file chan_sip.c.
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 192 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 613 of file chan_sip.c.
ast_mutex_t monlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 607 of file chan_sip.c.
Referenced by do_monitor(), restart_monitor(), and unload_module().
ast_mutex_t netlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [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 605 of file chan_sip.c.
Referenced by reload_config(), and sipsock_read().
char no_debug_usage[] [static] |
"Usage: sip set debug off\n" " Disables dumping of SIP packets for debugging purposes\n"
Definition at line 13114 of file chan_sip.c.
char no_history_usage[] [static] |
"Usage: sip history off\n" " Disables recording of SIP dialog history for debugging purposes\n"
Definition at line 13118 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Definition at line 237 of file chan_sip.c.
struct ast_config* notify_types = NULL [static] |
The list of manual NOTIFY types we know how to send
Definition at line 1322 of file chan_sip.c.
Referenced by complete_sipnotify(), reload_config(), and sip_notify().
char notify_usage[] [static] |
"Usage: sip notify <type> <peer> [<peer>...]\n" " Send a NOTIFY message to a SIP peer or peers\n" " Message types are defined in sip_notify.conf\n"
Definition at line 13054 of file chan_sip.c.
int ourport [static] |
Definition at line 1319 of file chan_sip.c.
Referenced by build_contact(), build_via(), initreqprep(), reload_config(), and transmit_notify_with_mwi().
struct sockaddr_in outboundproxyip [static] |
Definition at line 1318 of file chan_sip.c.
Referenced by reload_config().
int pedanticsipchecking [static] |
Extra checking ? Default off
Definition at line 553 of file chan_sip.c.
struct ast_peer_list peerl [static] |
The peer list: Peers and Friends.
Referenced by _sip_show_peers(), build_peer(), complete_sip_peer(), do_monitor(), expire_register(), find_peer(), load_module(), realtime_peer(), register_verify(), reload_config(), sip_do_reload(), sip_poke_all_peers(), sip_poke_peer_s(), sip_prune_realtime(), sip_show_inuse(), sip_show_objects(), and unload_module().
char prune_realtime_usage[] [static] |
"Usage: sip prune realtime [peer|user] [<name>|all|like <pattern>]\n" " Prunes object(s) from the cache.\n" " Optional regular expression pattern is used to filter the objects.\n"
Definition at line 13096 of file chan_sip.c.
int recordhistory [static] |
Record SIP history. Off by default
Definition at line 570 of file chan_sip.c.
struct c_referstatusstring referstatusstrings[] [static] |
Referenced by referstatus2str().
struct ast_register_list regl [static] |
The register list: Other SIP proxys we register with and place calls to.
Referenced by load_module(), 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 596 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 594 of file chan_sip.c.
int ruserobjs = 0 [static] |
Realtime users
Definition at line 592 of file chan_sip.c.
struct sched_context* sched [static] |
The scheduling context
Definition at line 618 of file chan_sip.c.
char seen_lastms = 0 [static] |
Definition at line 196 of file chan_sip.c.
char show_channel_usage[] [static] |
"Usage: sip show channel <channel>\n" " Provides detailed status on a given SIP channel.\n"
Definition at line 13078 of file chan_sip.c.
char show_channels_usage[] [static] |
"Usage: sip show channels\n" " Lists all currently active SIP channels.\n"
Definition at line 13074 of file chan_sip.c.
char show_domains_usage[] [static] |
"Usage: sip show domains\n" " Lists all configured SIP local domains.\n" " Asterisk only responds to SIP messages to local domains.\n"
Definition at line 13049 of file chan_sip.c.
char show_history_usage[] [static] |
"Usage: sip show history <channel>\n" " Provides detailed dialog history on a given SIP channel.\n"
Definition at line 13082 of file chan_sip.c.
char show_inuse_usage[] [static] |
"Usage: sip show inuse [all]\n" " List all SIP users and peers usage counters and limits.\n" " Add option \"all\" to show all devices, not only those with a limit.\n"
Definition at line 13069 of file chan_sip.c.
char show_objects_usage[] [static] |
"Usage: sip show objects\n" " Lists status of known SIP objects\n"
Definition at line 13135 of file chan_sip.c.
char show_peer_usage[] [static] |
"Usage: sip show peer <name> [load]\n" " Shows all details on one SIP peer and the current status.\n" " Option \"load\" forces lookup of peer in realtime storage.\n"
Definition at line 13091 of file chan_sip.c.
char show_peers_usage[] [static] |
"Usage: sip show peers [like <pattern>]\n" " Lists all known SIP peers.\n" " Optional regular expression pattern is used to filter the peer list.\n"
Definition at line 13086 of file chan_sip.c.
char show_reg_usage[] [static] |
"Usage: sip show registry\n" " Lists all registration requests and status.\n"
Definition at line 13101 of file chan_sip.c.
char show_settings_usage[] [static] |
"Usage: sip show settings\n" " Provides detailed list of the configuration of the SIP channel.\n"
Definition at line 13139 of file chan_sip.c.
char show_subscriptions_usage[] [static] |
"Usage: sip show subscriptions\n" " Lists active SIP subscriptions for extension states\n"
Definition at line 13131 of file chan_sip.c.
char show_user_usage[] [static] |
"Usage: sip show user <name> [load]\n" " Shows all details on one SIP user and the current status.\n" " Option \"load\" forces lookup of peer in realtime storage.\n"
Definition at line 13064 of file chan_sip.c.
char show_users_usage[] [static] |
"Usage: sip show users [like <pattern>]\n" " Lists all known SIP users.\n" " Optional regular expression pattern is used to filter the user list.\n"
Definition at line 13059 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
Definition at line 13197 of file chan_sip.c.
Referenced by load_module(), and unload_module().
struct cfsip_methods sip_methods[] [static] |
XXX Note that sip_methods[i].id == i must hold or the code breaks
Referenced by __sip_ack(), __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_request(), handle_request_subscribe(), handle_response(), init_req(), 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_MUTEX_INITIALIZER ) [static] |
Definition at line 609 of file chan_sip.c.
Referenced by do_monitor(), and sip_reload().
char sip_reload_usage[] [static] |
"Usage: sip reload\n" " Reloads SIP configuration from sip.conf\n"
Definition at line 13127 of file chan_sip.c.
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 615 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 616 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 1728 of file chan_sip.c.
Referenced by load_module(), and unload_module().
struct ast_channel_tech sip_tech [static] |
Definition of this channel for PBX channel registration.
Definition at line 1670 of file chan_sip.c.
Referenced by acf_channel_read(), func_header_read(), function_sipchaninfo_read(), handle_request_invite(), handle_response_invite(), load_module(), sip_dtmfmode(), 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. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames.
Definition at line 1696 of file chan_sip.c.
Referenced by acf_channel_read(), func_header_read(), function_sipchaninfo_read(), handle_request_invite(), handle_response_invite(), sip_dtmfmode(), and sip_new().
struct ast_udptl_protocol sip_udptl [static] |
{ type: "SIP", get_udptl_info: sip_get_udptl_peer, set_udptl_peer: sip_set_udptl_peer, }
Interface structure with callbacks used to connect to UDPTL module.
Definition at line 1737 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 13388 of file chan_sip.c.
Referenced by load_module(), and unload_module().
Structure to declare a dialplan function: SIPPEER.
Definition at line 13304 of file chan_sip.c.
Referenced by load_module(), and unload_module().
int sipsock = -1 [static] |
Main socket for SIP network communication
Definition at line 1310 of file chan_sip.c.
Referenced by __sip_xmit(), do_monitor(), process_via(), reg_source_db(), reload_config(), sipsock_read(), and unload_module().
int* sipsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 620 of file chan_sip.c.
int speerobjs = 0 [static] |
Statis peers
Definition at line 593 of file chan_sip.c.
int srvlookup [static] |
SRV Lookup on or off. Default is on
Definition at line 552 of file chan_sip.c.
struct cfsubscription_types subscription_types[] [static] |
Referenced by find_subscription_type(), and subscription_type2str().
int suserobjs = 0 [static] |
Static users
Definition at line 591 of file chan_sip.c.
char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static] |
Definition at line 19936 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 19941 of file chan_sip.c.
struct ast_threadstorage ts_temp_pvt = { .once = PTHREAD_ONCE_INIT , .key_init = temp_pvt_init , } [static] |
Definition at line 1263 of file chan_sip.c.
Referenced by transmit_response_using_temp().
struct ast_user_list userl [static] |
The user list: Users and friends.
Referenced by complete_sip_user(), find_user(), load_module(), realtime_user(), reload_config(), sip_prune_realtime(), sip_show_inuse(), sip_show_objects(), sip_show_users(), and unload_module().