#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"
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 | sip_auth |
sip_auth: Credentials for authentication to other SIP services More... | |
struct | sip_dual |
structure used in transfers More... | |
struct | sip_history |
sip_history: Structure for saving transactions within a SIP dialog More... | |
struct | sip_history_head |
struct | sip_invite_param |
Parameters to the transmit_invite function. More... | |
struct | sip_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_pvt::request_queue |
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 | 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 | FALSE 0 |
#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 | IPTOS_MINCOST 0x02 |
#define | MAX(a, b) ((a) > (b) ? (a) : (b)) |
#define | MAX_AUTHTRIES 3 |
#define | MAX_HISTORY_ENTRIES 50 |
#define | MAX_RETRANS 6 |
#define | NO_RTP 0 |
#define | NOT_SUPPORTED 0 |
#define | 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_CONSTANT_SSRC (1 << 31) |
#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_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 | TRUE 1 |
#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_digit (struct sip_request *req, char digit, unsigned int duration) |
Add DTMF INFO tone to sip message. | |
static int | add_header (struct sip_request *req, const char *var, const char *value) |
Add header to SIP message. | |
static int | add_header_contentLength (struct sip_request *req, int len) |
Add 'Content-Length' header to SIP message. | |
static int | add_line (struct sip_request *req, const char *line) |
Add content (not header) to SIP message. | |
static void | add_noncodec_to_sdp (const struct sip_pvt *p, int format, int sample_rate, 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 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 int | cb_extensionstate (char *context, char *exten, int state, void *data) |
Callback for the devicestate notification (SUBSCRIBE) support subsystem. | |
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_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 int | clear_realm_authentication (struct sip_auth *authlist) |
Clear realm authentication list (at reload). | |
static void | clear_sip_domains (void) |
Clear our domain list (at reload). | |
static char * | complete_sip_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 * | 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 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 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 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 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 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 | 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 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 sip_pvt *pvt, int with_sdp) |
static int | send_provisional_keepalive_with_sdp (const void *data) |
static int | send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Send SIP Request to the other part of the dialogue. | |
static int | send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Transmit response on SIP request. | |
static 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 | |
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 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 = "6989f2ec67f8497e38c12890500c525b" , .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 = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, 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 = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } |
static ast_mutex_t | netlock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, 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 |
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 = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, 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. | |
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. |
SIP over TLS
Better support of forking
VIA branch tag transaction checking
Transaction support
A new INVITE is sent to handle_request_invite(), that will end up starting a new channel in the PBX, the new channel after that executing in a separate channel thread. This is an incoming "call". When the call is answered, either by a bridged channel or the PBX itself the sip_answer() function is called.
The actual media - Video or Audio - is mostly handled by the RTP subsystem in rtp.c
Definition in file chan_sip.c.
#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO" |
SIP Methods we support.
Definition at line 482 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 1907 of file chan_sip.c.
Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), cb_extensionstate(), 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(), 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" |
#define CAN_CREATE_DIALOG 1 |
Definition at line 373 of file chan_sip.c.
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
Definition at line 374 of file chan_sip.c.
#define CAN_NOT_CREATE_DIALOG 0 |
Definition at line 372 of file chan_sip.c.
#define CHECK_AUTH_BUF_INITLEN 256 |
Definition at line 9004 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
#define DEC_CALL_LIMIT 0 |
Definition at line 621 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 623 of file chan_sip.c.
Referenced by handle_response_invite(), and update_call_counter().
#define DEFAULT_ALLOW_EXT_DOM TRUE |
Definition at line 514 of file chan_sip.c.
#define DEFAULT_ALLOWGUEST TRUE |
Definition at line 508 of file chan_sip.c.
#define DEFAULT_AUTOCREATEPEER FALSE |
Definition at line 518 of file chan_sip.c.
#define DEFAULT_CALLERID "asterisk" |
Definition at line 505 of file chan_sip.c.
#define DEFAULT_COMPACTHEADERS FALSE |
Definition at line 510 of file chan_sip.c.
#define DEFAULT_CONTEXT "default" |
Definition at line 501 of file chan_sip.c.
#define DEFAULT_DEFAULT_EXPIRY 120 |
Definition at line 172 of file chan_sip.c.
#define DEFAULT_EXPIRY 900 |
Expire slowly
Definition at line 189 of file chan_sip.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Qualification: How often to check, if the host is down...
Definition at line 206 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 205 of file chan_sip.c.
#define DEFAULT_MAX_CALL_BITRATE (384) |
Max bitrate for video
Definition at line 521 of file chan_sip.c.
#define DEFAULT_MAX_EXPIRY 3600 |
Definition at line 174 of file chan_sip.c.
#define DEFAULT_MAX_FORWARDS "70" |
Definition at line 176 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 204 of file chan_sip.c.
#define DEFAULT_MIN_EXPIRY 60 |
Definition at line 173 of file chan_sip.c.
#define DEFAULT_MOHINTERPRET "default" |
Definition at line 502 of file chan_sip.c.
#define DEFAULT_MOHSUGGEST "" |
Definition at line 503 of file chan_sip.c.
#define DEFAULT_MWITIME 10 |
Definition at line 507 of file chan_sip.c.
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
Definition at line 506 of file chan_sip.c.
#define DEFAULT_NOTIFYRINGING TRUE |
Definition at line 516 of file chan_sip.c.
#define DEFAULT_PEDANTIC FALSE |
Definition at line 517 of file chan_sip.c.
#define DEFAULT_QUALIFY FALSE |
Definition at line 519 of file chan_sip.c.
#define DEFAULT_REALM "asterisk" |
Definition at line 515 of file chan_sip.c.
#define DEFAULT_REGISTRATION_TIMEOUT 20 |
Definition at line 175 of file chan_sip.c.
#define DEFAULT_RETRANS 1000 |
How frequently to retransmit Default: 2 * 500 ms in RFC 3261
Definition at line 208 of file chan_sip.c.
#define DEFAULT_SRVLOOKUP TRUE |
Recommended setting is ON
Definition at line 509 of file chan_sip.c.
#define DEFAULT_T1MIN 100 |
100 MS for minimal roundtrip time
Definition at line 520 of file chan_sip.c.
#define DEFAULT_TOS_AUDIO 0 |
Audio packets should be marked as DSCP EF (Expedited Forwarding), but the default is 0 to be compatible with previous versions.
Definition at line 512 of file chan_sip.c.
#define DEFAULT_TOS_SIP 0 |
Call signalling packets should be marked as DSCP CS3, but the default is 0 to be compatible with previous versions.
Definition at line 511 of file chan_sip.c.
#define DEFAULT_TOS_VIDEO 0 |
Video packets should be marked as DSCP AF41, but the default is 0 to be compatible with previous versions.
Definition at line 513 of file chan_sip.c.
#define DEFAULT_TRANS_TIMEOUT -1 |
Definition at line 213 of file chan_sip.c.
Referenced by __sip_autodestruct(), auto_congest(), cb_extensionstate(), 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(), 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 523 of file chan_sip.c.
#define DEFAULT_VMEXTEN "asterisk" |
Definition at line 504 of file chan_sip.c.
#define EXPIRY_GUARD_LIMIT 30 |
Below here, we use EXPIRY_GUARD_PCT instead of EXPIRY_GUARD_SECS
Definition at line 181 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 183 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 187 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 180 of file chan_sip.c.
Referenced by handle_response_register().
#define FALSE 0 |
Definition at line 154 of file chan_sip.c.
#define FLAG_FATAL (1 << 1) |
#define FLAG_RESPONSE (1 << 0) |
Definition at line 1072 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" |
#define FROMDOMAIN_INVALID "anonymous.invalid" |
#define INC_CALL_LIMIT 1 |
Definition at line 622 of file chan_sip.c.
Referenced by handle_request_invite(), and update_call_counter().
#define INC_CALL_RINGING 3 |
#define INITIAL_CSEQ 101 |
our initial sip sequence number
Definition at line 223 of file chan_sip.c.
Referenced by sip_alloc(), sip_register(), and transmit_response_using_temp().
#define IPTOS_MINCOST 0x02 |
Definition at line 167 of file chan_sip.c.
#define MAX | ( | a, | |||
b | ) | ((a) > (b) ? (a) : (b)) |
Definition at line 198 of file chan_sip.c.
#define MAX_AUTHTRIES 3 |
Try authentication three times, then fail
Definition at line 215 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 1070 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 209 of file chan_sip.c.
#define NO_RTP 0 |
Definition at line 239 of file chan_sip.c.
#define NOT_SUPPORTED 0 |
Definition at line 415 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 214 of file chan_sip.c.
Referenced by send_provisional_keepalive_full(), and update_provisional_keepalive().
#define RTP 1 |
Definition at line 238 of file chan_sip.c.
#define SDP_MAX_RTPMAP_CODECS 32 |
Maximum number of codecs allowed in received SDP
Definition at line 221 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 6900 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 729 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 770 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 758 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), 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 759 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 744 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 745 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 749 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 747 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 748 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 746 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
#define SIP_FLAGS_TO_COPY |
Value:
(SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \ SIP_PROG_INBAND | SIP_USECLIENTCODE | SIP_NAT | SIP_G726_NONSTANDARD | \ SIP_USEREQPHONE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE)
Definition at line 775 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 743 of file chan_sip.c.
#define SIP_G726_NONSTANDARD (1 << 31) |
Use non-standard packing for G726-32 data
Definition at line 773 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 736 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 772 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 763 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 762 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), set_insecure_flags(), and sip_addrcmp().
#define SIP_MAX_HEADERS 64 |
Max amount of SIP headers to read
Definition at line 217 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 218 of file chan_sip.c.
Referenced by add_line(), and parse_request().
#define SIP_MAX_PACKET 4096 |
Also from RFC 3261 (2543), should sub headers tho
Definition at line 219 of file chan_sip.c.
#define SIP_NAT (3 << 18) |
four settings, uses two bits
Definition at line 751 of file chan_sip.c.
Referenced by _sip_show_peer(), build_via(), copy_via_headers(), create_addr(), create_addr_from_peer(), handle_common_options(), process_sdp(), register_verify(), sip_alloc(), sip_nat_mode(), sip_real_dst(), sip_show_channel(), sip_show_settings(), sip_show_users(), and transmit_response_using_temp().
#define SIP_NAT_ALWAYS (3 << 18) |
NAT Both ROUTE and RFC3581
Definition at line 755 of file chan_sip.c.
Referenced by copy_via_headers(), handle_common_options(), and nat2str().
#define SIP_NAT_NEVER (0 << 18) |
No nat support
Definition at line 752 of file chan_sip.c.
Referenced by handle_common_options(), and nat2str().
#define SIP_NAT_RFC3581 (1 << 18) |
NAT RFC3581
Definition at line 753 of file chan_sip.c.
Referenced by build_via(), copy_via_headers(), handle_common_options(), and nat2str().
#define SIP_NAT_ROUTE (2 << 18) |
NAT Only ROUTE
Definition at line 754 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 730 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 734 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 769 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 731 of file chan_sip.c.
Referenced by add_sdp(), process_sdp(), and sip_indicate().
#define SIP_OPT_100REL (1 << 1) |
Definition at line 418 of file chan_sip.c.
#define SIP_OPT_EARLY_SESSION (1 << 3) |
Definition at line 420 of file chan_sip.c.
#define SIP_OPT_EVENTLIST (1 << 11) |
Definition at line 428 of file chan_sip.c.
#define SIP_OPT_GRUU (1 << 12) |
Definition at line 429 of file chan_sip.c.
#define SIP_OPT_HISTINFO (1 << 15) |
Definition at line 432 of file chan_sip.c.
#define SIP_OPT_JOIN (1 << 4) |
Definition at line 421 of file chan_sip.c.
#define SIP_OPT_NOREFERSUB (1 << 14) |
Definition at line 431 of file chan_sip.c.
#define SIP_OPT_PATH (1 << 5) |
Definition at line 422 of file chan_sip.c.
#define SIP_OPT_PRECONDITION (1 << 7) |
Definition at line 424 of file chan_sip.c.
#define SIP_OPT_PREF (1 << 6) |
Definition at line 423 of file chan_sip.c.
#define SIP_OPT_PRIVACY (1 << 8) |
Definition at line 425 of file chan_sip.c.
#define SIP_OPT_REPLACES (1 << 0) |
#define SIP_OPT_RESPRIORITY (1 << 16) |
Definition at line 433 of file chan_sip.c.
#define SIP_OPT_SDP_ANAT (1 << 9) |
Definition at line 426 of file chan_sip.c.
#define SIP_OPT_SEC_AGREE (1 << 10) |
Definition at line 427 of file chan_sip.c.
#define SIP_OPT_TARGET_DIALOG (1 << 13) |
Definition at line 430 of file chan_sip.c.
#define SIP_OPT_TIMER (1 << 2) |
Definition at line 419 of file chan_sip.c.
#define SIP_OUTGOING (1 << 13) |
Direction of the last transaction in this dialog
Definition at line 742 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 797 of file chan_sip.c.
Referenced by _sip_show_peer(), get_destination(), handle_common_options(), handle_request_invite(), and sip_show_settings().
#define SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
Allow subscriptions from this peer?
Definition at line 796 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), build_user(), handle_common_options(), handle_request_subscribe(), and sip_show_settings().
#define SIP_PAGE2_BUGGY_MWI (1 << 26) |
26: Buggy CISCO MWI fix
Definition at line 809 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 804 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 807 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 806 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_CONSTANT_SSRC (1 << 31) |
31: Don't change SSRC on reinvite
Definition at line 814 of file chan_sip.c.
Referenced by create_addr_from_peer(), handle_common_options(), and handle_request_invite().
#define SIP_PAGE2_DEBUG (3 << 11) |
Definition at line 790 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
Definition at line 791 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
Definition at line 792 of file chan_sip.c.
Referenced by 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 812 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 793 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 |
Value:
(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_CONSTANT_SSRC)
Definition at line 816 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_IGNOREREGEXPIRE (1 << 10) |
Definition at line 789 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), and sip_show_settings().
#define SIP_PAGE2_INC_RINGING (1 << 19) |
Did this connection increment the counter of in-use calls?
Definition at line 799 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 810 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 808 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 813 of file chan_sip.c.
Referenced by check_user_full(), and check_via().
#define SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
Definition at line 785 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), parse_register_contact(), and reg_source_db().
#define SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
#define SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
Definition at line 782 of file chan_sip.c.
Referenced by build_peer(), complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), parse_register_contact(), sip_prune_realtime(), sip_show_settings(), update_call_counter(), and update_peer().
#define SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
Definition at line 786 of file chan_sip.c.
Referenced by realtime_update_peer(), and sip_show_settings().
#define SIP_PAGE2_RTUPDATE (1 << 1) |
Definition at line 783 of file chan_sip.c.
Referenced by destroy_association(), handle_response_peerpoke(), sip_poke_noanswer(), sip_show_settings(), and update_peer().
#define SIP_PAGE2_SELFDESTRUCT (1 << 14) |
Automatic peers need to destruct themselves
Definition at line 794 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 788 of file chan_sip.c.
Referenced by cb_extensionstate(), and handle_response().
#define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
Only issue MWI notification if subscribed to
Definition at line 798 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 800 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 802 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 803 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 801 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 811 of file chan_sip.c.
Referenced by handle_common_options(), and process_sdp().
#define SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
Definition at line 795 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), check_user_full(), create_addr_from_peer(), handle_common_options(), sip_alloc(), and sip_show_settings().
#define SIP_PENDINGBYE (1 << 6) |
Need to send bye after we ack?
Definition at line 735 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 822 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 824 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 823 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 765 of file chan_sip.c.
Referenced by handle_common_options(), sip_indicate(), and sip_show_settings().
#define SIP_PROG_INBAND_NEVER (0 << 25) |
#define SIP_PROG_INBAND_NO (1 << 25) |
Definition at line 767 of file chan_sip.c.
Referenced by handle_common_options(), and sip_show_settings().
#define SIP_PROG_INBAND_YES (2 << 25) |
Definition at line 768 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 733 of file chan_sip.c.
Referenced by sip_indicate(), and sip_write().
#define SIP_PROMISCREDIR (1 << 8) |
Promiscuous redirection
Definition at line 737 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 740 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), parse_register_contact(), sip_destroy_peer(), sip_destroy_user(), 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 760 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 771 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 210 of file chan_sip.c.
Referenced by sip_call(), and sip_sipredirect().
#define SIP_TRUSTRPID (1 << 9) |
Trust RPID headers?
Definition at line 738 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 741 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 739 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), initreqprep(), and sip_show_settings().
#define SIPBUFSIZE 512 |
Definition at line 161 of file chan_sip.c.
Referenced by __sip_show_channels(), add_route(), add_sdp(), 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 853 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 854 of file chan_sip.c.
#define sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
Definition at line 855 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 488 of file chan_sip.c.
Referenced by __set_address_from_contact(), build_contact(), build_peer(), check_via(), create_addr(), initreqprep(), parse_register_contact(), 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 414 of file chan_sip.c.
#define SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support.
Definition at line 485 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 828 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 847 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 848 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 843 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 844 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 845 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 846 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 833 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 832 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 830 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 829 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 836 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 835 of file chan_sip.c.
Referenced by add_sdp(), create_addr_from_peer(), process_sdp_a_image(), and sip_alloc().
#define T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
Set for t38UDPRedundancy
Definition at line 837 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 839 of file chan_sip.c.
Referenced by add_sdp().
#define T38FAX_VERSION_0 (0 << 6) |
Version 0
Definition at line 840 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 841 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp_a_image().
#define TRUE 1 |
Definition at line 158 of file chan_sip.c.
#define UNLINK | ( | element, | |||
head, | |||||
prev | ) |
--- some list management macros.
Definition at line 1665 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 165 of file chan_sip.c.
#define XMIT_ERROR -2 |
Definition at line 163 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 348 of file chan_sip.c.
00348 { 00349 AUTH_SUCCESSFUL = 0, 00350 AUTH_CHALLENGE_SENT = 1, 00351 AUTH_SECRET_FAILED = -1, 00352 AUTH_USERNAME_MISMATCH = -2, 00353 AUTH_NOT_FOUND = -3, 00354 AUTH_FAKE_AUTH = -4, 00355 AUTH_UNKNOWN_DOMAIN = -5, 00356 AUTH_PEER_NOT_DYNAMIC = -6, 00357 AUTH_ACL_FAILED = -7, 00358 };
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 692 of file chan_sip.c.
00692 { 00693 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00694 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00695 };
enum invitestates |
States for the INVITE transaction, not the dialog.
Definition at line 258 of file chan_sip.c.
00258 { 00259 INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */ 00260 INV_CALLING = 1, /*!< Invite sent, no answer */ 00261 INV_PROCEEDING = 2, /*!< We got/sent 1xx message */ 00262 INV_EARLY_MEDIA = 3, /*!< We got/sent 18x message with to-tag back */ 00263 INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */ 00264 INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */ 00265 INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 00266 The only way out of this is a BYE from one side */ 00267 INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */ 00268 };
enum media_type |
Definition at line 285 of file chan_sip.c.
00285 { 00286 PARSE_REGISTER_DENIED, 00287 PARSE_REGISTER_FAILED, 00288 PARSE_REGISTER_UPDATE, 00289 PARSE_REGISTER_QUERY, 00290 };
enum referstatus |
Parameters to know status of transfer.
Definition at line 877 of file chan_sip.c.
00877 { 00878 REFER_IDLE, /*!< No REFER is in progress */ 00879 REFER_SENT, /*!< Sent REFER to transferee */ 00880 REFER_RECEIVED, /*!< Received REFER from transferer */ 00881 REFER_CONFIRMED, /*!< Refer confirmed with a 100 TRYING */ 00882 REFER_ACCEPTED, /*!< Accepted by transferee */ 00883 REFER_RINGING, /*!< Target Ringing */ 00884 REFER_200OK, /*!< Answered by transfer target */ 00885 REFER_FAILED, /*!< REFER declined - go on */ 00886 REFER_NOAUTH /*!< We had no auth for REFER */ 00887 };
enum sip_auth_type |
Authentication types - proxy or www authentication.
Definition at line 342 of file chan_sip.c.
00342 { 00343 PROXY_AUTH, 00344 WWW_AUTH, 00345 };
enum sip_result |
Definition at line 250 of file chan_sip.c.
00250 { 00251 AST_SUCCESS = 0, 00252 AST_FAILURE = -1, 00253 };
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 317 of file chan_sip.c.
00317 { 00318 SIP_UNKNOWN, /* Unknown response */ 00319 SIP_RESPONSE, /* Not request, response to outbound request */ 00320 SIP_REGISTER, 00321 SIP_OPTIONS, 00322 SIP_NOTIFY, 00323 SIP_INVITE, 00324 SIP_ACK, 00325 SIP_PRACK, /* Not supported at all */ 00326 SIP_BYE, 00327 SIP_REFER, 00328 SIP_SUBSCRIBE, 00329 SIP_MESSAGE, 00330 SIP_UPDATE, /* We can send UPDATE; but not accept it */ 00331 SIP_INFO, 00332 SIP_CANCEL, 00333 SIP_PUBLISH, /* Not supported at all */ 00334 SIP_PING, /* Not supported at all, no standard but still implemented out there */ 00335 };
enum sipregistrystate |
States for outbound registrations (with register= lines in sip.conf.
Definition at line 361 of file chan_sip.c.
00361 { 00362 REG_STATE_UNREGISTERED = 0, /*!< We are not registered */ 00363 REG_STATE_REGSENT, /*!< Registration request sent */ 00364 REG_STATE_AUTHSENT, /*!< We have tried to authenticate */ 00365 REG_STATE_REGISTERED, /*!< Registered and done */ 00366 REG_STATE_REJECTED, /*!< Registration rejected */ 00367 REG_STATE_TIMEOUT, /*!< Registration timed out */ 00368 REG_STATE_NOAUTH, /*!< We have no accepted credentials */ 00369 REG_STATE_FAILED, /*!< Registration failed after several tries */ 00370 };
enum subscriptiontype |
Definition at line 292 of file chan_sip.c.
00292 { 00293 NONE = 0, 00294 XPIDF_XML, 00295 DIALOG_INFO_XML, 00296 CPIM_PIDF_XML, 00297 PIDF_XML, 00298 MWI_NOTIFICATION 00299 };
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 858 of file chan_sip.c.
00858 { 00859 T38_DISABLED = 0, /*!< Not enabled */ 00860 T38_LOCAL_REINVITE, /*!< Offered from local - REINVITE */ 00861 T38_PEER_DIRECT, /*!< Offered from peer */ 00862 T38_PEER_REINVITE, /*!< Offered from peer - REINVITE */ 00863 T38_ENABLED /*!< Negotiated (enabled) */ 00864 };
enum transfermodes |
Authorization scheme for call transfers.
Definition at line 244 of file chan_sip.c.
00244 { 00245 TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */ 00246 TRANSFER_CLOSED, /*!< Allow no SIP transfers */ 00247 };
enum xmittype |
Definition at line 278 of file chan_sip.c.
00278 { 00279 XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits. 00280 If it fails, it's critical and will cause a teardown of the session */ 00281 XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */ 00282 XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */ 00283 };
static const char * __get_header | ( | const struct sip_request * | req, | |
const char * | name, | |||
int * | start | |||
) | [static] |
Definition at line 4504 of file chan_sip.c.
References ast_skip_blanks(), find_alias(), sip_request::header, sip_request::headers, and len().
04505 { 04506 int pass; 04507 04508 /* 04509 * Technically you can place arbitrary whitespace both before and after the ':' in 04510 * a header, although RFC3261 clearly says you shouldn't before, and place just 04511 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04512 * a good idea to say you can do it, and if you can do it, why in the hell would. 04513 * you say you shouldn't. 04514 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04515 * and we always allow spaces after that for compatibility. 04516 */ 04517 for (pass = 0; name && pass < 2;pass++) { 04518 int x, len = strlen(name); 04519 for (x=*start; x<req->headers; x++) { 04520 if (!strncasecmp(req->header[x], name, len)) { 04521 char *r = req->header[x] + len; /* skip name */ 04522 if (pedanticsipchecking) 04523 r = ast_skip_blanks(r); 04524 04525 if (*r == ':') { 04526 *start = x+1; 04527 return ast_skip_blanks(r+1); 04528 } 04529 } 04530 } 04531 if (pass == 0) /* Try aliases */ 04532 name = find_alias(name, NULL); 04533 } 04534 04535 /* Don't return NULL, so get_header is always a valid pointer */ 04536 return ""; 04537 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 19677 of file chan_sip.c.
static int __set_address_from_contact | ( | const char * | fullcontact, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 8618 of file chan_sip.c.
References ahp, ast_copy_string(), ast_gethostbyname(), ast_log(), hp, LOG_NOTICE, and STANDARD_SIP_PORT.
Referenced by build_peer(), and set_address_from_contact().
08619 { 08620 struct hostent *hp; 08621 struct ast_hostent ahp; 08622 int port; 08623 char *c, *host, *pt; 08624 char contact_buf[256]; 08625 char *contact; 08626 08627 /* Work on a copy */ 08628 ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf)); 08629 contact = contact_buf; 08630 08631 /* Make sure it's a SIP URL */ 08632 if (strncasecmp(contact, "sip:", 4)) { 08633 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 08634 } else 08635 contact += 4; 08636 08637 /* Ditch arguments */ 08638 /* XXX this code is replicated also shortly below */ 08639 08640 /* Grab host */ 08641 host = strchr(contact, '@'); 08642 if (!host) { /* No username part */ 08643 host = contact; 08644 c = NULL; 08645 } else { 08646 *host++ = '\0'; 08647 } 08648 pt = strchr(host, ':'); 08649 if (pt) { 08650 *pt++ = '\0'; 08651 port = atoi(pt); 08652 } else 08653 port = STANDARD_SIP_PORT; 08654 08655 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 08656 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 08657 08658 /* XXX This could block for a long time XXX */ 08659 /* We should only do this if it's a name, not an IP */ 08660 hp = ast_gethostbyname(host, &ahp); 08661 if (!hp) { 08662 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 08663 return -1; 08664 } 08665 sin->sin_family = AF_INET; 08666 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 08667 sin->sin_port = htons(port); 08668 08669 return 0; 08670 }
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 2223 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, sched, 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().
02224 { 02225 struct sip_pkt *cur, *prev = NULL; 02226 02227 /* Just in case... */ 02228 char *msg; 02229 int res = FALSE; 02230 02231 msg = sip_methods[sipmethod].text; 02232 02233 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02234 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02235 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02236 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02237 if (!resp && (seqno == p->pendinginvite)) { 02238 if (option_debug) 02239 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02240 p->pendinginvite = 0; 02241 } 02242 /* this is our baby */ 02243 res = TRUE; 02244 UNLINK(cur, p->packets, prev); 02245 if (cur->retransid > -1) { 02246 if (sipdebug && option_debug > 3) 02247 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02248 } 02249 /* This odd section is designed to thwart a 02250 * race condition in the packet scheduler. There are 02251 * two conditions under which deleting the packet from the 02252 * scheduler can fail. 02253 * 02254 * 1. The packet has been removed from the scheduler because retransmission 02255 * is being attempted. The problem is that if the packet is currently attempting 02256 * retransmission and we are at this point in the code, then that MUST mean 02257 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 02258 * lock temporarily to allow retransmission. 02259 * 02260 * 2. The packet has reached its maximum number of retransmissions and has 02261 * been permanently removed from the packet scheduler. If this is the case, then 02262 * the packet's retransid will be set to -1. The atomicity of the setting and checking 02263 * of the retransid to -1 is ensured since in both cases p's lock is held. 02264 */ 02265 AST_SCHED_DEL_SPINLOCK(sched, cur->retransid, &p->lock); 02266 free(cur); 02267 break; 02268 } 02269 } 02270 if (option_debug) 02271 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"); 02272 return res; 02273 }
static int __sip_autodestruct | ( | const void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 2136 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup(), ast_set_flag, ast_test_flag, ASTOBJ_UNREF, sip_pvt::autokillid, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_pvt::lastmsg, LOG_DEBUG, LOG_WARNING, sip_pvt::method, method_match(), NONE, option_debug, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, sip_pvt::relatedpeer, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, sip_scheddestroy(), sip_pvt::subscribed, transmit_request_with_auth(), transmit_state_notify(), TRUE, and XMIT_RELIABLE.
Referenced by sip_scheddestroy().
02137 { 02138 struct sip_pvt *p = (struct sip_pvt *)data; 02139 02140 /* If this is a subscription, tell the phone that we got a timeout */ 02141 if (p->subscribed) { 02142 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 02143 p->subscribed = NONE; 02144 append_history(p, "Subscribestatus", "timeout"); 02145 if (option_debug > 2) 02146 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02147 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02148 } 02149 02150 /* If there are packets still waiting for delivery, delay the destruction */ 02151 /* via bug 12101, the two usages of SIP_NEEDDESTROY in the following block 02152 * of code make a sort of "safety relief valve", that allows sip channels 02153 * that were created via INVITE, then thru some sequence were CANCELED, 02154 * to die, rather than infinitely be rescheduled */ 02155 if (p->packets && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 02156 char method_str[31]; 02157 if (option_debug > 2) 02158 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 02159 append_history(p, "ReliableXmit", "timeout"); 02160 if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) { 02161 if (method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) { 02162 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 02163 } 02164 } 02165 return 10000; 02166 } 02167 02168 /* If we're destroying a subscription, dereference peer object too */ 02169 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 02170 ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer); 02171 02172 /* Reset schedule ID */ 02173 p->autokillid = -1; 02174 02175 if (option_debug) 02176 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02177 append_history(p, "AutoDestroy", "%s", p->callid); 02178 if (p->owner) { 02179 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02180 ast_queue_hangup(p->owner); 02181 } else if (p->refer && !ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 02182 if (option_debug > 2) 02183 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02184 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02185 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02186 } else 02187 sip_destroy(p); 02188 return 0; 02189 }
static int __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 3242 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_rtp_destroy(), ast_rtp_get_bridged(), AST_SCHED_DEL, AST_SOFTHANGUP_DEV, ast_test_flag, ast_udptl_destroy(), ast_verbose(), ASTOBJ_UNREF, sip_pvt::callid, DEC_CALL_LIMIT, sip_pvt::flags, free, free_old_route(), iflist, sip_history::list, LOG_DEBUG, sip_pvt::method, sip_peer::mwipvt, ast_channel::name, sip_pvt::next, sip_history::next, option_debug, sip_pvt::owner, sip_pvt::relatedpeer, sip_pkt::retransid, sip_pvt::rtp, sched, sip_debug_test_pvt(), sip_destroy_peer(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_registry_destroy(), ast_channel::tech_pvt, UNLINK, update_call_counter(), and sip_pvt::vrtp.
Referenced by do_monitor(), sip_destroy(), and unload_module().
03243 { 03244 struct sip_pvt *cur, *prev = NULL; 03245 struct sip_pkt *cp; 03246 struct sip_request *req; 03247 03248 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 03249 if (p->rtp && ast_rtp_get_bridged(p->rtp)) { 03250 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03251 return -1; 03252 } 03253 03254 if (p->vrtp && ast_rtp_get_bridged(p->vrtp)) { 03255 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03256 return -1; 03257 } 03258 03259 if (sip_debug_test_pvt(p) || option_debug > 2) 03260 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03261 03262 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03263 update_call_counter(p, DEC_CALL_LIMIT); 03264 if (option_debug > 1) 03265 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 03266 } 03267 03268 /* Unlink us from the owner if we have one */ 03269 if (p->owner) { 03270 if (lockowner) 03271 ast_channel_lock(p->owner); 03272 if (option_debug) 03273 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 03274 p->owner->tech_pvt = NULL; 03275 /* Make sure that the channel knows its backend is going away */ 03276 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03277 if (lockowner) 03278 ast_channel_unlock(p->owner); 03279 /* Give the channel a chance to react before deallocation */ 03280 usleep(1); 03281 } 03282 03283 /* Remove link from peer to subscription of MWI */ 03284 if (p->relatedpeer) { 03285 if (p->relatedpeer->mwipvt == p) { 03286 p->relatedpeer->mwipvt = NULL; 03287 } 03288 ASTOBJ_UNREF(p->relatedpeer, sip_destroy_peer); 03289 } 03290 03291 if (dumphistory) 03292 sip_dump_history(p); 03293 03294 if (p->options) 03295 free(p->options); 03296 03297 if (p->stateid > -1) 03298 ast_extension_state_del(p->stateid, NULL); 03299 AST_SCHED_DEL(sched, p->initid); 03300 AST_SCHED_DEL(sched, p->waitid); 03301 AST_SCHED_DEL(sched, p->autokillid); 03302 AST_SCHED_DEL(sched, p->request_queue_sched_id); 03303 AST_SCHED_DEL(sched, p->provisional_keepalive_sched_id); 03304 03305 if (p->rtp) { 03306 ast_rtp_destroy(p->rtp); 03307 } 03308 if (p->vrtp) { 03309 ast_rtp_destroy(p->vrtp); 03310 } 03311 if (p->udptl) 03312 ast_udptl_destroy(p->udptl); 03313 if (p->refer) 03314 free(p->refer); 03315 if (p->route) { 03316 free_old_route(p->route); 03317 p->route = NULL; 03318 } 03319 if (p->registry) { 03320 if (p->registry->call == p) 03321 p->registry->call = NULL; 03322 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 03323 } 03324 03325 /* Clear history */ 03326 if (p->history) { 03327 struct sip_history *hist; 03328 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 03329 free(hist); 03330 p->history_entries--; 03331 } 03332 free(p->history); 03333 p->history = NULL; 03334 } 03335 03336 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 03337 ast_free(req); 03338 } 03339 03340 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 03341 if (cur == p) { 03342 UNLINK(cur, iflist, prev); 03343 break; 03344 } 03345 } 03346 if (!cur) { 03347 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 03348 return 0; 03349 } 03350 03351 /* remove all current packets in this dialog */ 03352 while((cp = p->packets)) { 03353 p->packets = p->packets->next; 03354 AST_SCHED_DEL(sched, cp->retransid); 03355 free(cp); 03356 } 03357 if (p->chanvars) { 03358 ast_variables_destroy(p->chanvars); 03359 p->chanvars = NULL; 03360 } 03361 ast_mutex_destroy(&p->lock); 03362 03363 ast_string_field_free_memory(p); 03364 03365 free(p); 03366 return 0; 03367 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 8043 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
08044 { 08045 int res; 08046 08047 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 08048 return res; 08049 }
static void __sip_pretend_ack | ( | struct sip_pvt * | p | ) | [static] |
Pretend to ack all packets called with p locked.
Definition at line 2277 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, and sip_methods.
Referenced by handle_request_bye(), handle_request_cancel(), sip_hangup(), and sip_reg_timeout().
02278 { 02279 struct sip_pkt *cur = NULL; 02280 02281 while (p->packets) { 02282 int method; 02283 if (cur == p->packets) { 02284 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02285 return; 02286 } 02287 cur = p->packets; 02288 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02289 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02290 } 02291 }
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 2083 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, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, LOG_DEBUG, option_debug, sip_pkt::owner, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), sched, SIP_INVITE, sipdebug, sip_pvt::timer_t1, and XMIT_ERROR.
Referenced by send_request(), and send_response().
02084 { 02085 struct sip_pkt *pkt; 02086 int siptimer_a = DEFAULT_RETRANS; 02087 int xmitres = 0; 02088 int respid; 02089 02090 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 02091 return AST_FAILURE; 02092 memcpy(pkt->data, data, len); 02093 pkt->method = sipmethod; 02094 pkt->packetlen = len; 02095 pkt->next = p->packets; 02096 pkt->owner = p; 02097 pkt->seqno = seqno; 02098 pkt->data[len] = '\0'; 02099 if (resp) { 02100 ast_set_flag(pkt, FLAG_RESPONSE); 02101 /* Parse out the response code */ 02102 if (sscanf(pkt->data, "SIP/2.0 %30d", &respid) == 1) { 02103 pkt->response_code = respid; 02104 } 02105 } 02106 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 02107 pkt->retransid = -1; 02108 if (fatal) 02109 ast_set_flag(pkt, FLAG_FATAL); 02110 if (pkt->timer_t1) 02111 siptimer_a = pkt->timer_t1 * 2; 02112 02113 if (option_debug > 3 && sipdebug) 02114 ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 02115 pkt->retransid = -1; 02116 pkt->next = p->packets; 02117 p->packets = pkt; 02118 if (sipmethod == SIP_INVITE) { 02119 /* Note this is a pending invite */ 02120 p->pendinginvite = seqno; 02121 } 02122 02123 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 02124 02125 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02126 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02127 return AST_FAILURE; 02128 } else { 02129 /* Schedule retransmission */ 02130 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 02131 return AST_SUCCESS; 02132 } 02133 }
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 2294 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, sched, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, and TRUE.
Referenced by handle_response(), and sip_hangup().
02295 { 02296 struct sip_pkt *cur; 02297 int res = FALSE; 02298 02299 for (cur = p->packets; cur; cur = cur->next) { 02300 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02301 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02302 /* this is our baby */ 02303 if (cur->retransid > -1) { 02304 if (option_debug > 3 && sipdebug) 02305 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02306 } 02307 AST_SCHED_DEL(sched, cur->retransid); 02308 res = TRUE; 02309 break; 02310 } 02311 } 02312 if (option_debug) 02313 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"); 02314 return res; 02315 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
SIP show channels CLI (main function).
Definition at line 11601 of file chan_sip.c.
References ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock, ast_test_flag, sip_pvt::callid, sip_pvt::cid_num, sip_pvt::flags, FORMAT, FORMAT2, FORMAT3H, sip_pvt::icseq, iflist, iflock, sip_pvt::lastmsg, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, sip_pvt::refer, referstatus2str(), RESULT_SHOWUSAGE, S_OR, sip_pvt::sa, SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, SIPBUFSIZE, sip_refer::status, sip_pvt::subscribed, and sip_pvt::username.
Referenced by sip_show_channels(), and sip_show_subscriptions().
11602 { 11603 #define FORMAT3L "%-15.15s %-15.15s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" 11604 #define FORMAT3H "%-15.15s %-15.15s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" 11605 #define FORMAT2 "%-15.15s %-15.15s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" 11606 #define FORMAT "%-15.15s %-15.15s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" 11607 struct sip_pvt *cur; 11608 int numchans = 0; 11609 int usedchans = 0; 11610 char *referstatus = NULL; 11611 11612 if (argc != 3) 11613 return RESULT_SHOWUSAGE; 11614 ast_mutex_lock(&iflock); 11615 cur = iflist; 11616 if (!subscriptions) 11617 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 11618 else 11619 ast_cli(fd, FORMAT3H, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry"); 11620 for (; cur; cur = cur->next) { 11621 referstatus = ""; 11622 if (cur->refer) { /* SIP transfer in progress */ 11623 referstatus = referstatus2str(cur->refer->status); 11624 } 11625 if (cur->subscribed == NONE && !subscriptions) { 11626 char formatbuf[SIPBUFSIZE/2]; 11627 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 11628 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 11629 cur->callid, 11630 cur->ocseq, cur->icseq, 11631 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 11632 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 11633 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 11634 cur->lastmsg , 11635 referstatus 11636 ); 11637 numchans++; 11638 } 11639 if (cur->subscribed != NONE && subscriptions) { 11640 ast_cli(fd, FORMAT3L, ast_inet_ntoa(cur->sa.sin_addr), 11641 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 11642 cur->callid, 11643 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 11644 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 11645 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 11646 subscription_type2str(cur->subscribed), 11647 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>", 11648 cur->expiry 11649 ); 11650 numchans++; 11651 } 11652 if (cur->owner) { /* Count SIP dialog owned by a real channel */ 11653 usedchans++; 11654 } 11655 } 11656 ast_mutex_unlock(&iflock); 11657 if (!subscriptions) 11658 ast_cli(fd, "%d active SIP dialog%s\n", numchans, (numchans != 1) ? "s" : ""); 11659 else 11660 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 11661 ast_cli(fd, "%d used SIP channel%s\n", usedchans, (usedchans != 1) ? "s" : ""); 11662 return RESULT_SUCCESS; 11663 #undef FORMAT 11664 #undef FORMAT2 11665 #undef FORMAT3 11666 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message.
Definition at line 1832 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().
01833 { 01834 int res; 01835 const struct sockaddr_in *dst = sip_real_dst(p); 01836 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01837 01838 if (res == -1) { 01839 switch (errno) { 01840 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 01841 case EHOSTUNREACH: /* Host can't be reached */ 01842 case ENETDOWN: /* Inteface down */ 01843 case ENETUNREACH: /* Network failure */ 01844 case ECONNREFUSED: /* ICMP port unreachable */ 01845 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 01846 } 01847 01848 } 01849 01850 if (res != len) 01851 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)); 01852 return res; 01853 }
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 6578 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), get_header(), ast_channel::hangupcause, sip_pvt::method, sip_pvt::owner, respprep(), send_response(), and SIP_INVITE.
Referenced by transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().
06579 { 06580 struct sip_request resp; 06581 int seqno = 0; 06582 06583 if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) { 06584 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06585 return -1; 06586 } 06587 respprep(&resp, p, msg, req); 06588 add_header_contentLength(&resp, 0); 06589 /* If we are cancelling an incoming invite for some reason, add information 06590 about the reason why we are doing this in clear text */ 06591 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 06592 char buf[10]; 06593 06594 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 06595 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 06596 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 06597 } 06598 return send_response(p, &resp, reliable, seqno); 06599 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 19677 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 11158 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, 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, S_OR, sched, 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_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().
11159 { 11160 char status[30] = ""; 11161 char cbuf[256]; 11162 struct sip_peer *peer; 11163 char codec_buf[512]; 11164 struct ast_codec_pref *pref; 11165 struct ast_variable *v; 11166 struct sip_auth *auth; 11167 int x = 0, codec = 0, load_realtime; 11168 int realtimepeers; 11169 11170 realtimepeers = ast_check_realtime("sippeers"); 11171 11172 if (argc < 4) 11173 return RESULT_SHOWUSAGE; 11174 11175 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 11176 peer = find_peer(argv[3], NULL, load_realtime, 0); 11177 if (s) { /* Manager */ 11178 if (peer) { 11179 const char *id = astman_get_header(m,"ActionID"); 11180 11181 astman_append(s, "Response: Success\r\n"); 11182 if (!ast_strlen_zero(id)) 11183 astman_append(s, "ActionID: %s\r\n",id); 11184 } else { 11185 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]); 11186 astman_send_error(s, m, cbuf); 11187 return 0; 11188 } 11189 } 11190 if (peer && type==0 ) { /* Normal listing */ 11191 ast_cli(fd,"\n\n"); 11192 ast_cli(fd, " * Name : %s\n", peer->name); 11193 if (realtimepeers) { /* Realtime is enabled */ 11194 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 11195 } 11196 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 11197 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 11198 for (auth = peer->auth; auth; auth = auth->next) { 11199 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 11200 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 11201 } 11202 ast_cli(fd, " Context : %s\n", peer->context); 11203 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 11204 ast_cli(fd, " Language : %s\n", peer->language); 11205 if (!ast_strlen_zero(peer->accountcode)) 11206 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 11207 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 11208 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 11209 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 11210 if (!ast_strlen_zero(peer->fromuser)) 11211 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 11212 if (!ast_strlen_zero(peer->fromdomain)) 11213 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 11214 ast_cli(fd, " Callgroup : "); 11215 print_group(fd, peer->callgroup, 0); 11216 ast_cli(fd, " Pickupgroup : "); 11217 print_group(fd, peer->pickupgroup, 0); 11218 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 11219 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 11220 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 11221 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 11222 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 11223 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 11224 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 11225 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 11226 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))); 11227 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 11228 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 11229 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 11230 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 11231 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 11232 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 11233 #endif 11234 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 11235 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 11236 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 11237 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 11238 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 11239 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 11240 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 11241 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 11242 11243 /* - is enumerated */ 11244 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 11245 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 11246 ast_cli(fd, " ToHost : %s\n", peer->tohost); 11247 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)); 11248 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 11249 if (!ast_strlen_zero(global_regcontext)) 11250 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 11251 ast_cli(fd, " Def. Username: %s\n", peer->username); 11252 ast_cli(fd, " SIP Options : "); 11253 if (peer->sipoptions) { 11254 int lastoption = -1; 11255 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 11256 if (sip_options[x].id != lastoption) { 11257 if (peer->sipoptions & sip_options[x].id) 11258 ast_cli(fd, "%s ", sip_options[x].text); 11259 lastoption = x; 11260 } 11261 } 11262 } else 11263 ast_cli(fd, "(none)"); 11264 11265 ast_cli(fd, "\n"); 11266 ast_cli(fd, " Codecs : "); 11267 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 11268 ast_cli(fd, "%s\n", codec_buf); 11269 ast_cli(fd, " Codec Order : ("); 11270 print_codec_to_cli(fd, &peer->prefs); 11271 ast_cli(fd, ")\n"); 11272 11273 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 11274 ast_cli(fd, " Status : "); 11275 peer_status(peer, status, sizeof(status)); 11276 ast_cli(fd, "%s\n",status); 11277 ast_cli(fd, " Useragent : %s\n", peer->useragent); 11278 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 11279 if (peer->chanvars) { 11280 ast_cli(fd, " Variables :\n"); 11281 for (v = peer->chanvars ; v ; v = v->next) 11282 ast_cli(fd, " %s = %s\n", v->name, v->value); 11283 } 11284 ast_cli(fd,"\n"); 11285 ASTOBJ_UNREF(peer,sip_destroy_peer); 11286 } else if (peer && type == 1) { /* manager listing */ 11287 char buf[256]; 11288 astman_append(s, "Channeltype: SIP\r\n"); 11289 astman_append(s, "ObjectName: %s\r\n", peer->name); 11290 astman_append(s, "ChanObjectType: peer\r\n"); 11291 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 11292 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 11293 astman_append(s, "Context: %s\r\n", peer->context); 11294 astman_append(s, "Language: %s\r\n", peer->language); 11295 if (!ast_strlen_zero(peer->accountcode)) 11296 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 11297 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 11298 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 11299 if (!ast_strlen_zero(peer->fromuser)) 11300 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 11301 if (!ast_strlen_zero(peer->fromdomain)) 11302 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 11303 astman_append(s, "Callgroup: "); 11304 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 11305 astman_append(s, "Pickupgroup: "); 11306 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 11307 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 11308 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 11309 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 11310 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 11311 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 11312 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 11313 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 11314 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 11315 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))); 11316 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 11317 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 11318 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 11319 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 11320 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 11321 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 11322 11323 /* - is enumerated */ 11324 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 11325 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 11326 astman_append(s, "ToHost: %s\r\n", peer->tohost); 11327 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)); 11328 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)); 11329 astman_append(s, "Default-Username: %s\r\n", peer->username); 11330 if (!ast_strlen_zero(global_regcontext)) 11331 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 11332 astman_append(s, "Codecs: "); 11333 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 11334 astman_append(s, "%s\r\n", codec_buf); 11335 astman_append(s, "CodecOrder: "); 11336 pref = &peer->prefs; 11337 for(x = 0; x < 32 ; x++) { 11338 codec = ast_codec_pref_index(pref,x); 11339 if (!codec) 11340 break; 11341 astman_append(s, "%s", ast_getformatname(codec)); 11342 if (x < 31 && ast_codec_pref_index(pref,x+1)) 11343 astman_append(s, ","); 11344 } 11345 11346 astman_append(s, "\r\n"); 11347 astman_append(s, "Status: "); 11348 peer_status(peer, status, sizeof(status)); 11349 astman_append(s, "%s\r\n", status); 11350 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 11351 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 11352 if (peer->chanvars) { 11353 for (v = peer->chanvars ; v ; v = v->next) { 11354 astman_append(s, "ChanVariable:\n"); 11355 astman_append(s, " %s,%s\r\n", v->name, v->value); 11356 } 11357 } 11358 11359 ASTOBJ_UNREF(peer,sip_destroy_peer); 11360 11361 } else { 11362 ast_cli(fd,"Peer %s not found.\n", argv[3]); 11363 ast_cli(fd,"\n"); 11364 } 11365 11366 return RESULT_SUCCESS; 11367 }
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 10708 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, s, SIP_NAT_ROUTE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_VIDEOSUPPORT, SIP_REALTIME, and TRUE.
Referenced by manager_sip_show_peers(), and sip_show_peers().
10709 { 10710 regex_t regexbuf; 10711 int havepattern = FALSE; 10712 10713 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 10714 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 10715 10716 char name[256]; 10717 int total_peers = 0; 10718 int peers_mon_online = 0; 10719 int peers_mon_offline = 0; 10720 int peers_unmon_offline = 0; 10721 int peers_unmon_online = 0; 10722 const char *id; 10723 char idtext[256] = ""; 10724 int realtimepeers; 10725 10726 realtimepeers = ast_check_realtime("sippeers"); 10727 10728 if (s) { /* Manager - get ActionID */ 10729 id = astman_get_header(m,"ActionID"); 10730 if (!ast_strlen_zero(id)) 10731 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10732 } 10733 10734 switch (argc) { 10735 case 5: 10736 if (!strcasecmp(argv[3], "like")) { 10737 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 10738 return RESULT_SHOWUSAGE; 10739 havepattern = TRUE; 10740 } else 10741 return RESULT_SHOWUSAGE; 10742 case 3: 10743 break; 10744 default: 10745 return RESULT_SHOWUSAGE; 10746 } 10747 10748 if (!s) /* Normal list */ 10749 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 10750 10751 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10752 char status[20] = ""; 10753 char srch[2000]; 10754 char pstatus; 10755 10756 ASTOBJ_RDLOCK(iterator); 10757 10758 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10759 ASTOBJ_UNLOCK(iterator); 10760 continue; 10761 } 10762 10763 if (!ast_strlen_zero(iterator->username) && !s) 10764 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 10765 else 10766 ast_copy_string(name, iterator->name, sizeof(name)); 10767 10768 pstatus = peer_status(iterator, status, sizeof(status)); 10769 if (pstatus == 1) 10770 peers_mon_online++; 10771 else if (pstatus == 0) 10772 peers_mon_offline++; 10773 else { 10774 if (iterator->addr.sin_port == 0) 10775 peers_unmon_offline++; 10776 else 10777 peers_unmon_online++; 10778 } 10779 10780 snprintf(srch, sizeof(srch), FORMAT, name, 10781 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10782 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10783 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10784 iterator->ha ? " A " : " ", /* permit/deny */ 10785 ntohs(iterator->addr.sin_port), status, 10786 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10787 10788 if (!s) {/* Normal CLI list */ 10789 ast_cli(fd, FORMAT, name, 10790 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10791 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10792 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10793 iterator->ha ? " A " : " ", /* permit/deny */ 10794 10795 ntohs(iterator->addr.sin_port), status, 10796 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10797 } else { /* Manager format */ 10798 /* The names here need to be the same as other channels */ 10799 astman_append(s, 10800 "Event: PeerEntry\r\n%s" 10801 "Channeltype: SIP\r\n" 10802 "ObjectName: %s\r\n" 10803 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 10804 "IPaddress: %s\r\n" 10805 "IPport: %d\r\n" 10806 "Dynamic: %s\r\n" 10807 "Natsupport: %s\r\n" 10808 "VideoSupport: %s\r\n" 10809 "ACL: %s\r\n" 10810 "Status: %s\r\n" 10811 "RealtimeDevice: %s\r\n\r\n", 10812 idtext, 10813 iterator->name, 10814 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 10815 ntohs(iterator->addr.sin_port), 10816 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 10817 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 10818 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 10819 iterator->ha ? "yes" : "no", /* permit/deny */ 10820 status, 10821 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 10822 } 10823 10824 ASTOBJ_UNLOCK(iterator); 10825 10826 total_peers++; 10827 } while(0) ); 10828 10829 if (!s) 10830 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 10831 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 10832 10833 if (havepattern) 10834 regfree(®exbuf); 10835 10836 if (total) 10837 *total = total_peers; 10838 10839 10840 return RESULT_SUCCESS; 10841 #undef FORMAT 10842 #undef FORMAT2 10843 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 15910 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(), LOG_ERROR, parse(), sip_pvt::rtp, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, type, and sip_pvt::vrtp.
15911 { 15912 struct ast_rtp_quality qos; 15913 struct sip_pvt *p = chan->tech_pvt; 15914 char *all = "", *parse = ast_strdupa(preparse); 15915 AST_DECLARE_APP_ARGS(args, 15916 AST_APP_ARG(param); 15917 AST_APP_ARG(type); 15918 AST_APP_ARG(field); 15919 ); 15920 AST_STANDARD_APP_ARGS(args, parse); 15921 15922 /* Sanity check */ 15923 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 15924 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 15925 return 0; 15926 } 15927 15928 if (strcasecmp(args.param, "rtpqos")) 15929 return 0; 15930 15931 /* Default arguments of audio,all */ 15932 if (ast_strlen_zero(args.type)) 15933 args.type = "audio"; 15934 if (ast_strlen_zero(args.field)) 15935 args.field = "all"; 15936 15937 memset(buf, 0, buflen); 15938 memset(&qos, 0, sizeof(qos)); 15939 15940 if (p == NULL) { 15941 return -1; 15942 } 15943 15944 if (strcasecmp(args.type, "AUDIO") == 0) { 15945 all = ast_rtp_get_quality(p->rtp, &qos); 15946 } else if (strcasecmp(args.type, "VIDEO") == 0) { 15947 all = ast_rtp_get_quality(p->vrtp, &qos); 15948 } 15949 15950 if (strcasecmp(args.field, "local_ssrc") == 0) 15951 snprintf(buf, buflen, "%u", qos.local_ssrc); 15952 else if (strcasecmp(args.field, "local_lostpackets") == 0) 15953 snprintf(buf, buflen, "%u", qos.local_lostpackets); 15954 else if (strcasecmp(args.field, "local_jitter") == 0) 15955 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 15956 else if (strcasecmp(args.field, "local_count") == 0) 15957 snprintf(buf, buflen, "%u", qos.local_count); 15958 else if (strcasecmp(args.field, "remote_ssrc") == 0) 15959 snprintf(buf, buflen, "%u", qos.remote_ssrc); 15960 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 15961 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 15962 else if (strcasecmp(args.field, "remote_jitter") == 0) 15963 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 15964 else if (strcasecmp(args.field, "remote_count") == 0) 15965 snprintf(buf, buflen, "%u", qos.remote_count); 15966 else if (strcasecmp(args.field, "rtt") == 0) 15967 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 15968 else if (strcasecmp(args.field, "all") == 0) 15969 ast_copy_string(buf, all, buflen); 15970 else { 15971 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 15972 return -1; 15973 } 15974 return 0; 15975 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2328 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
02329 { 02330 if (!req->lines) { 02331 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 02332 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 02333 req->len += strlen(req->data + req->len); 02334 } 02335 }
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 6796 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().
06799 { 06800 int rtp_code; 06801 struct ast_format_list fmt; 06802 06803 06804 if (debug) 06805 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 06806 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 06807 return; 06808 06809 if (p->rtp) { 06810 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06811 fmt = ast_codec_pref_getsize(pref, codec); 06812 } 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 */ 06813 return; 06814 ast_build_string(m_buf, m_size, " %d", rtp_code); 06815 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06816 ast_rtp_lookup_mime_subtype(1, codec, 06817 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 06818 sample_rate); 06819 if (codec == AST_FORMAT_G729A) { 06820 /* Indicate that we don't support VAD (G.729 annex B) */ 06821 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 06822 } else if (codec == AST_FORMAT_G723_1) { 06823 /* Indicate that we don't support VAD (G.723.1 annex A) */ 06824 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 06825 } else if (codec == AST_FORMAT_ILBC) { 06826 /* Add information about us using only 20/30 ms packetization */ 06827 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 06828 } 06829 06830 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 06831 *min_packet_size = fmt.cur_ms; 06832 06833 /* Our first codec packetization processed cannot be less than zero */ 06834 if ((*min_packet_size) == 0 && fmt.cur_ms) 06835 *min_packet_size = fmt.cur_ms; 06836 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 6764 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
06765 { 06766 char tmp[256]; 06767 06768 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 06769 add_header(req, "Content-Type", "application/dtmf-relay"); 06770 add_header_contentLength(req, strlen(tmp)); 06771 add_line(req, tmp); 06772 return 0; 06773 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 6075 of file chan_sip.c.
References ast_log(), sip_request::data, find_alias(), sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, and SIP_MAX_HEADERS.
06076 { 06077 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 06078 06079 if (req->headers == SIP_MAX_HEADERS) { 06080 ast_log(LOG_WARNING, "Out of SIP header space\n"); 06081 return -1; 06082 } 06083 06084 if (req->lines) { 06085 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 06086 return -1; 06087 } 06088 06089 if (maxlen <= 0) { 06090 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 06091 return -1; 06092 } 06093 06094 req->header[req->headers] = req->data + req->len; 06095 06096 if (compactheaders) 06097 var = find_alias(var, var); 06098 06099 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 06100 req->len += strlen(req->header[req->headers]); 06101 req->headers++; 06102 06103 return 0; 06104 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 6107 of file chan_sip.c.
References add_header().
Referenced by __transmit_response(), add_digit(), add_sdp(), add_text(), add_vidupdate(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_request(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_unsupported(), and transmit_state_notify().
06108 { 06109 char clen[10]; 06110 06111 snprintf(clen, sizeof(clen), "%d", len); 06112 return add_header(req, "Content-Length", clen); 06113 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 6116 of file chan_sip.c.
References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, and SIP_MAX_LINES.
06117 { 06118 if (req->lines == SIP_MAX_LINES) { 06119 ast_log(LOG_WARNING, "Out of SIP line space\n"); 06120 return -1; 06121 } 06122 if (!req->lines) { 06123 /* Add extra empty return */ 06124 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 06125 req->len += strlen(req->data + req->len); 06126 } 06127 if (req->len >= sizeof(req->data) - 4) { 06128 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 06129 return -1; 06130 } 06131 req->line[req->lines] = req->data + req->len; 06132 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 06133 req->len += strlen(req->line[req->lines]); 06134 req->lines++; 06135 return 0; 06136 }
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 6875 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().
06878 { 06879 int rtp_code; 06880 06881 if (debug) 06882 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06883 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06884 return; 06885 06886 ast_build_string(m_buf, m_size, " %d", rtp_code); 06887 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06888 ast_rtp_lookup_mime_subtype(0, format, 0), 06889 sample_rate); 06890 if (format == AST_RTP_DTMF) 06891 /* Indicate we support DTMF and FLASH... */ 06892 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06893 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static] |
Add realm authentication in list.
Definition at line 17667 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_log(), ast_strlen_zero(), ast_verbose(), LOG_DEBUG, sip_auth::md5secret, sip_auth::next, option_debug, option_verbose, sip_auth::realm, secret, and username.
Referenced by build_peer().
17668 { 17669 char authcopy[256]; 17670 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 17671 struct sip_auth *a, *b, *auth; 17672 17673 if (ast_strlen_zero(configuration)) 17674 return authlist; 17675 17676 if (option_debug) 17677 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 17678 17679 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 17680 17681 username = authcopy; 17682 /* split user[:secret] and realm */ 17683 realm = strrchr(username, '@'); 17684 if (realm) 17685 *realm++ = '\0'; 17686 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 17687 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 17688 return authlist; 17689 } 17690 17691 /* parse username at ':' for secret, or '#" for md5secret */ 17692 if ((secret = strchr(username, ':'))) { 17693 *secret++ = '\0'; 17694 } else if ((md5secret = strchr(username, '#'))) { 17695 *md5secret++ = '\0'; 17696 } 17697 17698 if (!(auth = ast_calloc(1, sizeof(*auth)))) 17699 return authlist; 17700 17701 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 17702 ast_copy_string(auth->username, username, sizeof(auth->username)); 17703 if (secret) 17704 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 17705 if (md5secret) 17706 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 17707 17708 /* find the end of the list */ 17709 for (b = NULL, a = authlist; a ; b = a, a = a->next) 17710 ; 17711 if (b) 17712 b->next = auth; /* Add structure add end of list */ 17713 else 17714 authlist = auth; 17715 17716 if (option_verbose > 2) 17717 ast_verbose("Added authentication for realm %s\n", realm); 17718 17719 return authlist; 17720 17721 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 6237 of file chan_sip.c.
References add_header(), ast_copy_string(), sip_route::hop, sip_route::next, and SIPBUFSIZE.
Referenced by initreqprep(), and reqprep().
06238 { 06239 char r[SIPBUFSIZE*2], *p; 06240 int n, rem = sizeof(r); 06241 06242 if (!route) 06243 return; 06244 06245 p = r; 06246 for (;route ; route = route->next) { 06247 n = strlen(route->hop); 06248 if (rem < n+3) /* we need room for ",<route>" */ 06249 break; 06250 if (p != r) { /* add a separator after fist route */ 06251 *p++ = ','; 06252 --rem; 06253 } 06254 *p++ = '<'; 06255 ast_copy_string(p, route->hop, rem); /* cannot fail */ 06256 p += n; 06257 *p++ = '>'; 06258 rem -= (n+2); 06259 } 06260 *p = '\0'; 06261 add_header(req, "Route", r); 06262 }
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 6903 of file chan_sip.c.
References add_codec_to_sdp(), add_header(), add_header_contentLength(), add_line(), 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, len(), LOG_DEBUG, sip_pvt::maxcallbitrate, sip_pvt::offered_media, option_debug, sip_pvt::ourip, sip_pvt::owner, t38properties::peercapability, sip_pvt::prefcodec, sip_pvt::prefs, 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, TRUE, sip_pvt::udptl, sip_pvt::udptlredirip, sip_pvt::vredirip, and sip_pvt::vrtp.
06904 { 06905 int len = 0; 06906 int alreadysent = 0; 06907 06908 struct sockaddr_in sin; 06909 struct sockaddr_in vsin; 06910 struct sockaddr_in dest; 06911 struct sockaddr_in vdest = { 0, }; 06912 06913 /* SDP fields */ 06914 char *version = "v=0\r\n"; /* Protocol version */ 06915 char *subject = "s=session\r\n"; /* Subject of the session */ 06916 char owner[256]; /* Session owner/creator */ 06917 char connection[256]; /* Connection data */ 06918 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06919 char bandwidth[256] = ""; /* Max bitrate */ 06920 char *hold; 06921 char m_audio[256]; /* Media declaration line for audio */ 06922 char m_video[256]; /* Media declaration line for video */ 06923 char m_modem[256]; /* Media declaration line for t38 */ 06924 char a_audio[1024]; /* Attributes for audio */ 06925 char a_video[1024]; /* Attributes for video */ 06926 char a_modem[1024]; /* Attributes for t38 */ 06927 char *m_audio_next = m_audio; 06928 char *m_video_next = m_video; 06929 char *m_modem_next = m_modem; 06930 size_t m_audio_left = sizeof(m_audio); 06931 size_t m_video_left = sizeof(m_video); 06932 size_t m_modem_left = sizeof(m_modem); 06933 char *a_audio_next = a_audio; 06934 char *a_video_next = a_video; 06935 char *a_modem_next = a_modem; 06936 size_t a_audio_left = sizeof(a_audio); 06937 size_t a_video_left = sizeof(a_video); 06938 size_t a_modem_left = sizeof(a_modem); 06939 char dummy_answer[256]; 06940 06941 int x; 06942 int capability = 0; 06943 int needvideo = FALSE; 06944 int debug = sip_debug_test_pvt(p); 06945 int min_audio_packet_size = 0; 06946 int min_video_packet_size = 0; 06947 06948 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06949 m_modem[0] = '\0'; 06950 06951 if (!p->rtp) { 06952 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06953 return AST_FAILURE; 06954 } 06955 06956 /* Set RTP Session ID and version */ 06957 if (!p->sessionid) { 06958 p->sessionid = getpid(); 06959 p->sessionversion = p->sessionid; 06960 } else 06961 p->sessionversion++; 06962 06963 /* Get our addresses */ 06964 ast_rtp_get_us(p->rtp, &sin); 06965 if (p->vrtp) 06966 ast_rtp_get_us(p->vrtp, &vsin); 06967 06968 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06969 if (p->redirip.sin_addr.s_addr) { 06970 dest.sin_port = p->redirip.sin_port; 06971 dest.sin_addr = p->redirip.sin_addr; 06972 } else { 06973 dest.sin_addr = p->ourip; 06974 dest.sin_port = sin.sin_port; 06975 } 06976 06977 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06978 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06979 06980 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 06981 hold = "a=recvonly\r\n"; 06982 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 06983 hold = "a=inactive\r\n"; 06984 else 06985 hold = "a=sendrecv\r\n"; 06986 06987 if (add_audio) { 06988 capability = p->jointcapability; 06989 06990 06991 if (option_debug > 1) { 06992 char codecbuf[SIPBUFSIZE]; 06993 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"); 06994 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06995 } 06996 06997 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06998 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06999 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 07000 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 07001 } 07002 #endif 07003 07004 /* Check if we need video in this call */ 07005 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 07006 if (p->vrtp) { 07007 needvideo = TRUE; 07008 if (option_debug > 1) 07009 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 07010 } else if (option_debug > 1) 07011 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 07012 } 07013 07014 07015 /* Ok, we need video. Let's add what we need for video and set codecs. 07016 Video is handled differently than audio since we can not transcode. */ 07017 if (needvideo) { 07018 /* Determine video destination */ 07019 if (p->vredirip.sin_addr.s_addr) { 07020 vdest.sin_addr = p->vredirip.sin_addr; 07021 vdest.sin_port = p->vredirip.sin_port; 07022 } else { 07023 vdest.sin_addr = p->ourip; 07024 vdest.sin_port = vsin.sin_port; 07025 } 07026 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vsin.sin_port)); 07027 07028 /* Build max bitrate string */ 07029 if (p->maxcallbitrate) 07030 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 07031 if (debug) 07032 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 07033 } 07034 07035 if (debug) 07036 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 07037 07038 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 07039 07040 /* Now, start adding audio codecs. These are added in this order: 07041 - First what was requested by the calling channel 07042 - Then preferences in order from sip.conf device config for this peer/user 07043 - Then other codecs in capabilities, including video 07044 */ 07045 07046 /* Prefer the audio codec we were requested to use, first, no matter what 07047 Note that p->prefcodec can include video codecs, so mask them out 07048 */ 07049 if (capability & p->prefcodec) { 07050 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 07051 07052 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 07053 &m_audio_next, &m_audio_left, 07054 &a_audio_next, &a_audio_left, 07055 debug, &min_audio_packet_size); 07056 alreadysent |= codec; 07057 } 07058 07059 /* Start by sending our preferred audio codecs */ 07060 for (x = 0; x < 32; x++) { 07061 int codec; 07062 07063 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 07064 break; 07065 07066 if (!(capability & codec)) 07067 continue; 07068 07069 if (alreadysent & codec) 07070 continue; 07071 07072 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 07073 &m_audio_next, &m_audio_left, 07074 &a_audio_next, &a_audio_left, 07075 debug, &min_audio_packet_size); 07076 alreadysent |= codec; 07077 } 07078 07079 /* Now send any other common audio and video codecs, and non-codec formats: */ 07080 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 07081 if (!(capability & x)) /* Codec not requested */ 07082 continue; 07083 07084 if (alreadysent & x) /* Already added to SDP */ 07085 continue; 07086 07087 if (x <= AST_FORMAT_MAX_AUDIO) 07088 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 07089 &m_audio_next, &m_audio_left, 07090 &a_audio_next, &a_audio_left, 07091 debug, &min_audio_packet_size); 07092 else 07093 add_codec_to_sdp(p, x, 90000, 07094 &m_video_next, &m_video_left, 07095 &a_video_next, &a_video_left, 07096 debug, &min_video_packet_size); 07097 } 07098 07099 /* Now add DTMF RFC2833 telephony-event as a codec */ 07100 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 07101 if (!(p->jointnoncodeccapability & x)) 07102 continue; 07103 07104 add_noncodec_to_sdp(p, x, 8000, 07105 &m_audio_next, &m_audio_left, 07106 &a_audio_next, &a_audio_left, 07107 debug); 07108 } 07109 07110 if (option_debug > 2) 07111 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 07112 07113 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 07114 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 07115 07116 if (min_audio_packet_size) 07117 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 07118 07119 if (min_video_packet_size) 07120 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 07121 07122 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 07123 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 07124 07125 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 07126 if (needvideo) 07127 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 07128 } 07129 07130 if (add_t38 && p->udptl) { 07131 struct sockaddr_in udptlsin; 07132 struct sockaddr_in udptldest = { 0, }; 07133 07134 ast_udptl_get_us(p->udptl, &udptlsin); 07135 07136 if (p->udptlredirip.sin_addr.s_addr) { 07137 udptldest.sin_port = p->udptlredirip.sin_port; 07138 udptldest.sin_addr = p->udptlredirip.sin_addr; 07139 } else { 07140 udptldest.sin_addr = p->ourip; 07141 udptldest.sin_port = udptlsin.sin_port; 07142 } 07143 07144 if (debug) { 07145 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 07146 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 07147 p->t38.capability, 07148 p->t38.peercapability, 07149 p->t38.jointcapability); 07150 } 07151 07152 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 07153 07154 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 07155 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 07156 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 07157 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 07158 if ((x = t38_get_rate(p->t38.jointcapability))) 07159 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 07160 if ((p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) == T38FAX_FILL_BIT_REMOVAL) 07161 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval\r\n"); 07162 if ((p->t38.jointcapability & T38FAX_TRANSCODING_MMR) == T38FAX_TRANSCODING_MMR) 07163 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR\r\n"); 07164 if ((p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) == T38FAX_TRANSCODING_JBIG) 07165 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG\r\n"); 07166 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 07167 x = ast_udptl_get_local_max_datagram(p->udptl); 07168 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 07169 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 07170 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 07171 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 07172 } 07173 07174 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime); 07175 if (add_audio) 07176 len += strlen(m_audio) + strlen(a_audio) + strlen(hold); 07177 if (needvideo) /* only if video response is appropriate */ 07178 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 07179 if (add_t38) { 07180 len += strlen(m_modem) + strlen(a_modem); 07181 } 07182 07183 add_header(resp, "Content-Type", "application/sdp"); 07184 add_header_contentLength(resp, len); 07185 add_line(resp, version); 07186 add_line(resp, owner); 07187 add_line(resp, subject); 07188 add_line(resp, connection); 07189 if (needvideo) /* only if video response is appropriate */ 07190 add_line(resp, bandwidth); 07191 add_line(resp, stime); 07192 if (add_audio) { 07193 add_line(resp, m_audio); 07194 add_line(resp, a_audio); 07195 add_line(resp, hold); 07196 } else if (p->offered_media[SDP_AUDIO].offered) { 07197 snprintf(dummy_answer, sizeof(dummy_answer), "m=audio 0 RTP/AVP %s\r\n", p->offered_media[SDP_AUDIO].text); 07198 add_line(resp, dummy_answer); 07199 } 07200 if (needvideo) { /* only if video response is appropriate */ 07201 add_line(resp, m_video); 07202 add_line(resp, a_video); 07203 add_line(resp, hold); /* Repeat hold for the video stream */ 07204 } else if (p->offered_media[SDP_VIDEO].offered) { 07205 snprintf(dummy_answer, sizeof(dummy_answer), "m=video 0 RTP/AVP %s\r\n", p->offered_media[SDP_VIDEO].text); 07206 add_line(resp, dummy_answer); 07207 } 07208 if (add_t38) { 07209 add_line(resp, m_modem); 07210 add_line(resp, a_modem); 07211 } else if (p->offered_media[SDP_IMAGE].offered) { 07212 add_line(resp, "m=image 0 udptl t38\r\n"); 07213 } 07214 07215 /* Update lastrtprx when we send our SDP */ 07216 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 07217 07218 if (option_debug > 2) { 07219 char buf[SIPBUFSIZE]; 07220 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 07221 } 07222 07223 return AST_SUCCESS; 07224 }
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 17603 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::list, LOG_DEBUG, and sipdebug.
17604 { 17605 struct domain *d; 17606 17607 if (ast_strlen_zero(domain)) { 17608 ast_log(LOG_WARNING, "Zero length domain.\n"); 17609 return 1; 17610 } 17611 17612 if (!(d = ast_calloc(1, sizeof(*d)))) 17613 return 0; 17614 17615 ast_copy_string(d->domain, domain, sizeof(d->domain)); 17616 17617 if (!ast_strlen_zero(context)) 17618 ast_copy_string(d->context, context, sizeof(d->context)); 17619 17620 d->mode = mode; 17621 17622 AST_LIST_LOCK(&domain_list); 17623 AST_LIST_INSERT_TAIL(&domain_list, d, list); 17624 AST_LIST_UNLOCK(&domain_list); 17625 17626 if (sipdebug) 17627 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 17628 17629 return 1; 17630 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 6753 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
06754 { 06755 /* XXX Convert \n's to \r\n's XXX */ 06756 add_header(req, "Content-Type", "text/plain"); 06757 add_header_contentLength(req, strlen(text)); 06758 add_line(req, text); 06759 return 0; 06760 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 6777 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
06778 { 06779 const char *xml_is_a_huge_waste_of_space = 06780 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 06781 " <media_control>\r\n" 06782 " <vc_primitive>\r\n" 06783 " <to_encoder>\r\n" 06784 " <picture_fast_update>\r\n" 06785 " </picture_fast_update>\r\n" 06786 " </to_encoder>\r\n" 06787 " </vc_primitive>\r\n" 06788 " </media_control>\r\n"; 06789 add_header(req, "Content-Type", "application/media_control+xml"); 06790 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 06791 add_line(req, xml_is_a_huge_waste_of_space); 06792 return 0; 06793 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 6687 of file chan_sip.c.
References add_header(), and t.
Referenced by build_csv_record(), transmit_invite(), transmit_response_with_date(), and transmit_response_with_unsupported().
06688 { 06689 char tmpdat[256]; 06690 struct tm tm; 06691 time_t t = time(NULL); 06692 06693 gmtime_r(&t, &tm); 06694 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 06695 add_header(req, "Date", tmpdat); 06696 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1940 of file chan_sip.c.
References append_history_va(), ast_test_flag, sip_pvt::flags, and SIP_NO_HISTORY.
01941 { 01942 va_list ap; 01943 01944 if (!p) 01945 return; 01946 01947 if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 01948 && !recordhistory && !dumphistory) { 01949 return; 01950 } 01951 01952 va_start(ap, fmt); 01953 append_history_va(p, fmt, ap); 01954 va_end(ap); 01955 01956 return; 01957 }
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 1913 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, free, sip_history::list, and MAX_HISTORY_ENTRIES.
Referenced by append_history_full().
01914 { 01915 char buf[80], *c = buf; /* max history length */ 01916 struct sip_history *hist; 01917 int l; 01918 01919 vsnprintf(buf, sizeof(buf), fmt, ap); 01920 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01921 l = strlen(buf) + 1; 01922 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01923 return; 01924 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01925 free(hist); 01926 return; 01927 } 01928 memcpy(hist->event, buf, l); 01929 if (p->history_entries == MAX_HISTORY_ENTRIES) { 01930 struct sip_history *oldest; 01931 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 01932 p->history_entries--; 01933 free(oldest); 01934 } 01935 AST_LIST_INSERT_TAIL(p->history, hist, list); 01936 p->history_entries++; 01937 }
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 14100 of file chan_sip.c.
References ast_channel::_state, ast_deactivate_generator(), AST_FLAG_MOH, ast_moh_stop(), AST_STATE_UP, and ast_test_flag.
Referenced by attempt_transfer(), and handle_invite_replaces().
14101 { 14102 if (chan && chan->_state == AST_STATE_UP) { 14103 if (ast_test_flag(chan, AST_FLAG_MOH)) 14104 ast_moh_stop(chan); 14105 else if (chan->generatordata) 14106 ast_deactivate_generator(chan); 14107 } 14108 }
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 1873 of file chan_sip.c.
References ahp, ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), AST_SUCCESS, externexpire, externhost, 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().
01874 { 01875 struct sockaddr_in theirs, ours; 01876 01877 /* Get our local information */ 01878 ast_ouraddrfor(them, us); 01879 theirs.sin_addr = *them; 01880 ours.sin_addr = *us; 01881 01882 if (localaddr && externip.sin_addr.s_addr && 01883 (ast_apply_ha(localaddr, &theirs)) && 01884 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01885 if (externexpire && time(NULL) >= externexpire) { 01886 struct ast_hostent ahp; 01887 struct hostent *hp; 01888 01889 externexpire = time(NULL) + externrefresh; 01890 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01891 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01892 } else 01893 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01894 } 01895 *us = externip.sin_addr; 01896 if (option_debug) { 01897 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01898 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01899 } 01900 } else if (bindaddr.sin_addr.s_addr) 01901 *us = bindaddr.sin_addr; 01902 return AST_SUCCESS; 01903 }
Attempt transfer of SIP call This fix for attended transfers on a local PBX.
Definition at line 14112 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, ast_channel::name, and option_debug.
14113 { 14114 int res = 0; 14115 struct ast_channel *peera = NULL, 14116 *peerb = NULL, 14117 *peerc = NULL, 14118 *peerd = NULL; 14119 14120 14121 /* We will try to connect the transferee with the target and hangup 14122 all channels to the transferer */ 14123 if (option_debug > 3) { 14124 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 14125 if (transferer->chan1) 14126 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 14127 else 14128 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 14129 if (target->chan1) 14130 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 14131 else 14132 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 14133 if (transferer->chan2) 14134 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 14135 else 14136 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 14137 if (target->chan2) 14138 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)"); 14139 else 14140 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 14141 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 14142 } 14143 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 14144 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 14145 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 14146 peerc = transferer->chan2; /* Asterisk to Transferee */ 14147 peerd = target->chan2; /* Asterisk to Target */ 14148 if (option_debug > 2) 14149 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 14150 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 14151 peera = target->chan1; /* Transferer to PBX -> target channel */ 14152 peerb = transferer->chan1; /* Transferer to IVR*/ 14153 peerc = target->chan2; /* Asterisk to Target */ 14154 peerd = transferer->chan2; /* Nothing */ 14155 if (option_debug > 2) 14156 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 14157 } 14158 14159 if (peera && peerb && peerc && (peerb != peerc)) { 14160 ast_quiet_chan(peera); /* Stop generators */ 14161 ast_quiet_chan(peerb); 14162 ast_quiet_chan(peerc); 14163 if (peerd) 14164 ast_quiet_chan(peerd); 14165 14166 if (option_debug > 3) 14167 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 14168 if (ast_channel_masquerade(peerb, peerc)) { 14169 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 14170 res = -1; 14171 } else 14172 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 14173 return res; 14174 } else { 14175 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 14176 if (transferer->chan1) 14177 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 14178 if (target->chan1) 14179 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 14180 return -2; 14181 } 14182 return 0; 14183 }
static int auto_congest | ( | const void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 3105 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, ast_channel::name, sip_pvt::owner, and sip_scheddestroy().
03106 { 03107 struct sip_pvt *p = (struct sip_pvt *)nothing; 03108 03109 ast_mutex_lock(&p->lock); 03110 p->initid = -1; 03111 if (p->owner) { 03112 /* XXX fails on possible deadlock */ 03113 if (!ast_channel_trylock(p->owner)) { 03114 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 03115 append_history(p, "Cong", "Auto-congesting (timer)"); 03116 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 03117 ast_channel_unlock(p->owner); 03118 } 03119 03120 /* Give the channel a chance to act before we proceed with destruction */ 03121 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03122 } 03123 ast_mutex_unlock(&p->lock); 03124 return 0; 03125 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4672 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().
04673 { 04674 char buf[33]; 04675 04676 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04677 04678 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04679 04680 }
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 4683 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().
04684 { 04685 char buf[33]; 04686 04687 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04688 04689 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04690 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 7401 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), sip_pvt::exten, ourport, and STANDARD_SIP_PORT.
Referenced by check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().
07402 { 07403 /* Construct Contact: header */ 07404 if (ourport != STANDARD_SIP_PORT) 07405 ast_string_field_build(p, our_contact, "<sip:%s%s%s:%d>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip), ourport); 07406 else 07407 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 07408 }
static struct sip_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime, | |||
int | devstate_only | |||
) | [static] |
Build peer from configuration (file or realtime static/dynamic).
Definition at line 17935 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, global_contact_ha, global_flags, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastms, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, LOG_ERROR, 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, sched, 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::username, ast_variable::value, and sip_peer::vmexten.
17936 { 17937 struct sip_peer *peer = NULL; 17938 struct ast_ha *oldha = NULL; 17939 int obproxyfound=0; 17940 int found=0; 17941 int firstpass=1; 17942 int format=0; /* Ama flags */ 17943 time_t regseconds = 0; 17944 char *varname = NULL, *varval = NULL; 17945 struct ast_variable *tmpvar = NULL; 17946 struct ast_flags peerflags[2] = {{(0)}}; 17947 struct ast_flags mask[2] = {{(0)}}; 17948 int alt_fullcontact = alt ? 1 : 0; 17949 char fullcontact[sizeof(peer->fullcontact)] = ""; 17950 17951 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 17952 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 17953 /* We also use a case-sensitive comparison (unlike find_peer) so 17954 that case changes made to the peer name will be properly handled 17955 during reload 17956 */ 17957 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 17958 17959 if (peer) { 17960 /* Already in the list, remove it and it will be added back (or FREE'd) */ 17961 found = 1; 17962 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 17963 firstpass = 0; 17964 } else { 17965 if (!(peer = ast_calloc(1, sizeof(*peer)))) 17966 return NULL; 17967 17968 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 17969 rpeerobjs++; 17970 else 17971 speerobjs++; 17972 ASTOBJ_INIT(peer); 17973 } 17974 /* Note that our peer HAS had its reference count incrased */ 17975 if (firstpass) { 17976 peer->lastmsgssent = -1; 17977 oldha = peer->ha; 17978 peer->ha = NULL; 17979 set_peer_defaults(peer); /* Set peer defaults */ 17980 } 17981 if (!found && name) 17982 ast_copy_string(peer->name, name, sizeof(peer->name)); 17983 17984 /* If we have channel variables, remove them (reload) */ 17985 if (peer->chanvars) { 17986 ast_variables_destroy(peer->chanvars); 17987 peer->chanvars = NULL; 17988 /* XXX should unregister ? */ 17989 } 17990 17991 if (found) 17992 peer->portinuri = 0; 17993 17994 /* If we have realm authentication information, remove them (reload) */ 17995 clear_realm_authentication(peer->auth); 17996 peer->auth = NULL; 17997 17998 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 17999 if (!devstate_only) { 18000 if (handle_common_options(&peerflags[0], &mask[0], v)) { 18001 continue; 18002 } 18003 if (realtime && !strcasecmp(v->name, "regseconds")) { 18004 ast_get_time_t(v->value, ®seconds, 0, NULL); 18005 } else if (realtime && !strcasecmp(v->name, "name")) 18006 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 18007 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 18008 if (alt_fullcontact && !alt) { 18009 /* Reset, because the alternate also has a fullcontact and we 18010 * do NOT want the field value to be doubled. It might be 18011 * tempting to skip this, but the first table might not have 18012 * fullcontact and since we're here, we know that the alternate 18013 * absolutely does. */ 18014 alt_fullcontact = 0; 18015 fullcontact[0] = '\0'; 18016 } 18017 /* Reconstruct field, because realtime separates our value at the ';' */ 18018 if (!ast_strlen_zero(fullcontact)) { 18019 strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1); 18020 strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1); 18021 } else { 18022 ast_copy_string(fullcontact, v->value, sizeof(fullcontact)); 18023 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 18024 } 18025 } else if (!strcasecmp(v->name, "secret")) 18026 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 18027 else if (!strcasecmp(v->name, "md5secret")) 18028 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 18029 else if (!strcasecmp(v->name, "auth")) 18030 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 18031 else if (!strcasecmp(v->name, "callerid")) { 18032 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 18033 } else if (!strcasecmp(v->name, "fullname")) { 18034 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 18035 } else if (!strcasecmp(v->name, "trunkname")) { 18036 /* This is actually for a trunk, so we don't want to override callerid */ 18037 ast_copy_string(peer->cid_name, "", sizeof(peer->cid_name)); 18038 } else if (!strcasecmp(v->name, "cid_number")) { 18039 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 18040 } else if (!strcasecmp(v->name, "context")) { 18041 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 18042 } else if (!strcasecmp(v->name, "subscribecontext")) { 18043 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 18044 } else if (!strcasecmp(v->name, "fromdomain")) { 18045 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 18046 } else if (!strcasecmp(v->name, "usereqphone")) { 18047 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 18048 } else if (!strcasecmp(v->name, "fromuser")) { 18049 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 18050 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 18051 if (!strcasecmp(v->value, "dynamic")) { 18052 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 18053 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 18054 } else { 18055 /* They'll register with us */ 18056 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 18057 /* Initialize stuff if this is a new peer, or if it used to be 18058 * non-dynamic before the reload. */ 18059 memset(&peer->addr.sin_addr, 0, 4); 18060 if (peer->addr.sin_port) { 18061 /* If we've already got a port, make it the default rather than absolute */ 18062 peer->defaddr.sin_port = peer->addr.sin_port; 18063 peer->addr.sin_port = 0; 18064 } 18065 } 18066 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 18067 } 18068 } else { 18069 /* Non-dynamic. Make sure we become that way if we're not */ 18070 if (!AST_SCHED_DEL(sched, peer->expire)) { 18071 struct sip_peer *peer_ptr = peer; 18072 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 18073 } 18074 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 18075 if (!strcasecmp(v->name, "outboundproxy")) { 18076 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 18077 ast_log(LOG_ERROR, "srvlookup failed for outboundproxy: %s, on peer %s, removing peer\n", v->value, peer->name); 18078 ASTOBJ_UNREF(peer, sip_destroy_peer); 18079 return NULL; 18080 } 18081 } 18082 if (!strcasecmp(v->name, "outboundproxy")) 18083 obproxyfound=1; 18084 else { 18085 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 18086 if (!peer->addr.sin_port) 18087 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 18088 } 18089 if (global_dynamic_exclude_static) { 18090 global_contact_ha = ast_append_ha("deny", (char *)ast_inet_ntoa(peer->addr.sin_addr), global_contact_ha); 18091 } 18092 } 18093 } else if (!strcasecmp(v->name, "defaultip")) { 18094 if (ast_get_ip(&peer->defaddr, v->value)) { 18095 ASTOBJ_UNREF(peer, sip_destroy_peer); 18096 return NULL; 18097 } 18098 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 18099 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 18100 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 18101 peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha); 18102 } else if (!strcasecmp(v->name, "port")) { 18103 peer->portinuri = 1; 18104 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 18105 peer->defaddr.sin_port = htons(atoi(v->value)); 18106 else 18107 peer->addr.sin_port = htons(atoi(v->value)); 18108 } else if (!strcasecmp(v->name, "callingpres")) { 18109 peer->callingpres = ast_parse_caller_presentation(v->value); 18110 if (peer->callingpres == -1) 18111 peer->callingpres = atoi(v->value); 18112 } else if (!strcasecmp(v->name, "username")) { 18113 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 18114 } else if (!strcasecmp(v->name, "language")) { 18115 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 18116 } else if (!strcasecmp(v->name, "regexten")) { 18117 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 18118 } else if (!strcasecmp(v->name, "amaflags")) { 18119 format = ast_cdr_amaflags2int(v->value); 18120 if (format < 0) { 18121 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 18122 } else { 18123 peer->amaflags = format; 18124 } 18125 } else if (!strcasecmp(v->name, "accountcode")) { 18126 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 18127 } else if (!strcasecmp(v->name, "mohinterpret") 18128 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 18129 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 18130 } else if (!strcasecmp(v->name, "mohsuggest")) { 18131 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 18132 } else if (!strcasecmp(v->name, "mailbox")) { 18133 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 18134 } else if (!strcasecmp(v->name, "hasvoicemail")) { 18135 /* People expect that if 'hasvoicemail' is set, that the mailbox will 18136 * be also set, even if not explicitly specified. */ 18137 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 18138 ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox)); 18139 } 18140 } else if (!strcasecmp(v->name, "subscribemwi")) { 18141 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 18142 } else if (!strcasecmp(v->name, "vmexten")) { 18143 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 18144 } else if (!strcasecmp(v->name, "callgroup")) { 18145 peer->callgroup = ast_get_group(v->value); 18146 } else if (!strcasecmp(v->name, "allowtransfer")) { 18147 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 18148 } else if (!strcasecmp(v->name, "pickupgroup")) { 18149 peer->pickupgroup = ast_get_group(v->value); 18150 } else if (!strcasecmp(v->name, "allow")) { 18151 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 18152 } else if (!strcasecmp(v->name, "disallow")) { 18153 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 18154 } else if (!strcasecmp(v->name, "autoframing")) { 18155 peer->autoframing = ast_true(v->value); 18156 } else if (!strcasecmp(v->name, "rtptimeout")) { 18157 if ((sscanf(v->value, "%30d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 18158 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 18159 peer->rtptimeout = global_rtptimeout; 18160 } 18161 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 18162 if ((sscanf(v->value, "%30d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 18163 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 18164 peer->rtpholdtimeout = global_rtpholdtimeout; 18165 } 18166 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 18167 if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 18168 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 18169 peer->rtpkeepalive = global_rtpkeepalive; 18170 } 18171 } else if (!strcasecmp(v->name, "setvar")) { 18172 /* Set peer channel variable */ 18173 varname = ast_strdupa(v->value); 18174 if ((varval = strchr(varname, '='))) { 18175 *varval++ = '\0'; 18176 if ((tmpvar = ast_variable_new(varname, varval))) { 18177 tmpvar->next = peer->chanvars; 18178 peer->chanvars = tmpvar; 18179 } 18180 } 18181 } 18182 } 18183 18184 /* These apply to devstate lookups */ 18185 if (realtime && !strcasecmp(v->name, "lastms")) { 18186 sscanf(v->value, "%30d", &peer->lastms); 18187 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 18188 inet_aton(v->value, &(peer->addr.sin_addr)); 18189 } else if (!strcasecmp(v->name, "qualify")) { 18190 if (!strcasecmp(v->value, "no")) { 18191 peer->maxms = 0; 18192 } else if (!strcasecmp(v->value, "yes")) { 18193 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 18194 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 18195 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); 18196 peer->maxms = 0; 18197 } 18198 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) { 18199 /* This would otherwise cause a network storm, where the 18200 * qualify response refreshes the peer from the database, 18201 * which in turn causes another qualify to be sent, ad 18202 * infinitum. */ 18203 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); 18204 peer->maxms = 0; 18205 } 18206 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 18207 peer->call_limit = atoi(v->value); 18208 if (peer->call_limit < 0) { 18209 peer->call_limit = 0; 18210 } 18211 } 18212 } 18213 18214 if (!ast_strlen_zero(fullcontact)) { 18215 ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact)); 18216 /* We have a hostname in the fullcontact, but if we don't have an 18217 * address listed on the entry (or if it's 'dynamic'), then we need to 18218 * parse the entry to obtain the IP address, so a dynamic host can be 18219 * contacted immediately after reload (as opposed to waiting for it to 18220 * register once again). But if we have an address for this peer and NAT was 18221 * specified, use that address instead. */ 18222 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE) || !peer->addr.sin_addr.s_addr) { 18223 __set_address_from_contact(fullcontact, &peer->addr); 18224 } 18225 } 18226 18227 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !obproxyfound && !ast_strlen_zero(peer->tohost)) { 18228 if (ast_get_ip_or_srv(&peer->addr, peer->tohost, srvlookup && !peer->portinuri ? "_sip._udp" : NULL)) { 18229 ast_log(LOG_ERROR, "host lookup failed for %s, on peer %s, removing peer\n", peer->tohost, peer->name); 18230 ASTOBJ_UNREF(peer, sip_destroy_peer); 18231 return NULL; 18232 } 18233 } 18234 18235 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 18236 time_t nowtime = time(NULL); 18237 18238 if ((nowtime - regseconds) > 0) { 18239 destroy_association(peer); 18240 memset(&peer->addr, 0, sizeof(peer->addr)); 18241 peer->lastms = -1; 18242 if (option_debug) 18243 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 18244 } 18245 } 18246 18247 /* Startup regular pokes */ 18248 if (realtime && peer->lastms > 0) { 18249 ASTOBJ_REF(peer); 18250 sip_poke_peer(peer); 18251 } 18252 18253 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 18254 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 18255 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 18256 global_allowsubscribe = TRUE; /* No global ban any more */ 18257 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 18258 reg_source_db(peer); 18259 ASTOBJ_UNMARK(peer); 18260 ast_free_ha(oldha); 18261 return peer; 18262 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 12365 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().
12366 { 12367 char a1[256]; 12368 char a2[256]; 12369 char a1_hash[256]; 12370 char a2_hash[256]; 12371 char resp[256]; 12372 char resp_hash[256]; 12373 char uri[256]; 12374 char opaque[256] = ""; 12375 char cnonce[80]; 12376 const char *username; 12377 const char *secret; 12378 const char *md5secret; 12379 struct sip_auth *auth = NULL; /* Realm authentication */ 12380 12381 if (!ast_strlen_zero(p->domain)) 12382 ast_copy_string(uri, p->domain, sizeof(uri)); 12383 else if (!ast_strlen_zero(p->uri)) 12384 ast_copy_string(uri, p->uri, sizeof(uri)); 12385 else 12386 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 12387 12388 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 12389 12390 /* Check if we have separate auth credentials */ 12391 if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */ 12392 auth = find_realm_authentication(authl, p->realm); /* If not, global list */ 12393 12394 if (auth) { 12395 if (sipdebug && option_debug > 1) 12396 ast_log(LOG_DEBUG, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username); 12397 username = auth->username; 12398 secret = auth->secret; 12399 md5secret = auth->md5secret; 12400 if (sipdebug) 12401 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 12402 } else { 12403 /* No authentication, use peer or register= config */ 12404 username = p->authname; 12405 secret = p->peersecret; 12406 md5secret = p->peermd5secret; 12407 } 12408 if (ast_strlen_zero(username)) /* We have no authentication */ 12409 return -1; 12410 12411 /* Calculate SIP digest response */ 12412 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 12413 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 12414 if (!ast_strlen_zero(md5secret)) 12415 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 12416 else 12417 ast_md5_hash(a1_hash,a1); 12418 ast_md5_hash(a2_hash,a2); 12419 12420 p->noncecount++; 12421 if (!ast_strlen_zero(p->qop)) 12422 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 12423 else 12424 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 12425 ast_md5_hash(resp_hash, resp); 12426 12427 /* only include the opaque string if it's set */ 12428 if (!ast_strlen_zero(p->opaque)) { 12429 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 12430 } 12431 12432 /* XXX We hard code our qop to "auth" for now. XXX */ 12433 if (!ast_strlen_zero(p->qop)) 12434 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); 12435 else 12436 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); 12437 12438 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 12439 12440 return 0; 12441 }
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 8884 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, 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().
08885 { 08886 struct sip_route *thishop, *head, *tail; 08887 int start = 0; 08888 int len; 08889 const char *rr, *contact, *c; 08890 08891 /* Once a persistant route is set, don't fool with it */ 08892 if (p->route && p->route_persistant) { 08893 if (option_debug) 08894 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 08895 return; 08896 } 08897 08898 if (p->route) { 08899 free_old_route(p->route); 08900 p->route = NULL; 08901 } 08902 08903 /* We only want to create the route set the first time this is called */ 08904 p->route_persistant = 1; 08905 08906 /* Build a tailq, then assign it to p->route when done. 08907 * If backwards, we add entries from the head so they end up 08908 * in reverse order. However, we do need to maintain a correct 08909 * tail pointer because the contact is always at the end. 08910 */ 08911 head = NULL; 08912 tail = head; 08913 /* 1st we pass through all the hops in any Record-Route headers */ 08914 for (;;) { 08915 /* Each Record-Route header */ 08916 rr = __get_header(req, "Record-Route", &start); 08917 if (*rr == '\0') 08918 break; 08919 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 08920 ++rr; 08921 len = strcspn(rr, ">") + 1; 08922 /* Make a struct route */ 08923 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08924 /* ast_calloc is not needed because all fields are initialized in this block */ 08925 ast_copy_string(thishop->hop, rr, len); 08926 if (option_debug > 1) 08927 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 08928 /* Link in */ 08929 if (backwards) { 08930 /* Link in at head so they end up in reverse order */ 08931 thishop->next = head; 08932 head = thishop; 08933 /* If this was the first then it'll be the tail */ 08934 if (!tail) 08935 tail = thishop; 08936 } else { 08937 thishop->next = NULL; 08938 /* Link in at the end */ 08939 if (tail) 08940 tail->next = thishop; 08941 else 08942 head = thishop; 08943 tail = thishop; 08944 } 08945 } 08946 } 08947 } 08948 08949 /* Only append the contact if we are dealing with a strict router */ 08950 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 08951 /* 2nd append the Contact: if there is one */ 08952 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08953 contact = get_header(req, "Contact"); 08954 if (!ast_strlen_zero(contact)) { 08955 if (option_debug > 1) 08956 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08957 /* Look for <: delimited address */ 08958 c = strchr(contact, '<'); 08959 if (c) { 08960 /* Take to > */ 08961 ++c; 08962 len = strcspn(c, ">") + 1; 08963 } else { 08964 /* No <> - just take the lot */ 08965 c = contact; 08966 len = strlen(contact) + 1; 08967 } 08968 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08969 /* ast_calloc is not needed because all fields are initialized in this block */ 08970 ast_copy_string(thishop->hop, c, len); 08971 thishop->next = NULL; 08972 /* Goes at the end */ 08973 if (tail) 08974 tail->next = thishop; 08975 else 08976 head = thishop; 08977 } 08978 } 08979 } 08980 08981 /* Store as new route */ 08982 p->route = head; 08983 08984 /* For debugging dump what we ended up with */ 08985 if (sip_debug_test_pvt(p)) 08986 list_route(p->route); 08987 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 7411 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, sip_pvt::ourip, sip_pvt::owner, sip_pvt::rpid, sip_pvt::rpid_from, S_OR, sip_pvt::tag, and TRUE.
Referenced by initreqprep().
07412 { 07413 int send_pres_tags = TRUE; 07414 const char *privacy=NULL; 07415 const char *screen=NULL; 07416 char buf[256]; 07417 const char *clid = default_callerid; 07418 const char *clin = NULL; 07419 const char *fromdomain; 07420 07421 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 07422 return; 07423 07424 if (p->owner && !ast_strlen_zero(p->owner->cid.cid_num)) 07425 clid = p->owner->cid.cid_num; 07426 if (p->owner && p->owner->cid.cid_name) 07427 clin = p->owner->cid.cid_name; 07428 if (ast_strlen_zero(clin)) 07429 clin = clid; 07430 07431 switch (p->callingpres) { 07432 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 07433 privacy = "off"; 07434 screen = "no"; 07435 break; 07436 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 07437 privacy = "off"; 07438 screen = "yes"; 07439 break; 07440 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 07441 privacy = "off"; 07442 screen = "no"; 07443 break; 07444 case AST_PRES_ALLOWED_NETWORK_NUMBER: 07445 privacy = "off"; 07446 screen = "yes"; 07447 break; 07448 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 07449 privacy = "full"; 07450 screen = "no"; 07451 break; 07452 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 07453 privacy = "full"; 07454 screen = "yes"; 07455 break; 07456 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 07457 privacy = "full"; 07458 screen = "no"; 07459 break; 07460 case AST_PRES_PROHIB_NETWORK_NUMBER: 07461 privacy = "full"; 07462 screen = "yes"; 07463 break; 07464 case AST_PRES_NUMBER_NOT_AVAILABLE: 07465 send_pres_tags = FALSE; 07466 break; 07467 default: 07468 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 07469 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 07470 privacy = "full"; 07471 else 07472 privacy = "off"; 07473 screen = "no"; 07474 break; 07475 } 07476 07477 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 07478 07479 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 07480 if (send_pres_tags) 07481 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 07482 ast_string_field_set(p, rpid, buf); 07483 07484 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 07485 S_OR(p->fromuser, clid), 07486 fromdomain, p->tag); 07487 }
static struct sip_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static] |
Initiate a SIP user structure from configuration (configuration or realtime).
Definition at line 17752 of file chan_sip.c.
References 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, default_prefs, ast_flags::flags, format, global_flags, handle_common_options(), ast_variable::lineno, ast_variable::name, ast_variable::next, SIP_FLAGS_TO_COPY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_FLAGS_TO_COPY, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, and ast_variable::value.
17753 { 17754 struct sip_user *user; 17755 int format; 17756 struct ast_ha *oldha = NULL; 17757 char *varname = NULL, *varval = NULL; 17758 struct ast_variable *tmpvar = NULL; 17759 struct ast_flags userflags[2] = {{(0)}}; 17760 struct ast_flags mask[2] = {{(0)}}; 17761 17762 17763 if (!(user = ast_calloc(1, sizeof(*user)))) 17764 return NULL; 17765 17766 suserobjs++; 17767 ASTOBJ_INIT(user); 17768 ast_copy_string(user->name, name, sizeof(user->name)); 17769 oldha = user->ha; 17770 user->ha = NULL; 17771 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 17772 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 17773 user->capability = global_capability; 17774 user->allowtransfer = global_allowtransfer; 17775 user->maxcallbitrate = default_maxcallbitrate; 17776 user->autoframing = global_autoframing; 17777 user->prefs = default_prefs; 17778 /* set default context */ 17779 strcpy(user->context, default_context); 17780 strcpy(user->language, default_language); 17781 strcpy(user->mohinterpret, default_mohinterpret); 17782 strcpy(user->mohsuggest, default_mohsuggest); 17783 /* First we walk through the v parameters list and then the alt parameters list */ 17784 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 17785 if (handle_common_options(&userflags[0], &mask[0], v)) 17786 continue; 17787 17788 if (!strcasecmp(v->name, "context")) { 17789 ast_copy_string(user->context, v->value, sizeof(user->context)); 17790 } else if (!strcasecmp(v->name, "subscribecontext")) { 17791 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 17792 } else if (!strcasecmp(v->name, "setvar")) { 17793 varname = ast_strdupa(v->value); 17794 if ((varval = strchr(varname,'='))) { 17795 *varval++ = '\0'; 17796 if ((tmpvar = ast_variable_new(varname, varval))) { 17797 tmpvar->next = user->chanvars; 17798 user->chanvars = tmpvar; 17799 } 17800 } 17801 } else if (!strcasecmp(v->name, "permit") || 17802 !strcasecmp(v->name, "deny")) { 17803 user->ha = ast_append_ha(v->name, v->value, user->ha); 17804 } else if (!strcasecmp(v->name, "allowtransfer")) { 17805 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17806 } else if (!strcasecmp(v->name, "secret")) { 17807 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 17808 } else if (!strcasecmp(v->name, "md5secret")) { 17809 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 17810 } else if (!strcasecmp(v->name, "callerid")) { 17811 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 17812 } else if (!strcasecmp(v->name, "fullname")) { 17813 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 17814 } else if (!strcasecmp(v->name, "trunkname")) { 17815 /* This is actually for a trunk, so we don't want to override callerid */ 17816 ast_copy_string(user->cid_name, "", sizeof(user->cid_name)); 17817 } else if (!strcasecmp(v->name, "cid_number")) { 17818 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 17819 } else if (!strcasecmp(v->name, "callgroup")) { 17820 user->callgroup = ast_get_group(v->value); 17821 } else if (!strcasecmp(v->name, "pickupgroup")) { 17822 user->pickupgroup = ast_get_group(v->value); 17823 } else if (!strcasecmp(v->name, "language")) { 17824 ast_copy_string(user->language, v->value, sizeof(user->language)); 17825 } else if (!strcasecmp(v->name, "mohinterpret") 17826 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17827 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 17828 } else if (!strcasecmp(v->name, "mohsuggest")) { 17829 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 17830 } else if (!strcasecmp(v->name, "accountcode")) { 17831 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 17832 } else if (!strcasecmp(v->name, "call-limit")) { 17833 user->call_limit = atoi(v->value); 17834 if (user->call_limit < 0) 17835 user->call_limit = 0; 17836 } else if (!strcasecmp(v->name, "amaflags")) { 17837 format = ast_cdr_amaflags2int(v->value); 17838 if (format < 0) { 17839 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 17840 } else { 17841 user->amaflags = format; 17842 } 17843 } else if (!strcasecmp(v->name, "allow")) { 17844 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 17845 } else if (!strcasecmp(v->name, "disallow")) { 17846 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 17847 } else if (!strcasecmp(v->name, "autoframing")) { 17848 user->autoframing = ast_true(v->value); 17849 } else if (!strcasecmp(v->name, "callingpres")) { 17850 user->callingpres = ast_parse_caller_presentation(v->value); 17851 if (user->callingpres == -1) 17852 user->callingpres = atoi(v->value); 17853 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17854 user->maxcallbitrate = atoi(v->value); 17855 if (user->maxcallbitrate < 0) 17856 user->maxcallbitrate = default_maxcallbitrate; 17857 } 17858 /* We can't just report unknown options here because this may be a 17859 * type=friend entry. All user options are valid for a peer, but not 17860 * the other way around. */ 17861 } 17862 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 17863 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 17864 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 17865 global_allowsubscribe = TRUE; /* No global ban any more */ 17866 ast_free_ha(oldha); 17867 return user; 17868 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1857 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().
01858 { 01859 /* Work around buggy UNIDEN UIP200 firmware */ 01860 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01861 01862 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01863 snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s", 01864 ast_inet_ntoa(p->ourip), ourport, (int) p->branch, rport); 01865 }
static int cb_extensionstate | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 9209 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, 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 handle_request_subscribe(), and handle_response().
09210 { 09211 struct sip_pvt *p = data; 09212 09213 ast_mutex_lock(&p->lock); 09214 09215 switch(state) { 09216 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 09217 case AST_EXTENSION_REMOVED: /* Extension is gone */ 09218 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 09219 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09220 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 09221 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); 09222 p->stateid = -1; 09223 p->subscribed = NONE; 09224 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 09225 break; 09226 default: /* Tell user */ 09227 p->laststate = state; 09228 break; 09229 } 09230 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 09231 if (!p->pendinginvite) { 09232 transmit_state_notify(p, state, 1, FALSE); 09233 } else { 09234 /* We already have a NOTIFY sent that is not answered. Queue the state up. 09235 if many state changes happen meanwhile, we will only send a notification of the last one */ 09236 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 09237 } 09238 } 09239 if (option_verbose > 1) 09240 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, 09241 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 09242 09243 09244 ast_mutex_unlock(&p->lock); 09245 09246 return 0; 09247 }
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 5268 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_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().
05269 { 05270 if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 05271 sip_peer_hold(dialog, holdstate); 05272 if (global_callevents) 05273 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 05274 "Channel: %s\r\n" 05275 "Uniqueid: %s\r\n", 05276 dialog->owner->name, 05277 dialog->owner->uniqueid); 05278 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 05279 if (!holdstate) { /* Put off remote hold */ 05280 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 05281 return; 05282 } 05283 /* No address for RTP, we're on hold */ 05284 05285 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 05286 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 05287 else if (sendonly == 2) /* Inactive stream */ 05288 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 05289 else 05290 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 05291 return; 05292 }
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 9011 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, 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, text, transmit_response_with_auth(), and TRUE.
Referenced by check_user_full(), and register_verify().
09014 { 09015 const char *response = "407 Proxy Authentication Required"; 09016 const char *reqheader = "Proxy-Authorization"; 09017 const char *respheader = "Proxy-Authenticate"; 09018 const char *authtoken; 09019 char a1_hash[256]; 09020 char resp_hash[256]=""; 09021 char *c; 09022 int wrongnonce = FALSE; 09023 int good_response; 09024 const char *usednonce = p->randdata; 09025 struct ast_dynamic_str *buf; 09026 int res; 09027 09028 /* table of recognised keywords, and their value in the digest */ 09029 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 09030 struct x { 09031 const char *key; 09032 const char *s; 09033 } *i, keys[] = { 09034 [K_RESP] = { "response=", "" }, 09035 [K_URI] = { "uri=", "" }, 09036 [K_USER] = { "username=", "" }, 09037 [K_NONCE] = { "nonce=", "" }, 09038 [K_LAST] = { NULL, NULL} 09039 }; 09040 09041 /* Always OK if no secret */ 09042 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 09043 return AUTH_SUCCESSFUL; 09044 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 09045 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 09046 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 09047 different circumstances! What a surprise. */ 09048 response = "401 Unauthorized"; 09049 reqheader = "Authorization"; 09050 respheader = "WWW-Authenticate"; 09051 } 09052 authtoken = get_header(req, reqheader); 09053 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 09054 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 09055 information */ 09056 if (!reliable) { 09057 /* Resend message if this was NOT a reliable delivery. Otherwise the 09058 retransmission should get it */ 09059 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 09060 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 09061 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09062 } 09063 return AUTH_CHALLENGE_SENT; 09064 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 09065 /* We have no auth, so issue challenge and request authentication */ 09066 set_nonce_randdata(p, 1); /* Create nonce for challenge */ 09067 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 09068 /* Schedule auto destroy in 32 seconds */ 09069 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09070 return AUTH_CHALLENGE_SENT; 09071 } 09072 09073 /* --- We have auth, so check it */ 09074 09075 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 09076 an example in the spec of just what it is you're doing a hash on. */ 09077 09078 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) 09079 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 09080 09081 /* Make a copy of the response and parse it */ 09082 res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken); 09083 09084 if (res == AST_DYNSTR_BUILD_FAILED) 09085 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 09086 09087 c = buf->str; 09088 09089 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 09090 for (i = keys; i->key != NULL; i++) { 09091 const char *separator = ","; /* default */ 09092 09093 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 09094 continue; 09095 /* Found. Skip keyword, take text in quotes or up to the separator. */ 09096 c += strlen(i->key); 09097 if (*c == '"') { /* in quotes. Skip first and look for last */ 09098 c++; 09099 separator = "\""; 09100 } 09101 i->s = c; 09102 strsep(&c, separator); 09103 break; 09104 } 09105 if (i->key == NULL) /* not found, jump after space or comma */ 09106 strsep(&c, " ,"); 09107 } 09108 09109 /* Verify that digest username matches the username we auth as */ 09110 if (strcmp(username, keys[K_USER].s)) { 09111 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 09112 username, keys[K_USER].s); 09113 /* Oops, we're trying something here */ 09114 return AUTH_USERNAME_MISMATCH; 09115 } 09116 09117 /* Verify nonce from request matches our nonce, and the nonce has not already been responded to. 09118 * If this check fails, send 401 with new nonce */ 09119 if (strcasecmp(p->randdata, keys[K_NONCE].s) || p->stalenonce) { /* XXX it was 'n'casecmp ? */ 09120 wrongnonce = TRUE; 09121 usednonce = keys[K_NONCE].s; 09122 } else { 09123 p->stalenonce = 1; /* now, since the nonce has a response, mark it as stale so it can't be sent or responded to again */ 09124 } 09125 09126 if (!ast_strlen_zero(md5secret)) 09127 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 09128 else { 09129 char a1[256]; 09130 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 09131 ast_md5_hash(a1_hash, a1); 09132 } 09133 09134 /* compute the expected response to compare with what we received */ 09135 { 09136 char a2[256]; 09137 char a2_hash[256]; 09138 char resp[256]; 09139 09140 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 09141 S_OR(keys[K_URI].s, uri)); 09142 ast_md5_hash(a2_hash, a2); 09143 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 09144 ast_md5_hash(resp_hash, resp); 09145 } 09146 09147 good_response = keys[K_RESP].s && 09148 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 09149 if (wrongnonce) { 09150 if (good_response) { 09151 if (sipdebug) 09152 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 09153 /* We got working auth token, based on stale nonce . */ 09154 set_nonce_randdata(p, 0); 09155 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 09156 } else { 09157 /* Everything was wrong, so give the device one more try with a new challenge */ 09158 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 09159 if (sipdebug) 09160 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 09161 set_nonce_randdata(p, 1); 09162 } else { 09163 if (sipdebug) 09164 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 09165 } 09166 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 09167 } 09168 09169 /* Schedule auto destroy in 32 seconds */ 09170 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09171 return AUTH_CHALLENGE_SENT; 09172 } 09173 if (good_response) { 09174 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 09175 return AUTH_SUCCESSFUL; 09176 } 09177 09178 /* Ok, we have a bad username/secret pair */ 09179 /* Tell the UAS not to re-send this authentication data, because 09180 it will continue to fail 09181 */ 09182 09183 return AUTH_SECRET_FAILED; 09184 }
static void check_auth_buf_init | ( | void | ) | [static] |
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 12840 of file chan_sip.c.
References ast_clear_flag, ast_log(), ast_test_flag, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, INV_CALLING, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, LOG_DEBUG, option_debug, 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().
12841 { 12842 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 12843 /* if we can't BYE, then this is really a pending CANCEL */ 12844 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 12845 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 12846 /* Actually don't destroy us yet, wait for the 487 on our original 12847 INVITE, but do set an autodestruct just in case we never get it. */ 12848 else { 12849 /* We have a pending outbound invite, don't send someting 12850 new in-transaction */ 12851 if (p->pendinginvite) 12852 return; 12853 12854 /* Perhaps there is an SD change INVITE outstanding */ 12855 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 12856 } 12857 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 12858 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12859 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 12860 /* if we can't REINVITE, hold it for later */ 12861 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 12862 if (option_debug) 12863 ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 12864 } else { 12865 if (option_debug) 12866 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 12867 /* Didn't get to reinvite yet, so do it now */ 12868 transmit_reinvite_with_sdp(p); 12869 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 12870 } 12871 } 12872 }
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 17633 of file chan_sip.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, and domain::list.
Referenced by func_check_sipdomain(), get_destination(), handle_request_refer(), and register_verify().
17634 { 17635 struct domain *d; 17636 int result = 0; 17637 17638 AST_LIST_LOCK(&domain_list); 17639 AST_LIST_TRAVERSE(&domain_list, d, list) { 17640 if (strcasecmp(d->domain, domain)) 17641 continue; 17642 17643 if (len && !ast_strlen_zero(d->context)) 17644 ast_copy_string(context, d->context, len); 17645 17646 result = 1; 17647 break; 17648 } 17649 AST_LIST_UNLOCK(&domain_list); 17650 17651 return result; 17652 }
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 10454 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
10455 { 10456 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 10457 }
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 10125 of file chan_sip.c.
References sip_peer::accountcode, sip_user::accountcode, accountcode, sip_user::allowtransfer, sip_peer::amaflags, sip_user::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_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, AUTH_FAKE_AUTH, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, sip_peer::autoframing, sip_user::autoframing, build_contact(), sip_peer::call_limit, sip_user::call_limit, sip_peer::callgroup, sip_user::callgroup, sip_peer::callingpres, sip_user::callingpres, sip_peer::capability, sip_user::capability, sip_peer::chanvars, sip_user::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, find_peer(), find_user(), sip_peer::flags, sip_user::flags, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), sip_user::ha, sip_peer::language, sip_user::language, language, sip_peer::lastms, LOG_NOTICE, sip_peer::maxcallbitrate, sip_user::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_peer::pickupgroup, sip_user::pickupgroup, sip_peer::prefs, sip_user::prefs, 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_peer::subscribecontext, sip_user::subscribecontext, t, sip_peer::username, and username.
Referenced by check_user(), and handle_request_subscribe().
10128 { 10129 struct sip_user *user = NULL; 10130 struct sip_peer *peer; 10131 char from[256], *c; 10132 char *of; 10133 char rpid_num[50]; 10134 const char *rpid; 10135 enum check_auth_result res = AUTH_SUCCESSFUL; 10136 char *t; 10137 char calleridname[50]; 10138 int debug=sip_debug_test_addr(sin); 10139 struct ast_variable *tmpvar = NULL, *v = NULL; 10140 char *uri2 = ast_strdupa(uri); 10141 10142 /* Terminate URI */ 10143 t = uri2; 10144 while (*t && *t > 32 && *t != ';') 10145 t++; 10146 *t = '\0'; 10147 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 10148 if (pedanticsipchecking) 10149 ast_uri_decode(from); 10150 /* XXX here tries to map the username for invite things */ 10151 memset(calleridname, 0, sizeof(calleridname)); 10152 get_calleridname(from, calleridname, sizeof(calleridname)); 10153 if (calleridname[0]) 10154 ast_string_field_set(p, cid_name, calleridname); 10155 10156 rpid = get_header(req, "Remote-Party-ID"); 10157 memset(rpid_num, 0, sizeof(rpid_num)); 10158 if (!ast_strlen_zero(rpid)) 10159 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 10160 10161 of = get_in_brackets(from); 10162 if (ast_strlen_zero(p->exten)) { 10163 t = uri2; 10164 if (!strncasecmp(t, "sip:", 4)) 10165 t+= 4; 10166 ast_string_field_set(p, exten, t); 10167 t = strchr(p->exten, '@'); 10168 if (t) 10169 *t = '\0'; 10170 if (ast_strlen_zero(p->our_contact)) 10171 build_contact(p); 10172 } 10173 /* save the URI part of the From header */ 10174 ast_string_field_set(p, from, of); 10175 if (strncasecmp(of, "sip:", 4)) { 10176 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 10177 } else 10178 of += 4; 10179 /* Get just the username part */ 10180 if ((c = strchr(of, '@'))) { 10181 char *tmp; 10182 *c = '\0'; 10183 if ((c = strchr(of, ':'))) 10184 *c = '\0'; 10185 tmp = ast_strdupa(of); 10186 /* We need to be able to handle auth-headers looking like 10187 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 10188 */ 10189 tmp = strsep(&tmp, ";"); 10190 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10191 ast_shrink_phone_number(tmp); 10192 ast_string_field_set(p, cid_num, tmp); 10193 } 10194 10195 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 10196 user = find_user(of, 1); 10197 10198 /* Find user based on user name in the from header */ 10199 if (user && ast_apply_ha(user->ha, sin)) { 10200 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 10201 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10202 if (sipmethod == SIP_INVITE) { 10203 /* copy channel vars */ 10204 for (v = user->chanvars ; v ; v = v->next) { 10205 if ((tmpvar = ast_variable_new(v->name, v->value))) { 10206 tmpvar->next = p->chanvars; 10207 p->chanvars = tmpvar; 10208 } 10209 } 10210 } 10211 p->prefs = user->prefs; 10212 /* Set Frame packetization */ 10213 if (p->rtp) { 10214 ast_rtp_codec_setpref(p->rtp, &p->prefs); 10215 p->autoframing = user->autoframing; 10216 } 10217 /* replace callerid if rpid found, and not restricted */ 10218 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 10219 char *tmp; 10220 if (*calleridname) 10221 ast_string_field_set(p, cid_name, calleridname); 10222 tmp = ast_strdupa(rpid_num); 10223 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10224 ast_shrink_phone_number(tmp); 10225 ast_string_field_set(p, cid_num, tmp); 10226 } 10227 10228 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 10229 10230 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 10231 if (sip_cancel_destroy(p)) 10232 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 10233 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 10234 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10235 /* Copy SIP extensions profile from INVITE */ 10236 if (p->sipoptions) 10237 user->sipoptions = p->sipoptions; 10238 10239 /* If we have a call limit, set flag */ 10240 if (user->call_limit) 10241 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 10242 if (!ast_strlen_zero(user->context)) 10243 ast_string_field_set(p, context, user->context); 10244 if (!ast_strlen_zero(user->cid_num)) { 10245 char *tmp = ast_strdupa(user->cid_num); 10246 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10247 ast_shrink_phone_number(tmp); 10248 ast_string_field_set(p, cid_num, tmp); 10249 } 10250 if (!ast_strlen_zero(user->cid_name)) 10251 ast_string_field_set(p, cid_name, user->cid_name); 10252 ast_string_field_set(p, username, user->name); 10253 ast_string_field_set(p, peername, user->name); 10254 ast_string_field_set(p, peersecret, user->secret); 10255 ast_string_field_set(p, peermd5secret, user->md5secret); 10256 ast_string_field_set(p, subscribecontext, user->subscribecontext); 10257 ast_string_field_set(p, accountcode, user->accountcode); 10258 ast_string_field_set(p, language, user->language); 10259 ast_string_field_set(p, mohsuggest, user->mohsuggest); 10260 ast_string_field_set(p, mohinterpret, user->mohinterpret); 10261 p->allowtransfer = user->allowtransfer; 10262 p->amaflags = user->amaflags; 10263 p->callgroup = user->callgroup; 10264 p->pickupgroup = user->pickupgroup; 10265 if (user->callingpres) /* User callingpres setting will override RPID header */ 10266 p->callingpres = user->callingpres; 10267 10268 /* Set default codec settings for this call */ 10269 p->capability = user->capability; /* User codec choice */ 10270 p->jointcapability = user->capability; /* Our codecs */ 10271 if (p->peercapability) /* AND with peer's codecs */ 10272 p->jointcapability &= p->peercapability; 10273 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 10274 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 10275 p->noncodeccapability |= AST_RTP_DTMF; 10276 else 10277 p->noncodeccapability &= ~AST_RTP_DTMF; 10278 p->jointnoncodeccapability = p->noncodeccapability; 10279 if (p->t38.peercapability) 10280 p->t38.jointcapability &= p->t38.peercapability; 10281 p->maxcallbitrate = user->maxcallbitrate; 10282 /* If we do not support video, remove video from call structure */ 10283 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 10284 ast_rtp_destroy(p->vrtp); 10285 p->vrtp = NULL; 10286 } 10287 } 10288 if (user && debug) 10289 ast_verbose("Found user '%s'\n", user->name); 10290 } else { 10291 if (user) { 10292 if (!authpeer && debug) 10293 ast_verbose("Found user '%s', but fails host access\n", user->name); 10294 ASTOBJ_UNREF(user,sip_destroy_user); 10295 } 10296 user = NULL; 10297 } 10298 10299 if (!user) { 10300 /* If we didn't find a user match, check for peers */ 10301 if (sipmethod == SIP_SUBSCRIBE) 10302 /* For subscribes, match on peer name only */ 10303 peer = find_peer(of, NULL, 1, 0); 10304 else 10305 /* Look for peer based on the IP address we received data from */ 10306 /* If peer is registered from this IP address or have this as a default 10307 IP address, this call is from the peer 10308 */ 10309 peer = find_peer(NULL, &p->recv, 1, 0); 10310 10311 if (peer) { 10312 /* Set Frame packetization */ 10313 if (p->rtp) { 10314 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 10315 p->autoframing = peer->autoframing; 10316 } 10317 if (debug) 10318 ast_verbose("Found peer '%s'\n", peer->name); 10319 10320 /* Take the peer */ 10321 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 10322 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10323 10324 /* Copy SIP extensions profile to peer */ 10325 if (p->sipoptions) 10326 peer->sipoptions = p->sipoptions; 10327 10328 /* replace callerid if rpid found, and not restricted */ 10329 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 10330 char *tmp = ast_strdupa(rpid_num); 10331 if (*calleridname) 10332 ast_string_field_set(p, cid_name, calleridname); 10333 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10334 ast_shrink_phone_number(tmp); 10335 ast_string_field_set(p, cid_num, tmp); 10336 } 10337 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 10338 10339 ast_string_field_set(p, peersecret, peer->secret); 10340 ast_string_field_set(p, peermd5secret, peer->md5secret); 10341 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 10342 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 10343 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 10344 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 10345 p->callingpres = peer->callingpres; 10346 if (peer->maxms && peer->lastms) 10347 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 10348 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 10349 /* Pretend there is no required authentication */ 10350 ast_string_field_free(p, peersecret); 10351 ast_string_field_free(p, peermd5secret); 10352 } 10353 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 10354 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 10355 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10356 /* If we have a call limit, set flag */ 10357 if (peer->call_limit) 10358 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 10359 ast_string_field_set(p, peername, peer->name); 10360 ast_string_field_set(p, authname, peer->name); 10361 10362 if (sipmethod == SIP_INVITE) { 10363 /* copy channel vars */ 10364 for (v = peer->chanvars ; v ; v = v->next) { 10365 if ((tmpvar = ast_variable_new(v->name, v->value))) { 10366 tmpvar->next = p->chanvars; 10367 p->chanvars = tmpvar; 10368 } 10369 } 10370 } 10371 if (authpeer) { 10372 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 10373 } 10374 10375 if (!ast_strlen_zero(peer->username)) { 10376 ast_string_field_set(p, username, peer->username); 10377 /* Use the default username for authentication on outbound calls */ 10378 /* XXX this takes the name from the caller... can we override ? */ 10379 ast_string_field_set(p, authname, peer->username); 10380 } 10381 if (!ast_strlen_zero(peer->cid_num)) { 10382 char *tmp = ast_strdupa(peer->cid_num); 10383 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10384 ast_shrink_phone_number(tmp); 10385 ast_string_field_set(p, cid_num, tmp); 10386 } 10387 if (!ast_strlen_zero(peer->cid_name)) 10388 ast_string_field_set(p, cid_name, peer->cid_name); 10389 ast_string_field_set(p, fullcontact, peer->fullcontact); 10390 if (!ast_strlen_zero(peer->context)) 10391 ast_string_field_set(p, context, peer->context); 10392 ast_string_field_set(p, peersecret, peer->secret); 10393 ast_string_field_set(p, peermd5secret, peer->md5secret); 10394 ast_string_field_set(p, language, peer->language); 10395 ast_string_field_set(p, accountcode, peer->accountcode); 10396 p->amaflags = peer->amaflags; 10397 p->callgroup = peer->callgroup; 10398 p->pickupgroup = peer->pickupgroup; 10399 p->capability = peer->capability; 10400 p->prefs = peer->prefs; 10401 p->jointcapability = peer->capability; 10402 if (p->peercapability) 10403 p->jointcapability &= p->peercapability; 10404 p->maxcallbitrate = peer->maxcallbitrate; 10405 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 10406 ast_rtp_destroy(p->vrtp); 10407 p->vrtp = NULL; 10408 } 10409 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 10410 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 10411 p->noncodeccapability |= AST_RTP_DTMF; 10412 else 10413 p->noncodeccapability &= ~AST_RTP_DTMF; 10414 p->jointnoncodeccapability = p->noncodeccapability; 10415 if (p->t38.peercapability) 10416 p->t38.jointcapability &= p->t38.peercapability; 10417 } 10418 ASTOBJ_UNREF(peer, sip_destroy_peer); 10419 } else { 10420 if (debug) 10421 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 10422 10423 /* do we allow guests? */ 10424 if (!global_allowguest) { 10425 if (global_alwaysauthreject) 10426 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 10427 else 10428 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 10429 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 10430 char *tmp = ast_strdupa(rpid_num); 10431 if (*calleridname) 10432 ast_string_field_set(p, cid_name, calleridname); 10433 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10434 ast_shrink_phone_number(tmp); 10435 ast_string_field_set(p, cid_num, tmp); 10436 } 10437 } 10438 10439 } 10440 10441 if (user) 10442 ASTOBJ_UNREF(user, sip_destroy_user); 10443 10444 if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT)) { 10445 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 10446 } 10447 10448 return res; 10449 }
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 9982 of file chan_sip.c.
References ahp, ast_copy_string(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_skip_blanks(), ast_verbose(), sip_pvt::flags, get_header(), hp, 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().
09983 { 09984 char via[512]; 09985 char *c, *pt, *maddr; 09986 struct hostent *hp; 09987 struct ast_hostent ahp; 09988 09989 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 09990 09991 /* Work on the leftmost value of the topmost Via header */ 09992 c = strchr(via, ','); 09993 if (c) 09994 *c = '\0'; 09995 09996 /* Check for rport */ 09997 c = strstr(via, ";rport"); 09998 if (c && (c[6] != '=')) /* rport query, not answer */ 09999 ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT); 10000 10001 /* Check for maddr */ 10002 maddr = strstr(via, "maddr="); 10003 if (maddr) { 10004 maddr += 6; 10005 c = maddr + strspn(maddr, "0123456789."); 10006 *c = '\0'; 10007 } 10008 10009 c = strchr(via, ';'); 10010 if (c) 10011 *c = '\0'; 10012 10013 c = strchr(via, ' '); 10014 if (c) { 10015 *c = '\0'; 10016 c = ast_skip_blanks(c+1); 10017 if (strcasecmp(via, "SIP/2.0/UDP")) { 10018 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 10019 return; 10020 } 10021 pt = strchr(c, ':'); 10022 if (pt) 10023 *pt++ = '\0'; /* remember port pointer */ 10024 /* Use maddr if found */ 10025 if (maddr) 10026 c = maddr; 10027 hp = ast_gethostbyname(c, &ahp); 10028 if (!hp) { 10029 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 10030 return; 10031 } 10032 memset(&p->sa, 0, sizeof(p->sa)); 10033 p->sa.sin_family = AF_INET; 10034 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 10035 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 10036 10037 if (sip_debug_test_pvt(p)) { 10038 const struct sockaddr_in *dst = sip_real_dst(p); 10039 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 10040 } 10041 } 10042 }
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 10898 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), ast_copy_string(), and AST_MAX_CONTEXT.
10899 { 10900 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 10901 10902 while ((oldcontext = strsep(&old, "&"))) { 10903 stalecontext = '\0'; 10904 ast_copy_string(newlist, new, sizeof(newlist)); 10905 stringp = newlist; 10906 while ((newcontext = strsep(&stringp, "&"))) { 10907 if (strcmp(newcontext, oldcontext) == 0) { 10908 /* This is not the context you're looking for */ 10909 stalecontext = '\0'; 10910 break; 10911 } else if (strcmp(newcontext, oldcontext)) { 10912 stalecontext = oldcontext; 10913 } 10914 10915 } 10916 if (stalecontext) 10917 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 10918 } 10919 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 17724 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
17725 { 17726 struct sip_auth *a = authlist; 17727 struct sip_auth *b; 17728 17729 while (a) { 17730 b = a; 17731 a = a->next; 17732 free(b); 17733 } 17734 17735 return 1; 17736 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 17655 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free, and domain::list.
Referenced by reload_config(), and unload_module().
17656 { 17657 struct domain *d; 17658 17659 AST_LIST_LOCK(&domain_list); 17660 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 17661 free(d); 17662 AST_LIST_UNLOCK(&domain_list); 17663 }
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 11718 of file chan_sip.c.
References complete_sip_peer().
11719 { 11720 if (pos == 3) 11721 return complete_sip_peer(word, state, 0); 11722 11723 return NULL; 11724 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 11692 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().
11693 { 11694 char *result = NULL; 11695 int wordlen = strlen(word); 11696 int which = 0; 11697 11698 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 11699 /* locking of the object is not required because only the name and flags are being compared */ 11700 if (!strncasecmp(word, iterator->name, wordlen) && 11701 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 11702 ++which > state) 11703 result = ast_strdup(iterator->name); 11704 } while(0) ); 11705 return result; 11706 }
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 11786 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
11787 { 11788 if (pos == 4) 11789 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11790 return NULL; 11791 }
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 11794 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
11795 { 11796 if (pos == 4) 11797 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11798 11799 return NULL; 11800 }
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 11709 of file chan_sip.c.
References complete_sip_peer().
11710 { 11711 if (pos == 3) 11712 return complete_sip_peer(word, state, 0); 11713 11714 return NULL; 11715 }
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 11747 of file chan_sip.c.
References complete_sip_user().
11748 { 11749 if (pos == 3) 11750 return complete_sip_user(word, state, 0); 11751 11752 return NULL; 11753 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 11727 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().
11728 { 11729 char *result = NULL; 11730 int wordlen = strlen(word); 11731 int which = 0; 11732 11733 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 11734 /* locking of the object is not required because only the name and flags are being compared */ 11735 if (!strncasecmp(word, iterator->name, wordlen)) { 11736 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 11737 continue; 11738 if (++which > state) { 11739 result = ast_strdup(iterator->name); 11740 } 11741 } 11742 } while(0) ); 11743 return result; 11744 }
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 11669 of file chan_sip.c.
References ast_mutex_lock, ast_strdup, sip_pvt::callid, iflist, iflock, and sip_pvt::next.
11670 { 11671 int which=0; 11672 struct sip_pvt *cur; 11673 char *c = NULL; 11674 int wordlen = strlen(word); 11675 11676 if (pos != 3) { 11677 return NULL; 11678 } 11679 11680 ast_mutex_lock(&iflock); 11681 for (cur = iflist; cur; cur = cur->next) { 11682 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 11683 c = ast_strdup(cur->callid); 11684 break; 11685 } 11686 } 11687 ast_mutex_unlock(&iflock); 11688 return c; 11689 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 11756 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
11757 { 11758 char *c = NULL; 11759 11760 if (pos == 2) { 11761 int which = 0; 11762 char *cat = NULL; 11763 int wordlen = strlen(word); 11764 11765 /* do completion for notify type */ 11766 11767 if (!notify_types) 11768 return NULL; 11769 11770 while ( (cat = ast_category_browse(notify_types, cat)) ) { 11771 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 11772 c = ast_strdup(cat); 11773 break; 11774 } 11775 } 11776 return c; 11777 } 11778 11779 if (pos > 2) 11780 return complete_sip_peer(word, state, 0); 11781 11782 return NULL; 11783 }
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 6150 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
06151 { 06152 int start = 0; 06153 int copied = 0; 06154 for (;;) { 06155 const char *tmp = __get_header(orig, field, &start); 06156 06157 if (ast_strlen_zero(tmp)) 06158 break; 06159 /* Add what we're responding to */ 06160 add_header(req, field, tmp); 06161 copied++; 06162 } 06163 return copied ? 0 : -1; 06164 }
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 6139 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
06140 { 06141 const char *tmp = get_header(orig, field); 06142 06143 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 06144 return add_header(req, field, tmp); 06145 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 06146 return -1; 06147 }
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 7247 of file chan_sip.c.
References offset.
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().
07248 { 07249 long offset; 07250 int x; 07251 offset = ((void *)dst) - ((void *)src); 07252 /* First copy stuff */ 07253 memcpy(dst, src, sizeof(*dst)); 07254 /* Now fix pointer arithmetic */ 07255 for (x=0; x < src->headers; x++) 07256 dst->header[x] += offset; 07257 for (x=0; x < src->lines; x++) 07258 dst->line[x] += offset; 07259 dst->rlPart1 += offset; 07260 dst->rlPart2 += offset; 07261 }
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 6172 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().
06173 { 06174 int copied = 0; 06175 int start = 0; 06176 06177 for (;;) { 06178 char new[512]; 06179 const char *oh = __get_header(orig, field, &start); 06180 06181 if (ast_strlen_zero(oh)) 06182 break; 06183 06184 if (!copied) { /* Only check for empty rport in topmost via header */ 06185 char leftmost[512], *others, *rport; 06186 06187 /* Only work on leftmost value */ 06188 ast_copy_string(leftmost, oh, sizeof(leftmost)); 06189 others = strchr(leftmost, ','); 06190 if (others) 06191 *others++ = '\0'; 06192 06193 /* Find ;rport; (empty request) */ 06194 rport = strstr(leftmost, ";rport"); 06195 if (rport && *(rport+6) == '=') 06196 rport = NULL; /* We already have a parameter to rport */ 06197 06198 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 06199 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 06200 /* We need to add received port - rport */ 06201 char *end; 06202 06203 rport = strstr(leftmost, ";rport"); 06204 06205 if (rport) { 06206 end = strchr(rport + 1, ';'); 06207 if (end) 06208 memmove(rport, end, strlen(end) + 1); 06209 else 06210 *rport = '\0'; 06211 } 06212 06213 /* Add rport to first VIA header if requested */ 06214 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 06215 leftmost, ast_inet_ntoa(p->recv.sin_addr), 06216 ntohs(p->recv.sin_port), 06217 others ? "," : "", others ? others : ""); 06218 } else { 06219 /* We should *always* add a received to the topmost via */ 06220 snprintf(new, sizeof(new), "%s;received=%s%s%s", 06221 leftmost, ast_inet_ntoa(p->recv.sin_addr), 06222 others ? "," : "", others ? others : ""); 06223 } 06224 oh = new; /* the header to copy */ 06225 } /* else add the following via headers untouched */ 06226 add_header(req, field, oh); 06227 copied++; 06228 } 06229 if (!copied) { 06230 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 06231 return -1; 06232 } 06233 return 0; 06234 }
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 3029 of file chan_sip.c.
References ahp, ast_copy_string(), ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ASTOBJ_UNREF, create_addr_from_peer(), do_setnat(), find_peer(), sip_pvt::flags, hp, 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.
03030 { 03031 struct hostent *hp; 03032 struct ast_hostent ahp; 03033 struct sip_peer *p; 03034 char *port; 03035 int portno = 0; 03036 char host[MAXHOSTNAMELEN], *hostn; 03037 char peer[256]; 03038 03039 ast_copy_string(peer, opeer, sizeof(peer)); 03040 port = strchr(peer, ':'); 03041 if (port) { 03042 *port++ = '\0'; 03043 dialog->portinuri = 1; 03044 } 03045 dialog->sa.sin_family = AF_INET; 03046 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 03047 p = find_peer(peer, NULL, 1, 0); 03048 03049 if (p) { 03050 int res = create_addr_from_peer(dialog, p); 03051 if (port) { 03052 portno = atoi(port); 03053 dialog->sa.sin_port = dialog->recv.sin_port = htons(portno); 03054 } 03055 ASTOBJ_UNREF(p, sip_destroy_peer); 03056 return res; 03057 } 03058 03059 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 03060 03061 ast_string_field_set(dialog, tohost, peer); 03062 03063 if (sin) { 03064 memcpy(&dialog->sa.sin_addr, &sin->sin_addr, sizeof(dialog->sa.sin_addr)); 03065 if (!sin->sin_port) { 03066 if (ast_strlen_zero(port) || sscanf(port, "%30u", &portno) != 1) { 03067 portno = STANDARD_SIP_PORT; 03068 } 03069 } else { 03070 portno = ntohs(sin->sin_port); 03071 } 03072 } else { 03073 hostn = peer; 03074 /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then 03075 * an A record lookup should be used instead of SRV. 03076 */ 03077 if (!port && srvlookup) { 03078 char service[MAXHOSTNAMELEN]; 03079 int tportno; 03080 int ret; 03081 03082 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 03083 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 03084 if (ret > 0) { 03085 hostn = host; 03086 portno = tportno; 03087 } 03088 } 03089 if (!portno) 03090 portno = port ? atoi(port) : STANDARD_SIP_PORT; 03091 03092 hp = ast_gethostbyname(hostn, &ahp); 03093 if (!hp) { 03094 ast_log(LOG_WARNING, "No such host: %s\n", peer); 03095 return -1; 03096 } 03097 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 03098 } 03099 dialog->sa.sin_port = htons(portno); 03100 dialog->recv = dialog->sa; 03101 return 0; 03102 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 2912 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_constantssrc(), 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_CONSTANT_SSRC, 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().
02913 { 02914 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 02915 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 02916 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 02917 dialog->recv = dialog->sa; 02918 } else 02919 return -1; 02920 02921 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 02922 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 02923 dialog->capability = peer->capability; 02924 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 02925 ast_rtp_destroy(dialog->vrtp); 02926 dialog->vrtp = NULL; 02927 } 02928 dialog->prefs = peer->prefs; 02929 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 02930 dialog->t38.capability = global_t38_capability; 02931 if (dialog->udptl) { 02932 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 02933 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 02934 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 02935 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 02936 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 02937 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 02938 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 02939 if (option_debug > 1) 02940 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 02941 } 02942 dialog->t38.jointcapability = dialog->t38.capability; 02943 } else if (dialog->udptl) { 02944 ast_udptl_destroy(dialog->udptl); 02945 dialog->udptl = NULL; 02946 } 02947 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 02948 02949 if (dialog->rtp) { 02950 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 02951 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 02952 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 02953 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 02954 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 02955 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_CONSTANT_SSRC)) { 02956 ast_rtp_set_constantssrc(dialog->rtp); 02957 } 02958 /* Set Frame packetization */ 02959 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 02960 dialog->autoframing = peer->autoframing; 02961 } 02962 if (dialog->vrtp) { 02963 ast_rtp_setdtmf(dialog->vrtp, 0); 02964 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 02965 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 02966 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 02967 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 02968 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_CONSTANT_SSRC)) { 02969 ast_rtp_set_constantssrc(dialog->vrtp); 02970 } 02971 } 02972 02973 ast_string_field_set(dialog, peername, peer->name); 02974 ast_string_field_set(dialog, authname, peer->username); 02975 ast_string_field_set(dialog, username, peer->username); 02976 ast_string_field_set(dialog, peersecret, peer->secret); 02977 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 02978 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 02979 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 02980 ast_string_field_set(dialog, tohost, peer->tohost); 02981 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 02982 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 02983 char *tmpcall; 02984 char *c; 02985 tmpcall = ast_strdupa(dialog->callid); 02986 c = strchr(tmpcall, '@'); 02987 if (c) { 02988 *c = '\0'; 02989 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 02990 } 02991 } 02992 if (ast_strlen_zero(dialog->tohost)) 02993 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 02994 if (!ast_strlen_zero(peer->fromdomain)) 02995 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 02996 if (!ast_strlen_zero(peer->fromuser)) 02997 ast_string_field_set(dialog, fromuser, peer->fromuser); 02998 if (!ast_strlen_zero(peer->language)) 02999 ast_string_field_set(dialog, language, peer->language); 03000 dialog->maxtime = peer->maxms; 03001 dialog->callgroup = peer->callgroup; 03002 dialog->pickupgroup = peer->pickupgroup; 03003 dialog->peerauth = peer->auth; 03004 dialog->allowtransfer = peer->allowtransfer; 03005 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 03006 /* Minimum is settable or default to 100 ms */ 03007 if (peer->maxms && peer->lastms) 03008 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 03009 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 03010 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 03011 dialog->noncodeccapability |= AST_RTP_DTMF; 03012 else 03013 dialog->noncodeccapability &= ~AST_RTP_DTMF; 03014 dialog->jointnoncodeccapability = dialog->noncodeccapability; 03015 ast_string_field_set(dialog, context, peer->context); 03016 dialog->rtptimeout = peer->rtptimeout; 03017 if (peer->call_limit) 03018 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 03019 dialog->maxcallbitrate = peer->maxcallbitrate; 03020 if (!dialog->portinuri) 03021 dialog->portinuri = peer->portinuri; 03022 03023 return 0; 03024 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 8465 of file chan_sip.c.
References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_peer::flags, global_flags, sip_peer::name, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, and SIP_PAGE2_RTUPDATE.
Referenced by build_peer(), expire_register(), and parse_register_contact().
08466 { 08467 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 08468 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT) && ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) { 08469 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 08470 ast_update_realtime("sippeers", "name", peer->name, "lastms", "", NULL); 08471 } else 08472 ast_db_del("SIP/Registry", peer->name); 08473 } 08474 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 7296 of file chan_sip.c.
References ast_log(), ast_skip_blanks(), ast_skip_nonblanks(), ast_trim_blanks(), sip_request::header, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by parse_request().
07297 { 07298 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 07299 07300 if (!*e) 07301 return -1; 07302 req->rlPart1 = e; /* method or protocol */ 07303 e = ast_skip_nonblanks(e); 07304 if (*e) 07305 *e++ = '\0'; 07306 /* Get URI or status code */ 07307 e = ast_skip_blanks(e); 07308 if ( !*e ) 07309 return -1; 07310 ast_trim_blanks(e); 07311 07312 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 07313 if (strlen(e) < 3) /* status code is 3 digits */ 07314 return -1; 07315 req->rlPart2 = e; 07316 } else { /* We have a request */ 07317 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 07318 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 07319 e++; 07320 if (!*e) 07321 return -1; 07322 } 07323 req->rlPart2 = e; /* URI */ 07324 e = ast_skip_nonblanks(e); 07325 if (*e) 07326 *e++ = '\0'; 07327 e = ast_skip_blanks(e); 07328 if (strcasecmp(e, "SIP/2.0") ) { 07329 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 07330 return -1; 07331 } 07332 } 07333 return 1; 07334 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 16927 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_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_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, ast_verbose(), DEADLOCK_AVOIDANCE, FALSE, sip_pvt::flags, iflist, iflock, io, sip_pvt::lock, LOG_NOTICE, sip_pvt::next, option_verbose, sip_pvt::owner, sip_pvt::packets, sip_do_reload(), SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, sip_reload_lock, sipsock, sipsock_read(), t, T38_ENABLED, and VERBOSE_PREFIX_1.
16928 { 16929 int res; 16930 struct sip_pvt *sip; 16931 struct sip_peer *peer = NULL; 16932 time_t t; 16933 int fastrestart = FALSE; 16934 int lastpeernum = -1; 16935 int curpeernum; 16936 int reloading; 16937 16938 /* Add an I/O event to our SIP UDP socket */ 16939 if (sipsock > -1) 16940 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 16941 16942 /* From here on out, we die whenever asked */ 16943 for(;;) { 16944 /* Check for a reload request */ 16945 ast_mutex_lock(&sip_reload_lock); 16946 reloading = sip_reloading; 16947 sip_reloading = FALSE; 16948 ast_mutex_unlock(&sip_reload_lock); 16949 if (reloading) { 16950 if (option_verbose > 0) 16951 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 16952 sip_do_reload(sip_reloadreason); 16953 16954 /* Change the I/O fd of our UDP socket */ 16955 if (sipsock > -1) { 16956 if (sipsock_read_id) 16957 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 16958 else 16959 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 16960 } else if (sipsock_read_id) { 16961 ast_io_remove(io, sipsock_read_id); 16962 sipsock_read_id = NULL; 16963 } 16964 } 16965 restartsearch: 16966 /* Check for interfaces needing to be killed */ 16967 ast_mutex_lock(&iflock); 16968 t = time(NULL); 16969 /* don't scan the interface list if it hasn't been a reasonable period 16970 of time since the last time we did it (when MWI is being sent, we can 16971 get back to this point every millisecond or less) 16972 */ 16973 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 16974 /*! \note If we can't get a lock on an interface, skip it and come 16975 * back later. Note that there is the possibility of a deadlock with 16976 * sip_hangup otherwise, because sip_hangup is called with the channel 16977 * locked first, and the iface lock is attempted second. 16978 */ 16979 if (ast_mutex_trylock(&sip->lock)) 16980 continue; 16981 16982 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 16983 if (sip->rtp && sip->owner && 16984 (sip->owner->_state == AST_STATE_UP) && 16985 !sip->redirip.sin_addr.s_addr && 16986 sip->t38.state != T38_ENABLED) { 16987 if (sip->lastrtptx && 16988 ast_rtp_get_rtpkeepalive(sip->rtp) && 16989 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 16990 /* Need to send an empty RTP packet */ 16991 sip->lastrtptx = time(NULL); 16992 ast_rtp_sendcng(sip->rtp, 0); 16993 } 16994 if (sip->lastrtprx && 16995 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 16996 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 16997 /* Might be a timeout now -- see if we're on hold */ 16998 struct sockaddr_in sin = { 0, }; 16999 ast_rtp_get_peer(sip->rtp, &sin); 17000 if (!ast_test_flag(&sip->flags[1], SIP_PAGE2_CALL_ONHOLD) || 17001 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 17002 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 17003 /* Needs a hangup */ 17004 if (ast_rtp_get_rtptimeout(sip->rtp)) { 17005 while (sip->owner && ast_channel_trylock(sip->owner)) { 17006 DEADLOCK_AVOIDANCE(&sip->lock); 17007 } 17008 if (sip->owner) { 17009 ast_log(LOG_NOTICE, 17010 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 17011 sip->owner->name, 17012 (long) (t - sip->lastrtprx)); 17013 /* Issue a softhangup */ 17014 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 17015 ast_channel_unlock(sip->owner); 17016 /* forget the timeouts for this call, since a hangup 17017 has already been requested and we don't want to 17018 repeatedly request hangups 17019 */ 17020 ast_rtp_set_rtptimeout(sip->rtp, 0); 17021 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 17022 if (sip->vrtp) { 17023 ast_rtp_set_rtptimeout(sip->vrtp, 0); 17024 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 17025 } 17026 } 17027 } 17028 } 17029 } 17030 } 17031 /* If we have sessions that needs to be destroyed, do it now */ 17032 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 17033 !sip->owner) { 17034 ast_mutex_unlock(&sip->lock); 17035 __sip_destroy(sip, 1); 17036 ast_mutex_unlock(&iflock); 17037 usleep(1); 17038 goto restartsearch; 17039 } 17040 ast_mutex_unlock(&sip->lock); 17041 } 17042 ast_mutex_unlock(&iflock); 17043 17044 /* XXX TODO The scheduler usage in this module does not have sufficient 17045 * synchronization being done between running the scheduler and places 17046 * scheduling tasks. As it is written, any scheduled item may not run 17047 * any sooner than about 1 second, regardless of whether a sooner time 17048 * was asked for. */ 17049 17050 pthread_testcancel(); 17051 /* Wait for sched or io */ 17052 res = ast_sched_wait(sched); 17053 if ((res < 0) || (res > 1000)) 17054 res = 1000; 17055 /* If we might need to send more mailboxes, don't wait long at all.*/ 17056 if (fastrestart) 17057 res = 1; 17058 res = ast_io_wait(io, res); 17059 if (option_debug && res > 20) 17060 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 17061 ast_mutex_lock(&monlock); 17062 res = ast_sched_runq(sched); 17063 if (option_debug && res >= 20) 17064 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 17065 17066 /* Send MWI notifications to peers - static and cached realtime peers */ 17067 t = time(NULL); 17068 fastrestart = FALSE; 17069 curpeernum = 0; 17070 peer = NULL; 17071 /* Find next peer that needs mwi */ 17072 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 17073 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 17074 fastrestart = TRUE; 17075 lastpeernum = curpeernum; 17076 peer = ASTOBJ_REF(iterator); 17077 }; 17078 curpeernum++; 17079 } while (0) 17080 ); 17081 /* Send MWI to the peer */ 17082 if (peer) { 17083 ASTOBJ_WRLOCK(peer); 17084 sip_send_mwi_to_peer(peer, FALSE); 17085 ASTOBJ_UNLOCK(peer); 17086 ASTOBJ_UNREF(peer,sip_destroy_peer); 17087 } else { 17088 /* Reset where we come from */ 17089 lastpeernum = -1; 17090 } 17091 ast_mutex_unlock(&monlock); 17092 } 17093 /* Never reached */ 17094 return NULL; 17095 17096 }
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 12266 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().
12267 { 12268 char digest[1024]; 12269 12270 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 12271 return -2; 12272 12273 p->authtries++; 12274 if (option_debug > 1) 12275 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 12276 memset(digest, 0, sizeof(digest)); 12277 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 12278 /* No way to authenticate */ 12279 return -1; 12280 } 12281 /* Now we have a reply digest */ 12282 p->options->auth = digest; 12283 p->options->authheader = respheader; 12284 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 12285 }
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 12245 of file chan_sip.c.
References append_history, ast_test_flag, ast_verbose(), sip_pvt::authtries, sip_pvt::flags, reply_digest(), sip_debug_test_pvt(), SIP_NO_HISTORY, SIP_REGISTER, and transmit_register().
Referenced by handle_response_register().
12246 { 12247 char digest[1024]; 12248 p->authtries++; 12249 memset(digest,0,sizeof(digest)); 12250 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 12251 /* There's nothing to use for authentication */ 12252 /* No digest challenge in request */ 12253 if (sip_debug_test_pvt(p) && p->registry) 12254 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 12255 /* No old challenge */ 12256 return -1; 12257 } 12258 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 12259 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 12260 if (sip_debug_test_pvt(p) && p->registry) 12261 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 12262 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 12263 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 2888 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().
02889 { 02890 const char *mode = natflags ? "On" : "Off"; 02891 02892 if (p->rtp) { 02893 if (option_debug) 02894 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 02895 ast_rtp_setnat(p->rtp, natflags); 02896 } 02897 if (p->vrtp) { 02898 if (option_debug) 02899 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 02900 ast_rtp_setnat(p->vrtp, natflags); 02901 } 02902 if (p->udptl) { 02903 if (option_debug) 02904 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 02905 ast_udptl_setnat(p->udptl, natflags); 02906 } 02907 }
static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 16906 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.
16907 { 16908 time_t t = time(NULL); 16909 16910 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 16911 !peer->mwipvt) { /* We don't have a subscription */ 16912 peer->lastmsgcheck = t; /* Reset timer */ 16913 return FALSE; 16914 } 16915 16916 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 16917 return TRUE; 16918 16919 return FALSE; 16920 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 11087 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
11088 { 11089 switch (mode) { 11090 case SIP_DOMAIN_AUTO: 11091 return "[Automatic]"; 11092 case SIP_DOMAIN_CONFIG: 11093 return "[Configured]"; 11094 } 11095 11096 return ""; 11097 }
static const char * dtmfmode2str | ( | int | mode | ) | const [static] |
Convert DTMF mode to printable string.
Definition at line 10867 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().
10868 { 10869 switch (mode) { 10870 case SIP_DTMF_RFC2833: 10871 return "rfc2833"; 10872 case SIP_DTMF_INFO: 10873 return "info"; 10874 case SIP_DTMF_INBAND: 10875 return "inband"; 10876 case SIP_DTMF_AUTO: 10877 return "auto"; 10878 } 10879 return "<error>"; 10880 }
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 8477 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(), and reg_source_db().
08478 { 08479 struct sip_peer *peer = (struct sip_peer *)data; 08480 08481 if (!peer) /* Hmmm. We have no peer. Weird. */ 08482 return 0; 08483 08484 memset(&peer->addr, 0, sizeof(peer->addr)); 08485 08486 destroy_association(peer); /* remove registration data from storage */ 08487 08488 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08489 register_peer_exten(peer, FALSE); /* Remove regexten */ 08490 peer->expire = -1; 08491 peer->portinuri = 0; 08492 ast_device_state_changed("SIP/%s", peer->name); 08493 08494 /* Do we need to release this peer from memory? 08495 Only for realtime peers and autocreated peers 08496 */ 08497 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 08498 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 08499 struct sip_peer *peer_ptr = peer_ptr; 08500 peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); 08501 if (peer_ptr) { 08502 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08503 } 08504 } 08505 08506 ASTOBJ_UNREF(peer, sip_destroy_peer); 08507 08508 return 0; 08509 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 7388 of file chan_sip.c.
References ast_copy_string(), ast_string_field_set, ast_strlen_zero(), get_header(), get_in_brackets(), and SIPBUFSIZE.
Referenced by handle_request(), and handle_request_invite().
07389 { 07390 char stripped[SIPBUFSIZE]; 07391 char *c; 07392 07393 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 07394 c = get_in_brackets(stripped); 07395 c = strsep(&c, ";"); /* trim ; and beyond */ 07396 if (!ast_strlen_zero(c)) 07397 ast_string_field_set(p, uri, c); 07398 }
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 4467 of file chan_sip.c.
References aliases.
04468 { 04469 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 04470 static const struct cfalias { 04471 char * const fullname; 04472 char * const shortname; 04473 } aliases[] = { 04474 { "Content-Type", "c" }, 04475 { "Content-Encoding", "e" }, 04476 { "From", "f" }, 04477 { "Call-ID", "i" }, 04478 { "Contact", "m" }, 04479 { "Content-Length", "l" }, 04480 { "Subject", "s" }, 04481 { "To", "t" }, 04482 { "Supported", "k" }, 04483 { "Refer-To", "r" }, 04484 { "Referred-By", "b" }, 04485 { "Allow-Events", "u" }, 04486 { "Event", "o" }, 04487 { "Via", "v" }, 04488 { "Accept-Contact", "a" }, 04489 { "Reject-Contact", "j" }, 04490 { "Request-Disposition", "d" }, 04491 { "Session-Expires", "x" }, 04492 { "Identity", "y" }, 04493 { "Identity-Info", "n" }, 04494 }; 04495 int x; 04496 04497 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04498 if (!strcasecmp(aliases[x].fullname, name)) 04499 return aliases[x].shortname; 04500 04501 return _default; 04502 }
static struct sip_pvt * find_call | ( | struct sip_request * | req, | |
struct sockaddr_in * | sin, | |||
const int | intended_method | |||
) | [static] |
Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read.
Definition at line 4840 of file chan_sip.c.
References ast_log(), ast_mutex_lock, ast_set_flag, ast_strlen_zero(), ast_test_flag, sip_pvt::callid, FALSE, sip_pvt::flags, sip_pvt::from, get_header(), gettag(), iflist, iflock, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_WITH_TOTAG, SIP_REGISTER, SIP_RESPONSE, sip_pvt::tag, and sip_pvt::theirtag.
Referenced by sipsock_read().
04841 { 04842 struct sip_pvt *p = NULL; 04843 char *tag = ""; /* note, tag is never NULL */ 04844 char totag[128]; 04845 char fromtag[128]; 04846 const char *callid = get_header(req, "Call-ID"); 04847 const char *from = get_header(req, "From"); 04848 const char *to = get_header(req, "To"); 04849 const char *cseq = get_header(req, "Cseq"); 04850 04851 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 04852 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 04853 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 04854 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 04855 return NULL; /* Invalid packet */ 04856 04857 if (pedanticsipchecking) { 04858 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 04859 we need more to identify a branch - so we have to check branch, from 04860 and to tags to identify a call leg. 04861 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 04862 in sip.conf 04863 */ 04864 if (gettag(req, "To", totag, sizeof(totag))) 04865 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 04866 gettag(req, "From", fromtag, sizeof(fromtag)); 04867 04868 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 04869 04870 if (option_debug > 4 ) 04871 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); 04872 } 04873 04874 ast_mutex_lock(&iflock); 04875 for (p = iflist; p; p = p->next) { 04876 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 04877 int found = FALSE; 04878 if (ast_strlen_zero(p->callid)) 04879 continue; 04880 if (req->method == SIP_REGISTER) 04881 found = (!strcmp(p->callid, callid)); 04882 else { 04883 found = !strcmp(p->callid, callid); 04884 if (pedanticsipchecking && found) { 04885 found = ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED) || !strcmp(p->theirtag, tag); 04886 } 04887 } 04888 04889 if (option_debug > 4) 04890 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); 04891 04892 /* If we get a new request within an existing to-tag - check the to tag as well */ 04893 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 04894 if (p->tag[0] == '\0' && totag[0]) { 04895 /* We have no to tag, but they have. Wrong dialog */ 04896 found = FALSE; 04897 } else if (totag[0]) { /* Both have tags, compare them */ 04898 if (strcmp(totag, p->tag)) { 04899 found = FALSE; /* This is not our packet */ 04900 } 04901 } 04902 if (!found && option_debug > 4) 04903 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); 04904 } 04905 if (found) { 04906 /* Found the call */ 04907 ast_mutex_lock(&p->lock); 04908 ast_mutex_unlock(&iflock); 04909 return p; 04910 } 04911 } 04912 ast_mutex_unlock(&iflock); 04913 04914 /* See if the method is capable of creating a dialog */ 04915 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04916 if (intended_method == SIP_REFER) { 04917 /* We do support REFER, but not outside of a dialog yet */ 04918 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04919 } else if (intended_method == SIP_NOTIFY) { 04920 /* We do not support out-of-dialog NOTIFY either, 04921 like voicemail notification, so cancel that early */ 04922 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04923 } else { 04924 /* Ok, time to create a new SIP dialog object, a pvt */ 04925 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04926 /* Ok, we've created a dialog, let's go and process it */ 04927 ast_mutex_lock(&p->lock); 04928 } else { 04929 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04930 getting a dialog from sip_alloc. 04931 04932 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04933 send an error message. 04934 04935 Sorry, we apologize for the inconvienience 04936 */ 04937 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04938 if (option_debug > 3) 04939 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04940 } 04941 } 04942 return p; 04943 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04944 /* A method we do not support, let's take it on the volley */ 04945 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04946 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04947 /* This is a request outside of a dialog that we don't know about 04948 ...never reply to an ACK! 04949 */ 04950 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04951 } 04952 /* We do not respond to responses for dialogs that we don't know about, we just drop 04953 the session quickly */ 04954 04955 return p; 04956 }
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 2438 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02439 { 02440 char last_char = '\0'; 02441 const char *s; 02442 for (s = start; *s && s != lim; last_char = *s++) { 02443 if (*s == '"' && last_char != '\\') 02444 break; 02445 } 02446 return s; 02447 }
static struct sip_peer * find_peer | ( | const char * | peer, | |
struct sockaddr_in * | sin, | |||
int | realtime, | |||
int | devstate_only | |||
) | [static] |
Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name.
Definition at line 2800 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
02801 { 02802 struct sip_peer *p = NULL; 02803 02804 if (peer) 02805 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02806 else 02807 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02808 02809 if (!p && (realtime || devstate_only)) 02810 p = realtime_peer(peer, sin, devstate_only); 02811 02812 return p; 02813 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
const char * | realm | |||
) | [static] |
Find authentication for a specific realm.
Definition at line 17739 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
17740 { 17741 struct sip_auth *a; 17742 17743 for (a = authlist; a; a = a->next) { 17744 if (!strcasecmp(a->realm, realm)) 17745 break; 17746 } 17747 17748 return a; 17749 }
static int find_sdp | ( | struct sip_request * | req | ) | [static] |
Determine whether a SIP message contains an SDP in its body.
req | the SIP request to process |
Definition at line 5176 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, get_header(), sip_request::line, sip_request::lines, sip_request::sdp_count, sip_request::sdp_start, and TRUE.
Referenced by handle_request(), handle_request_invite(), handle_response(), and handle_response_invite().
05177 { 05178 const char *content_type; 05179 const char *content_length; 05180 const char *search; 05181 char *boundary; 05182 unsigned int x; 05183 int boundaryisquoted = FALSE; 05184 int found_application_sdp = FALSE; 05185 int found_end_of_headers = FALSE; 05186 05187 content_length = get_header(req, "Content-Length"); 05188 05189 if (!ast_strlen_zero(content_length)) { 05190 if (sscanf(content_length, "%30u", &x) != 1) { 05191 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 05192 return 0; 05193 } 05194 05195 /* Content-Length of zero means there can't possibly be an 05196 SDP here, even if the Content-Type says there is */ 05197 if (x == 0) 05198 return 0; 05199 } 05200 05201 content_type = get_header(req, "Content-Type"); 05202 05203 /* if the body contains only SDP, this is easy */ 05204 if (!strncasecmp(content_type, "application/sdp", 15)) { 05205 req->sdp_start = 0; 05206 req->sdp_count = req->lines; 05207 return req->lines ? 1 : 0; 05208 } 05209 05210 /* if it's not multipart/mixed, there cannot be an SDP */ 05211 if (strncasecmp(content_type, "multipart/mixed", 15)) 05212 return 0; 05213 05214 /* if there is no boundary marker, it's invalid */ 05215 if ((search = strcasestr(content_type, ";boundary="))) 05216 search += 10; 05217 else if ((search = strcasestr(content_type, "; boundary="))) 05218 search += 11; 05219 else 05220 return 0; 05221 05222 if (ast_strlen_zero(search)) 05223 return 0; 05224 05225 /* If the boundary is quoted with ", remove quote */ 05226 if (*search == '\"') { 05227 search++; 05228 boundaryisquoted = TRUE; 05229 } 05230 05231 /* make a duplicate of the string, with two extra characters 05232 at the beginning */ 05233 boundary = ast_strdupa(search - 2); 05234 boundary[0] = boundary[1] = '-'; 05235 /* Remove final quote */ 05236 if (boundaryisquoted) 05237 boundary[strlen(boundary) - 1] = '\0'; 05238 05239 /* search for the boundary marker, the empty line delimiting headers from 05240 sdp part and the end boundry if it exists */ 05241 05242 for (x = 0; x < (req->lines ); x++) { 05243 if(!strncasecmp(req->line[x], boundary, strlen(boundary))){ 05244 if(found_application_sdp && found_end_of_headers){ 05245 req->sdp_count = (x - 1) - req->sdp_start; 05246 return 1; 05247 } 05248 found_application_sdp = FALSE; 05249 } 05250 if(!strcasecmp(req->line[x], "Content-Type: application/sdp")) 05251 found_application_sdp = TRUE; 05252 05253 if(strlen(req->line[x]) == 0 ){ 05254 if(found_application_sdp && !found_end_of_headers){ 05255 req->sdp_start = x; 05256 found_end_of_headers = TRUE; 05257 } 05258 } 05259 } 05260 if(found_application_sdp && found_end_of_headers) { 05261 req->sdp_count = x - req->sdp_start; 05262 return TRUE; 05263 } 05264 return FALSE; 05265 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1740 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().
01741 { 01742 int i, res = 0; 01743 01744 if (ast_strlen_zero(msg)) 01745 return 0; 01746 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01747 if (method_match(i, msg)) 01748 res = sip_methods[i].id; 01749 } 01750 return res; 01751 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static] |
Find subscription type in array.
Definition at line 11576 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
11577 { 11578 int i; 11579 11580 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 11581 if (subscription_types[i].type == subtype) { 11582 return &subscription_types[i]; 11583 } 11584 } 11585 return &subscription_types[0]; 11586 }
static struct sip_user * find_user | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf).
Definition at line 2879 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
02880 { 02881 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 02882 if (!u && realtime) 02883 u = realtime_user(name); 02884 return u; 02885 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 8861 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
08862 { 08863 struct sip_route *next; 08864 08865 while (route) { 08866 next = route->next; 08867 free(route); 08868 route = next; 08869 } 08870 }
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 12602 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), and check_sip_domain().
12603 { 12604 if (ast_strlen_zero(data)) { 12605 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 12606 return -1; 12607 } 12608 if (check_sip_domain(data, NULL, 0)) 12609 ast_copy_string(buf, data, len); 12610 else 12611 buf[0] = '\0'; 12612 return 0; 12613 }
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 12538 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::header, sip_pvt::initreq, sip_tech, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
12539 { 12540 struct sip_pvt *p; 12541 const char *content = NULL; 12542 AST_DECLARE_APP_ARGS(args, 12543 AST_APP_ARG(header); 12544 AST_APP_ARG(number); 12545 ); 12546 int i, number, start = 0; 12547 12548 if (ast_strlen_zero(data)) { 12549 ast_log(LOG_WARNING, "This function requires a header name.\n"); 12550 return -1; 12551 } 12552 12553 ast_channel_lock(chan); 12554 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 12555 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 12556 ast_channel_unlock(chan); 12557 return -1; 12558 } 12559 12560 AST_STANDARD_APP_ARGS(args, data); 12561 if (!args.number) { 12562 number = 1; 12563 } else { 12564 sscanf(args.number, "%30d", &number); 12565 if (number < 1) 12566 number = 1; 12567 } 12568 12569 p = chan->tech_pvt; 12570 12571 /* If there is no private structure, this channel is no longer alive */ 12572 if (!p) { 12573 ast_channel_unlock(chan); 12574 return -1; 12575 } 12576 12577 for (i = 0; i < number; i++) 12578 content = __get_header(&p->initreq, args.header, &start); 12579 12580 if (ast_strlen_zero(content)) { 12581 ast_channel_unlock(chan); 12582 return -1; 12583 } 12584 12585 ast_copy_string(buf, content, len); 12586 ast_channel_unlock(chan); 12587 12588 return 0; 12589 }
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 12721 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_inet_ntoa(), ast_log(), sip_pvt::from, 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.
12722 { 12723 struct sip_pvt *p; 12724 12725 *buf = 0; 12726 12727 if (!data) { 12728 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 12729 return -1; 12730 } 12731 12732 ast_channel_lock(chan); 12733 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 12734 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 12735 ast_channel_unlock(chan); 12736 return -1; 12737 } 12738 12739 p = chan->tech_pvt; 12740 12741 /* If there is no private structure, this channel is no longer alive */ 12742 if (!p) { 12743 ast_channel_unlock(chan); 12744 return -1; 12745 } 12746 12747 if (!strcasecmp(data, "peerip")) { 12748 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 12749 } else if (!strcasecmp(data, "recvip")) { 12750 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 12751 } else if (!strcasecmp(data, "from")) { 12752 ast_copy_string(buf, p->from, len); 12753 } else if (!strcasecmp(data, "uri")) { 12754 ast_copy_string(buf, p->uri, len); 12755 } else if (!strcasecmp(data, "useragent")) { 12756 ast_copy_string(buf, p->useragent, len); 12757 } else if (!strcasecmp(data, "peername")) { 12758 ast_copy_string(buf, p->peername, len); 12759 } else if (!strcasecmp(data, "t38passthrough")) { 12760 if (p->t38.state == T38_DISABLED) 12761 ast_copy_string(buf, "0", sizeof("0")); 12762 else /* T38 is offered or enabled in this call */ 12763 ast_copy_string(buf, "1", sizeof("1")); 12764 } else { 12765 ast_channel_unlock(chan); 12766 return -1; 12767 } 12768 ast_channel_unlock(chan); 12769 12770 return 0; 12771 }
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 12627 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_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, 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::prefs, sip_peer::regexten, sip_destroy_peer(), SIP_PAGE2_DYNAMIC, and sip_peer::useragent.
12628 { 12629 struct sip_peer *peer; 12630 char *colname; 12631 12632 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 12633 *colname++ = '\0'; 12634 else if ((colname = strchr(data, '|'))) 12635 *colname++ = '\0'; 12636 else 12637 colname = "ip"; 12638 12639 if (!(peer = find_peer(data, NULL, 1, 0))) 12640 return -1; 12641 12642 if (!strcasecmp(colname, "ip")) { 12643 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 12644 } else if (!strcasecmp(colname, "status")) { 12645 peer_status(peer, buf, len); 12646 } else if (!strcasecmp(colname, "language")) { 12647 ast_copy_string(buf, peer->language, len); 12648 } else if (!strcasecmp(colname, "regexten")) { 12649 ast_copy_string(buf, peer->regexten, len); 12650 } else if (!strcasecmp(colname, "limit")) { 12651 snprintf(buf, len, "%d", peer->call_limit); 12652 } else if (!strcasecmp(colname, "curcalls")) { 12653 snprintf(buf, len, "%d", peer->inUse); 12654 } else if (!strcasecmp(colname, "accountcode")) { 12655 ast_copy_string(buf, peer->accountcode, len); 12656 } else if (!strcasecmp(colname, "useragent")) { 12657 ast_copy_string(buf, peer->useragent, len); 12658 } else if (!strcasecmp(colname, "mailbox")) { 12659 ast_copy_string(buf, peer->mailbox, len); 12660 } else if (!strcasecmp(colname, "context")) { 12661 ast_copy_string(buf, peer->context, len); 12662 } else if (!strcasecmp(colname, "expire")) { 12663 snprintf(buf, len, "%d", peer->expire); 12664 } else if (!strcasecmp(colname, "dynamic")) { 12665 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 12666 } else if (!strcasecmp(colname, "callerid_name")) { 12667 ast_copy_string(buf, peer->cid_name, len); 12668 } else if (!strcasecmp(colname, "callerid_num")) { 12669 ast_copy_string(buf, peer->cid_num, len); 12670 } else if (!strcasecmp(colname, "codecs")) { 12671 ast_getformatname_multiple(buf, len -1, peer->capability); 12672 } else if (!strncasecmp(colname, "codec[", 6)) { 12673 char *codecnum; 12674 int index = 0, codec = 0; 12675 12676 codecnum = colname + 6; /* move past the '[' */ 12677 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 12678 index = atoi(codecnum); 12679 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 12680 ast_copy_string(buf, ast_getformatname(codec), len); 12681 } else { 12682 buf[0] = '\0'; 12683 } 12684 } else { 12685 buf[0] = '\0'; 12686 } 12687 12688 ASTOBJ_UNREF(peer, sip_destroy_peer); 12689 12690 return 0; 12691 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4659 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04660 { 04661 long val[4]; 04662 int x; 04663 04664 for (x=0; x<4; x++) 04665 val[x] = ast_random(); 04666 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04667 04668 return buf; 04669 }
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 9922 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, 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().
09923 { 09924 char tmp[256] = "", *c, *a; 09925 struct sip_request *req = oreq ? oreq : &p->initreq; 09926 struct sip_refer *referdata = NULL; 09927 const char *transfer_context = NULL; 09928 09929 if (!p->refer && !sip_refer_allocate(p)) 09930 return -1; 09931 09932 referdata = p->refer; 09933 09934 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 09935 c = get_in_brackets(tmp); 09936 09937 if (pedanticsipchecking) 09938 ast_uri_decode(c); 09939 09940 if (strncasecmp(c, "sip:", 4)) { 09941 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 09942 return -1; 09943 } 09944 c += 4; 09945 if ((a = strchr(c, ';'))) /* Remove arguments */ 09946 *a = '\0'; 09947 09948 if ((a = strchr(c, '@'))) { /* Separate Domain */ 09949 *a++ = '\0'; 09950 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 09951 } 09952 09953 if (sip_debug_test_pvt(p)) 09954 ast_verbose("Looking for %s in %s\n", c, p->context); 09955 09956 if (p->owner) /* Mimic behaviour in res_features.c */ 09957 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 09958 09959 /* By default, use the context in the channel sending the REFER */ 09960 if (ast_strlen_zero(transfer_context)) { 09961 transfer_context = S_OR(p->owner->macrocontext, 09962 S_OR(p->context, default_context)); 09963 } 09964 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 09965 /* This is a blind transfer */ 09966 if (option_debug) 09967 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 09968 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 09969 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 09970 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 09971 referdata->refer_call = NULL; 09972 /* Set new context */ 09973 ast_string_field_set(p, context, transfer_context); 09974 return 0; 09975 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 09976 return 1; 09977 } 09978 09979 return -1; 09980 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 4451 of file chan_sip.c.
References get_body_by_line(), len(), sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
04452 { 04453 int x; 04454 int len = strlen(name); 04455 char *r; 04456 04457 for (x = 0; x < req->lines; x++) { 04458 r = get_body_by_line(req->line[x], name, len); 04459 if (r[0] != '\0') 04460 return r; 04461 } 04462 04463 return ""; 04464 }
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 4396 of file chan_sip.c.
References ast_skip_blanks().
Referenced by get_body(), and get_sdp_iterate().
04397 { 04398 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 04399 return ast_skip_blanks(line + nameLen + 1); 04400 04401 return ""; 04402 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 10045 of file chan_sip.c.
References ast_copy_string(), and ast_skip_blanks().
Referenced by check_user_full().
10046 { 10047 const char *end = strchr(input,'<'); /* first_bracket */ 10048 const char *tmp = strchr(input,'"'); /* first quote */ 10049 int bytes = 0; 10050 int maxbytes = outputsize - 1; 10051 10052 if (!end || end == input) /* we require a part in brackets */ 10053 return NULL; 10054 10055 end--; /* move just before "<" */ 10056 10057 if (tmp && tmp <= end) { 10058 /* The quote (tmp) precedes the bracket (end+1). 10059 * Find the matching quote and return the content. 10060 */ 10061 end = strchr(tmp+1, '"'); 10062 if (!end) 10063 return NULL; 10064 bytes = (int) (end - tmp); 10065 /* protect the output buffer */ 10066 if (bytes > maxbytes) 10067 bytes = maxbytes; 10068 ast_copy_string(output, tmp + 1, bytes); 10069 } else { 10070 /* No quoted string, or it is inside brackets. */ 10071 /* clear the empty characters in the begining*/ 10072 input = ast_skip_blanks(input); 10073 /* clear the empty characters in the end */ 10074 while(*end && *end < 33 && end > input) 10075 end--; 10076 if (end >= input) { 10077 bytes = (int) (end - input) + 2; 10078 /* protect the output buffer */ 10079 if (bytes > maxbytes) 10080 bytes = maxbytes; 10081 ast_copy_string(output, input, bytes); 10082 } else 10083 return NULL; 10084 } 10085 return output; 10086 }
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 9565 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, sip_pvt::exten, get_header(), get_in_brackets(), global_flags, sip_pvt::initreq, LOG_DEBUG, 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, and sip_pvt::subscribecontext.
Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().
09566 { 09567 char tmp[256] = "", *uri, *a; 09568 char tmpf[256] = "", *from; 09569 struct sip_request *req; 09570 char *colon; 09571 char *decoded_uri; 09572 09573 req = oreq; 09574 if (!req) 09575 req = &p->initreq; 09576 09577 /* Find the request URI */ 09578 if (req->rlPart2) 09579 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 09580 09581 if (pedanticsipchecking) 09582 ast_uri_decode(tmp); 09583 09584 uri = get_in_brackets(tmp); 09585 09586 if (strncasecmp(uri, "sip:", 4)) { 09587 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 09588 return -1; 09589 } 09590 uri += 4; 09591 09592 /* Now find the From: caller ID and name */ 09593 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 09594 if (!ast_strlen_zero(tmpf)) { 09595 if (pedanticsipchecking) 09596 ast_uri_decode(tmpf); 09597 from = get_in_brackets(tmpf); 09598 } else { 09599 from = NULL; 09600 } 09601 09602 if (!ast_strlen_zero(from)) { 09603 if (strncasecmp(from, "sip:", 4)) { 09604 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 09605 return -1; 09606 } 09607 from += 4; 09608 if ((a = strchr(from, '@'))) 09609 *a++ = '\0'; 09610 else 09611 a = from; /* just a domain */ 09612 from = strsep(&from, ";"); /* Remove userinfo options */ 09613 a = strsep(&a, ";"); /* Remove URI options */ 09614 ast_string_field_set(p, fromdomain, a); 09615 } 09616 09617 /* Skip any options and find the domain */ 09618 09619 /* Get the target domain */ 09620 if ((a = strchr(uri, '@'))) { 09621 *a++ = '\0'; 09622 } else { /* No username part */ 09623 a = uri; 09624 uri = "s"; /* Set extension to "s" */ 09625 } 09626 colon = strchr(a, ':'); /* Remove :port */ 09627 if (colon) 09628 *colon = '\0'; 09629 09630 uri = strsep(&uri, ";"); /* Remove userinfo options */ 09631 a = strsep(&a, ";"); /* Remove URI options */ 09632 09633 ast_string_field_set(p, domain, a); 09634 09635 if (!AST_LIST_EMPTY(&domain_list)) { 09636 char domain_context[AST_MAX_EXTENSION]; 09637 09638 domain_context[0] = '\0'; 09639 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 09640 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 09641 if (option_debug) 09642 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 09643 return -2; 09644 } 09645 } 09646 /* If we have a context defined, overwrite the original context */ 09647 if (!ast_strlen_zero(domain_context)) 09648 ast_string_field_set(p, context, domain_context); 09649 } 09650 09651 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 09652 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) 09653 ast_string_field_set(p, context, p->subscribecontext); 09654 09655 if (sip_debug_test_pvt(p)) 09656 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 09657 09658 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 09659 if (req->method == SIP_SUBSCRIBE) { 09660 char hint[AST_MAX_EXTENSION]; 09661 return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1); 09662 } else { 09663 decoded_uri = ast_strdupa(uri); 09664 ast_uri_decode(decoded_uri); 09665 /* Check the dialplan for the username part of the request URI, 09666 the domain will be stored in the SIPDOMAIN variable 09667 Since extensions.conf can have unescaped characters, try matching a decoded 09668 uri in addition to the non-decoded uri 09669 Return 0 if we have a matching extension */ 09670 if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) || ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) || 09671 !strcmp(decoded_uri, ast_pickup_ext())) { 09672 if (!oreq) 09673 ast_string_field_set(p, exten, decoded_uri); 09674 return 0; 09675 } 09676 } 09677 09678 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 09679 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 09680 ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))) || 09681 !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri))) { 09682 return 1; 09683 } 09684 09685 return -1; 09686 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4540 of file chan_sip.c.
References __get_header().
04541 { 04542 int start = 0; 04543 return __get_header(req, name, &start); 04544 }
static char * get_in_brackets | ( | char * | tmp | ) | [static] |
Pick out text in brackets from character string.
tmp | input string that will be modified Examples: |
Definition at line 2460 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().
02461 { 02462 const char *parse = tmp; 02463 char *first_bracket; 02464 02465 /* 02466 * Skip any quoted text until we find the part in brackets. 02467 * On any error give up and return the full string. 02468 */ 02469 while ( (first_bracket = strchr(parse, '<')) ) { 02470 char *first_quote = strchr(parse, '"'); 02471 02472 if (!first_quote || first_quote > first_bracket) 02473 break; /* no need to look at quoted part */ 02474 /* the bracket is within quotes, so ignore it */ 02475 parse = find_closing_quote(first_quote + 1, NULL); 02476 if (!*parse) { /* not found, return full string ? */ 02477 /* XXX or be robust and return in-bracket part ? */ 02478 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02479 break; 02480 } 02481 parse++; 02482 } 02483 if (first_bracket) { 02484 char *second_bracket = strchr(first_bracket + 1, '>'); 02485 if (second_bracket) { 02486 *second_bracket = '\0'; 02487 tmp = first_bracket + 1; 02488 } else { 02489 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02490 } 02491 } 02492 return tmp; 02493 }
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 5300 of file chan_sip.c.
References ast_gethostbyname(), ast_log(), ast_strlen_zero(), get_sdp_iterate(), hp, len(), SDP_AUDIO, sip_request::sdp_start, and SDP_VIDEO.
Referenced by handle_request_invite().
05301 { 05302 const char *m; 05303 const char *c; 05304 int miterator = req->sdp_start; 05305 int citerator = req->sdp_start; 05306 int x = 0; 05307 int numberofports; 05308 int len; 05309 char host[258] = ""; /*Initialize to empty so we will know if we have any input */ 05310 struct ast_hostent audiohp; 05311 struct hostent *hp; 05312 05313 c = get_sdp_iterate(&citerator, req, "c"); 05314 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05315 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05316 /* Continue since there may be a valid host in a c= line specific to the audio stream */ 05317 } 05318 /* We only want the m and c lines for audio */ 05319 for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) { 05320 if ((media == SDP_AUDIO && ((sscanf(m, "audio %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05321 (sscanf(m, "audio %30d RTP/AVP %n", &x, &len) == 1 && len > 0))) || 05322 (media == SDP_VIDEO && ((sscanf(m, "video %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05323 (sscanf(m, "video %30d RTP/AVP %n", &x, &len) == 1 && len > 0)))) { 05324 /* See if there's a c= line for this media stream. 05325 * XXX There is no guarantee that we'll be grabbing the c= line for this 05326 * particular media stream here. However, this is the same logic used in process_sdp. 05327 */ 05328 c = get_sdp_iterate(&citerator, req, "c"); 05329 if (!ast_strlen_zero(c)) { 05330 sscanf(c, "IN IP4 %256s", host); 05331 } 05332 break; 05333 } 05334 } 05335 05336 if (ast_strlen_zero(host) || x == 0) { 05337 ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video"); 05338 return -1; 05339 } 05340 05341 hp = ast_gethostbyname(host, &audiohp); 05342 if (!hp) { 05343 ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video"); 05344 return -1; 05345 } 05346 05347 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 05348 sin->sin_port = htons(x); 05349 return 0; 05350 }
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 10460 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
10461 { 10462 int x; 10463 int y; 10464 10465 buf[0] = '\0'; 10466 y = len - strlen(buf) - 5; 10467 if (y < 0) 10468 y = 0; 10469 for (x=0;x<req->lines;x++) { 10470 strncat(buf, req->line[x], y); /* safe */ 10471 y -= strlen(req->line[x]) + 1; 10472 if (y < 0) 10473 y = 0; 10474 if (y != 0) 10475 strcat(buf, "\n"); /* safe */ 10476 } 10477 return 0; 10478 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 9536 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, and sip_debug_test_pvt().
Referenced by handle_request_invite().
09537 { 09538 char tmp[256], *c, *a; 09539 struct sip_request *req; 09540 09541 req = oreq; 09542 if (!req) 09543 req = &p->initreq; 09544 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 09545 if (ast_strlen_zero(tmp)) 09546 return 0; 09547 c = get_in_brackets(tmp); 09548 if (strncasecmp(c, "sip:", 4)) { 09549 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 09550 return -1; 09551 } 09552 c += 4; 09553 a = c; 09554 strsep(&a, "@;"); /* trim anything after @ or ; */ 09555 if (sip_debug_test_pvt(p)) 09556 ast_verbose("RDNIS is %s\n", c); 09557 ast_string_field_set(p, rdnis, c); 09558 09559 return 0; 09560 }
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 9759 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::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, 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, and sip_debug_test_pvt().
Referenced by handle_request_refer().
09760 { 09761 09762 const char *p_referred_by = NULL; 09763 char *h_refer_to = NULL; 09764 char *h_referred_by = NULL; 09765 char *refer_to; 09766 const char *p_refer_to; 09767 char *referred_by_uri = NULL; 09768 char *ptr; 09769 struct sip_request *req = NULL; 09770 const char *transfer_context = NULL; 09771 struct sip_refer *referdata; 09772 09773 09774 req = outgoing_req; 09775 referdata = transferer->refer; 09776 09777 if (!req) 09778 req = &transferer->initreq; 09779 09780 p_refer_to = get_header(req, "Refer-To"); 09781 if (ast_strlen_zero(p_refer_to)) { 09782 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 09783 return -2; /* Syntax error */ 09784 } 09785 h_refer_to = ast_strdupa(p_refer_to); 09786 refer_to = get_in_brackets(h_refer_to); 09787 if (pedanticsipchecking) 09788 ast_uri_decode(refer_to); 09789 09790 if (strncasecmp(refer_to, "sip:", 4)) { 09791 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 09792 return -3; 09793 } 09794 refer_to += 4; /* Skip sip: */ 09795 09796 /* Get referred by header if it exists */ 09797 p_referred_by = get_header(req, "Referred-By"); 09798 if (!ast_strlen_zero(p_referred_by)) { 09799 char *lessthan; 09800 h_referred_by = ast_strdupa(p_referred_by); 09801 if (pedanticsipchecking) 09802 ast_uri_decode(h_referred_by); 09803 09804 /* Store referrer's caller ID name */ 09805 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 09806 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 09807 *(lessthan - 1) = '\0'; /* Space */ 09808 } 09809 09810 referred_by_uri = get_in_brackets(h_referred_by); 09811 if(strncasecmp(referred_by_uri, "sip:", 4)) { 09812 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 09813 referred_by_uri = (char *) NULL; 09814 } else { 09815 referred_by_uri += 4; /* Skip sip: */ 09816 } 09817 } 09818 09819 /* Check for arguments in the refer_to header */ 09820 if ((ptr = strcasestr(refer_to, "replaces="))) { 09821 char *to = NULL, *from = NULL; 09822 09823 /* This is an attended transfer */ 09824 referdata->attendedtransfer = 1; 09825 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 09826 ast_uri_decode(referdata->replaces_callid); 09827 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 09828 *ptr++ = '\0'; 09829 } 09830 09831 if (ptr) { 09832 /* Find the different tags before we destroy the string */ 09833 to = strcasestr(ptr, "to-tag="); 09834 from = strcasestr(ptr, "from-tag="); 09835 } 09836 09837 /* Grab the to header */ 09838 if (to) { 09839 ptr = to + 7; 09840 if ((to = strchr(ptr, '&'))) 09841 *to = '\0'; 09842 if ((to = strchr(ptr, ';'))) 09843 *to = '\0'; 09844 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 09845 } 09846 09847 if (from) { 09848 ptr = from + 9; 09849 if ((to = strchr(ptr, '&'))) 09850 *to = '\0'; 09851 if ((to = strchr(ptr, ';'))) 09852 *to = '\0'; 09853 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 09854 } 09855 09856 if (option_debug > 1) { 09857 if (!pedanticsipchecking) 09858 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 09859 else 09860 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>" ); 09861 } 09862 } 09863 09864 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 09865 char *urioption = NULL, *domain; 09866 *ptr++ = '\0'; 09867 09868 if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */ 09869 *urioption++ = '\0'; 09870 09871 domain = ptr; 09872 if ((ptr = strchr(domain, ':'))) /* Remove :port */ 09873 *ptr = '\0'; 09874 09875 /* Save the domain for the dial plan */ 09876 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 09877 if (urioption) 09878 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 09879 } 09880 09881 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 09882 *ptr = '\0'; 09883 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 09884 09885 if (referred_by_uri) { 09886 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 09887 *ptr = '\0'; 09888 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 09889 } else { 09890 referdata->referred_by[0] = '\0'; 09891 } 09892 09893 /* Determine transfer context */ 09894 if (transferer->owner) /* Mimic behaviour in res_features.c */ 09895 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 09896 09897 /* By default, use the context in the channel sending the REFER */ 09898 if (ast_strlen_zero(transfer_context)) { 09899 transfer_context = S_OR(transferer->owner->macrocontext, 09900 S_OR(transferer->context, default_context)); 09901 } 09902 09903 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 09904 09905 /* Either an existing extension or the parking extension */ 09906 if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 09907 if (sip_debug_test_pvt(transferer)) { 09908 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 09909 } 09910 /* We are ready to transfer to the extension */ 09911 return 0; 09912 } 09913 if (sip_debug_test_pvt(transferer)) 09914 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 09915 09916 /* Failure, we can't find this extension */ 09917 return -1; 09918 }
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 10092 of file chan_sip.c.
References ast_copy_string(), and AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
10093 { 10094 char *start; 10095 char *end; 10096 10097 start = strchr(input,':'); 10098 if (!start) { 10099 output[0] = '\0'; 10100 return 0; 10101 } 10102 start++; 10103 10104 /* we found "number" */ 10105 ast_copy_string(output,start,maxlen); 10106 output[maxlen-1] = '\0'; 10107 10108 end = strchr(output,'@'); 10109 if (end) 10110 *end = '\0'; 10111 else 10112 output[0] = '\0'; 10113 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 10114 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 10115 10116 return 0; 10117 }
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 4408 of file chan_sip.c.
References get_body_by_line(), len(), sip_request::line, sip_request::sdp_count, and sip_request::sdp_start.
04409 { 04410 int len = strlen(name); 04411 04412 while (*start < (req->sdp_start + req->sdp_count)) { 04413 const char *r = get_body_by_line(req->line[(*start)++], name, len); 04414 if (r[0] != '\0') 04415 return r; 04416 } 04417 04418 /* if the line was not found, ensure that *start points past the SDP */ 04419 (*start)++; 04420 04421 return ""; 04422 }
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 4429 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().
04430 { 04431 char type = '\0'; 04432 const char *line = NULL; 04433 04434 if (stop > (req->sdp_start + req->sdp_count)) { 04435 stop = req->sdp_start + req->sdp_count; 04436 } 04437 04438 while (*start < stop) { 04439 line = req->line[(*start)++]; 04440 if (line[1] == '=') { 04441 type = line[0]; 04442 *value = ast_skip_blanks(line + 2); 04443 break; 04444 } 04445 } 04446 04447 return type; 04448 }
static struct sip_pvt * get_sip_pvt_byid_locked | ( | const char * | callid, | |
const char * | totag, | |||
const char * | fromtag | |||
) | [static] |
Lock interface lock and find matching pvt lock.
Definition at line 9690 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().
09691 { 09692 struct sip_pvt *sip_pvt_ptr; 09693 09694 ast_mutex_lock(&iflock); 09695 09696 if (option_debug > 3 && totag) { 09697 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 09698 } 09699 09700 /* Search interfaces and find the match */ 09701 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 09702 if (!strcmp(sip_pvt_ptr->callid, callid)) { 09703 int match = 1; 09704 09705 if (option_debug > 3) 09706 ast_log(LOG_DEBUG, "Found call with callid %s (ourtag=%s, theirtag=%s)\n", callid, sip_pvt_ptr->tag, sip_pvt_ptr->theirtag); 09707 09708 /* Go ahead and lock it (and its owner) before returning */ 09709 ast_mutex_lock(&sip_pvt_ptr->lock); 09710 09711 /* Check if tags match. If not, this is not the call we want 09712 * (With a forking SIP proxy, several call legs share the 09713 * call id, but have different tags) 09714 */ 09715 if (pedanticsipchecking) { 09716 /* RFC 3891 09717 * > 3. User Agent Server Behavior: Receiving a Replaces Header 09718 * > The Replaces header contains information used to match an existing 09719 * > SIP dialog (call-id, to-tag, and from-tag). Upon receiving an INVITE 09720 * > with a Replaces header, the User Agent (UA) attempts to match this 09721 * > information with a confirmed or early dialog. The User Agent Server 09722 * > (UAS) matches the to-tag and from-tag parameters as if they were tags 09723 * > present in an incoming request. In other words, the to-tag parameter 09724 * > is compared to the local tag, and the from-tag parameter is compared 09725 * > to the remote tag. 09726 * 09727 * Thus, the totag is always compared to the local tag, regardless if 09728 * this our call is an incoming or outgoing call. 09729 */ 09730 if (ast_strlen_zero(fromtag) || strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, sip_pvt_ptr->tag))) 09731 match = 0; 09732 } 09733 09734 if (!match) { 09735 ast_mutex_unlock(&sip_pvt_ptr->lock); 09736 continue; 09737 } 09738 09739 if (option_debug > 3 && totag) 09740 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 09741 ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL) ? "OUTGOING": "INCOMING", 09742 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 09743 09744 /* deadlock avoidance... */ 09745 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 09746 DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock); 09747 } 09748 break; 09749 } 09750 } 09751 ast_mutex_unlock(&iflock); 09752 if (option_debug > 3 && !sip_pvt_ptr) 09753 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 09754 return sip_pvt_ptr; 09755 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 14190 of file chan_sip.c.
References ast_copy_string(), and get_header().
Referenced by find_call(), handle_request(), handle_request_subscribe(), and handle_response().
14191 { 14192 const char *thetag; 14193 14194 if (!tagbuf) 14195 return NULL; 14196 tagbuf[0] = '\0'; /* reset the buffer */ 14197 thetag = get_header(req, header); 14198 thetag = strcasestr(thetag, ";tag="); 14199 if (thetag) { 14200 thetag += 5; 14201 ast_copy_string(tagbuf, thetag, tagbufsize); 14202 return strsep(&tagbuf, ";"); 14203 } 14204 return NULL; 14205 }
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 17487 of file chan_sip.c.
References ast_clear_flag, ast_copy_string(), ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_channel::flags, ast_variable::lineno, ast_variable::name, ast_channel::next, set_insecure_flags(), SIP_CAN_REINVITE, SIP_CAN_REINVITE_NAT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_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_CONSTANT_SSRC, 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, and ast_variable::value.
Referenced by build_peer(), and build_user().
17488 { 17489 int res = 1; 17490 17491 if (!strcasecmp(v->name, "trustrpid")) { 17492 ast_set_flag(&mask[0], SIP_TRUSTRPID); 17493 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 17494 } else if (!strcasecmp(v->name, "sendrpid")) { 17495 ast_set_flag(&mask[0], SIP_SENDRPID); 17496 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 17497 } else if (!strcasecmp(v->name, "g726nonstandard")) { 17498 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 17499 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 17500 } else if (!strcasecmp(v->name, "useclientcode")) { 17501 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 17502 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 17503 } else if (!strcasecmp(v->name, "dtmfmode")) { 17504 ast_set_flag(&mask[0], SIP_DTMF); 17505 ast_clear_flag(&flags[0], SIP_DTMF); 17506 if (!strcasecmp(v->value, "inband")) 17507 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 17508 else if (!strcasecmp(v->value, "rfc2833")) 17509 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 17510 else if (!strcasecmp(v->value, "info")) 17511 ast_set_flag(&flags[0], SIP_DTMF_INFO); 17512 else if (!strcasecmp(v->value, "auto")) 17513 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 17514 else { 17515 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 17516 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 17517 } 17518 } else if (!strcasecmp(v->name, "nat")) { 17519 ast_set_flag(&mask[0], SIP_NAT); 17520 ast_clear_flag(&flags[0], SIP_NAT); 17521 if (!strcasecmp(v->value, "never")) 17522 ast_set_flag(&flags[0], SIP_NAT_NEVER); 17523 else if (!strcasecmp(v->value, "route")) 17524 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 17525 else if (ast_true(v->value)) 17526 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 17527 else 17528 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 17529 } else if (!strcasecmp(v->name, "canreinvite")) { 17530 ast_set_flag(&mask[0], SIP_REINVITE); 17531 ast_clear_flag(&flags[0], SIP_REINVITE); 17532 if(ast_true(v->value)) { 17533 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 17534 } else if (!ast_false(v->value)) { 17535 char buf[64]; 17536 char *word, *next = buf; 17537 17538 ast_copy_string(buf, v->value, sizeof(buf)); 17539 while ((word = strsep(&next, ","))) { 17540 if(!strcasecmp(word, "update")) { 17541 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 17542 } else if(!strcasecmp(word, "nonat")) { 17543 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 17544 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 17545 } else { 17546 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 17547 } 17548 } 17549 } 17550 } else if (!strcasecmp(v->name, "insecure")) { 17551 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 17552 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 17553 set_insecure_flags(flags, v->value, v->lineno); 17554 } else if (!strcasecmp(v->name, "progressinband")) { 17555 ast_set_flag(&mask[0], SIP_PROG_INBAND); 17556 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 17557 if (ast_true(v->value)) 17558 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 17559 else if (strcasecmp(v->value, "never")) 17560 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 17561 } else if (!strcasecmp(v->name, "promiscredir")) { 17562 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 17563 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 17564 } else if (!strcasecmp(v->name, "videosupport")) { 17565 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 17566 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 17567 } else if (!strcasecmp(v->name, "allowoverlap")) { 17568 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 17569 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 17570 } else if (!strcasecmp(v->name, "allowsubscribe")) { 17571 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 17572 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 17573 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 17574 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 17575 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 17576 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 17577 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 17578 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 17579 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 17580 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 17581 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 17582 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 17583 #endif 17584 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 17585 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 17586 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 17587 } else if (!strcasecmp(v->name, "buggymwi")) { 17588 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 17589 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 17590 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 17591 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 17592 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 17593 } else if (!strcasecmp(v->name, "constantssrc")) { 17594 ast_set_flag(&mask[1], SIP_PAGE2_CONSTANT_SSRC); 17595 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_CONSTANT_SSRC); 17596 } else 17597 res = 0; 17598 17599 return res; 17600 }
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 14380 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, ast_channel::name, 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().
14381 { 14382 int earlyreplace = 0; 14383 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 14384 struct ast_channel *c = p->owner; /* Our incoming call */ 14385 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 14386 struct ast_channel *targetcall; /* The bridge to the take-over target */ 14387 14388 /* Check if we're in ring state */ 14389 if (replacecall->_state == AST_STATE_RING) 14390 earlyreplace = 1; 14391 14392 /* Check if we have a bridge */ 14393 if (!(targetcall = ast_bridged_channel(replacecall))) { 14394 /* We have no bridge */ 14395 if (!earlyreplace) { 14396 if (option_debug > 1) 14397 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 14398 oneleggedreplace = 1; 14399 } 14400 } 14401 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 14402 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 14403 14404 if (option_debug > 3) { 14405 if (targetcall) 14406 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); 14407 else 14408 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 14409 } 14410 14411 if (ignore) { 14412 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 14413 /* We should answer something here. If we are here, the 14414 call we are replacing exists, so an accepted 14415 can't harm */ 14416 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 14417 /* Do something more clever here */ 14418 if (c) { 14419 *nounlock = 1; 14420 ast_channel_unlock(c); 14421 } 14422 ast_channel_unlock(replacecall); 14423 ast_mutex_unlock(&p->refer->refer_call->lock); 14424 return 1; 14425 } 14426 if (!c) { 14427 /* What to do if no channel ??? */ 14428 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 14429 transmit_response_reliable(p, "503 Service Unavailable", req); 14430 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 14431 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14432 ast_channel_unlock(replacecall); 14433 ast_mutex_unlock(&p->refer->refer_call->lock); 14434 return 1; 14435 } 14436 append_history(p, "Xfer", "INVITE/Replace received"); 14437 /* We have three channels to play with 14438 channel c: New incoming call 14439 targetcall: Call from PBX to target 14440 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 14441 replacecall: The owner of the previous 14442 We need to masq C into refer_call to connect to 14443 targetcall; 14444 If we are talking to internal audio stream, target call is null. 14445 */ 14446 14447 /* Fake call progress */ 14448 transmit_response(p, "100 Trying", req); 14449 ast_setstate(c, AST_STATE_RING); 14450 14451 /* Masquerade the new call into the referred call to connect to target call 14452 Targetcall is not touched by the masq */ 14453 14454 /* Answer the incoming call and set channel to UP state */ 14455 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 14456 14457 ast_setstate(c, AST_STATE_UP); 14458 14459 /* Stop music on hold and other generators */ 14460 ast_quiet_chan(replacecall); 14461 ast_quiet_chan(targetcall); 14462 if (option_debug > 3) 14463 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 14464 14465 /* Make sure that the masq does not free our PVT for the old call */ 14466 if (! earlyreplace && ! oneleggedreplace ) 14467 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14468 14469 /* Prepare the masquerade - if this does not happen, we will be gone */ 14470 if(ast_channel_masquerade(replacecall, c)) 14471 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 14472 else if (option_debug > 3) 14473 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 14474 14475 /* C should now be in place of replacecall */ 14476 if (ast_do_masquerade(replacecall)) { 14477 ast_log(LOG_WARNING, "Failed to perform masquerade with INVITE replaces\n"); 14478 } 14479 14480 if (earlyreplace || oneleggedreplace ) { 14481 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 14482 } 14483 14484 ast_setstate(c, AST_STATE_DOWN); 14485 if (option_debug > 3) { 14486 struct ast_channel *test; 14487 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 14488 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 14489 if (replacecall) 14490 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 14491 if (p->owner) { 14492 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 14493 test = ast_bridged_channel(p->owner); 14494 if (test) 14495 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 14496 else 14497 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 14498 } else 14499 ast_log(LOG_DEBUG, " -- No channel yet \n"); 14500 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 14501 } 14502 14503 /* unlock sip pvt and owner so hangup can do its thing */ 14504 ast_channel_unlock(replacecall); 14505 ast_channel_unlock(c); 14506 ast_mutex_unlock(&p->refer->refer_call->lock); 14507 ast_mutex_unlock(&p->lock); 14508 *nounlock = 1; 14509 14510 /* The call should be down with no ast_channel, so hang it up */ 14511 c->tech_pvt = NULL; 14512 ast_hangup(c); 14513 14514 ast_mutex_lock(&p->lock); /* lock PVT structure again after hangup */ 14515 14516 return 0; 14517 }
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 16424 of file chan_sip.c.
References __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(), 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, cfsip_methods::id, sip_pvt::initreq, INV_TERMINATED, len(), LOG_DEBUG, LOG_ERROR, LOG_NOTICE, sip_request::method, sip_pvt::method, option_debug, process_sdp(), sip_request::rlPart1, sip_request::rlPart2, 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, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and sip_pvt::useragent.
16425 { 16426 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 16427 relatively static */ 16428 const char *cmd; 16429 const char *cseq; 16430 const char *useragent; 16431 int seqno; 16432 int len; 16433 int ignore = FALSE; 16434 int respid; 16435 int res = 0; 16436 int debug = sip_debug_test_pvt(p); 16437 char *e; 16438 int error = 0; 16439 int oldmethod = p->method; 16440 int acked = 0; 16441 16442 /* Get Method and Cseq */ 16443 cseq = get_header(req, "Cseq"); 16444 cmd = req->header[0]; 16445 16446 /* Must have Cseq */ 16447 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 16448 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 16449 error = 1; 16450 } 16451 if (!error && sscanf(cseq, "%30d%n", &seqno, &len) != 1) { 16452 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 16453 error = 1; 16454 } 16455 if (error) { 16456 if (!p->initreq.headers) /* New call */ 16457 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 16458 return -1; 16459 } 16460 /* Get the command XXX */ 16461 16462 cmd = req->rlPart1; 16463 e = ast_skip_blanks(req->rlPart2); 16464 16465 /* Save useragent of the client */ 16466 useragent = get_header(req, "User-Agent"); 16467 if (!ast_strlen_zero(useragent)) 16468 ast_string_field_set(p, useragent, useragent); 16469 16470 /* Find out SIP method for incoming request */ 16471 if (req->method == SIP_RESPONSE) { /* Response to our request */ 16472 /* Response to our request -- Do some sanity checks */ 16473 if (ast_strlen_zero(e)) { 16474 return 0; 16475 } 16476 if (sscanf(e, "%30d %n", &respid, &len) != 1) { 16477 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 16478 return 0; 16479 } 16480 if (respid <= 0) { 16481 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 16482 return 0; 16483 } 16484 if (!p->initreq.headers) { 16485 if (option_debug) 16486 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 16487 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16488 return 0; 16489 } 16490 if (p->ocseq && (p->ocseq < seqno)) { 16491 if (option_debug) 16492 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 16493 return -1; 16494 } else { 16495 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) { 16496 extract_uri(p, req); 16497 } 16498 handle_response(p, respid, e + len, req, seqno); 16499 } 16500 return 0; 16501 } 16502 16503 /* New SIP request coming in 16504 (could be new request in existing SIP dialog as well...) 16505 */ 16506 16507 p->method = req->method; /* Find out which SIP method they are using */ 16508 if (option_debug > 3) 16509 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 16510 16511 if (p->icseq && (p->icseq > seqno) ) { 16512 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 16513 if (option_debug > 2) 16514 ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 16515 } else { 16516 if (option_debug) 16517 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 16518 if (req->method != SIP_ACK) 16519 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 16520 return -1; 16521 } 16522 } else if (p->icseq && 16523 p->icseq == seqno && 16524 req->method != SIP_ACK && 16525 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 16526 /* ignore means "don't do anything with it" but still have to 16527 respond appropriately. We do this if we receive a repeat of 16528 the last sequence number */ 16529 ignore = 2; 16530 ast_set_flag(req, SIP_PKT_IGNORE); 16531 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 16532 if (option_debug > 2) 16533 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 16534 } 16535 16536 if (seqno >= p->icseq) 16537 /* Next should follow monotonically (but not necessarily 16538 incrementally -- thanks again to the genius authors of SIP -- 16539 increasing */ 16540 p->icseq = seqno; 16541 16542 /* Find their tag if we haven't got it */ 16543 if (ast_strlen_zero(p->theirtag)) { 16544 char tag[128]; 16545 16546 gettag(req, "From", tag, sizeof(tag)); 16547 ast_string_field_set(p, theirtag, tag); 16548 } 16549 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 16550 16551 if (pedanticsipchecking) { 16552 /* If this is a request packet without a from tag, it's not 16553 correct according to RFC 3261 */ 16554 /* Check if this a new request in a new dialog with a totag already attached to it, 16555 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 16556 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 16557 /* If this is a first request and it got a to-tag, it is not for us */ 16558 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 16559 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 16560 /* Will cease to exist after ACK */ 16561 } else if (req->method != SIP_ACK) { 16562 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 16563 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16564 } 16565 return res; 16566 } 16567 } 16568 16569 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 16570 transmit_response(p, "400 Bad request", req); 16571 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16572 return -1; 16573 } 16574 16575 /* Handle various incoming SIP methods in requests */ 16576 switch (p->method) { 16577 case SIP_OPTIONS: 16578 res = handle_request_options(p, req); 16579 break; 16580 case SIP_INVITE: 16581 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 16582 break; 16583 case SIP_REFER: 16584 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 16585 break; 16586 case SIP_CANCEL: 16587 res = handle_request_cancel(p, req); 16588 break; 16589 case SIP_BYE: 16590 res = handle_request_bye(p, req); 16591 break; 16592 case SIP_MESSAGE: 16593 res = handle_request_message(p, req); 16594 break; 16595 case SIP_SUBSCRIBE: 16596 res = handle_request_subscribe(p, req, sin, seqno, e); 16597 break; 16598 case SIP_REGISTER: 16599 res = handle_request_register(p, req, sin, e); 16600 break; 16601 case SIP_INFO: 16602 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16603 ast_verbose("Receiving INFO!\n"); 16604 if (!ignore) 16605 handle_request_info(p, req); 16606 else /* if ignoring, transmit response */ 16607 transmit_response(p, "200 OK", req); 16608 break; 16609 case SIP_NOTIFY: 16610 res = handle_request_notify(p, req, sin, seqno, e); 16611 break; 16612 case SIP_ACK: 16613 /* Make sure we don't ignore this */ 16614 if (seqno == p->pendinginvite) { 16615 p->invitestate = INV_TERMINATED; 16616 p->pendinginvite = 0; 16617 acked = __sip_ack(p, seqno, FLAG_RESPONSE, 0); 16618 if (find_sdp(req)) { 16619 if (process_sdp(p, req)) 16620 return -1; 16621 } 16622 check_pendings(p); 16623 } else if (p->glareinvite == seqno) { 16624 /* handle ack for the 491 pending send for glareinvite */ 16625 p->glareinvite = 0; 16626 acked = __sip_ack(p, seqno, 1, 0); 16627 } 16628 if (!acked) { 16629 /* Got an ACK that did not match anything. Ignore 16630 * silently and restore previous method */ 16631 p->method = oldmethod; 16632 } 16633 /* Got an ACK that we did not match. Ignore silently */ 16634 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 16635 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16636 break; 16637 default: 16638 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 16639 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 16640 cmd, ast_inet_ntoa(p->sa.sin_addr)); 16641 /* If this is some new method, and we don't have a call, destroy it now */ 16642 if (!p->initreq.headers) 16643 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16644 break; 16645 } 16646 return res; 16647 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 15978 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(), ast_channel::context, context, copy_request(), DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, get_also_info(), get_header(), sip_pvt::initreq, INV_TERMINATED, LOG_DEBUG, LOG_NOTICE, option_debug, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_alreadygone(), SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_IGNORE, sip_scheddestroy(), stop_media_flows(), transmit_response(), and transmit_response_reliable().
Referenced by handle_request().
15979 { 15980 struct ast_channel *c=NULL; 15981 int res; 15982 struct ast_channel *bridged_to; 15983 15984 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 15985 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE)) 15986 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 15987 15988 __sip_pretend_ack(p); 15989 15990 p->invitestate = INV_TERMINATED; 15991 15992 copy_request(&p->initreq, req); 15993 check_via(p, req); 15994 sip_alreadygone(p); 15995 15996 /* Get RTCP quality before end of call */ 15997 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 15998 char *audioqos, *videoqos; 15999 if (p->rtp) { 16000 audioqos = ast_rtp_get_quality(p->rtp, NULL); 16001 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 16002 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 16003 if (p->owner) 16004 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 16005 } 16006 if (p->vrtp) { 16007 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 16008 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 16009 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 16010 if (p->owner) 16011 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 16012 } 16013 } 16014 16015 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 16016 16017 if (!ast_strlen_zero(get_header(req, "Also"))) { 16018 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 16019 ast_inet_ntoa(p->recv.sin_addr)); 16020 if (ast_strlen_zero(p->context)) 16021 ast_string_field_set(p, context, default_context); 16022 res = get_also_info(p, req); 16023 if (!res) { 16024 c = p->owner; 16025 if (c) { 16026 bridged_to = ast_bridged_channel(c); 16027 if (bridged_to) { 16028 /* Don't actually hangup here... */ 16029 ast_queue_control(c, AST_CONTROL_UNHOLD); 16030 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 16031 } else 16032 ast_queue_hangup(p->owner); 16033 } 16034 } else { 16035 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 16036 if (p->owner) 16037 ast_queue_hangup(p->owner); 16038 } 16039 } else if (p->owner) { 16040 ast_queue_hangup(p->owner); 16041 if (option_debug > 2) 16042 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 16043 } else { 16044 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16045 if (option_debug > 2) 16046 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 16047 } 16048 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 16049 transmit_response(p, "200 OK", req); 16050 16051 return 1; 16052 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 15848 of file chan_sip.c.
References __sip_pretend_ack(), ast_free, ast_log(), ast_queue_hangup(), AST_SCHED_DEL, AST_STATE_UP, ast_test_flag, check_via(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, INV_CANCELLED, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, sip_pkt::next, option_debug, sip_dual::req, sip_pkt::response_code, sip_pkt::retransid, sched, sip_pkt::seqno, sip_alreadygone(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), UNLINK, and update_call_counter().
Referenced by handle_request().
15849 { 15850 15851 check_via(p, req); 15852 sip_alreadygone(p); 15853 15854 /* At this point, we could have cancelled the invite at the same time 15855 as the other side sends a CANCEL. Our final reply with error code 15856 might not have been received by the other side before the CANCEL 15857 was sent, so let's just give up retransmissions and waiting for 15858 ACK on our error code. The call is hanging up any way. */ 15859 if (p->invitestate == INV_TERMINATED) 15860 __sip_pretend_ack(p); 15861 else 15862 p->invitestate = INV_CANCELLED; 15863 15864 if (p->owner && p->owner->_state == AST_STATE_UP) { 15865 /* This call is up, cancel is ignored, we need a bye */ 15866 transmit_response(p, "200 OK", req); 15867 if (option_debug) 15868 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 15869 return 0; 15870 } 15871 15872 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 15873 update_call_counter(p, DEC_CALL_LIMIT); 15874 15875 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 15876 if (p->owner) 15877 ast_queue_hangup(p->owner); 15878 else 15879 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15880 if (p->initreq.len > 0) { 15881 struct sip_pkt *pkt, *prev_pkt; 15882 /* If the CANCEL we are receiving is a retransmission, and we already have scheduled 15883 * a reliable 487, then we don't want to schedule another one on top of the previous 15884 * one. 15885 * 15886 * As odd as this may sound, we can't rely on the previously-transmitted "reliable" 15887 * response in this situation. What if we've sent all of our reliable responses 15888 * already and now all of a sudden, we get this second CANCEL? 15889 * 15890 * The only way to do this correctly is to cancel our previously-scheduled reliably- 15891 * transmitted response and send a new one in its place. 15892 */ 15893 for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->next) { 15894 if (pkt->seqno == p->lastinvite && pkt->response_code == 487) { 15895 AST_SCHED_DEL(sched, pkt->retransid); 15896 UNLINK(pkt, p->packets, prev_pkt); 15897 ast_free(pkt); 15898 break; 15899 } 15900 } 15901 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 15902 transmit_response(p, "200 OK", req); 15903 return 1; 15904 } else { 15905 transmit_response(p, "481 Call Leg Does Not Exist", req); 15906 return 0; 15907 } 15908 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 11941 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, f, sip_pvt::flags, get_body(), get_header(), sip_pvt::owner, sip_scheddestroy(), SIP_USECLIENTCODE, sipdebug, and transmit_response().
Referenced by handle_request().
11942 { 11943 char buf[1024]; 11944 unsigned int event; 11945 const char *c = get_header(req, "Content-Type"); 11946 11947 /* Need to check the media/type */ 11948 if (!strcasecmp(c, "application/dtmf-relay") || 11949 !strcasecmp(c, "application/DTMF") || 11950 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 11951 unsigned int duration = 0; 11952 11953 /* Try getting the "signal=" part */ 11954 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 11955 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 11956 transmit_response(p, "200 OK", req); /* Should return error */ 11957 return; 11958 } else { 11959 ast_copy_string(buf, c, sizeof(buf)); 11960 } 11961 11962 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 11963 duration = atoi(c); 11964 if (!duration) 11965 duration = 100; /* 100 ms */ 11966 11967 if (!p->owner) { /* not a PBX call */ 11968 transmit_response(p, "481 Call leg/transaction does not exist", req); 11969 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11970 return; 11971 } 11972 11973 if (ast_strlen_zero(buf)) { 11974 transmit_response(p, "200 OK", req); 11975 return; 11976 } 11977 11978 if (buf[0] == '*') 11979 event = 10; 11980 else if (buf[0] == '#') 11981 event = 11; 11982 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 11983 event = 12 + buf[0] - 'A'; 11984 else 11985 event = atoi(buf); 11986 if (event == 16) { 11987 /* send a FLASH event */ 11988 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 11989 ast_queue_frame(p->owner, &f); 11990 if (sipdebug) 11991 ast_verbose("* DTMF-relay event received: FLASH\n"); 11992 } else { 11993 /* send a DTMF event */ 11994 struct ast_frame f = { AST_FRAME_DTMF, }; 11995 if (event < 10) { 11996 f.subclass = '0' + event; 11997 } else if (event < 11) { 11998 f.subclass = '*'; 11999 } else if (event < 12) { 12000 f.subclass = '#'; 12001 } else if (event < 16) { 12002 f.subclass = 'A' + (event - 12); 12003 } 12004 f.len = duration; 12005 ast_queue_frame(p->owner, &f); 12006 if (sipdebug) 12007 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 12008 } 12009 transmit_response(p, "200 OK", req); 12010 return; 12011 } else if (!strcasecmp(c, "application/media_control+xml")) { 12012 /* Eh, we'll just assume it's a fast picture update for now */ 12013 if (p->owner) 12014 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 12015 transmit_response(p, "200 OK", req); 12016 return; 12017 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 12018 /* Client code (from SNOM phone) */ 12019 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 12020 if (p->owner && p->owner->cdr) 12021 ast_cdr_setuserfield(p->owner, c); 12022 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 12023 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 12024 transmit_response(p, "200 OK", req); 12025 } else { 12026 transmit_response(p, "403 Unauthorized", req); 12027 } 12028 return; 12029 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 12030 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 12031 transmit_response(p, "200 OK", req); 12032 return; 12033 } 12034 12035 /* Other type of INFO message, not really understood by Asterisk */ 12036 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 12037 12038 /* Nothing in the header is interesting, now check if content-length is 0 */ 12039 if (!strcasecmp(get_header(req, "Content-Length"), "0")) { 12040 transmit_response(p, "200 OK", req); 12041 return; 12042 } /* else ... there issomething in the message body, do something with it if you need to */ 12043 12044 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 12045 transmit_response(p, "415 Unsupported media type", req); 12046 return; 12047 }
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 14810 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_set_constantssrc(), 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(), ast_channel::call_forward, 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, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, make_our_tag(), ast_channel::name, 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_CONSTANT_SSRC, 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, 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().
14811 { 14812 int res = 1; 14813 int gotdest; 14814 const char *p_replaces; 14815 char *replace_id = NULL; 14816 const char *required; 14817 unsigned int required_profile = 0; 14818 struct ast_channel *c = NULL; /* New channel */ 14819 int reinvite = 0; 14820 14821 /* Find out what they support */ 14822 if (!p->sipoptions) { 14823 const char *supported = get_header(req, "Supported"); 14824 if (!ast_strlen_zero(supported)) 14825 parse_sip_options(p, supported); 14826 } 14827 14828 /* Find out what they require */ 14829 required = get_header(req, "Require"); 14830 if (!ast_strlen_zero(required)) { 14831 required_profile = parse_sip_options(NULL, required); 14832 if (required_profile && !(required_profile & SIP_OPT_REPLACES)) { 14833 /* At this point we only support REPLACES */ 14834 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 14835 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 14836 p->invitestate = INV_COMPLETED; 14837 if (!p->lastinvite) 14838 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14839 return -1; 14840 } 14841 } 14842 14843 /* Check if this is a loop */ 14844 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->invitestate != INV_TERMINATED && p->invitestate != INV_CONFIRMED)) { 14845 /* This is a call to ourself. Send ourselves an error code and stop 14846 processing immediately, as SIP really has no good mechanism for 14847 being able to call yourself */ 14848 /* If pedantic is on, we need to check the tags. If they're different, this is 14849 in fact a forked call through a SIP proxy somewhere. */ 14850 int different; 14851 if (pedanticsipchecking) 14852 different = sip_uri_cmp(p->initreq.rlPart2, req->rlPart2); 14853 else 14854 different = strcmp(p->initreq.rlPart2, req->rlPart2); 14855 if (!different) { 14856 transmit_response(p, "482 Loop Detected", req); 14857 p->invitestate = INV_COMPLETED; 14858 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14859 return 0; 14860 } else { 14861 /* This is a spiral. What we need to do is to just change the outgoing INVITE 14862 * so that it now routes to the new Request URI. Since we created the INVITE ourselves 14863 * that should be all we need to do. 14864 */ 14865 char *uri = ast_strdupa(req->rlPart2); 14866 char *at = strchr(uri, '@'); 14867 char *peerorhost; 14868 if (option_debug > 2) { 14869 ast_log(LOG_DEBUG, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", p->initreq.rlPart2, req->rlPart2); 14870 } 14871 transmit_response(p, "100 Trying", req); 14872 if (at) { 14873 *at = '\0'; 14874 } 14875 /* Parse out "sip:" */ 14876 if ((peerorhost = strchr(uri, ':'))) { 14877 *peerorhost++ = '\0'; 14878 } 14879 ast_string_field_free(p, theirtag); 14880 /* Treat this as if there were a call forward instead... 14881 */ 14882 ast_string_field_set(p->owner, call_forward, peerorhost); 14883 ast_queue_control(p->owner, AST_CONTROL_BUSY); 14884 return 0; 14885 } 14886 } 14887 14888 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 14889 if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && (p->invitestate == INV_COMPLETED || p->invitestate == INV_TERMINATED)) { 14890 /* What do these circumstances mean? We have received an INVITE for an "incoming" dialog for which we 14891 * have sent a final response. We have not yet received an ACK, though (which is why p->pendinginvite is non-zero). 14892 * We also know that the INVITE is not a retransmission, because otherwise the "ignore" flag would be set. 14893 * This means that either we are receiving a reinvite for a terminated dialog, or we are receiving an INVITE with 14894 * credentials based on one we challenged earlier. 14895 * 14896 * The action to take in either case is to treat the INVITE as though it contains an implicit ACK for the previous 14897 * transaction. Calling __sip_ack will take care of this by clearing the p->pendinginvite and removing the response 14898 * from the previous transaction from the list of outstanding packets. 14899 */ 14900 __sip_ack(p, p->pendinginvite, FLAG_RESPONSE, 0); 14901 } else { 14902 /* We already have a pending invite. Sorry. You are on hold. */ 14903 p->glareinvite = seqno; 14904 if (p->rtp && find_sdp(req)) { 14905 struct sockaddr_in sin; 14906 if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &sin)) { 14907 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Audio may not work properly on this call.\n"); 14908 } else { 14909 ast_rtp_set_alt_peer(p->rtp, &sin); 14910 } 14911 if (p->vrtp) { 14912 if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &sin)) { 14913 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Video may not work properly on this call.\n"); 14914 } else { 14915 ast_rtp_set_alt_peer(p->vrtp, &sin); 14916 } 14917 } 14918 } 14919 transmit_response_reliable(p, "491 Request Pending", req); 14920 if (option_debug) 14921 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 14922 /* Don't destroy dialog here */ 14923 return 0; 14924 } 14925 } 14926 14927 p_replaces = get_header(req, "Replaces"); 14928 if (!ast_strlen_zero(p_replaces)) { 14929 /* We have a replaces header */ 14930 char *ptr; 14931 char *fromtag = NULL; 14932 char *totag = NULL; 14933 char *start, *to; 14934 int error = 0; 14935 14936 if (p->owner) { 14937 if (option_debug > 2) 14938 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 14939 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 14940 /* Do not destroy existing call */ 14941 return -1; 14942 } 14943 14944 if (sipdebug && option_debug > 2) 14945 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 14946 /* Create a buffer we can manipulate */ 14947 replace_id = ast_strdupa(p_replaces); 14948 ast_uri_decode(replace_id); 14949 14950 if (!p->refer && !sip_refer_allocate(p)) { 14951 transmit_response_reliable(p, "500 Server Internal Error", req); 14952 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 14953 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14954 p->invitestate = INV_COMPLETED; 14955 return -1; 14956 } 14957 14958 /* Todo: (When we find phones that support this) 14959 if the replaces header contains ";early-only" 14960 we can only replace the call in early 14961 stage, not after it's up. 14962 14963 If it's not in early mode, 486 Busy. 14964 */ 14965 14966 /* Skip leading whitespace */ 14967 replace_id = ast_skip_blanks(replace_id); 14968 14969 start = replace_id; 14970 while ( (ptr = strsep(&start, ";")) ) { 14971 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 14972 if ( (to = strcasestr(ptr, "to-tag=") ) ) 14973 totag = to + 7; /* skip the keyword */ 14974 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 14975 fromtag = to + 9; /* skip the keyword */ 14976 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 14977 } 14978 } 14979 14980 if (sipdebug && option_debug > 3) 14981 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>"); 14982 14983 14984 /* Try to find call that we are replacing 14985 If we have a Replaces header, we need to cancel that call if we succeed with this call 14986 */ 14987 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 14988 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 14989 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 14990 error = 1; 14991 } 14992 14993 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 14994 14995 /* The matched call is the call from the transferer to Asterisk . 14996 We want to bridge the bridged part of the call to the 14997 incoming invite, thus taking over the refered call */ 14998 14999 if (p->refer->refer_call == p) { 15000 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 15001 p->refer->refer_call = NULL; 15002 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 15003 error = 1; 15004 } 15005 15006 if (!error && !p->refer->refer_call->owner) { 15007 /* Oops, someting wrong anyway, no owner, no call */ 15008 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 15009 /* Check for better return code */ 15010 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req); 15011 error = 1; 15012 } 15013 15014 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 ) { 15015 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 15016 transmit_response_reliable(p, "603 Declined (Replaces)", req); 15017 error = 1; 15018 } 15019 15020 if (error) { /* Give up this dialog */ 15021 append_history(p, "Xfer", "INVITE/Replace Failed."); 15022 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15023 ast_mutex_unlock(&p->lock); 15024 if (p->refer->refer_call) { 15025 ast_mutex_unlock(&p->refer->refer_call->lock); 15026 if (p->refer->refer_call->owner) { 15027 ast_channel_unlock(p->refer->refer_call->owner); 15028 } 15029 } 15030 p->invitestate = INV_COMPLETED; 15031 return -1; 15032 } 15033 } 15034 15035 15036 /* Check if this is an INVITE that sets up a new dialog or 15037 a re-invite in an existing dialog */ 15038 15039 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 15040 int newcall = (p->initreq.headers ? TRUE : FALSE); 15041 15042 if (sip_cancel_destroy(p)) 15043 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15044 /* This also counts as a pending invite */ 15045 p->pendinginvite = seqno; 15046 check_via(p, req); 15047 15048 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 15049 if (!p->owner) { /* Not a re-invite */ 15050 if (debug) 15051 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 15052 if (newcall) 15053 append_history(p, "Invite", "New call: %s", p->callid); 15054 parse_ok_contact(p, req); 15055 } else { /* Re-invite on existing call */ 15056 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 15057 /* Handle SDP here if we already have an owner */ 15058 if (find_sdp(req)) { 15059 if (process_sdp(p, req)) { 15060 transmit_response_reliable(p, "488 Not acceptable here", req); 15061 if (!p->lastinvite) 15062 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15063 return -1; 15064 } 15065 ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE); 15066 } else { 15067 p->jointcapability = p->capability; 15068 if (option_debug > 2) 15069 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 15070 /* Some devices signal they want to be put off hold by sending a re-invite 15071 *without* an SDP, which is supposed to mean "Go back to your state" 15072 and since they put os on remote hold, we go back to off hold */ 15073 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 15074 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 15075 /* Activate a re-invite */ 15076 ast_queue_frame(p->owner, &ast_null_frame); 15077 change_hold_state(p, req, FALSE, 0); 15078 } 15079 } 15080 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 15081 append_history(p, "ReInv", "Re-invite received"); 15082 } 15083 } else if (debug) 15084 ast_verbose("Ignoring this INVITE request\n"); 15085 15086 15087 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 15088 /* This is a new invite */ 15089 /* Handle authentication if this is our first invite */ 15090 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 15091 if (res == AUTH_CHALLENGE_SENT) { 15092 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 15093 return 0; 15094 } 15095 if (res < 0) { /* Something failed in authentication */ 15096 if (res == AUTH_FAKE_AUTH) { 15097 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 15098 transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE); 15099 } else { 15100 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 15101 transmit_response_reliable(p, "403 Forbidden", req); 15102 } 15103 p->invitestate = INV_COMPLETED; 15104 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15105 ast_string_field_free(p, theirtag); 15106 return 0; 15107 } 15108 15109 /* We have a succesful authentication, process the SDP portion if there is one */ 15110 if (find_sdp(req)) { 15111 if (process_sdp(p, req)) { 15112 /* Unacceptable codecs */ 15113 transmit_response_reliable(p, "488 Not acceptable here", req); 15114 p->invitestate = INV_COMPLETED; 15115 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15116 if (option_debug) 15117 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 15118 return -1; 15119 } 15120 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CONSTANT_SSRC)) { 15121 if (p->rtp) { 15122 ast_rtp_set_constantssrc(p->rtp); 15123 } 15124 if (p->vrtp) { 15125 ast_rtp_set_constantssrc(p->vrtp); 15126 } 15127 } 15128 } else { /* No SDP in invite, call control session */ 15129 p->jointcapability = p->capability; 15130 if (option_debug > 1) 15131 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 15132 } 15133 15134 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 15135 /* This seems redundant ... see !p-owner above */ 15136 if (p->owner) 15137 ast_queue_frame(p->owner, &ast_null_frame); 15138 15139 15140 /* Initialize the context if it hasn't been already */ 15141 if (ast_strlen_zero(p->context)) 15142 ast_string_field_set(p, context, default_context); 15143 15144 15145 /* Check number of concurrent calls -vs- incoming limit HERE */ 15146 if (option_debug) 15147 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 15148 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 15149 if (res < 0) { 15150 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 15151 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 15152 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15153 p->invitestate = INV_COMPLETED; 15154 } 15155 return 0; 15156 } 15157 gotdest = get_destination(p, NULL); /* Get destination right away */ 15158 get_rdnis(p, NULL); /* Get redirect information */ 15159 extract_uri(p, req); /* Get the Contact URI */ 15160 build_contact(p); /* Build our contact header */ 15161 15162 if (p->rtp) { 15163 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 15164 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 15165 } 15166 15167 if (!replace_id && gotdest) { /* No matching extension found */ 15168 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 15169 transmit_response_reliable(p, "484 Address Incomplete", req); 15170 else { 15171 char *decoded_exten = ast_strdupa(p->exten); 15172 15173 transmit_response_reliable(p, "404 Not Found", req); 15174 ast_uri_decode(decoded_exten); 15175 ast_log(LOG_NOTICE, "Call from '%s' to extension" 15176 " '%s' rejected because extension not found.\n", 15177 S_OR(p->username, p->peername), decoded_exten); 15178 } 15179 p->invitestate = INV_COMPLETED; 15180 update_call_counter(p, DEC_CALL_LIMIT); 15181 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15182 return 0; 15183 } else { 15184 /* If no extension was specified, use the s one */ 15185 /* Basically for calling to IP/Host name only */ 15186 if (ast_strlen_zero(p->exten)) 15187 ast_string_field_set(p, exten, "s"); 15188 /* Initialize our tag */ 15189 15190 make_our_tag(p->tag, sizeof(p->tag)); 15191 /* First invitation - create the channel */ 15192 c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL)); 15193 *recount = 1; 15194 15195 /* Save Record-Route for any later requests we make on this dialogue */ 15196 build_route(p, req, 0); 15197 15198 if (c) { 15199 /* Pre-lock the call */ 15200 ast_channel_lock(c); 15201 } 15202 } 15203 } else { 15204 if (option_debug > 1 && sipdebug) { 15205 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 15206 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 15207 else 15208 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 15209 } 15210 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 15211 reinvite = 1; 15212 c = p->owner; 15213 } 15214 15215 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 15216 p->lastinvite = seqno; 15217 15218 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 15219 /* Go and take over the target call */ 15220 if (sipdebug && option_debug > 3) 15221 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 15222 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin, nounlock); 15223 } 15224 15225 15226 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 15227 enum ast_channel_state c_state = c->_state; 15228 15229 if (c_state != AST_STATE_UP && reinvite && 15230 (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) { 15231 /* If these conditions are true, and the channel is still in the 'ringing' 15232 * state, then this likely means that we have a situation where the initial 15233 * INVITE transaction has completed *but* the channel's state has not yet been 15234 * changed to UP. The reason this could happen is if the reinvite is received 15235 * on the SIP socket prior to an application calling ast_read on this channel 15236 * to read the answer frame we earlier queued on it. In this case, the reinvite 15237 * is completely legitimate so we need to handle this the same as if the channel 15238 * were already UP. Thus we are purposely falling through to the AST_STATE_UP case. 15239 */ 15240 c_state = AST_STATE_UP; 15241 } 15242 15243 switch(c_state) { 15244 case AST_STATE_DOWN: 15245 if (option_debug > 1) 15246 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 15247 transmit_provisional_response(p, "100 Trying", req, 0); 15248 p->invitestate = INV_PROCEEDING; 15249 ast_setstate(c, AST_STATE_RING); 15250 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 15251 enum ast_pbx_result res; 15252 15253 res = ast_pbx_start(c); 15254 15255 switch(res) { 15256 case AST_PBX_FAILED: 15257 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 15258 p->invitestate = INV_COMPLETED; 15259 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15260 transmit_response(p, "503 Unavailable", req); 15261 else 15262 transmit_response_reliable(p, "503 Unavailable", req); 15263 break; 15264 case AST_PBX_CALL_LIMIT: 15265 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 15266 p->invitestate = INV_COMPLETED; 15267 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15268 transmit_response(p, "480 Temporarily Unavailable", req); 15269 else 15270 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 15271 break; 15272 case AST_PBX_SUCCESS: 15273 /* nothing to do */ 15274 break; 15275 } 15276 15277 if (res) { 15278 15279 /* Unlock locks so ast_hangup can do its magic */ 15280 ast_mutex_unlock(&c->lock); 15281 ast_mutex_unlock(&p->lock); 15282 ast_hangup(c); 15283 ast_mutex_lock(&p->lock); 15284 c = NULL; 15285 } 15286 } else { /* Pickup call in call group */ 15287 ast_channel_unlock(c); 15288 *nounlock = 1; 15289 if (ast_pickup_call(c)) { 15290 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 15291 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15292 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 15293 else 15294 transmit_response_reliable(p, "503 Unavailable", req); 15295 sip_alreadygone(p); 15296 /* Unlock locks so ast_hangup can do its magic */ 15297 ast_mutex_unlock(&p->lock); 15298 c->hangupcause = AST_CAUSE_CALL_REJECTED; 15299 } else { 15300 ast_mutex_unlock(&p->lock); 15301 ast_setstate(c, AST_STATE_DOWN); 15302 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 15303 } 15304 p->invitestate = INV_COMPLETED; 15305 ast_hangup(c); 15306 ast_mutex_lock(&p->lock); 15307 c = NULL; 15308 } 15309 break; 15310 case AST_STATE_RING: 15311 transmit_provisional_response(p, "100 Trying", req, 0); 15312 p->invitestate = INV_PROCEEDING; 15313 break; 15314 case AST_STATE_RINGING: 15315 transmit_provisional_response(p, "180 Ringing", req, 0); 15316 p->invitestate = INV_PROCEEDING; 15317 break; 15318 case AST_STATE_UP: 15319 if (option_debug > 1) 15320 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 15321 15322 transmit_response(p, "100 Trying", req); 15323 15324 if (p->t38.state == T38_PEER_REINVITE) { 15325 struct ast_channel *bridgepeer = NULL; 15326 struct sip_pvt *bridgepvt = NULL; 15327 15328 if ((bridgepeer = ast_bridged_channel(p->owner))) { 15329 /* 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*/ 15330 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 15331 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 15332 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 15333 if (bridgepvt->t38.state == T38_DISABLED) { 15334 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 15335 /* Send re-invite to the bridged channel */ 15336 sip_handle_t38_reinvite(bridgepeer, p, 1); 15337 } else { /* Something is wrong with peers udptl struct */ 15338 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 15339 ast_mutex_lock(&bridgepvt->lock); 15340 bridgepvt->t38.state = T38_DISABLED; 15341 ast_mutex_unlock(&bridgepvt->lock); 15342 if (option_debug > 1) 15343 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 15344 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15345 transmit_response(p, "488 Not acceptable here", req); 15346 else 15347 transmit_response_reliable(p, "488 Not acceptable here", req); 15348 15349 } 15350 } else { 15351 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 15352 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15353 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 15354 p->t38.state = T38_ENABLED; 15355 if (option_debug) 15356 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 15357 } 15358 } else { 15359 /* Other side is not a SIP channel */ 15360 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15361 transmit_response(p, "488 Not acceptable here", req); 15362 else 15363 transmit_response_reliable(p, "488 Not acceptable here", req); 15364 p->t38.state = T38_DISABLED; 15365 if (option_debug > 1) 15366 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 15367 15368 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 15369 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15370 } 15371 } else { 15372 /* we are not bridged in a call */ 15373 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15374 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 15375 p->t38.state = T38_ENABLED; 15376 if (option_debug) 15377 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 15378 } 15379 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 15380 /* If this is not a re-invite or something to ignore - it's critical */ 15381 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15382 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 15383 } 15384 p->invitestate = INV_TERMINATED; 15385 break; 15386 default: 15387 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 15388 transmit_response(p, "100 Trying", req); 15389 break; 15390 } 15391 } else { 15392 if (p && (p->autokillid == -1)) { 15393 const char *msg; 15394 15395 if (!p->jointcapability) 15396 msg = "488 Not Acceptable Here (codec error)"; 15397 else { 15398 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 15399 msg = "503 Unavailable"; 15400 } 15401 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15402 transmit_response(p, msg, req); 15403 else 15404 transmit_response_reliable(p, msg, req); 15405 p->invitestate = INV_COMPLETED; 15406 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15407 } 15408 } 15409 return res; 15410 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 16055 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().
16056 { 16057 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 16058 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16059 ast_verbose("Receiving message!\n"); 16060 receive_message(p, req); 16061 } else 16062 transmit_response(p, "202 Accepted", req); 16063 return 1; 16064 }
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 14208 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, option_debug, sip_scheddestroy(), sipdebug, transmit_response(), and TRUE.
Referenced by handle_request().
14209 { 14210 /* This is mostly a skeleton for future improvements */ 14211 /* Mostly created to return proper answers on notifications on outbound REFER's */ 14212 int res = 0; 14213 const char *event = get_header(req, "Event"); 14214 char *eventid = NULL; 14215 char *sep; 14216 14217 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 14218 *sep++ = '\0'; 14219 eventid = sep; 14220 } 14221 14222 if (option_debug > 1 && sipdebug) 14223 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 14224 14225 if (strcmp(event, "refer")) { 14226 /* We don't understand this event. */ 14227 /* Here's room to implement incoming voicemail notifications :-) */ 14228 transmit_response(p, "489 Bad event", req); 14229 res = -1; 14230 } else { 14231 /* Save nesting depth for now, since there might be other events we will 14232 support in the future */ 14233 14234 /* Handle REFER notifications */ 14235 14236 char buf[1024]; 14237 char *cmd, *code; 14238 int respcode; 14239 int success = TRUE; 14240 14241 /* EventID for each transfer... EventID is basically the REFER cseq 14242 14243 We are getting notifications on a call that we transfered 14244 We should hangup when we are getting a 200 OK in a sipfrag 14245 Check if we have an owner of this event */ 14246 14247 /* Check the content type */ 14248 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 14249 /* We need a sipfrag */ 14250 transmit_response(p, "400 Bad request", req); 14251 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14252 return -1; 14253 } 14254 14255 /* Get the text of the attachment */ 14256 if (get_msg_text(buf, sizeof(buf), req)) { 14257 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 14258 transmit_response(p, "400 Bad request", req); 14259 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14260 return -1; 14261 } 14262 14263 /* 14264 From the RFC... 14265 A minimal, but complete, implementation can respond with a single 14266 NOTIFY containing either the body: 14267 SIP/2.0 100 Trying 14268 14269 if the subscription is pending, the body: 14270 SIP/2.0 200 OK 14271 if the reference was successful, the body: 14272 SIP/2.0 503 Service Unavailable 14273 if the reference failed, or the body: 14274 SIP/2.0 603 Declined 14275 14276 if the REFER request was accepted before approval to follow the 14277 reference could be obtained and that approval was subsequently denied 14278 (see Section 2.4.7). 14279 14280 If there are several REFERs in the same dialog, we need to 14281 match the ID of the event header... 14282 */ 14283 if (option_debug > 2) 14284 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 14285 cmd = ast_skip_blanks(buf); 14286 code = cmd; 14287 /* We are at SIP/2.0 */ 14288 while(*code && (*code > 32)) { /* Search white space */ 14289 code++; 14290 } 14291 *code++ = '\0'; 14292 code = ast_skip_blanks(code); 14293 sep = code; 14294 sep++; 14295 while(*sep && (*sep > 32)) { /* Search white space */ 14296 sep++; 14297 } 14298 *sep++ = '\0'; /* Response string */ 14299 respcode = atoi(code); 14300 switch (respcode) { 14301 case 100: /* Trying: */ 14302 case 101: /* dialog establishment */ 14303 /* Don't do anything yet */ 14304 break; 14305 case 183: /* Ringing: */ 14306 /* Don't do anything yet */ 14307 break; 14308 case 200: /* OK: The new call is up, hangup this call */ 14309 /* Hangup the call that we are replacing */ 14310 break; 14311 case 301: /* Moved permenantly */ 14312 case 302: /* Moved temporarily */ 14313 /* Do we get the header in the packet in this case? */ 14314 success = FALSE; 14315 break; 14316 case 503: /* Service Unavailable: The new call failed */ 14317 /* Cancel transfer, continue the call */ 14318 success = FALSE; 14319 break; 14320 case 603: /* Declined: Not accepted */ 14321 /* Cancel transfer, continue the current call */ 14322 success = FALSE; 14323 break; 14324 } 14325 if (!success) { 14326 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 14327 } 14328 14329 /* Confirm that we received this packet */ 14330 transmit_response(p, "200 OK", req); 14331 }; 14332 14333 if (!p->lastinvite) 14334 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14335 14336 return res; 14337 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 14340 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().
14341 { 14342 int res; 14343 14344 14345 /* XXX Should we authenticate OPTIONS? XXX */ 14346 14347 if (p->lastinvite) { 14348 /* if this is a request in an active dialog, just confirm that the dialog exists. */ 14349 transmit_response_with_allow(p, "200 OK", req, 0); 14350 return 0; 14351 } 14352 14353 res = get_destination(p, req); 14354 build_contact(p); 14355 14356 if (ast_strlen_zero(p->context)) 14357 ast_string_field_set(p, context, default_context); 14358 14359 if (ast_shutting_down()) 14360 transmit_response_with_allow(p, "503 Unavailable", req, 0); 14361 else if (res < 0) 14362 transmit_response_with_allow(p, "404 Not Found", req, 0); 14363 else 14364 transmit_response_with_allow(p, "200 OK", req, 0); 14365 14366 /* Destroy if this OPTIONS was the opening request, but not if 14367 it's in the middle of a normal call flow. */ 14368 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14369 14370 return res; 14371 }
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 15577 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_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, ast_channel::name, 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().
15578 { 15579 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 15580 /* Chan2: Call between asterisk and transferee */ 15581 15582 int res = 0; 15583 15584 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15585 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"); 15586 15587 if (!p->owner) { 15588 /* This is a REFER outside of an existing SIP dialog */ 15589 /* We can't handle that, so decline it */ 15590 if (option_debug > 2) 15591 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 15592 transmit_response(p, "603 Declined (No dialog)", req); 15593 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 15594 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 15595 sip_alreadygone(p); 15596 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15597 } 15598 return 0; 15599 } 15600 15601 15602 /* Check if transfer is allowed from this device */ 15603 if (p->allowtransfer == TRANSFER_CLOSED ) { 15604 /* Transfer not allowed, decline */ 15605 transmit_response(p, "603 Declined (policy)", req); 15606 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 15607 /* Do not destroy SIP session */ 15608 return 0; 15609 } 15610 15611 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 15612 /* Already have a pending REFER */ 15613 transmit_response(p, "491 Request pending", req); 15614 append_history(p, "Xfer", "Refer failed. Request pending."); 15615 return 0; 15616 } 15617 15618 /* Allocate memory for call transfer data */ 15619 if (!p->refer && !sip_refer_allocate(p)) { 15620 transmit_response(p, "500 Internal Server Error", req); 15621 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 15622 return -3; 15623 } 15624 15625 res = get_refer_info(p, req); /* Extract headers */ 15626 15627 p->refer->status = REFER_SENT; 15628 15629 if (res != 0) { 15630 switch (res) { 15631 case -2: /* Syntax error */ 15632 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 15633 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 15634 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15635 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 15636 break; 15637 case -3: 15638 transmit_response(p, "603 Declined (Non sip: uri)", req); 15639 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 15640 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15641 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 15642 break; 15643 default: 15644 /* Refer-to extension not found, fake a failed transfer */ 15645 transmit_response(p, "202 Accepted", req); 15646 append_history(p, "Xfer", "Refer failed. Bad extension."); 15647 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 15648 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15649 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15650 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 15651 break; 15652 } 15653 return 0; 15654 } 15655 if (ast_strlen_zero(p->context)) 15656 ast_string_field_set(p, context, default_context); 15657 15658 /* If we do not support SIP domains, all transfers are local */ 15659 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 15660 p->refer->localtransfer = 1; 15661 if (sipdebug && option_debug > 2) 15662 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 15663 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 15664 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 15665 p->refer->localtransfer = 1; 15666 } else if (sipdebug && option_debug > 2) 15667 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 15668 15669 /* Is this a repeat of a current request? Ignore it */ 15670 /* Don't know what else to do right now. */ 15671 if (ignore) 15672 return res; 15673 15674 /* If this is a blind transfer, we have the following 15675 channels to work with: 15676 - chan1, chan2: The current call between transferer and transferee (2 channels) 15677 - target_channel: A new call from the transferee to the target (1 channel) 15678 We need to stay tuned to what happens in order to be able 15679 to bring back the call to the transferer */ 15680 15681 /* If this is a attended transfer, we should have all call legs within reach: 15682 - chan1, chan2: The call between the transferer and transferee (2 channels) 15683 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 15684 We want to bridge chan2 with targetcall_pvt! 15685 15686 The replaces call id in the refer message points 15687 to the call leg between Asterisk and the transferer. 15688 So we need to connect the target and the transferee channel 15689 and hangup the two other channels silently 15690 15691 If the target is non-local, the call ID could be on a remote 15692 machine and we need to send an INVITE with replaces to the 15693 target. We basically handle this as a blind transfer 15694 and let the sip_call function catch that we need replaces 15695 header in the INVITE. 15696 */ 15697 15698 15699 /* Get the transferer's channel */ 15700 current.chan1 = p->owner; 15701 15702 /* Find the other part of the bridge (2) - transferee */ 15703 current.chan2 = ast_bridged_channel(current.chan1); 15704 15705 if (sipdebug && option_debug > 2) 15706 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>"); 15707 15708 if (!current.chan2 && !p->refer->attendedtransfer) { 15709 /* No bridged channel, propably IVR or echo or similar... */ 15710 /* Guess we should masquerade or something here */ 15711 /* Until we figure it out, refuse transfer of such calls */ 15712 if (sipdebug && option_debug > 2) 15713 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 15714 p->refer->status = REFER_FAILED; 15715 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 15716 transmit_response(p, "603 Declined", req); 15717 return -1; 15718 } 15719 15720 if (current.chan2) { 15721 if (sipdebug && option_debug > 3) 15722 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 15723 15724 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 15725 } 15726 15727 ast_set_flag(&p->flags[0], SIP_GOTREFER); 15728 15729 /* Attended transfer: Find all call legs and bridge transferee with target*/ 15730 if (p->refer->attendedtransfer) { 15731 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 15732 return res; /* We're done with the transfer */ 15733 /* Fall through for remote transfers that we did not find locally */ 15734 if (sipdebug && option_debug > 3) 15735 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 15736 /* Fallthrough if we can't find the call leg internally */ 15737 } 15738 15739 15740 /* Parking a call */ 15741 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 15742 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 15743 *nounlock = 1; 15744 ast_channel_unlock(current.chan1); 15745 copy_request(¤t.req, req); 15746 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15747 p->refer->status = REFER_200OK; 15748 append_history(p, "Xfer", "REFER to call parking."); 15749 if (sipdebug && option_debug > 3) 15750 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 15751 sip_park(current.chan2, current.chan1, req, seqno); 15752 return res; 15753 } 15754 15755 /* Blind transfers and remote attended xfers */ 15756 transmit_response(p, "202 Accepted", req); 15757 15758 if (current.chan1 && current.chan2) { 15759 if (option_debug > 2) 15760 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 15761 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 15762 } 15763 if (current.chan2) { 15764 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 15765 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 15766 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 15767 /* One for the new channel */ 15768 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 15769 /* Attended transfer to remote host, prepare headers for the INVITE */ 15770 if (p->refer->referred_by) 15771 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 15772 } 15773 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 15774 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 15775 char tempheader[SIPBUFSIZE]; 15776 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 15777 p->refer->replaces_callid_totag ? ";to-tag=" : "", 15778 p->refer->replaces_callid_totag, 15779 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 15780 p->refer->replaces_callid_fromtag); 15781 if (current.chan2) 15782 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 15783 } 15784 /* Must release lock now, because it will not longer 15785 be accessible after the transfer! */ 15786 *nounlock = 1; 15787 ast_channel_unlock(current.chan1); 15788 15789 /* Connect the call */ 15790 15791 /* FAKE ringing if not attended transfer */ 15792 if (!p->refer->attendedtransfer) 15793 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 15794 15795 /* For blind transfer, this will lead to a new call */ 15796 /* For attended transfer to remote host, this will lead to 15797 a new SIP call with a replaces header, if the dial plan allows it 15798 */ 15799 if (!current.chan2) { 15800 /* We have no bridge, so we're talking with Asterisk somehow */ 15801 /* We need to masquerade this call */ 15802 /* What to do to fix this situation: 15803 * Set up the new call in a new channel 15804 * Let the new channel masq into this channel 15805 Please add that code here :-) 15806 */ 15807 p->refer->status = REFER_FAILED; 15808 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 15809 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15810 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 15811 return -1; 15812 } 15813 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 15814 15815 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 15816 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 15817 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 15818 15819 if (!res) { 15820 /* Success - we have a new channel */ 15821 if (option_debug > 2) 15822 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 15823 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 15824 if (p->refer->localtransfer) 15825 p->refer->status = REFER_200OK; 15826 if (p->owner) 15827 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 15828 append_history(p, "Xfer", "Refer succeeded."); 15829 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15830 /* Do not hangup call, the other side do that when we say 200 OK */ 15831 /* We could possibly implement a timer here, auto congestion */ 15832 res = 0; 15833 } else { 15834 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 15835 if (option_debug > 2) 15836 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 15837 append_history(p, "Xfer", "Refer failed."); 15838 /* Failure of some kind */ 15839 p->refer->status = REFER_FAILED; 15840 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 15841 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15842 res = -1; 15843 } 15844 return res; 15845 }
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 16371 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, check_via(), copy_request(), DEFAULT_TRANS_TIMEOUT, get_header(), sip_pvt::initreq, LOG_NOTICE, register_verify(), SIP_PKT_DEBUG, and sip_scheddestroy().
Referenced by handle_request().
16372 { 16373 enum check_auth_result res; 16374 16375 /* Use this as the basis */ 16376 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16377 ast_verbose("Using latest REGISTER request as basis request\n"); 16378 copy_request(&p->initreq, req); 16379 check_via(p, req); 16380 if ((res = register_verify(p, sin, req, e)) < 0) { 16381 const char *reason; 16382 16383 switch (res) { 16384 case AUTH_SECRET_FAILED: 16385 reason = "Wrong password"; 16386 break; 16387 case AUTH_USERNAME_MISMATCH: 16388 reason = "Username/auth name mismatch"; 16389 break; 16390 case AUTH_NOT_FOUND: 16391 reason = "No matching peer found"; 16392 break; 16393 case AUTH_UNKNOWN_DOMAIN: 16394 reason = "Not a local domain"; 16395 break; 16396 case AUTH_PEER_NOT_DYNAMIC: 16397 reason = "Peer is not supposed to register"; 16398 break; 16399 case AUTH_ACL_FAILED: 16400 reason = "Device does not match ACL"; 16401 break; 16402 default: 16403 reason = "Unknown failure"; 16404 break; 16405 } 16406 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 16407 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 16408 reason); 16409 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 16410 } else 16411 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 16412 16413 if (res < 1) { 16414 /* Destroy the session, but keep us around for just a bit in case they don't 16415 get our 200 OK */ 16416 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16417 } 16418 return res; 16419 }
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 16067 of file chan_sip.c.
References 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_mutex_lock, ast_mutex_unlock, 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, cb_extensionstate(), 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, iflist, iflock, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, sip_peer::mailbox, make_our_tag(), sip_request::method, sip_peer::mwipvt, sip_peer::name, sip_pvt::next, 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().
16068 { 16069 int gotdest = 0; 16070 int res = 0; 16071 int firststate = AST_EXTENSION_REMOVED; 16072 struct sip_peer *authpeer = NULL; 16073 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 16074 const char *accept = get_header(req, "Accept"); 16075 int resubscribe = (p->subscribed != NONE); 16076 char *temp, *event; 16077 16078 if (p->initreq.headers) { 16079 /* We already have a dialog */ 16080 if (p->initreq.method != SIP_SUBSCRIBE) { 16081 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 16082 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 16083 transmit_response(p, "403 Forbidden (within dialog)", req); 16084 /* Do not destroy session, since we will break the call if we do */ 16085 if (option_debug) 16086 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); 16087 return 0; 16088 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 16089 if (option_debug) { 16090 if (resubscribe) 16091 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 16092 else 16093 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 16094 } 16095 } 16096 } 16097 16098 /* Check if we have a global disallow setting on subscriptions. 16099 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 16100 */ 16101 if (!global_allowsubscribe) { 16102 transmit_response(p, "403 Forbidden (policy)", req); 16103 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16104 return 0; 16105 } 16106 16107 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 16108 const char *to = get_header(req, "To"); 16109 char totag[128]; 16110 16111 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 16112 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 16113 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16114 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 16115 transmit_response(p, "481 Subscription does not exist", req); 16116 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16117 return 0; 16118 } 16119 16120 /* Use this as the basis */ 16121 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16122 ast_verbose("Creating new subscription\n"); 16123 16124 copy_request(&p->initreq, req); 16125 check_via(p, req); 16126 build_route(p, req, 0); 16127 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 16128 ast_verbose("Ignoring this SUBSCRIBE request\n"); 16129 16130 /* Find parameters to Event: header value and remove them for now */ 16131 if (ast_strlen_zero(eventheader)) { 16132 transmit_response(p, "489 Bad Event", req); 16133 if (option_debug > 1) 16134 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 16135 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16136 return 0; 16137 } 16138 16139 if ( (strchr(eventheader, ';'))) { 16140 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 16141 temp = strchr(event, ';'); 16142 *temp = '\0'; /* Remove any options for now */ 16143 /* We might need to use them later :-) */ 16144 } else 16145 event = (char *) eventheader; /* XXX is this legal ? */ 16146 16147 /* Handle authentication */ 16148 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 16149 /* if an authentication response was sent, we are done here */ 16150 if (res == AUTH_CHALLENGE_SENT) { 16151 if (authpeer) 16152 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16153 return 0; 16154 } 16155 if (res < 0) { 16156 if (res == AUTH_FAKE_AUTH) { 16157 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 16158 transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE); 16159 } else { 16160 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 16161 transmit_response_reliable(p, "403 Forbidden", req); 16162 } 16163 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16164 if (authpeer) 16165 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16166 return 0; 16167 } 16168 16169 /* Check if this user/peer is allowed to subscribe at all */ 16170 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 16171 transmit_response(p, "403 Forbidden (policy)", req); 16172 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16173 if (authpeer) 16174 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16175 return 0; 16176 } 16177 16178 if (strcmp(event, "message-summary")) { 16179 /* Get destination right away */ 16180 gotdest = get_destination(p, NULL); 16181 } 16182 16183 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 16184 parse_ok_contact(p, req); 16185 16186 build_contact(p); 16187 if (gotdest) { 16188 transmit_response(p, "404 Not Found", req); 16189 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16190 if (authpeer) 16191 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16192 return 0; 16193 } 16194 16195 /* Initialize tag for new subscriptions */ 16196 if (ast_strlen_zero(p->tag)) 16197 make_our_tag(p->tag, sizeof(p->tag)); 16198 16199 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 16200 unsigned int pidf_xml; 16201 16202 if (authpeer) /* No need for authpeer here */ 16203 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16204 16205 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 16206 16207 pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0; 16208 16209 /* Older versions of Polycom firmware will claim pidf+xml, but really 16210 * they only support xpidf+xml. */ 16211 if (pidf_xml && strstr(p->useragent, "Polycom")) { 16212 p->subscribed = XPIDF_XML; 16213 } else if (pidf_xml) { 16214 p->subscribed = PIDF_XML; /* RFC 3863 format */ 16215 } else if (strstr(accept, "application/dialog-info+xml")) { 16216 p->subscribed = DIALOG_INFO_XML; 16217 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 16218 } else if (strstr(accept, "application/cpim-pidf+xml")) { 16219 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 16220 } else if (strstr(accept, "application/xpidf+xml")) { 16221 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 16222 } else if (ast_strlen_zero(accept)) { 16223 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 16224 transmit_response(p, "489 Bad Event", req); 16225 16226 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 16227 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 16228 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16229 return 0; 16230 } 16231 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 16232 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 16233 } else { 16234 /* Can't find a format for events that we know about */ 16235 char mybuf[200]; 16236 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 16237 transmit_response(p, mybuf, req); 16238 16239 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 16240 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 16241 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16242 return 0; 16243 } 16244 } else if (!strcmp(event, "message-summary")) { 16245 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 16246 /* Format requested that we do not support */ 16247 transmit_response(p, "406 Not Acceptable", req); 16248 if (option_debug > 1) 16249 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 16250 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16251 if (authpeer) /* No need for authpeer here */ 16252 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16253 return 0; 16254 } 16255 /* Looks like they actually want a mailbox status 16256 This version of Asterisk supports mailbox subscriptions 16257 The subscribed URI needs to exist in the dial plan 16258 In most devices, this is configurable to the voicemailmain extension you use 16259 */ 16260 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 16261 transmit_response(p, "404 Not found (no mailbox)", req); 16262 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16263 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 16264 if (authpeer) /* No need for authpeer here */ 16265 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16266 return 0; 16267 } 16268 16269 p->subscribed = MWI_NOTIFICATION; 16270 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 16271 /* We only allow one subscription per peer */ 16272 sip_destroy(authpeer->mwipvt); 16273 authpeer->mwipvt = p; /* Link from peer to pvt */ 16274 p->relatedpeer = ASTOBJ_REF(authpeer); /* Link from pvt to peer */ 16275 } else { /* At this point, Asterisk does not understand the specified event */ 16276 transmit_response(p, "489 Bad Event", req); 16277 if (option_debug > 1) 16278 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 16279 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16280 if (authpeer) /* No need for authpeer here */ 16281 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16282 return 0; 16283 } 16284 16285 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 16286 if (p->stateid > -1) 16287 ast_extension_state_del(p->stateid, cb_extensionstate); 16288 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 16289 } 16290 16291 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 16292 p->lastinvite = seqno; 16293 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 16294 p->expiry = atoi(get_header(req, "Expires")); 16295 16296 /* check if the requested expiry-time is within the approved limits from sip.conf */ 16297 if (p->expiry > max_expiry) 16298 p->expiry = max_expiry; 16299 if (p->expiry < min_expiry && p->expiry > 0) 16300 p->expiry = min_expiry; 16301 16302 if (sipdebug || option_debug > 1) { 16303 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 16304 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 16305 else 16306 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 16307 } 16308 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 16309 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 16310 if (p->expiry > 0) 16311 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 16312 16313 if (p->subscribed == MWI_NOTIFICATION) { 16314 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 16315 transmit_response(p, "200 OK", req); 16316 if (p->relatedpeer) { /* Send first notification */ 16317 ASTOBJ_WRLOCK(p->relatedpeer); 16318 sip_send_mwi_to_peer(p->relatedpeer, TRUE); 16319 ASTOBJ_UNLOCK(p->relatedpeer); 16320 } 16321 } else { 16322 struct sip_pvt *p_old; 16323 16324 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 16325 16326 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)); 16327 transmit_response(p, "404 Not found", req); 16328 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16329 return 0; 16330 } 16331 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 16332 transmit_response(p, "200 OK", req); 16333 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 16334 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 16335 /* hide the 'complete' exten/context in the refer_to field for later display */ 16336 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 16337 16338 /* remove any old subscription from this peer for the same exten/context, 16339 as the peer has obviously forgotten about it and it's wasteful to wait 16340 for it to expire and send NOTIFY messages to the peer only to have them 16341 ignored (or generate errors) 16342 */ 16343 ast_mutex_lock(&iflock); 16344 for (p_old = iflist; p_old; p_old = p_old->next) { 16345 if (p_old == p) 16346 continue; 16347 if (p_old->initreq.method != SIP_SUBSCRIBE) 16348 continue; 16349 if (p_old->subscribed == NONE) 16350 continue; 16351 ast_mutex_lock(&p_old->lock); 16352 if (!strcmp(p_old->username, p->username)) { 16353 if (!strcmp(p_old->exten, p->exten) && 16354 !strcmp(p_old->context, p->context)) { 16355 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 16356 ast_mutex_unlock(&p_old->lock); 16357 break; 16358 } 16359 } 16360 ast_mutex_unlock(&p_old->lock); 16361 } 16362 ast_mutex_unlock(&iflock); 16363 } 16364 if (!p->expiry) 16365 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16366 } 16367 return 1; 16368 }
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 13481 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(), ast_channel::call_forward, cb_extensionstate(), 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::laststate, LOG_DEBUG, LOG_NOTICE, MAX_AUTHTRIES, sip_pvt::method, NONE, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_pvt::relatedpeer, 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_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(), VERBOSE_PREFIX_3, and XMIT_UNRELIABLE.
13482 { 13483 struct ast_channel *owner; 13484 int sipmethod; 13485 int res = 1; 13486 int ack_res; 13487 const char *c = get_header(req, "Cseq"); 13488 /* 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 */ 13489 char *c_copy = ast_strdupa(c); 13490 /* Skip the Cseq and its subsequent spaces */ 13491 const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy)); 13492 13493 if (!msg) 13494 msg = ""; 13495 13496 sipmethod = find_sip_method(msg); 13497 13498 owner = p->owner; 13499 if (owner) 13500 owner->hangupcause = hangup_sip2cause(resp); 13501 13502 /* Acknowledge whatever it is destined for */ 13503 if ((resp >= 100) && (resp <= 199)) { 13504 ack_res = __sip_semi_ack(p, seqno, 0, sipmethod); 13505 } else { 13506 ack_res = __sip_ack(p, seqno, 0, sipmethod); 13507 } 13508 13509 if (ack_res == FALSE) { 13510 append_history(p, "Ignore", "Ignoring this retransmit\n"); 13511 return; 13512 } 13513 13514 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 13515 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 13516 p->pendinginvite = 0; 13517 13518 /* Get their tag if we haven't already */ 13519 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 13520 char tag[128]; 13521 13522 gettag(req, "To", tag, sizeof(tag)); 13523 ast_string_field_set(p, theirtag, tag); 13524 } 13525 13526 /* RFC 3261 Section 15 specifies that if we receive a 408 or 481 13527 * in response to a BYE, then we should end the current dialog 13528 * and session. It is known that at least one phone manufacturer 13529 * potentially will send a 404 in response to a BYE, so we'll be 13530 * liberal in what we accept and end the dialog and session if we 13531 * receive any of those responses to a BYE. 13532 */ 13533 if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) { 13534 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13535 return; 13536 } 13537 13538 if (p->relatedpeer && p->method == SIP_OPTIONS) { 13539 /* We don't really care what the response is, just that it replied back. 13540 Well, as long as it's not a 100 response... since we might 13541 need to hang around for something more "definitive" */ 13542 if (resp != 100) 13543 handle_response_peerpoke(p, resp, req); 13544 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 13545 switch(resp) { 13546 case 100: /* 100 Trying */ 13547 case 101: /* 101 Dialog establishment */ 13548 if (sipmethod == SIP_INVITE) 13549 handle_response_invite(p, resp, rest, req, seqno); 13550 break; 13551 case 183: /* 183 Session Progress */ 13552 if (sipmethod == SIP_INVITE) 13553 handle_response_invite(p, resp, rest, req, seqno); 13554 break; 13555 case 180: /* 180 Ringing */ 13556 if (sipmethod == SIP_INVITE) 13557 handle_response_invite(p, resp, rest, req, seqno); 13558 break; 13559 case 182: /* 182 Queued */ 13560 if (sipmethod == SIP_INVITE) 13561 handle_response_invite(p, resp, rest, req, seqno); 13562 break; 13563 case 200: /* 200 OK */ 13564 p->authtries = 0; /* Reset authentication counter */ 13565 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 13566 /* We successfully transmitted a message 13567 or a video update request in INFO */ 13568 /* Nothing happens here - the message is inside a dialog */ 13569 } else if (sipmethod == SIP_INVITE) { 13570 handle_response_invite(p, resp, rest, req, seqno); 13571 } else if (sipmethod == SIP_NOTIFY) { 13572 /* They got the notify, this is the end */ 13573 if (p->owner) { 13574 if (!p->refer) { 13575 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 13576 ast_queue_hangup(p->owner); 13577 } else if (option_debug > 3) 13578 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 13579 } else { 13580 if (p->subscribed == NONE) 13581 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13582 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 13583 /* Ready to send the next state we have on queue */ 13584 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 13585 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 13586 } 13587 } 13588 } else if (sipmethod == SIP_REGISTER) 13589 res = handle_response_register(p, resp, rest, req, seqno); 13590 else if (sipmethod == SIP_BYE) { /* Ok, we're ready to go */ 13591 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13592 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 13593 } else if (sipmethod == SIP_SUBSCRIBE) 13594 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 13595 break; 13596 case 202: /* Transfer accepted */ 13597 if (sipmethod == SIP_REFER) 13598 handle_response_refer(p, resp, rest, req, seqno); 13599 break; 13600 case 401: /* Not www-authorized on SIP method */ 13601 if (sipmethod == SIP_INVITE) 13602 handle_response_invite(p, resp, rest, req, seqno); 13603 else if (sipmethod == SIP_REFER) 13604 handle_response_refer(p, resp, rest, req, seqno); 13605 else if (p->registry && sipmethod == SIP_REGISTER) 13606 res = handle_response_register(p, resp, rest, req, seqno); 13607 else if (sipmethod == SIP_BYE) { 13608 if (ast_strlen_zero(p->authname)) { 13609 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 13610 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 13611 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13612 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) { 13613 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13614 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13615 /* We fail to auth bye on our own call, but still needs to tear down the call. 13616 Life, they call it. */ 13617 } 13618 } else { 13619 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 13620 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13621 } 13622 break; 13623 case 403: /* Forbidden - we failed authentication */ 13624 if (sipmethod == SIP_INVITE) 13625 handle_response_invite(p, resp, rest, req, seqno); 13626 else if (p->registry && sipmethod == SIP_REGISTER) 13627 res = handle_response_register(p, resp, rest, req, seqno); 13628 else { 13629 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 13630 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13631 } 13632 break; 13633 case 404: /* Not found */ 13634 if (p->registry && sipmethod == SIP_REGISTER) 13635 res = handle_response_register(p, resp, rest, req, seqno); 13636 else if (sipmethod == SIP_INVITE) 13637 handle_response_invite(p, resp, rest, req, seqno); 13638 else if (owner) 13639 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13640 break; 13641 case 407: /* Proxy auth required */ 13642 if (sipmethod == SIP_INVITE) 13643 handle_response_invite(p, resp, rest, req, seqno); 13644 else if (sipmethod == SIP_REFER) 13645 handle_response_refer(p, resp, rest, req, seqno); 13646 else if (p->registry && sipmethod == SIP_REGISTER) 13647 res = handle_response_register(p, resp, rest, req, seqno); 13648 else if (sipmethod == SIP_BYE) { 13649 if (ast_strlen_zero(p->authname)) { 13650 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 13651 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 13652 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13653 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 13654 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13655 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13656 } 13657 } else /* We can't handle this, giving up in a bad way */ 13658 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13659 13660 break; 13661 case 408: /* Request timeout - terminate dialog */ 13662 if (sipmethod == SIP_INVITE) 13663 handle_response_invite(p, resp, rest, req, seqno); 13664 else if (sipmethod == SIP_REGISTER) 13665 res = handle_response_register(p, resp, rest, req, seqno); 13666 else if (sipmethod == SIP_BYE) { 13667 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13668 if (option_debug) 13669 ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 13670 } else { 13671 if (owner) 13672 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13673 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13674 } 13675 break; 13676 case 481: /* Call leg does not exist */ 13677 if (sipmethod == SIP_INVITE) { 13678 handle_response_invite(p, resp, rest, req, seqno); 13679 } else if (sipmethod == SIP_REFER) { 13680 handle_response_refer(p, resp, rest, req, seqno); 13681 } else if (sipmethod == SIP_BYE) { 13682 /* The other side has no transaction to bye, 13683 just assume it's all right then */ 13684 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13685 } else if (sipmethod == SIP_CANCEL) { 13686 /* The other side has no transaction to cancel, 13687 just assume it's all right then */ 13688 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13689 } else { 13690 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13691 /* Guessing that this is not an important request */ 13692 } 13693 break; 13694 case 487: 13695 if (sipmethod == SIP_INVITE) 13696 handle_response_invite(p, resp, rest, req, seqno); 13697 break; 13698 case 488: /* Not acceptable here - codec error */ 13699 if (sipmethod == SIP_INVITE) 13700 handle_response_invite(p, resp, rest, req, seqno); 13701 break; 13702 case 491: /* Pending */ 13703 if (sipmethod == SIP_INVITE) 13704 handle_response_invite(p, resp, rest, req, seqno); 13705 else { 13706 if (option_debug) 13707 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 13708 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13709 } 13710 break; 13711 case 501: /* Not Implemented */ 13712 if (sipmethod == SIP_INVITE) 13713 handle_response_invite(p, resp, rest, req, seqno); 13714 else if (sipmethod == SIP_REFER) 13715 handle_response_refer(p, resp, rest, req, seqno); 13716 else 13717 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 13718 break; 13719 case 603: /* Declined transfer */ 13720 if (sipmethod == SIP_REFER) { 13721 handle_response_refer(p, resp, rest, req, seqno); 13722 break; 13723 } 13724 /* Fallthrough */ 13725 default: 13726 if ((resp >= 300) && (resp < 700)) { 13727 /* Fatal response */ 13728 if ((option_verbose > 2) && (resp != 487)) 13729 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 13730 13731 if (sipmethod == SIP_INVITE) 13732 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 13733 13734 /* XXX Locking issues?? XXX */ 13735 switch(resp) { 13736 case 300: /* Multiple Choices */ 13737 case 301: /* Moved permenantly */ 13738 case 302: /* Moved temporarily */ 13739 case 305: /* Use Proxy */ 13740 parse_moved_contact(p, req); 13741 /* Fall through */ 13742 case 486: /* Busy here */ 13743 case 600: /* Busy everywhere */ 13744 case 603: /* Decline */ 13745 if (p->owner) 13746 ast_queue_control(p->owner, AST_CONTROL_BUSY); 13747 break; 13748 case 482: /* 13749 \note SIP is incapable of performing a hairpin call, which 13750 is yet another failure of not having a layer 2 (again, YAY 13751 IETF for thinking ahead). So we treat this as a call 13752 forward and hope we end up at the right place... */ 13753 if (option_debug) 13754 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 13755 if (p->owner) 13756 ast_string_field_build(p->owner, call_forward, 13757 "Local/%s@%s", p->username, p->context); 13758 /* Fall through */ 13759 case 480: /* Temporarily Unavailable */ 13760 case 404: /* Not Found */ 13761 case 410: /* Gone */ 13762 case 400: /* Bad Request */ 13763 case 500: /* Server error */ 13764 if (sipmethod == SIP_REFER) { 13765 handle_response_refer(p, resp, rest, req, seqno); 13766 break; 13767 } 13768 /* Fall through */ 13769 case 502: /* Bad gateway */ 13770 case 503: /* Service Unavailable */ 13771 case 504: /* Server Timeout */ 13772 if (owner) 13773 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13774 break; 13775 default: 13776 /* Send hangup */ 13777 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 13778 ast_queue_hangup(p->owner); 13779 break; 13780 } 13781 /* ACK on invite */ 13782 if (sipmethod == SIP_INVITE) 13783 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13784 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 13785 sip_alreadygone(p); 13786 if (!p->owner) 13787 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13788 } else if ((resp >= 100) && (resp < 200)) { 13789 if (sipmethod == SIP_INVITE) { 13790 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13791 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13792 if (find_sdp(req)) 13793 process_sdp(p, req); 13794 if (p->owner) { 13795 /* Queue a progress frame */ 13796 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 13797 } 13798 } 13799 } else 13800 ast_log(LOG_NOTICE, "Dont know how to handle a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : ast_inet_ntoa(p->sa.sin_addr)); 13801 } 13802 } else { 13803 /* Responses to OUTGOING SIP requests on INCOMING calls 13804 get handled here. As well as out-of-call message responses */ 13805 if (ast_test_flag(req, SIP_PKT_DEBUG)) 13806 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 13807 13808 if (sipmethod == SIP_INVITE && resp == 200) { 13809 /* Tags in early session is replaced by the tag in 200 OK, which is 13810 the final reply to our INVITE */ 13811 char tag[128]; 13812 13813 gettag(req, "To", tag, sizeof(tag)); 13814 ast_string_field_set(p, theirtag, tag); 13815 } 13816 13817 switch(resp) { 13818 case 200: 13819 if (sipmethod == SIP_INVITE) { 13820 handle_response_invite(p, resp, rest, req, seqno); 13821 } else if (sipmethod == SIP_CANCEL) { 13822 if (option_debug) 13823 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 13824 13825 /* Wait for 487, then destroy */ 13826 } else if (sipmethod == SIP_NOTIFY) { 13827 /* They got the notify, this is the end */ 13828 if (p->owner) { 13829 if (p->refer) { 13830 if (option_debug) 13831 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 13832 } else 13833 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 13834 /* ast_queue_hangup(p->owner); Disabled */ 13835 } else { 13836 if (!p->subscribed && !p->refer) 13837 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13838 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 13839 /* Ready to send the next state we have on queue */ 13840 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 13841 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 13842 } 13843 } 13844 } else if (sipmethod == SIP_BYE) 13845 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13846 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 13847 /* We successfully transmitted a message or 13848 a video update request in INFO */ 13849 ; 13850 else if (sipmethod == SIP_BYE) 13851 /* Ok, we're ready to go */ 13852 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13853 break; 13854 case 202: /* Transfer accepted */ 13855 if (sipmethod == SIP_REFER) 13856 handle_response_refer(p, resp, rest, req, seqno); 13857 break; 13858 case 401: /* www-auth */ 13859 case 407: 13860 if (sipmethod == SIP_REFER) 13861 handle_response_refer(p, resp, rest, req, seqno); 13862 else if (sipmethod == SIP_INVITE) 13863 handle_response_invite(p, resp, rest, req, seqno); 13864 else if (sipmethod == SIP_BYE) { 13865 char *auth, *auth2; 13866 13867 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 13868 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 13869 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 13870 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13871 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13872 } 13873 } 13874 break; 13875 case 481: /* Call leg does not exist */ 13876 if (sipmethod == SIP_INVITE) { 13877 /* Re-invite failed */ 13878 handle_response_invite(p, resp, rest, req, seqno); 13879 } else if (sipmethod == SIP_BYE) { 13880 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13881 } else if (sipdebug) { 13882 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 13883 } 13884 break; 13885 case 501: /* Not Implemented */ 13886 if (sipmethod == SIP_INVITE) 13887 handle_response_invite(p, resp, rest, req, seqno); 13888 else if (sipmethod == SIP_REFER) 13889 handle_response_refer(p, resp, rest, req, seqno); 13890 break; 13891 case 603: /* Declined transfer */ 13892 if (sipmethod == SIP_REFER) { 13893 handle_response_refer(p, resp, rest, req, seqno); 13894 break; 13895 } 13896 /* Fallthrough */ 13897 default: /* Errors without handlers */ 13898 if ((resp >= 100) && (resp < 200)) { 13899 if (sipmethod == SIP_INVITE) { /* re-invite */ 13900 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13901 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13902 } 13903 } 13904 if ((resp >= 300) && (resp < 700)) { 13905 if ((option_verbose > 2) && (resp != 487)) 13906 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)); 13907 switch(resp) { 13908 case 488: /* Not acceptable here - codec error */ 13909 case 603: /* Decline */ 13910 case 500: /* Server error */ 13911 case 502: /* Bad gateway */ 13912 case 503: /* Service Unavailable */ 13913 case 504: /* Server timeout */ 13914 13915 /* re-invite failed */ 13916 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 13917 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13918 break; 13919 } 13920 } 13921 break; 13922 } 13923 } 13924 }
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 12892 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_ERROR, LOG_NOTICE, MAX_AUTHTRIES, ast_channel::name, option_debug, sip_pvt::options, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, sip_pvt::rtp, sched, 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_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().
12893 { 12894 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 12895 int res = 0; 12896 int xmitres = 0; 12897 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 12898 struct ast_channel *bridgepeer = NULL; 12899 12900 if (option_debug > 3) { 12901 if (reinvite) 12902 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 12903 else 12904 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 12905 } 12906 12907 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 12908 if (option_debug) 12909 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 12910 return; 12911 } 12912 12913 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 12914 /* Don't auto congest anymore since we've gotten something useful back */ 12915 AST_SCHED_DEL(sched, p->initid); 12916 12917 /* RFC3261 says we must treat every 1xx response (but not 100) 12918 that we don't recognize as if it was 183. 12919 */ 12920 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183) 12921 resp = 183; 12922 12923 /* Any response between 100 and 199 is PROCEEDING */ 12924 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 12925 p->invitestate = INV_PROCEEDING; 12926 12927 /* Final response, not 200 ? */ 12928 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 12929 p->invitestate = INV_COMPLETED; 12930 12931 12932 switch (resp) { 12933 case 100: /* Trying */ 12934 case 101: /* Dialog establishment */ 12935 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12936 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12937 check_pendings(p); 12938 break; 12939 12940 case 180: /* 180 Ringing */ 12941 case 182: /* 182 Queued */ 12942 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12943 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12944 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12945 ast_queue_control(p->owner, AST_CONTROL_RINGING); 12946 if (p->owner->_state != AST_STATE_UP) { 12947 ast_setstate(p->owner, AST_STATE_RINGING); 12948 } 12949 } 12950 if (find_sdp(req)) { 12951 if (p->invitestate != INV_CANCELLED) 12952 p->invitestate = INV_EARLY_MEDIA; 12953 res = process_sdp(p, req); 12954 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12955 /* Queue a progress frame only if we have SDP in 180 or 182 */ 12956 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12957 } 12958 } 12959 check_pendings(p); 12960 break; 12961 12962 case 183: /* Session progress */ 12963 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12964 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12965 if (find_sdp(req)) { 12966 if (p->invitestate != INV_CANCELLED) 12967 p->invitestate = INV_EARLY_MEDIA; 12968 res = process_sdp(p, req); 12969 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12970 /* Queue a progress frame */ 12971 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12972 } 12973 } else { 12974 /* Alcatel PBXs are known to send 183s with no SDP after sending 12975 * a 100 Trying response. We're just going to treat this sort of thing 12976 * the same as we would treat a 180 Ringing 12977 */ 12978 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12979 ast_queue_control(p->owner, AST_CONTROL_RINGING); 12980 } 12981 } 12982 check_pendings(p); 12983 break; 12984 12985 case 200: /* 200 OK on invite - someone's answering our call */ 12986 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12987 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12988 p->authtries = 0; 12989 if (find_sdp(req)) { 12990 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 12991 if (!reinvite) 12992 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 12993 /* For re-invites, we try to recover */ 12994 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12995 } 12996 12997 /* Parse contact header for continued conversation */ 12998 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 12999 /* This is important when we have a SIP proxy between us and the phone */ 13000 if (outgoing) { 13001 update_call_counter(p, DEC_CALL_RINGING); 13002 parse_ok_contact(p, req); 13003 /* Save Record-Route for any later requests we make on this dialogue */ 13004 if (!reinvite) 13005 build_route(p, req, 1); 13006 13007 if(set_address_from_contact(p)) { 13008 /* Bad contact - we don't know how to reach this device */ 13009 /* We need to ACK, but then send a bye */ 13010 if (!p->route && !ast_test_flag(req, SIP_PKT_IGNORE)) 13011 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 13012 } 13013 13014 } 13015 13016 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 13017 struct sip_pvt *bridgepvt = NULL; 13018 13019 if (!bridgepeer->tech) { 13020 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 13021 break; 13022 } 13023 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 13024 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 13025 if (bridgepvt->udptl) { 13026 if (p->t38.state == T38_PEER_REINVITE) { 13027 sip_handle_t38_reinvite(bridgepeer, p, 0); 13028 ast_rtp_set_rtptimers_onhold(p->rtp); 13029 if (p->vrtp) 13030 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 13031 } 13032 } else { 13033 if (option_debug > 1) 13034 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 13035 ast_mutex_lock(&bridgepvt->lock); 13036 bridgepvt->t38.state = T38_DISABLED; 13037 ast_mutex_unlock(&bridgepvt->lock); 13038 if (option_debug) 13039 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 13040 p->t38.state = T38_DISABLED; 13041 if (option_debug > 1) 13042 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13043 } 13044 } else { 13045 /* Other side is not a SIP channel */ 13046 if (option_debug > 1) 13047 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 13048 p->t38.state = T38_DISABLED; 13049 if (option_debug > 1) 13050 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13051 } 13052 } 13053 if (p->t38.state == T38_LOCAL_REINVITE) { 13054 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 13055 p->t38.state = T38_ENABLED; 13056 if (option_debug) 13057 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13058 } 13059 13060 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 13061 if (!reinvite) { 13062 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 13063 } else { /* RE-invite */ 13064 ast_queue_frame(p->owner, &ast_null_frame); 13065 } 13066 } else { 13067 /* It's possible we're getting an 200 OK after we've tried to disconnect 13068 by sending CANCEL */ 13069 /* First send ACK, then send bye */ 13070 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 13071 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 13072 } 13073 /* If I understand this right, the branch is different for a non-200 ACK only */ 13074 p->invitestate = INV_TERMINATED; 13075 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 13076 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 13077 check_pendings(p); 13078 break; 13079 case 407: /* Proxy authentication */ 13080 case 401: /* Www auth */ 13081 /* First we ACK */ 13082 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13083 if (p->options) 13084 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 13085 13086 /* Then we AUTH */ 13087 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 13088 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13089 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 13090 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 13091 if (p->authtries < MAX_AUTHTRIES) 13092 p->invitestate = INV_CALLING; 13093 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 13094 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 13095 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13096 sip_alreadygone(p); 13097 if (p->owner) 13098 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13099 } 13100 } 13101 break; 13102 13103 case 403: /* Forbidden */ 13104 /* First we ACK */ 13105 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13106 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 13107 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 13108 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13109 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13110 sip_alreadygone(p); 13111 break; 13112 13113 case 404: /* Not found */ 13114 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13115 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 13116 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13117 sip_alreadygone(p); 13118 break; 13119 13120 case 408: /* Request timeout */ 13121 case 481: /* Call leg does not exist */ 13122 /* Could be REFER caused INVITE with replaces */ 13123 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 13124 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13125 if (p->owner) 13126 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13127 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13128 break; 13129 case 487: /* Cancelled transaction */ 13130 /* We have sent CANCEL on an outbound INVITE 13131 This transaction is already scheduled to be killed by sip_hangup(). 13132 */ 13133 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13134 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 13135 ast_queue_hangup(p->owner); 13136 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 13137 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13138 update_call_counter(p, DEC_CALL_LIMIT); 13139 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 13140 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13141 sip_alreadygone(p); 13142 } 13143 break; 13144 case 488: /* Not acceptable here */ 13145 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13146 if (reinvite && p->udptl) { 13147 /* If this is a T.38 call, we should go back to 13148 audio. If this is an audio call - something went 13149 terribly wrong since we don't renegotiate codecs, 13150 only IP/port . 13151 */ 13152 p->t38.state = T38_DISABLED; 13153 /* Try to reset RTP timers */ 13154 ast_rtp_set_rtptimers_onhold(p->rtp); 13155 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 13156 13157 /*! \bug Is there any way we can go back to the audio call on both 13158 sides here? 13159 */ 13160 /* While figuring that out, hangup the call */ 13161 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 13162 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13163 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13164 } else { 13165 /* We can't set up this call, so give up */ 13166 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 13167 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13168 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13169 /* If there's no dialog to end, then mark p as already gone */ 13170 if (!reinvite) 13171 sip_alreadygone(p); 13172 } 13173 break; 13174 case 491: /* Pending */ 13175 /* we really should have to wait a while, then retransmit 13176 * We should support the retry-after at some point 13177 * At this point, we treat this as a congestion if the call is not in UP state 13178 */ 13179 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13180 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 13181 if (p->owner->_state != AST_STATE_UP) { 13182 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13183 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13184 } else { 13185 /* This is a re-invite that failed. 13186 * Reset the flag after a while 13187 */ 13188 int wait; 13189 /* RFC 3261, if owner of call, wait between 2.1 to 4 seconds, 13190 * if not owner of call, wait 0 to 2 seconds */ 13191 if (ast_test_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL)) { 13192 wait = 2100 + ast_random() % 2000; 13193 } else { 13194 wait = ast_random() % 2000; 13195 } 13196 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 13197 if (option_debug > 2) 13198 ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait); 13199 } 13200 } 13201 break; 13202 13203 case 501: /* Not implemented */ 13204 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13205 if (p->owner) 13206 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13207 break; 13208 } 13209 if (xmitres == XMIT_ERROR) 13210 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 13211 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 13409 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, global_flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_peer::name, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::relatedpeer, s, sched, sip_destroy_peer(), SIP_NEEDDESTROY, SIP_PAGE2_RTUPDATE, and sip_poke_peer_s().
Referenced by handle_response().
13410 { 13411 struct sip_peer *peer = p->relatedpeer; 13412 int statechanged, is_reachable, was_reachable; 13413 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 13414 13415 /* 13416 * Compute the response time to a ping (goes in peer->lastms.) 13417 * -1 means did not respond, 0 means unknown, 13418 * 1..maxms is a valid response, >maxms means late response. 13419 */ 13420 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 13421 pingtime = 1; 13422 13423 /* Now determine new state and whether it has changed. 13424 * Use some helper variables to simplify the writing 13425 * of the expressions. 13426 */ 13427 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 13428 is_reachable = pingtime <= peer->maxms; 13429 statechanged = peer->lastms == 0 /* yes, unknown before */ 13430 || was_reachable != is_reachable; 13431 13432 peer->lastms = pingtime; 13433 peer->call = NULL; 13434 if (statechanged) { 13435 const char *s = is_reachable ? "Reachable" : "Lagged"; 13436 char str_lastms[20]; 13437 snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime); 13438 13439 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 13440 peer->name, s, pingtime, peer->maxms); 13441 ast_device_state_changed("SIP/%s", peer->name); 13442 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) { 13443 ast_update_realtime("sippeers", "name", peer->name, "lastms", str_lastms, NULL); 13444 } 13445 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 13446 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 13447 peer->name, s, pingtime); 13448 } 13449 13450 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 13451 struct sip_peer *peer_ptr = peer; 13452 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 13453 } 13454 13455 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13456 13457 /* Try again eventually */ 13458 peer->pokeexpire = ast_sched_add(sched, 13459 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 13460 sip_poke_peer_s, ASTOBJ_REF(peer)); 13461 13462 if (peer->pokeexpire == -1) { 13463 ASTOBJ_UNREF(peer, sip_destroy_peer); 13464 } 13465 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 13216 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, 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().
13217 { 13218 char *auth = "Proxy-Authenticate"; 13219 char *auth2 = "Proxy-Authorization"; 13220 13221 /* If no refer structure exists, then do nothing */ 13222 if (!p->refer) 13223 return; 13224 13225 switch (resp) { 13226 case 202: /* Transfer accepted */ 13227 /* We need to do something here */ 13228 /* The transferee is now sending INVITE to target */ 13229 p->refer->status = REFER_ACCEPTED; 13230 /* Now wait for next message */ 13231 if (option_debug > 2) 13232 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 13233 /* We should hang along, waiting for NOTIFY's here */ 13234 break; 13235 13236 case 401: /* Not www-authorized on SIP method */ 13237 case 407: /* Proxy auth */ 13238 if (ast_strlen_zero(p->authname)) { 13239 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 13240 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 13241 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13242 } 13243 if (resp == 401) { 13244 auth = "WWW-Authenticate"; 13245 auth2 = "Authorization"; 13246 } 13247 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 13248 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 13249 p->refer->status = REFER_NOAUTH; 13250 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13251 } 13252 break; 13253 case 481: /* Call leg does not exist */ 13254 13255 /* A transfer with Replaces did not work */ 13256 /* OEJ: We should Set flag, cancel the REFER, go back 13257 to original call - but right now we can't */ 13258 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 13259 if (p->owner) 13260 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13261 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13262 break; 13263 13264 case 500: /* Server error */ 13265 case 501: /* Method not implemented */ 13266 /* Return to the current call onhold */ 13267 /* Status flag needed to be reset */ 13268 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 13269 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13270 p->refer->status = REFER_FAILED; 13271 break; 13272 case 603: /* Transfer declined */ 13273 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 13274 p->refer->status = REFER_FAILED; 13275 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13276 break; 13277 } 13278 }
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 13281 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, 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, sched, SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, sip_registry::timeout, sip_pvt::username, and sip_registry::username.
Referenced by handle_response().
13282 { 13283 int expires, expires_ms; 13284 struct sip_registry *r; 13285 r=p->registry; 13286 13287 switch (resp) { 13288 case 401: /* Unauthorized */ 13289 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 13290 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 13291 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13292 } 13293 break; 13294 case 403: /* Forbidden */ 13295 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 13296 if (global_regattempts_max) 13297 p->registry->regattempts = global_regattempts_max+1; 13298 AST_SCHED_DEL(sched, r->timeout); 13299 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13300 break; 13301 case 404: /* Not found */ 13302 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 13303 if (global_regattempts_max) 13304 p->registry->regattempts = global_regattempts_max+1; 13305 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13306 r->call = NULL; 13307 AST_SCHED_DEL(sched, r->timeout); 13308 break; 13309 case 407: /* Proxy auth */ 13310 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 13311 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 13312 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13313 } 13314 break; 13315 case 408: /* Request timeout */ 13316 /* Got a timeout response, so reset the counter of failed responses */ 13317 if (r) { 13318 r->regattempts = 0; 13319 } else { 13320 ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid); 13321 } 13322 break; 13323 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 13324 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 13325 if (global_regattempts_max) 13326 p->registry->regattempts = global_regattempts_max+1; 13327 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13328 r->call = NULL; 13329 AST_SCHED_DEL(sched, r->timeout); 13330 break; 13331 case 200: /* 200 OK */ 13332 if (!r) { 13333 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)); 13334 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13335 return 0; 13336 } 13337 13338 r->regstate = REG_STATE_REGISTERED; 13339 r->regtime = time(NULL); /* Reset time of last succesful registration */ 13340 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 13341 r->regattempts = 0; 13342 if (option_debug) 13343 ast_log(LOG_DEBUG, "Registration successful\n"); 13344 if (r->timeout > -1) { 13345 if (option_debug) 13346 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 13347 } 13348 AST_SCHED_DEL(sched, r->timeout); 13349 r->call = NULL; 13350 p->registry = NULL; 13351 /* Let this one hang around until we have all the responses */ 13352 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13353 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 13354 13355 /* set us up for re-registering */ 13356 /* figure out how long we got registered for */ 13357 AST_SCHED_DEL(sched, r->expire); 13358 /* according to section 6.13 of RFC, contact headers override 13359 expires headers, so check those first */ 13360 expires = 0; 13361 13362 /* XXX todo: try to save the extra call */ 13363 if (!ast_strlen_zero(get_header(req, "Contact"))) { 13364 const char *contact = NULL; 13365 const char *tmptmp = NULL; 13366 int start = 0; 13367 for(;;) { 13368 contact = __get_header(req, "Contact", &start); 13369 /* this loop ensures we get a contact header about our register request */ 13370 if(!ast_strlen_zero(contact)) { 13371 if( (tmptmp=strstr(contact, p->our_contact))) { 13372 contact=tmptmp; 13373 break; 13374 } 13375 } else 13376 break; 13377 } 13378 tmptmp = strcasestr(contact, "expires="); 13379 if (tmptmp) { 13380 if (sscanf(tmptmp + 8, "%30d;", &expires) != 1) 13381 expires = 0; 13382 } 13383 13384 } 13385 if (!expires) 13386 expires=atoi(get_header(req, "expires")); 13387 if (!expires) 13388 expires=default_expiry; 13389 13390 expires_ms = expires * 1000; 13391 if (expires <= EXPIRY_GUARD_LIMIT) 13392 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 13393 else 13394 expires_ms -= EXPIRY_GUARD_SECS * 1000; 13395 if (sipdebug) 13396 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 13397 13398 r->refresh= (int) expires_ms / 1000; 13399 13400 /* Schedule re-registration before we expire */ 13401 AST_SCHED_DEL(sched, r->expire); 13402 r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 13403 ASTOBJ_UNREF(r, sip_registry_destroy); 13404 } 13405 return 1; 13406 }
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 3620 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().
03621 { 03622 switch (cause) { 03623 case AST_CAUSE_UNALLOCATED: /* 1 */ 03624 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03625 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03626 return "404 Not Found"; 03627 case AST_CAUSE_CONGESTION: /* 34 */ 03628 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03629 return "503 Service Unavailable"; 03630 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03631 return "408 Request Timeout"; 03632 case AST_CAUSE_NO_ANSWER: /* 19 */ 03633 case AST_CAUSE_UNREGISTERED: /* 20 */ 03634 return "480 Temporarily unavailable"; 03635 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03636 return "403 Forbidden"; 03637 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03638 return "410 Gone"; 03639 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03640 return "480 Temporarily unavailable"; 03641 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03642 return "484 Address incomplete"; 03643 case AST_CAUSE_USER_BUSY: 03644 return "486 Busy here"; 03645 case AST_CAUSE_FAILURE: 03646 return "500 Server internal failure"; 03647 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03648 return "501 Not Implemented"; 03649 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03650 return "503 Service Unavailable"; 03651 /* Used in chan_iax2 */ 03652 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03653 return "502 Bad Gateway"; 03654 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03655 return "488 Not Acceptable Here"; 03656 03657 case AST_CAUSE_NOTDEFINED: 03658 default: 03659 if (option_debug) 03660 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03661 return NULL; 03662 } 03663 03664 /* Never reached */ 03665 return 0; 03666 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3508 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().
03509 { 03510 /* Possible values taken from causes.h */ 03511 03512 switch(cause) { 03513 case 401: /* Unauthorized */ 03514 return AST_CAUSE_CALL_REJECTED; 03515 case 403: /* Not found */ 03516 return AST_CAUSE_CALL_REJECTED; 03517 case 404: /* Not found */ 03518 return AST_CAUSE_UNALLOCATED; 03519 case 405: /* Method not allowed */ 03520 return AST_CAUSE_INTERWORKING; 03521 case 407: /* Proxy authentication required */ 03522 return AST_CAUSE_CALL_REJECTED; 03523 case 408: /* No reaction */ 03524 return AST_CAUSE_NO_USER_RESPONSE; 03525 case 409: /* Conflict */ 03526 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03527 case 410: /* Gone */ 03528 return AST_CAUSE_NUMBER_CHANGED; 03529 case 411: /* Length required */ 03530 return AST_CAUSE_INTERWORKING; 03531 case 413: /* Request entity too large */ 03532 return AST_CAUSE_INTERWORKING; 03533 case 414: /* Request URI too large */ 03534 return AST_CAUSE_INTERWORKING; 03535 case 415: /* Unsupported media type */ 03536 return AST_CAUSE_INTERWORKING; 03537 case 420: /* Bad extension */ 03538 return AST_CAUSE_NO_ROUTE_DESTINATION; 03539 case 480: /* No answer */ 03540 return AST_CAUSE_NO_ANSWER; 03541 case 481: /* No answer */ 03542 return AST_CAUSE_INTERWORKING; 03543 case 482: /* Loop detected */ 03544 return AST_CAUSE_INTERWORKING; 03545 case 483: /* Too many hops */ 03546 return AST_CAUSE_NO_ANSWER; 03547 case 484: /* Address incomplete */ 03548 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03549 case 485: /* Ambigous */ 03550 return AST_CAUSE_UNALLOCATED; 03551 case 486: /* Busy everywhere */ 03552 return AST_CAUSE_BUSY; 03553 case 487: /* Request terminated */ 03554 return AST_CAUSE_INTERWORKING; 03555 case 488: /* No codecs approved */ 03556 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03557 case 491: /* Request pending */ 03558 return AST_CAUSE_INTERWORKING; 03559 case 493: /* Undecipherable */ 03560 return AST_CAUSE_INTERWORKING; 03561 case 500: /* Server internal failure */ 03562 return AST_CAUSE_FAILURE; 03563 case 501: /* Call rejected */ 03564 return AST_CAUSE_FACILITY_REJECTED; 03565 case 502: 03566 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03567 case 503: /* Service unavailable */ 03568 return AST_CAUSE_CONGESTION; 03569 case 504: /* Gateway timeout */ 03570 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03571 case 505: /* SIP version not supported */ 03572 return AST_CAUSE_INTERWORKING; 03573 case 600: /* Busy everywhere */ 03574 return AST_CAUSE_USER_BUSY; 03575 case 603: /* Decline */ 03576 return AST_CAUSE_CALL_REJECTED; 03577 case 604: /* Does not exist anywhere */ 03578 return AST_CAUSE_UNALLOCATED; 03579 case 606: /* Not acceptable */ 03580 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03581 default: 03582 return AST_CAUSE_NORMAL; 03583 } 03584 /* Never reached */ 03585 return 0; 03586 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 6342 of file chan_sip.c.
References sip_methods, and cfsip_methods::text.
06343 { 06344 /* Initialize a request */ 06345 memset(req, 0, sizeof(*req)); 06346 req->method = sipmethod; 06347 req->header[0] = req->data; 06348 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 06349 req->len = strlen(req->header[0]); 06350 req->headers++; 06351 return 0; 06352 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 6329 of file chan_sip.c.
References SIP_RESPONSE.
06330 { 06331 /* Initialize a response */ 06332 memset(resp, 0, sizeof(*resp)); 06333 resp->method = SIP_RESPONSE; 06334 resp->header[0] = resp->data; 06335 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 06336 resp->len = strlen(resp->header[0]); 06337 resp->headers++; 06338 return 0; 06339 }
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 1704 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().
01705 { 01706 if (p->initreq.headers && option_debug) { 01707 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01708 } 01709 /* Use this as the basis */ 01710 copy_request(&p->initreq, req); 01711 parse_request(&p->initreq); 01712 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01713 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01714 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 7490 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, 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().
07491 { 07492 char invite_buf[256] = ""; 07493 char *invite = invite_buf; 07494 size_t invite_max = sizeof(invite_buf); 07495 char from[256]; 07496 char to[256]; 07497 char tmp[SIPBUFSIZE/2]; 07498 char tmp2[SIPBUFSIZE/2]; 07499 const char *l = NULL, *n = NULL, *d = NULL; 07500 const char *urioptions = ""; 07501 07502 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 07503 const char *s = p->username; /* being a string field, cannot be NULL */ 07504 07505 /* Test p->username against allowed characters in AST_DIGIT_ANY 07506 If it matches the allowed characters list, then sipuser = ";user=phone" 07507 If not, then sipuser = "" 07508 */ 07509 /* + is allowed in first position in a tel: uri */ 07510 if (*s == '+') 07511 s++; 07512 for (; *s; s++) { 07513 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 07514 break; 07515 } 07516 /* If we have only digits, add ;user=phone to the uri */ 07517 if (!*s) 07518 urioptions = ";user=phone"; 07519 } 07520 07521 07522 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 07523 07524 d = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 07525 if (p->owner) { 07526 l = p->owner->cid.cid_num; 07527 n = p->owner->cid.cid_name; 07528 } 07529 /* if we are not sending RPID and user wants his callerid restricted */ 07530 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 07531 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 07532 l = CALLERID_UNKNOWN; 07533 n = l; 07534 d = FROMDOMAIN_INVALID; 07535 } 07536 if (ast_strlen_zero(l)) 07537 l = default_callerid; 07538 if (ast_strlen_zero(n)) 07539 n = l; 07540 /* Allow user to be overridden */ 07541 if (!ast_strlen_zero(p->fromuser)) 07542 l = p->fromuser; 07543 else /* Save for any further attempts */ 07544 ast_string_field_set(p, fromuser, l); 07545 07546 /* Allow user to be overridden */ 07547 if (!ast_strlen_zero(p->fromname)) 07548 n = p->fromname; 07549 else /* Save for any further attempts */ 07550 ast_string_field_set(p, fromname, n); 07551 07552 if (pedanticsipchecking) { 07553 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07554 n = tmp; 07555 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 07556 l = tmp2; 07557 } 07558 07559 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 07560 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, d, ourport, p->tag); 07561 else 07562 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, d, p->tag); 07563 07564 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 07565 if (!ast_strlen_zero(p->fullcontact)) { 07566 /* If we have full contact, trust it */ 07567 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 07568 } else { 07569 /* Otherwise, use the username while waiting for registration */ 07570 ast_build_string(&invite, &invite_max, "sip:"); 07571 if (!ast_strlen_zero(p->username)) { 07572 n = p->username; 07573 if (pedanticsipchecking) { 07574 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07575 n = tmp; 07576 } 07577 ast_build_string(&invite, &invite_max, "%s@", n); 07578 } 07579 ast_build_string(&invite, &invite_max, "%s", p->tohost); 07580 if (p->portinuri) 07581 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 07582 ast_build_string(&invite, &invite_max, "%s", urioptions); 07583 } 07584 07585 /* If custom URI options have been provided, append them */ 07586 if (p->options && !ast_strlen_zero(p->options->uri_options)) 07587 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 07588 07589 ast_string_field_set(p, uri, invite_buf); 07590 07591 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 07592 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 07593 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (!strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); 07594 } else if (p->options && p->options->vxml_url) { 07595 /* If there is a VXML URL append it to the SIP URL */ 07596 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 07597 } else 07598 snprintf(to, sizeof(to), "<%s>", p->uri); 07599 07600 init_req(req, sipmethod, p->uri); 07601 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 07602 07603 add_header(req, "Via", p->via); 07604 /* This will be a no-op most of the time. However, under certain circumstances, 07605 * NOTIFY messages will use this function for preparing the request and should 07606 * have Route headers present. 07607 */ 07608 add_route(req, p->route); 07609 /* Build Remote Party-ID and From */ 07610 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 07611 build_rpid(p); 07612 add_header(req, "From", p->rpid_from); 07613 } else 07614 add_header(req, "From", from); 07615 add_header(req, "To", to); 07616 ast_string_field_set(p, exten, l); 07617 build_contact(p); 07618 add_header(req, "Contact", p->our_contact); 07619 add_header(req, "Call-ID", p->callid); 07620 add_header(req, "CSeq", tmp); 07621 if (!ast_strlen_zero(global_useragent)) 07622 add_header(req, "User-Agent", global_useragent); 07623 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07624 if (!ast_strlen_zero(p->rpid)) 07625 add_header(req, "Remote-Party-ID", p->rpid); 07626 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | const [static] |
Convert Insecure setting to printable string.
Definition at line 10883 of file chan_sip.c.
Referenced by _sip_show_peer().
10884 { 10885 if (port && invite) 10886 return "port,invite"; 10887 else if (port) 10888 return "port"; 10889 else if (invite) 10890 return "invite"; 10891 else 10892 return "no"; 10893 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 8873 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
08874 { 08875 if (!route) 08876 ast_verbose("list_route: no route\n"); 08877 else { 08878 for (;route; route = route->next) 08879 ast_verbose("list_route: hop: <%s>\n", route->hop); 08880 } 08881 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 19524 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, cli_sip, EVENT_FLAG_SYSTEM, io, io_context_create(), io_context_destroy(), LOG_ERROR, manager_sip_show_peer(), manager_sip_show_peers(), peerl, regl, reload_config(), restart_monitor(), sched, 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.
19525 { 19526 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 19527 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 19528 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 19529 19530 if (!(sched = sched_context_create())) { 19531 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 19532 return AST_MODULE_LOAD_FAILURE; 19533 } 19534 19535 if (!(io = io_context_create())) { 19536 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 19537 sched_context_destroy(sched); 19538 return AST_MODULE_LOAD_FAILURE; 19539 } 19540 19541 sip_reloadreason = CHANNEL_MODULE_LOAD; 19542 19543 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 19544 return AST_MODULE_LOAD_DECLINE; 19545 19546 /* Make sure we can register our sip channel type */ 19547 if (ast_channel_register(&sip_tech)) { 19548 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 19549 io_context_destroy(io); 19550 sched_context_destroy(sched); 19551 return AST_MODULE_LOAD_FAILURE; 19552 } 19553 19554 /* Register all CLI functions for SIP */ 19555 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 19556 19557 /* Tell the RTP subdriver that we're here */ 19558 ast_rtp_proto_register(&sip_rtp); 19559 19560 /* Tell the UDPTL subdriver that we're here */ 19561 ast_udptl_proto_register(&sip_udptl); 19562 19563 /* Register dialplan applications */ 19564 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 19565 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 19566 19567 /* Register dialplan functions */ 19568 ast_custom_function_register(&sip_header_function); 19569 ast_custom_function_register(&sippeer_function); 19570 ast_custom_function_register(&sipchaninfo_function); 19571 ast_custom_function_register(&checksipdomain_function); 19572 19573 /* Register manager commands */ 19574 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 19575 "List SIP peers (text format)", mandescr_show_peers); 19576 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 19577 "Show SIP peer (text format)", mandescr_show_peer); 19578 19579 sip_poke_all_peers(); 19580 sip_send_all_registers(); 19581 19582 /* And start the monitor for the first time */ 19583 restart_monitor(); 19584 19585 return AST_MODULE_LOAD_SUCCESS; 19586 }
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 15414 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), ast_channel_unlock, ast_clear_flag, ast_hangup(), 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, ast_channel::name, 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(), transmit_response(), and TRUE.
Referenced by handle_request_refer().
15415 { 15416 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 15417 /* Chan 2: Call from Asterisk to target */ 15418 int res = 0; 15419 struct sip_pvt *targetcall_pvt; 15420 15421 /* Check if the call ID of the replaces header does exist locally */ 15422 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 15423 transferer->refer->replaces_callid_fromtag))) { 15424 if (transferer->refer->localtransfer) { 15425 /* We did not find the refered call. Sorry, can't accept then */ 15426 transmit_response(transferer, "202 Accepted", req); 15427 /* Let's fake a response from someone else in order 15428 to follow the standard */ 15429 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 15430 append_history(transferer, "Xfer", "Refer failed"); 15431 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 15432 transferer->refer->status = REFER_FAILED; 15433 return -1; 15434 } 15435 /* Fall through for remote transfers that we did not find locally */ 15436 if (option_debug > 2) 15437 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 15438 return 0; 15439 } 15440 15441 /* Ok, we can accept this transfer */ 15442 transmit_response(transferer, "202 Accepted", req); 15443 append_history(transferer, "Xfer", "Refer accepted"); 15444 if (!targetcall_pvt->owner) { /* No active channel */ 15445 if (option_debug > 3) 15446 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 15447 /* Cancel transfer */ 15448 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 15449 append_history(transferer, "Xfer", "Refer failed"); 15450 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 15451 transferer->refer->status = REFER_FAILED; 15452 ast_mutex_unlock(&targetcall_pvt->lock); 15453 return -1; 15454 } 15455 15456 /* We have a channel, find the bridge */ 15457 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 15458 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 15459 15460 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 15461 /* Wrong state of new channel */ 15462 if (option_debug > 3) { 15463 if (target.chan2) 15464 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 15465 else if (target.chan1->_state != AST_STATE_RING) 15466 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 15467 else 15468 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 15469 } 15470 } 15471 15472 /* Transfer */ 15473 if (option_debug > 3 && sipdebug) { 15474 if (current->chan2) /* We have two bridges */ 15475 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 15476 else /* One bridge, propably transfer of IVR/voicemail etc */ 15477 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 15478 } 15479 15480 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 15481 15482 /* Perform the transfer */ 15483 res = attempt_transfer(current, &target); 15484 ast_mutex_unlock(&targetcall_pvt->lock); 15485 if (res) { 15486 /* Failed transfer */ 15487 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 15488 append_history(transferer, "Xfer", "Refer failed"); 15489 transferer->refer->status = REFER_FAILED; 15490 if (targetcall_pvt->owner) 15491 ast_channel_unlock(targetcall_pvt->owner); 15492 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 15493 if (res != -2) 15494 ast_hangup(transferer->owner); 15495 else 15496 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 15497 } else { 15498 /* Transfer succeeded! */ 15499 15500 /* Tell transferer that we're done. */ 15501 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 15502 append_history(transferer, "Xfer", "Refer succeeded"); 15503 transferer->refer->status = REFER_200OK; 15504 if (targetcall_pvt->owner) { 15505 if (option_debug) 15506 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 15507 ast_channel_unlock(targetcall_pvt->owner); 15508 } 15509 } 15510 return 1; 15511 }
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 5038 of file chan_sip.c.
References t.
Referenced by sipsock_read().
05039 { 05040 int h = 0, t = 0; 05041 int lws = 0; 05042 05043 for (; h < len;) { 05044 /* Eliminate all CRs */ 05045 if (msgbuf[h] == '\r') { 05046 h++; 05047 continue; 05048 } 05049 /* Check for end-of-line */ 05050 if (msgbuf[h] == '\n') { 05051 /* Check for end-of-message */ 05052 if (h + 1 == len) 05053 break; 05054 /* Check for a continuation line */ 05055 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 05056 /* Merge continuation line */ 05057 h++; 05058 continue; 05059 } 05060 /* Propagate LF and start new line */ 05061 msgbuf[t++] = msgbuf[h++]; 05062 lws = 0; 05063 continue; 05064 } 05065 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 05066 if (lws) { 05067 h++; 05068 continue; 05069 } 05070 msgbuf[t++] = msgbuf[h++]; 05071 lws = 1; 05072 continue; 05073 } 05074 msgbuf[t++] = msgbuf[h++]; 05075 if (lws) 05076 lws = 0; 05077 } 05078 msgbuf[t] = '\0'; 05079 return t; 05080 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4693 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().
04694 { 04695 snprintf(tagbuf, len, "as%08lx", ast_random()); 04696 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 11128 of file chan_sip.c.
References _sip_show_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), and s.
Referenced by load_module().
11129 { 11130 const char *a[4]; 11131 const char *peer; 11132 int ret; 11133 11134 peer = astman_get_header(m,"Peer"); 11135 if (ast_strlen_zero(peer)) { 11136 astman_send_error(s, m, "Peer: <name> missing."); 11137 return 0; 11138 } 11139 a[0] = "sip"; 11140 a[1] = "show"; 11141 a[2] = "peer"; 11142 a[3] = peer; 11143 11144 ret = _sip_show_peer(1, -1, s, m, 4, a); 11145 astman_append(s, "\r\n\r\n" ); 11146 return ret; 11147 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10679 of file chan_sip.c.
References _sip_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), s, and total.
Referenced by load_module().
10680 { 10681 const char *id = astman_get_header(m,"ActionID"); 10682 const char *a[] = {"sip", "show", "peers"}; 10683 char idtext[256] = ""; 10684 int total = 0; 10685 10686 if (!ast_strlen_zero(id)) 10687 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10688 10689 astman_send_ack(s, m, "Peer status list will follow"); 10690 /* List the peers in separate manager events */ 10691 _sip_show_peers(-1, &total, s, m, 3, a); 10692 /* Send final confirmation */ 10693 astman_append(s, 10694 "Event: PeerlistComplete\r\n" 10695 "ListItems: %d\r\n" 10696 "%s" 10697 "\r\n", total, idtext); 10698 return 0; 10699 }
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 1730 of file chan_sip.c.
References sip_request::len, sip_methods, and text.
Referenced by __sip_autodestruct(), __sip_semi_ack(), and find_sip_method().
01731 { 01732 int len = strlen(sip_methods[id].text); 01733 int l_name = name ? strlen(name) : 0; 01734 /* true if the string is long enough, and ends with whitespace, and matches */ 01735 return (l_name >= len && name[len] < 33 && 01736 !strncasecmp(sip_methods[id].text, name, len)); 01737 }
static char * nat2str | ( | int | nat | ) | const [static] |
Convert NAT setting to text string.
Definition at line 10582 of file chan_sip.c.
References SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, and SIP_NAT_ROUTE.
Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_users().
10583 { 10584 switch(nat) { 10585 case SIP_NAT_NEVER: 10586 return "No"; 10587 case SIP_NAT_ROUTE: 10588 return "Route"; 10589 case SIP_NAT_ALWAYS: 10590 return "Always"; 10591 case SIP_NAT_RFC3581: 10592 return "RFC3581"; 10593 default: 10594 return "Unknown"; 10595 } 10596 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 2319 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
02320 { 02321 memset(dst, 0, sizeof(*dst)); 02322 memcpy(dst->data, src->data, sizeof(dst->data)); 02323 dst->len = src->len; 02324 parse_request(dst); 02325 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 12790 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_test_flag, 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().
12791 { 12792 char tmp[SIPBUFSIZE]; 12793 char *s, *e, *uri, *t; 12794 char *domain; 12795 12796 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 12797 if ((t = strchr(tmp, ','))) 12798 *t = '\0'; 12799 s = get_in_brackets(tmp); 12800 uri = ast_strdupa(s); 12801 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 12802 if (!strncasecmp(s, "sip:", 4)) 12803 s += 4; 12804 e = strchr(s, ';'); 12805 if (e) 12806 *e = '\0'; 12807 if (option_debug) 12808 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 12809 if (p->owner) 12810 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 12811 } else { 12812 e = strchr(tmp, '@'); 12813 if (e) { 12814 *e++ = '\0'; 12815 domain = e; 12816 } else { 12817 /* No username part */ 12818 domain = tmp; 12819 } 12820 e = strchr(s, ';'); /* Strip of parameters in the username part */ 12821 if (e) 12822 *e = '\0'; 12823 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 12824 if (e) 12825 *e = '\0'; 12826 12827 if (!strncasecmp(s, "sip:", 4)) 12828 s += 4; 12829 if (option_debug > 1) 12830 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 12831 if (p->owner) { 12832 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 12833 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 12834 ast_string_field_set(p->owner, call_forward, s); 12835 } 12836 } 12837 }
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 8598 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().
08599 { 08600 char contact[SIPBUFSIZE]; 08601 char *c; 08602 08603 /* Look for brackets */ 08604 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08605 c = get_in_brackets(contact); 08606 08607 /* Save full contact to call pvt for later bye or re-invite */ 08608 ast_string_field_set(pvt, fullcontact, c); 08609 08610 /* Save URI for later ACKs, BYE or RE-invites */ 08611 ast_string_field_set(pvt, okcontacturi, c); 08612 08613 /* We should return false for URI:s we can't handle, 08614 like sips:, tel:, mailto:,ldap: etc */ 08615 return TRUE; 08616 }
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 8687 of file chan_sip.c.
References sip_peer::addr, ahp, ast_apply_ha(), ast_copy_string(), ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_sched_when(), AST_SENSE_ALLOW, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::contactha, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), global_contact_ha, hp, inaddrcmp(), sip_peer::lastms, LOG_NOTICE, 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(), sched, 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, sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.
Referenced by register_verify().
08688 { 08689 char contact[SIPBUFSIZE]; 08690 char data[SIPBUFSIZE]; 08691 const char *expires = get_header(req, "Expires"); 08692 int expiry = atoi(expires); 08693 char *curi, *n, *pt; 08694 int port; 08695 const char *useragent; 08696 struct hostent *hp; 08697 struct ast_hostent ahp; 08698 struct sockaddr_in oldsin, testsin; 08699 08700 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08701 08702 if (ast_strlen_zero(expires)) { /* No expires header */ 08703 expires = strcasestr(contact, ";expires="); 08704 if (expires) { 08705 /* XXX bug here, we overwrite the string */ 08706 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 08707 if (sscanf(expires + 9, "%30d", &expiry) != 1) 08708 expiry = default_expiry; 08709 } else { 08710 /* Nothing has been specified */ 08711 expiry = default_expiry; 08712 } 08713 } 08714 08715 /* Look for brackets */ 08716 curi = contact; 08717 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 08718 strsep(&curi, ";"); /* This is Header options, not URI options */ 08719 curi = get_in_brackets(contact); 08720 08721 /* if they did not specify Contact: or Expires:, they are querying 08722 what we currently have stored as their contact address, so return 08723 it 08724 */ 08725 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 08726 /* If we have an active registration, tell them when the registration is going to expire */ 08727 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 08728 pvt->expiry = ast_sched_when(sched, peer->expire); 08729 return PARSE_REGISTER_QUERY; 08730 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 08731 /* This means remove all registrations and return OK */ 08732 memset(&peer->addr, 0, sizeof(peer->addr)); 08733 if (!AST_SCHED_DEL(sched, peer->expire)) { 08734 struct sip_peer *peer_ptr = peer; 08735 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08736 } 08737 08738 destroy_association(peer); 08739 08740 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 08741 peer->fullcontact[0] = '\0'; 08742 peer->useragent[0] = '\0'; 08743 peer->sipoptions = 0; 08744 peer->lastms = 0; 08745 peer->portinuri = 0; 08746 pvt->expiry = 0; 08747 08748 if (option_verbose > 2) 08749 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 08750 08751 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 08752 return PARSE_REGISTER_UPDATE; 08753 } 08754 08755 /* Store whatever we got as a contact from the client */ 08756 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 08757 08758 /* For the 200 OK, we should use the received contact */ 08759 ast_string_field_build(pvt, our_contact, "<%s>", curi); 08760 08761 /* Make sure it's a SIP URL */ 08762 if (strncasecmp(curi, "sip:", 4)) { 08763 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 08764 } else 08765 curi += 4; 08766 /* Ditch q */ 08767 curi = strsep(&curi, ";"); 08768 /* Grab host */ 08769 n = strchr(curi, '@'); 08770 if (!n) { 08771 n = curi; 08772 curi = NULL; 08773 } else 08774 *n++ = '\0'; 08775 pt = strchr(n, ':'); 08776 if (pt) { 08777 *pt++ = '\0'; 08778 port = atoi(pt); 08779 peer->portinuri = 1; 08780 } else { 08781 port = STANDARD_SIP_PORT; 08782 peer->portinuri = 0; 08783 } 08784 oldsin = peer->addr; 08785 08786 /* Check that they're allowed to register at this IP */ 08787 /* XXX This could block for a long time XXX */ 08788 hp = ast_gethostbyname(n, &ahp); 08789 if (!hp) { 08790 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 08791 *peer->fullcontact = '\0'; 08792 ast_string_field_set(pvt, our_contact, ""); 08793 return PARSE_REGISTER_FAILED; 08794 } 08795 memcpy(&testsin.sin_addr, hp->h_addr, sizeof(testsin.sin_addr)); 08796 if ( ast_apply_ha(global_contact_ha, &testsin) != AST_SENSE_ALLOW || 08797 ast_apply_ha(peer->contactha, &testsin) != AST_SENSE_ALLOW) { 08798 ast_log(LOG_WARNING, "Host '%s' disallowed by contact ACL (violating IP %s)\n", n, ast_inet_ntoa(testsin.sin_addr)); 08799 *peer->fullcontact = '\0'; 08800 ast_string_field_set(pvt, our_contact, ""); 08801 return PARSE_REGISTER_DENIED; 08802 } 08803 08804 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 08805 peer->addr.sin_family = AF_INET; 08806 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 08807 peer->addr.sin_port = htons(port); 08808 } else { 08809 /* Don't trust the contact field. Just use what they came to us 08810 with */ 08811 peer->addr = pvt->recv; 08812 } 08813 08814 /* Save SIP options profile */ 08815 peer->sipoptions = pvt->sipoptions; 08816 08817 if (curi && ast_strlen_zero(peer->username)) 08818 ast_copy_string(peer->username, curi, sizeof(peer->username)); 08819 08820 if (!AST_SCHED_DEL(sched, peer->expire)) { 08821 struct sip_peer *peer_ptr = peer; 08822 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08823 } 08824 if (expiry > max_expiry) 08825 expiry = max_expiry; 08826 if (expiry < min_expiry) 08827 expiry = min_expiry; 08828 if (ast_test_flag(&peer->flags[0], SIP_REALTIME) && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 08829 peer->expire = -1; 08830 } else { 08831 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08832 if (peer->expire == -1) { 08833 struct sip_peer *peer_ptr = peer; 08834 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08835 } 08836 } 08837 pvt->expiry = expiry; 08838 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); 08839 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08840 ast_db_put("SIP/Registry", peer->name, data); 08841 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08842 08843 /* Is this a new IP address for us? */ 08844 if (option_verbose > 2 && inaddrcmp(&peer->addr, &oldsin)) { 08845 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)); 08846 } 08847 sip_poke_peer(peer); 08848 register_peer_exten(peer, 1); 08849 08850 /* Save User agent */ 08851 useragent = get_header(req, "User-Agent"); 08852 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 08853 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 08854 if (option_verbose > 3) 08855 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 08856 } 08857 return PARSE_REGISTER_UPDATE; 08858 }
static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 5085 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, option_debug, SIP_MAX_HEADERS, SIP_MAX_LINES, and sipdebug.
Referenced by initialize_initreq(), parse_copy(), and sipsock_read().
05086 { 05087 /* Divide fields by NULL's */ 05088 char *c; 05089 int f = 0; 05090 05091 c = req->data; 05092 05093 /* First header starts immediately */ 05094 req->header[f] = c; 05095 while(*c) { 05096 if (*c == '\n') { 05097 /* We've got a new header */ 05098 *c = 0; 05099 05100 if (sipdebug && option_debug > 3) 05101 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 05102 if (ast_strlen_zero(req->header[f])) { 05103 /* Line by itself means we're now in content */ 05104 c++; 05105 break; 05106 } 05107 if (f >= SIP_MAX_HEADERS - 1) { 05108 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 05109 } else { 05110 f++; 05111 req->header[f] = c + 1; 05112 } 05113 } else if (*c == '\r') { 05114 /* Ignore but eliminate \r's */ 05115 *c = 0; 05116 } 05117 c++; 05118 } 05119 05120 req->headers = f; 05121 05122 /* Check a non-newline-terminated last header */ 05123 if (!ast_strlen_zero(req->header[f])) { 05124 if (sipdebug && option_debug > 3) 05125 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 05126 req->headers++; 05127 } 05128 05129 /* Now we process any body content */ 05130 f = 0; 05131 req->line[f] = c; 05132 while (*c) { 05133 if (*c == '\n') { 05134 /* We've got a new line */ 05135 *c = 0; 05136 if (sipdebug && option_debug > 3) 05137 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 05138 if (f == SIP_MAX_LINES - 1) { 05139 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 05140 break; 05141 } else { 05142 f++; 05143 req->line[f] = c + 1; 05144 } 05145 } else if (*c == '\r') { 05146 /* Ignore and eliminate \r's */ 05147 *c = 0; 05148 } 05149 c++; 05150 } 05151 05152 req->lines = f; 05153 05154 /* Check a non-newline-terminated last line */ 05155 if (!ast_strlen_zero(req->line[f])) { 05156 if (sipdebug && option_debug > 3) 05157 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 05158 req->lines++; 05159 } 05160 05161 if (*c) 05162 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 05163 05164 /* Split up the first line parts */ 05165 return determine_firstline_parts(req); 05166 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 1754 of file chan_sip.c.
References ast_log(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), FALSE, LOG_DEBUG, sip_request::next, option_debug, sip_options, sipdebug, sip_pvt::sipoptions, text, and TRUE.
Referenced by handle_request_invite().
01755 { 01756 char *next, *sep; 01757 char *temp; 01758 unsigned int profile = 0; 01759 int i, found; 01760 01761 if (ast_strlen_zero(supported) ) 01762 return 0; 01763 temp = ast_strdupa(supported); 01764 01765 if (option_debug > 2 && sipdebug) 01766 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01767 01768 for (next = temp; next; next = sep) { 01769 found = FALSE; 01770 if ( (sep = strchr(next, ',')) != NULL) 01771 *sep++ = '\0'; 01772 next = ast_skip_blanks(next); 01773 if (option_debug > 2 && sipdebug) 01774 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01775 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01776 if (!strcasecmp(next, sip_options[i].text)) { 01777 profile |= sip_options[i].id; 01778 found = TRUE; 01779 if (option_debug > 2 && sipdebug) 01780 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01781 break; 01782 } 01783 } 01784 if (!found && option_debug > 2 && sipdebug) { 01785 if (!strncasecmp(next, "x-", 2)) 01786 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01787 else 01788 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01789 } 01790 } 01791 01792 if (pvt) 01793 pvt->sipoptions = profile; 01794 return profile; 01795 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Report Peer status in character string.
Definition at line 10601 of file chan_sip.c.
References ast_copy_string(), sip_peer::lastms, and sip_peer::maxms.
10602 { 10603 int res = 0; 10604 if (peer->maxms) { 10605 if (peer->lastms < 0) { 10606 ast_copy_string(status, "UNREACHABLE", statuslen); 10607 } else if (peer->lastms > peer->maxms) { 10608 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 10609 res = 1; 10610 } else if (peer->lastms) { 10611 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 10612 res = 1; 10613 } else { 10614 ast_copy_string(status, "UNKNOWN", statuslen); 10615 } 10616 } else { 10617 ast_copy_string(status, "Unmonitored", statuslen); 10618 /* Checking if port is 0 */ 10619 res = -1; 10620 } 10621 return res; 10622 }
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 11069 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().
11070 { 11071 int x, codec; 11072 11073 for(x = 0; x < 32 ; x++) { 11074 codec = ast_codec_pref_index(pref, x); 11075 if (!codec) 11076 break; 11077 ast_cli(fd, "%s", ast_getformatname(codec)); 11078 ast_cli(fd, ":%d", pref->framing[x]); 11079 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 11080 ast_cli(fd, ","); 11081 } 11082 if (!x) 11083 ast_cli(fd, "none"); 11084 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 10860 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
10861 { 10862 char buf[256]; 10863 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 10864 }
static void process_request_queue | ( | struct sip_pvt * | p, | |
int * | recount, | |||
int * | nounlock | |||
) | [static] |
Definition at line 16649 of file chan_sip.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_log(), handle_request(), LOG_DEBUG, sip_request::next, option_debug, and sip_pvt::request_queue.
Referenced by sipsock_read().
16650 { 16651 struct sip_request *req; 16652 16653 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 16654 if (handle_request(p, req, &p->recv, recount, nounlock) == -1) { 16655 /* Request failed */ 16656 if (option_debug) { 16657 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 16658 } 16659 } 16660 ast_free(req); 16661 } 16662 }
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
< 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 5357 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_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, len(), LOG_DEBUG, LOG_ERROR, LOG_NOTICE, sip_pvt::mohsuggest, ast_channel::name, 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, TRUE, type, sip_pvt::udptl, sip_pvt::vrtp, and ast_channel::writeformat.
05358 { 05359 /* Iterators for SDP parsing */ 05360 int start = req->sdp_start; 05361 int next = start; 05362 int iterator = start; 05363 05364 /* Temporary vars for SDP parsing */ 05365 char type = '\0'; 05366 const char *value = NULL; 05367 const char *m = NULL; /* SDP media offer */ 05368 const char *nextm = NULL; 05369 int len = -1; 05370 05371 /* Host information */ 05372 struct ast_hostent audiohp; 05373 struct ast_hostent videohp; 05374 struct ast_hostent sessionhp; 05375 struct hostent *hp = NULL; /*!< RTP Audio host IP */ 05376 struct hostent *vhp = NULL; /*!< RTP video host IP */ 05377 int portno = -1; /*!< RTP Audio port number */ 05378 int vportno = -1; /*!< RTP Video port number */ 05379 int udptlportno = -1; /*!< UDPTL Image port number */ 05380 struct sockaddr_in sin; /*!< media socket address */ 05381 struct sockaddr_in vsin; /*!< video socket address */ 05382 struct sockaddr_in isin; /*!< image socket address */ 05383 05384 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 05385 int peercapability = 0, peernoncodeccapability = 0; 05386 int vpeercapability = 0, vpeernoncodeccapability = 0; 05387 struct ast_rtp *newaudiortp, *newvideortp; /*!< Buffers for codec handling */ 05388 int newjointcapability; /*!< Negotiated capability */ 05389 int newpeercapability; 05390 int newnoncodeccapability; 05391 const char *codecs; 05392 int codec; 05393 05394 /* Others */ 05395 int sendonly = -1; 05396 int vsendonly = -1; 05397 int numberofports; 05398 int numberofmediastreams = 0; 05399 int last_rtpmap_codec = 0; 05400 int debug = sip_debug_test_pvt(p); 05401 05402 /* Initial check */ 05403 if (!p->rtp) { 05404 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 05405 return -1; 05406 } 05407 05408 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 05409 #ifdef LOW_MEMORY 05410 newaudiortp = ast_threadstorage_get(&ts_audio_rtp, ast_rtp_alloc_size()); 05411 #else 05412 newaudiortp = alloca(ast_rtp_alloc_size()); 05413 #endif 05414 memset(newaudiortp, 0, ast_rtp_alloc_size()); 05415 ast_rtp_new_init(newaudiortp); 05416 ast_rtp_pt_clear(newaudiortp); 05417 05418 #ifdef LOW_MEMORY 05419 newvideortp = ast_threadstorage_get(&ts_video_rtp, ast_rtp_alloc_size()); 05420 #else 05421 newvideortp = alloca(ast_rtp_alloc_size()); 05422 #endif 05423 memset(newvideortp, 0, ast_rtp_alloc_size()); 05424 ast_rtp_new_init(newvideortp); 05425 ast_rtp_pt_clear(newvideortp); 05426 05427 05428 /* Update our last rtprx when we receive an SDP, too */ 05429 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 05430 05431 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 05432 05433 memset(p->offered_media, 0, sizeof(p->offered_media)); 05434 05435 05436 /* Scan for the first media stream (m=) line to limit scanning of globals */ 05437 nextm = get_sdp_iterate(&next, req, "m"); 05438 if (ast_strlen_zero(nextm)) { 05439 ast_log(LOG_WARNING, "Insufficient information for SDP (m= not found)\n"); 05440 return -1; 05441 } 05442 05443 /* Scan session level SDP parameters (lines before first media stream) */ 05444 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 05445 int processed = FALSE; 05446 switch (type) { 05447 case 'c': 05448 if (process_sdp_c(value, &sessionhp)) { 05449 processed = TRUE; 05450 hp = &sessionhp.hp; 05451 vhp = hp; 05452 } 05453 break; 05454 case 'a': 05455 if (process_sdp_a_sendonly(value, &sendonly)) { 05456 processed = TRUE; 05457 vsendonly = sendonly; 05458 } 05459 else if (process_sdp_a_audio(value, p, newaudiortp, &last_rtpmap_codec)) 05460 processed = TRUE; 05461 else if (process_sdp_a_video(value, p, newvideortp, &last_rtpmap_codec)) 05462 processed = TRUE; 05463 else if (process_sdp_a_image(value, p)) 05464 processed = TRUE; 05465 break; 05466 } 05467 05468 if (option_debug > 2) 05469 ast_log(LOG_DEBUG, "Processing session-level SDP %c=%s... %s\n", type, value, (processed == TRUE)? "OK." : "UNSUPPORTED."); 05470 } 05471 05472 05473 /* Scan media stream (m=) specific parameters loop */ 05474 while (!ast_strlen_zero(nextm)) { 05475 int audio = FALSE; 05476 int video = FALSE; 05477 int image = FALSE; 05478 int x; 05479 05480 numberofports = 1; 05481 len = -1; 05482 start = next; 05483 m = nextm; 05484 iterator = next; 05485 nextm = get_sdp_iterate(&next, req, "m"); 05486 05487 /* Search for audio media definition */ 05488 if ((sscanf(m, "audio %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05489 (sscanf(m, "audio %30d RTP/AVP %n", &x, &len) == 1 && len > 0)) { 05490 /* Found audio stream in this media definition */ 05491 audio = TRUE; 05492 p->offered_media[SDP_AUDIO].offered = TRUE; 05493 numberofmediastreams++; 05494 portno = x; 05495 05496 /* Scan through the RTP payload types specified in a "m=" line: */ 05497 codecs = m + len; 05498 ast_copy_string(p->offered_media[SDP_AUDIO].text, codecs, sizeof(p->offered_media[SDP_AUDIO].text)); 05499 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05500 if (sscanf(codecs, "%30d%n", &codec, &len) != 1) { 05501 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05502 return -1; 05503 } 05504 if (debug) 05505 ast_verbose("Found RTP audio format %d\n", codec); 05506 ast_rtp_set_m_type(newaudiortp, codec); 05507 } 05508 /* Search for video media definition */ 05509 } else if ((sscanf(m, "video %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05510 (sscanf(m, "video %30d RTP/AVP %n", &x, &len) == 1 && len >= 0)) { 05511 /* Found video stream in this media definition */ 05512 video = TRUE; 05513 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 05514 p->offered_media[SDP_VIDEO].offered = TRUE; 05515 numberofmediastreams++; 05516 vportno = x; 05517 05518 /* Scan through the RTP payload types specified in a "m=" line: */ 05519 codecs = m + len; 05520 ast_copy_string(p->offered_media[SDP_VIDEO].text, codecs, sizeof(p->offered_media[SDP_VIDEO].text)); 05521 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05522 if (sscanf(codecs, "%30d%n", &codec, &len) != 1) { 05523 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05524 return -1; 05525 } 05526 if (debug) 05527 ast_verbose("Found RTP video format %d\n", codec); 05528 ast_rtp_set_m_type(newvideortp, codec); 05529 } 05530 /* Search for image media definition */ 05531 } else if (p->udptl && ((sscanf(m, "image %30d udptl t38%n", &x, &len) == 1 && len > 0) || 05532 (sscanf(m, "image %30d UDPTL t38%n", &x, &len) == 1 && len >= 0))) { 05533 /* Found image stream in this media definition */ 05534 image = TRUE; 05535 if (debug) 05536 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 05537 p->offered_media[SDP_IMAGE].offered = TRUE; 05538 udptlportno = x; 05539 numberofmediastreams++; 05540 05541 if (p->owner && p->lastinvite) { 05542 if (p->t38.state != T38_LOCAL_REINVITE) { 05543 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 05544 if (option_debug > 1) 05545 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 05546 } 05547 } else { 05548 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 05549 p->t38.direct = 1; 05550 if (option_debug > 1) 05551 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05552 } 05553 } else { 05554 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 05555 continue; 05556 } 05557 05558 /* Check for number of ports */ 05559 if (numberofports > 1) 05560 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 05561 05562 05563 05564 /* Media stream specific parameters */ 05565 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 05566 int processed = FALSE; 05567 05568 switch (type) { 05569 case 'c': 05570 if (audio) { 05571 if (process_sdp_c(value, &audiohp)) { 05572 processed = TRUE; 05573 hp = &audiohp.hp; 05574 } 05575 } 05576 else if (video) { 05577 if (process_sdp_c(value, &videohp)) { 05578 processed = TRUE; 05579 vhp = &videohp.hp; 05580 } 05581 } 05582 break; 05583 case 'a': 05584 /* Audio specific scanning */ 05585 if (audio) { 05586 if (process_sdp_a_sendonly(value, &sendonly)) 05587 processed = TRUE; 05588 else if (process_sdp_a_audio(value, p, newaudiortp, &last_rtpmap_codec)) 05589 processed = TRUE; 05590 } 05591 /* Video specific scanning */ 05592 else if (video) { 05593 if (process_sdp_a_sendonly(value, &vsendonly)) 05594 processed = TRUE; 05595 else if (process_sdp_a_video(value, p, newvideortp, &last_rtpmap_codec)) 05596 processed = TRUE; 05597 } 05598 /* Image (T.38 FAX) specific scanning */ 05599 else if (image) { 05600 if (process_sdp_a_image(value, p)) 05601 processed = TRUE; 05602 } 05603 break; 05604 } 05605 05606 if (option_debug > 2) 05607 ast_log(LOG_DEBUG, "Processing media-level (%s) SDP %c=%s... %s\n", 05608 (audio == TRUE)? "audio" : (video == TRUE)? "video" : "image", 05609 type, value, 05610 (processed == TRUE)? "OK." : "UNSUPPORTED."); 05611 } 05612 } 05613 05614 /* Sanity checks */ 05615 if (!hp && !vhp) { 05616 ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n"); 05617 return -1; 05618 } 05619 05620 if (portno == -1 && vportno == -1 && udptlportno == -1) 05621 /* No acceptable offer found in SDP - we have no ports */ 05622 /* Do not change RTP or VRTP if this is a re-invite */ 05623 return -2; 05624 05625 if (numberofmediastreams > 2) 05626 /* We have too many fax, audio and/or video media streams, fail this offer */ 05627 return -3; 05628 05629 if (udptlportno == -1) { 05630 p->t38.state = T38_DISABLED; 05631 if (option_debug > 2) 05632 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05633 } 05634 05635 05636 /* Now gather all of the codecs that we are asked for: */ 05637 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05638 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05639 05640 newjointcapability = p->capability & (peercapability | vpeercapability); 05641 newpeercapability = (peercapability | vpeercapability); 05642 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05643 05644 05645 if (debug) { 05646 /* shame on whoever coded this.... */ 05647 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE]; 05648 05649 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05650 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 05651 ast_getformatname_multiple(s2, SIPBUFSIZE, newpeercapability), 05652 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 05653 ast_getformatname_multiple(s4, SIPBUFSIZE, newjointcapability)); 05654 05655 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05656 ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0), 05657 ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0), 05658 ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0)); 05659 05660 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 05661 p->t38.capability, 05662 p->t38.peercapability, 05663 p->t38.jointcapability); 05664 05665 } 05666 if (!newjointcapability) { 05667 /* If T.38 was not negotiated either, totally bail out... */ 05668 if (!p->t38.jointcapability || !udptlportno) { 05669 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05670 /* Do NOT Change current setting */ 05671 return -1; 05672 } else { 05673 if (option_debug > 2) 05674 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05675 } 05676 } 05677 05678 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05679 they are acceptable */ 05680 p->jointcapability = newjointcapability; /* Our joint codec profile */ 05681 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05682 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05683 05684 ast_rtp_pt_copy(p->rtp, newaudiortp); 05685 if (p->vrtp) 05686 ast_rtp_pt_copy(p->vrtp, newvideortp); 05687 05688 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05689 ast_clear_flag(&p->flags[0], SIP_DTMF); 05690 if (newnoncodeccapability & AST_RTP_DTMF) { 05691 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05692 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05693 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05694 ast_rtp_setdtmf(p->rtp, 1); 05695 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05696 } else { 05697 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05698 } 05699 } 05700 05701 /* Setup audio port number */ 05702 if (p->rtp) { 05703 if (portno > 0) { 05704 sin.sin_family = AF_INET; 05705 sin.sin_port = htons(portno); 05706 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 05707 ast_rtp_set_peer(p->rtp, &sin); 05708 if (debug) 05709 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05710 } else if (udptlportno > 0) { 05711 if (debug) 05712 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n"); 05713 } else { 05714 ast_rtp_stop(p->rtp); 05715 if (debug) 05716 ast_verbose("Peer doesn't provide audio\n"); 05717 } 05718 } 05719 05720 /* Setup video port number */ 05721 if (p->vrtp) { 05722 if (vportno > 0) { 05723 vsin.sin_family = AF_INET; 05724 vsin.sin_port = htons(vportno); 05725 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 05726 ast_rtp_set_peer(p->vrtp, &vsin); 05727 if (debug) 05728 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05729 } else { 05730 ast_rtp_stop(p->vrtp); 05731 if (debug) 05732 ast_verbose("Peer doesn't provide video\n"); 05733 } 05734 } 05735 05736 /* Setup image port number */ 05737 if (p->udptl) { 05738 if (udptlportno > 0) { 05739 isin.sin_family = AF_INET; 05740 isin.sin_port = htons(udptlportno); 05741 if (ast_test_flag(&p->flags[0], SIP_NAT) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 05742 struct sockaddr_in peer = { 0, }; 05743 ast_rtp_get_peer(p->rtp, &peer); 05744 if (peer.sin_addr.s_addr) { 05745 memcpy(&isin.sin_addr, &peer.sin_addr, sizeof(isin.sin_addr)); 05746 if (debug) 05747 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)); 05748 } 05749 } else 05750 memcpy(&isin.sin_addr, hp->h_addr, sizeof(isin.sin_addr)); 05751 ast_udptl_set_peer(p->udptl, &isin); 05752 if (debug) 05753 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(isin.sin_addr), ntohs(isin.sin_port)); 05754 } else { 05755 ast_udptl_stop(p->udptl); 05756 if (debug) 05757 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 05758 } 05759 } 05760 05761 05762 /* Ok, we're going with this offer */ 05763 if (option_debug > 1) { 05764 char buf[SIPBUFSIZE]; 05765 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 05766 } 05767 05768 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05769 return 0; 05770 05771 if (option_debug > 3) 05772 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05773 05774 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05775 if (debug) { 05776 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 05777 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05778 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 05779 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 05780 } 05781 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05782 ast_set_read_format(p->owner, p->owner->readformat); 05783 ast_set_write_format(p->owner, p->owner->writeformat); 05784 } 05785 05786 /* sendonly processing */ 05787 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05788 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05789 /* Activate a re-invite */ 05790 ast_queue_frame(p->owner, &ast_null_frame); 05791 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05792 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05793 S_OR(p->mohsuggest, NULL), 05794 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05795 if (sendonly) 05796 ast_rtp_stop(p->rtp); 05797 /* RTCP needs to go ahead, even if we're on hold!!! */ 05798 /* Activate a re-invite */ 05799 ast_queue_frame(p->owner, &ast_null_frame); 05800 } 05801 05802 /* Manager Hold and Unhold events must be generated, if necessary */ 05803 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) 05804 change_hold_state(p, req, FALSE, sendonly); 05805 else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) 05806 change_hold_state(p, req, TRUE, sendonly); 05807 05808 return 0; 05809 }
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 5851 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, 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().
05852 { 05853 int found = FALSE; 05854 int codec; 05855 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05856 int debug = sip_debug_test_pvt(p); 05857 05858 if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 05859 char *tmp = strrchr(a, ':'); 05860 long int framing = 0; 05861 if (tmp) { 05862 tmp++; 05863 framing = strtol(tmp, NULL, 10); 05864 if (framing == LONG_MIN || framing == LONG_MAX) { 05865 framing = 0; 05866 if (option_debug) 05867 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05868 } 05869 } 05870 if (framing && p->autoframing) { 05871 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05872 int codec_n; 05873 int format = 0; 05874 for (codec_n = 0; codec_n < MAX_RTP_PT; codec_n++) { 05875 format = ast_rtp_codec_getformat(codec_n); 05876 if (!format) /* non-codec or not found */ 05877 continue; 05878 if (option_debug) 05879 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05880 ast_codec_pref_setsize(pref, format, framing); 05881 } 05882 ast_rtp_codec_setpref(p->rtp, pref); 05883 } 05884 found = TRUE; 05885 } else if (sscanf(a, "rtpmap: %30u %[^/]/", &codec, mimeSubtype) == 2) { 05886 /* We have a rtpmap to handle */ 05887 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 05888 /* Note: should really look at the 'freq' and '#chans' params too */ 05889 if (ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05890 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) { 05891 if (debug) 05892 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 05893 (*last_rtpmap_codec)++; 05894 found = TRUE; 05895 } 05896 } else { 05897 if (debug) 05898 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 05899 } 05900 05901 if (!found) { 05902 /* Remove this codec since it's an unknown media type for us */ 05903 ast_rtp_unset_m_type(newaudiortp, codec); 05904 if (debug) 05905 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 05906 } 05907 } 05908 05909 return found; 05910 }
static int process_sdp_a_image | ( | const char * | a, | |
struct sip_pvt * | p | |||
) | [static] |
Definition at line 5945 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().
05946 { 05947 int found = FALSE; 05948 char s[256]; 05949 int x; 05950 05951 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05952 if ((sscanf(a, "T38FaxMaxBuffer:%30d", &x) == 1)) { 05953 found = TRUE; 05954 if (option_debug > 2) 05955 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05956 } else if ((sscanf(a, "T38MaxBitRate:%30d", &x) == 1) || (sscanf(a, "T38FaxMaxRate:%30d", &x) == 1)) { 05957 found = TRUE; 05958 if (option_debug > 2) 05959 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05960 switch (x) { 05961 case 14400: 05962 p->t38.peercapability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05963 break; 05964 case 12000: 05965 p->t38.peercapability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05966 break; 05967 case 9600: 05968 p->t38.peercapability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05969 break; 05970 case 7200: 05971 p->t38.peercapability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05972 break; 05973 case 4800: 05974 p->t38.peercapability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05975 break; 05976 case 2400: 05977 p->t38.peercapability |= T38FAX_RATE_2400; 05978 break; 05979 } 05980 } else if ((sscanf(a, "T38FaxVersion:%30d", &x) == 1)) { 05981 found = TRUE; 05982 if (option_debug > 2) 05983 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05984 if (x == 0) 05985 p->t38.peercapability |= T38FAX_VERSION_0; 05986 else if (x == 1) 05987 p->t38.peercapability |= T38FAX_VERSION_1; 05988 } else if ((sscanf(a, "T38FaxMaxDatagram:%30d", &x) == 1) || (sscanf(a, "T38MaxDatagram:%30d", &x) == 1)) { 05989 found = TRUE; 05990 if (option_debug > 2) 05991 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05992 ast_udptl_set_far_max_datagram(p->udptl, x); 05993 ast_udptl_set_local_max_datagram(p->udptl, x); 05994 } else if ((strncmp(a, "T38FaxFillBitRemoval", 20) == 0)) { 05995 found = TRUE; 05996 if ((sscanf(a, "T38FaxFillBitRemoval:%30d", &x) == 1)) { 05997 if (option_debug > 2) 05998 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05999 if (x == 1) 06000 p->t38.peercapability |= T38FAX_FILL_BIT_REMOVAL; 06001 } else { 06002 if (option_debug > 2) 06003 ast_log(LOG_DEBUG, "FillBitRemoval\n"); 06004 p->t38.peercapability |= T38FAX_FILL_BIT_REMOVAL; 06005 } 06006 } else if ((strncmp(a, "T38FaxTranscodingMMR", 20) == 0)) { 06007 found = TRUE; 06008 if ((sscanf(a, "T38FaxTranscodingMMR:%30d", &x) == 1)) { 06009 if (option_debug > 2) 06010 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 06011 if (x == 1) 06012 p->t38.peercapability |= T38FAX_TRANSCODING_MMR; 06013 } else { 06014 if (option_debug > 2) 06015 ast_log(LOG_DEBUG, "Transcoding MMR\n"); 06016 p->t38.peercapability |= T38FAX_TRANSCODING_MMR; 06017 } 06018 } else if ((strncmp(a, "T38FaxTranscodingJBIG", 21) == 0)) { 06019 found = TRUE; 06020 if ((sscanf(a, "T38FaxTranscodingJBIG:%30d", &x) == 1)) { 06021 if (option_debug > 2) 06022 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 06023 if (x == 1) 06024 p->t38.peercapability |= T38FAX_TRANSCODING_JBIG; 06025 } else { 06026 if (option_debug > 2) 06027 ast_log(LOG_DEBUG, "Transcoding JBIG\n"); 06028 p->t38.peercapability |= T38FAX_TRANSCODING_JBIG; 06029 } 06030 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 06031 found = TRUE; 06032 if (option_debug > 2) 06033 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 06034 if (!strcasecmp(s, "localTCF")) 06035 p->t38.peercapability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 06036 else if (!strcasecmp(s, "transferredTCF")) 06037 p->t38.peercapability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 06038 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 06039 found = TRUE; 06040 if (option_debug > 2) 06041 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 06042 if (!strcasecmp(s, "t38UDPRedundancy")) { 06043 p->t38.peercapability |= T38FAX_UDP_EC_REDUNDANCY; 06044 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 06045 } else if (!strcasecmp(s, "t38UDPFEC")) { 06046 p->t38.peercapability |= T38FAX_UDP_EC_FEC; 06047 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 06048 } else { 06049 p->t38.peercapability |= T38FAX_UDP_EC_NONE; 06050 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 06051 } 06052 } 06053 06054 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 06055 int t38speed = p->t38.peercapability & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 06056 06057 p->t38.jointcapability = (p->t38.peercapability & 255); /* Put everything beside supported speeds settings */ 06058 p->t38.jointcapability |= (t38speed & p->t38.capability); /* Put the lower of our's and peer's speed */ 06059 } 06060 06061 return found; 06062 }
static int process_sdp_a_sendonly | ( | const char * | a, | |
int * | sendonly | |||
) | [static] |
Definition at line 5831 of file chan_sip.c.
Referenced by process_sdp().
05832 { 05833 int found = FALSE; 05834 05835 if (!strcasecmp(a, "sendonly")) { 05836 if (*sendonly == -1) 05837 *sendonly = 1; 05838 found = TRUE; 05839 } else if (!strcasecmp(a, "inactive")) { 05840 if (*sendonly == -1) 05841 *sendonly = 2; 05842 found = TRUE; 05843 } else if (!strcasecmp(a, "sendrecv")) { 05844 if (*sendonly == -1) 05845 *sendonly = 0; 05846 found = TRUE; 05847 } 05848 return found; 05849 }
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 5912 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().
05913 { 05914 int found = FALSE; 05915 int codec; 05916 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05917 int debug = sip_debug_test_pvt(p); 05918 05919 if (sscanf(a, "rtpmap: %30u %[^/]/", &codec, mimeSubtype) == 2) { 05920 /* We have a rtpmap to handle */ 05921 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 05922 /* Note: should really look at the 'freq' and '#chans' params too */ 05923 if (p->vrtp && ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) { 05924 if (debug) 05925 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 05926 (*last_rtpmap_codec)++; 05927 found = TRUE; 05928 } 05929 } else { 05930 if (debug) 05931 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 05932 } 05933 05934 if (!found) { 05935 /* Remove this codec since it's an unknown media type for us */ 05936 ast_rtp_unset_m_type(newvideortp, codec); 05937 if (debug) 05938 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 05939 } 05940 } 05941 05942 return found; 05943 }
static int process_sdp_c | ( | const char * | c, | |
struct ast_hostent * | hp | |||
) | [static] |
Definition at line 5812 of file chan_sip.c.
References ast_gethostbyname(), ast_log(), FALSE, hp, and TRUE.
Referenced by process_sdp().
05813 { 05814 char host[258]; 05815 struct hostent *hp; 05816 05817 /* Check for Media-description-level-address */ 05818 if (sscanf(c, "IN IP4 %255s", host) != 1) { 05819 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05820 return FALSE; 05821 } else { 05822 if (!(hp = ast_gethostbyname(host, ast_hp))) { 05823 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in c= line, '%s'\n", c); 05824 return FALSE; 05825 } 05826 return TRUE; 05827 } 05828 return FALSE; 05829 }
static int queue_request | ( | struct sip_pvt * | p, | |
const struct sip_request * | req | |||
) | [static] |
Definition at line 16714 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, ast_sched_add(), copy_request(), sip_request::next, sip_pvt::request_queue, sip_pvt::request_queue_sched_id, sched, and scheduler_process_request_queue().
Referenced by sipsock_read().
16715 { 16716 struct sip_request *newreq; 16717 16718 if (!(newreq = ast_calloc(1, sizeof(*newreq)))) { 16719 return -1; 16720 } 16721 16722 copy_request(newreq, req); 16723 AST_LIST_INSERT_TAIL(&p->request_queue, newreq, next); 16724 if (p->request_queue_sched_id == -1) { 16725 p->request_queue_sched_id = ast_sched_add(sched, 10, scheduler_process_request_queue, p); 16726 } 16727 16728 return 0; 16729 }
static struct sip_peer * realtime_peer | ( | const char * | newpeername, | |
struct sockaddr_in * | sin, | |||
int | devstate_only | |||
) | [static] |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
Definition at line 2642 of file chan_sip.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), sip_request::flags, hp, ast_variable::name, ast_variable::next, ast_variable::value, and var.
02643 { 02644 struct sip_peer *peer=NULL; 02645 struct ast_variable *var = NULL; 02646 struct ast_config *peerlist = NULL; 02647 struct ast_variable *tmp; 02648 struct ast_flags flags = {0}; 02649 const char *iabuf = NULL; 02650 char portstring[6]; /*up to five digits plus null terminator*/ 02651 const char *insecure; 02652 char *cat = NULL; 02653 unsigned short portnum; 02654 02655 /* First check on peer name */ 02656 if (newpeername) { 02657 var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL); 02658 if (!var && sin) 02659 var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02660 if (!var) { 02661 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02662 /*!\note 02663 * If this one loaded something, then we need to ensure that the host 02664 * field matched. The only reason why we can't have this as a criteria 02665 * is because we only have the IP address and the host field might be 02666 * set as a name (and the reverse PTR might not match). 02667 */ 02668 if (var && sin) { 02669 for (tmp = var; tmp; tmp = tmp->next) { 02670 if (!strcasecmp(tmp->name, "host")) { 02671 struct hostent *hp; 02672 struct ast_hostent ahp; 02673 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02674 /* No match */ 02675 ast_variables_destroy(var); 02676 var = NULL; 02677 } 02678 break; 02679 } 02680 } 02681 } 02682 } 02683 } 02684 02685 if (!var && sin) { /* Then check on IP address */ 02686 iabuf = ast_inet_ntoa(sin->sin_addr); 02687 portnum = ntohs(sin->sin_port); 02688 sprintf(portstring, "%d", portnum); 02689 var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */ 02690 if (!var) 02691 var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL); /* Then check for registered hosts */ 02692 if (!var) { 02693 peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/ 02694 if(peerlist){ 02695 while((cat = ast_category_browse(peerlist, cat))) 02696 { 02697 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02698 set_insecure_flags(&flags, insecure, -1); 02699 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02700 var = ast_category_root(peerlist, cat); 02701 break; 02702 } 02703 } 02704 } 02705 if(!var) { 02706 ast_config_destroy(peerlist); 02707 peerlist = NULL; /*for safety's sake*/ 02708 cat = NULL; 02709 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/ 02710 if(peerlist) { 02711 while((cat = ast_category_browse(peerlist, cat))) 02712 { 02713 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02714 set_insecure_flags(&flags, insecure, -1); 02715 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02716 var = ast_category_root(peerlist, cat); 02717 break; 02718 } 02719 } 02720 } 02721 } 02722 } 02723 } 02724 02725 if (!var) { 02726 if(peerlist) 02727 ast_config_destroy(peerlist); 02728 return NULL; 02729 } 02730 02731 for (tmp = var; tmp; tmp = tmp->next) { 02732 /* If this is type=user, then skip this object. */ 02733 if (!strcasecmp(tmp->name, "type") && 02734 !strcasecmp(tmp->value, "user")) { 02735 ast_variables_destroy(var); 02736 return NULL; 02737 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02738 newpeername = tmp->value; 02739 } else if (!strcasecmp(tmp->name, "lastms")) { 02740 seen_lastms = 1; 02741 } 02742 } 02743 02744 if (!newpeername) { /* Did not find peer in realtime */ 02745 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 02746 if(peerlist) 02747 ast_config_destroy(peerlist); 02748 else 02749 ast_variables_destroy(var); 02750 return NULL; 02751 } 02752 02753 /* Peer found in realtime, now build it in memory */ 02754 peer = build_peer(newpeername, var, NULL, 1, devstate_only); 02755 if (!peer) { 02756 if(peerlist) 02757 ast_config_destroy(peerlist); 02758 else 02759 ast_variables_destroy(var); 02760 return NULL; 02761 } 02762 02763 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) { 02764 /* Cache peer */ 02765 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02766 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02767 if (!AST_SCHED_DEL(sched, peer->expire)) { 02768 struct sip_peer *peer_ptr = peer; 02769 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02770 } 02771 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, ASTOBJ_REF(peer)); 02772 if (peer->expire == -1) { 02773 struct sip_peer *peer_ptr = peer; 02774 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02775 } 02776 } 02777 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02778 } 02779 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02780 if(peerlist) 02781 ast_config_destroy(peerlist); 02782 else 02783 ast_variables_destroy(var); 02784 return peer; 02785 }
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 2521 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(), global_flags, ipaddr, and SIP_PAGE2_RTSAVE_SYSNAME.
02522 { 02523 char port[10]; 02524 char ipaddr[INET_ADDRSTRLEN]; 02525 char regseconds[20]; 02526 char str_lastms[20]; 02527 02528 char *sysname = ast_config_AST_SYSTEM_NAME; 02529 char *syslabel = NULL; 02530 02531 time_t nowtime = time(NULL) + expirey; 02532 const char *fc = fullcontact ? "fullcontact" : NULL; 02533 02534 snprintf(str_lastms, sizeof(str_lastms), "%d", lastms); 02535 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02536 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02537 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02538 02539 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02540 sysname = NULL; 02541 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02542 syslabel = "regserver"; 02543 02544 if (fc) 02545 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02546 "port", port, "regseconds", regseconds, 02547 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02548 else 02549 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02550 "port", port, "regseconds", regseconds, 02551 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02552 if (seen_lastms) { 02553 /* We cannot do this in the same statement as above, because the lack of 02554 * this field could cause the whole statement to fail. */ 02555 ast_update_realtime("sippeers", "name", peername, "lastms", str_lastms, NULL); 02556 } 02557 }
static struct sip_user * realtime_user | ( | const char * | username | ) | [static] |
Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped).
Definition at line 2835 of file chan_sip.c.
References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
02836 { 02837 struct ast_variable *var; 02838 struct ast_variable *tmp; 02839 struct sip_user *user = NULL; 02840 02841 var = ast_load_realtime("sipusers", "name", username, NULL); 02842 02843 if (!var) 02844 return NULL; 02845 02846 for (tmp = var; tmp; tmp = tmp->next) { 02847 if (!strcasecmp(tmp->name, "type") && 02848 !strcasecmp(tmp->value, "peer")) { 02849 ast_variables_destroy(var); 02850 return NULL; 02851 } 02852 } 02853 02854 user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02855 02856 if (!user) { /* No user found */ 02857 ast_variables_destroy(var); 02858 return NULL; 02859 } 02860 02861 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02862 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02863 suserobjs++; 02864 ASTOBJ_CONTAINER_LINK(&userl,user); 02865 } else { 02866 /* Move counter from s to r... */ 02867 suserobjs--; 02868 ruserobjs++; 02869 } 02870 ast_set_flag(&user->flags[0], SIP_REALTIME); 02871 ast_variables_destroy(var); 02872 return user; 02873 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 10484 of file chan_sip.c.
References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose(), sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, f, get_header(), get_msg_text(), sip_pvt::owner, sip_debug_test_pvt(), sip_scheddestroy(), and transmit_response().
Referenced by handle_request_message().
10485 { 10486 char buf[1024]; 10487 struct ast_frame f; 10488 const char *content_type = get_header(req, "Content-Type"); 10489 10490 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 10491 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 10492 if (!p->owner) 10493 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10494 return; 10495 } 10496 10497 if (get_msg_text(buf, sizeof(buf), req)) { 10498 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 10499 transmit_response(p, "202 Accepted", req); 10500 if (!p->owner) 10501 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10502 return; 10503 } 10504 10505 if (p->owner) { 10506 if (sip_debug_test_pvt(p)) 10507 ast_verbose("Message received: '%s'\n", buf); 10508 memset(&f, 0, sizeof(f)); 10509 f.frametype = AST_FRAME_TEXT; 10510 f.subclass = 0; 10511 f.offset = 0; 10512 f.data = buf; 10513 f.datalen = strlen(buf); 10514 ast_queue_frame(p->owner, &f); 10515 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 10516 } else { /* Message outside of a call, we do not support that */ 10517 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); 10518 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 10519 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10520 } 10521 return; 10522 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1689 of file chan_sip.c.
References referstatusstrings, and text.
Referenced by __sip_show_channels().
01690 { 01691 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01692 int x; 01693 01694 for (x = 0; x < i; x++) { 01695 if (referstatusstrings[x].status == rstatus) 01696 return (char *) referstatusstrings[x].text; 01697 } 01698 return ""; 01699 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 8526 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_peer::expire, expire_register(), sip_peer::flags, sip_peer::fullcontact, LOG_DEBUG, sip_peer::name, option_debug, sip_peer::pokeexpire, register_peer_exten(), sched, sip_destroy_peer(), SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, TRUE, sip_peer::username, and username.
08527 { 08528 char data[256]; 08529 struct in_addr in; 08530 int expiry; 08531 int port; 08532 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 08533 08534 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08535 return; 08536 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 08537 return; 08538 08539 scan = data; 08540 addr = strsep(&scan, ":"); 08541 port_str = strsep(&scan, ":"); 08542 expiry_str = strsep(&scan, ":"); 08543 username = strsep(&scan, ":"); 08544 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 08545 08546 if (!inet_aton(addr, &in)) 08547 return; 08548 08549 if (port_str) 08550 port = atoi(port_str); 08551 else 08552 return; 08553 08554 if (expiry_str) 08555 expiry = atoi(expiry_str); 08556 else 08557 return; 08558 08559 if (username) 08560 ast_copy_string(peer->username, username, sizeof(peer->username)); 08561 if (contact) 08562 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 08563 08564 if (option_debug > 1) 08565 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 08566 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 08567 08568 memset(&peer->addr, 0, sizeof(peer->addr)); 08569 peer->addr.sin_family = AF_INET; 08570 peer->addr.sin_addr = in; 08571 peer->addr.sin_port = htons(port); 08572 if (sipsock < 0) { 08573 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 08574 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 08575 struct sip_peer *peer_ptr = peer; 08576 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08577 } 08578 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer)); 08579 if (peer->pokeexpire == -1) { 08580 struct sip_peer *peer_ptr = peer; 08581 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08582 } 08583 } else 08584 sip_poke_peer(peer); 08585 if (!AST_SCHED_DEL(sched, peer->expire)) { 08586 struct sip_peer *peer_ptr = peer; 08587 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08588 } 08589 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08590 if (peer->expire == -1) { 08591 struct sip_peer *peer_ptr = peer; 08592 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08593 } 08594 register_peer_exten(peer, TRUE); 08595 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2560 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, and S_OR.
02561 { 02562 char multi[256]; 02563 char *stringp, *ext, *context; 02564 02565 /* XXX note that global_regcontext is both a global 'enable' flag and 02566 * the name of the global regexten context, if not specified 02567 * individually. 02568 */ 02569 if (ast_strlen_zero(global_regcontext)) 02570 return; 02571 02572 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02573 stringp = multi; 02574 while ((ext = strsep(&stringp, "&"))) { 02575 if ((context = strchr(ext, '@'))) { 02576 *context++ = '\0'; /* split ext@context */ 02577 if (!ast_context_find(context)) { 02578 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02579 continue; 02580 } 02581 } else { 02582 context = global_regcontext; 02583 } 02584 if (onoff) { 02585 if (!ast_exists_extension(NULL, context, ext, 1, NULL)) { 02586 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02587 ast_strdup(peer->name), ast_free_ptr, "SIP"); 02588 } 02589 } else { 02590 ast_context_remove_extension(context, ext, 1, NULL); 02591 } 02592 } 02593 }
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 9349 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_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, 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, 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, t, temp_peer(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), update_peer(), and XMIT_UNRELIABLE.
09351 { 09352 enum check_auth_result res = AUTH_NOT_FOUND; 09353 struct sip_peer *peer; 09354 char tmp[256]; 09355 char *name, *c; 09356 char *t; 09357 char *domain; 09358 09359 /* Terminate URI */ 09360 t = uri; 09361 while(*t && (*t > 32) && (*t != ';')) 09362 t++; 09363 *t = '\0'; 09364 09365 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 09366 if (pedanticsipchecking) 09367 ast_uri_decode(tmp); 09368 09369 c = get_in_brackets(tmp); 09370 c = strsep(&c, ";"); /* Ditch ;user=phone */ 09371 09372 if (!strncasecmp(c, "sip:", 4)) { 09373 name = c + 4; 09374 } else { 09375 name = c; 09376 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 09377 } 09378 09379 /* Strip off the domain name */ 09380 if ((c = strchr(name, '@'))) { 09381 *c++ = '\0'; 09382 domain = c; 09383 if ((c = strchr(domain, ':'))) /* Remove :port */ 09384 *c = '\0'; 09385 if (!AST_LIST_EMPTY(&domain_list)) { 09386 if (!check_sip_domain(domain, NULL, 0)) { 09387 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 09388 return AUTH_UNKNOWN_DOMAIN; 09389 } 09390 } 09391 } 09392 09393 ast_string_field_set(p, exten, name); 09394 build_contact(p); 09395 peer = find_peer(name, NULL, 1, 0); 09396 if (!(peer && ast_apply_ha(peer->ha, sin))) { 09397 /* Peer fails ACL check */ 09398 if (peer) { 09399 ASTOBJ_UNREF(peer, sip_destroy_peer); 09400 res = AUTH_ACL_FAILED; 09401 } else 09402 res = AUTH_NOT_FOUND; 09403 } 09404 if (peer) { 09405 /* Set Frame packetization */ 09406 if (p->rtp) { 09407 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09408 p->autoframing = peer->autoframing; 09409 } 09410 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 09411 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 09412 res = AUTH_PEER_NOT_DYNAMIC; 09413 } else { 09414 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 09415 transmit_response(p, "100 Trying", req); 09416 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09417 if (sip_cancel_destroy(p)) 09418 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09419 09420 /* We have a succesful registration attemp with proper authentication, 09421 now, update the peer */ 09422 switch (parse_register_contact(p, peer, req)) { 09423 case PARSE_REGISTER_DENIED: 09424 transmit_response_with_date(p, "603 Denied", req); 09425 peer->lastmsgssent = -1; 09426 res = 0; 09427 break; 09428 case PARSE_REGISTER_FAILED: 09429 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 09430 transmit_response_with_date(p, "400 Bad Request", req); 09431 peer->lastmsgssent = -1; 09432 res = 0; 09433 break; 09434 case PARSE_REGISTER_QUERY: 09435 ast_string_field_set(p, fullcontact, peer->fullcontact); 09436 transmit_response_with_date(p, "200 OK", req); 09437 peer->lastmsgssent = -1; 09438 res = 0; 09439 break; 09440 case PARSE_REGISTER_UPDATE: 09441 ast_string_field_set(p, fullcontact, peer->fullcontact); 09442 update_peer(peer, p->expiry); 09443 /* Say OK and ask subsystem to retransmit msg counter */ 09444 transmit_response_with_date(p, "200 OK", req); 09445 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 09446 peer->lastmsgssent = -1; 09447 res = 0; 09448 break; 09449 } 09450 } 09451 } 09452 } 09453 if (!peer && autocreatepeer) { 09454 /* Create peer if we have autocreate mode enabled */ 09455 peer = temp_peer(name); 09456 if (peer) { 09457 ASTOBJ_CONTAINER_LINK(&peerl, peer); 09458 if (sip_cancel_destroy(p)) 09459 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09460 switch (parse_register_contact(p, peer, req)) { 09461 case PARSE_REGISTER_DENIED: 09462 ast_log(LOG_WARNING, "Registration denied because of contact ACL\n"); 09463 transmit_response_with_date(p, "403 Forbidden (ACL)", req); 09464 peer->lastmsgssent = -1; 09465 res = 0; 09466 break; 09467 case PARSE_REGISTER_FAILED: 09468 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 09469 transmit_response_with_date(p, "400 Bad Request", req); 09470 peer->lastmsgssent = -1; 09471 res = 0; 09472 break; 09473 case PARSE_REGISTER_QUERY: 09474 ast_string_field_set(p, fullcontact, peer->fullcontact); 09475 transmit_response_with_date(p, "200 OK", req); 09476 peer->lastmsgssent = -1; 09477 res = 0; 09478 break; 09479 case PARSE_REGISTER_UPDATE: 09480 ast_string_field_set(p, fullcontact, peer->fullcontact); 09481 /* Say OK and ask subsystem to retransmit msg counter */ 09482 transmit_response_with_date(p, "200 OK", req); 09483 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 09484 peer->lastmsgssent = -1; 09485 res = 0; 09486 break; 09487 } 09488 } 09489 } 09490 if (!peer && global_alwaysauthreject) { 09491 /* If we found a peer, we transmit a 100 Trying. Therefore, if we're 09492 * trying to avoid leaking information, we MUST also transmit the same 09493 * response when we DON'T find a peer. */ 09494 transmit_response(p, "100 Trying", req); 09495 /* Insert a fake delay between the 100 and the subsequent failure. */ 09496 sched_yield(); 09497 } 09498 if (!res) { 09499 ast_device_state_changed("SIP/%s", peer->name); 09500 } 09501 if (res < 0) { 09502 switch (res) { 09503 case AUTH_SECRET_FAILED: 09504 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 09505 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09506 break; 09507 case AUTH_USERNAME_MISMATCH: 09508 /* Username and digest username does not match. 09509 Asterisk uses the From: username for authentication. We need the 09510 users to use the same authentication user name until we support 09511 proper authentication by digest auth name */ 09512 case AUTH_NOT_FOUND: 09513 case AUTH_PEER_NOT_DYNAMIC: 09514 case AUTH_ACL_FAILED: 09515 if (global_alwaysauthreject) { 09516 transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE); 09517 } else { 09518 /* URI not found */ 09519 if (res == AUTH_PEER_NOT_DYNAMIC) 09520 transmit_response(p, "403 Forbidden", &p->initreq); 09521 else 09522 transmit_response(p, "404 Not found", &p->initreq); 09523 } 09524 break; 09525 default: 09526 break; 09527 } 09528 } 09529 if (peer) 09530 ASTOBJ_UNREF(peer, sip_destroy_peer); 09531 09532 return res; 09533 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | const [static] |
Convert registration state status to string.
Definition at line 7995 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.
07996 { 07997 switch(regstate) { 07998 case REG_STATE_FAILED: 07999 return "Failed"; 08000 case REG_STATE_UNREGISTERED: 08001 return "Unregistered"; 08002 case REG_STATE_REGSENT: 08003 return "Request Sent"; 08004 case REG_STATE_AUTHSENT: 08005 return "Auth. Sent"; 08006 case REG_STATE_REGISTERED: 08007 return "Registered"; 08008 case REG_STATE_REJECTED: 08009 return "Rejected"; 08010 case REG_STATE_TIMEOUT: 08011 return "Timeout"; 08012 case REG_STATE_NOAUTH: 08013 return "No Authentication"; 08014 default: 08015 return "Unknown"; 08016 } 08017 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 19410 of file chan_sip.c.
References sip_reload().
19411 { 19412 return sip_reload(0, 0, NULL); 19413 }
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
Definition at line 18270 of file chan_sip.c.
References ahp, ast_config_load(), ast_free_ha(), ast_log(), AST_MAX_CONTEXT, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, authl, bindaddr, clear_realm_authentication(), clear_sip_domains(), context, FALSE, global_contact_ha, hp, LOG_DEBUG, LOG_NOTICE, option_debug, regl, and sip_destroy().
18271 { 18272 struct ast_config *cfg, *ucfg; 18273 struct ast_variable *v; 18274 struct sip_peer *peer; 18275 struct sip_user *user; 18276 struct ast_hostent ahp; 18277 char *cat, *stringp, *context, *oldregcontext; 18278 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 18279 struct hostent *hp; 18280 int format; 18281 struct ast_flags dummy[2]; 18282 int auto_sip_domains = FALSE; 18283 struct sockaddr_in old_bindaddr = bindaddr; 18284 int registry_count = 0, peer_count = 0, user_count = 0; 18285 unsigned int temp_tos = 0; 18286 struct ast_flags debugflag = {0}; 18287 18288 cfg = ast_config_load(config); 18289 18290 /* We *must* have a config file otherwise stop immediately */ 18291 if (!cfg) { 18292 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 18293 return -1; 18294 } 18295 18296 if (option_debug > 3) 18297 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 18298 18299 clear_realm_authentication(authl); 18300 clear_sip_domains(); 18301 authl = NULL; 18302 18303 ast_free_ha(global_contact_ha); 18304 global_contact_ha = NULL; 18305 18306 /* First, destroy all outstanding registry calls */ 18307 /* This is needed, since otherwise active registry entries will not be destroyed */ 18308 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 18309 ASTOBJ_RDLOCK(iterator); 18310 if (iterator->call) { 18311 if (option_debug > 2) 18312 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 18313 /* This will also remove references to the registry */ 18314 sip_destroy(iterator->call); 18315 } 18316 ASTOBJ_UNLOCK(iterator); 18317 18318 } while(0)); 18319 18320 /* Then, actually destroy users and registry */ 18321 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 18322 if (option_debug > 3) 18323 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 18324 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 18325 if (option_debug > 3) 18326 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 18327 ASTOBJ_CONTAINER_MARKALL(&peerl); 18328 18329 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 18330 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 18331 oldregcontext = oldcontexts; 18332 18333 /* Clear all flags before setting default values */ 18334 /* Preserve debugging settings for console */ 18335 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 18336 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 18337 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 18338 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 18339 18340 /* Reset IP addresses */ 18341 memset(&bindaddr, 0, sizeof(bindaddr)); 18342 ast_free_ha(localaddr); 18343 memset(&localaddr, 0, sizeof(localaddr)); 18344 memset(&externip, 0, sizeof(externip)); 18345 memset(&default_prefs, 0 , sizeof(default_prefs)); 18346 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 18347 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 18348 ourport = STANDARD_SIP_PORT; 18349 srvlookup = DEFAULT_SRVLOOKUP; 18350 global_tos_sip = DEFAULT_TOS_SIP; 18351 global_tos_audio = DEFAULT_TOS_AUDIO; 18352 global_tos_video = DEFAULT_TOS_VIDEO; 18353 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 18354 externexpire = 0; /* Expiration for DNS re-issuing */ 18355 externrefresh = 10; 18356 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 18357 18358 /* Reset channel settings to default before re-configuring */ 18359 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 18360 global_regcontext[0] = '\0'; 18361 expiry = DEFAULT_EXPIRY; 18362 global_notifyringing = DEFAULT_NOTIFYRINGING; 18363 global_limitonpeers = FALSE; 18364 global_prematuremediafilter = FALSE; 18365 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 18366 global_notifyhold = FALSE; 18367 global_alwaysauthreject = 0; 18368 global_allowsubscribe = FALSE; 18369 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 18370 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 18371 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 18372 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 18373 else 18374 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 18375 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 18376 compactheaders = DEFAULT_COMPACTHEADERS; 18377 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 18378 global_regattempts_max = 0; 18379 pedanticsipchecking = DEFAULT_PEDANTIC; 18380 global_mwitime = DEFAULT_MWITIME; 18381 autocreatepeer = DEFAULT_AUTOCREATEPEER; 18382 global_autoframing = 0; 18383 global_allowguest = DEFAULT_ALLOWGUEST; 18384 global_rtptimeout = 0; 18385 global_rtpholdtimeout = 0; 18386 global_rtpkeepalive = 0; 18387 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 18388 global_rtautoclear = 120; 18389 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 18390 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 18391 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 18392 18393 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 18394 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 18395 default_subscribecontext[0] = '\0'; 18396 default_language[0] = '\0'; 18397 default_fromdomain[0] = '\0'; 18398 default_qualify = DEFAULT_QUALIFY; 18399 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 18400 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 18401 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 18402 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 18403 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 18404 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 18405 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 18406 18407 /* Debugging settings, always default to off */ 18408 dumphistory = FALSE; 18409 recordhistory = FALSE; 18410 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 18411 18412 /* Misc settings for the channel */ 18413 global_relaxdtmf = FALSE; 18414 global_callevents = FALSE; 18415 global_t1min = DEFAULT_T1MIN; 18416 global_shrinkcallerid = 1; 18417 18418 global_matchexterniplocally = FALSE; 18419 18420 /* Copy the default jb config over global_jbconf */ 18421 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 18422 18423 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 18424 18425 /* Read the [general] config section of sip.conf (or from realtime config) */ 18426 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 18427 if (handle_common_options(&global_flags[0], &dummy[0], v)) 18428 continue; 18429 /* handle jb conf */ 18430 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 18431 continue; 18432 18433 /* Create the interface list */ 18434 if (!strcasecmp(v->name, "context")) { 18435 ast_copy_string(default_context, v->value, sizeof(default_context)); 18436 } else if (!strcasecmp(v->name, "subscribecontext")) { 18437 ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext)); 18438 } else if (!strcasecmp(v->name, "allowguest")) { 18439 global_allowguest = ast_true(v->value) ? 1 : 0; 18440 } else if (!strcasecmp(v->name, "realm")) { 18441 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 18442 } else if (!strcasecmp(v->name, "useragent")) { 18443 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 18444 if (option_debug) 18445 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 18446 } else if (!strcasecmp(v->name, "allowtransfer")) { 18447 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 18448 } else if (!strcasecmp(v->name, "rtcachefriends")) { 18449 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 18450 } else if (!strcasecmp(v->name, "rtsavesysname")) { 18451 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 18452 } else if (!strcasecmp(v->name, "rtupdate")) { 18453 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 18454 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 18455 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 18456 } else if (!strcasecmp(v->name, "t1min")) { 18457 global_t1min = atoi(v->value); 18458 } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) { 18459 global_dynamic_exclude_static = ast_true(v->value); 18460 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 18461 global_contact_ha = ast_append_ha(v->name + 7, v->value, global_contact_ha); 18462 } else if (!strcasecmp(v->name, "rtautoclear")) { 18463 int i = atoi(v->value); 18464 if (i > 0) 18465 global_rtautoclear = i; 18466 else 18467 i = 0; 18468 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 18469 } else if (!strcasecmp(v->name, "usereqphone")) { 18470 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 18471 } else if (!strcasecmp(v->name, "prematuremedia")) { 18472 global_prematuremediafilter = ast_true(v->value); 18473 } else if (!strcasecmp(v->name, "relaxdtmf")) { 18474 global_relaxdtmf = ast_true(v->value); 18475 } else if (!strcasecmp(v->name, "checkmwi")) { 18476 if ((sscanf(v->value, "%30d", &global_mwitime) != 1) || (global_mwitime < 0)) { 18477 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 18478 global_mwitime = DEFAULT_MWITIME; 18479 } 18480 } else if (!strcasecmp(v->name, "vmexten")) { 18481 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 18482 } else if (!strcasecmp(v->name, "rtptimeout")) { 18483 if ((sscanf(v->value, "%30d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 18484 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 18485 global_rtptimeout = 0; 18486 } 18487 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 18488 if ((sscanf(v->value, "%30d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 18489 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 18490 global_rtpholdtimeout = 0; 18491 } 18492 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 18493 if ((sscanf(v->value, "%30d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 18494 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 18495 global_rtpkeepalive = 0; 18496 } 18497 } else if (!strcasecmp(v->name, "compactheaders")) { 18498 compactheaders = ast_true(v->value); 18499 } else if (!strcasecmp(v->name, "notifymimetype")) { 18500 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 18501 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 18502 global_limitonpeers = ast_true(v->value); 18503 } else if (!strcasecmp(v->name, "directrtpsetup")) { 18504 global_directrtpsetup = ast_true(v->value); 18505 } else if (!strcasecmp(v->name, "notifyringing")) { 18506 global_notifyringing = ast_true(v->value); 18507 } else if (!strcasecmp(v->name, "notifyhold")) { 18508 global_notifyhold = ast_true(v->value); 18509 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 18510 global_alwaysauthreject = ast_true(v->value); 18511 } else if (!strcasecmp(v->name, "mohinterpret") 18512 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 18513 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 18514 } else if (!strcasecmp(v->name, "mohsuggest")) { 18515 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 18516 } else if (!strcasecmp(v->name, "language")) { 18517 ast_copy_string(default_language, v->value, sizeof(default_language)); 18518 } else if (!strcasecmp(v->name, "regcontext")) { 18519 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 18520 stringp = newcontexts; 18521 /* Let's remove any contexts that are no longer defined in regcontext */ 18522 cleanup_stale_contexts(stringp, oldregcontext); 18523 /* Create contexts if they don't exist already */ 18524 while ((context = strsep(&stringp, "&"))) { 18525 if (!ast_context_find(context)) 18526 ast_context_create(NULL, context,"SIP"); 18527 } 18528 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 18529 } else if (!strcasecmp(v->name, "callerid")) { 18530 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 18531 } else if (!strcasecmp(v->name, "fromdomain")) { 18532 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 18533 } else if (!strcasecmp(v->name, "outboundproxy")) { 18534 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 18535 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 18536 } else if (!strcasecmp(v->name, "outboundproxyport")) { 18537 /* Port needs to be after IP */ 18538 sscanf(v->value, "%30d", &format); 18539 outboundproxyip.sin_port = htons(format); 18540 } else if (!strcasecmp(v->name, "autocreatepeer")) { 18541 autocreatepeer = ast_true(v->value); 18542 } else if (!strcasecmp(v->name, "srvlookup")) { 18543 srvlookup = ast_true(v->value); 18544 } else if (!strcasecmp(v->name, "pedantic")) { 18545 pedanticsipchecking = ast_true(v->value); 18546 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 18547 max_expiry = atoi(v->value); 18548 if (max_expiry < 1) 18549 max_expiry = DEFAULT_MAX_EXPIRY; 18550 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 18551 min_expiry = atoi(v->value); 18552 if (min_expiry < 1) 18553 min_expiry = DEFAULT_MIN_EXPIRY; 18554 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 18555 default_expiry = atoi(v->value); 18556 if (default_expiry < 1) 18557 default_expiry = DEFAULT_DEFAULT_EXPIRY; 18558 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 18559 if (ast_true(v->value)) 18560 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 18561 } else if (!strcasecmp(v->name, "dumphistory")) { 18562 dumphistory = ast_true(v->value); 18563 } else if (!strcasecmp(v->name, "recordhistory")) { 18564 recordhistory = ast_true(v->value); 18565 } else if (!strcasecmp(v->name, "registertimeout")) { 18566 global_reg_timeout = atoi(v->value); 18567 if (global_reg_timeout < 1) 18568 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 18569 } else if (!strcasecmp(v->name, "registerattempts")) { 18570 global_regattempts_max = atoi(v->value); 18571 } else if (!strcasecmp(v->name, "bindaddr")) { 18572 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 18573 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 18574 } else { 18575 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 18576 } 18577 } else if (!strcasecmp(v->name, "localnet")) { 18578 struct ast_ha *na; 18579 if (!(na = ast_append_ha("d", v->value, localaddr))) 18580 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 18581 else 18582 localaddr = na; 18583 } else if (!strcasecmp(v->name, "localmask")) { 18584 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 18585 } else if (!strcasecmp(v->name, "externip")) { 18586 if (!(hp = ast_gethostbyname(v->value, &ahp))) 18587 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 18588 else 18589 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 18590 externexpire = 0; 18591 } else if (!strcasecmp(v->name, "externhost")) { 18592 ast_copy_string(externhost, v->value, sizeof(externhost)); 18593 if (!(hp = ast_gethostbyname(externhost, &ahp))) 18594 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 18595 else 18596 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 18597 externexpire = time(NULL); 18598 } else if (!strcasecmp(v->name, "externrefresh")) { 18599 if (sscanf(v->value, "%30d", &externrefresh) != 1) { 18600 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 18601 externrefresh = 10; 18602 } 18603 } else if (!strcasecmp(v->name, "allow")) { 18604 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 18605 } else if (!strcasecmp(v->name, "disallow")) { 18606 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 18607 } else if (!strcasecmp(v->name, "autoframing")) { 18608 global_autoframing = ast_true(v->value); 18609 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 18610 allow_external_domains = ast_true(v->value); 18611 } else if (!strcasecmp(v->name, "autodomain")) { 18612 auto_sip_domains = ast_true(v->value); 18613 } else if (!strcasecmp(v->name, "domain")) { 18614 char *domain = ast_strdupa(v->value); 18615 char *context = strchr(domain, ','); 18616 18617 if (context) 18618 *context++ = '\0'; 18619 18620 if (option_debug && ast_strlen_zero(context)) 18621 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 18622 if (ast_strlen_zero(domain)) 18623 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 18624 else 18625 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 18626 } else if (!strcasecmp(v->name, "register")) { 18627 if (sip_register(v->value, v->lineno) == 0) 18628 registry_count++; 18629 } else if (!strcasecmp(v->name, "tos")) { 18630 if (!ast_str2tos(v->value, &temp_tos)) { 18631 global_tos_sip = temp_tos; 18632 global_tos_audio = temp_tos; 18633 global_tos_video = temp_tos; 18634 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 18635 } else 18636 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 18637 } else if (!strcasecmp(v->name, "tos_sip")) { 18638 if (ast_str2tos(v->value, &global_tos_sip)) 18639 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 18640 } else if (!strcasecmp(v->name, "tos_audio")) { 18641 if (ast_str2tos(v->value, &global_tos_audio)) 18642 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 18643 } else if (!strcasecmp(v->name, "tos_video")) { 18644 if (ast_str2tos(v->value, &global_tos_video)) 18645 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 18646 } else if (!strcasecmp(v->name, "bindport")) { 18647 if (sscanf(v->value, "%5d", &ourport) == 1) { 18648 bindaddr.sin_port = htons(ourport); 18649 } else { 18650 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 18651 } 18652 } else if (!strcasecmp(v->name, "qualify")) { 18653 if (!strcasecmp(v->value, "no")) { 18654 default_qualify = 0; 18655 } else if (!strcasecmp(v->value, "yes")) { 18656 default_qualify = DEFAULT_MAXMS; 18657 } else if (sscanf(v->value, "%30d", &default_qualify) != 1) { 18658 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 18659 default_qualify = 0; 18660 } 18661 } else if (!strcasecmp(v->name, "callevents")) { 18662 global_callevents = ast_true(v->value); 18663 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 18664 default_maxcallbitrate = atoi(v->value); 18665 if (default_maxcallbitrate < 0) 18666 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 18667 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 18668 global_matchexterniplocally = ast_true(v->value); 18669 } else if (!strcasecmp(v->name, "constantssrc")) { 18670 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_CONSTANT_SSRC); 18671 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 18672 if (ast_true(v->value)) { 18673 global_shrinkcallerid = 1; 18674 } else if (ast_false(v->value)) { 18675 global_shrinkcallerid = 0; 18676 } else { 18677 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 18678 } 18679 } 18680 } 18681 18682 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 18683 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 18684 allow_external_domains = 1; 18685 } 18686 18687 /* Build list of authentication to various SIP realms, i.e. service providers */ 18688 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 18689 /* Format for authentication is auth = username:password@realm */ 18690 if (!strcasecmp(v->name, "auth")) 18691 authl = add_realm_authentication(authl, v->value, v->lineno); 18692 } 18693 18694 ucfg = ast_config_load("users.conf"); 18695 if (ucfg) { 18696 struct ast_variable *gen; 18697 int genhassip, genregistersip; 18698 const char *hassip, *registersip; 18699 18700 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 18701 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 18702 gen = ast_variable_browse(ucfg, "general"); 18703 cat = ast_category_browse(ucfg, NULL); 18704 while (cat) { 18705 if (strcasecmp(cat, "general")) { 18706 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 18707 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 18708 if (ast_true(hassip) || (!hassip && genhassip)) { 18709 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 18710 if (user) { 18711 ASTOBJ_CONTAINER_LINK(&userl,user); 18712 ASTOBJ_UNREF(user, sip_destroy_user); 18713 user_count++; 18714 } 18715 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, 0); 18716 if (peer) { 18717 ast_device_state_changed("SIP/%s", peer->name); 18718 ASTOBJ_CONTAINER_LINK(&peerl,peer); 18719 ASTOBJ_UNREF(peer, sip_destroy_peer); 18720 peer_count++; 18721 } 18722 } 18723 if (ast_true(registersip) || (!registersip && genregistersip)) { 18724 char tmp[256]; 18725 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 18726 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 18727 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 18728 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 18729 const char *authuser = ast_variable_retrieve(ucfg, cat, "authuser"); 18730 if (!host) 18731 host = ast_variable_retrieve(ucfg, "general", "host"); 18732 if (!username) 18733 username = ast_variable_retrieve(ucfg, "general", "username"); 18734 if (!secret) 18735 secret = ast_variable_retrieve(ucfg, "general", "secret"); 18736 if (!contact) 18737 contact = "s"; 18738 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 18739 if (!ast_strlen_zero(secret)) { 18740 if (!ast_strlen_zero(authuser)) { 18741 snprintf(tmp, sizeof(tmp), "%s:%s:%s@%s/%s", username, secret, authuser, host, contact); 18742 } else { 18743 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 18744 } 18745 } else if (!ast_strlen_zero(authuser)) { 18746 snprintf(tmp, sizeof(tmp), "%s::%s@%s/%s", username, authuser, host, contact); 18747 } else { 18748 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 18749 } 18750 if (sip_register(tmp, 0) == 0) 18751 registry_count++; 18752 } 18753 } 18754 } 18755 cat = ast_category_browse(ucfg, cat); 18756 } 18757 ast_config_destroy(ucfg); 18758 } 18759 18760 18761 /* Load peers, users and friends */ 18762 cat = NULL; 18763 while ( (cat = ast_category_browse(cfg, cat)) ) { 18764 const char *utype; 18765 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 18766 continue; 18767 utype = ast_variable_retrieve(cfg, cat, "type"); 18768 if (!utype) { 18769 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 18770 continue; 18771 } else { 18772 int is_user = 0, is_peer = 0; 18773 if (!strcasecmp(utype, "user")) 18774 is_user = 1; 18775 else if (!strcasecmp(utype, "friend")) 18776 is_user = is_peer = 1; 18777 else if (!strcasecmp(utype, "peer")) 18778 is_peer = 1; 18779 else { 18780 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 18781 continue; 18782 } 18783 if (is_user) { 18784 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 18785 if (user) { 18786 ASTOBJ_CONTAINER_LINK(&userl,user); 18787 ASTOBJ_UNREF(user, sip_destroy_user); 18788 user_count++; 18789 } 18790 } 18791 if (is_peer) { 18792 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0); 18793 if (peer) { 18794 ASTOBJ_CONTAINER_LINK(&peerl,peer); 18795 ASTOBJ_UNREF(peer, sip_destroy_peer); 18796 peer_count++; 18797 } 18798 } 18799 } 18800 } 18801 if (ast_find_ourip(&__ourip, bindaddr)) { 18802 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 18803 ast_config_destroy(cfg); 18804 return 0; 18805 } 18806 if (!ntohs(bindaddr.sin_port)) 18807 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 18808 bindaddr.sin_family = AF_INET; 18809 ast_mutex_lock(&netlock); 18810 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 18811 close(sipsock); 18812 sipsock = -1; 18813 } 18814 if (sipsock < 0) { 18815 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 18816 if (sipsock < 0) { 18817 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 18818 ast_config_destroy(cfg); 18819 return -1; 18820 } else { 18821 /* Allow SIP clients on the same host to access us: */ 18822 const int reuseFlag = 1; 18823 18824 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 18825 (const char*)&reuseFlag, 18826 sizeof reuseFlag); 18827 18828 ast_enable_packet_fragmentation(sipsock); 18829 18830 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 18831 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 18832 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 18833 strerror(errno)); 18834 close(sipsock); 18835 sipsock = -1; 18836 } else { 18837 if (option_verbose > 1) { 18838 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 18839 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 18840 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); 18841 } 18842 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 18843 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 18844 } 18845 } 18846 } 18847 ast_mutex_unlock(&netlock); 18848 18849 /* Add default domains - host name, IP address and IP:port */ 18850 /* Only do this if user added any sip domain with "localdomains" */ 18851 /* In order to *not* break backwards compatibility */ 18852 /* Some phones address us at IP only, some with additional port number */ 18853 if (auto_sip_domains) { 18854 char temp[MAXHOSTNAMELEN]; 18855 18856 /* First our default IP address */ 18857 if (bindaddr.sin_addr.s_addr) 18858 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 18859 else 18860 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 18861 18862 /* Our extern IP address, if configured */ 18863 if (externip.sin_addr.s_addr) 18864 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 18865 18866 /* Extern host name (NAT traversal support) */ 18867 if (!ast_strlen_zero(externhost)) 18868 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 18869 18870 /* Our host name */ 18871 if (!gethostname(temp, sizeof(temp))) 18872 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 18873 } 18874 18875 /* Release configuration from memory */ 18876 ast_config_destroy(cfg); 18877 18878 /* Load the list of manual NOTIFY types to support */ 18879 if (notify_types) 18880 ast_config_destroy(notify_types); 18881 notify_types = ast_config_load(notify_config); 18882 18883 /* Done, tell the manager */ 18884 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); 18885 18886 return 0; 18887 }
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 12291 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, 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, and sip_pvt::registry.
Referenced by do_proxy_auth(), and do_register_auth().
12292 { 12293 char tmp[512]; 12294 char *c; 12295 char oldnonce[256]; 12296 12297 /* table of recognised keywords, and places where they should be copied */ 12298 const struct x { 12299 const char *key; 12300 int field_index; 12301 } *i, keys[] = { 12302 { "realm=", ast_string_field_index(p, realm) }, 12303 { "nonce=", ast_string_field_index(p, nonce) }, 12304 { "opaque=", ast_string_field_index(p, opaque) }, 12305 { "qop=", ast_string_field_index(p, qop) }, 12306 { "domain=", ast_string_field_index(p, domain) }, 12307 { NULL, 0 }, 12308 }; 12309 12310 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 12311 if (ast_strlen_zero(tmp)) 12312 return -1; 12313 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 12314 ast_log(LOG_WARNING, "missing Digest.\n"); 12315 return -1; 12316 } 12317 c = tmp + strlen("Digest "); 12318 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 12319 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 12320 for (i = keys; i->key != NULL; i++) { 12321 char *src, *separator; 12322 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 12323 continue; 12324 /* Found. Skip keyword, take text in quotes or up to the separator. */ 12325 c += strlen(i->key); 12326 if (*c == '"') { 12327 src = ++c; 12328 separator = "\""; 12329 } else { 12330 src = c; 12331 separator = ","; 12332 } 12333 strsep(&c, separator); /* clear separator and move ptr */ 12334 ast_string_field_index_set(p, i->field_index, src); 12335 break; 12336 } 12337 if (i->key == NULL) /* not found, try ',' */ 12338 strsep(&c, ","); 12339 } 12340 /* Reset nonce count */ 12341 if (strcmp(p->nonce, oldnonce)) 12342 p->noncecount = 0; 12343 12344 /* Save auth data for following registrations */ 12345 if (p->registry) { 12346 struct sip_registry *r = p->registry; 12347 12348 if (strcmp(r->nonce, p->nonce)) { 12349 ast_string_field_set(r, realm, p->realm); 12350 ast_string_field_set(r, nonce, p->nonce); 12351 ast_string_field_set(r, domain, p->domain); 12352 ast_string_field_set(r, opaque, p->opaque); 12353 ast_string_field_set(r, qop, p->qop); 12354 r->noncecount = 0; 12355 } 12356 } 12357 return build_reply_digest(p, sipmethod, digest, digest_len); 12358 }
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 6466 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, sip_pvt::tag, text, cfsip_methods::text, sip_pvt::theirtag, TRUE, sip_pvt::uri, and sip_pvt::via.
06467 { 06468 struct sip_request *orig = &p->initreq; 06469 char stripped[80]; 06470 char tmp[80]; 06471 char newto[256]; 06472 const char *c; 06473 const char *ot, *of; 06474 int is_strict = FALSE; /*!< Strict routing flag */ 06475 06476 memset(req, 0, sizeof(struct sip_request)); 06477 06478 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 06479 06480 if (!seqno) { 06481 p->ocseq++; 06482 seqno = p->ocseq; 06483 } 06484 06485 /* A CANCEL must have the same branch as the INVITE that it is canceling. */ 06486 if (sipmethod == SIP_CANCEL) { 06487 p->branch = p->invite_branch; 06488 build_via(p); 06489 } else if (newbranch && (sipmethod == SIP_INVITE)) { 06490 p->branch ^= ast_random(); 06491 p->invite_branch = p->branch; 06492 build_via(p); 06493 } else if (newbranch) { 06494 p->branch ^= ast_random(); 06495 build_via(p); 06496 } 06497 06498 /* Check for strict or loose router */ 06499 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 06500 is_strict = TRUE; 06501 if (sipdebug) 06502 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 06503 } 06504 06505 if (sipmethod == SIP_CANCEL) 06506 c = p->initreq.rlPart2; /* Use original URI */ 06507 else if (sipmethod == SIP_ACK) { 06508 /* Use URI from Contact: in 200 OK (if INVITE) 06509 (we only have the contacturi on INVITEs) */ 06510 if (!ast_strlen_zero(p->okcontacturi)) 06511 c = is_strict ? p->route->hop : p->okcontacturi; 06512 else 06513 c = p->initreq.rlPart2; 06514 } else if (!ast_strlen_zero(p->okcontacturi)) 06515 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 06516 else if (!ast_strlen_zero(p->uri)) 06517 c = p->uri; 06518 else { 06519 char *n; 06520 /* We have no URI, use To: or From: header as URI (depending on direction) */ 06521 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 06522 sizeof(stripped)); 06523 n = get_in_brackets(stripped); 06524 c = strsep(&n, ";"); /* trim ; and beyond */ 06525 } 06526 init_req(req, sipmethod, c); 06527 06528 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 06529 06530 add_header(req, "Via", p->via); 06531 if (p->route) { 06532 set_destination(p, p->route->hop); 06533 add_route(req, is_strict ? p->route->next : p->route); 06534 } 06535 06536 ot = get_header(orig, "To"); 06537 of = get_header(orig, "From"); 06538 06539 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 06540 as our original request, including tag (or presumably lack thereof) */ 06541 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 06542 /* Add the proper tag if we don't have it already. If they have specified 06543 their tag, use it. Otherwise, use our own tag */ 06544 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 06545 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06546 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06547 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06548 else 06549 snprintf(newto, sizeof(newto), "%s", ot); 06550 ot = newto; 06551 } 06552 06553 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06554 add_header(req, "From", of); 06555 add_header(req, "To", ot); 06556 } else { 06557 add_header(req, "From", ot); 06558 add_header(req, "To", of); 06559 } 06560 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 06561 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 06562 add_header(req, "Contact", p->our_contact); 06563 06564 copy_header(req, orig, "Call-ID"); 06565 add_header(req, "CSeq", tmp); 06566 06567 if (!ast_strlen_zero(global_useragent)) 06568 add_header(req, "User-Agent", global_useragent); 06569 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06570 06571 if (!ast_strlen_zero(p->rpid)) 06572 add_header(req, "Remote-Party-ID", p->rpid); 06573 06574 return 0; 06575 }
static int resp_needs_contact | ( | const char * | msg, | |
enum sipmethod | method | |||
) | [inline, static] |
Test if this response needs a contact header.
Definition at line 6355 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().
06355 { 06356 /* Requirements for Contact header inclusion in responses generated 06357 * from the header tables found in the following RFCs. Where the 06358 * Contact header was marked mandatory (m) or optional (o) this 06359 * function returns 1. 06360 * 06361 * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER) 06362 * - RFC 2976 (INFO) 06363 * - RFC 3262 (PRACK) 06364 * - RFC 3265 (SUBSCRIBE, NOTIFY) 06365 * - RFC 3311 (UPDATE) 06366 * - RFC 3428 (MESSAGE) 06367 * - RFC 3515 (REFER) 06368 * - RFC 3903 (PUBLISH) 06369 */ 06370 06371 switch (method) { 06372 /* 1xx, 2xx, 3xx, 485 */ 06373 case SIP_INVITE: 06374 case SIP_UPDATE: 06375 case SIP_SUBSCRIBE: 06376 case SIP_NOTIFY: 06377 if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3)) 06378 return 1; 06379 break; 06380 06381 /* 2xx, 3xx, 485 */ 06382 case SIP_REGISTER: 06383 case SIP_OPTIONS: 06384 if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3)) 06385 return 1; 06386 break; 06387 06388 /* 3xx, 485 */ 06389 case SIP_BYE: 06390 case SIP_PRACK: 06391 case SIP_MESSAGE: 06392 case SIP_PUBLISH: 06393 if (msg[0] == '3' || !strncmp(msg, "485", 3)) 06394 return 1; 06395 break; 06396 06397 /* 2xx, 3xx, 4xx, 5xx, 6xx */ 06398 case SIP_REFER: 06399 if (msg[0] >= '2' && msg[0] <= '6') 06400 return 1; 06401 break; 06402 06403 /* contact will not be included for everything else */ 06404 case SIP_ACK: 06405 case SIP_CANCEL: 06406 case SIP_INFO: 06407 case SIP_PING: 06408 default: 06409 return 0; 06410 } 06411 return 0; 06412 }
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 6416 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_copy_string(), 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(), sip_pvt::method, sip_pvt::our_contact, resp_needs_contact(), SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, SIPBUFSIZE, SUPPORTED_EXTENSIONS, sip_pvt::tag, and sip_pvt::theirtag.
06417 { 06418 char newto[256]; 06419 const char *ot; 06420 06421 init_resp(resp, msg); 06422 copy_via_headers(p, resp, req, "Via"); 06423 if (msg[0] == '1' || msg[0] == '2') 06424 copy_all_header(resp, req, "Record-Route"); 06425 copy_header(resp, req, "From"); 06426 ot = get_header(req, "To"); 06427 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 06428 /* Add the proper tag if we don't have it already. If they have specified 06429 their tag, use it. Otherwise, use our own tag */ 06430 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06431 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06432 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06433 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06434 else 06435 ast_copy_string(newto, ot, sizeof(newto)); 06436 ot = newto; 06437 } 06438 add_header(resp, "To", ot); 06439 copy_header(resp, req, "Call-ID"); 06440 copy_header(resp, req, "CSeq"); 06441 if (!ast_strlen_zero(global_useragent)) 06442 add_header(resp, "User-Agent", global_useragent); 06443 add_header(resp, "Allow", ALLOWED_METHODS); 06444 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 06445 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 06446 /* For registration responses, we also need expiry and 06447 contact info */ 06448 char tmp[256]; 06449 06450 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 06451 add_header(resp, "Expires", tmp); 06452 if (p->expiry) { /* Only add contact if we have an expiry time */ 06453 char contact[SIPBUFSIZE]; 06454 const char *contact_uri = p->method == SIP_SUBSCRIBE ? p->our_contact : p->fullcontact; 06455 char *brackets = strchr(contact_uri, '<'); 06456 snprintf(contact, sizeof(contact), "%s%s%s;expires=%d", brackets ? "" : "<", contact_uri, brackets ? "" : ">", p->expiry); 06457 add_header(resp, "Contact", contact); /* Not when we unregister */ 06458 } 06459 } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) { 06460 add_header(resp, "Contact", p->our_contact); 06461 } 06462 return 0; 06463 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 17099 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, and monlock.
17100 { 17101 /* If we're supposed to be stopped -- stay stopped */ 17102 if (monitor_thread == AST_PTHREADT_STOP) 17103 return 0; 17104 ast_mutex_lock(&monlock); 17105 if (monitor_thread == pthread_self()) { 17106 ast_mutex_unlock(&monlock); 17107 ast_log(LOG_WARNING, "Cannot kill myself\n"); 17108 return -1; 17109 } 17110 if (monitor_thread != AST_PTHREADT_NULL) { 17111 /* Wake up the thread */ 17112 pthread_kill(monitor_thread, SIGURG); 17113 } else { 17114 /* Start a new monitor */ 17115 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 17116 ast_mutex_unlock(&monlock); 17117 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 17118 return -1; 17119 } 17120 } 17121 ast_mutex_unlock(&monlock); 17122 return 0; 17123 }
static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 1960 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, ast_channel::name, 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, sip_pkt::timer_a, sip_pkt::timer_t1, and XMIT_ERROR.
01961 { 01962 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 01963 int reschedule = DEFAULT_RETRANS; 01964 int xmitres = 0; 01965 01966 /* Lock channel PVT */ 01967 ast_mutex_lock(&pkt->owner->lock); 01968 01969 if (pkt->retrans < MAX_RETRANS) { 01970 pkt->retrans++; 01971 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01972 if (sipdebug && option_debug > 3) 01973 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); 01974 } else { 01975 int siptimer_a; 01976 01977 if (sipdebug && option_debug > 3) 01978 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01979 if (!pkt->timer_a) 01980 pkt->timer_a = 2 ; 01981 else 01982 pkt->timer_a = 2 * pkt->timer_a; 01983 01984 /* For non-invites, a maximum of 4 secs */ 01985 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01986 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01987 siptimer_a = 4000; 01988 01989 /* Reschedule re-transmit */ 01990 reschedule = siptimer_a; 01991 if (option_debug > 3) 01992 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); 01993 } 01994 01995 if (sip_debug_test_pvt(pkt->owner)) { 01996 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 01997 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 01998 pkt->retrans, sip_nat_mode(pkt->owner), 01999 ast_inet_ntoa(dst->sin_addr), 02000 ntohs(dst->sin_port), pkt->data); 02001 } 02002 02003 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 02004 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 02005 ast_mutex_unlock(&pkt->owner->lock); 02006 if (xmitres == XMIT_ERROR) 02007 ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid); 02008 else 02009 return reschedule; 02010 } 02011 /* Too many retries */ 02012 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 02013 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 02014 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); 02015 } else if ((pkt->method == SIP_OPTIONS) && sipdebug) { 02016 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) -- See doc/sip-retransmit.txt.\n", pkt->owner->callid); 02017 } 02018 if (xmitres == XMIT_ERROR) { 02019 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid); 02020 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02021 } else 02022 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02023 02024 pkt->retransid = -1; 02025 02026 if (ast_test_flag(pkt, FLAG_FATAL)) { 02027 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 02028 DEADLOCK_AVOIDANCE(&pkt->owner->lock); /* SIP_PVT, not channel */ 02029 } 02030 02031 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 02032 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 02033 02034 if (pkt->owner->owner) { 02035 sip_alreadygone(pkt->owner); 02036 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); 02037 ast_queue_hangup(pkt->owner->owner); 02038 ast_channel_unlock(pkt->owner->owner); 02039 } else { 02040 /* If no channel owner, destroy now */ 02041 02042 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 02043 if (pkt->method != SIP_OPTIONS) { 02044 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02045 sip_alreadygone(pkt->owner); 02046 if (option_debug) 02047 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 02048 } 02049 } 02050 } 02051 02052 if (pkt->method == SIP_BYE) { 02053 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 02054 if (pkt->owner->owner) 02055 ast_channel_unlock(pkt->owner->owner); 02056 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 02057 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02058 } 02059 02060 /* In any case, go ahead and remove the packet */ 02061 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 02062 if (cur == pkt) 02063 break; 02064 } 02065 if (cur) { 02066 if (prev) 02067 prev->next = cur->next; 02068 else 02069 pkt->owner->packets = cur->next; 02070 ast_mutex_unlock(&pkt->owner->lock); 02071 free(cur); 02072 pkt = NULL; 02073 } else 02074 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 02075 if (pkt) 02076 ast_mutex_unlock(&pkt->owner->lock); 02077 return 0; 02078 }
static int scheduler_process_request_queue | ( | const void * | data | ) | [static] |
Definition at line 16664 of file chan_sip.c.
References ast_channel_trylock, ast_mutex_lock, ast_mutex_unlock, sip_pvt::lock, and sip_pvt::owner.
Referenced by queue_request().
16665 { 16666 struct sip_pvt *p = (struct sip_pvt *) data; 16667 int recount = 0; 16668 int nounlock = 0; 16669 int lockretry; 16670 16671 for (lockretry = 10; lockretry > 0; lockretry--) { 16672 ast_mutex_lock(&p->lock); 16673 16674 /* lock the owner if it has one -- we may need it */ 16675 /* because this is deadlock-prone, we need to try and unlock if failed */ 16676 if (!p->owner || !ast_channel_trylock(p->owner)) { 16677 break; /* locking succeeded */ 16678 } 16679 16680 if (lockretry != 1) { 16681 ast_mutex_unlock(&p->lock); 16682 /* Sleep for a very short amount of time */ 16683 usleep(1); 16684 } 16685 } 16686 16687 if (!lockretry) { 16688 int retry = !AST_LIST_EMPTY(&p->request_queue); 16689 16690 /* we couldn't get the owner lock, which is needed to process 16691 the queued requests, so return a non-zero value, which will 16692 cause the scheduler to run this request again later if there 16693 still requests to be processed 16694 */ 16695 ast_mutex_unlock(&p->lock); 16696 return retry; 16697 }; 16698 16699 process_request_queue(p, &recount, &nounlock); 16700 p->request_queue_sched_id = -1; 16701 16702 if (p->owner && !nounlock) { 16703 ast_channel_unlock(p->owner); 16704 } 16705 ast_mutex_unlock(&p->lock); 16706 16707 if (recount) { 16708 ast_update_use_count(); 16709 } 16710 16711 return 0; 16712 }
static int send_provisional_keepalive | ( | const void * | data | ) | [static] |
Definition at line 2357 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
02357 { 02358 struct sip_pvt *pvt = (struct sip_pvt *) data; 02359 02360 return send_provisional_keepalive_full(pvt, 0); 02361 }
static int send_provisional_keepalive_full | ( | struct sip_pvt * | pvt, | |
int | with_sdp | |||
) | [static] |
Definition at line 2337 of file chan_sip.c.
References sip_pvt::initreq, INV_COMPLETED, sip_pvt::invitestate, sip_pvt::last_provisional, PROVIS_KEEPALIVE_TIMEOUT, S_OR, transmit_response(), transmit_response_with_sdp(), and XMIT_UNRELIABLE.
Referenced by send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().
02338 { 02339 const char *msg = NULL; 02340 02341 if (!pvt->last_provisional || !strncasecmp(pvt->last_provisional, "100", 3)) { 02342 msg = "183 Session Progress"; 02343 } 02344 02345 if (pvt->invitestate < INV_COMPLETED) { 02346 if (with_sdp) { 02347 transmit_response_with_sdp(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq, XMIT_UNRELIABLE); 02348 } else { 02349 transmit_response(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq); 02350 } 02351 return PROVIS_KEEPALIVE_TIMEOUT; 02352 } 02353 02354 return 0; 02355 }
static int send_provisional_keepalive_with_sdp | ( | const void * | data | ) | [static] |
Definition at line 2363 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
02363 { 02364 struct sip_pvt *pvt = (void *)data; 02365 02366 return send_provisional_keepalive_full(pvt, 1); 02367 }
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 2412 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, sip_pvt::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.
02413 { 02414 int res; 02415 02416 add_blank(req); 02417 if (sip_debug_test_pvt(p)) { 02418 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02419 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); 02420 else 02421 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); 02422 } 02423 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02424 struct sip_request tmp; 02425 parse_copy(&tmp, req); 02426 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02427 } 02428 res = (reliable) ? 02429 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02430 __sip_xmit(p, req->data, req->len); 02431 return res; 02432 }
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 2378 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_inet_ntoa(), AST_SCHED_DEL, ast_test_flag, ast_verbose(), sip_request::data, sip_pvt::flags, get_header(), sip_pvt::initreq, sip_request::len, sip_request::method, parse_copy(), sip_pvt::provisional_keepalive_sched_id, sched, 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.
02379 { 02380 int res; 02381 02382 add_blank(req); 02383 if (sip_debug_test_pvt(p)) { 02384 const struct sockaddr_in *dst = sip_real_dst(p); 02385 02386 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02387 reliable ? "Reliably " : "", sip_nat_mode(p), 02388 ast_inet_ntoa(dst->sin_addr), 02389 ntohs(dst->sin_port), req->data); 02390 } 02391 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02392 struct sip_request tmp; 02393 parse_copy(&tmp, req); 02394 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02395 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02396 } 02397 02398 /* If we are sending a final response to an INVITE, stop retransmitting provisional responses */ 02399 if (p->initreq.method == SIP_INVITE && reliable == XMIT_CRITICAL) { 02400 AST_SCHED_DEL(sched, p->provisional_keepalive_sched_id); 02401 } 02402 02403 res = (reliable) ? 02404 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02405 __sip_xmit(p, req->data, req->len); 02406 if (res > 0) 02407 return 0; 02408 return res; 02409 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 8673 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().
08674 { 08675 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 08676 /* NAT: Don't trust the contact field. Just use what they came to us 08677 with. */ 08678 pvt->sa = pvt->recv; 08679 return 0; 08680 } 08681 08682 return __set_address_from_contact(pvt->fullcontact, &pvt->sa); 08683 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 6265 of file chan_sip.c.
References ahp, ast_copy_string(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_verbose(), debug, hostname, hp, sip_pvt::sa, sip_debug_test_pvt(), and STANDARD_SIP_PORT.
Referenced by reqprep().
06266 { 06267 char *h, *maddr, hostname[256]; 06268 int port, hn; 06269 struct hostent *hp; 06270 struct ast_hostent ahp; 06271 int debug=sip_debug_test_pvt(p); 06272 06273 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 06274 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 06275 06276 if (debug) 06277 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 06278 06279 /* Find and parse hostname */ 06280 h = strchr(uri, '@'); 06281 if (h) 06282 ++h; 06283 else { 06284 h = uri; 06285 if (strncasecmp(h, "sip:", 4) == 0) 06286 h += 4; 06287 else if (strncasecmp(h, "sips:", 5) == 0) 06288 h += 5; 06289 } 06290 hn = strcspn(h, ":;>") + 1; 06291 if (hn > sizeof(hostname)) 06292 hn = sizeof(hostname); 06293 ast_copy_string(hostname, h, hn); 06294 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 06295 h += hn - 1; 06296 06297 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 06298 if (*h == ':') { 06299 /* Parse port */ 06300 ++h; 06301 port = strtol(h, &h, 10); 06302 } 06303 else 06304 port = STANDARD_SIP_PORT; 06305 06306 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 06307 maddr = strstr(h, "maddr="); 06308 if (maddr) { 06309 maddr += 6; 06310 hn = strspn(maddr, "0123456789.") + 1; 06311 if (hn > sizeof(hostname)) 06312 hn = sizeof(hostname); 06313 ast_copy_string(hostname, maddr, hn); 06314 } 06315 06316 hp = ast_gethostbyname(hostname, &ahp); 06317 if (hp == NULL) { 06318 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 06319 return; 06320 } 06321 p->sa.sin_family = AF_INET; 06322 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 06323 p->sa.sin_port = htons(port); 06324 if (debug) 06325 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 06326 }
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 17436 of file chan_sip.c.
References ast_copy_string(), ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_true(), ast_channel::flags, ast_channel::next, SIP_INSECURE_INVITE, and SIP_INSECURE_PORT.
Referenced by handle_common_options().
17437 { 17438 static int dep_insecure_very = 0; 17439 static int dep_insecure_yes = 0; 17440 17441 if (ast_strlen_zero(value)) 17442 return; 17443 17444 if (!strcasecmp(value, "very")) { 17445 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 17446 if(!dep_insecure_very) { 17447 if(lineno != -1) 17448 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno); 17449 else 17450 ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n"); 17451 dep_insecure_very = 1; 17452 } 17453 } 17454 else if (ast_true(value)) { 17455 ast_set_flag(flags, SIP_INSECURE_PORT); 17456 if(!dep_insecure_yes) { 17457 if(lineno != -1) 17458 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno); 17459 else 17460 ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value); 17461 dep_insecure_yes = 1; 17462 } 17463 } 17464 else if (!ast_false(value)) { 17465 char buf[64]; 17466 char *word, *next; 17467 ast_copy_string(buf, value, sizeof(buf)); 17468 next = buf; 17469 while ((word = strsep(&next, ","))) { 17470 if (!strcasecmp(word, "port")) 17471 ast_set_flag(flags, SIP_INSECURE_PORT); 17472 else if (!strcasecmp(word, "invite")) 17473 ast_set_flag(flags, SIP_INSECURE_INVITE); 17474 else 17475 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 17476 } 17477 } 17478 }
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 8995 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().
08996 { 08997 if (p->stalenonce || forceupdate || ast_strlen_zero(p->randdata)) { 08998 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08999 p->stalenonce = 0; 09000 } 09001 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 17871 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, global_flags, 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().
17872 { 17873 if (peer->expire == 0) { 17874 /* Don't reset expire or port time during reload 17875 if we have an active registration 17876 */ 17877 peer->expire = -1; 17878 peer->pokeexpire = -1; 17879 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 17880 } 17881 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 17882 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 17883 strcpy(peer->context, default_context); 17884 strcpy(peer->subscribecontext, default_subscribecontext); 17885 strcpy(peer->language, default_language); 17886 strcpy(peer->mohinterpret, default_mohinterpret); 17887 strcpy(peer->mohsuggest, default_mohsuggest); 17888 peer->addr.sin_family = AF_INET; 17889 peer->defaddr.sin_family = AF_INET; 17890 peer->capability = global_capability; 17891 peer->maxcallbitrate = default_maxcallbitrate; 17892 peer->rtptimeout = global_rtptimeout; 17893 peer->rtpholdtimeout = global_rtpholdtimeout; 17894 peer->rtpkeepalive = global_rtpkeepalive; 17895 peer->allowtransfer = global_allowtransfer; 17896 peer->autoframing = global_autoframing; 17897 strcpy(peer->vmexten, default_vmexten); 17898 peer->secret[0] = '\0'; 17899 peer->md5secret[0] = '\0'; 17900 peer->cid_num[0] = '\0'; 17901 peer->cid_name[0] = '\0'; 17902 peer->fromdomain[0] = '\0'; 17903 peer->fromuser[0] = '\0'; 17904 peer->regexten[0] = '\0'; 17905 peer->mailbox[0] = '\0'; 17906 peer->callgroup = 0; 17907 peer->pickupgroup = 0; 17908 peer->maxms = default_qualify; 17909 peer->prefs = default_prefs; 17910 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 19223 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), ast_strlen_zero(), FALSE, inbuf(), LOG_DEBUG, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), sipdebug, and TRUE.
Referenced by load_module().
19224 { 19225 int no = 0; 19226 int ok = FALSE; 19227 char varbuf[30]; 19228 char *inbuf = (char *) data; 19229 19230 if (ast_strlen_zero(inbuf)) { 19231 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 19232 return 0; 19233 } 19234 ast_channel_lock(chan); 19235 19236 /* Check for headers */ 19237 while (!ok && no <= 50) { 19238 no++; 19239 snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no); 19240 19241 /* Compare without the leading underscores */ 19242 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL) ) 19243 ok = TRUE; 19244 } 19245 if (ok) { 19246 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 19247 if (sipdebug) 19248 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 19249 } else { 19250 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 19251 } 19252 ast_channel_unlock(chan); 19253 return 0; 19254 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 2788 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02789 { 02790 /* We know name is the first field, so we can cast */ 02791 struct sip_peer *p = (struct sip_peer *) name; 02792 return !(!inaddrcmp(&p->addr, sin) || 02793 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02794 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02795 }
static struct sip_pvt * sip_alloc | ( | ast_string_field | callid, | |
struct sockaddr_in * | sin, | |||
int | useglobal_nat, | |||
const int | intended_method | |||
) | [static] |
Allocate SIP_PVT structure and set defaults.
Definition at line 4699 of file chan_sip.c.
References __ourip, 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(), bindaddr, build_callid_pvt(), build_via(), context, default_prefs, do_setnat(), errno, free, sip_pvt::fromdomain, global_flags, iflist, iflock, INITIAL_CSEQ, io, LOG_DEBUG, make_our_tag(), mohinterpret, mohsuggest, NONE, option_debug, sched, 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, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, text, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
04701 { 04702 struct sip_pvt *p; 04703 04704 if (!(p = ast_calloc(1, sizeof(*p)))) 04705 return NULL; 04706 04707 if (ast_string_field_init(p, 512)) { 04708 free(p); 04709 return NULL; 04710 } 04711 04712 ast_mutex_init(&p->lock); 04713 04714 p->method = intended_method; 04715 p->initid = -1; 04716 p->waitid = -1; 04717 p->autokillid = -1; 04718 p->request_queue_sched_id = -1; 04719 p->provisional_keepalive_sched_id = -1; 04720 p->subscribed = NONE; 04721 p->stateid = -1; 04722 p->prefs = default_prefs; /* Set default codecs for this call */ 04723 04724 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04725 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04726 04727 if (sin) { 04728 p->sa = *sin; 04729 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04730 p->ourip = __ourip; 04731 } else 04732 p->ourip = __ourip; 04733 04734 /* Copy global flags to this PVT at setup. */ 04735 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04736 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04737 04738 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04739 04740 p->branch = ast_random(); 04741 make_our_tag(p->tag, sizeof(p->tag)); 04742 p->ocseq = INITIAL_CSEQ; 04743 04744 if (sip_methods[intended_method].need_rtp) { 04745 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04746 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04747 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04748 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04749 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04750 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04751 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04752 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04753 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04754 /* If rtp was successfully allocated, but vrtp was not, then we need to be sure to free rtp here */ 04755 if (p->rtp) { 04756 ast_rtp_destroy(p->rtp); 04757 } 04758 if (p->udptl) { 04759 ast_udptl_destroy(p->udptl); 04760 } 04761 ast_mutex_destroy(&p->lock); 04762 if (p->chanvars) { 04763 ast_variables_destroy(p->chanvars); 04764 p->chanvars = NULL; 04765 } 04766 ast_string_field_free_memory(p); 04767 free(p); 04768 return NULL; 04769 } 04770 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04771 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04772 ast_rtp_settos(p->rtp, global_tos_audio); 04773 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04774 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04775 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04776 if (p->vrtp) { 04777 ast_rtp_settos(p->vrtp, global_tos_video); 04778 ast_rtp_setdtmf(p->vrtp, 0); 04779 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04780 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04781 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04782 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04783 } 04784 if (p->udptl) 04785 ast_udptl_settos(p->udptl, global_tos_audio); 04786 p->maxcallbitrate = default_maxcallbitrate; 04787 p->autoframing = global_autoframing; 04788 ast_rtp_codec_setpref(p->rtp, &p->prefs); 04789 } 04790 04791 if (useglobal_nat && sin) { 04792 /* Setup NAT structure according to global settings if we have an address */ 04793 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04794 p->recv = *sin; 04795 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04796 } 04797 04798 if (p->method != SIP_REGISTER) 04799 ast_string_field_set(p, fromdomain, default_fromdomain); 04800 build_via(p); 04801 if (!callid) 04802 build_callid_pvt(p); 04803 else 04804 ast_string_field_set(p, callid, callid); 04805 /* Assign default music on hold class */ 04806 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04807 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04808 p->capability = global_capability; 04809 p->allowtransfer = global_allowtransfer; 04810 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04811 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04812 p->noncodeccapability |= AST_RTP_DTMF; 04813 if (p->udptl) { 04814 p->t38.capability = global_t38_capability; 04815 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04816 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04817 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04818 p->t38.capability |= T38FAX_UDP_EC_FEC; 04819 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04820 p->t38.capability |= T38FAX_UDP_EC_NONE; 04821 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04822 p->t38.jointcapability = p->t38.capability; 04823 } 04824 ast_string_field_set(p, context, default_context); 04825 04826 AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue); 04827 04828 /* Add to active dialog list */ 04829 ast_mutex_lock(&iflock); 04830 p->next = iflist; 04831 iflist = p; 04832 ast_mutex_unlock(&iflock); 04833 if (option_debug) 04834 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"); 04835 return p; 04836 }
static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1716 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().
01717 { 01718 if (option_debug > 2) 01719 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01720 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01721 }
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 3862 of file chan_sip.c.
References ast_channel::_state, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set_flag, ast_setstate(), AST_STATE_UP, sip_pvt::lock, LOG_DEBUG, ast_channel::name, option_debug, SIP_PAGE2_DIALOG_ESTABLISHED, ast_channel::tech_pvt, transmit_response_with_sdp(), try_suggested_sip_codec(), and XMIT_CRITICAL.
03863 { 03864 int res = 0; 03865 struct sip_pvt *p = ast->tech_pvt; 03866 03867 ast_mutex_lock(&p->lock); 03868 if (ast->_state != AST_STATE_UP) { 03869 try_suggested_sip_codec(p); 03870 03871 ast_setstate(ast, AST_STATE_UP); 03872 if (option_debug) 03873 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 03874 03875 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03876 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 03877 } 03878 ast_mutex_unlock(&p->lock); 03879 return res; 03880 }
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 3130 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, ast_var_t::entries, sip_pvt::flags, ast_channel::hangupcause, INC_CALL_RINGING, sip_pvt::initid, INV_CALLING, sip_pvt::invitestate, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, LOG_DEBUG, sip_pvt::maxtime, ast_channel::name, sip_pvt::noncodeccapability, option_debug, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, sched, 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.
03131 { 03132 int res, xmitres = 0; 03133 struct sip_pvt *p; 03134 struct varshead *headp; 03135 struct ast_var_t *current; 03136 const char *referer = NULL; /* SIP refererer */ 03137 03138 p = ast->tech_pvt; 03139 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 03140 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 03141 return -1; 03142 } 03143 03144 /* Check whether there is vxml_url, distinctive ring variables */ 03145 headp=&ast->varshead; 03146 AST_LIST_TRAVERSE(headp,current,entries) { 03147 /* Check whether there is a VXML_URL variable */ 03148 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 03149 p->options->vxml_url = ast_var_value(current); 03150 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 03151 p->options->uri_options = ast_var_value(current); 03152 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 03153 /* Check whether there is a ALERT_INFO variable */ 03154 p->options->distinctive_ring = ast_var_value(current); 03155 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 03156 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 03157 p->options->addsipheaders = 1; 03158 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 03159 /* This is a transfered call */ 03160 p->options->transfer = 1; 03161 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 03162 /* This is the referer */ 03163 referer = ast_var_value(current); 03164 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 03165 /* We're replacing a call. */ 03166 p->options->replaces = ast_var_value(current); 03167 } 03168 } 03169 03170 res = 0; 03171 ast_set_flag(&p->flags[0], SIP_OUTGOING); 03172 03173 if (p->options->transfer) { 03174 char buf[SIPBUFSIZE/2]; 03175 03176 if (referer) { 03177 if (sipdebug && option_debug > 2) 03178 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 03179 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 03180 } else 03181 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 03182 ast_string_field_set(p, cid_name, buf); 03183 } 03184 if (option_debug) 03185 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 03186 03187 res = update_call_counter(p, INC_CALL_RINGING); 03188 if ( res != -1 ) { 03189 p->callingpres = ast->cid.cid_pres; 03190 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 03191 p->jointnoncodeccapability = p->noncodeccapability; 03192 03193 /* If there are no audio formats left to offer, punt */ 03194 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 03195 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 03196 res = -1; 03197 } else { 03198 p->t38.jointcapability = p->t38.capability; 03199 if (option_debug > 1) 03200 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 03201 xmitres = transmit_invite(p, SIP_INVITE, 1, 2); 03202 if (xmitres == XMIT_ERROR) 03203 return -1; /* Transmission error */ 03204 03205 p->invitestate = INV_CALLING; 03206 03207 /* Initialize auto-congest time */ 03208 AST_SCHED_DEL(sched, p->initid); 03209 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 03210 } 03211 } else { 03212 ast->hangupcause = AST_CAUSE_USER_BUSY; 03213 } 03214 return res; 03215 }
static int sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2209 of file chan_sip.c.
References append_history, ast_sched_del(), sip_pvt::autokillid, and sched.
Referenced by cb_extensionstate(), check_user_full(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), and sip_hangup().
02210 { 02211 int res = 0; 02212 if (p->autokillid > -1) { 02213 if (!(res = ast_sched_del(sched, p->autokillid))) { 02214 append_history(p, "CancelDestroy", ""); 02215 p->autokillid = -1; 02216 } 02217 } 02218 return res; 02219 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1798 of file chan_sip.c.
References sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01799 { 01800 if (!sipdebug) 01801 return 0; 01802 if (debugaddr.sin_addr.s_addr) { 01803 if (((ntohs(debugaddr.sin_port) != 0) 01804 && (debugaddr.sin_port != addr->sin_port)) 01805 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01806 return 0; 01807 } 01808 return 1; 01809 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1824 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().
01825 { 01826 if (!sipdebug) 01827 return 0; 01828 return sip_debug_test_addr(sip_real_dst(p)); 01829 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3498 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().
03499 { 03500 ast_mutex_lock(&iflock); 03501 if (option_debug > 2) 03502 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03503 __sip_destroy(p, 1); 03504 ast_mutex_unlock(&iflock); 03505 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2596 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_SELFDESTRUCT, and SIP_REALTIME.
Referenced by __sip_autodestruct(), __sip_destroy(), _sip_show_peer(), build_peer(), check_user_full(), create_addr(), expire_register(), function_sippeer(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), reg_source_db(), register_verify(), 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().
02597 { 02598 if (option_debug > 2) 02599 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02600 02601 /* Delete it, it needs to disappear */ 02602 if (peer->call) 02603 sip_destroy(peer->call); 02604 02605 if (peer->mwipvt) /* We have an active subscription, delete it */ 02606 sip_destroy(peer->mwipvt); 02607 02608 if (peer->chanvars) { 02609 ast_variables_destroy(peer->chanvars); 02610 peer->chanvars = NULL; 02611 } 02612 02613 register_peer_exten(peer, FALSE); 02614 ast_free_ha(peer->ha); 02615 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02616 apeerobjs--; 02617 else if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02618 rpeerobjs--; 02619 else 02620 speerobjs--; 02621 clear_realm_authentication(peer->auth); 02622 peer->auth = NULL; 02623 free(peer); 02624 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2816 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, and SIP_REALTIME.
Referenced by check_user_full(), sip_show_user(), unload_module(), and update_call_counter().
02817 { 02818 if (option_debug > 2) 02819 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02820 ast_free_ha(user->ha); 02821 if (user->chanvars) { 02822 ast_variables_destroy(user->chanvars); 02823 user->chanvars = NULL; 02824 } 02825 if (ast_test_flag(&user->flags[0], SIP_REALTIME)) 02826 ruserobjs--; 02827 else 02828 suserobjs--; 02829 free(user); 02830 }
static int sip_devicestate | ( | void * | data | ) | [static] |
Part of PBX channel interface.
For peers with call limit:
For peers without call limit:
Peers that does not have a known call and can't be reached by OPTIONS
If we return AST_DEVICE_UNKNOWN, the device state engine will try to find out a state by walking the channel list.
The queue system (app_queue.c) treats a member as "active" if devicestate is != AST_DEVICE_UNAVAILBALE && != AST_DEVICE_INVALID
When placing a call to the queue member, queue system sets a member to busy if != AST_DEVICE_NOT_INUSE and != AST_DEVICE_UNKNOWN
Definition at line 17271 of file chan_sip.c.
References sip_peer::addr, ahp, 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().
17272 { 17273 char *host; 17274 char *tmp; 17275 17276 struct hostent *hp; 17277 struct ast_hostent ahp; 17278 struct sip_peer *p; 17279 17280 int res = AST_DEVICE_INVALID; 17281 17282 /* make sure data is not null. Maybe unnecessary, but better be safe */ 17283 host = ast_strdupa(data ? data : ""); 17284 if ((tmp = strchr(host, '@'))) 17285 host = tmp + 1; 17286 17287 if (option_debug > 2) 17288 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 17289 17290 /* If find_peer asks for a realtime peer, then this breaks rtautoclear. This 17291 * is because when a peer tries to autoexpire, the last thing it does is to 17292 * queue up an event telling the system that the devicestate has changed 17293 * (presumably to unavailable). If we ask for a realtime peer here, this would 17294 * load it BACK into memory, thus defeating the point of trying to trying to 17295 * clear dead hosts out of memory. 17296 */ 17297 if ((p = find_peer(host, NULL, 0, 1))) { 17298 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 17299 /* we have an address for the peer */ 17300 17301 /* Check status in this order 17302 - Hold 17303 - Ringing 17304 - Busy (enforced only by call limit) 17305 - Inuse (we have a call) 17306 - Unreachable (qualify) 17307 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 17308 for registered devices */ 17309 17310 if (p->onHold) 17311 /* First check for hold or ring states */ 17312 res = AST_DEVICE_ONHOLD; 17313 else if (p->inRinging) { 17314 if (p->inRinging == p->inUse) 17315 res = AST_DEVICE_RINGING; 17316 else 17317 res = AST_DEVICE_RINGINUSE; 17318 } else if (p->call_limit && (p->inUse == p->call_limit)) 17319 /* check call limit */ 17320 res = AST_DEVICE_BUSY; 17321 else if (p->call_limit && p->inUse) 17322 /* Not busy, but we do have a call */ 17323 res = AST_DEVICE_INUSE; 17324 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 17325 /* We don't have a call. Are we reachable at all? Requires qualify= */ 17326 res = AST_DEVICE_UNAVAILABLE; 17327 else /* Default reply if we're registered and have no other data */ 17328 res = AST_DEVICE_NOT_INUSE; 17329 } else { 17330 /* there is no address, it's unavailable */ 17331 res = AST_DEVICE_UNAVAILABLE; 17332 } 17333 ASTOBJ_UNREF(p,sip_destroy_peer); 17334 } else { 17335 char *port = strchr(host, ':'); 17336 if (port) 17337 *port = '\0'; 17338 hp = ast_gethostbyname(host, &ahp); 17339 if (hp) 17340 res = AST_DEVICE_UNKNOWN; 17341 } 17342 17343 return res; 17344 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 12104 of file chan_sip.c.
References ast_cli(), ast_set_flag, debugaddr, global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.
12105 { 12106 int oldsipdebug = sipdebug_console; 12107 if (argc != 3) { 12108 if (argc != 5) 12109 return RESULT_SHOWUSAGE; 12110 else if (strcmp(argv[3], "ip") == 0) 12111 return sip_do_debug_ip(fd, argc, argv); 12112 else if (strcmp(argv[3], "peer") == 0) 12113 return sip_do_debug_peer(fd, argc, argv); 12114 else 12115 return RESULT_SHOWUSAGE; 12116 } 12117 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12118 memset(&debugaddr, 0, sizeof(debugaddr)); 12119 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 12120 return RESULT_SUCCESS; 12121 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 12123 of file chan_sip.c.
References ast_cli(), ast_set_flag, debugaddr, global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.
12124 { 12125 int oldsipdebug = sipdebug_console; 12126 char *newargv[6] = { "sip", "set", "debug", NULL }; 12127 if (argc != 2) { 12128 if (argc != 4) 12129 return RESULT_SHOWUSAGE; 12130 else if (strcmp(argv[2], "ip") == 0) { 12131 newargv[3] = argv[2]; 12132 newargv[4] = argv[3]; 12133 return sip_do_debug_ip(fd, argc + 1, newargv); 12134 } else if (strcmp(argv[2], "peer") == 0) { 12135 newargv[3] = argv[2]; 12136 newargv[4] = argv[3]; 12137 return sip_do_debug_peer(fd, argc + 1, newargv); 12138 } else 12139 return RESULT_SHOWUSAGE; 12140 } 12141 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12142 memset(&debugaddr, 0, sizeof(debugaddr)); 12143 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 12144 return RESULT_SUCCESS; 12145 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 12050 of file chan_sip.c.
References ahp, ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), ast_set_flag, debugaddr, global_flags, hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
12051 { 12052 struct hostent *hp; 12053 struct ast_hostent ahp; 12054 int port = 0; 12055 char *p, *arg; 12056 12057 /* sip set debug ip <ip> */ 12058 if (argc != 5) 12059 return RESULT_SHOWUSAGE; 12060 p = arg = argv[4]; 12061 strsep(&p, ":"); 12062 if (p) 12063 port = atoi(p); 12064 hp = ast_gethostbyname(arg, &ahp); 12065 if (hp == NULL) 12066 return RESULT_SHOWUSAGE; 12067 12068 debugaddr.sin_family = AF_INET; 12069 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 12070 debugaddr.sin_port = htons(port); 12071 if (port == 0) 12072 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 12073 else 12074 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 12075 12076 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12077 12078 return RESULT_SUCCESS; 12079 }
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 12082 of file chan_sip.c.
References sip_peer::addr, ast_cli(), ast_inet_ntoa(), ast_set_flag, ASTOBJ_UNREF, debugaddr, find_peer(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_destroy_peer(), and SIP_PAGE2_DEBUG_CONSOLE.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
12083 { 12084 struct sip_peer *peer; 12085 if (argc != 5) 12086 return RESULT_SHOWUSAGE; 12087 peer = find_peer(argv[4], NULL, 1, 0); 12088 if (peer) { 12089 if (peer->addr.sin_addr.s_addr) { 12090 debugaddr.sin_family = AF_INET; 12091 debugaddr.sin_addr = peer->addr.sin_addr; 12092 debugaddr.sin_port = peer->addr.sin_port; 12093 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 12094 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12095 } else 12096 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 12097 ASTOBJ_UNREF(peer,sip_destroy_peer); 12098 } else 12099 ast_cli(fd, "No such peer '%s'\n", argv[4]); 12100 return RESULT_SUCCESS; 12101 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 12223 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
12224 { 12225 if (argc != 2) { 12226 return RESULT_SHOWUSAGE; 12227 } 12228 recordhistory = TRUE; 12229 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 12230 return RESULT_SUCCESS; 12231 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 19369 of file chan_sip.c.
References ast_log(), ASTOBJ_CONTAINER_PRUNE_MARKED, LOG_DEBUG, peerl, reload_config(), sip_destroy_peer(), sip_poke_all_peers(), and sip_send_all_registers().
Referenced by do_monitor().
19370 { 19371 reload_config(reason); 19372 19373 /* Prune peers who still are supposed to be deleted */ 19374 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 19375 if (option_debug > 3) 19376 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 19377 19378 /* Send qualify (OPTIONS) to all peers */ 19379 sip_poke_all_peers(); 19380 19381 /* Register with all services */ 19382 sip_send_all_registers(); 19383 19384 if (option_debug > 3) 19385 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 19386 19387 return 0; 19388 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 19168 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, 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().
19169 { 19170 struct sip_pvt *p; 19171 char *mode; 19172 if (data) 19173 mode = (char *)data; 19174 else { 19175 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 19176 return 0; 19177 } 19178 ast_channel_lock(chan); 19179 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 19180 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 19181 ast_channel_unlock(chan); 19182 return 0; 19183 } 19184 p = chan->tech_pvt; 19185 if (!p) { 19186 ast_channel_unlock(chan); 19187 return 0; 19188 } 19189 ast_mutex_lock(&p->lock); 19190 if (!strcasecmp(mode,"info")) { 19191 ast_clear_flag(&p->flags[0], SIP_DTMF); 19192 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 19193 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 19194 } else if (!strcasecmp(mode,"rfc2833")) { 19195 ast_clear_flag(&p->flags[0], SIP_DTMF); 19196 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 19197 p->jointnoncodeccapability |= AST_RTP_DTMF; 19198 } else if (!strcasecmp(mode,"inband")) { 19199 ast_clear_flag(&p->flags[0], SIP_DTMF); 19200 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 19201 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 19202 } else 19203 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 19204 if (p->rtp) 19205 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 19206 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 19207 if (!p->vad) { 19208 p->vad = ast_dsp_new(); 19209 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 19210 } 19211 } else { 19212 if (p->vad) { 19213 ast_dsp_free(p->vad); 19214 p->vad = NULL; 19215 } 19216 } 19217 ast_mutex_unlock(&p->lock); 19218 ast_channel_unlock(chan); 19219 return 0; 19220 }
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 11908 of file chan_sip.c.
References AST_LIST_TRAVERSE, ast_log(), sip_pvt::callid, sip_history::event, sip_pvt::history, sip_history::list, LOG_DEBUG, LOG_NOTICE, option_debug, sipdebug, and sip_pvt::subscribed.
Referenced by __sip_destroy().
11909 { 11910 int x = 0; 11911 struct sip_history *hist; 11912 static int errmsg = 0; 11913 11914 if (!dialog) 11915 return; 11916 11917 if (!option_debug && !sipdebug) { 11918 if (!errmsg) { 11919 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 11920 errmsg = 1; 11921 } 11922 return; 11923 } 11924 11925 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 11926 if (dialog->subscribed) 11927 ast_log(LOG_DEBUG, " * Subscription\n"); 11928 else 11929 ast_log(LOG_DEBUG, " * SIP Call\n"); 11930 if (dialog->history) 11931 AST_LIST_TRAVERSE(dialog->history, hist, list) 11932 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 11933 if (!x) 11934 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 11935 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 11936 }
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 3976 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, ast_channel::name, option_debug, sip_pvt::owner, sip_set_rtp_peer(), and ast_channel::tech_pvt.
03977 { 03978 int ret = -1; 03979 struct sip_pvt *p; 03980 03981 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 03982 ast_log(LOG_DEBUG, "New channel is zombie\n"); 03983 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 03984 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 03985 03986 if (!newchan || !newchan->tech_pvt) { 03987 if (!newchan) 03988 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 03989 else 03990 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 03991 return -1; 03992 } 03993 p = newchan->tech_pvt; 03994 03995 if (!p) { 03996 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 03997 return -1; 03998 } 03999 04000 ast_mutex_lock(&p->lock); 04001 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 04002 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 04003 if (p->owner != oldchan) 04004 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 04005 else { 04006 p->owner = newchan; 04007 /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native 04008 RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be 04009 able to do this if the masquerade happens before the bridge breaks (e.g., AMI 04010 redirect of both channels). Note that a channel can not be masqueraded *into* 04011 a native bridge. So there is no danger that this breaks a native bridge that 04012 should stay up. */ 04013 sip_set_rtp_peer(newchan, NULL, NULL, 0, 0); 04014 ret = 0; 04015 } 04016 if (option_debug > 2) 04017 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 04018 04019 ast_mutex_unlock(&p->lock); 04020 return ret; 04021 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 19313 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::jointcapability, and ast_channel::tech_pvt.
19314 { 19315 struct sip_pvt *p = chan->tech_pvt; 19316 return p->jointcapability ? p->jointcapability : p->capability; 19317 }
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 19024 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.
19025 { 19026 struct sip_pvt *p = NULL; 19027 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 19028 19029 if (!(p = chan->tech_pvt)) 19030 return AST_RTP_GET_FAILED; 19031 19032 ast_mutex_lock(&p->lock); 19033 if (!(p->rtp)) { 19034 ast_mutex_unlock(&p->lock); 19035 return AST_RTP_GET_FAILED; 19036 } 19037 19038 *rtp = p->rtp; 19039 19040 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 19041 res = AST_RTP_TRY_PARTIAL; 19042 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 19043 res = AST_RTP_TRY_NATIVE; 19044 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 19045 res = AST_RTP_GET_FAILED; 19046 19047 ast_mutex_unlock(&p->lock); 19048 19049 return res; 19050 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 18889 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.
18890 { 18891 struct sip_pvt *p; 18892 struct ast_udptl *udptl = NULL; 18893 18894 p = chan->tech_pvt; 18895 if (!p) 18896 return NULL; 18897 18898 ast_mutex_lock(&p->lock); 18899 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18900 udptl = p->udptl; 18901 ast_mutex_unlock(&p->lock); 18902 return udptl; 18903 }
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 19053 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_pvt::rtp, SIP_CAN_REINVITE, ast_channel::tech_pvt, and sip_pvt::vrtp.
19054 { 19055 struct sip_pvt *p = NULL; 19056 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 19057 19058 if (!(p = chan->tech_pvt)) 19059 return AST_RTP_GET_FAILED; 19060 19061 ast_mutex_lock(&p->lock); 19062 if (!(p->vrtp)) { 19063 ast_mutex_unlock(&p->lock); 19064 return AST_RTP_GET_FAILED; 19065 } 19066 19067 *rtp = p->vrtp; 19068 19069 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 19070 res = AST_RTP_TRY_NATIVE; 19071 19072 ast_mutex_unlock(&p->lock); 19073 19074 return res; 19075 }
static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
struct sip_pvt * | pvt, | |||
int | reinvite | |||
) | [static] |
Handle T38 reinvite.
Definition at line 18941 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, ast_channel::name, 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_ENABLED, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), transmit_response_with_t38_sdp(), sip_pvt::udptl, sip_pvt::udptlredirip, and XMIT_CRITICAL.
Referenced by handle_request_invite(), and handle_response_invite().
18942 { 18943 struct sip_pvt *p; 18944 int flag = 0; 18945 18946 p = chan->tech_pvt; 18947 if (!p || !pvt->udptl) 18948 return -1; 18949 18950 /* Setup everything on the other side like offered/responded from first side */ 18951 ast_mutex_lock(&p->lock); 18952 18953 /*! \todo check if this is not set earlier when setting up the PVT. If not 18954 maybe it should move there. */ 18955 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 18956 18957 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 18958 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 18959 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 18960 18961 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 18962 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 18963 not really T38 re-invites which are different. In this 18964 case it's used properly, to see if we can reinvite over 18965 NAT 18966 */ 18967 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 18968 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 18969 flag =1; 18970 } else { 18971 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18972 } 18973 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 18974 if (!p->pendinginvite) { 18975 if (option_debug > 2) { 18976 if (flag) 18977 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)); 18978 else 18979 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)); 18980 } 18981 transmit_reinvite_with_t38_sdp(p); 18982 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18983 if (option_debug > 2) { 18984 if (flag) 18985 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)); 18986 else 18987 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)); 18988 } 18989 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18990 } 18991 } 18992 /* Reset lastrtprx timer */ 18993 p->lastrtprx = p->lastrtptx = time(NULL); 18994 ast_mutex_unlock(&p->lock); 18995 return 0; 18996 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 18997 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 18998 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 18999 flag = 1; 19000 } else { 19001 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 19002 } 19003 if (option_debug > 2) { 19004 if (flag) 19005 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)); 19006 else 19007 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)); 19008 } 19009 pvt->t38.state = T38_ENABLED; 19010 p->t38.state = T38_ENABLED; 19011 if (option_debug > 1) { 19012 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 19013 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 19014 } 19015 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 19016 p->lastrtprx = p->lastrtptx = time(NULL); 19017 ast_mutex_unlock(&p->lock); 19018 return 0; 19019 } 19020 }
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 3671 of file chan_sip.c.
References __sip_pretend_ack(), __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, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, find_sip_method(), FLAG_RESPONSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, sip_pvt::hangupcause, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, sip_pkt::method, sip_pkt::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, sched, 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, and XMIT_RELIABLE.
03672 { 03673 struct sip_pvt *p = ast->tech_pvt; 03674 int needcancel = FALSE; 03675 int needdestroy = 0; 03676 struct ast_channel *oldowner = ast; 03677 03678 if (!p) { 03679 if (option_debug) 03680 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03681 return 0; 03682 } 03683 03684 /* Store hangupcause locally in PVT so we still have it before disconnect */ 03685 if (p->owner) 03686 p->hangupcause = p->owner->hangupcause; 03687 03688 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03689 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03690 if (option_debug && sipdebug) 03691 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03692 update_call_counter(p, DEC_CALL_LIMIT); 03693 } 03694 if (option_debug >3) 03695 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03696 if (p->autokillid > -1 && sip_cancel_destroy(p)) 03697 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03698 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03699 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03700 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03701 p->owner->tech_pvt = NULL; 03702 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03703 return 0; 03704 } 03705 if (option_debug) { 03706 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03707 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03708 else { 03709 if (option_debug) 03710 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03711 } 03712 } 03713 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03714 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03715 03716 ast_mutex_lock(&p->lock); 03717 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03718 if (option_debug && sipdebug) 03719 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03720 update_call_counter(p, DEC_CALL_LIMIT); 03721 } 03722 03723 /* Determine how to disconnect */ 03724 if (p->owner != ast) { 03725 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03726 ast_mutex_unlock(&p->lock); 03727 return 0; 03728 } 03729 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03730 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03731 needcancel = TRUE; 03732 if (option_debug > 3) 03733 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03734 } 03735 03736 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 03737 03738 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->hangupcause) : "Unknown"); 03739 03740 /* Disconnect */ 03741 if (p->vad) 03742 ast_dsp_free(p->vad); 03743 03744 p->owner = NULL; 03745 ast->tech_pvt = NULL; 03746 03747 ast_module_unref(ast_module_info->self); 03748 03749 /* Do not destroy this pvt until we have timeout or 03750 get an answer to the BYE or INVITE/CANCEL 03751 If we get no answer during retransmit period, drop the call anyway. 03752 (Sorry, mother-in-law, you can't deny a hangup by sending 03753 603 declined to BYE...) 03754 */ 03755 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03756 needdestroy = 1; /* Set destroy flag at end of this function */ 03757 else if (p->invitestate != INV_CALLING) 03758 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03759 03760 /* Start the process if it's not already started */ 03761 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03762 if (needcancel) { /* Outgoing call, not up */ 03763 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03764 /* stop retransmitting an INVITE that has not received a response */ 03765 struct sip_pkt *cur; 03766 03767 /* if we can't send right now, mark it pending */ 03768 if (p->invitestate == INV_CALLING) { 03769 /* We can't send anything in CALLING state */ 03770 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03771 __sip_pretend_ack(p); 03772 /* 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. */ 03773 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03774 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 03775 } else { 03776 for (cur = p->packets; cur; cur = cur->next) { 03777 __sip_semi_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), cur->method ? cur->method : find_sip_method(cur->data)); 03778 } 03779 p->invitestate = INV_CANCELLED; 03780 /* Send a new request: CANCEL */ 03781 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 03782 /* Actually don't destroy us yet, wait for the 487 on our original 03783 INVITE, but do set an autodestruct just in case we never get it. */ 03784 needdestroy = 0; 03785 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03786 } 03787 } else { /* Incoming call, not up */ 03788 const char *res; 03789 AST_SCHED_DEL(sched, p->provisional_keepalive_sched_id); 03790 if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause))) 03791 transmit_response_reliable(p, res, &p->initreq); 03792 else 03793 transmit_response_reliable(p, "603 Declined", &p->initreq); 03794 p->invitestate = INV_TERMINATED; 03795 } 03796 } else { /* Call is in UP state, send BYE */ 03797 if (!p->pendinginvite) { 03798 char *audioqos = ""; 03799 char *videoqos = ""; 03800 if (p->rtp) 03801 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03802 if (p->vrtp) 03803 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03804 /* Send a hangup */ 03805 if (oldowner->_state == AST_STATE_UP) { 03806 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03807 } 03808 03809 /* Get RTCP quality before end of call */ 03810 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03811 if (p->rtp) 03812 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03813 if (p->vrtp) 03814 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03815 } 03816 if (p->rtp && oldowner) 03817 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03818 if (p->vrtp && oldowner) 03819 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03820 } else { 03821 /* Note we will need a BYE when this all settles out 03822 but we can't send one while we have "INVITE" outstanding. */ 03823 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03824 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03825 AST_SCHED_DEL(sched, p->waitid); 03826 if (sip_cancel_destroy(p)) 03827 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03828 } 03829 } 03830 } 03831 if (needdestroy) 03832 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03833 ast_mutex_unlock(&p->lock); 03834 return 0; 03835 }
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 4092 of file chan_sip.c.
References ast_channel::_state, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock, ast_mutex_unlock, 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, 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.
04093 { 04094 struct sip_pvt *p = ast->tech_pvt; 04095 int res = 0; 04096 04097 ast_mutex_lock(&p->lock); 04098 switch(condition) { 04099 case AST_CONTROL_RINGING: 04100 if (ast->_state == AST_STATE_RING) { 04101 p->invitestate = INV_EARLY_MEDIA; 04102 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 04103 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 04104 /* Send 180 ringing if out-of-band seems reasonable */ 04105 transmit_provisional_response(p, "180 Ringing", &p->initreq, 0); 04106 ast_set_flag(&p->flags[0], SIP_RINGING); 04107 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 04108 break; 04109 } else { 04110 /* Well, if it's not reasonable, just send in-band */ 04111 } 04112 } 04113 res = -1; 04114 break; 04115 case AST_CONTROL_BUSY: 04116 if (ast->_state != AST_STATE_UP) { 04117 transmit_response_reliable(p, "486 Busy Here", &p->initreq); 04118 p->invitestate = INV_COMPLETED; 04119 sip_alreadygone(p); 04120 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 04121 break; 04122 } 04123 res = -1; 04124 break; 04125 case AST_CONTROL_CONGESTION: 04126 if (ast->_state != AST_STATE_UP) { 04127 transmit_response_reliable(p, "503 Service Unavailable", &p->initreq); 04128 p->invitestate = INV_COMPLETED; 04129 sip_alreadygone(p); 04130 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 04131 break; 04132 } 04133 res = -1; 04134 break; 04135 case AST_CONTROL_PROCEEDING: 04136 if ((ast->_state != AST_STATE_UP) && 04137 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04138 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04139 transmit_response(p, "100 Trying", &p->initreq); 04140 p->invitestate = INV_PROCEEDING; 04141 break; 04142 } 04143 res = -1; 04144 break; 04145 case AST_CONTROL_PROGRESS: 04146 if ((ast->_state != AST_STATE_UP) && 04147 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04148 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04149 p->invitestate = INV_EARLY_MEDIA; 04150 transmit_provisional_response(p, "183 Session Progress", &p->initreq, 1); 04151 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 04152 break; 04153 } 04154 res = -1; 04155 break; 04156 case AST_CONTROL_HOLD: 04157 ast_rtp_new_source(p->rtp); 04158 ast_moh_start(ast, data, p->mohinterpret); 04159 break; 04160 case AST_CONTROL_UNHOLD: 04161 ast_rtp_new_source(p->rtp); 04162 ast_moh_stop(ast); 04163 break; 04164 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 04165 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 04166 transmit_info_with_vidupdate(p); 04167 /* ast_rtcp_send_h261fur(p->vrtp); */ 04168 } else 04169 res = -1; 04170 break; 04171 case AST_CONTROL_SRCUPDATE: 04172 ast_rtp_new_source(p->rtp); 04173 break; 04174 case -1: 04175 res = -1; 04176 break; 04177 default: 04178 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 04179 res = -1; 04180 break; 04181 } 04182 ast_mutex_unlock(&p->lock); 04183 return res; 04184 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1818 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().
01819 { 01820 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01821 }
static struct ast_channel* sip_new | ( | struct sip_pvt * | i, | |
int | state, | |||
const char * | title | |||
) | [static] |
Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.
Definition at line 4192 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_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, ast_channel::name, 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().
04193 { 04194 struct ast_channel *tmp; 04195 struct ast_variable *v = NULL; 04196 int fmt; 04197 int what; 04198 int needvideo = 0, video = 0; 04199 char *decoded_exten; 04200 04201 if (option_debug != 0) { 04202 ast_verbose(VERBOSE_PREFIX_3 "NEW SIP CHANNEL, title: <%s>\n", title?title:"Null"); 04203 ast_verbose(VERBOSE_PREFIX_3 "from: %s\n", i->from); 04204 ast_verbose(VERBOSE_PREFIX_3 "username: <%s>\n", i->username); 04205 ast_verbose(VERBOSE_PREFIX_3 "peername: <%s>\n", i->peername); 04206 ast_verbose(VERBOSE_PREFIX_3 "fromdomain: %s\n", i->fromdomain); 04207 ast_verbose(VERBOSE_PREFIX_3 "fromuser: %s\n", i->fromuser); 04208 ast_verbose(VERBOSE_PREFIX_3 "fromname: %s\n", i->fromname); 04209 ast_verbose(VERBOSE_PREFIX_3 "fullcontact: %s\n", i->fullcontact); 04210 } 04211 04212 { 04213 char my_name[128]; /* pick a good name */ 04214 const char *f, *fromdomain = NULL; 04215 04216 if (!ast_strlen_zero(i->fromdomain) && strchr(i->fromdomain,':')) 04217 fromdomain = strchr(i->fromdomain,':') + 1; /* skip ':' */ 04218 else 04219 fromdomain = i->fromdomain; 04220 04221 if (!ast_strlen_zero(i->username)) { 04222 if (!ast_strlen_zero(title) && strcmp(i->username, title)) { 04223 /* title not empty and different from username */ 04224 snprintf(my_name, sizeof(my_name), "%s@%s", i->username, title); 04225 } else { 04226 /* username not empty, title is empty or equal to username */ 04227 snprintf(my_name, sizeof(my_name), "%s", i->username); 04228 } 04229 } else { /* username empty */ 04230 if (!ast_strlen_zero(i->peername)) { 04231 /* call from unregisted peer */ 04232 snprintf(my_name, sizeof(my_name), "%s", i->peername); 04233 } else { /* username and peername empty */ 04234 if (!ast_strlen_zero(title)) { /* title not empty */ 04235 snprintf(my_name, sizeof(my_name), "%s", title); 04236 } else if (!ast_strlen_zero(i->from)) { /* title empty, From: not empty */ 04237 f = i->from; 04238 if (!strncmp(f, "sip:", 4)) 04239 f += 4; 04240 snprintf(my_name, sizeof(my_name), "%s", f); 04241 } else { /* fallback to fromdomain */ 04242 snprintf(my_name, sizeof(my_name), "%s", fromdomain); 04243 } 04244 } 04245 } 04246 ast_mutex_unlock(&i->lock); 04247 /* Don't hold a sip pvt lock while we allocate a channel */ 04248 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)); 04249 04250 } 04251 if (!tmp) { 04252 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 04253 ast_mutex_lock(&i->lock); 04254 return NULL; 04255 } 04256 ast_mutex_lock(&i->lock); 04257 04258 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 04259 tmp->tech = &sip_tech_info; 04260 else 04261 tmp->tech = &sip_tech; 04262 04263 /* Select our native format based on codec preference until we receive 04264 something from another device to the contrary. */ 04265 if (i->jointcapability) { /* The joint capabilities of us and peer */ 04266 what = i->jointcapability; 04267 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 04268 } else if (i->capability) { /* Our configured capability for this peer */ 04269 what = i->capability; 04270 video = i->capability & AST_FORMAT_VIDEO_MASK; 04271 } else { 04272 what = global_capability; /* Global codec support */ 04273 video = global_capability & AST_FORMAT_VIDEO_MASK; 04274 } 04275 04276 /* Set the native formats for audio and merge in video */ 04277 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video; 04278 if (option_debug > 2) { 04279 char buf[SIPBUFSIZE]; 04280 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 04281 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 04282 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 04283 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 04284 if (i->prefcodec) 04285 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 04286 } 04287 04288 /* XXX Why are we choosing a codec from the native formats?? */ 04289 fmt = ast_best_codec(tmp->nativeformats); 04290 04291 /* If we have a prefcodec setting, we have an inbound channel that set a 04292 preferred format for this call. Otherwise, we check the jointcapability 04293 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 04294 */ 04295 if (i->vrtp) { 04296 if (i->prefcodec) 04297 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 04298 else 04299 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 04300 } 04301 04302 if (option_debug > 2) { 04303 if (needvideo) 04304 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 04305 else 04306 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 04307 } 04308 04309 04310 04311 if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 04312 i->vad = ast_dsp_new(); 04313 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 04314 if (global_relaxdtmf) 04315 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04316 } 04317 if (i->rtp) { 04318 tmp->fds[0] = ast_rtp_fd(i->rtp); 04319 tmp->fds[1] = ast_rtcp_fd(i->rtp); 04320 } 04321 if (needvideo && i->vrtp) { 04322 tmp->fds[2] = ast_rtp_fd(i->vrtp); 04323 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 04324 } 04325 if (i->udptl) { 04326 tmp->fds[5] = ast_udptl_fd(i->udptl); 04327 } 04328 if (state == AST_STATE_RING) 04329 tmp->rings = 1; 04330 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04331 tmp->writeformat = fmt; 04332 tmp->rawwriteformat = fmt; 04333 tmp->readformat = fmt; 04334 tmp->rawreadformat = fmt; 04335 tmp->tech_pvt = i; 04336 04337 tmp->callgroup = i->callgroup; 04338 tmp->pickupgroup = i->pickupgroup; 04339 tmp->cid.cid_pres = i->callingpres; 04340 if (!ast_strlen_zero(i->accountcode)) 04341 ast_string_field_set(tmp, accountcode, i->accountcode); 04342 if (i->amaflags) 04343 tmp->amaflags = i->amaflags; 04344 if (!ast_strlen_zero(i->language)) 04345 ast_string_field_set(tmp, language, i->language); 04346 i->owner = tmp; 04347 ast_module_ref(ast_module_info->self); 04348 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04349 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 04350 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 04351 * structure so that there aren't issues when forming URI's 04352 */ 04353 decoded_exten = ast_strdupa(i->exten); 04354 ast_uri_decode(decoded_exten); 04355 ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten)); 04356 04357 /* Don't use ast_set_callerid() here because it will 04358 * generate an unnecessary NewCallerID event */ 04359 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04360 if (!ast_strlen_zero(i->rdnis)) 04361 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04362 04363 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 04364 tmp->cid.cid_dnid = ast_strdup(i->exten); 04365 04366 tmp->priority = 1; 04367 if (!ast_strlen_zero(i->uri)) 04368 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 04369 if (!ast_strlen_zero(i->domain)) 04370 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 04371 if (!ast_strlen_zero(i->useragent)) 04372 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 04373 if (!ast_strlen_zero(i->callid)) 04374 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 04375 if (i->rtp) 04376 ast_jb_configure(tmp, &global_jbconf); 04377 04378 /* Set channel variables for this call from configuration */ 04379 for (v = i->chanvars ; v ; v = v->next) 04380 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04381 04382 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 04383 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04384 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04385 ast_hangup(tmp); 04386 tmp = NULL; 04387 } 04388 04389 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 04390 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 04391 04392 return tmp; 04393 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 12204 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
12205 { 12206 if (argc != 4) 12207 return RESULT_SHOWUSAGE; 12208 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12209 ast_cli(fd, "SIP Debugging Disabled\n"); 12210 return RESULT_SUCCESS; 12211 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 12213 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
12214 { 12215 if (argc != 3) 12216 return RESULT_SHOWUSAGE; 12217 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12218 ast_cli(fd, "SIP Debugging Disabled\n"); 12219 return RESULT_SUCCESS; 12220 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 12234 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
12235 { 12236 if (argc != 3) { 12237 return RESULT_SHOWUSAGE; 12238 } 12239 recordhistory = FALSE; 12240 ast_cli(fd, "SIP History Recording Disabled\n"); 12241 return RESULT_SUCCESS; 12242 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 12148 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(), notify_types, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), and var.
12149 { 12150 struct ast_variable *varlist; 12151 int i; 12152 12153 if (argc < 4) 12154 return RESULT_SHOWUSAGE; 12155 12156 if (!notify_types) { 12157 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 12158 return RESULT_FAILURE; 12159 } 12160 12161 varlist = ast_variable_browse(notify_types, argv[2]); 12162 12163 if (!varlist) { 12164 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 12165 return RESULT_FAILURE; 12166 } 12167 12168 for (i = 3; i < argc; i++) { 12169 struct sip_pvt *p; 12170 struct sip_request req; 12171 struct ast_variable *var; 12172 12173 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 12174 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 12175 return RESULT_FAILURE; 12176 } 12177 12178 if (create_addr(p, argv[i], NULL)) { 12179 /* Maybe they're not registered, etc. */ 12180 sip_destroy(p); 12181 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 12182 continue; 12183 } 12184 12185 initreqprep(&req, p, SIP_NOTIFY); 12186 12187 for (var = varlist; var; var = var->next) 12188 add_header(&req, var->name, ast_unescape_semicolon(var->value)); 12189 12190 /* Recalculate our side, and recalculate Call ID */ 12191 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 12192 p->ourip = __ourip; 12193 build_via(p); 12194 build_callid_pvt(p); 12195 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 12196 transmit_sip_request(p, &req); 12197 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12198 } 12199 12200 return RESULT_SUCCESS; 12201 }
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 13999 of file chan_sip.c.
References ast_channel::accountcode, ast_channel::amaflags, ast_calloc, AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_trylock, ast_channel_unlock, ast_copy_string(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, ast_channel::context, copy_request(), DEADLOCK_AVOIDANCE, ast_channel::exten, free, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, ast_channel::name, option_debug, ast_channel::priority, ast_channel::readformat, sip_park_thread(), ast_channel::tech_pvt, and ast_channel::writeformat.
Referenced by handle_request_refer().
14000 { 14001 struct sip_dual *d; 14002 struct ast_channel *transferee, *transferer; 14003 /* Chan2m: The transferer, chan1m: The transferee */ 14004 pthread_t th; 14005 14006 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 14007 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 14008 if ((!transferer) || (!transferee)) { 14009 if (transferee) { 14010 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 14011 ast_hangup(transferee); 14012 } 14013 if (transferer) { 14014 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 14015 ast_hangup(transferer); 14016 } 14017 return -1; 14018 } 14019 14020 /* Make formats okay */ 14021 transferee->readformat = chan1->readformat; 14022 transferee->writeformat = chan1->writeformat; 14023 14024 /* Prepare for taking over the channel */ 14025 ast_channel_masquerade(transferee, chan1); 14026 14027 /* Setup the extensions and such */ 14028 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 14029 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 14030 transferee->priority = chan1->priority; 14031 14032 /* We make a clone of the peer channel too, so we can play 14033 back the announcement */ 14034 14035 /* Make formats okay */ 14036 transferer->readformat = chan2->readformat; 14037 transferer->writeformat = chan2->writeformat; 14038 14039 /* Prepare for taking over the channel. Go ahead and grab this channel 14040 * lock here to avoid a deadlock with callbacks into the channel driver 14041 * that hold the channel lock and want the pvt lock. */ 14042 while (ast_channel_trylock(chan2)) { 14043 struct sip_pvt *pvt = chan2->tech_pvt; 14044 DEADLOCK_AVOIDANCE(&pvt->lock); 14045 } 14046 ast_channel_masquerade(transferer, chan2); 14047 ast_channel_unlock(chan2); 14048 14049 /* Setup the extensions and such */ 14050 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 14051 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 14052 transferer->priority = chan2->priority; 14053 14054 ast_channel_lock(transferer); 14055 if (ast_do_masquerade(transferer)) { 14056 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 14057 ast_channel_unlock(transferer); 14058 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 14059 ast_hangup(transferer); 14060 return -1; 14061 } 14062 ast_channel_unlock(transferer); 14063 if (!transferer || !transferee) { 14064 if (!transferer) { 14065 if (option_debug) 14066 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 14067 } 14068 if (!transferee) { 14069 if (option_debug) 14070 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 14071 } 14072 return -1; 14073 } 14074 if ((d = ast_calloc(1, sizeof(*d)))) { 14075 pthread_attr_t attr; 14076 14077 pthread_attr_init(&attr); 14078 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 14079 14080 /* Save original request for followup */ 14081 copy_request(&d->req, req); 14082 d->chan1 = transferee; /* Transferee */ 14083 d->chan2 = transferer; /* Transferer */ 14084 d->seqno = seqno; 14085 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 14086 /* Could not start thread */ 14087 free(d); /* We don't need it anymore. If thread is created, d will be free'd 14088 by sip_park_thread() */ 14089 pthread_attr_destroy(&attr); 14090 return 0; 14091 } 14092 pthread_attr_destroy(&attr); 14093 } 14094 return -1; 14095 }
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 13932 of file chan_sip.c.
References append_history, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_do_masquerade(), ast_hangup(), ast_log(), ast_park_call(), sip_dual::chan1, sip_dual::chan2, copy_request(), ext, free, ast_channel::hangupcause, LOG_DEBUG, LOG_ERROR, ast_channel::name, 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().
13933 { 13934 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 13935 struct sip_dual *d; 13936 struct sip_request req; 13937 int ext; 13938 int res; 13939 13940 d = stuff; 13941 transferee = d->chan1; 13942 transferer = d->chan2; 13943 copy_request(&req, &d->req); 13944 13945 if (!transferee || !transferer) { 13946 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 13947 return NULL; 13948 } 13949 if (option_debug > 3) 13950 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 13951 13952 ast_channel_lock(transferee); 13953 if (ast_do_masquerade(transferee)) { 13954 ast_log(LOG_WARNING, "Masquerade failed.\n"); 13955 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 13956 ast_channel_unlock(transferee); 13957 return NULL; 13958 } 13959 ast_channel_unlock(transferee); 13960 13961 res = ast_park_call(transferee, transferer, 0, &ext); 13962 13963 13964 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 13965 if (!res) { 13966 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 13967 } else { 13968 /* Then tell the transferer what happened */ 13969 sprintf(buf, "Call parked on extension '%d'", ext); 13970 transmit_message_with_text(transferer->tech_pvt, buf); 13971 } 13972 #endif 13973 13974 /* Any way back to the current call??? */ 13975 /* Transmit response to the REFER request */ 13976 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 13977 if (!res) { 13978 /* Transfer succeeded */ 13979 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 13980 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 13981 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13982 ast_hangup(transferer); /* This will cause a BYE */ 13983 if (option_debug) 13984 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 13985 } else { 13986 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 13987 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 13988 if (option_debug) 13989 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 13990 /* Do not hangup call */ 13991 } 13992 free(d); 13993 return NULL; 13994 }
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 9187 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().
09188 { 09189 struct sip_peer *peer = find_peer(p->peername, NULL, 1, 0); 09190 09191 if (!peer) 09192 return; 09193 09194 /* If they put someone on hold, increment the value... otherwise decrement it */ 09195 if (hold) 09196 peer->onHold++; 09197 else 09198 peer->onHold--; 09199 09200 /* Request device state update */ 09201 ast_device_state_changed("SIP/%s", peer->name); 09202 09203 return; 09204 }
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 19323 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, peerl, sched, sip_destroy_peer(), and sip_poke_peer_s().
Referenced by load_module(), and sip_do_reload().
19324 { 19325 int ms = 0; 19326 19327 if (!speerobjs) /* No peers, just give up */ 19328 return; 19329 19330 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 19331 ASTOBJ_WRLOCK(iterator); 19332 if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) { 19333 struct sip_peer *peer_ptr = iterator; 19334 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 19335 } 19336 ms += 100; 19337 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator)); 19338 if (iterator->pokeexpire == -1) { 19339 struct sip_peer *peer_ptr = iterator; 19340 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 19341 } 19342 ASTOBJ_UNLOCK(iterator); 19343 } while (0) 19344 ); 19345 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 17126 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, global_flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::name, sip_peer::pokeexpire, sched, sip_destroy(), sip_destroy_peer(), SIP_PAGE2_RTUPDATE, and sip_poke_peer_s().
Referenced by sip_poke_peer().
17127 { 17128 struct sip_peer *peer = (struct sip_peer *)data; 17129 17130 peer->pokeexpire = -1; 17131 if (peer->lastms > -1) { 17132 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 17133 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) { 17134 ast_update_realtime("sippeers", "name", peer->name, "lastms", "-1", NULL); 17135 } 17136 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 17137 } 17138 if (peer->call) 17139 sip_destroy(peer->call); 17140 peer->call = NULL; 17141 peer->lastms = -1; 17142 ast_device_state_changed("SIP/%s", peer->name); 17143 17144 /* This function gets called one place outside of the scheduler ... */ 17145 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 17146 struct sip_peer *peer_ptr = peer; 17147 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17148 } 17149 17150 /* There is no need to ASTOBJ_REF() here. Just let the scheduled callback 17151 * inherit the reference that the current callback already has. */ 17152 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 17153 if (peer->pokeexpire == -1) { 17154 ASTOBJ_UNREF(peer, sip_destroy_peer); 17155 } 17156 17157 return 0; 17158 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 17163 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, sched, 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().
17164 { 17165 struct sip_pvt *p; 17166 int xmitres = 0; 17167 17168 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 17169 /* IF we have no IP, or this isn't to be monitored, return 17170 imeediately after clearing things out */ 17171 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 17172 struct sip_peer *peer_ptr = peer; 17173 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17174 } 17175 peer->lastms = 0; 17176 peer->call = NULL; 17177 return 0; 17178 } 17179 if (peer->call) { 17180 if (sipdebug) 17181 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 17182 sip_destroy(peer->call); 17183 } 17184 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 17185 return -1; 17186 17187 p->sa = peer->addr; 17188 p->recv = peer->addr; 17189 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 17190 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 17191 17192 /* Send OPTIONs to peer's fullcontact */ 17193 if (!ast_strlen_zero(peer->fullcontact)) 17194 ast_string_field_set(p, fullcontact, peer->fullcontact); 17195 17196 if (!ast_strlen_zero(peer->tohost)) 17197 ast_string_field_set(p, tohost, peer->tohost); 17198 else 17199 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 17200 17201 /* Recalculate our side, and recalculate Call ID */ 17202 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 17203 p->ourip = __ourip; 17204 build_via(p); 17205 build_callid_pvt(p); 17206 17207 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 17208 struct sip_peer *peer_ptr = peer; 17209 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17210 } 17211 17212 p->relatedpeer = ASTOBJ_REF(peer); 17213 ast_set_flag(&p->flags[0], SIP_OUTGOING); 17214 #ifdef VOCAL_DATA_HACK 17215 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 17216 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 17217 #else 17218 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 17219 #endif 17220 gettimeofday(&peer->ps, NULL); 17221 if (xmitres == XMIT_ERROR) { 17222 sip_poke_noanswer(ASTOBJ_REF(peer)); /* Immediately unreachable, network problems */ 17223 } else { 17224 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 17225 struct sip_peer *peer_ptr = peer; 17226 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17227 } 17228 peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer)); 17229 if (peer->pokeexpire == -1) { 17230 struct sip_peer *peer_ptr = peer; 17231 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17232 } 17233 } 17234 17235 return 0; 17236 }
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 8512 of file chan_sip.c.
References ASTOBJ_UNREF, 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().
08513 { 08514 struct sip_peer *peer = (struct sip_peer *) data; 08515 08516 peer->pokeexpire = -1; 08517 08518 sip_poke_peer(peer); 08519 08520 ASTOBJ_UNREF(peer, sip_destroy_peer); 08521 08522 return 0; 08523 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 10922 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, name, peerl, RESULT_SHOWUSAGE, sip_destroy_peer(), SIP_PAGE2_RTCACHEFRIENDS, and TRUE.
10923 { 10924 struct sip_peer *peer; 10925 struct sip_user *user; 10926 int pruneuser = FALSE; 10927 int prunepeer = FALSE; 10928 int multi = FALSE; 10929 char *name = NULL; 10930 regex_t regexbuf; 10931 10932 switch (argc) { 10933 case 4: 10934 if (!strcasecmp(argv[3], "user")) 10935 return RESULT_SHOWUSAGE; 10936 if (!strcasecmp(argv[3], "peer")) 10937 return RESULT_SHOWUSAGE; 10938 if (!strcasecmp(argv[3], "like")) 10939 return RESULT_SHOWUSAGE; 10940 if (!strcasecmp(argv[3], "all")) { 10941 multi = TRUE; 10942 pruneuser = prunepeer = TRUE; 10943 } else { 10944 pruneuser = prunepeer = TRUE; 10945 name = argv[3]; 10946 } 10947 break; 10948 case 5: 10949 if (!strcasecmp(argv[4], "like")) 10950 return RESULT_SHOWUSAGE; 10951 if (!strcasecmp(argv[3], "all")) 10952 return RESULT_SHOWUSAGE; 10953 if (!strcasecmp(argv[3], "like")) { 10954 multi = TRUE; 10955 name = argv[4]; 10956 pruneuser = prunepeer = TRUE; 10957 } else if (!strcasecmp(argv[3], "user")) { 10958 pruneuser = TRUE; 10959 if (!strcasecmp(argv[4], "all")) 10960 multi = TRUE; 10961 else 10962 name = argv[4]; 10963 } else if (!strcasecmp(argv[3], "peer")) { 10964 prunepeer = TRUE; 10965 if (!strcasecmp(argv[4], "all")) 10966 multi = TRUE; 10967 else 10968 name = argv[4]; 10969 } else 10970 return RESULT_SHOWUSAGE; 10971 break; 10972 case 6: 10973 if (strcasecmp(argv[4], "like")) 10974 return RESULT_SHOWUSAGE; 10975 if (!strcasecmp(argv[3], "user")) { 10976 pruneuser = TRUE; 10977 name = argv[5]; 10978 } else if (!strcasecmp(argv[3], "peer")) { 10979 prunepeer = TRUE; 10980 name = argv[5]; 10981 } else 10982 return RESULT_SHOWUSAGE; 10983 break; 10984 default: 10985 return RESULT_SHOWUSAGE; 10986 } 10987 10988 if (multi && name) { 10989 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 10990 return RESULT_SHOWUSAGE; 10991 } 10992 10993 if (multi) { 10994 if (prunepeer) { 10995 int pruned = 0; 10996 10997 ASTOBJ_CONTAINER_WRLOCK(&peerl); 10998 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10999 ASTOBJ_RDLOCK(iterator); 11000 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 11001 ASTOBJ_UNLOCK(iterator); 11002 continue; 11003 }; 11004 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 11005 ASTOBJ_MARK(iterator); 11006 pruned++; 11007 } 11008 ASTOBJ_UNLOCK(iterator); 11009 } while (0) ); 11010 if (pruned) { 11011 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 11012 ast_cli(fd, "%d peers pruned.\n", pruned); 11013 } else 11014 ast_cli(fd, "No peers found to prune.\n"); 11015 ASTOBJ_CONTAINER_UNLOCK(&peerl); 11016 } 11017 if (pruneuser) { 11018 int pruned = 0; 11019 11020 ASTOBJ_CONTAINER_WRLOCK(&userl); 11021 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 11022 ASTOBJ_RDLOCK(iterator); 11023 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 11024 ASTOBJ_UNLOCK(iterator); 11025 continue; 11026 }; 11027 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 11028 ASTOBJ_MARK(iterator); 11029 pruned++; 11030 } 11031 ASTOBJ_UNLOCK(iterator); 11032 } while (0) ); 11033 if (pruned) { 11034 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 11035 ast_cli(fd, "%d users pruned.\n", pruned); 11036 } else 11037 ast_cli(fd, "No users found to prune.\n"); 11038 ASTOBJ_CONTAINER_UNLOCK(&userl); 11039 } 11040 } else { 11041 if (prunepeer) { 11042 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 11043 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 11044 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 11045 ASTOBJ_CONTAINER_LINK(&peerl, peer); 11046 } else 11047 ast_cli(fd, "Peer '%s' pruned.\n", name); 11048 ASTOBJ_UNREF(peer, sip_destroy_peer); 11049 } else 11050 ast_cli(fd, "Peer '%s' not found.\n", name); 11051 } 11052 if (pruneuser) { 11053 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 11054 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 11055 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 11056 ASTOBJ_CONTAINER_LINK(&userl, user); 11057 } else 11058 ast_cli(fd, "User '%s' pruned.\n", name); 11059 ASTOBJ_UNREF(user, sip_destroy_user); 11060 } else 11061 ast_cli(fd, "User '%s' not found.\n", name); 11062 } 11063 } 11064 11065 return RESULT_SUCCESS; 11066 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
Read SIP RTP from channel.
Definition at line 4619 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, ast_channel::name, 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().
04620 { 04621 struct ast_frame *fr; 04622 struct sip_pvt *p = ast->tech_pvt; 04623 int faxdetected = FALSE; 04624 04625 ast_mutex_lock(&p->lock); 04626 fr = sip_rtp_read(ast, p, &faxdetected); 04627 p->lastrtprx = time(NULL); 04628 04629 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04630 /* 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 */ 04631 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04632 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04633 if (!p->pendinginvite) { 04634 if (option_debug > 2) 04635 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04636 p->t38.state = T38_LOCAL_REINVITE; 04637 transmit_reinvite_with_t38_sdp(p); 04638 if (option_debug > 1) 04639 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04640 } 04641 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04642 if (option_debug > 2) 04643 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04644 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04645 } 04646 } 04647 04648 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 04649 if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 04650 fr = &ast_null_frame; 04651 } 04652 04653 ast_mutex_unlock(&p->lock); 04654 return fr; 04655 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static] |
The real destination address for a write.
Definition at line 1812 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().
01813 { 01814 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01815 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 8315 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().
08316 { 08317 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 08318 return p->refer ? 1 : 0; 08319 }
static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 8052 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().
08053 { 08054 08055 /* if we are here, our registration timed out, so we'll just do it over */ 08056 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 08057 struct sip_pvt *p; 08058 int res; 08059 08060 /* if we couldn't get a reference to the registry object, punt */ 08061 if (!r) 08062 return 0; 08063 08064 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 08065 if (r->call) { 08066 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 08067 in the single SIP manager thread. */ 08068 p = r->call; 08069 ast_mutex_lock(&p->lock); 08070 if (p->registry) 08071 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 08072 r->call = NULL; 08073 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 08074 /* Pretend to ACK anything just in case */ 08075 __sip_pretend_ack(p); 08076 ast_mutex_unlock(&p->lock); 08077 } 08078 /* If we have a limit, stop registration and give up */ 08079 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 08080 /* Ok, enough is enough. Don't try any more */ 08081 /* We could add an external notification here... 08082 steal it from app_voicemail :-) */ 08083 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 08084 r->regstate = REG_STATE_FAILED; 08085 } else { 08086 r->regstate = REG_STATE_UNREGISTERED; 08087 r->timeout = -1; 08088 r->needdns = TRUE; 08089 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 08090 } 08091 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)); 08092 ASTOBJ_UNREF(r, sip_registry_destroy); 08093 return 0; 08094 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4959 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::contact, FALSE, free, hostname, INITIAL_CSEQ, LOG_ERROR, regl, secret, sip_registry_destroy(), TRUE, and username.
04960 { 04961 struct sip_registry *reg; 04962 int portnum = 0; 04963 char username[256] = ""; 04964 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04965 char *porta=NULL; 04966 char *contact=NULL; 04967 04968 if (!value) 04969 return -1; 04970 ast_copy_string(username, value, sizeof(username)); 04971 /* First split around the last '@' then parse the two components. */ 04972 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04973 if (hostname) 04974 *hostname++ = '\0'; 04975 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04976 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04977 return -1; 04978 } 04979 /* split user[:secret[:authuser]] */ 04980 secret = strchr(username, ':'); 04981 if (secret) { 04982 *secret++ = '\0'; 04983 authuser = strchr(secret, ':'); 04984 if (authuser) 04985 *authuser++ = '\0'; 04986 } 04987 /* split host[:port][/contact] */ 04988 contact = strchr(hostname, '/'); 04989 if (contact) 04990 *contact++ = '\0'; 04991 if (ast_strlen_zero(contact)) 04992 contact = "s"; 04993 porta = strchr(hostname, ':'); 04994 if (porta) { 04995 *porta++ = '\0'; 04996 portnum = atoi(porta); 04997 if (portnum == 0) { 04998 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04999 return -1; 05000 } 05001 } 05002 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 05003 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 05004 return -1; 05005 } 05006 05007 if (ast_string_field_init(reg, 256)) { 05008 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 05009 free(reg); 05010 return -1; 05011 } 05012 05013 regobjs++; 05014 ASTOBJ_INIT(reg); 05015 ast_string_field_set(reg, contact, contact); 05016 if (!ast_strlen_zero(username)) 05017 ast_string_field_set(reg, username, username); 05018 if (hostname) 05019 ast_string_field_set(reg, hostname, hostname); 05020 if (authuser) 05021 ast_string_field_set(reg, authuser, authuser); 05022 if (secret) 05023 ast_string_field_set(reg, secret, secret); 05024 reg->expire = -1; 05025 reg->timeout = -1; 05026 reg->refresh = default_expiry; 05027 reg->portno = portnum; 05028 reg->callid_valid = FALSE; 05029 reg->ocseq = INITIAL_CSEQ; 05030 reg->needdns = TRUE; 05031 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 05032 ASTOBJ_UNREF(reg,sip_registry_destroy); 05033 return 0; 05034 }
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 3219 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, sched, sip_destroy(), sip_registry::timeout, and sip_registry::username.
Referenced by __sip_destroy(), handle_response_register(), sip_reg_timeout(), sip_register(), sip_reregister(), and unload_module().
03220 { 03221 /* Really delete */ 03222 if (option_debug > 2) 03223 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 03224 03225 if (reg->call) { 03226 /* Clear registry before destroying to ensure 03227 we don't get reentered trying to grab the registry lock */ 03228 reg->call->registry = NULL; 03229 if (option_debug > 2) 03230 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 03231 sip_destroy(reg->call); 03232 } 03233 AST_SCHED_DEL(sched, reg->expire); 03234 AST_SCHED_DEL(sched, reg->timeout); 03235 ast_string_field_free_memory(reg); 03236 regobjs--; 03237 free(reg); 03238 03239 }
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 12878 of file chan_sip.c.
References ast_mutex_lock, ast_mutex_unlock, ast_set_flag, check_pendings(), sip_pvt::flags, sip_pvt::lock, SIP_NEEDREINVITE, and sip_pvt::waitid.
Referenced by handle_response_invite().
12879 { 12880 struct sip_pvt *p = (struct sip_pvt *) data; 12881 12882 ast_mutex_lock(&p->lock); /* called from schedule thread which requires a lock */ 12883 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 12884 p->waitid = -1; 12885 check_pendings(p); 12886 ast_mutex_unlock(&p->lock); 12887 return 0; 12888 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 19391 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().
19392 { 19393 ast_mutex_lock(&sip_reload_lock); 19394 if (sip_reloading) 19395 ast_verbose("Previous SIP reload not yet done\n"); 19396 else { 19397 sip_reloading = TRUE; 19398 if (fd) 19399 sip_reloadreason = CHANNEL_CLI_RELOAD; 19400 else 19401 sip_reloadreason = CHANNEL_MODULE_RELOAD; 19402 } 19403 ast_mutex_unlock(&sip_reload_lock); 19404 restart_monitor(); 19405 19406 return 0; 19407 }
static struct ast_channel * sip_request_call | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
Definition at line 17348 of file chan_sip.c.
References __ourip, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, 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, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::options, sip_pvt::peername, restart_monitor(), sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), SIP_PAGE2_OUTGOING_CALL, and username.
17349 { 17350 int oldformat; 17351 struct sip_pvt *p; 17352 struct ast_channel *tmpc = NULL; 17353 char *ext, *host; 17354 char tmp[256]; 17355 char *dest = data; 17356 17357 oldformat = format; 17358 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 17359 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)); 17360 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 17361 return NULL; 17362 } 17363 if (option_debug) 17364 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 17365 17366 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 17367 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 17368 *cause = AST_CAUSE_SWITCH_CONGESTION; 17369 return NULL; 17370 } 17371 17372 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 17373 17374 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 17375 sip_destroy(p); 17376 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 17377 *cause = AST_CAUSE_SWITCH_CONGESTION; 17378 return NULL; 17379 } 17380 17381 ast_copy_string(tmp, dest, sizeof(tmp)); 17382 host = strchr(tmp, '@'); 17383 if (host) { 17384 *host++ = '\0'; 17385 ext = tmp; 17386 } else { 17387 ext = strchr(tmp, '/'); 17388 if (ext) 17389 *ext++ = '\0'; 17390 host = tmp; 17391 } 17392 17393 if (create_addr(p, host, NULL)) { 17394 *cause = AST_CAUSE_UNREGISTERED; 17395 if (option_debug > 2) 17396 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registered\n"); 17397 sip_destroy(p); 17398 return NULL; 17399 } 17400 if (ast_strlen_zero(p->peername) && ext) 17401 ast_string_field_set(p, peername, ext); 17402 /* Recalculate our side, and recalculate Call ID */ 17403 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 17404 p->ourip = __ourip; 17405 build_via(p); 17406 build_callid_pvt(p); 17407 17408 /* We have an extension to call, don't use the full contact here */ 17409 /* This to enable dialing registered peers with extension dialling, 17410 like SIP/peername/extension 17411 SIP/peername will still use the full contact */ 17412 if (ext) { 17413 ast_string_field_set(p, username, ext); 17414 ast_string_field_free(p, fullcontact); 17415 } 17416 #if 0 17417 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 17418 #endif 17419 p->prefcodec = oldformat; /* Format for this call */ 17420 ast_mutex_lock(&p->lock); 17421 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 17422 ast_mutex_unlock(&p->lock); 17423 if (!tmpc) 17424 sip_destroy(p); 17425 ast_update_use_count(); 17426 restart_monitor(); 17427 return tmpc; 17428 }
static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 8020 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().
08021 { 08022 /* if we are here, we know that we need to reregister. */ 08023 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 08024 08025 /* if we couldn't get a reference to the registry object, punt */ 08026 if (!r) 08027 return 0; 08028 08029 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 08030 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 08031 /* Since registry's are only added/removed by the the monitor thread, this 08032 may be overkill to reference/dereference at all here */ 08033 if (sipdebug) 08034 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 08035 08036 r->expire = -1; 08037 __sip_do_register(r); 08038 ASTOBJ_UNREF(r, sip_registry_destroy); 08039 return 0; 08040 }
static struct ast_frame * sip_rtp_read | ( | struct ast_channel * | ast, | |
struct sip_pvt * | p, | |||
int * | faxdetect | |||
) | [static] |
Read RTP from network.
Definition at line 4547 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, sip_pvt::jointcapability, LOG_DEBUG, ast_channel::name, 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, sip_pvt::t38, t38properties::t38support, sip_pvt::udptl, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by sip_read().
04548 { 04549 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04550 struct ast_frame *f; 04551 04552 if (!p->rtp) { 04553 /* We have no RTP allocated for this channel */ 04554 return &ast_null_frame; 04555 } 04556 04557 switch(ast->fdno) { 04558 case 0: 04559 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04560 break; 04561 case 1: 04562 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04563 break; 04564 case 2: 04565 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04566 break; 04567 case 3: 04568 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04569 break; 04570 case 5: 04571 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04572 break; 04573 default: 04574 f = &ast_null_frame; 04575 } 04576 /* Don't forward RFC2833 if we're not supposed to */ 04577 if (f && (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && 04578 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) { 04579 ast_log(LOG_DEBUG,"Ignoring DTMF (%c) RTP frame because dtmfmode is not RFC2833\n", f->subclass); 04580 return &ast_null_frame; 04581 } 04582 04583 /* We already hold the channel lock */ 04584 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 04585 return f; 04586 04587 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04588 if (!(f->subclass & p->jointcapability)) { 04589 if (option_debug) { 04590 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04591 ast_getformatname(f->subclass), p->owner->name); 04592 } 04593 return &ast_null_frame; 04594 } 04595 if (option_debug) 04596 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04597 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04598 ast_set_read_format(p->owner, p->owner->readformat); 04599 ast_set_write_format(p->owner, p->owner->writeformat); 04600 } 04601 04602 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04603 f = ast_dsp_process(p->owner, p->vad, f); 04604 if (f && f->frametype == AST_FRAME_DTMF) { 04605 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04606 if (option_debug) 04607 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04608 *faxdetect = 1; 04609 } else if (option_debug) { 04610 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04611 } 04612 } 04613 } 04614 04615 return f; 04616 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2192 of file chan_sip.c.
References __sip_autodestruct(), append_history, ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ast_verbose(), sip_pvt::callid, sip_pvt::flags, sip_pvt::method, sched, sip_debug_test_pvt(), sip_methods, SIP_NO_HISTORY, and sip_pvt::timer_t1.
Referenced by __sip_autodestruct(), auto_congest(), cb_extensionstate(), 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(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), sip_sipredirect(), and transmit_fake_auth_response().
02193 { 02194 if (ms < 0) { 02195 if (p->timer_t1 == 0) 02196 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02197 ms = p->timer_t1 * 64; 02198 } 02199 if (sip_debug_test_pvt(p)) 02200 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02201 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02202 append_history(p, "SchedDestroy", "%d ms", ms); 02203 02204 AST_SCHED_DEL(sched, p->autokillid); 02205 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02206 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 19348 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, regl, sched, and sip_reregister().
Referenced by load_module(), and sip_do_reload().
19349 { 19350 int ms; 19351 int regspacing; 19352 if (!regobjs) 19353 return; 19354 regspacing = default_expiry * 1000/regobjs; 19355 if (regspacing > 100) 19356 regspacing = 100; 19357 ms = regspacing; 19358 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 19359 ASTOBJ_WRLOCK(iterator); 19360 AST_SCHED_DEL(sched, iterator->expire); 19361 ms += regspacing; 19362 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 19363 ASTOBJ_UNLOCK(iterator); 19364 } while (0) 19365 ); 19366 }
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 16856 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 handle_request_subscribe().
16857 { 16858 /* Called with peerl lock, but releases it */ 16859 struct sip_pvt *p; 16860 int newmsgs, oldmsgs; 16861 16862 /* Do we have an IP address? If not, skip this peer */ 16863 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 16864 return 0; 16865 16866 /* Check for messages */ 16867 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 16868 16869 peer->lastmsgcheck = time(NULL); 16870 16871 /* Return now if it's the same thing we told them last time */ 16872 if (!force && ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 16873 return 0; 16874 } 16875 16876 16877 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 16878 16879 if (peer->mwipvt) { 16880 /* Base message on subscription */ 16881 p = peer->mwipvt; 16882 } else { 16883 /* Build temporary dialog for this message */ 16884 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 16885 return -1; 16886 if (create_addr_from_peer(p, peer)) { 16887 /* Maybe they're not registered, etc. */ 16888 sip_destroy(p); 16889 return 0; 16890 } 16891 /* Recalculate our side, and recalculate Call ID */ 16892 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16893 p->ourip = __ourip; 16894 build_via(p); 16895 build_callid_pvt(p); 16896 /* Destroy this session after 32 secs */ 16897 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16898 } 16899 /* Send MWI */ 16900 ast_set_flag(&p->flags[0], SIP_OUTGOING); 16901 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 16902 return 0; 16903 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 4023 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.
04024 { 04025 struct sip_pvt *p = ast->tech_pvt; 04026 int res = 0; 04027 04028 ast_mutex_lock(&p->lock); 04029 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 04030 case SIP_DTMF_INBAND: 04031 res = -1; /* Tell Asterisk to generate inband indications */ 04032 break; 04033 case SIP_DTMF_RFC2833: 04034 if (p->rtp) 04035 ast_rtp_senddigit_begin(p->rtp, digit); 04036 break; 04037 default: 04038 break; 04039 } 04040 ast_mutex_unlock(&p->lock); 04041 04042 return res; 04043 }
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 4047 of file chan_sip.c.
References ast_mutex_lock, ast_mutex_unlock, ast_rtp_senddigit_end(), ast_test_flag, sip_pvt::flags, sip_pvt::lock, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, and transmit_info_with_digit().
04048 { 04049 struct sip_pvt *p = ast->tech_pvt; 04050 int res = 0; 04051 04052 ast_mutex_lock(&p->lock); 04053 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 04054 case SIP_DTMF_INFO: 04055 transmit_info_with_digit(p, digit, duration); 04056 break; 04057 case SIP_DTMF_RFC2833: 04058 if (p->rtp) 04059 ast_rtp_senddigit_end(p->rtp, digit); 04060 break; 04061 case SIP_DTMF_INBAND: 04062 res = -1; /* Tell Asterisk to stop inband indications */ 04063 break; 04064 } 04065 ast_mutex_unlock(&p->lock); 04066 04067 return res; 04068 }
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 2497 of file chan_sip.c.
References ast_verbose(), debug, ast_channel::name, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().
02498 { 02499 struct sip_pvt *p = ast->tech_pvt; 02500 int debug = sip_debug_test_pvt(p); 02501 02502 if (debug) 02503 ast_verbose("Sending text %s on %s\n", text, ast->name); 02504 if (!p) 02505 return -1; 02506 /* NOT ast_strlen_zero, because a zero-length message is specifically 02507 * allowed by RFC 3428 (See section 10, Examples) */ 02508 if (!text) 02509 return 0; 02510 if (debug) 02511 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02512 transmit_message_with_text(p, text); 02513 return 0; 02514 }
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 19078 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, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, 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(), sip_pvt::vredirip, and sip_pvt::vrtp.
Referenced by sip_fixup().
19079 { 19080 struct sip_pvt *p; 19081 int changed = 0; 19082 19083 p = chan->tech_pvt; 19084 if (!p) 19085 return -1; 19086 19087 /* Disable early RTP bridge */ 19088 if (!ast_bridged_channel(chan) && !global_directrtpsetup) /* We are in early state */ 19089 return 0; 19090 19091 ast_mutex_lock(&p->lock); 19092 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 19093 /* If we're destroyed, don't bother */ 19094 ast_mutex_unlock(&p->lock); 19095 return 0; 19096 } 19097 19098 /* if this peer cannot handle reinvites of the media stream to devices 19099 that are known to be behind a NAT, then stop the process now 19100 */ 19101 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 19102 ast_mutex_unlock(&p->lock); 19103 return 0; 19104 } 19105 19106 if (rtp) { 19107 changed |= ast_rtp_get_peer(rtp, &p->redirip); 19108 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 19109 memset(&p->redirip, 0, sizeof(p->redirip)); 19110 changed = 1; 19111 } 19112 if (vrtp) { 19113 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 19114 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 19115 memset(&p->vredirip, 0, sizeof(p->vredirip)); 19116 changed = 1; 19117 } 19118 if (codecs) { 19119 if (p->redircodecs != codecs && (p->jointcapability & codecs) != p->jointcapability) { 19120 p->redircodecs = codecs; 19121 p->jointcapability &= codecs; 19122 p->capability &= codecs; 19123 changed = 1; 19124 } 19125 } 19126 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 19127 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 19128 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 19129 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 19130 if (option_debug) 19131 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)); 19132 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 19133 if (option_debug > 2) { 19134 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)); 19135 } 19136 transmit_reinvite_with_sdp(p); 19137 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 19138 if (option_debug > 2) { 19139 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)); 19140 } 19141 /* We have a pending Invite. Send re-invite when we're done with the invite */ 19142 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 19143 } 19144 } 19145 /* Reset lastrtprx timer */ 19146 p->lastrtprx = p->lastrtptx = time(NULL); 19147 ast_mutex_unlock(&p->lock); 19148 return 0; 19149 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 18905 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, sip_pvt::ourip, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), sip_pvt::udptl, and sip_pvt::udptlredirip.
18906 { 18907 struct sip_pvt *p; 18908 18909 p = chan->tech_pvt; 18910 if (!p) 18911 return -1; 18912 ast_mutex_lock(&p->lock); 18913 if (udptl) 18914 ast_udptl_get_peer(udptl, &p->udptlredirip); 18915 else 18916 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18917 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 18918 if (!p->pendinginvite) { 18919 if (option_debug > 2) { 18920 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); 18921 } 18922 transmit_reinvite_with_t38_sdp(p); 18923 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18924 if (option_debug > 2) { 18925 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); 18926 } 18927 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18928 } 18929 } 18930 /* Reset lastrtprx timer */ 18931 p->lastrtprx = p->lastrtptx = time(NULL); 18932 ast_mutex_unlock(&p->lock); 18933 return 0; 18934 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 11803 of file chan_sip.c.
References sip_pvt::allowtransfer, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock, ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::capability, sip_pvt::cid_num, dtmfmode2str(), sip_pvt::flags, sip_route::hop, iflist, iflock, sip_pvt::jointcapability, sip_pvt::lastmsg, len(), sip_pvt::maxcallbitrate, ast_channel::name, 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, 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.
11804 { 11805 struct sip_pvt *cur; 11806 size_t len; 11807 int found = 0; 11808 11809 if (argc != 4) 11810 return RESULT_SHOWUSAGE; 11811 len = strlen(argv[3]); 11812 ast_mutex_lock(&iflock); 11813 for (cur = iflist; cur; cur = cur->next) { 11814 if (!strncasecmp(cur->callid, argv[3], len)) { 11815 char formatbuf[SIPBUFSIZE/2]; 11816 ast_cli(fd,"\n"); 11817 if (cur->subscribed != NONE) 11818 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 11819 else 11820 ast_cli(fd, " * SIP Call\n"); 11821 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 11822 ast_cli(fd, " Call-ID: %s\n", cur->callid); 11823 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 11824 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 11825 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 11826 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 11827 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 11828 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 11829 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 11830 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 11831 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 11832 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 11833 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 11834 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)" ); 11835 ast_cli(fd, " Our Tag: %s\n", cur->tag); 11836 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 11837 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 11838 if (!ast_strlen_zero(cur->username)) 11839 ast_cli(fd, " Username: %s\n", cur->username); 11840 if (!ast_strlen_zero(cur->peername)) 11841 ast_cli(fd, " Peername: %s\n", cur->peername); 11842 if (!ast_strlen_zero(cur->uri)) 11843 ast_cli(fd, " Original uri: %s\n", cur->uri); 11844 if (!ast_strlen_zero(cur->cid_num)) 11845 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 11846 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 11847 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 11848 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 11849 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 11850 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 11851 ast_cli(fd, " SIP Options: "); 11852 if (cur->sipoptions) { 11853 int x; 11854 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 11855 if (cur->sipoptions & sip_options[x].id) 11856 ast_cli(fd, "%s ", sip_options[x].text); 11857 } 11858 } else 11859 ast_cli(fd, "(none)\n"); 11860 ast_cli(fd, "\n\n"); 11861 found++; 11862 } 11863 } 11864 ast_mutex_unlock(&iflock); 11865 if (!found) 11866 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11867 return RESULT_SUCCESS; 11868 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 11589 of file chan_sip.c.
References __sip_show_channels().
11590 { 11591 return __sip_show_channels(fd, argc, argv, 0); 11592 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 11100 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::list, domain::mode, RESULT_SUCCESS, and S_OR.
11101 { 11102 struct domain *d; 11103 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 11104 11105 if (AST_LIST_EMPTY(&domain_list)) { 11106 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 11107 return RESULT_SUCCESS; 11108 } else { 11109 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 11110 AST_LIST_LOCK(&domain_list); 11111 AST_LIST_TRAVERSE(&domain_list, d, list) 11112 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 11113 domain_mode_to_text(d->mode)); 11114 AST_LIST_UNLOCK(&domain_list); 11115 ast_cli(fd, "\n"); 11116 return RESULT_SUCCESS; 11117 } 11118 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 11871 of file chan_sip.c.
References ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock, sip_pvt::callid, sip_pvt::history, iflist, iflock, len(), sip_pvt::next, NONE, RESULT_SHOWUSAGE, and sip_pvt::subscribed.
11872 { 11873 struct sip_pvt *cur; 11874 size_t len; 11875 int found = 0; 11876 11877 if (argc != 4) 11878 return RESULT_SHOWUSAGE; 11879 if (!recordhistory) 11880 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 11881 len = strlen(argv[3]); 11882 ast_mutex_lock(&iflock); 11883 for (cur = iflist; cur; cur = cur->next) { 11884 if (!strncasecmp(cur->callid, argv[3], len)) { 11885 struct sip_history *hist; 11886 int x = 0; 11887 11888 ast_cli(fd,"\n"); 11889 if (cur->subscribed != NONE) 11890 ast_cli(fd, " * Subscription\n"); 11891 else 11892 ast_cli(fd, " * SIP Call\n"); 11893 if (cur->history) 11894 AST_LIST_TRAVERSE(cur->history, hist, list) 11895 ast_cli(fd, "%d. %s\n", ++x, hist->event); 11896 if (x == 0) 11897 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 11898 found++; 11899 } 11900 } 11901 ast_mutex_unlock(&iflock); 11902 if (!found) 11903 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11904 return RESULT_SUCCESS; 11905 }
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 10525 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.
10526 { 10527 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 10528 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 10529 char ilimits[40]; 10530 char iused[40]; 10531 int showall = FALSE; 10532 10533 if (argc < 3) 10534 return RESULT_SHOWUSAGE; 10535 10536 if (argc == 4 && !strcmp(argv[3],"all")) 10537 showall = TRUE; 10538 10539 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 10540 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10541 ASTOBJ_RDLOCK(iterator); 10542 if (iterator->call_limit) 10543 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 10544 else 10545 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 10546 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 10547 if (showall || iterator->call_limit) 10548 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 10549 ASTOBJ_UNLOCK(iterator); 10550 } while (0) ); 10551 10552 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 10553 10554 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10555 ASTOBJ_RDLOCK(iterator); 10556 if (iterator->call_limit) 10557 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 10558 else 10559 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 10560 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 10561 if (showall || iterator->call_limit) 10562 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 10563 ASTOBJ_UNLOCK(iterator); 10564 } while (0) ); 10565 10566 return RESULT_SUCCESS; 10567 #undef FORMAT 10568 #undef FORMAT2 10569 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 10846 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
10847 { 10848 char tmp[256]; 10849 if (argc != 3) 10850 return RESULT_SHOWUSAGE; 10851 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 10852 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 10853 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 10854 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 10855 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 10856 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 10857 return RESULT_SUCCESS; 10858 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 11152 of file chan_sip.c.
References _sip_show_peer().
11153 { 11154 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 11155 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 10702 of file chan_sip.c.
References _sip_show_peers().
10703 { 10704 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 10705 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 11425 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.
11426 { 11427 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 11428 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 11429 char host[80]; 11430 char tmpdat[256]; 11431 struct tm tm; 11432 11433 11434 if (argc != 3) 11435 return RESULT_SHOWUSAGE; 11436 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 11437 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 11438 ASTOBJ_RDLOCK(iterator); 11439 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 11440 if (iterator->regtime) { 11441 ast_localtime(&iterator->regtime, &tm, NULL); 11442 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 11443 } else { 11444 tmpdat[0] = 0; 11445 } 11446 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 11447 ASTOBJ_UNLOCK(iterator); 11448 } while(0)); 11449 return RESULT_SUCCESS; 11450 #undef FORMAT 11451 #undef FORMAT2 11452 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 11455 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(), global_flags, nat2str(), print_codec_to_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, SIP_DTMF, SIP_NAT, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RFC2833_COMPENSATE, 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().
11456 { 11457 int realtimepeers; 11458 int realtimeusers; 11459 char codec_buf[SIPBUFSIZE]; 11460 11461 realtimepeers = ast_check_realtime("sippeers"); 11462 realtimeusers = ast_check_realtime("sipusers"); 11463 11464 if (argc != 3) 11465 return RESULT_SHOWUSAGE; 11466 ast_cli(fd, "\n\nGlobal Settings:\n"); 11467 ast_cli(fd, "----------------\n"); 11468 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 11469 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 11470 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 11471 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 11472 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 11473 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 11474 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 11475 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 11476 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 11477 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 11478 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 11479 ast_cli(fd, " Our auth realm %s\n", global_realm); 11480 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 11481 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 11482 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 11483 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 11484 ast_cli(fd, " User Agent: %s\n", global_useragent); 11485 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 11486 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 11487 ast_cli(fd, " Caller ID: %s\n", default_callerid); 11488 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 11489 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 11490 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 11491 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 11492 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 11493 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 11494 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 11495 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 11496 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 11497 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 11498 #endif 11499 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 11500 if (!realtimepeers && !realtimeusers) 11501 ast_cli(fd, " SIP realtime: Disabled\n" ); 11502 else 11503 ast_cli(fd, " SIP realtime: Enabled\n" ); 11504 11505 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 11506 ast_cli(fd, "---------------------------\n"); 11507 ast_cli(fd, " Codecs: "); 11508 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 11509 ast_cli(fd, "%s\n", codec_buf); 11510 ast_cli(fd, " Codec Order: "); 11511 print_codec_to_cli(fd, &default_prefs); 11512 ast_cli(fd, "\n"); 11513 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 11514 ast_cli(fd, " No premature media: %s\n", global_prematuremediafilter ? "Yes" : "No"); 11515 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 11516 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 11517 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 11518 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 11519 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 11520 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 11521 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 11522 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 11523 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 11524 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 11525 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 11526 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 11527 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 11528 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 11529 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 11530 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 11531 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 11532 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 11533 ast_cli(fd, "\nDefault Settings:\n"); 11534 ast_cli(fd, "-----------------\n"); 11535 ast_cli(fd, " Context: %s\n", default_context); 11536 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 11537 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 11538 ast_cli(fd, " Qualify: %d\n", default_qualify); 11539 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 11540 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" ); 11541 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 11542 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 11543 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 11544 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 11545 11546 11547 if (realtimepeers || realtimeusers) { 11548 ast_cli(fd, "\nRealtime SIP Settings:\n"); 11549 ast_cli(fd, "----------------------\n"); 11550 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 11551 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 11552 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 11553 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 11554 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 11555 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 11556 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 11557 } 11558 ast_cli(fd, "\n----\n"); 11559 return RESULT_SUCCESS; 11560 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 11595 of file chan_sip.c.
References __sip_show_channels().
11596 { 11597 return __sip_show_channels(fd, argc, argv, 1); 11598 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 11370 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.
11371 { 11372 char cbuf[256]; 11373 struct sip_user *user; 11374 struct ast_variable *v; 11375 int load_realtime; 11376 11377 if (argc < 4) 11378 return RESULT_SHOWUSAGE; 11379 11380 /* Load from realtime storage? */ 11381 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 11382 11383 user = find_user(argv[3], load_realtime); 11384 if (user) { 11385 ast_cli(fd,"\n\n"); 11386 ast_cli(fd, " * Name : %s\n", user->name); 11387 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 11388 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 11389 ast_cli(fd, " Context : %s\n", user->context); 11390 ast_cli(fd, " Language : %s\n", user->language); 11391 if (!ast_strlen_zero(user->accountcode)) 11392 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 11393 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 11394 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 11395 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 11396 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 11397 ast_cli(fd, " Call limit : %d\n", user->call_limit); 11398 ast_cli(fd, " Callgroup : "); 11399 print_group(fd, user->callgroup, 0); 11400 ast_cli(fd, " Pickupgroup : "); 11401 print_group(fd, user->pickupgroup, 0); 11402 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 11403 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 11404 ast_cli(fd, " Codec Order : ("); 11405 print_codec_to_cli(fd, &user->prefs); 11406 ast_cli(fd, ")\n"); 11407 11408 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 11409 if (user->chanvars) { 11410 ast_cli(fd, " Variables :\n"); 11411 for (v = user->chanvars ; v ; v = v->next) 11412 ast_cli(fd, " %s = %s\n", v->name, v->value); 11413 } 11414 ast_cli(fd,"\n"); 11415 ASTOBJ_UNREF(user,sip_destroy_user); 11416 } else { 11417 ast_cli(fd,"User %s not found.\n", argv[3]); 11418 ast_cli(fd,"\n"); 11419 } 11420 11421 return RESULT_SUCCESS; 11422 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 10625 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, nat2str(), RESULT_SHOWUSAGE, SIP_NAT, TRUE, and userl.
10626 { 10627 regex_t regexbuf; 10628 int havepattern = FALSE; 10629 10630 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 10631 10632 switch (argc) { 10633 case 5: 10634 if (!strcasecmp(argv[3], "like")) { 10635 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 10636 return RESULT_SHOWUSAGE; 10637 havepattern = TRUE; 10638 } else 10639 return RESULT_SHOWUSAGE; 10640 case 3: 10641 break; 10642 default: 10643 return RESULT_SHOWUSAGE; 10644 } 10645 10646 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 10647 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10648 ASTOBJ_RDLOCK(iterator); 10649 10650 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10651 ASTOBJ_UNLOCK(iterator); 10652 continue; 10653 } 10654 10655 ast_cli(fd, FORMAT, iterator->name, 10656 iterator->secret, 10657 iterator->accountcode, 10658 iterator->context, 10659 iterator->ha ? "Yes" : "No", 10660 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 10661 ASTOBJ_UNLOCK(iterator); 10662 } while (0) 10663 ); 10664 10665 if (havepattern) 10666 regfree(®exbuf); 10667 10668 return RESULT_SUCCESS; 10669 #undef FORMAT 10670 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 19262 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, and transmit_response_reliable().
Referenced by sip_transfer().
19263 { 19264 char *cdest; 19265 char *extension, *host, *port; 19266 char tmp[80]; 19267 19268 cdest = ast_strdupa(dest); 19269 19270 extension = strsep(&cdest, "@"); 19271 host = strsep(&cdest, ":"); 19272 port = strsep(&cdest, ":"); 19273 if (ast_strlen_zero(extension)) { 19274 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 19275 return 0; 19276 } 19277 19278 /* we'll issue the redirect message here */ 19279 if (!host) { 19280 char *localtmp; 19281 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 19282 if (ast_strlen_zero(tmp)) { 19283 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 19284 return 0; 19285 } 19286 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 19287 char lhost[80], lport[80]; 19288 memset(lhost, 0, sizeof(lhost)); 19289 memset(lport, 0, sizeof(lport)); 19290 localtmp++; 19291 /* This is okey because lhost and lport are as big as tmp */ 19292 sscanf(localtmp, "%80[^<>:; ]:%80[^<>:; ]", lhost, lport); 19293 if (ast_strlen_zero(lhost)) { 19294 ast_log(LOG_ERROR, "Can't find the host address\n"); 19295 return 0; 19296 } 19297 host = ast_strdupa(lhost); 19298 if (!ast_strlen_zero(lport)) { 19299 port = ast_strdupa(lport); 19300 } 19301 } 19302 } 19303 19304 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 19305 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 19306 19307 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 19308 sip_alreadygone(p); 19309 return 0; 19310 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 4071 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().
04072 { 04073 struct sip_pvt *p = ast->tech_pvt; 04074 int res; 04075 04076 if (dest == NULL) /* functions below do not take a NULL */ 04077 dest = ""; 04078 ast_mutex_lock(&p->lock); 04079 if (ast->_state == AST_STATE_RING) 04080 res = sip_sipredirect(p, dest); 04081 else 04082 res = transmit_refer(p, dest); 04083 ast_mutex_unlock(&p->lock); 04084 return res; 04085 }
static int sip_uri_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
Definition at line 14721 of file chan_sip.c.
References ast_strdupa, S_OR, sip_uri_headers_cmp(), and sip_uri_params_cmp().
Referenced by handle_request_invite().
14722 { 14723 char *uri1 = ast_strdupa(input1); 14724 char *uri2 = ast_strdupa(input2); 14725 char *host1; 14726 char *host2; 14727 char *params1; 14728 char *params2; 14729 char *headers1; 14730 char *headers2; 14731 14732 /* Strip off "sip:" from the URI. We know this is present 14733 * because it was checked back in parse_request() 14734 */ 14735 strsep(&uri1, ":"); 14736 strsep(&uri2, ":"); 14737 14738 if ((host1 = strchr(uri1, '@'))) { 14739 *host1++ = '\0'; 14740 } 14741 if ((host2 = strchr(uri2, '@'))) { 14742 *host2++ = '\0'; 14743 } 14744 14745 /* Check for mismatched username and passwords. This is the 14746 * only case-sensitive comparison of a SIP URI 14747 */ 14748 if ((host1 && !host2) || 14749 (host2 && !host1) || 14750 (host1 && host2 && strcmp(uri1, uri2))) { 14751 return 1; 14752 } 14753 14754 if (!host1) 14755 host1 = uri1; 14756 if (!host2) 14757 host2 = uri2; 14758 14759 /* Strip off the parameters and headers so we can compare 14760 * host and port 14761 */ 14762 14763 if ((params1 = strchr(host1, ';'))) { 14764 *params1++ = '\0'; 14765 } 14766 if ((params2 = strchr(host2, ';'))) { 14767 *params2++ = '\0'; 14768 } 14769 14770 /* Headers come after parameters, but there may be headers without 14771 * parameters, thus the S_OR 14772 */ 14773 if ((headers1 = strchr(S_OR(params1, host1), '?'))) { 14774 *headers1++ = '\0'; 14775 } 14776 if ((headers2 = strchr(S_OR(params2, host2), '?'))) { 14777 *headers2++ = '\0'; 14778 } 14779 14780 /* Now the host/port are properly isolated. We can get by with a string comparison 14781 * because the SIP URI checking rules have some interesting exceptions that make 14782 * this possible. I will note 2 in particular 14783 * 1. hostnames which resolve to the same IP address as well as a hostname and its 14784 * IP address are not considered a match with SIP URI's. 14785 * 2. If one URI specifies a port and the other does not, then the URIs do not match. 14786 * This includes if one URI explicitly contains port 5060 and the other implies it 14787 * by not having a port specified. 14788 */ 14789 14790 if (strcasecmp(host1, host2)) { 14791 return 1; 14792 } 14793 14794 /* Headers have easier rules to follow, so do those first */ 14795 if (sip_uri_headers_cmp(headers1, headers2)) { 14796 return 1; 14797 } 14798 14799 /* And now the parameters. Ugh */ 14800 return sip_uri_params_cmp(params1, params2); 14801 }
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 14675 of file chan_sip.c.
References ast_strdupa, and ast_strlen_zero().
Referenced by sip_uri_cmp().
14676 { 14677 char *headers1 = NULL; 14678 char *headers2 = NULL; 14679 int zerolength1 = 0; 14680 int zerolength2 = 0; 14681 int different = 0; 14682 char *header1; 14683 14684 if (ast_strlen_zero(input1)) { 14685 zerolength1 = 1; 14686 } else { 14687 headers1 = ast_strdupa(input1); 14688 } 14689 14690 if (ast_strlen_zero(input2)) { 14691 zerolength2 = 1; 14692 } else { 14693 headers2 = ast_strdupa(input2); 14694 } 14695 14696 if ((zerolength1 && !zerolength2) || 14697 (zerolength2 && !zerolength1)) 14698 return 1; 14699 14700 if (zerolength1 && zerolength2) 14701 return 0; 14702 14703 /* At this point, we can definitively state that both inputs are 14704 * not zero-length. First, one more optimization. If the length 14705 * of the headers is not equal, then we definitely have no match 14706 */ 14707 if (strlen(headers1) != strlen(headers2)) { 14708 return 1; 14709 } 14710 14711 for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) { 14712 if (!strcasestr(headers2, header1)) { 14713 different = 1; 14714 break; 14715 } 14716 } 14717 14718 return different; 14719 }
static int sip_uri_params_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
helper routine for sip_uri_cmp
This takes the parameters from two SIP URIs and determines if the URIs match. The rules for parameters *suck*. Here's a breakdown 1. If a parameter appears in both URIs, then they must have the same value in order for the URIs to match 2. If one URI has a user, maddr, ttl, or method parameter, then the other URI must also have that parameter and must have the same value in order for the URIs to match 3. All other headers appearing in only one URI are not considered when determining if URIs match
input1 | Parameters from URI 1 | |
input2 | Parameters from URI 2 |
Definition at line 14535 of file chan_sip.c.
References ast_strdupa, and ast_strlen_zero().
Referenced by sip_uri_cmp().
14536 { 14537 char *params1 = NULL; 14538 char *params2 = NULL; 14539 char *pos1; 14540 char *pos2; 14541 int zerolength1 = 0; 14542 int zerolength2 = 0; 14543 int maddrmatch = 0; 14544 int ttlmatch = 0; 14545 int usermatch = 0; 14546 int methodmatch = 0; 14547 14548 if (ast_strlen_zero(input1)) { 14549 zerolength1 = 1; 14550 } else { 14551 params1 = ast_strdupa(input1); 14552 } 14553 if (ast_strlen_zero(input2)) { 14554 zerolength2 = 1; 14555 } else { 14556 params2 = ast_strdupa(input2); 14557 } 14558 14559 /*Quick optimization. If both params are zero-length, then 14560 * they match 14561 */ 14562 if (zerolength1 && zerolength2) { 14563 return 0; 14564 } 14565 14566 pos1 = params1; 14567 while (!ast_strlen_zero(pos1)) { 14568 char *name1 = pos1; 14569 char *value1 = strchr(pos1, '='); 14570 char *semicolon1 = strchr(pos1, ';'); 14571 int matched = 0; 14572 if (semicolon1) { 14573 *semicolon1++ = '\0'; 14574 } 14575 if (!value1) { 14576 goto fail; 14577 } 14578 *value1++ = '\0'; 14579 /* Checkpoint reached. We have the name and value parsed for param1 14580 * We have to duplicate params2 each time through the second loop 14581 * or else we can't search and replace the semicolons with \0 each 14582 * time 14583 */ 14584 pos2 = ast_strdupa(params2); 14585 while (!ast_strlen_zero(pos2)) { 14586 char *name2 = pos2; 14587 char *value2 = strchr(pos2, '='); 14588 char *semicolon2 = strchr(pos2, ';'); 14589 if (semicolon2) { 14590 *semicolon2++ = '\0'; 14591 } 14592 if (!value2) { 14593 goto fail; 14594 } 14595 *value2++ = '\0'; 14596 if (!strcasecmp(name1, name2)) { 14597 if (strcasecmp(value1, value2)) { 14598 goto fail; 14599 } else { 14600 matched = 1; 14601 break; 14602 } 14603 } 14604 pos2 = semicolon2; 14605 } 14606 /* Need to see if the parameter we're looking at is one of the 'must-match' parameters */ 14607 if (!strcasecmp(name1, "maddr")) { 14608 if (matched) { 14609 maddrmatch = 1; 14610 } else { 14611 goto fail; 14612 } 14613 } else if (!strcasecmp(name1, "ttl")) { 14614 if (matched) { 14615 ttlmatch = 1; 14616 } else { 14617 goto fail; 14618 } 14619 } else if (!strcasecmp(name1, "user")) { 14620 if (matched) { 14621 usermatch = 1; 14622 } else { 14623 goto fail; 14624 } 14625 } else if (!strcasecmp(name1, "method")) { 14626 if (matched) { 14627 methodmatch = 1; 14628 } else { 14629 goto fail; 14630 } 14631 } 14632 pos1 = semicolon1; 14633 } 14634 14635 /* We've made it out of that horrible O(m*n) construct and there are no 14636 * failures yet. We're not done yet, though, because params2 could have 14637 * an maddr, ttl, user, or method header and params1 did not. 14638 */ 14639 pos2 = params2; 14640 while (!ast_strlen_zero(pos2)) { 14641 char *name2 = pos2; 14642 char *value2 = strchr(pos2, '='); 14643 char *semicolon2 = strchr(pos2, ';'); 14644 if (semicolon2) { 14645 *semicolon2++ = '\0'; 14646 } 14647 if (!value2) { 14648 goto fail; 14649 } 14650 *value2++ = '\0'; 14651 if ((!strcasecmp(name2, "maddr") && !maddrmatch) || 14652 (!strcasecmp(name2, "ttl") && !ttlmatch) || 14653 (!strcasecmp(name2, "user") && !usermatch) || 14654 (!strcasecmp(name2, "method") && !methodmatch)) { 14655 goto fail; 14656 } 14657 } 14658 return 0; 14659 14660 fail: 14661 return 1; 14662 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 3883 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, 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.
03884 { 03885 struct sip_pvt *p = ast->tech_pvt; 03886 int res = 0; 03887 03888 switch (frame->frametype) { 03889 case AST_FRAME_VOICE: 03890 if (!(frame->subclass & ast->nativeformats)) { 03891 char s1[512], s2[512], s3[512]; 03892 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 03893 frame->subclass, 03894 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 03895 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 03896 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 03897 ast->readformat, 03898 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 03899 ast->writeformat); 03900 return 0; 03901 } 03902 if (p) { 03903 ast_mutex_lock(&p->lock); 03904 if (p->rtp) { 03905 /* If channel is not up, activate early media session */ 03906 if ((ast->_state != AST_STATE_UP) && 03907 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03908 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03909 ast_rtp_new_source(p->rtp); 03910 if (!global_prematuremediafilter) { 03911 p->invitestate = INV_EARLY_MEDIA; 03912 transmit_provisional_response(p, "183 Session Progress", &p->initreq, 1); 03913 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03914 } 03915 } else if (p->t38.state == T38_ENABLED && !p->t38.direct) { 03916 /* drop frame, can't sent VOICE frames while in T.38 mode */ 03917 } else { 03918 p->lastrtptx = time(NULL); 03919 res = ast_rtp_write(p->rtp, frame); 03920 } 03921 } 03922 ast_mutex_unlock(&p->lock); 03923 } 03924 break; 03925 case AST_FRAME_VIDEO: 03926 if (p) { 03927 ast_mutex_lock(&p->lock); 03928 if (p->vrtp) { 03929 /* Activate video early media */ 03930 if ((ast->_state != AST_STATE_UP) && 03931 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03932 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03933 p->invitestate = INV_EARLY_MEDIA; 03934 transmit_provisional_response(p, "183 Session Progress", &p->initreq, 1); 03935 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03936 } 03937 p->lastrtptx = time(NULL); 03938 res = ast_rtp_write(p->vrtp, frame); 03939 } 03940 ast_mutex_unlock(&p->lock); 03941 } 03942 break; 03943 case AST_FRAME_IMAGE: 03944 return 0; 03945 break; 03946 case AST_FRAME_MODEM: 03947 if (p) { 03948 ast_mutex_lock(&p->lock); 03949 /* UDPTL requires two-way communication, so early media is not needed here. 03950 we simply forget the frames if we get modem frames before the bridge is up. 03951 Fax will re-transmit. 03952 */ 03953 if (ast->_state == AST_STATE_UP) { 03954 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->t38.state == T38_DISABLED) { 03955 if (!p->pendinginvite) { 03956 p->t38.state = T38_LOCAL_REINVITE; 03957 transmit_reinvite_with_t38_sdp(p); 03958 } 03959 } else if (p->t38.state == T38_ENABLED) { 03960 res = ast_udptl_write(p->udptl, frame); 03961 } 03962 } 03963 ast_mutex_unlock(&p->lock); 03964 } 03965 break; 03966 default: 03967 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 03968 return 0; 03969 } 03970 03971 return res; 03972 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 16736 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(), errno, find_call(), find_sip_method(), sip_pvt::flags, get_header(), handle_request(), len(), sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, lws2sws(), netlock, option_debug, sip_pvt::owner, parse_request(), process_request_queue(), queue_request(), sip_pvt::recv, S_OR, sched, SIP_ACK, sip_debug_test_addr(), SIP_NO_HISTORY, SIP_PKT_DEBUG, sipsock, and transmit_response().
Referenced by do_monitor().
16737 { 16738 struct sip_request req; 16739 struct sockaddr_in sin = { 0, }; 16740 struct sip_pvt *p; 16741 int res; 16742 socklen_t len = sizeof(sin); 16743 int nounlock = 0; 16744 int recount = 0; 16745 int lockretry; 16746 16747 memset(&req, 0, sizeof(req)); 16748 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 16749 if (res < 0) { 16750 #if !defined(__FreeBSD__) 16751 if (errno == EAGAIN) 16752 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 16753 else 16754 #endif 16755 if (errno != ECONNREFUSED) 16756 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 16757 return 1; 16758 } 16759 if (option_debug && res == sizeof(req.data) - 1) 16760 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 16761 16762 req.data[res] = '\0'; 16763 req.len = res; 16764 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 16765 ast_set_flag(&req, SIP_PKT_DEBUG); 16766 if (pedanticsipchecking) 16767 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 16768 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 16769 ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); 16770 16771 if(parse_request(&req) == -1) /* Bad packet, can't parse */ 16772 return 1; 16773 16774 req.method = find_sip_method(req.rlPart1); 16775 16776 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 16777 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 16778 16779 if (req.headers < 2) /* Must have at least two headers */ 16780 return 1; 16781 16782 /* Process request, with netlock held, and with usual deadlock avoidance */ 16783 for (lockretry = 10; lockretry > 0; lockretry--) { 16784 ast_mutex_lock(&netlock); 16785 16786 /* Find the active SIP dialog or create a new one */ 16787 p = find_call(&req, &sin, req.method); /* returns p locked */ 16788 if (p == NULL) { 16789 if (option_debug) 16790 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 16791 ast_mutex_unlock(&netlock); 16792 return 1; 16793 } 16794 /* Go ahead and lock the owner if it has one -- we may need it */ 16795 /* because this is deadlock-prone, we need to try and unlock if failed */ 16796 if (!p->owner || !ast_channel_trylock(p->owner)) 16797 break; /* locking succeeded */ 16798 if (lockretry != 1) { 16799 ast_mutex_unlock(&p->lock); 16800 ast_mutex_unlock(&netlock); 16801 /* Sleep for a very short amount of time */ 16802 usleep(1); 16803 } 16804 } 16805 p->recv = sin; 16806 16807 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 16808 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 16809 16810 if (!lockretry) { 16811 if (!queue_request(p, &req)) { 16812 /* the request has been queued for later handling */ 16813 ast_mutex_unlock(&p->lock); 16814 ast_mutex_unlock(&netlock); 16815 return 1; 16816 } 16817 16818 /* This is unsafe, since p->owner is not locked. */ 16819 if (p->owner) 16820 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 ??? - ")); 16821 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 16822 if (req.method != SIP_ACK) 16823 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 16824 /* XXX We could add retry-after to make sure they come back */ 16825 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 16826 ast_mutex_unlock(&p->lock); 16827 ast_mutex_unlock(&netlock); 16828 return 1; 16829 } 16830 16831 /* if there are queued requests on this sip_pvt, process them first, so that everything is 16832 handled in order 16833 */ 16834 if (!AST_LIST_EMPTY(&p->request_queue)) { 16835 AST_SCHED_DEL(sched, p->request_queue_sched_id); 16836 process_request_queue(p, &recount, &nounlock); 16837 } 16838 16839 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 16840 /* Request failed */ 16841 if (option_debug) 16842 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 16843 } 16844 16845 if (p->owner && !nounlock) 16846 ast_channel_unlock(p->owner); 16847 ast_mutex_unlock(&p->lock); 16848 ast_mutex_unlock(&netlock); 16849 if (recount) 16850 ast_update_use_count(); 16851 16852 return 1; 16853 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 13468 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().
13469 { 13470 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 13471 if (p->rtp) 13472 ast_rtp_stop(p->rtp); 13473 if (p->vrtp) 13474 ast_rtp_stop(p->vrtp); 13475 if (p->udptl) 13476 ast_udptl_stop(p->udptl); 13477 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 11563 of file chan_sip.c.
References subscription_types, and type.
Referenced by sip_show_channel().
11564 { 11565 int i; 11566 11567 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 11568 if (subscription_types[i].type == subtype) { 11569 return subscription_types[i].text; 11570 } 11571 } 11572 return subscription_types[0].text; 11573 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 6839 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().
06840 { 06841 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 06842 06843 if (maxrate & T38FAX_RATE_14400) { 06844 if (option_debug > 1) 06845 ast_log(LOG_DEBUG, "T38MaxBitRate 14400 found\n"); 06846 return 14400; 06847 } else if (maxrate & T38FAX_RATE_12000) { 06848 if (option_debug > 1) 06849 ast_log(LOG_DEBUG, "T38MaxBitRate 12000 found\n"); 06850 return 12000; 06851 } else if (maxrate & T38FAX_RATE_9600) { 06852 if (option_debug > 1) 06853 ast_log(LOG_DEBUG, "T38MaxBitRate 9600 found\n"); 06854 return 9600; 06855 } else if (maxrate & T38FAX_RATE_7200) { 06856 if (option_debug > 1) 06857 ast_log(LOG_DEBUG, "T38MaxBitRate 7200 found\n"); 06858 return 7200; 06859 } else if (maxrate & T38FAX_RATE_4800) { 06860 if (option_debug > 1) 06861 ast_log(LOG_DEBUG, "T38MaxBitRate 4800 found\n"); 06862 return 4800; 06863 } else if (maxrate & T38FAX_RATE_2400) { 06864 if (option_debug > 1) 06865 ast_log(LOG_DEBUG, "T38MaxBitRate 2400 found\n"); 06866 return 2400; 06867 } else { 06868 if (option_debug > 1) 06869 ast_log(LOG_DEBUG, "Strange, T38MaxBitRate NOT found in peers T38 SDP.\n"); 06870 return 0; 06871 } 06872 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 17913 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_set_flag, ASTOBJ_INIT, default_prefs, reg_source_db(), set_peer_defaults(), SIP_PAGE2_DYNAMIC, and SIP_PAGE2_SELFDESTRUCT.
Referenced by register_verify().
17914 { 17915 struct sip_peer *peer; 17916 17917 if (!(peer = ast_calloc(1, sizeof(*peer)))) 17918 return NULL; 17919 17920 apeerobjs++; 17921 ASTOBJ_INIT(peer); 17922 set_peer_defaults(peer); 17923 17924 ast_copy_string(peer->name, name, sizeof(peer->name)); 17925 17926 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 17927 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17928 peer->prefs = default_prefs; 17929 reg_source_db(peer); 17930 17931 return peer; 17932 }
static void temp_pvt_cleanup | ( | void * | ) | [static] |
Definition at line 6601 of file chan_sip.c.
References ast_string_field_free_memory, and free.
06602 { 06603 struct sip_pvt *p = data; 06604 06605 ast_string_field_free_memory(p); 06606 06607 free(data); 06608 }
static void temp_pvt_init | ( | void | ) | [static] |
static char * transfermode2str | ( | enum transfermodes | mode | ) | const [static] |
Convert transfer mode to text string.
Definition at line 10572 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().
10573 { 10574 if (mode == TRANSFER_OPENFORALL) 10575 return "open"; 10576 else if (mode == TRANSFER_CLOSED) 10577 return "closed"; 10578 return "strict"; 10579 }
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 9252 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, 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, transmit_response(), and transmit_response_with_auth().
Referenced by handle_request_invite(), handle_request_subscribe(), and register_verify().
09253 { 09254 /* We have to emulate EXACTLY what we'd get with a good peer 09255 * and a bad password, or else we leak information. */ 09256 const char *response = "407 Proxy Authentication Required"; 09257 const char *reqheader = "Proxy-Authorization"; 09258 const char *respheader = "Proxy-Authenticate"; 09259 const char *authtoken; 09260 struct ast_dynamic_str *buf; 09261 char *c; 09262 09263 /* table of recognised keywords, and their value in the digest */ 09264 enum keys { K_NONCE, K_LAST }; 09265 struct x { 09266 const char *key; 09267 const char *s; 09268 } *i, keys[] = { 09269 [K_NONCE] = { "nonce=", "" }, 09270 [K_LAST] = { NULL, NULL} 09271 }; 09272 09273 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 09274 response = "401 Unauthorized"; 09275 reqheader = "Authorization"; 09276 respheader = "WWW-Authenticate"; 09277 } 09278 authtoken = get_header(req, reqheader); 09279 if (ast_test_flag(req, SIP_PKT_IGNORE) && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 09280 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 09281 * information */ 09282 transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0); 09283 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 09284 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09285 return; 09286 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 09287 /* We have no auth, so issue challenge and request authentication */ 09288 set_nonce_randdata(p, 1); 09289 transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0); 09290 /* Schedule auto destroy in 32 seconds */ 09291 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09292 return; 09293 } 09294 09295 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 09296 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09297 return; 09298 } 09299 09300 /* Make a copy of the response and parse it */ 09301 if (ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) { 09302 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09303 return; 09304 } 09305 09306 c = buf->str; 09307 09308 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 09309 for (i = keys; i->key != NULL; i++) { 09310 const char *separator = ","; /* default */ 09311 09312 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 09313 continue; 09314 } 09315 /* Found. Skip keyword, take text in quotes or up to the separator. */ 09316 c += strlen(i->key); 09317 if (*c == '"') { /* in quotes. Skip first and look for last */ 09318 c++; 09319 separator = "\""; 09320 } 09321 i->s = c; 09322 strsep(&c, separator); 09323 break; 09324 } 09325 if (i->key == NULL) { /* not found, jump after space or comma */ 09326 strsep(&c, " ,"); 09327 } 09328 } 09329 09330 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 09331 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { 09332 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 09333 set_nonce_randdata(p, 1); 09334 } 09335 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 09336 09337 /* Schedule auto destroy in 32 seconds */ 09338 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09339 } else { 09340 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09341 } 09342 }
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 8396 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
08397 { 08398 struct sip_request req; 08399 08400 reqprep(&req, p, SIP_INFO, 0, 1); 08401 add_digit(&req, digit, duration); 08402 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08403 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 8406 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
08407 { 08408 struct sip_request req; 08409 08410 reqprep(&req, p, SIP_INFO, 0, 1); 08411 add_vidupdate(&req); 08412 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08413 }
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 7629 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), ast_channel_lock, ast_channel_unlock, AST_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(), ast_var_t::entries, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::invite_branch, sip_pvt::lastinvite, LOG_DEBUG, sip_request::method, ast_channel::name, 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().
07630 { 07631 struct sip_request req; 07632 07633 req.method = sipmethod; 07634 if (init) { /* Seems like init always is 2 */ 07635 /* Bump branch even on initial requests */ 07636 p->branch ^= ast_random(); 07637 p->invite_branch = p->branch; 07638 build_via(p); 07639 if (init > 1) 07640 initreqprep(&req, p, sipmethod); 07641 else 07642 reqprep(&req, p, sipmethod, 0, 0); 07643 } else 07644 reqprep(&req, p, sipmethod, 0, 1); 07645 07646 if (p->options && p->options->auth) 07647 add_header(&req, p->options->authheader, p->options->auth); 07648 append_date(&req); 07649 if (sipmethod == SIP_REFER) { /* Call transfer */ 07650 if (p->refer) { 07651 char buf[SIPBUFSIZE]; 07652 if (!ast_strlen_zero(p->refer->refer_to)) 07653 add_header(&req, "Refer-To", p->refer->refer_to); 07654 if (!ast_strlen_zero(p->refer->referred_by)) { 07655 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 07656 add_header(&req, "Referred-By", buf); 07657 } 07658 } 07659 } 07660 /* This new INVITE is part of an attended transfer. Make sure that the 07661 other end knows and replace the current call with this new call */ 07662 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 07663 add_header(&req, "Replaces", p->options->replaces); 07664 add_header(&req, "Require", "replaces"); 07665 } 07666 07667 add_header(&req, "Allow", ALLOWED_METHODS); 07668 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07669 if (p->options && p->options->addsipheaders && p->owner) { 07670 struct ast_channel *chan = p->owner; /* The owner channel */ 07671 struct varshead *headp; 07672 07673 ast_channel_lock(chan); 07674 07675 headp = &chan->varshead; 07676 07677 if (!headp) 07678 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 07679 else { 07680 const struct ast_var_t *current; 07681 AST_LIST_TRAVERSE(headp, current, entries) { 07682 /* SIPADDHEADER: Add SIP header to outgoing call */ 07683 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 07684 char *content, *end; 07685 const char *header = ast_var_value(current); 07686 char *headdup = ast_strdupa(header); 07687 07688 /* Strip of the starting " (if it's there) */ 07689 if (*headdup == '"') 07690 headdup++; 07691 if ((content = strchr(headdup, ':'))) { 07692 *content++ = '\0'; 07693 content = ast_skip_blanks(content); /* Skip white space */ 07694 /* Strip the ending " (if it's there) */ 07695 end = content + strlen(content) -1; 07696 if (*end == '"') 07697 *end = '\0'; 07698 07699 add_header(&req, headdup, content); 07700 if (sipdebug) 07701 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 07702 } 07703 } 07704 } 07705 } 07706 07707 ast_channel_unlock(chan); 07708 } 07709 if (sdp) { 07710 memset(p->offered_media, 0, sizeof(p->offered_media)); 07711 if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) { 07712 ast_udptl_offered_from_local(p->udptl, 1); 07713 if (option_debug) 07714 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 07715 add_sdp(&req, p, 0, 1); 07716 } else if (p->rtp) 07717 add_sdp(&req, p, 1, 0); 07718 } else { 07719 add_header_contentLength(&req, 0); 07720 } 07721 07722 if (!p->initreq.headers || init > 2) 07723 initialize_initreq(p, &req); 07724 p->lastinvite = p->ocseq; 07725 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 07726 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 8305 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().
08306 { 08307 struct sip_request req; 08308 08309 reqprep(&req, p, SIP_MESSAGE, 0, 1); 08310 add_text(&req, text); 08311 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08312 }
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 7917 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), 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(), 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().
07918 { 07919 struct sip_request req; 07920 char tmp[500]; 07921 char *t = tmp; 07922 size_t maxbytes = sizeof(tmp); 07923 07924 initreqprep(&req, p, SIP_NOTIFY); 07925 add_header(&req, "Event", "message-summary"); 07926 add_header(&req, "Content-Type", default_notifymime); 07927 07928 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07929 /* if we listen to non-standard SIP port we have to specify the SIP port 07930 in the URI, except domains are used - in this case the SRV records should be 07931 used to redirect the client to the non-standard SIP port */ 07932 if ((ourport != STANDARD_SIP_PORT) && ast_strlen_zero(p->fromdomain)) { 07933 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s:%d\r\n", 07934 S_OR(vmexten, default_vmexten), ast_inet_ntoa(p->ourip), ourport); 07935 } else { 07936 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07937 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07938 } 07939 /* Cisco has a bug in the SIP stack where it can't accept the 07940 (0/0) notification. This can temporarily be disabled in 07941 sip.conf with the "buggymwi" option */ 07942 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)")); 07943 07944 if (p->subscribed) { 07945 if (p->expiry) 07946 add_header(&req, "Subscription-State", "active"); 07947 else /* Expired */ 07948 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07949 } 07950 07951 if (t > tmp + sizeof(tmp)) 07952 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07953 07954 add_header_contentLength(&req, strlen(tmp)); 07955 add_line(&req, tmp); 07956 07957 if (!p->initreq.headers) 07958 initialize_initreq(p, &req); 07959 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07960 }
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 7971 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ALLOWED_METHODS, sip_request::headers, initialize_initreq(), sip_pvt::initreq, sip_pvt::ocseq, reqprep(), send_request(), SIP_NOTIFY, SIPBUFSIZE, SUPPORTED_EXTENSIONS, and XMIT_RELIABLE.
Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().
07972 { 07973 struct sip_request req; 07974 char tmp[SIPBUFSIZE/2]; 07975 07976 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07977 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07978 add_header(&req, "Event", tmp); 07979 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07980 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07981 add_header(&req, "Allow", ALLOWED_METHODS); 07982 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07983 07984 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07985 add_header_contentLength(&req, strlen(tmp)); 07986 add_line(&req, tmp); 07987 07988 if (!p->initreq.headers) 07989 initialize_initreq(p, &req); 07990 07991 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07992 }
static int transmit_provisional_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req, | |||
int | with_sdp | |||
) | [static] |
Definition at line 6740 of file chan_sip.c.
References transmit_response(), transmit_response_with_sdp(), update_provisional_keepalive(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite(), sip_indicate(), and sip_write().
06741 { 06742 int res; 06743 06744 if (!(res = with_sdp ? transmit_response_with_sdp(p, msg, req, XMIT_UNRELIABLE) : transmit_response(p, msg, req))) { 06745 p->last_provisional = msg; 06746 update_provisional_keepalive(p, with_sdp); 06747 } 06748 06749 return res; 06750 }
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 8326 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().
08327 { 08328 struct sip_request req = { 08329 .headers = 0, 08330 }; 08331 char from[256]; 08332 const char *of; 08333 char *c; 08334 char referto[256]; 08335 char *ttag, *ftag; 08336 char *theirtag = ast_strdupa(p->theirtag); 08337 08338 if (option_debug || sipdebug) 08339 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 08340 08341 /* Are we transfering an inbound or outbound call ? */ 08342 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 08343 of = get_header(&p->initreq, "To"); 08344 ttag = theirtag; 08345 ftag = p->tag; 08346 } else { 08347 of = get_header(&p->initreq, "From"); 08348 ftag = theirtag; 08349 ttag = p->tag; 08350 } 08351 08352 ast_copy_string(from, of, sizeof(from)); 08353 of = get_in_brackets(from); 08354 ast_string_field_set(p, from, of); 08355 if (strncasecmp(of, "sip:", 4)) 08356 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 08357 else 08358 of += 4; 08359 /* Get just the username part */ 08360 if ((c = strchr(dest, '@'))) 08361 c = NULL; 08362 else if ((c = strchr(of, '@'))) 08363 *c++ = '\0'; 08364 if (c) 08365 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 08366 else 08367 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 08368 08369 /* save in case we get 407 challenge */ 08370 sip_refer_allocate(p); 08371 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 08372 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 08373 p->refer->status = REFER_SENT; /* Set refer status */ 08374 08375 reqprep(&req, p, SIP_REFER, 0, 1); 08376 08377 add_header(&req, "Refer-To", referto); 08378 add_header(&req, "Allow", ALLOWED_METHODS); 08379 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 08380 if (!ast_strlen_zero(p->our_contact)) 08381 add_header(&req, "Referred-By", p->our_contact); 08382 08383 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08384 /* We should propably wait for a NOTIFY here until we ack the transfer */ 08385 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 08386 08387 /*! \todo In theory, we should hang around and wait for a reply, before 08388 returning to the dial plan here. Don't know really how that would 08389 affect the transfer() app or the pbx, but, well, to make this 08390 useful we should have a STATUS code on transfer(). 08391 */ 08392 }
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 8097 of file chan_sip.c.
References __ourip, add_header(), add_header_contentLength(), 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, 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::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_registry::portno, sip_registry::qop, sip_pvt::qop, sip_registry::realm, sip_pvt::realm, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sched, 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().
08098 { 08099 struct sip_request req; 08100 char from[256]; 08101 char to[256]; 08102 char tmp[80]; 08103 char addr[80]; 08104 struct sip_pvt *p; 08105 char *fromdomain; 08106 08107 /* exit if we are already in process with this registrar ?*/ 08108 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 08109 if (r) { 08110 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 08111 } 08112 return 0; 08113 } 08114 08115 if (r->call) { /* We have a registration */ 08116 if (!auth) { 08117 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 08118 return 0; 08119 } else { 08120 p = r->call; 08121 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 08122 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 08123 } 08124 } else { 08125 /* Build callid for registration if we haven't registered before */ 08126 if (!r->callid_valid) { 08127 build_callid_registry(r, __ourip, default_fromdomain); 08128 r->callid_valid = TRUE; 08129 } 08130 /* Allocate SIP packet for registration */ 08131 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 08132 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 08133 return 0; 08134 } 08135 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 08136 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 08137 /* Find address to hostname if we haven't tried to connect 08138 * or a connection error has occurred */ 08139 if (create_addr(p, r->hostname, r->needdns ? NULL : &r->us)) { 08140 /* we have what we hope is a temporary network error, 08141 * probably DNS. We need to reschedule a registration try */ 08142 sip_destroy(p); 08143 08144 if (r->timeout > -1) 08145 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 08146 else 08147 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); 08148 08149 AST_SCHED_DEL(sched, r->timeout); 08150 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 08151 r->regattempts++; 08152 return 0; 08153 } 08154 if (r->needdns) { 08155 memcpy(&r->us, &p->sa, sizeof(r->us)); 08156 } 08157 r->needdns = FALSE; 08158 /* Copy back Call-ID in case create_addr changed it */ 08159 ast_string_field_set(r, callid, p->callid); 08160 if (r->portno) { 08161 p->sa.sin_port = htons(r->portno); 08162 p->recv.sin_port = htons(r->portno); 08163 } else /* Set registry port to the port set from the peer definition/srv or default */ 08164 r->portno = ntohs(p->sa.sin_port); 08165 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 08166 r->call=p; /* Save pointer to SIP packet */ 08167 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 08168 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 08169 ast_string_field_set(p, peersecret, r->secret); 08170 if (!ast_strlen_zero(r->md5secret)) 08171 ast_string_field_set(p, peermd5secret, r->md5secret); 08172 /* User name in this realm 08173 - if authuser is set, use that, otherwise use username */ 08174 if (!ast_strlen_zero(r->authuser)) { 08175 ast_string_field_set(p, peername, r->authuser); 08176 ast_string_field_set(p, authname, r->authuser); 08177 } else if (!ast_strlen_zero(r->username)) { 08178 ast_string_field_set(p, peername, r->username); 08179 ast_string_field_set(p, authname, r->username); 08180 ast_string_field_set(p, fromuser, r->username); 08181 } 08182 if (!ast_strlen_zero(r->username)) 08183 ast_string_field_set(p, username, r->username); 08184 /* Save extension in packet */ 08185 ast_string_field_set(p, exten, r->contact); 08186 08187 /* 08188 check which address we should use in our contact header 08189 based on whether the remote host is on the external or 08190 internal network so we can register through nat 08191 */ 08192 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 08193 p->ourip = bindaddr.sin_addr; 08194 build_contact(p); 08195 } 08196 08197 /* set up a timeout */ 08198 if (auth == NULL) { 08199 if (r->timeout > -1) 08200 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 08201 AST_SCHED_DEL(sched, r->timeout); 08202 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 08203 if (option_debug) 08204 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 08205 } 08206 08207 if ((fromdomain = strchr(r->username, '@'))) { 08208 /* the domain name is just behind '@' */ 08209 fromdomain++ ; 08210 /* We have a domain in the username for registration */ 08211 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 08212 if (!ast_strlen_zero(p->theirtag)) 08213 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 08214 else 08215 snprintf(to, sizeof(to), "<sip:%s>", r->username); 08216 08217 /* If the registration username contains '@', then the domain should be used as 08218 the equivalent of "fromdomain" for the registration */ 08219 if (ast_strlen_zero(p->fromdomain)) { 08220 ast_string_field_set(p, fromdomain, fromdomain); 08221 } 08222 } else { 08223 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 08224 if (!ast_strlen_zero(p->theirtag)) 08225 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 08226 else 08227 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 08228 } 08229 08230 /* Fromdomain is what we are registering to, regardless of actual 08231 host name from SRV */ 08232 if (!ast_strlen_zero(p->fromdomain)) { 08233 if (r->portno && r->portno != STANDARD_SIP_PORT) 08234 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 08235 else 08236 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 08237 } else { 08238 if (r->portno && r->portno != STANDARD_SIP_PORT) 08239 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 08240 else 08241 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 08242 } 08243 ast_string_field_set(p, uri, addr); 08244 08245 p->branch ^= ast_random(); 08246 08247 init_req(&req, sipmethod, addr); 08248 08249 /* Add to CSEQ */ 08250 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 08251 p->ocseq = r->ocseq; 08252 08253 build_via(p); 08254 add_header(&req, "Via", p->via); 08255 add_header(&req, "From", from); 08256 add_header(&req, "To", to); 08257 add_header(&req, "Call-ID", p->callid); 08258 add_header(&req, "CSeq", tmp); 08259 if (!ast_strlen_zero(global_useragent)) 08260 add_header(&req, "User-Agent", global_useragent); 08261 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 08262 08263 08264 if (auth) /* Add auth header */ 08265 add_header(&req, authheader, auth); 08266 else if (!ast_strlen_zero(r->nonce)) { 08267 char digest[1024]; 08268 08269 /* We have auth data to reuse, build a digest header! */ 08270 if (sipdebug) 08271 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 08272 ast_string_field_set(p, realm, r->realm); 08273 ast_string_field_set(p, nonce, r->nonce); 08274 ast_string_field_set(p, domain, r->domain); 08275 ast_string_field_set(p, opaque, r->opaque); 08276 ast_string_field_set(p, qop, r->qop); 08277 r->noncecount++; 08278 p->noncecount = r->noncecount; 08279 08280 memset(digest,0,sizeof(digest)); 08281 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 08282 add_header(&req, "Authorization", digest); 08283 else 08284 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 08285 08286 } 08287 08288 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 08289 add_header(&req, "Expires", tmp); 08290 add_header(&req, "Contact", p->our_contact); 08291 add_header(&req, "Event", "registration"); 08292 add_header_contentLength(&req, 0); 08293 08294 initialize_initreq(p, &req); 08295 if (sip_debug_test_pvt(p)) 08296 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 08297 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 08298 r->regattempts++; /* Another attempt */ 08299 if (option_debug > 3) 08300 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 08301 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 08302 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 7342 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(), 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(), and sip_set_rtp_peer().
07343 { 07344 struct sip_request req; 07345 07346 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 07347 07348 add_header(&req, "Allow", ALLOWED_METHODS); 07349 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07350 if (sipdebug) 07351 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 07352 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07353 append_history(p, "ReInv", "Re-invite sent"); 07354 memset(p->offered_media, 0, sizeof(p->offered_media)); 07355 add_sdp(&req, p, 1, 0); 07356 /* Use this as the basis */ 07357 initialize_initreq(p, &req); 07358 p->lastinvite = p->ocseq; 07359 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 07360 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07361 }
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 7367 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().
07368 { 07369 struct sip_request req; 07370 07371 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 07372 07373 add_header(&req, "Allow", ALLOWED_METHODS); 07374 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07375 if (sipdebug) 07376 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 07377 memset(p->offered_media, 0, sizeof(p->offered_media)); 07378 add_sdp(&req, p, 0, 1); 07379 07380 /* Use this as the basis */ 07381 initialize_initreq(p, &req); 07382 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 07383 p->lastinvite = p->ocseq; 07384 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07385 }
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 8418 of file chan_sip.c.
References add_header_contentLength(), 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().
08419 { 08420 struct sip_request resp; 08421 08422 if (sipmethod == SIP_ACK) 08423 p->invitestate = INV_CONFIRMED; 08424 08425 reqprep(&resp, p, sipmethod, seqno, newbranch); 08426 add_header_contentLength(&resp, 0); 08427 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 08428 }
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 8431 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), ast_strlen_zero(), sip_invite_param::auth_type, build_reply_digest(), sip_pvt::callid, sip_pvt::hangupcause, 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().
08432 { 08433 struct sip_request resp; 08434 08435 reqprep(&resp, p, sipmethod, seqno, newbranch); 08436 if (!ast_strlen_zero(p->realm)) { 08437 char digest[1024]; 08438 08439 memset(digest, 0, sizeof(digest)); 08440 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 08441 if (p->options && p->options->auth_type == PROXY_AUTH) 08442 add_header(&resp, "Proxy-Authorization", digest); 08443 else if (p->options && p->options->auth_type == WWW_AUTH) 08444 add_header(&resp, "Authorization", digest); 08445 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 08446 add_header(&resp, "Proxy-Authorization", digest); 08447 } else 08448 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 08449 } 08450 /* If we are hanging up and know a cause for that, send it in clear text to make 08451 debugging easier. */ 08452 if (sipmethod == SIP_BYE) { 08453 char buf[10]; 08454 08455 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->hangupcause)); 08456 snprintf(buf, sizeof(buf), "%d", p->hangupcause); 08457 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 08458 } 08459 08460 add_header_contentLength(&resp, 0); 08461 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 08462 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 6662 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
06663 { 06664 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06665 }
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 6681 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_hangup(), sip_indicate(), and sip_sipredirect().
06682 { 06683 return __transmit_response(p, msg, req, XMIT_CRITICAL); 06684 }
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 6611 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(), build_via(), check_via(), do_setnat(), sip_pvt::fromdomain, global_flags, INITIAL_CSEQ, LOG_NOTICE, make_our_tag(), SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, ts_temp_pvt, and XMIT_UNRELIABLE.
06612 { 06613 struct sip_pvt *p = NULL; 06614 06615 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 06616 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 06617 return -1; 06618 } 06619 06620 /* if the structure was just allocated, initialize it */ 06621 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 06622 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 06623 if (ast_string_field_init(p, 512)) 06624 return -1; 06625 } 06626 06627 /* Initialize the bare minimum */ 06628 p->method = intended_method; 06629 06630 if (sin) { 06631 p->sa = *sin; 06632 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 06633 p->ourip = __ourip; 06634 } else 06635 p->ourip = __ourip; 06636 06637 p->branch = ast_random(); 06638 make_our_tag(p->tag, sizeof(p->tag)); 06639 p->ocseq = INITIAL_CSEQ; 06640 06641 if (useglobal_nat && sin) { 06642 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 06643 p->recv = *sin; 06644 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 06645 } 06646 check_via(p, req); 06647 06648 ast_string_field_set(p, fromdomain, default_fromdomain); 06649 build_via(p); 06650 ast_string_field_set(p, callid, callid); 06651 06652 /* Use this temporary pvt structure to send the message */ 06653 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06654 06655 /* Free the string fields, but not the pool space */ 06656 ast_string_field_reset_all(p); 06657 06658 return 0; 06659 }
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 6709 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
06710 { 06711 struct sip_request resp; 06712 respprep(&resp, p, msg, req); 06713 add_header(&resp, "Accept", "application/sdp"); 06714 add_header_contentLength(&resp, 0); 06715 return send_response(p, &resp, reliable, 0); 06716 }
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 6719 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_history, ast_log(), get_header(), sip_pvt::noncecount, respprep(), send_response(), and sip_pvt::username.
Referenced by check_auth(), and transmit_fake_auth_response().
06720 { 06721 struct sip_request resp; 06722 char tmp[512]; 06723 int seqno = 0; 06724 06725 if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) { 06726 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06727 return -1; 06728 } 06729 /* Stale means that they sent us correct authentication, but 06730 based it on an old challenge (nonce) */ 06731 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 06732 respprep(&resp, p, msg, req); 06733 add_header(&resp, header, tmp); 06734 add_header_contentLength(&resp, 0); 06735 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 06736 return send_response(p, &resp, reliable, seqno); 06737 }
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 6699 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
06700 { 06701 struct sip_request resp; 06702 respprep(&resp, p, msg, req); 06703 append_date(&resp); 06704 add_header_contentLength(&resp, 0); 06705 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06706 }
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 7266 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, 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().
07267 { 07268 struct sip_request resp; 07269 int seqno; 07270 if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) { 07271 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 07272 return -1; 07273 } 07274 respprep(&resp, p, msg, req); 07275 if (p->rtp) { 07276 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07277 if (option_debug) 07278 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 07279 ast_rtp_codec_setpref(p->rtp, &p->prefs); 07280 } 07281 try_suggested_sip_codec(p); 07282 if (p->t38.state == T38_PEER_DIRECT || p->t38.state == T38_ENABLED) { 07283 p->t38.state = T38_ENABLED; 07284 add_sdp(&resp, p, 1, 1); 07285 } else { 07286 add_sdp(&resp, p, 1, 0); 07287 } 07288 } else 07289 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 07290 if (reliable && !p->pendinginvite) 07291 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 07292 return send_response(p, &resp, reliable, seqno); 07293 }
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 7227 of file chan_sip.c.
References add_sdp(), ast_log(), sip_pvt::callid, get_header(), LOG_ERROR, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.
Referenced by handle_request_invite(), and sip_handle_t38_reinvite().
07228 { 07229 struct sip_request resp; 07230 int seqno; 07231 07232 if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) { 07233 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 07234 return -1; 07235 } 07236 respprep(&resp, p, msg, req); 07237 if (p->udptl) { 07238 add_sdp(&resp, p, 0, 1); 07239 } else 07240 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 07241 if (retrans && !p->pendinginvite) 07242 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 07243 return send_response(p, &resp, retrans, seqno); 07244 }
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 6668 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
06669 { 06670 struct sip_request resp; 06671 respprep(&resp, p, msg, req); 06672 append_date(&resp); 06673 add_header(&resp, "Unsupported", unsupported); 06674 add_header_contentLength(&resp, 0); 06675 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06676 }
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 7963 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().
07964 { 07965 if (!p->initreq.headers) /* Initialize first request before sending */ 07966 initialize_initreq(p, req); 07967 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07968 }
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 7729 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_copy_string(), ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, sip_pvt::context, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, sip_pvt::exten, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, NONE, sip_pvt::ocseq, sip_pvt::pendinginvite, PIDF_XML, reqprep(), send_request(), SIP_NOTIFY, sip_pvt::subscribed, t, XMIT_RELIABLE, and XPIDF_XML.
Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe().
07730 { 07731 char tmp[4000], from[256], to[256]; 07732 char *t = tmp, *c, *mfrom, *mto; 07733 size_t maxbytes = sizeof(tmp); 07734 struct sip_request req; 07735 char hint[AST_MAX_EXTENSION]; 07736 char *statestring = "terminated"; 07737 const struct cfsubscription_types *subscriptiontype; 07738 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 07739 char *pidfstate = "--"; 07740 char *pidfnote= "Ready"; 07741 07742 memset(from, 0, sizeof(from)); 07743 memset(to, 0, sizeof(to)); 07744 memset(tmp, 0, sizeof(tmp)); 07745 07746 switch (state) { 07747 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 07748 statestring = (global_notifyringing) ? "early" : "confirmed"; 07749 local_state = NOTIFY_INUSE; 07750 pidfstate = "busy"; 07751 pidfnote = "Ringing"; 07752 break; 07753 case AST_EXTENSION_RINGING: 07754 statestring = "early"; 07755 local_state = NOTIFY_INUSE; 07756 pidfstate = "busy"; 07757 pidfnote = "Ringing"; 07758 break; 07759 case AST_EXTENSION_INUSE: 07760 statestring = "confirmed"; 07761 local_state = NOTIFY_INUSE; 07762 pidfstate = "busy"; 07763 pidfnote = "On the phone"; 07764 break; 07765 case AST_EXTENSION_BUSY: 07766 statestring = "confirmed"; 07767 local_state = NOTIFY_CLOSED; 07768 pidfstate = "busy"; 07769 pidfnote = "On the phone"; 07770 break; 07771 case AST_EXTENSION_UNAVAILABLE: 07772 statestring = "terminated"; 07773 local_state = NOTIFY_CLOSED; 07774 pidfstate = "away"; 07775 pidfnote = "Unavailable"; 07776 break; 07777 case AST_EXTENSION_ONHOLD: 07778 statestring = "confirmed"; 07779 local_state = NOTIFY_CLOSED; 07780 pidfstate = "busy"; 07781 pidfnote = "On Hold"; 07782 break; 07783 case AST_EXTENSION_NOT_INUSE: 07784 default: 07785 /* Default setting */ 07786 break; 07787 } 07788 07789 subscriptiontype = find_subscription_type(p->subscribed); 07790 07791 /* Check which device/devices we are watching and if they are registered */ 07792 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 07793 char *hint2 = hint, *individual_hint = NULL; 07794 int hint_count = 0, unavailable_count = 0; 07795 07796 while ((individual_hint = strsep(&hint2, "&"))) { 07797 hint_count++; 07798 07799 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 07800 unavailable_count++; 07801 } 07802 07803 /* If none of the hinted devices are registered, we will 07804 * override notification and show no availability. 07805 */ 07806 if (hint_count > 0 && hint_count == unavailable_count) { 07807 local_state = NOTIFY_CLOSED; 07808 pidfstate = "away"; 07809 pidfnote = "Not online"; 07810 } 07811 } 07812 07813 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 07814 c = get_in_brackets(from); 07815 if (strncasecmp(c, "sip:", 4)) { 07816 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07817 return -1; 07818 } 07819 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 07820 07821 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 07822 c = get_in_brackets(to); 07823 if (strncasecmp(c, "sip:", 4)) { 07824 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07825 return -1; 07826 } 07827 mto = strsep(&c, ";"); /* trim ; and beyond */ 07828 07829 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07830 07831 07832 add_header(&req, "Event", subscriptiontype->event); 07833 add_header(&req, "Content-Type", subscriptiontype->mediatype); 07834 switch(state) { 07835 case AST_EXTENSION_DEACTIVATED: 07836 if (timeout) 07837 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07838 else { 07839 add_header(&req, "Subscription-State", "terminated;reason=probation"); 07840 add_header(&req, "Retry-After", "60"); 07841 } 07842 break; 07843 case AST_EXTENSION_REMOVED: 07844 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 07845 break; 07846 default: 07847 if (p->expiry) 07848 add_header(&req, "Subscription-State", "active"); 07849 else /* Expired */ 07850 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07851 } 07852 switch (p->subscribed) { 07853 case XPIDF_XML: 07854 case CPIM_PIDF_XML: 07855 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07856 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 07857 ast_build_string(&t, &maxbytes, "<presence>\n"); 07858 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 07859 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 07860 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 07861 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 07862 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 07863 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 07864 break; 07865 case PIDF_XML: /* Eyebeam supports this format */ 07866 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 07867 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); 07868 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07869 if (pidfstate[0] != '-') 07870 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07871 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07872 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07873 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07874 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07875 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07876 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07877 else 07878 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07879 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07880 break; 07881 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07882 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07883 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); 07884 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07885 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07886 else 07887 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07888 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07889 if (state == AST_EXTENSION_ONHOLD) { 07890 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07891 "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n" 07892 "</target>\n</local>\n", mto); 07893 } 07894 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07895 break; 07896 case NONE: 07897 default: 07898 break; 07899 } 07900 07901 if (t > tmp + sizeof(tmp)) 07902 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07903 07904 add_header_contentLength(&req, strlen(tmp)); 07905 add_line(&req, tmp); 07906 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 07907 07908 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07909 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3838 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().
03839 { 03840 int fmt; 03841 const char *codec; 03842 03843 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 03844 if (!codec) 03845 return; 03846 03847 fmt = ast_getformatbyname(codec); 03848 if (fmt) { 03849 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 03850 if (p->jointcapability & fmt) { 03851 p->jointcapability &= fmt; 03852 p->capability &= fmt; 03853 } else 03854 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 03855 } else 03856 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 03857 return; 03858 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 19589 of file chan_sip.c.
References __sip_destroy(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free_ha(), 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(), cli_sip, global_contact_ha, iflist, iflock, localaddr, monlock, sip_pvt::next, sip_pvt::owner, peerl, regl, sched, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_header_function, sip_registry_destroy(), sip_rtp, sip_tech, sip_udptl, sipchaninfo_function, sippeer_function, sipsock, TRUE, and userl.
19590 { 19591 struct sip_pvt *p, *pl; 19592 19593 /* First, take us out of the channel type list */ 19594 ast_channel_unregister(&sip_tech); 19595 19596 /* Unregister dial plan functions */ 19597 ast_custom_function_unregister(&sipchaninfo_function); 19598 ast_custom_function_unregister(&sippeer_function); 19599 ast_custom_function_unregister(&sip_header_function); 19600 ast_custom_function_unregister(&checksipdomain_function); 19601 19602 /* Unregister dial plan applications */ 19603 ast_unregister_application(app_dtmfmode); 19604 ast_unregister_application(app_sipaddheader); 19605 19606 /* Unregister CLI commands */ 19607 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 19608 19609 /* Disconnect from the RTP subsystem */ 19610 ast_rtp_proto_unregister(&sip_rtp); 19611 19612 /* Disconnect from UDPTL */ 19613 ast_udptl_proto_unregister(&sip_udptl); 19614 19615 /* Unregister AMI actions */ 19616 ast_manager_unregister("SIPpeers"); 19617 ast_manager_unregister("SIPshowpeer"); 19618 19619 ast_mutex_lock(&iflock); 19620 /* Hangup all interfaces if they have an owner */ 19621 for (p = iflist; p ; p = p->next) { 19622 if (p->owner) 19623 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 19624 } 19625 ast_mutex_unlock(&iflock); 19626 19627 ast_mutex_lock(&monlock); 19628 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 19629 pthread_cancel(monitor_thread); 19630 pthread_kill(monitor_thread, SIGURG); 19631 pthread_join(monitor_thread, NULL); 19632 } 19633 monitor_thread = AST_PTHREADT_STOP; 19634 ast_mutex_unlock(&monlock); 19635 19636 restartdestroy: 19637 ast_mutex_lock(&iflock); 19638 /* Destroy all the interfaces and free their memory */ 19639 p = iflist; 19640 while (p) { 19641 pl = p; 19642 p = p->next; 19643 if (__sip_destroy(pl, TRUE) < 0) { 19644 /* Something is still bridged, let it react to getting a hangup */ 19645 iflist = p; 19646 ast_mutex_unlock(&iflock); 19647 usleep(1); 19648 goto restartdestroy; 19649 } 19650 } 19651 iflist = NULL; 19652 ast_mutex_unlock(&iflock); 19653 19654 /* Free memory for local network address mask */ 19655 ast_free_ha(localaddr); 19656 19657 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 19658 ASTOBJ_CONTAINER_DESTROY(&userl); 19659 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 19660 ASTOBJ_CONTAINER_DESTROY(&peerl); 19661 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 19662 ASTOBJ_CONTAINER_DESTROY(®l); 19663 19664 clear_realm_authentication(authl); 19665 clear_sip_domains(); 19666 ast_free_ha(global_contact_ha); 19667 close(sipsock); 19668 sched_context_destroy(sched); 19669 19670 return 0; 19671 }
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 3383 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, 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().
03384 { 03385 char name[256]; 03386 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 03387 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03388 struct sip_user *u = NULL; 03389 struct sip_peer *p = NULL; 03390 03391 if (option_debug > 2) 03392 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03393 03394 /* Test if we need to check call limits, in order to avoid 03395 realtime lookups if we do not need it */ 03396 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 03397 return 0; 03398 03399 ast_copy_string(name, fup->username, sizeof(name)); 03400 03401 /* Check the list of users only for incoming calls */ 03402 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03403 inuse = &u->inUse; 03404 call_limit = &u->call_limit; 03405 inringing = NULL; 03406 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1, 0) ) ) { /* Try to find peer */ 03407 inuse = &p->inUse; 03408 call_limit = &p->call_limit; 03409 inringing = &p->inRinging; 03410 ast_copy_string(name, fup->peername, sizeof(name)); 03411 } 03412 if (!p && !u) { 03413 if (option_debug > 1) 03414 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03415 return 0; 03416 } 03417 03418 switch(event) { 03419 /* incoming and outgoing affects the inUse counter */ 03420 case DEC_CALL_LIMIT: 03421 if ( *inuse > 0 ) { 03422 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03423 (*inuse)--; 03424 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03425 } 03426 } else { 03427 *inuse = 0; 03428 } 03429 if (inringing) { 03430 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03431 if (*inringing > 0) 03432 (*inringing)--; 03433 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03434 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03435 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03436 } 03437 } 03438 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) { 03439 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 03440 sip_peer_hold(fup, 0); 03441 } 03442 if (option_debug > 1 || sipdebug) { 03443 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03444 } 03445 break; 03446 03447 case INC_CALL_RINGING: 03448 case INC_CALL_LIMIT: 03449 if (*call_limit > 0 ) { 03450 /* Let call limit affect only outgoing calls */ 03451 if (outgoing && (*inuse >= *call_limit)) { 03452 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); 03453 if (u) 03454 ASTOBJ_UNREF(u, sip_destroy_user); 03455 else 03456 ASTOBJ_UNREF(p, sip_destroy_peer); 03457 return -1; 03458 } 03459 } 03460 if (inringing && (event == INC_CALL_RINGING)) { 03461 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03462 (*inringing)++; 03463 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03464 } 03465 } 03466 /* Continue */ 03467 (*inuse)++; 03468 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03469 if (option_debug > 1 || sipdebug) { 03470 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03471 } 03472 break; 03473 03474 case DEC_CALL_RINGING: 03475 if (inringing) { 03476 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03477 if (*inringing > 0) 03478 (*inringing)--; 03479 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03480 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03481 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03482 } 03483 } 03484 break; 03485 03486 default: 03487 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03488 } 03489 if (p) { 03490 ast_device_state_changed("SIP/%s", p->name); 03491 ASTOBJ_UNREF(p, sip_destroy_peer); 03492 } else /* u must be set */ 03493 ASTOBJ_UNREF(u, sip_destroy_user); 03494 return 0; 03495 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 2627 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, sip_peer::fullcontact, global_flags, 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().
02628 { 02629 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02630 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02631 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02632 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry, p->lastms); 02633 } 02634 }
static void update_provisional_keepalive | ( | struct sip_pvt * | pvt, | |
int | with_sdp | |||
) | [static] |
Definition at line 2369 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, PROVIS_KEEPALIVE_TIMEOUT, sip_pvt::provisional_keepalive_sched_id, sched, send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().
Referenced by transmit_provisional_response().
02370 { 02371 AST_SCHED_DEL(sched, pvt->provisional_keepalive_sched_id); 02372 02373 pvt->provisional_keepalive_sched_id = ast_sched_add(sched, PROVIS_KEEPALIVE_TIMEOUT, 02374 with_sdp ? send_provisional_keepalive_with_sdp : send_provisional_keepalive, pvt); 02375 }
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 = "6989f2ec67f8497e38c12890500c525b" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 19677 of file chan_sip.c.
struct in_addr __ourip [static] |
Definition at line 1265 of file chan_sip.c.
int allow_external_domains [static] |
Accept calls to external SIP domains?
Definition at line 574 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 594 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 19153 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 19155 of file chan_sip.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 19677 of file chan_sip.c.
Definition at line 1254 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 553 of file chan_sip.c.
struct sockaddr_in bindaddr = { 0, } [static] |
The address we bind to
Definition at line 1259 of file chan_sip.c.
unsigned int chan_idx [static] |
Definition at line 402 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 9003 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
struct ast_custom_function checksipdomain_function [static] |
struct ast_cli_entry cli_sip[] [static] |
struct ast_cli_entry cli_sip_debug_deprecated [static] |
Initial value:
{ { "sip", "debug", NULL }, sip_do_debug_deprecated, "Enable SIP debugging", debug_usage }
Definition at line 19415 of file chan_sip.c.
struct ast_cli_entry cli_sip_no_debug_deprecated [static] |
Initial value:
{ { "sip", "no", "debug", NULL }, sip_no_debug_deprecated, "Disable SIP debugging", debug_usage }
Definition at line 19420 of file chan_sip.c.
int compactheaders [static] |
send compact sip headers
Definition at line 568 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Definition at line 235 of file chan_sip.c.
char debug_usage[] [static] |
Definition at line 12499 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1268 of file chan_sip.c.
Referenced by 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 532 of file chan_sip.c.
char default_context[AST_MAX_CONTEXT] [static] |
Definition at line 529 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 193 of file chan_sip.c.
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Definition at line 533 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 226 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Definition at line 531 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 540 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 537 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 538 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Definition at line 534 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 541 of file chan_sip.c.
Referenced by build_device(), build_user(), reload_config(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and temp_peer().
int default_qualify [static] |
Default Qualify= setting
Definition at line 535 of file chan_sip.c.
char default_subscribecontext[AST_MAX_CONTEXT] [static] |
Definition at line 530 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 536 of file chan_sip.c.
char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static] |
Definition at line 19152 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 19158 of file chan_sip.c.
int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 570 of file chan_sip.c.
int expiry = DEFAULT_EXPIRY [static] |
Definition at line 194 of file chan_sip.c.
Referenced by complete_dpreply(), and process_clearcache().
time_t externexpire = 0 [static] |
Expiration counter for re-resolving external host name in dynamic DNS
Definition at line 1262 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor().
char externhost[MAXHOSTNAMELEN] [static] |
External host name (possibly with dynamic DNS and DHCP
Definition at line 1261 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor().
struct sockaddr_in externip [static] |
External IP address if we are behind NAT
Definition at line 1260 of file chan_sip.c.
int externrefresh = 10 [static] |
int global_allowguest [static] |
allow unauthenticated users/peers to connect?
Definition at line 561 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 562 of file chan_sip.c.
enum transfermodes global_allowtransfer [static] |
SIP Refer restriction scheme
Definition at line 578 of file chan_sip.c.
int global_alwaysauthreject [static] |
Send 401 Unauthorized for all failing requests
Definition at line 550 of file chan_sip.c.
int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 577 of file chan_sip.c.
int global_callevents [static] |
Whether we send manager events or not
Definition at line 575 of file chan_sip.c.
int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 [static] |
struct ast_ha* global_contact_ha = NULL [static] |
Global list of addresses dynamic peers are not allowed to use.
Definition at line 586 of file chan_sip.c.
Referenced by build_peer(), parse_register_contact(), reload_config(), and unload_module().
int global_directrtpsetup [static] |
Enable support for Direct RTP setup (no re-invites)
Definition at line 544 of file chan_sip.c.
int global_dynamic_exclude_static = 0 [static] |
Definition at line 587 of file chan_sip.c.
struct ast_flags global_flags[2] = {{0}} [static] |
global SIP_ flags
Definition at line 597 of file chan_sip.c.
Referenced by build_peer(), build_radius_record(), build_user(), destroy_association(), get_destination(), handle_response_peerpoke(), load_module(), realtime_update_peer(), set_peer_defaults(), sip_alloc(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), sip_no_debug_deprecated(), sip_poke_noanswer(), sip_show_settings(), transmit_response_using_temp(), and update_peer().
struct ast_jb_conf global_jbconf [static] |
Definition at line 233 of file chan_sip.c.
int global_limitonpeers [static] |
Match call limit on peers only
Definition at line 546 of file chan_sip.c.
int global_matchexterniplocally [static] |
Match externip/externhost setting against localnet setting
Definition at line 580 of file chan_sip.c.
int global_mwitime [static] |
Time between MWI checks for peers
Definition at line 564 of file chan_sip.c.
int global_notifyhold [static] |
Send notifications on hold
Definition at line 549 of file chan_sip.c.
int global_notifyringing [static] |
Send notifications on ringing
Definition at line 548 of file chan_sip.c.
int global_prematuremediafilter [static] |
Enable/disable premature frames in a call (causing 183 early media)
Definition at line 545 of file chan_sip.c.
char global_realm[MAXHOSTNAMELEN] [static] |
Default realm
Definition at line 571 of file chan_sip.c.
int global_reg_timeout [static] |
Definition at line 558 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 559 of file chan_sip.c.
char global_regcontext[AST_MAX_CONTEXT] [static] |
Context for auto-extensions
Definition at line 572 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 554 of file chan_sip.c.
int global_rtautoclear [static] |
Definition at line 547 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Definition at line 556 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 557 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 555 of file chan_sip.c.
int global_shrinkcallerid [static] |
enable or disable shrinking of caller id
Definition at line 560 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 576 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 851 of file chan_sip.c.
unsigned int global_tos_audio [static] |
IP type of service for audio RTP packets
Definition at line 566 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 565 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 567 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 573 of file chan_sip.c.
char history_usage[] [static] |
Initial value:
"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 12516 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 = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } [static] |
struct io_context* io [static] |
The IO context
Definition at line 618 of file chan_sip.c.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1264 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and unload_module().
char mandescr_show_peer[] [static] |
Initial value:
"Description: Show one SIP peer with details on current status.\n" "Variables: \n" " Peer: <name> The peer name you want to check.\n" " ActionID: <id> Optional action ID for this AMI transaction.\n"
Definition at line 11121 of file chan_sip.c.
char mandescr_show_peers[] [static] |
Initial value:
"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 10672 of file chan_sip.c.
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 192 of file chan_sip.c.
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 191 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 612 of file chan_sip.c.
ast_mutex_t monlock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } [static] |
Definition at line 606 of file chan_sip.c.
ast_mutex_t netlock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, 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 604 of file chan_sip.c.
char no_debug_usage[] [static] |
Initial value:
"Usage: sip set debug off\n" " Disables dumping of SIP packets for debugging purposes\n"
Definition at line 12508 of file chan_sip.c.
char no_history_usage[] [static] |
Initial value:
"Usage: sip history off\n" " Disables recording of SIP dialog history for debugging purposes\n"
Definition at line 12512 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Definition at line 236 of file chan_sip.c.
struct ast_config* notify_types [static] |
The list of manual NOTIFY types we know how to send
Definition at line 1270 of file chan_sip.c.
Referenced by complete_sipnotify(), and sip_notify().
char notify_usage[] [static] |
Initial value:
"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 12448 of file chan_sip.c.
int ourport [static] |
Definition at line 1267 of file chan_sip.c.
struct sockaddr_in outboundproxyip [static] |
Definition at line 1266 of file chan_sip.c.
int pedanticsipchecking [static] |
Extra checking ? Default off
Definition at line 552 of file chan_sip.c.
struct ast_peer_list peerl [static] |
The peer list: Peers and Friends.
char prune_realtime_usage[] [static] |
Initial value:
"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 12490 of file chan_sip.c.
int recordhistory [static] |
Record SIP history. Off by default
Definition at line 569 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 595 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 593 of file chan_sip.c.
int ruserobjs = 0 [static] |
Realtime users
Definition at line 591 of file chan_sip.c.
struct sched_context* sched [static] |
The scheduling context
Definition at line 617 of file chan_sip.c.
char seen_lastms = 0 [static] |
Definition at line 195 of file chan_sip.c.
char show_channel_usage[] [static] |
Initial value:
"Usage: sip show channel <channel>\n" " Provides detailed status on a given SIP channel.\n"
Definition at line 12472 of file chan_sip.c.
char show_channels_usage[] [static] |
Initial value:
"Usage: sip show channels\n" " Lists all currently active SIP channels.\n"
Definition at line 12468 of file chan_sip.c.
char show_domains_usage[] [static] |
Initial value:
"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 12443 of file chan_sip.c.
char show_history_usage[] [static] |
Initial value:
"Usage: sip show history <channel>\n" " Provides detailed dialog history on a given SIP channel.\n"
Definition at line 12476 of file chan_sip.c.
char show_inuse_usage[] [static] |
Initial value:
"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 12463 of file chan_sip.c.
char show_objects_usage[] [static] |
Initial value:
"Usage: sip show objects\n" " Lists status of known SIP objects\n"
Definition at line 12529 of file chan_sip.c.
char show_peer_usage[] [static] |
Initial value:
"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 12485 of file chan_sip.c.
char show_peers_usage[] [static] |
Initial value:
"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 12480 of file chan_sip.c.
char show_reg_usage[] [static] |
Initial value:
"Usage: sip show registry\n" " Lists all registration requests and status.\n"
Definition at line 12495 of file chan_sip.c.
char show_settings_usage[] [static] |
Initial value:
"Usage: sip show settings\n" " Provides detailed list of the configuration of the SIP channel.\n"
Definition at line 12533 of file chan_sip.c.
char show_subscriptions_usage[] [static] |
Initial value:
"Usage: sip show subscriptions\n" " Lists active SIP subscriptions for extension states\n"
Definition at line 12525 of file chan_sip.c.
char show_user_usage[] [static] |
Initial value:
"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 12458 of file chan_sip.c.
char show_users_usage[] [static] |
Initial value:
"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 12453 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
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_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 = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } [static] |
char sip_reload_usage[] [static] |
Initial value:
"Usage: sip reload\n" " Reloads SIP configuration from sip.conf\n"
Definition at line 12521 of file chan_sip.c.
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 614 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 615 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 1673 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 1615 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 1641 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] |
Initial value:
{ type: "SIP", get_udptl_info: sip_get_udptl_peer, set_udptl_peer: sip_set_udptl_peer, }
Definition at line 1682 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 12774 of file chan_sip.c.
Referenced by load_module(), and unload_module().
Structure to declare a dialplan function: SIPPEER.
Definition at line 12694 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 1258 of file chan_sip.c.
Referenced by __sip_xmit(), do_monitor(), reg_source_db(), sipsock_read(), and unload_module().
int* sipsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 619 of file chan_sip.c.
int speerobjs = 0 [static] |
Statis peers
Definition at line 592 of file chan_sip.c.
int srvlookup [static] |
SRV Lookup on or off. Default is on
Definition at line 551 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 590 of file chan_sip.c.
char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static] |
Definition at line 19151 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 19156 of file chan_sip.c.
struct ast_threadstorage ts_temp_pvt = { .once = { PTHREAD_ONCE_INIT } , .key_init = temp_pvt_init , } [static] |
struct ast_user_list userl [static] |
The user list: Users and friends.