#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.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/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
Include dependency graph for chan_sip.c:
Go to the source code of this file.
Data Structures | |
struct | ast_peer_list |
The peer list: Peers and Friends ---. More... | |
struct | ast_user_list |
The user list: Users and friends ---. More... | |
Defines | |
#define | ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support. | |
#define | CALLERID_UNKNOWN "Unknown" |
#define | DEBUG_READ 0 |
#define | DEBUG_SEND 1 |
#define | DEC_CALL_LIMIT 0 |
#define | DEFAULT_CALLERID "asterisk" |
#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_EXPIRY 3600 |
#define | DEFAULT_MAX_FORWARDS "70" |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_MWITIME 10 |
#define | DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define | DEFAULT_REALM "asterisk" |
#define | DEFAULT_REGISTRATION_TIMEOUT 20 |
#define | DEFAULT_RETRANS 1000 |
#define | DEFAULT_SIP_PORT 5060 |
#define | DEFAULT_USERAGENT "Asterisk PBX" |
#define | DEFAULT_VMEXTEN "asterisk" |
#define | EXPIRY_GUARD_LIMIT 30 |
#define | EXPIRY_GUARD_MIN 500 |
#define | EXPIRY_GUARD_PCT 0.20 |
#define | EXPIRY_GUARD_SECS 15 |
#define | FLAG_FATAL (1 << 1) |
#define | FLAG_RESPONSE (1 << 0) |
#define | INC_CALL_LIMIT 1 |
#define | IPTOS_MINCOST 0x02 |
#define | MAX(a, b) ((a) > (b) ? (a) : (b)) |
#define | MAX_AUTHTRIES 3 |
#define | MAX_RETRANS 6 |
#define | NO_RTP 0 |
#define | NOT_SUPPORTED 0 |
#define | REG_STATE_AUTHSENT 2 |
#define | REG_STATE_FAILED 7 |
#define | REG_STATE_NOAUTH 6 |
#define | REG_STATE_REGISTERED 3 |
#define | REG_STATE_REGSENT 1 |
#define | REG_STATE_REJECTED 4 |
#define | REG_STATE_TIMEOUT 5 |
#define | REG_STATE_UNREGISTERED 0 |
#define | RTP 1 |
#define | SIP_ALREADYGONE (1 << 0) |
#define | SIP_CALL_LIMIT (1 << 29) |
#define | SIP_CALL_ONHOLD (1 << 28) |
#define | SIP_CAN_BYE (1 << 15) |
#define | SIP_CAN_REINVITE (1 << 20) |
#define | SIP_DEBUG_CONFIG 1 << 0 |
#define | SIP_DEBUG_CONSOLE 1 << 1 |
#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_GOTREFER (1 << 7) |
#define | SIP_INC_COUNT (1 << 31) |
#define | SIP_INSECURE_INVITE (1 << 23) |
#define | SIP_INSECURE_PORT (1 << 22) |
#define | SIP_LEN_CONTACT 256 |
#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_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_JOIN (1 << 4) |
#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_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_OSPAUTH (3 << 26) |
#define | SIP_OSPAUTH_EXCLUSIVE (3 << 26) |
#define | SIP_OSPAUTH_GATEWAY (1 << 26) |
#define | SIP_OSPAUTH_NO (0 << 26) |
#define | SIP_OSPAUTH_PROXY (2 << 26) |
#define | SIP_OUTGOING (1 << 13) |
#define | SIP_PAGE2_DYNAMIC (1 << 5) |
#define | SIP_PAGE2_IGNOREREGEXPIRE (1 << 3) |
#define | SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
#define | SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
#define | SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
#define | SIP_PAGE2_RTUPDATE (1 << 1) |
#define | SIP_PENDINGBYE (1 << 6) |
#define | SIP_PKT_DEBUG (1 << 0) |
#define | SIP_PKT_WITH_TOTAG (1 << 1) |
#define | SIP_PROG_INBAND (3 << 24) |
#define | SIP_PROG_INBAND_NEVER (0 << 24) |
#define | SIP_PROG_INBAND_NO (1 << 24) |
#define | SIP_PROG_INBAND_YES (2 << 24) |
#define | SIP_PROGRESS_SENT (1 << 4) |
#define | SIP_PROMISCREDIR (1 << 8) |
#define | SIP_REALTIME (1 << 11) |
#define | SIP_REINVITE (3 << 20) |
#define | SIP_REINVITE_UPDATE (2 << 20) |
#define | SIP_RINGING (1 << 3) |
#define | SIP_SELFDESTRUCT (1 << 14) |
#define | SIP_SENDRPID (1 << 30) |
#define | SIP_TRUSTRPID (1 << 9) |
#define | SIP_USECLIENTCODE (1 << 12) |
#define | SIP_USEREQPHONE (1 << 10) |
#define | SIPDUMPER |
#define | SUPPORTED 1 |
#define | SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support. | |
#define | VIDEO_CODEC_MASK 0x1fc0000 |
Enumerations | |
enum | domain_mode { SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG } |
enum | parse_register_result { PARSE_REGISTER_FAILED, PARSE_REGISTER_UPDATE, PARSE_REGISTER_QUERY } |
enum | sip_auth_type { PROXY_AUTH, WWW_AUTH } |
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 } |
enum | subscriptiontype { NONE = 0, TIMEOUT, XPIDF_XML, DIALOG_INFO_XML, CPIM_PIDF_XML, PIDF_XML } |
Functions | |
static char * | __get_header (struct sip_request *req, char *name, int *start) |
static int | __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
__sip_ack: Acknowledges receipt of a packet and stops retransmission --- | |
static int | __sip_autodestruct (void *data) |
__sip_autodestruct: Kill a call (called by scheduler) --- | |
static void | __sip_destroy (struct sip_pvt *p, int lockowner) |
__sip_destroy: Execute destrucion of call structure, release memory--- | |
static int | __sip_do_register (struct sip_registry *r) |
__sip_do_register: Register with SIP proxy --- | |
static int | __sip_pretend_ack (struct sip_pvt *p) |
static int | __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod) |
__sip_reliable_xmit: transmit packet with retransmits --- | |
static int | __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
__sip_semi_ack: Acks receipt of packet, keep it around (used for provisional responses) --- | |
static int | __sip_show_channels (int fd, int argc, char *argv[], int subscriptions) |
static int | __sip_xmit (struct sip_pvt *p, char *data, int len) |
__sip_xmit: Transmit SIP message --- | |
static int | __transmit_response (struct sip_pvt *p, char *msg, struct sip_request *req, int reliable) |
__transmit_response: Base transmit response function | |
static int | _sip_show_peer (int type, int fd, struct mansession *s, struct message *m, int argc, char *argv[]) |
static int | _sip_show_peers (int fd, int *total, struct mansession *s, struct message *m, int argc, char *argv[]) |
_sip_show_peers: Execute sip show peers command | |
static int | add_blank_header (struct sip_request *req) |
add_blank_header: Add blank header to SIP message | |
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) |
static int | add_digit (struct sip_request *req, char digit) |
add_digit: add DTMF INFO tone to sip message --- | |
static int | add_header (struct sip_request *req, const char *var, const char *value) |
add_header: Add header to SIP message | |
static int | add_header_contentLength (struct sip_request *req, int len) |
add_header_contentLen: Add 'Content-Length' header to SIP message | |
static int | add_line (struct sip_request *req, const char *line) |
add_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) |
static struct sip_auth * | add_realm_authentication (struct sip_auth *authlist, char *configuration, int lineno) |
add_realm_authentication: Add realm authentication in list --- | |
static void | add_route (struct sip_request *req, struct sip_route *route) |
add_route: Add route header into request per learned route --- | |
static int | add_sdp (struct sip_request *resp, struct sip_pvt *p) |
add_sdp: Add Session Description Protocol message --- | |
static int | add_sip_domain (const char *domain, const enum domain_mode mode, const char *context) |
add_sip_domain: Add SIP domain to list of domains we are responsible for | |
static int | add_text (struct sip_request *req, const char *text) |
add_text: Add text body to SIP message --- | |
static int | add_vidupdate (struct sip_request *req) |
add_vidupdate: add XML encoded media control with update --- | |
static void | append_date (struct sip_request *req) |
append_date: Append date to SIP message --- | |
static int | append_history (struct sip_pvt *p, const char *event, const char *data) |
append_history: Append to SIP dialog history | |
static | AST_LIST_HEAD_STATIC (domain_list, domain) |
AST_MUTEX_DEFINE_STATIC (sip_reload_lock) | |
AST_MUTEX_DEFINE_STATIC (monlock) | |
AST_MUTEX_DEFINE_STATIC (netlock) | |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
AST_MUTEX_DEFINE_STATIC (iflock) | |
Protect the interface list (of sip_pvt's). | |
AST_MUTEX_DEFINE_STATIC (rand_lock) | |
AST_MUTEX_DEFINE_STATIC (usecnt_lock) | |
static void | ast_quiet_chan (struct ast_channel *chan) |
ast_quiet_chan: Turn off generator data | |
static int | ast_sip_ouraddrfor (struct in_addr *them, struct in_addr *us) |
ast_sip_ouraddrfor: NAT fix - decide which IP address to use for ASterisk server? --- | |
static int | attempt_transfer (struct sip_pvt *p1, struct sip_pvt *p2) |
attempt_transfer: Attempt transfer of SIP call --- | |
static int | auto_congest (void *nothing) |
auto_congest: Scheduled congestion on a call --- | |
static void | build_callid (char *callid, int len, struct in_addr ourip, char *fromdomain) |
build_callid: Build SIP CALLID header --- | |
static void | build_contact (struct sip_pvt *p) |
build_contact: Build contact header - the contact header we send out --- | |
static struct sip_peer * | build_peer (const char *name, struct ast_variable *v, int realtime) |
build_peer: Build peer from config file --- | |
static int | build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len) |
build_reply_digest: Build reply digest --- | |
static void | build_route (struct sip_pvt *p, struct sip_request *req, int backwards) |
build_route: Build route list from Record-Route header --- | |
static void | build_rpid (struct sip_pvt *p) |
build_rpid: Build the Remote Party-ID & From using callingpres options --- | |
static struct sip_user * | build_user (const char *name, struct ast_variable *v, int realtime) |
build_user: Initiate a SIP user structure from sip.conf --- | |
static void | build_via (struct sip_pvt *p, char *buf, int len) |
build_via: Build a Via header for a request --- | |
static int | cb_extensionstate (char *context, char *exten, int state, void *data) |
cb_extensionstate: Callback for the devicestate notification (SUBSCRIBE) support subsystem --- | |
static int | check_auth (struct sip_pvt *p, struct sip_request *req, char *randdata, int randlen, char *username, char *secret, char *md5secret, int sipmethod, char *uri, int reliable, int ignore) |
check_auth: Check user authorization from peer definition --- | |
static int | check_osptoken (struct sip_pvt *p, char *token) |
check_osptoken: Validate OSP token for user authrroization --- | |
static void | check_pendings (struct sip_pvt *p) |
check_pendings: 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, int reliable, struct sockaddr_in *sin, int ignore) |
check_user: Find user --- | |
static int | check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, int reliable, struct sockaddr_in *sin, int ignore, char *mailbox, int mailboxlen) |
check_user_full: Check if matching user or peer is defined --- | |
static int | check_via (struct sip_pvt *p, struct sip_request *req) |
check Via: header for hostname, port and rport request/answer | |
static int | clear_realm_authentication (struct sip_auth *authlist) |
clear_realm_authentication: Clear realm authentication list (at reload) --- | |
static void | clear_sip_domains (void) |
clear_sip_domains: Clear our domain list (at reload) | |
static char * | complete_sip_debug_peer (char *line, char *word, int pos, int state) |
complete_sip_debug_peer: Support routine for 'sip debug peer' CLI --- | |
static char * | complete_sip_peer (char *word, int state, int flags2) |
complete_sip_peer: Do completion on peer name --- | |
static char * | complete_sip_prune_realtime_peer (char *line, char *word, int pos, int state) |
complete_sip_prune_realtime_peer: Support routine for 'sip prune realtime peer' CLI --- | |
static char * | complete_sip_prune_realtime_user (char *line, char *word, int pos, int state) |
complete_sip_prune_realtime_user: Support routine for 'sip prune realtime user' CLI --- | |
static char * | complete_sip_show_peer (char *line, char *word, int pos, int state) |
complete_sip_show_peer: Support routine for 'sip show peer' CLI --- | |
static char * | complete_sip_show_user (char *line, char *word, int pos, int state) |
complete_sip_show_user: Support routine for 'sip show user' CLI --- | |
static char * | complete_sip_user (char *word, int state, int flags2) |
complete_sip_user: Do completion on user name --- | |
static char * | complete_sipch (char *line, char *word, int pos, int state) |
complete_sipch: Support routine for 'sip show channel' CLI --- | |
static char * | complete_sipnotify (char *line, char *word, int pos, int state) |
complete_sipnotify: Support routine for 'sip notify' CLI --- | |
static int | copy_all_header (struct sip_request *req, struct sip_request *orig, char *field) |
copy_all_header: Copy all headers from one request to another --- | |
static int | copy_header (struct sip_request *req, struct sip_request *orig, char *field) |
copy_header: Copy one header field from one request to another | |
static void | copy_request (struct sip_request *dst, struct sip_request *src) |
copy_request: copy SIP request (mostly used to save request for responses) --- | |
static int | copy_via_headers (struct sip_pvt *p, struct sip_request *req, struct sip_request *orig, char *field) |
copy_via_headers: Copy SIP VIA Headers from the request to the response --- | |
static int | create_addr (struct sip_pvt *dialog, char *opeer) |
create_addr: 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 *r, struct sip_peer *peer) |
create_addr_from_peer: create address structure from peer reference --- | |
char * | description () |
Provides a description of the module. | |
static void | destroy_association (struct sip_peer *peer) |
static int | determine_firstline_parts (struct sip_request *req) |
determine_firstline_parts: parse first line of incoming SIP request | |
static void * | do_monitor (void *data) |
do_monitor: 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) |
do_proxy_auth: Add authentication on outbound SIP packet --- | |
static int | do_register_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader) |
do_register_auth: Authenticate for outbound registration --- | |
static const char * | domain_mode_to_text (const enum domain_mode mode) |
static const char * | dtmfmode2str (int mode) |
dtmfmode2str: Convert DTMF mode to printable string --- | |
static int | expire_register (void *data) |
expire_register: Expire registration of SIP peer --- | |
static void | extract_uri (struct sip_pvt *p, struct sip_request *req) |
extract_uri: Check Contact: URI of SIP message --- | |
static char * | find_alias (const char *name, char *_default) |
static struct sip_pvt * | find_call (struct sip_request *req, struct sockaddr_in *sin, const int intended_method) |
find_call: Connect incoming SIP message to current dialog or create new dialog structure | |
static struct sip_peer * | find_peer (const char *peer, struct sockaddr_in *sin, int realtime) |
find_peer: 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, char *realm) |
find_realm_authentication: 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. | |
int | find_sip_method (char *msg) |
find_sip_method: Find SIP method from header Strictly speaking, SIP methods are case SENSITIVE, but we don't check following Jon Postel's rule: Be gentle in what you accept, strict with what you send | |
static const struct cfsubscription_types * | find_subscription_type (enum subscriptiontype subtype) |
find_subscription_type: Find subscription type in array | |
static struct sip_user * | find_user (const char *name, int realtime) |
find_user: 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) |
free_old_route: Remove route from route list --- | |
static char * | func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
function_check_sipdomain: Dial plan function to check if domain is local | |
static char * | func_header_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
func_header_read: Read SIP header (dialplan function) | |
static char * | function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
function_sipchaninfo_read: ${SIPCHANINFO()} Dialplan function - reads sip channel data | |
static char * | function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
function_sippeer: ${SIPPEER()} Dialplan function - reads peer data | |
static int | get_also_info (struct sip_pvt *p, struct sip_request *oreq) |
get_also_info: Call transfer support (old way, depreciated)-- | |
static char * | get_body (struct sip_request *req, char *name) |
get_body: get a specific line from the message body | |
static char * | get_body_by_line (char *line, char *name, int nameLen) |
get_body_by_line: Reads one line of message body | |
static char * | get_calleridname (char *input, char *output, size_t outputsize) |
get_calleridname: Get caller id name from SIP headers --- | |
static int | get_destination (struct sip_pvt *p, struct sip_request *oreq) |
get_destination: Find out who the call is for -- | |
static char * | get_header (struct sip_request *req, char *name) |
get_header: Get header from SIP request --- | |
static char * | get_in_brackets (char *tmp) |
get_in_brackets: Pick out text in brackets from character string --- | |
static int | get_msg_text (char *buf, int len, struct sip_request *req) |
get_msg_text: Get text out of a SIP MESSAGE packet --- | |
static int | get_rdnis (struct sip_pvt *p, struct sip_request *oreq) |
get_rdnis: get referring dnis --- | |
static int | get_refer_info (struct sip_pvt *sip_pvt, struct sip_request *outgoing_req) |
get_refer_info: Call transfer support (the REFER method) --- | |
static int | get_rpid_num (char *input, char *output, int maxlen) |
get_rpid_num: 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 char * | get_sdp (struct sip_request *req, char *name) |
get_sdp: get a specific line from the SDP | |
static char * | get_sdp_iterate (int *iterator, struct sip_request *req, char *name) |
static struct sip_pvt * | get_sip_pvt_byid_locked (char *callid) |
get_sip_pvt_byid_locked: Lock interface lock and find matching pvt lock --- | |
static char * | gettag (struct sip_request *req, char *header, char *tagbuf, int tagbufsize) |
gettag: Get tag from packet | |
static int | handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v) |
handle_common_options: Handle flag-type options common to users and peers --- | |
static int | handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock) |
handle_request: Handle SIP requests (methods) --- | |
static int | handle_request_bye (struct sip_pvt *p, struct sip_request *req, int debug, int ignore) |
handle_request_bye: Handle incoming BYE request --- | |
static int | handle_request_cancel (struct sip_pvt *p, struct sip_request *req, int debug, int ignore) |
handle_request_cancel: Handle incoming CANCEL request --- | |
static void | handle_request_info (struct sip_pvt *p, struct sip_request *req) |
handle_request_info: Receive SIP INFO Message --- | |
static int | handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin, int *recount, char *e) |
handle_request_invite: Handle incoming INVITE request | |
static int | handle_request_message (struct sip_pvt *p, struct sip_request *req, int debug, int ignore) |
handle_request_message: Handle incoming MESSAGE request --- | |
static int | handle_request_options (struct sip_pvt *p, struct sip_request *req, int debug) |
handle_request_options: 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) |
handle_request_refer: Handle incoming REFER request --- | |
static int | handle_request_register (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, struct sockaddr_in *sin, char *e) |
handle_request_register: Handle incoming REGISTER request --- | |
static int | handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, struct sockaddr_in *sin, int seqno, char *e) |
handle_request_subscribe: Handle incoming SUBSCRIBE request --- | |
static void | handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
handle_response: Handle SIP response in dialogue --- | |
static void | handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
handle_response_invite: Handle SIP response in dialogue --- | |
static int | handle_response_peerpoke (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno, int sipmethod) |
handle_response_peerpoke: Handle qualification responses (OPTIONS) | |
static int | handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
handle_response_register: Handle responses on REGISTER to services --- | |
static char * | hangup_cause2sip (int cause) |
hangup_cause2sip: Convert Asterisk hangup causes to SIP codes | |
static int | hangup_sip2cause (int cause) |
hangup_sip2cause: Convert SIP hangup causes to Asterisk hangup causes --- | |
static int | init_req (struct sip_request *req, int sipmethod, char *recip) |
init_req: Initialize SIP request --- | |
static int | init_resp (struct sip_request *req, char *resp, struct sip_request *orig) |
init_resp: Initialize SIP response, based on SIP request --- | |
static void | initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod) |
initreqprep: Initiate new SIP request to peer/user --- | |
static const char * | insecure2str (int port, int invite) |
insecure2str: Convert Insecure setting to printable string --- | |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
static void | list_route (struct sip_route *route) |
list_route: List all routes - mostly for debugging --- | |
int | load_module () |
Initialize the module. | |
static int | lws2sws (char *msgbuf, int len) |
lws2sws: Parse multiline SIP headers into one header | |
static void | make_our_tag (char *tagbuf, size_t len) |
static int | manager_sip_show_peer (struct mansession *s, struct message *m) |
manager_sip_show_peer: Show SIP peers in the manager API --- | |
static int | manager_sip_show_peers (struct mansession *s, struct message *m) |
manager_sip_show_peers: Show SIP peers in the manager API --- | |
static char * | nat2str (int nat) |
nat2str: Convert NAT setting to text string | |
static void | parse_copy (struct sip_request *dst, struct sip_request *src) |
parse_copy: Copy SIP request, parse it | |
static void | parse_moved_contact (struct sip_pvt *p, struct sip_request *req) |
parse_moved_contact: Parse 302 Moved temporalily response | |
static int | parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req) |
parse_ok_contact: Parse contact header for 200 OK on INVITE --- | |
static enum parse_register_result | parse_register_contact (struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req) |
parse_register_contact: Parse contact header and save registration --- | |
static void | parse_request (struct sip_request *req) |
parse_request: Parse a SIP message ---- | |
unsigned int | parse_sip_options (struct sip_pvt *pvt, char *supported) |
parse_sip_options: Parse supported header in incoming packet | |
static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
peer_status: Report Peer status in character string | |
static void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
print_codec_to_cli: Print codec list from preference to CLI/manager | |
static void | print_group (int fd, unsigned int group, int crlf) |
print_group: Print call group and pickup group --- | |
static int | process_sdp (struct sip_pvt *p, struct sip_request *req) |
process_sdp: Process SIP SDP and activate RTP channels--- | |
static struct sip_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
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) |
realtime_update_peer: Update peer object in realtime storage --- | |
static struct sip_user * | realtime_user (const char *username) |
realtime_user: 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_message: Receive SIP MESSAGE method messages --- | |
static void | reg_source_db (struct sip_peer *peer) |
reg_source_db: Get registration details from Asterisk DB --- | |
static void | register_peer_exten (struct sip_peer *peer, int onoff) |
register_peer_exten: Automatically add peer extension to dial plan --- | |
static int | register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri, int ignore) |
register_verify: Verify registration of user | |
static char * | regstate2str (int regstate) |
int | reload (void) |
Reload stuff. | |
static int | reload_config (void) |
reload_config: 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_digest: reply to authentication for outbound registrations --- | |
static int | reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch) |
reqprep: Initialize a SIP request response packet --- | |
static int | respprep (struct sip_request *resp, struct sip_pvt *p, char *msg, struct sip_request *req) |
respprep: Prepare SIP response packet --- | |
static int | restart_monitor (void) |
restart_monitor: Start the channel monitor thread --- | |
static int | retrans_pkt (void *data) |
retrans_pkt: Retransmit SIP message if no answer --- | |
static void | sdpLineNum_iterator_init (int *iterator, struct sip_request *req) |
static int | send_request (struct sip_pvt *p, struct sip_request *req, int reliable, int seqno) |
send_request: Send SIP Request to the other part of the dialogue --- | |
static int | send_response (struct sip_pvt *p, struct sip_request *req, int reliable, int seqno) |
send_response: Transmit response on SIP request--- | |
static void | set_destination (struct sip_pvt *p, char *uri) |
set_destination: Set destination from SIP URI --- | |
static int | sip_addheader (struct ast_channel *chan, void *data) |
sip_addheader: Add a SIP header --- | |
static int | sip_addrcmp (char *name, struct sockaddr_in *sin) |
sip_addrcmp: Support routine for find_peer --- | |
static struct sip_pvt * | sip_alloc (char *callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method) |
sip_alloc: Allocate SIP_PVT structure and set defaults --- | |
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) |
sip_call: Initiate SIP call from PBX used from the dial() application | |
static int | sip_cancel_destroy (struct sip_pvt *p) |
sip_cancel_destroy: Cancel destruction of SIP call --- | |
static int | sip_debug_test_addr (struct sockaddr_in *addr) |
sip_debug_test_addr: See if we pass debug IP filter | |
static int | sip_debug_test_pvt (struct sip_pvt *p) |
sip_debug_test_pvt: Test PVT for debugging output | |
static void | sip_destroy (struct sip_pvt *p) |
sip_destroy: Destroy SIP call structure --- | |
static void | sip_destroy_peer (struct sip_peer *peer) |
sip_destroy_peer: Destroy peer object from memory | |
static void | sip_destroy_user (struct sip_user *user) |
sip_destroy_user: Remove user object from in-memory storage --- | |
static int | sip_devicestate (void *data) |
sip_devicestate: Part of PBX channel interface --- | |
static int | sip_do_debug (int fd, int argc, char *argv[]) |
sip_do_debug: Turn on SIP debugging (CLI command) | |
static int | sip_do_debug_ip (int fd, int argc, char *argv[]) |
sip_do_debug: 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[]) |
sip_do_history: Enable SIP History logging (CLI) --- | |
static int | sip_do_reload (void) |
sip_do_reload: Reload module | |
static int | sip_dtmfmode (struct ast_channel *chan, void *data) |
sip_dtmfmode: change the DTMFmode for a SIP call (application) --- | |
static void | sip_dump_history (struct sip_pvt *dialog) |
dump_history: 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) |
sip_get_codec: Return SIP UA's codec (part of the RTP interface) --- | |
static struct ast_rtp * | sip_get_rtp_peer (struct ast_channel *chan) |
sip_get_rtp_peer: Returns null if we can't reinvite (part of RTP interface) | |
static struct ast_rtp * | sip_get_vrtp_peer (struct ast_channel *chan) |
sip_get_vrtp_peer: Returns null if we can't reinvite video (part of RTP interface) | |
static int | sip_getheader (struct ast_channel *chan, void *data) |
sip_getheader: Get a SIP header (dialplan app) --- | |
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) |
sip_indicate: 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 struct ast_channel * | sip_new (struct sip_pvt *i, int state, char *title) |
sip_new: Initiate a call in the SIP channel | |
static int | sip_no_debug (int fd, int argc, char *argv[]) |
sip_no_debug: Disable SIP Debugging in CLI --- | |
static int | sip_no_history (int fd, int argc, char *argv[]) |
sip_no_history: Disable SIP History logging (CLI) --- | |
static int | sip_notify (int fd, int argc, char *argv[]) |
sip_notify: Send SIP notify to peer | |
static int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req) |
sip_park: Park a call --- | |
static void * | sip_park_thread (void *stuff) |
sip_park_thread: Park SIP call support function | |
static void | sip_poke_all_peers (void) |
sip_poke_all_peers: Send a poke to all known peers | |
static int | sip_poke_noanswer (void *data) |
sip_poke_noanswer: No answer to Qualify poke --- | |
static int | sip_poke_peer (struct sip_peer *peer) |
sip_poke_peer: Check availability of peer, also keep NAT open --- | |
static int | sip_poke_peer_s (void *data) |
static int | sip_prune_realtime (int fd, int argc, char *argv[]) |
sip_prune_realtime: Remove temporary realtime objects from memory (CLI) --- | |
static struct ast_frame * | sip_read (struct ast_channel *ast) |
sip_read: Read SIP RTP from channel | |
static int | sip_reg_timeout (void *data) |
sip_reg_timeout: Registration timeout, register again | |
static int | sip_register (char *value, int lineno) |
sip_register: Parse register=> line in sip.conf and add to registry | |
static void | sip_registry_destroy (struct sip_registry *reg) |
sip_registry_destroy: Destroy registry object --- | |
static int | sip_reload (int fd, int argc, char *argv[]) |
sip_reload: Force reload of module from cli --- | |
static struct ast_channel * | sip_request_call (const char *type, int format, void *data, int *cause) |
sip_request: PBX interface function -build SIP pvt structure --- | |
static int | sip_reregister (void *data) |
sip_reregister: Update registration with SIP Proxy--- | |
static struct ast_frame * | sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p) |
sip_rtp_read: Read RTP from network --- | |
static int | sip_scheddestroy (struct sip_pvt *p, int ms) |
sip_scheddestroy: Schedule destruction of SIP call --- | |
static void | sip_send_all_registers (void) |
sip_send_all_registers: Send all known registrations | |
static int | sip_send_mwi_to_peer (struct sip_peer *peer) |
sip_send_mwi_to_peer: Send message waiting indication --- | |
static int | sip_senddigit (struct ast_channel *ast, char digit) |
sip_senddigit: Send DTMF character on SIP channel | |
static int | sip_sendtext (struct ast_channel *ast, const char *text) |
sip_sendtext: Send SIP MESSAGE text within a call --- | |
static int | sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active) |
sip_set_rtp_peer: Set the RTP peer for this call --- | |
static int | sip_show_channel (int fd, int argc, char *argv[]) |
sip_show_channel: Show details of one call --- | |
static int | sip_show_channels (int fd, int argc, char *argv[]) |
sip_show_channels: Show active SIP channels --- | |
static int | sip_show_domains (int fd, int argc, char *argv[]) |
static int | sip_show_history (int fd, int argc, char *argv[]) |
sip_show_history: Show history details of one call --- | |
static int | sip_show_inuse (int fd, int argc, char *argv[]) |
sip_show_inuse: CLI Command to show calls within limits set by call_limit --- | |
static int | sip_show_objects (int fd, int argc, char *argv[]) |
sip_show_objects: List all allocated SIP Objects --- | |
static int | sip_show_peer (int fd, int argc, char *argv[]) |
sip_show_peer: Show one peer in detail --- | |
static int | sip_show_peers (int fd, int argc, char *argv[]) |
sip_show_peers: CLI Show Peers command | |
static int | sip_show_registry (int fd, int argc, char *argv[]) |
sip_show_registry: Show SIP Registry (registrations with other SIP proxies --- | |
static int | sip_show_settings (int fd, int argc, char *argv[]) |
sip_show_settings: List global settings for the SIP channel --- | |
static int | sip_show_subscriptions (int fd, int argc, char *argv[]) |
sip_show_subscriptions: Show active SIP subscriptions --- | |
static int | sip_show_user (int fd, int argc, char *argv[]) |
sip_show_user: Show one user in detail --- | |
static int | sip_show_users (int fd, int argc, char *argv[]) |
sip_show_users: CLI Command 'SIP Show Users' --- | |
static int | sip_sipredirect (struct sip_pvt *p, const char *dest) |
sip_sipredirect: Transfer call before connect with a 302 redirect --- | |
static int | sip_transfer (struct ast_channel *ast, const char *dest) |
sip_transfer: Transfer SIP call | |
static int | sip_write (struct ast_channel *ast, struct ast_frame *frame) |
sip_write: Send frame to media channel (rtp) --- | |
static int | sipsock_read (int *id, int fd, short events, void *ignore) |
sipsock_read: Read data from SIP socket --- | |
static const char * | subscription_type2str (enum subscriptiontype subtype) |
subscription_type2str: Show subscription type in string format | |
static struct sip_peer * | temp_peer (const char *name) |
temp_peer: Create temporary peer (used in autocreatepeer mode) --- | |
static force_inline int | thread_safe_rand (void) |
Thread-safe random number generator. | |
static void | transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, char *randdata, int randlen, int 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, char digit) |
transmit_info_with_digit: Send SIP INFO dtmf message, see Cisco documentation on cisco.co m --- | |
static int | transmit_info_with_vidupdate (struct sip_pvt *p) |
transmit_info_with_vidupdate: Send SIP INFO with video update request --- | |
static int | transmit_invite (struct sip_pvt *p, int sipmethod, int sendsdp, int init) |
transmit_invite: Build REFER/INVITE/OPTIONS message and transmit it --- | |
static int | transmit_message_with_text (struct sip_pvt *p, const char *text) |
transmit_message_with_text: Transmit text with SIP MESSAGE method --- | |
static int | transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten) |
transmit_notify_with_mwi: Notify user of messages waiting in voicemail --- | |
static int | transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq) |
transmit_notify_with_sipfrag: Notify a transferring party of the status of trasnfer --- | |
static int | transmit_refer (struct sip_pvt *p, const char *dest) |
transmit_refer: Transmit SIP REFER message --- | |
static int | transmit_register (struct sip_registry *r, int sipmethod, char *auth, char *authheader) |
transmit_register: Transmit register to SIP proxy or UA --- | |
static int | transmit_reinvite_with_sdp (struct sip_pvt *p) |
transmit_reinvite_with_sdp: Transmit reinvite with SDP :-) --- | |
static int | transmit_request (struct sip_pvt *p, int sipmethod, int inc, int reliable, int newbranch) |
transmit_request: transmit generic SIP request --- | |
static int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int inc, int reliable, int newbranch) |
transmit_request_with_auth: Transmit SIP request, auth added --- | |
static int | transmit_response (struct sip_pvt *p, char *msg, struct sip_request *req) |
transmit_response: Transmit response, no retransmits | |
static int | transmit_response_reliable (struct sip_pvt *p, char *msg, struct sip_request *req, int fatal) |
transmit_response_reliable: Transmit response, Make sure you get a reply | |
static int | transmit_response_with_allow (struct sip_pvt *p, char *msg, struct sip_request *req, int reliable) |
transmit_response_with_allow: Append Accept header, content length before transmitting response --- | |
static int | transmit_response_with_auth (struct sip_pvt *p, char *msg, struct sip_request *req, char *rand, int reliable, char *header, int stale) |
static int | transmit_response_with_date (struct sip_pvt *p, char *msg, struct sip_request *req) |
transmit_response_with_date: Append date and content length before transmitting response --- | |
static int | transmit_response_with_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans) |
transmit_response_with_sdp: Used for 200 OK and 183 early media --- | |
static int | transmit_response_with_unsupported (struct sip_pvt *p, char *msg, struct sip_request *req, char *unsupported) |
transmit_response_with_unsupported: Transmit response, no retransmits | |
static int | transmit_sip_request (struct sip_pvt *p, struct sip_request *req) |
transmit_sip_request: Transmit SIP request | |
static int | transmit_state_notify (struct sip_pvt *p, int state, int full, int substate) |
transmit_state_notify: 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. | |
int | unload_module () |
Cleanup all module structures, sockets, etc. | |
static int | update_call_counter (struct sip_pvt *fup, int event) |
update_call_counter: Handle call_limit for SIP users Note: This is going to be replaced by app_groupcount Thought: For realtime, we should propably update storage with inuse counter... | |
static void | update_peer (struct sip_peer *p, int expiry) |
update_peer: Update peer data in database (if used) --- | |
int | usecount () |
Provides a usecount. | |
Variables | |
static struct in_addr | __ourip |
static const struct cfalias | aliases [] |
Structure for conversion between compressed SIP and "normal" SIP. | |
int | allow_external_domains |
static int | apeerobjs = 0 |
static char * | app_dtmfmode = "SIPDtmfMode" |
static char * | app_sipaddheader = "SIPAddHeader" |
static char * | app_sipgetheader = "SIPGetHeader" |
static struct sip_auth * | authl |
static int | autocreatepeer = 0 |
static struct sockaddr_in | bindaddr = { 0, } |
static int | callevents = 0 |
static const char | channeltype [] = "SIP" |
static struct ast_custom_function | checksipdomain_function |
static int | compactheaders = 0 |
static const char | config [] = "sip.conf" |
static char | debug_usage [] |
static struct sockaddr_in | debugaddr |
static char | default_callerid [AST_MAX_EXTENSION] = DEFAULT_CALLERID |
static char | default_context [AST_MAX_CONTEXT] = DEFAULT_CONTEXT |
static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
static char | default_fromdomain [AST_MAX_EXTENSION] = "" |
static char | default_language [MAX_LANGUAGE] = "" |
static char | default_notifymime [AST_MAX_EXTENSION] = DEFAULT_NOTIFYMIME |
static int | default_qualify = 0 |
static char | default_subscribecontext [AST_MAX_CONTEXT] |
static char | default_useragent [AST_MAX_EXTENSION] = DEFAULT_USERAGENT |
static const char | desc [] = "Session Initiation Protocol (SIP)" |
static char * | descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" |
static char * | descrip_sipaddheader |
static char * | descrip_sipgetheader |
static int | dumphistory = 0 |
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 = 1 |
static int | global_alwaysauthreject = 0 |
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_flags | global_flags = {0} |
static struct ast_flags | global_flags_page2 = {0} |
static char | global_musicclass [MAX_MUSICCLASS] = "" |
static int | global_mwitime = DEFAULT_MWITIME |
static int | global_notifyringing = 1 |
static char | global_realm [MAXHOSTNAMELEN] = DEFAULT_REALM |
static int | global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT |
static int | global_regattempts_max = 0 |
static int | global_rtautoclear |
static int | global_rtpholdtimeout = 0 |
static int | global_rtpkeepalive = 0 |
static int | global_rtptimeout = 0 |
static char | global_vmexten [AST_MAX_EXTENSION] = DEFAULT_VMEXTEN |
static char | history_usage [] |
static struct sip_pvt * | iflist |
sip_pvt: PVT structures are used for each SIP conversation, ie. a call | |
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 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 struct ast_cli_entry | my_clis [] |
static char | no_debug_usage [] |
static char | no_history_usage [] |
static int | noncodeccapability = AST_RTP_DTMF |
static const char | notify_config [] = "sip_notify.conf" |
ast_config * | notify_types |
static char | notify_usage [] |
static int | ourport |
static struct sockaddr_in | outboundproxyip |
static int | pedanticsipchecking = 0 |
static struct ast_peer_list | peerl |
The peer list: Peers and Friends ---. | |
static struct ast_codec_pref | prefs |
static char | prune_realtime_usage [] |
static int | recordhistory = 0 |
static char | regcontext [AST_MAX_CONTEXT] = "" |
static struct ast_register_list | regl |
The register list: Other SIP proxys we register with and call ---. | |
static int | regobjs = 0 |
static int | relaxdtmf = 0 |
static int | rpeerobjs = 0 |
static int | ruserobjs = 0 |
static struct sched_context * | sched |
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 |
enum sipmethod | sip_method_list |
static const struct cfsip_methods | sip_methods [] |
static const 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 char | sip_reload_usage [] |
static int | sip_reloading = 0 |
static struct ast_rtp_protocol | sip_rtp |
sip_rtp: Interface structure with callbacks used to connect to rtp module -- | |
static const struct ast_channel_tech | sip_tech |
Definition of this channel for PBX channel registration. | |
static struct ast_custom_function | sipchaninfo_function |
static int | sipdebug = 0 |
ast_custom_function | sippeer_function |
static int | sipsock = -1 |
static int | speerobjs = 0 |
static int | srvlookup = 0 |
static const 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 char * | synopsis_sipgetheader = "Get a SIP header from an incoming call" |
static int | tos = 0 |
static int | usecnt = 0 |
static struct ast_user_list | userl |
The user list: Users and friends ---. | |
static int | videosupport = 0 |
Implementation of RFC 3261 - without S/MIME, TCP and TLS support Configuration file sip.conf
SIP over TLS
Better support of forking
Definition in file chan_sip.c.
|
SIP Methods we support.
Definition at line 323 of file chan_sip.c. Referenced by respprep(), transmit_invite(), and transmit_reinvite_with_sdp(). |
|
Definition at line 127 of file chan_sip.c. Referenced by initreqprep(). |
|
Definition at line 141 of file chan_sip.c. Referenced by ael_debug_read(), and ast_ael_compile(). |
|
Definition at line 142 of file chan_sip.c. |
|
Definition at line 445 of file chan_sip.c. Referenced by handle_request_invite(), handle_response(), sip_hangup(), and update_call_counter(). |
|
Definition at line 342 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 333 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 101 of file chan_sip.c. Referenced by reload_config(). |
|
Expire slowly Definition at line 436 of file chan_sip.c. |
|
Definition at line 133 of file chan_sip.c. |
|
Definition at line 132 of file chan_sip.c. |
|
Definition at line 102 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 104 of file chan_sip.c. Referenced by initreqprep(), reqprep(), and transmit_register(). |
|
Definition at line 131 of file chan_sip.c. |
|
Definition at line 386 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 347 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 432 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 103 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 135 of file chan_sip.c. |
|
From RFC 3261 (former 2543) Definition at line 328 of file chan_sip.c. Referenced by build_peer(), check_via(), create_addr(), parse_ok_contact(), parse_register_contact(), reload_config(), set_destination(), sip_show_registry(), and temp_peer(). |
|
Definition at line 90 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 337 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 109 of file chan_sip.c. Referenced by handle_response_register(). |
|
Definition at line 111 of file chan_sip.c. Referenced by handle_response_register(). |
|
Definition at line 115 of file chan_sip.c. Referenced by handle_response_register(). |
|
Definition at line 108 of file chan_sip.c. Referenced by handle_response_register(). |
|
Definition at line 703 of file chan_sip.c. Referenced by __sip_reliable_xmit(), and retrans_pkt(). |
|
Definition at line 702 of file chan_sip.c. Referenced by __sip_ack(), __sip_pretend_ack(), __sip_semi_ack(), handle_request(), and retrans_pkt(). |
|
Definition at line 446 of file chan_sip.c. Referenced by handle_request_invite(), sip_call(), sip_hangup(), and update_call_counter(). |
|
Definition at line 95 of file chan_sip.c. |
|
Definition at line 124 of file chan_sip.c. |
|
Definition at line 138 of file chan_sip.c. Referenced by handle_response(), handle_response_invite(), and handle_response_register(). |
|
Definition at line 137 of file chan_sip.c. |
|
Definition at line 150 of file chan_sip.c. |
|
Definition at line 267 of file chan_sip.c. |
|
Definition at line 811 of file chan_sip.c. Referenced by registry_rerequest(), regstate2str(), and transmit_register(). |
|
Definition at line 816 of file chan_sip.c. Referenced by regstate2str(), and sip_reg_timeout(). |
|
Definition at line 815 of file chan_sip.c. Referenced by registry_rerequest(), and regstate2str(). |
|
Definition at line 812 of file chan_sip.c. Referenced by handle_response_register(), iax2_ack_registry(), and regstate2str(). |
|
Definition at line 810 of file chan_sip.c. Referenced by iax2_do_register(), regstate2str(), and transmit_register(). |
|
Definition at line 813 of file chan_sip.c. Referenced by regstate2str(), and socket_read(). |
|
Definition at line 814 of file chan_sip.c. Referenced by attempt_transmit(), and regstate2str(). |
|
Definition at line 809 of file chan_sip.c. Referenced by regstate2str(), and sip_reg_timeout(). |
|
Definition at line 149 of file chan_sip.c. |
|
Whether or not we've already been destroyed by our peer Definition at line 518 of file chan_sip.c. Referenced by handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), retrans_pkt(), sip_hangup(), sip_indicate(), and sip_sipredirect(). |
|
Definition at line 566 of file chan_sip.c. Referenced by check_user_full(), create_addr_from_peer(), and update_call_counter(). |
|
Definition at line 565 of file chan_sip.c. Referenced by __sip_show_channels(), and process_sdp(). |
|
Can we send BYE for this dialog? Definition at line 533 of file chan_sip.c. Referenced by check_pendings(), handle_response_invite(), and sip_hangup(). |
|
allow peers to be reinvited to send media directly p2p Definition at line 548 of file chan_sip.c. Referenced by _sip_show_peer(), handle_common_options(), reload_config(), sip_get_rtp_peer(), and sip_get_vrtp_peer(). |
|
Definition at line 417 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 418 of file chan_sip.c. Referenced by sip_do_debug(), sip_do_debug_ip(), sip_do_debug_peer(), and sip_no_debug(). |
|
three settings, uses two bits Definition at line 535 of file chan_sip.c. Referenced by _sip_show_peer(), check_user_full(), create_addr_from_peer(), handle_common_options(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit(), sip_show_channel(), and sip_show_settings(). |
|
AUTO switch between rfc2833 and in-band DTMF Definition at line 539 of file chan_sip.c. Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), and sip_alloc(). |
|
Inband audio, only for ULAW/ALAW Definition at line 537 of file chan_sip.c. Referenced by dtmfmode2str(), handle_common_options(), process_sdp(), sip_dtmfmode(), sip_new(), sip_rtp_read(), and sip_senddigit(). |
|
SIP Info messages Definition at line 538 of file chan_sip.c. Referenced by dtmfmode2str(), handle_common_options(), sip_dtmfmode(), and sip_senddigit(). |
|
RTP DTMF Definition at line 536 of file chan_sip.c. Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), reload_config(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), and sip_senddigit(). |
|
Value: (SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \ SIP_PROG_INBAND | SIP_OSPAUTH | SIP_USECLIENTCODE | SIP_NAT | \ SIP_USEREQPHONE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE) Definition at line 572 of file chan_sip.c. Referenced by build_peer(), build_user(), check_user_full(), create_addr_from_peer(), sip_alloc(), sip_poke_peer(), and temp_peer(). |
|
Got a refer? Definition at line 525 of file chan_sip.c. Referenced by handle_request_refer(), and sip_set_rtp_peer(). |
|
Definition at line 570 of file chan_sip.c. Referenced by update_call_counter(). |
|
don't require authentication for incoming INVITEs Definition at line 552 of file chan_sip.c. Referenced by _sip_show_peer(), check_user_full(), and handle_common_options(). |
|
don't require matching port for incoming requests Definition at line 551 of file chan_sip.c. Referenced by _sip_show_peer(), handle_common_options(), and sip_addrcmp(). |
|
Definition at line 118 of file chan_sip.c. Referenced by parse_ok_contact(), and respprep(). |
|
Max amount of SIP headers to read Definition at line 442 of file chan_sip.c. Referenced by add_blank_header(), add_header(), and parse_request(). |
|
Max amount of lines in SIP attachment (like SDP) Definition at line 443 of file chan_sip.c. Referenced by add_line(), and parse_request(). |
|
Also from RFC 3261 (2543), should sub headers tho Definition at line 329 of file chan_sip.c. |
|
four settings, uses two bits Definition at line 541 of file chan_sip.c. Referenced by __sip_xmit(), _sip_show_peer(), build_via(), check_user_full(), check_via(), copy_via_headers(), create_addr_from_peer(), handle_common_options(), parse_ok_contact(), parse_register_contact(), register_verify(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_debug_test_pvt(), sip_show_channel(), sip_show_settings(), and sip_show_users(). |
|
Definition at line 545 of file chan_sip.c. Referenced by copy_via_headers(), handle_common_options(), and nat2str(). |
|
No nat support Definition at line 542 of file chan_sip.c. Referenced by handle_common_options(), and nat2str(). |
|
Definition at line 543 of file chan_sip.c. Referenced by build_via(), handle_common_options(), nat2str(), and reload_config(). |
|
Definition at line 544 of file chan_sip.c. Referenced by __sip_xmit(), check_user_full(), check_via(), create_addr_from_peer(), nat2str(), parse_ok_contact(), parse_register_contact(), retrans_pkt(), send_request(), send_response(), sip_alloc(), and sip_debug_test_pvt(). |
|
if we need to be destroyed Definition at line 519 of file chan_sip.c. Referenced by __sip_show_channels(), check_pendings(), do_monitor(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_peerpoke(), handle_response_register(), receive_message(), retrans_pkt(), sip_hangup(), sip_reg_timeout(), and sip_show_channel(). |
|
Do we need to send another reinvite? Definition at line 523 of file chan_sip.c. Referenced by check_pendings(), sip_hangup(), and sip_set_rtp_peer(). |
|
Didn't get video in invite, don't offer Definition at line 520 of file chan_sip.c. Referenced by add_sdp(), process_sdp(), and sip_indicate(). |
|
Definition at line 270 of file chan_sip.c. |
|
Definition at line 272 of file chan_sip.c. |
|
Definition at line 280 of file chan_sip.c. |
|
Definition at line 281 of file chan_sip.c. |
|
Definition at line 273 of file chan_sip.c. |
|
Definition at line 274 of file chan_sip.c. |
|
Definition at line 276 of file chan_sip.c. |
|
Definition at line 275 of file chan_sip.c. |
|
Definition at line 277 of file chan_sip.c. |
|
Definition at line 269 of file chan_sip.c. |
|
Definition at line 278 of file chan_sip.c. |
|
Definition at line 279 of file chan_sip.c. |
|
Definition at line 282 of file chan_sip.c. |
|
Definition at line 271 of file chan_sip.c. |
|
four settings, uses two bits Definition at line 559 of file chan_sip.c. Referenced by check_auth(), check_user_full(), and handle_common_options(). |
|
Definition at line 563 of file chan_sip.c. Referenced by check_auth(), and handle_common_options(). |
|
Definition at line 561 of file chan_sip.c. Referenced by check_auth(), and handle_common_options(). |
|
Definition at line 560 of file chan_sip.c. Referenced by check_auth(). |
|
Definition at line 562 of file chan_sip.c. Referenced by check_auth(), and handle_common_options(). |
|
Is this an outgoing call? Definition at line 531 of file chan_sip.c. Referenced by handle_request_bye(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), reqprep(), respprep(), sip_call(), sip_hangup(), sip_indicate(), sip_poke_peer(), sip_send_mwi_to_peer(), sip_show_channel(), sip_write(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), and update_call_counter(). |
|
Is this a dynamic peer? Definition at line 583 of file chan_sip.c. Referenced by _sip_show_peer(), build_peer(), function_sippeer(), register_verify(), and temp_peer(). |
|
Definition at line 581 of file chan_sip.c. Referenced by build_peer(), destroy_association(), reload_config(), and sip_show_settings(). |
|
Definition at line 582 of file chan_sip.c. Referenced by build_peer(), destroy_association(), parse_register_contact(), and reg_source_db(). |
|
Definition at line 580 of file chan_sip.c. Referenced by expire_register(), realtime_peer(), and reload_config(). |
|
Definition at line 578 of file chan_sip.c. Referenced by complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), realtime_peer(), realtime_user(), reload_config(), sip_prune_realtime(), sip_show_settings(), and update_peer(). |
|
Definition at line 579 of file chan_sip.c. Referenced by reload_config(), sip_show_settings(), and update_peer(). |
|
Need to send bye after we ack? Definition at line 524 of file chan_sip.c. Referenced by check_pendings(), handle_response_invite(), sip_hangup(), and sip_set_rtp_peer(). |
|
Debug this packet Definition at line 586 of file chan_sip.c. Referenced by sipsock_read(). |
|
This packet has a to-tag Definition at line 587 of file chan_sip.c. Referenced by find_call(), and handle_request(). |
|
three settings, uses two bits Definition at line 554 of file chan_sip.c. Referenced by handle_common_options(), sip_indicate(), and sip_show_settings(). |
|
Definition at line 555 of file chan_sip.c. Referenced by sip_indicate(), and sip_show_settings(). |
|
Definition at line 556 of file chan_sip.c. Referenced by handle_common_options(), and sip_show_settings(). |
|
Definition at line 557 of file chan_sip.c. Referenced by handle_common_options(), and sip_indicate(). |
|
Have sent 183 message progress Definition at line 522 of file chan_sip.c. Referenced by sip_indicate(), and sip_write(). |
|
Promiscuous redirection Definition at line 526 of file chan_sip.c. Referenced by _sip_show_peer(), handle_common_options(), parse_moved_contact(), sip_show_channel(), and sip_show_settings(). |
|
Flag for realtime users Definition at line 529 of file chan_sip.c. Referenced by build_peer(), parse_register_contact(), realtime_peer(), realtime_user(), sip_destroy_peer(), sip_destroy_user(), and update_peer(). |
|
two bits used Definition at line 547 of file chan_sip.c. Referenced by handle_common_options(). |
|
use UPDATE (RFC3311) when reinviting this peer Definition at line 549 of file chan_sip.c. Referenced by handle_common_options(), and transmit_reinvite_with_sdp(). |
|
Have sent 180 ringing Definition at line 521 of file chan_sip.c. Referenced by sip_indicate(). |
|
This is an autocreated peer Definition at line 532 of file chan_sip.c. Referenced by expire_register(), sip_destroy_peer(), and temp_peer(). |
|
Definition at line 568 of file chan_sip.c. Referenced by _sip_show_peer(), handle_common_options(), and initreqprep(). |
|
Trust RPID headers? Definition at line 527 of file chan_sip.c. Referenced by _sip_show_peer(), check_user_full(), and handle_common_options(). |
|
Trust X-ClientCode info message Definition at line 530 of file chan_sip.c. Referenced by handle_common_options(), handle_request_info(), and sip_show_settings(). |
|
Add user=phone to numeric URI. Default off Definition at line 528 of file chan_sip.c. Referenced by _sip_show_peer(), build_peer(), initreqprep(), reload_config(), and sip_show_settings(). |
|
Definition at line 100 of file chan_sip.c. |
|
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 266 of file chan_sip.c. |
|
SIP Extensions we support.
Definition at line 326 of file chan_sip.c. |
|
Definition at line 93 of file chan_sip.c. Referenced by add_sdp(). |
|
Definition at line 487 of file chan_sip.c. 00487 { 00488 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00489 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00490 };
|
|
Definition at line 5882 of file chan_sip.c. 05882 { 05883 PARSE_REGISTER_FAILED, 05884 PARSE_REGISTER_UPDATE, 05885 PARSE_REGISTER_QUERY, 05886 };
|
|
Definition at line 202 of file chan_sip.c. 00202 { 00203 PROXY_AUTH, 00204 WWW_AUTH, 00205 };
|
|
Definition at line 183 of file chan_sip.c. 00183 { 00184 SIP_UNKNOWN, 00185 SIP_RESPONSE, 00186 SIP_REGISTER, 00187 SIP_OPTIONS, 00188 SIP_NOTIFY, 00189 SIP_INVITE, 00190 SIP_ACK, 00191 SIP_PRACK, 00192 SIP_BYE, 00193 SIP_REFER, 00194 SIP_SUBSCRIBE, 00195 SIP_MESSAGE, 00196 SIP_UPDATE, 00197 SIP_INFO, 00198 SIP_CANCEL, 00199 SIP_PUBLISH, 00200 } sip_method_list;
|
|
Definition at line 160 of file chan_sip.c. 00160 { 00161 NONE = 0, 00162 TIMEOUT, 00163 XPIDF_XML, 00164 DIALOG_INFO_XML, 00165 CPIM_PIDF_XML, 00166 PIDF_XML 00167 };
|
|
Definition at line 2924 of file chan_sip.c. References find_alias(), pass, and pedanticsipchecking. 02925 { 02926 int pass; 02927 02928 /* 02929 * Technically you can place arbitrary whitespace both before and after the ':' in 02930 * a header, although RFC3261 clearly says you shouldn't before, and place just 02931 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 02932 * a good idea to say you can do it, and if you can do it, why in the hell would. 02933 * you say you shouldn't. 02934 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 02935 * and we always allow spaces after that for compatibility. 02936 */ 02937 for (pass = 0; name && pass < 2;pass++) { 02938 int x, len = strlen(name); 02939 for (x=*start; x<req->headers; x++) { 02940 if (!strncasecmp(req->header[x], name, len)) { 02941 char *r = req->header[x] + len; /* skip name */ 02942 if (pedanticsipchecking) 02943 r = ast_skip_blanks(r); 02944 02945 if (*r == ':') { 02946 *start = x+1; 02947 return ast_skip_blanks(r+1); 02948 } 02949 } 02950 } 02951 if (pass == 0) /* Try aliases */ 02952 name = find_alias(name, NULL); 02953 } 02954 02955 /* Don't return NULL, so get_header is always a valid pointer */ 02956 return ""; 02957 }
|
|
__sip_ack: Acknowledges receipt of a packet and stops retransmission ---
Definition at line 1362 of file chan_sip.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_test_flag, sip_pvt::callid, sip_pkt::data, FLAG_RESPONSE, free, sip_pvt::lock, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::retransid, sip_pkt::seqno, sip_methods, sipdebug, and cfsip_methods::text. Referenced by __sip_pretend_ack(), handle_request(), and handle_response(). 01363 { 01364 struct sip_pkt *cur, *prev = NULL; 01365 int res = -1; 01366 int resetinvite = 0; 01367 /* Just in case... */ 01368 char *msg; 01369 01370 msg = sip_methods[sipmethod].text; 01371 01372 ast_mutex_lock(&p->lock); 01373 cur = p->packets; 01374 while(cur) { 01375 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 01376 ((ast_test_flag(cur, FLAG_RESPONSE)) || 01377 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 01378 if (!resp && (seqno == p->pendinginvite)) { 01379 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 01380 p->pendinginvite = 0; 01381 resetinvite = 1; 01382 } 01383 /* this is our baby */ 01384 if (prev) 01385 prev->next = cur->next; 01386 else 01387 p->packets = cur->next; 01388 if (cur->retransid > -1) { 01389 if (sipdebug && option_debug > 3) 01390 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 01391 ast_sched_del(sched, cur->retransid); 01392 } 01393 free(cur); 01394 res = 0; 01395 break; 01396 } 01397 prev = cur; 01398 cur = cur->next; 01399 } 01400 ast_mutex_unlock(&p->lock); 01401 ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found"); 01402 return res; 01403 }
|
|
__sip_autodestruct: Kill a call (called by scheduler) ---
Definition at line 1306 of file chan_sip.c. References append_history(), AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup(), sip_pvt::autokillid, sip_pvt::callid, LOG_DEBUG, LOG_WARNING, NONE, sip_pvt::owner, sip_destroy(), sip_pvt::subscribed, TIMEOUT, and transmit_state_notify(). Referenced by sip_scheddestroy(). 01307 { 01308 struct sip_pvt *p = data; 01309 01310 01311 /* If this is a subscription, tell the phone that we got a timeout */ 01312 if (p->subscribed) { 01313 p->subscribed = TIMEOUT; 01314 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, 1); /* Send first notification */ 01315 p->subscribed = NONE; 01316 append_history(p, "Subscribestatus", "timeout"); 01317 return 10000; /* Reschedule this destruction so that we know that it's gone */ 01318 } 01319 01320 /* This scheduled event is now considered done. */ 01321 p->autokillid = -1; 01322 01323 ast_log(LOG_DEBUG, "Auto destroying call '%s'\n", p->callid); 01324 append_history(p, "AutoDestroy", ""); 01325 if (p->owner) { 01326 ast_log(LOG_WARNING, "Autodestruct on call '%s' with owner in place\n", p->callid); 01327 ast_queue_hangup(p->owner); 01328 } else { 01329 sip_destroy(p); 01330 } 01331 return 0; 01332 }
|
|
__sip_destroy: Execute destrucion of call structure, release memory---
Definition at line 2103 of file chan_sip.c. References ast_extension_state_del(), ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_destroy(), ast_sched_del(), ast_variables_destroy(), ast_verbose(), ASTOBJ_UNREF, sip_pvt::callid, dumphistory, free, free_old_route(), iflist, LOG_DEBUG, LOG_WARNING, sip_pvt::next, sip_history::next, sip_pkt::retransid, sip_debug_test_pvt(), sip_dump_history(), and sip_registry_destroy(). Referenced by do_monitor(), and sip_destroy(). 02104 { 02105 struct sip_pvt *cur, *prev = NULL; 02106 struct sip_pkt *cp; 02107 struct sip_history *hist; 02108 02109 if (sip_debug_test_pvt(p)) 02110 ast_verbose("Destroying call '%s'\n", p->callid); 02111 02112 if (dumphistory) 02113 sip_dump_history(p); 02114 02115 if (p->options) 02116 free(p->options); 02117 02118 if (p->stateid > -1) 02119 ast_extension_state_del(p->stateid, NULL); 02120 if (p->initid > -1) 02121 ast_sched_del(sched, p->initid); 02122 if (p->autokillid > -1) 02123 ast_sched_del(sched, p->autokillid); 02124 02125 if (p->rtp) { 02126 ast_rtp_destroy(p->rtp); 02127 } 02128 if (p->vrtp) { 02129 ast_rtp_destroy(p->vrtp); 02130 } 02131 if (p->route) { 02132 free_old_route(p->route); 02133 p->route = NULL; 02134 } 02135 if (p->registry) { 02136 if (p->registry->call == p) 02137 p->registry->call = NULL; 02138 ASTOBJ_UNREF(p->registry,sip_registry_destroy); 02139 } 02140 02141 if (p->rpid) 02142 free(p->rpid); 02143 02144 if (p->rpid_from) 02145 free(p->rpid_from); 02146 02147 /* Unlink us from the owner if we have one */ 02148 if (p->owner) { 02149 if (lockowner) 02150 ast_mutex_lock(&p->owner->lock); 02151 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 02152 p->owner->tech_pvt = NULL; 02153 if (lockowner) 02154 ast_mutex_unlock(&p->owner->lock); 02155 } 02156 /* Clear history */ 02157 while(p->history) { 02158 hist = p->history; 02159 p->history = p->history->next; 02160 free(hist); 02161 } 02162 02163 cur = iflist; 02164 while(cur) { 02165 if (cur == p) { 02166 if (prev) 02167 prev->next = cur->next; 02168 else 02169 iflist = cur->next; 02170 break; 02171 } 02172 prev = cur; 02173 cur = cur->next; 02174 } 02175 if (!cur) { 02176 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 02177 return; 02178 } 02179 while((cp = p->packets)) { 02180 p->packets = p->packets->next; 02181 if (cp->retransid > -1) { 02182 ast_sched_del(sched, cp->retransid); 02183 } 02184 free(cp); 02185 } 02186 if (p->chanvars) { 02187 ast_variables_destroy(p->chanvars); 02188 p->chanvars = NULL; 02189 } 02190 ast_mutex_destroy(&p->lock); 02191 free(p); 02192 }
|
|
__sip_do_register: Register with SIP proxy ---
Definition at line 5345 of file chan_sip.c. References SIP_REGISTER, and transmit_register(). Referenced by sip_reregister(). 05346 { 05347 int res; 05348 05349 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 05350 return res; 05351 }
|
|
Definition at line 1406 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_pvt::packets, sip_pkt::seqno, and sip_methods. Referenced by sip_hangup(), and sip_reg_timeout(). 01407 { 01408 struct sip_pkt *cur=NULL; 01409 01410 while(p->packets) { 01411 if (cur == p->packets) { 01412 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 01413 return -1; 01414 } 01415 cur = p->packets; 01416 if (cur->method) 01417 __sip_ack(p, p->packets->seqno, (ast_test_flag(p->packets, FLAG_RESPONSE)), cur->method); 01418 else { /* Unknown packet type */ 01419 char *c; 01420 char method[128]; 01421 ast_copy_string(method, p->packets->data, sizeof(method)); 01422 c = ast_skip_blanks(method); /* XXX what ? */ 01423 *c = '\0'; 01424 __sip_ack(p, p->packets->seqno, (ast_test_flag(p->packets, FLAG_RESPONSE)), find_sip_method(method)); 01425 } 01426 } 01427 return 0; 01428 }
|
|
__sip_reliable_xmit: transmit packet with retransmits ---
Definition at line 1267 of file chan_sip.c. References __sip_xmit(), ast_log(), ast_sched_add_variable(), ast_set_flag, DEFAULT_RETRANS, FLAG_FATAL, sip_pvt::flags, LOG_DEBUG, malloc, option_debug, sip_pkt::owner, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), SIP_INVITE, sipdebug, and sip_pvt::timer_t1. Referenced by send_request(), and send_response(). 01268 { 01269 struct sip_pkt *pkt; 01270 int siptimer_a = DEFAULT_RETRANS; 01271 01272 pkt = malloc(sizeof(struct sip_pkt) + len + 1); 01273 if (!pkt) 01274 return -1; 01275 memset(pkt, 0, sizeof(struct sip_pkt)); 01276 memcpy(pkt->data, data, len); 01277 pkt->method = sipmethod; 01278 pkt->packetlen = len; 01279 pkt->next = p->packets; 01280 pkt->owner = p; 01281 pkt->seqno = seqno; 01282 pkt->flags = resp; 01283 pkt->data[len] = '\0'; 01284 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 01285 if (fatal) 01286 ast_set_flag(pkt, FLAG_FATAL); 01287 if (pkt->timer_t1) 01288 siptimer_a = pkt->timer_t1 * 2; 01289 01290 /* Schedule retransmission */ 01291 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 01292 if (option_debug > 3 && sipdebug) 01293 ast_log(LOG_DEBUG, "*** SIP TIMER: Initalizing retransmit timer on packet: Id #%d\n", pkt->retransid); 01294 pkt->next = p->packets; 01295 p->packets = pkt; 01296 01297 __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 01298 if (sipmethod == SIP_INVITE) { 01299 /* Note this is a pending invite */ 01300 p->pendinginvite = seqno; 01301 } 01302 return 0; 01303 }
|
|
__sip_semi_ack: Acks receipt of packet, keep it around (used for provisional responses) ---
Definition at line 1431 of file chan_sip.c. References ast_log(), ast_sched_del(), ast_test_flag, sip_pvt::callid, sip_pkt::data, FLAG_RESPONSE, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pkt::retransid, sip_pkt::seqno, sip_methods, sipdebug, and cfsip_methods::text. Referenced by handle_response(). 01432 { 01433 struct sip_pkt *cur; 01434 int res = -1; 01435 char *msg = sip_methods[sipmethod].text; 01436 01437 cur = p->packets; 01438 while(cur) { 01439 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 01440 ((ast_test_flag(cur, FLAG_RESPONSE)) || 01441 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 01442 /* this is our baby */ 01443 if (cur->retransid > -1) { 01444 if (option_debug > 3 && sipdebug) 01445 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, msg); 01446 ast_sched_del(sched, cur->retransid); 01447 } 01448 cur->retransid = -1; 01449 res = 0; 01450 break; 01451 } 01452 cur = cur->next; 01453 } 01454 ast_log(LOG_DEBUG, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found"); 01455 return res; 01456 }
|
|
Definition at line 8390 of file chan_sip.c. References ast_cli(), ast_extension_state2str(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::cid_num, sip_pvt::exten, FORMAT, FORMAT2, sip_pvt::icseq, iflist, sip_pvt::lastmsg, sip_pvt::laststate, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::sa, SIP_CALL_ONHOLD, SIP_NEEDDESTROY, sip_pvt::subscribed, subscription_type2str(), and sip_pvt::username. Referenced by sip_show_channels(), and sip_show_subscriptions(). 08391 { 08392 #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s\n" 08393 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n" 08394 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s\n" 08395 struct sip_pvt *cur; 08396 char iabuf[INET_ADDRSTRLEN]; 08397 int numchans = 0; 08398 if (argc != 3) 08399 return RESULT_SHOWUSAGE; 08400 ast_mutex_lock(&iflock); 08401 cur = iflist; 08402 if (!subscriptions) 08403 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 08404 else 08405 ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type"); 08406 while (cur) { 08407 if (cur->subscribed == NONE && !subscriptions) { 08408 ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), 08409 ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 08410 cur->callid, 08411 cur->ocseq, cur->icseq, 08412 ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 08413 ast_test_flag(cur, SIP_CALL_ONHOLD) ? "Yes" : "No", 08414 ast_test_flag(cur, SIP_NEEDDESTROY) ? "(d)" : "", 08415 cur->lastmsg ); 08416 numchans++; 08417 } 08418 if (cur->subscribed != NONE && subscriptions) { 08419 ast_cli(fd, FORMAT3, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), 08420 ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 08421 cur->callid, cur->exten, ast_extension_state2str(cur->laststate), 08422 subscription_type2str(cur->subscribed)); 08423 numchans++; 08424 } 08425 cur = cur->next; 08426 } 08427 ast_mutex_unlock(&iflock); 08428 if (!subscriptions) 08429 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 08430 else 08431 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 08432 return RESULT_SUCCESS; 08433 #undef FORMAT 08434 #undef FORMAT2 08435 #undef FORMAT3 08436 }
|
|
__sip_xmit: Transmit SIP message ---
Definition at line 1062 of file chan_sip.c. References ast_inet_ntoa(), ast_log(), ast_test_flag, LOG_WARNING, sip_pvt::recv, sip_pvt::sa, SIP_NAT, SIP_NAT_ROUTE, and sipsock. Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response(). 01063 { 01064 int res; 01065 char iabuf[INET_ADDRSTRLEN]; 01066 01067 if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) 01068 res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->recv, sizeof(struct sockaddr_in)); 01069 else 01070 res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_in)); 01071 01072 if (res != len) { 01073 ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), res, strerror(errno)); 01074 } 01075 return res; 01076 }
|
|
__transmit_response: Base transmit response function
Definition at line 4208 of file chan_sip.c. References add_blank_header(), add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), get_header(), ast_channel::hangupcause, LOG_WARNING, sip_pvt::owner, respprep(), and send_response(). Referenced by transmit_response(), and transmit_response_reliable(). 04209 { 04210 struct sip_request resp; 04211 int seqno = 0; 04212 04213 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 04214 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 04215 return -1; 04216 } 04217 respprep(&resp, p, msg, req); 04218 add_header_contentLength(&resp, 0); 04219 /* If we are cancelling an incoming invite for some reason, add information 04220 about the reason why we are doing this in clear text */ 04221 if (msg[0] != '1' && p->owner && p->owner->hangupcause) { 04222 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 04223 } 04224 add_blank_header(&resp); 04225 return send_response(p, &resp, reliable, seqno); 04226 }
|
|
Definition at line 7996 of file chan_sip.c. References sip_peer::accountcode, sip_peer::addr, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, 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, mansession::fd, find_peer(), sip_peer::flags_page2, 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_auth::md5secret, sip_peer::md5secret, ast_variable::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, RESULT_SHOWUSAGE, RESULT_SUCCESS, 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_DYNAMIC, SIP_PROMISCREDIR, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::subscribecontext, text, sip_peer::tohost, 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(). 07997 { 07998 char status[30] = ""; 07999 char cbuf[256]; 08000 char iabuf[INET_ADDRSTRLEN]; 08001 struct sip_peer *peer; 08002 char codec_buf[512]; 08003 struct ast_codec_pref *pref; 08004 struct ast_variable *v; 08005 struct sip_auth *auth; 08006 int x = 0, codec = 0, load_realtime = 0; 08007 08008 if (argc < 4) 08009 return RESULT_SHOWUSAGE; 08010 08011 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 08012 peer = find_peer(argv[3], NULL, load_realtime); 08013 if (s) { /* Manager */ 08014 if (peer) 08015 ast_cli(s->fd, "Response: Success\r\n"); 08016 else { 08017 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); 08018 astman_send_error(s, m, cbuf); 08019 return 0; 08020 } 08021 } 08022 if (peer && type==0 ) { /* Normal listing */ 08023 ast_cli(fd,"\n\n"); 08024 ast_cli(fd, " * Name : %s\n", peer->name); 08025 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 08026 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 08027 auth = peer->auth; 08028 while(auth) { 08029 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 08030 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 08031 auth = auth->next; 08032 } 08033 ast_cli(fd, " Context : %s\n", peer->context); 08034 ast_cli(fd, " Subscr.Cont. : %s\n", ast_strlen_zero(peer->subscribecontext)?"<Not set>":peer->subscribecontext); 08035 ast_cli(fd, " Language : %s\n", peer->language); 08036 if (!ast_strlen_zero(peer->accountcode)) 08037 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 08038 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 08039 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 08040 if (!ast_strlen_zero(peer->fromuser)) 08041 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 08042 if (!ast_strlen_zero(peer->fromdomain)) 08043 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 08044 ast_cli(fd, " Callgroup : "); 08045 print_group(fd, peer->callgroup, 0); 08046 ast_cli(fd, " Pickupgroup : "); 08047 print_group(fd, peer->pickupgroup, 0); 08048 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 08049 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 08050 ast_cli(fd, " LastMsgsSent : %d\n", peer->lastmsgssent); 08051 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 08052 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)?"Yes":"No")); 08053 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 08054 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 08055 ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE))); 08056 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(peer, SIP_NAT))); 08057 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 08058 ast_cli(fd, " CanReinvite : %s\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Yes":"No")); 08059 ast_cli(fd, " PromiscRedir : %s\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Yes":"No")); 08060 ast_cli(fd, " User=Phone : %s\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Yes":"No")); 08061 ast_cli(fd, " Trust RPID : %s\n", (ast_test_flag(peer, SIP_TRUSTRPID) ? "Yes" : "No")); 08062 ast_cli(fd, " Send RPID : %s\n", (ast_test_flag(peer, SIP_SENDRPID) ? "Yes" : "No")); 08063 08064 /* - is enumerated */ 08065 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF))); 08066 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 08067 ast_cli(fd, " ToHost : %s\n", peer->tohost); 08068 ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port)); 08069 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 08070 ast_cli(fd, " Def. Username: %s\n", peer->username); 08071 ast_cli(fd, " SIP Options : "); 08072 if (peer->sipoptions) { 08073 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 08074 if (peer->sipoptions & sip_options[x].id) 08075 ast_cli(fd, "%s ", sip_options[x].text); 08076 } 08077 } else 08078 ast_cli(fd, "(none)"); 08079 08080 ast_cli(fd, "\n"); 08081 ast_cli(fd, " Codecs : "); 08082 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 08083 ast_cli(fd, "%s\n", codec_buf); 08084 ast_cli(fd, " Codec Order : ("); 08085 print_codec_to_cli(fd, &peer->prefs); 08086 08087 ast_cli(fd, ")\n"); 08088 08089 ast_cli(fd, " Status : "); 08090 peer_status(peer, status, sizeof(status)); 08091 ast_cli(fd, "%s\n",status); 08092 ast_cli(fd, " Useragent : %s\n", peer->useragent); 08093 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 08094 if (peer->chanvars) { 08095 ast_cli(fd, " Variables :\n"); 08096 for (v = peer->chanvars ; v ; v = v->next) 08097 ast_cli(fd, " %s = %s\n", v->name, v->value); 08098 } 08099 ast_cli(fd,"\n"); 08100 ASTOBJ_UNREF(peer,sip_destroy_peer); 08101 } else if (peer && type == 1) { /* manager listing */ 08102 ast_cli(fd, "Channeltype: SIP\r\n"); 08103 ast_cli(fd, "ObjectName: %s\r\n", peer->name); 08104 ast_cli(fd, "ChanObjectType: peer\r\n"); 08105 ast_cli(fd, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 08106 ast_cli(fd, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 08107 ast_cli(fd, "Context: %s\r\n", peer->context); 08108 ast_cli(fd, "Language: %s\r\n", peer->language); 08109 if (!ast_strlen_zero(peer->accountcode)) 08110 ast_cli(fd, "Accountcode: %s\r\n", peer->accountcode); 08111 ast_cli(fd, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 08112 ast_cli(fd, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 08113 if (!ast_strlen_zero(peer->fromuser)) 08114 ast_cli(fd, "SIP-FromUser: %s\r\n", peer->fromuser); 08115 if (!ast_strlen_zero(peer->fromdomain)) 08116 ast_cli(fd, "SIP-FromDomain: %s\r\n", peer->fromdomain); 08117 ast_cli(fd, "Callgroup: "); 08118 print_group(fd, peer->callgroup, 1); 08119 ast_cli(fd, "Pickupgroup: "); 08120 print_group(fd, peer->pickupgroup, 1); 08121 ast_cli(fd, "VoiceMailbox: %s\r\n", peer->mailbox); 08122 ast_cli(fd, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 08123 ast_cli(fd, "Call limit: %d\r\n", peer->call_limit); 08124 ast_cli(fd, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)?"Y":"N")); 08125 ast_cli(fd, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 08126 ast_cli(fd, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 08127 ast_cli(fd, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE))); 08128 ast_cli(fd, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(peer, SIP_NAT))); 08129 ast_cli(fd, "ACL: %s\r\n", (peer->ha?"Y":"N")); 08130 ast_cli(fd, "SIP-CanReinvite: %s\r\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Y":"N")); 08131 ast_cli(fd, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Y":"N")); 08132 ast_cli(fd, "SIP-UserPhone: %s\r\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Y":"N")); 08133 08134 /* - is enumerated */ 08135 ast_cli(fd, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF))); 08136 ast_cli(fd, "SIPLastMsg: %d\r\n", peer->lastmsg); 08137 ast_cli(fd, "ToHost: %s\r\n", peer->tohost); 08138 ast_cli(fd, "Address-IP: %s\r\nAddress-Port: %d\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", ntohs(peer->addr.sin_port)); 08139 ast_cli(fd, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 08140 ast_cli(fd, "Default-Username: %s\r\n", peer->username); 08141 ast_cli(fd, "Codecs: "); 08142 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 08143 ast_cli(fd, "%s\r\n", codec_buf); 08144 ast_cli(fd, "CodecOrder: "); 08145 pref = &peer->prefs; 08146 for(x = 0; x < 32 ; x++) { 08147 codec = ast_codec_pref_index(pref,x); 08148 if (!codec) 08149 break; 08150 ast_cli(fd, "%s", ast_getformatname(codec)); 08151 if (x < 31 && ast_codec_pref_index(pref,x+1)) 08152 ast_cli(fd, ","); 08153 } 08154 08155 ast_cli(fd, "\r\n"); 08156 ast_cli(fd, "Status: "); 08157 peer_status(peer, status, sizeof(status)); 08158 ast_cli(fd, "%s\r\n", status); 08159 ast_cli(fd, "SIP-Useragent: %s\r\n", peer->useragent); 08160 ast_cli(fd, "Reg-Contact : %s\r\n", peer->fullcontact); 08161 if (peer->chanvars) { 08162 for (v = peer->chanvars ; v ; v = v->next) { 08163 ast_cli(fd, "ChanVariable:\n"); 08164 ast_cli(fd, " %s,%s\r\n", v->name, v->value); 08165 } 08166 } 08167 08168 ASTOBJ_UNREF(peer,sip_destroy_peer); 08169 08170 } else { 08171 ast_cli(fd,"Peer %s not found.\n", argv[3]); 08172 ast_cli(fd,"\n"); 08173 } 08174 08175 return RESULT_SUCCESS; 08176 }
|
|
_sip_show_peers: Execute sip show peers command
Definition at line 7574 of file chan_sip.c. References ast_cli(), ast_strlen_zero(), astman_get_header(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT2, id, name, peer_status(), peerl, and RESULT_SHOWUSAGE. Referenced by manager_sip_show_peers(), and sip_show_peers(). 07575 { 07576 regex_t regexbuf; 07577 int havepattern = 0; 07578 07579 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s\n" 07580 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s\n" 07581 07582 char name[256]; 07583 char iabuf[INET_ADDRSTRLEN]; 07584 int total_peers = 0; 07585 int peers_online = 0; 07586 int peers_offline = 0; 07587 char *id; 07588 char idtext[256] = ""; 07589 07590 if (s) { /* Manager - get ActionID */ 07591 id = astman_get_header(m,"ActionID"); 07592 if (!ast_strlen_zero(id)) 07593 snprintf(idtext,256,"ActionID: %s\r\n",id); 07594 } 07595 07596 switch (argc) { 07597 case 5: 07598 if (!strcasecmp(argv[3], "like")) { 07599 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 07600 return RESULT_SHOWUSAGE; 07601 havepattern = 1; 07602 } else 07603 return RESULT_SHOWUSAGE; 07604 case 3: 07605 break; 07606 default: 07607 return RESULT_SHOWUSAGE; 07608 } 07609 07610 if (!s) { /* Normal list */ 07611 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status"); 07612 } 07613 07614 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07615 char status[20] = ""; 07616 char srch[2000]; 07617 char pstatus; 07618 07619 ASTOBJ_RDLOCK(iterator); 07620 07621 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07622 ASTOBJ_UNLOCK(iterator); 07623 continue; 07624 } 07625 07626 if (!ast_strlen_zero(iterator->username) && !s) 07627 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 07628 else 07629 ast_copy_string(name, iterator->name, sizeof(name)); 07630 07631 pstatus = peer_status(iterator, status, sizeof(status)); 07632 if (pstatus) 07633 peers_online++; 07634 else { 07635 if (pstatus == 0) 07636 peers_offline++; 07637 else { /* Unmonitored */ 07638 /* Checking if port is 0 */ 07639 if ( ntohs(iterator->addr.sin_port) == 0 ) { 07640 peers_offline++; 07641 } else { 07642 peers_online++; 07643 } 07644 } 07645 } 07646 07647 snprintf(srch, sizeof(srch), FORMAT, name, 07648 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", 07649 ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 07650 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 07651 iterator->ha ? " A " : " ", /* permit/deny */ 07652 ntohs(iterator->addr.sin_port), status); 07653 07654 if (!s) {/* Normal CLI list */ 07655 ast_cli(fd, FORMAT, name, 07656 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", 07657 ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 07658 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 07659 iterator->ha ? " A " : " ", /* permit/deny */ 07660 07661 ntohs(iterator->addr.sin_port), status); 07662 } else { /* Manager format */ 07663 /* The names here need to be the same as other channels */ 07664 ast_cli(fd, 07665 "Event: PeerEntry\r\n%s" 07666 "Channeltype: SIP\r\n" 07667 "ObjectName: %s\r\n" 07668 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 07669 "IPaddress: %s\r\n" 07670 "IPport: %d\r\n" 07671 "Dynamic: %s\r\n" 07672 "Natsupport: %s\r\n" 07673 "ACL: %s\r\n" 07674 "Status: %s\r\n\r\n", 07675 idtext, 07676 iterator->name, 07677 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "-none-", 07678 ntohs(iterator->addr.sin_port), 07679 ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 07680 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 07681 iterator->ha ? "yes" : "no", /* permit/deny */ 07682 status); 07683 } 07684 07685 ASTOBJ_UNLOCK(iterator); 07686 07687 total_peers++; 07688 } while(0) ); 07689 07690 if (!s) { 07691 ast_cli(fd,"%d sip peers [%d online , %d offline]\n",total_peers,peers_online,peers_offline); 07692 } 07693 07694 if (havepattern) 07695 regfree(®exbuf); 07696 07697 if (total) 07698 *total = total_peers; 07699 07700 07701 return RESULT_SUCCESS; 07702 #undef FORMAT 07703 #undef FORMAT2 07704 }
|
|
add_blank_header: Add blank header to SIP message
Definition at line 3797 of file chan_sip.c. References ast_log(), sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, LOG_WARNING, and SIP_MAX_HEADERS. Referenced by __transmit_response(), sip_notify(), transmit_invite(), transmit_refer(), transmit_register(), transmit_request(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), and transmit_response_with_date(). 03798 { 03799 if (req->headers == SIP_MAX_HEADERS) { 03800 ast_log(LOG_WARNING, "Out of SIP header space\n"); 03801 return -1; 03802 } 03803 if (req->lines) { 03804 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 03805 return -1; 03806 } 03807 if (req->len >= sizeof(req->data) - 4) { 03808 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 03809 return -1; 03810 } 03811 req->header[req->headers] = req->data + req->len; 03812 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "\r\n"); 03813 req->len += strlen(req->header[req->headers]); 03814 req->headers++; 03815 return 0; 03816 }
|
|
Definition at line 4349 of file chan_sip.c. References ast_build_string(), AST_FORMAT_G729A, ast_getformatname(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), ast_verbose(), and sip_pvt::rtp. Referenced by add_sdp(). 04352 { 04353 int rtp_code; 04354 04355 if (debug) 04356 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 04357 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 04358 return; 04359 04360 ast_build_string(m_buf, m_size, " %d", rtp_code); 04361 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 04362 ast_rtp_lookup_mime_subtype(1, codec), 04363 sample_rate); 04364 if (codec == AST_FORMAT_G729A) 04365 /* Indicate that we don't support VAD (G.729 annex B) */ 04366 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 04367 }
|
|
add_digit: add DTMF INFO tone to sip message ---
Definition at line 4318 of file chan_sip.c. References add_header(), add_header_contentLength(), and add_line(). Referenced by transmit_info_with_digit(). 04319 { 04320 char tmp[256]; 04321 04322 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=250\r\n", digit); 04323 add_header(req, "Content-Type", "application/dtmf-relay"); 04324 add_header_contentLength(req, strlen(tmp)); 04325 add_line(req, tmp); 04326 return 0; 04327 }
|
|
add_header: Add header to SIP message
Definition at line 3753 of file chan_sip.c. References aliases, ast_log(), compactheaders, sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, LOG_WARNING, and SIP_MAX_HEADERS. 03754 { 03755 int x = 0; 03756 03757 if (req->headers == SIP_MAX_HEADERS) { 03758 ast_log(LOG_WARNING, "Out of SIP header space\n"); 03759 return -1; 03760 } 03761 03762 if (req->lines) { 03763 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 03764 return -1; 03765 } 03766 03767 if (req->len >= sizeof(req->data) - 4) { 03768 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 03769 return -1; 03770 } 03771 03772 req->header[req->headers] = req->data + req->len; 03773 03774 if (compactheaders) { 03775 for (x = 0; x < (sizeof(aliases) / sizeof(aliases[0])); x++) 03776 if (!strcasecmp(aliases[x].fullname, var)) 03777 var = aliases[x].shortname; 03778 } 03779 03780 snprintf(req->header[req->headers], sizeof(req->data) - req->len - 4, "%s: %s\r\n", var, value); 03781 req->len += strlen(req->header[req->headers]); 03782 req->headers++; 03783 03784 return 0; 03785 }
|
|
add_header_contentLen: Add 'Content-Length' header to SIP message
Definition at line 3788 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(), and transmit_state_notify(). 03789 { 03790 char clen[10]; 03791 03792 snprintf(clen, sizeof(clen), "%d", len); 03793 return add_header(req, "Content-Length", clen); 03794 }
|
|
add_line: Add content (not header) to SIP message
Definition at line 3819 of file chan_sip.c. References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, LOG_WARNING, and SIP_MAX_LINES. 03820 { 03821 if (req->lines == SIP_MAX_LINES) { 03822 ast_log(LOG_WARNING, "Out of SIP line space\n"); 03823 return -1; 03824 } 03825 if (!req->lines) { 03826 /* Add extra empty return */ 03827 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 03828 req->len += strlen(req->data + req->len); 03829 } 03830 if (req->len >= sizeof(req->data) - 4) { 03831 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 03832 return -1; 03833 } 03834 req->line[req->lines] = req->data + req->len; 03835 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 03836 req->len += strlen(req->line[req->lines]); 03837 req->lines++; 03838 return 0; 03839 }
|
|
Definition at line 4369 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(). 04372 { 04373 int rtp_code; 04374 04375 if (debug) 04376 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format)); 04377 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 04378 return; 04379 04380 ast_build_string(m_buf, m_size, " %d", rtp_code); 04381 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 04382 ast_rtp_lookup_mime_subtype(0, format), 04383 sample_rate); 04384 if (format == AST_RTP_DTMF) 04385 /* Indicate we support DTMF and FLASH... */ 04386 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 04387 }
|
|
add_realm_authentication: Add realm authentication in list ---
Definition at line 11967 of file chan_sip.c. References ast_log(), ast_strlen_zero(), ast_verbose(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, sip_auth::md5secret, sip_auth::next, option_verbose, sip_auth::realm, secret, strsep(), and username. Referenced by build_peer(), and reload_config(). 11968 { 11969 char authcopy[256]; 11970 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 11971 char *stringp; 11972 struct sip_auth *auth; 11973 struct sip_auth *b = NULL, *a = authlist; 11974 11975 if (ast_strlen_zero(configuration)) 11976 return authlist; 11977 11978 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 11979 11980 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 11981 stringp = authcopy; 11982 11983 username = stringp; 11984 realm = strrchr(stringp, '@'); 11985 if (realm) { 11986 *realm = '\0'; 11987 realm++; 11988 } 11989 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 11990 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 11991 return authlist; 11992 } 11993 stringp = username; 11994 username = strsep(&stringp, ":"); 11995 if (username) { 11996 secret = strsep(&stringp, ":"); 11997 if (!secret) { 11998 stringp = username; 11999 md5secret = strsep(&stringp,"#"); 12000 } 12001 } 12002 auth = malloc(sizeof(struct sip_auth)); 12003 if (auth) { 12004 memset(auth, 0, sizeof(struct sip_auth)); 12005 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 12006 ast_copy_string(auth->username, username, sizeof(auth->username)); 12007 if (secret) 12008 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 12009 if (md5secret) 12010 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 12011 } else { 12012 ast_log(LOG_ERROR, "Allocation of auth structure failed, Out of memory\n"); 12013 return authlist; 12014 } 12015 12016 /* Add authentication to authl */ 12017 if (!authlist) { /* No existing list */ 12018 return auth; 12019 } 12020 while(a) { 12021 b = a; 12022 a = a->next; 12023 } 12024 b->next = auth; /* Add structure add end of list */ 12025 12026 if (option_verbose > 2) 12027 ast_verbose("Added authentication for realm %s\n", realm); 12028 12029 return authlist; 12030 12031 }
|
|
add_route: Add route header into request per learned route ---
Definition at line 3937 of file chan_sip.c. References add_header(), and n. Referenced by reqprep(). 03938 { 03939 char r[BUFSIZ*2], *p; 03940 int n, rem = sizeof(r); 03941 03942 if (!route) return; 03943 03944 p = r; 03945 while (route) { 03946 n = strlen(route->hop); 03947 if ((n+3)>rem) break; 03948 if (p != r) { 03949 *p++ = ','; 03950 --rem; 03951 } 03952 *p++ = '<'; 03953 ast_copy_string(p, route->hop, rem); p += n; 03954 *p++ = '>'; 03955 rem -= (n+2); 03956 route = route->next; 03957 } 03958 *p = '\0'; 03959 add_header(req, "Route", r); 03960 }
|
|
add_sdp: Add Session Description Protocol message ---
Definition at line 4390 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_FORMAT_MAX_AUDIO, AST_FORMAT_MAX_VIDEO, ast_inet_ntoa(), ast_log(), ast_rtp_get_us(), AST_RTP_MAX, ast_test_flag, ast_verbose(), capability, debug, sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_request::len, LOG_WARNING, sip_pvt::noncodeccapability, sip_pvt::ourip, sip_pvt::prefcodec, sip_pvt::prefs, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, s, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), SIP_NOVIDEO, t, VIDEO_CODEC_MASK, sip_pvt::vredirip, and sip_pvt::vrtp. 04391 { 04392 int len = 0; 04393 int pref_codec; 04394 int alreadysent = 0; 04395 struct sockaddr_in sin; 04396 struct sockaddr_in vsin; 04397 char v[256]; 04398 char s[256]; 04399 char o[256]; 04400 char c[256]; 04401 char t[256]; 04402 char m_audio[256]; 04403 char m_video[256]; 04404 char a_audio[1024]; 04405 char a_video[1024]; 04406 char *m_audio_next = m_audio; 04407 char *m_video_next = m_video; 04408 size_t m_audio_left = sizeof(m_audio); 04409 size_t m_video_left = sizeof(m_video); 04410 char *a_audio_next = a_audio; 04411 char *a_video_next = a_video; 04412 size_t a_audio_left = sizeof(a_audio); 04413 size_t a_video_left = sizeof(a_video); 04414 char iabuf[INET_ADDRSTRLEN]; 04415 int x; 04416 int capability; 04417 struct sockaddr_in dest; 04418 struct sockaddr_in vdest = { 0, }; 04419 int debug; 04420 04421 debug = sip_debug_test_pvt(p); 04422 04423 len = 0; 04424 if (!p->rtp) { 04425 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 04426 return -1; 04427 } 04428 capability = p->jointcapability; 04429 04430 if (!p->sessionid) { 04431 p->sessionid = getpid(); 04432 p->sessionversion = p->sessionid; 04433 } else 04434 p->sessionversion++; 04435 ast_rtp_get_us(p->rtp, &sin); 04436 if (p->vrtp) 04437 ast_rtp_get_us(p->vrtp, &vsin); 04438 04439 if (p->redirip.sin_addr.s_addr) { 04440 dest.sin_port = p->redirip.sin_port; 04441 dest.sin_addr = p->redirip.sin_addr; 04442 if (p->redircodecs) 04443 capability = p->redircodecs; 04444 } else { 04445 dest.sin_addr = p->ourip; 04446 dest.sin_port = sin.sin_port; 04447 } 04448 04449 /* Determine video destination */ 04450 if (p->vrtp) { 04451 if (p->vredirip.sin_addr.s_addr) { 04452 vdest.sin_port = p->vredirip.sin_port; 04453 vdest.sin_addr = p->vredirip.sin_addr; 04454 } else { 04455 vdest.sin_addr = p->ourip; 04456 vdest.sin_port = vsin.sin_port; 04457 } 04458 } 04459 if (debug){ 04460 ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(sin.sin_port)); 04461 if (p->vrtp) 04462 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(vsin.sin_port)); 04463 } 04464 04465 /* We break with the "recommendation" and send our IP, in order that our 04466 peer doesn't have to ast_gethostbyname() us */ 04467 04468 snprintf(v, sizeof(v), "v=0\r\n"); 04469 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr)); 04470 snprintf(s, sizeof(s), "s=session\r\n"); 04471 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr)); 04472 snprintf(t, sizeof(t), "t=0 0\r\n"); 04473 04474 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 04475 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 04476 04477 /* Prefer the codec we were requested to use, first, no matter what */ 04478 if (capability & p->prefcodec) { 04479 if (p->prefcodec <= AST_FORMAT_MAX_AUDIO) 04480 add_codec_to_sdp(p, p->prefcodec, 8000, 04481 &m_audio_next, &m_audio_left, 04482 &a_audio_next, &a_audio_left, 04483 debug); 04484 else 04485 add_codec_to_sdp(p, p->prefcodec, 90000, 04486 &m_video_next, &m_video_left, 04487 &a_video_next, &a_video_left, 04488 debug); 04489 alreadysent |= p->prefcodec; 04490 } 04491 04492 /* Start by sending our preferred codecs */ 04493 for (x = 0; x < 32; x++) { 04494 if (!(pref_codec = ast_codec_pref_index(&p->prefs, x))) 04495 break; 04496 04497 if (!(capability & pref_codec)) 04498 continue; 04499 04500 if (alreadysent & pref_codec) 04501 continue; 04502 04503 if (pref_codec <= AST_FORMAT_MAX_AUDIO) 04504 add_codec_to_sdp(p, pref_codec, 8000, 04505 &m_audio_next, &m_audio_left, 04506 &a_audio_next, &a_audio_left, 04507 debug); 04508 else 04509 add_codec_to_sdp(p, pref_codec, 90000, 04510 &m_video_next, &m_video_left, 04511 &a_video_next, &a_video_left, 04512 debug); 04513 alreadysent |= pref_codec; 04514 } 04515 04516 /* Now send any other common codecs, and non-codec formats: */ 04517 for (x = 1; x <= ((videosupport && p->vrtp) ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 04518 if (!(capability & x)) 04519 continue; 04520 04521 if (alreadysent & x) 04522 continue; 04523 04524 if (x <= AST_FORMAT_MAX_AUDIO) 04525 add_codec_to_sdp(p, x, 8000, 04526 &m_audio_next, &m_audio_left, 04527 &a_audio_next, &a_audio_left, 04528 debug); 04529 else 04530 add_codec_to_sdp(p, x, 90000, 04531 &m_video_next, &m_video_left, 04532 &a_video_next, &a_video_left, 04533 debug); 04534 } 04535 04536 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 04537 if (!(p->noncodeccapability & x)) 04538 continue; 04539 04540 add_noncodec_to_sdp(p, x, 8000, 04541 &m_audio_next, &m_audio_left, 04542 &a_audio_next, &a_audio_left, 04543 debug); 04544 } 04545 04546 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 04547 04548 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 04549 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 04550 04551 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 04552 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 04553 04554 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_audio) + strlen(a_audio); 04555 if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) /* only if video response is appropriate */ 04556 len += strlen(m_video) + strlen(a_video); 04557 04558 add_header(resp, "Content-Type", "application/sdp"); 04559 add_header_contentLength(resp, len); 04560 add_line(resp, v); 04561 add_line(resp, o); 04562 add_line(resp, s); 04563 add_line(resp, c); 04564 add_line(resp, t); 04565 add_line(resp, m_audio); 04566 add_line(resp, a_audio); 04567 if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) { /* only if video response is appropriate */ 04568 add_line(resp, m_video); 04569 add_line(resp, a_video); 04570 } 04571 04572 /* Update lastrtprx when we send our SDP */ 04573 time(&p->lastrtprx); 04574 time(&p->lastrtptx); 04575 04576 return 0; 04577 }
|
|
add_sip_domain: Add SIP domain to list of domains we are responsible for
Definition at line 11900 of file chan_sip.c. References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), calloc, list, LOG_DEBUG, LOG_ERROR, LOG_WARNING, and sipdebug. Referenced by reload_config(). 11901 { 11902 struct domain *d; 11903 11904 if (ast_strlen_zero(domain)) { 11905 ast_log(LOG_WARNING, "Zero length domain.\n"); 11906 return 1; 11907 } 11908 11909 d = calloc(1, sizeof(*d)); 11910 if (!d) { 11911 ast_log(LOG_ERROR, "Allocation of domain structure failed, Out of memory\n"); 11912 return 0; 11913 } 11914 11915 ast_copy_string(d->domain, domain, sizeof(d->domain)); 11916 11917 if (!ast_strlen_zero(context)) 11918 ast_copy_string(d->context, context, sizeof(d->context)); 11919 11920 d->mode = mode; 11921 11922 AST_LIST_LOCK(&domain_list); 11923 AST_LIST_INSERT_TAIL(&domain_list, d, list); 11924 AST_LIST_UNLOCK(&domain_list); 11925 11926 if (sipdebug) 11927 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 11928 11929 return 1; 11930 }
|
|
add_text: Add text body to SIP message ---
Definition at line 4307 of file chan_sip.c. References add_header(), add_header_contentLength(), and add_line(). Referenced by transmit_message_with_text(). 04308 { 04309 /* XXX Convert \n's to \r\n's XXX */ 04310 add_header(req, "Content-Type", "text/plain"); 04311 add_header_contentLength(req, strlen(text)); 04312 add_line(req, text); 04313 return 0; 04314 }
|
|
add_vidupdate: add XML encoded media control with update ---
Definition at line 4331 of file chan_sip.c. References add_header(), add_header_contentLength(), and add_line(). Referenced by transmit_info_with_vidupdate(). 04332 { 04333 const char *xml_is_a_huge_waste_of_space = 04334 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 04335 " <media_control>\r\n" 04336 " <vc_primitive>\r\n" 04337 " <to_encoder>\r\n" 04338 " <picture_fast_update>\r\n" 04339 " </picture_fast_update>\r\n" 04340 " </to_encoder>\r\n" 04341 " </vc_primitive>\r\n" 04342 " </media_control>\r\n"; 04343 add_header(req, "Content-Type", "application/media_control+xml"); 04344 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 04345 add_line(req, xml_is_a_huge_waste_of_space); 04346 return 0; 04347 }
|
|
append_date: Append date to SIP message ---
Definition at line 4251 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(). 04252 { 04253 char tmpdat[256]; 04254 struct tm tm; 04255 time_t t; 04256 04257 time(&t); 04258 gmtime_r(&t, &tm); 04259 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 04260 add_header(req, "Date", tmpdat); 04261 }
|
|
append_history: Append to SIP dialog history
Definition at line 1129 of file chan_sip.c. References ast_log(), sip_history::event, sip_pvt::history, LOG_WARNING, malloc, sip_history::next, and recordhistory. Referenced by __sip_autodestruct(), cb_extensionstate(), do_register_auth(), handle_request_subscribe(), process_sdp(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_reregister(), sip_scheddestroy(), sipsock_read(), and transmit_register(). 01130 { 01131 struct sip_history *hist, *prev; 01132 char *c; 01133 01134 if (!recordhistory || !p) 01135 return 0; 01136 if(!(hist = malloc(sizeof(struct sip_history)))) { 01137 ast_log(LOG_WARNING, "Can't allocate memory for history"); 01138 return 0; 01139 } 01140 memset(hist, 0, sizeof(struct sip_history)); 01141 snprintf(hist->event, sizeof(hist->event), "%-15s %s", event, data); 01142 /* Trim up nicely */ 01143 c = hist->event; 01144 while(*c) { 01145 if ((*c == '\r') || (*c == '\n')) { 01146 *c = '\0'; 01147 break; 01148 } 01149 c++; 01150 } 01151 /* Enqueue into history */ 01152 prev = p->history; 01153 if (prev) { 01154 while(prev->next) 01155 prev = prev->next; 01156 prev->next = hist; 01157 } else { 01158 p->history = hist; 01159 } 01160 return 0; 01161 }
|
|
The SIP domain list |
|
|
|
|
|
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
|
|
Protect the interface list (of sip_pvt's).
|
|
|
|
|
|
ast_quiet_chan: Turn off generator data
Definition at line 10264 of file chan_sip.c. References ast_channel::_state, ast_deactivate_generator(), AST_STATE_UP, and ast_channel::generatordata. Referenced by attempt_transfer(). 10265 { 10266 if (chan && chan->_state == AST_STATE_UP) { 10267 if (chan->generatordata) 10268 ast_deactivate_generator(chan); 10269 } 10270 }
|
|
ast_sip_ouraddrfor: NAT fix - decide which IP address to use for ASterisk server? ---
Definition at line 1094 of file chan_sip.c. References ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), externexpire, externhost, externrefresh, hp, localaddr, LOG_DEBUG, and LOG_NOTICE. Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register(). 01095 { 01096 /* 01097 * Using the localaddr structure built up with localnet statements 01098 * apply it to their address to see if we need to substitute our 01099 * externip or can get away with our internal bindaddr 01100 */ 01101 struct sockaddr_in theirs; 01102 theirs.sin_addr = *them; 01103 if (localaddr && externip.sin_addr.s_addr && 01104 ast_apply_ha(localaddr, &theirs)) { 01105 char iabuf[INET_ADDRSTRLEN]; 01106 if (externexpire && (time(NULL) >= externexpire)) { 01107 struct ast_hostent ahp; 01108 struct hostent *hp; 01109 time(&externexpire); 01110 externexpire += externrefresh; 01111 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01112 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01113 } else 01114 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01115 } 01116 memcpy(us, &externip.sin_addr, sizeof(struct in_addr)); 01117 ast_inet_ntoa(iabuf, sizeof(iabuf), *(struct in_addr *)&them->s_addr); 01118 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", iabuf); 01119 } 01120 else if (bindaddr.sin_addr.s_addr) 01121 memcpy(us, &bindaddr.sin_addr, sizeof(struct in_addr)); 01122 else 01123 return ast_ouraddrfor(them, us); 01124 return 0; 01125 }
|
|
attempt_transfer: Attempt transfer of SIP call ---
Definition at line 10273 of file chan_sip.c. References ast_bridged_channel(), ast_cdr_append(), ast_channel_masquerade(), ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), LOG_NOTICE, LOG_WARNING, and sip_pvt::owner. 10274 { 10275 int res = 0; 10276 struct ast_channel 10277 *chana = NULL, 10278 *chanb = NULL, 10279 *bridgea = NULL, 10280 *bridgeb = NULL, 10281 *peera = NULL, 10282 *peerb = NULL, 10283 *peerc = NULL, 10284 *peerd = NULL; 10285 10286 if (!p1->owner || !p2->owner) { 10287 ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n"); 10288 return -1; 10289 } 10290 chana = p1->owner; 10291 chanb = p2->owner; 10292 bridgea = ast_bridged_channel(chana); 10293 bridgeb = ast_bridged_channel(chanb); 10294 10295 if (bridgea) { 10296 peera = chana; 10297 peerb = chanb; 10298 peerc = bridgea; 10299 peerd = bridgeb; 10300 } else if (bridgeb) { 10301 peera = chanb; 10302 peerb = chana; 10303 peerc = bridgeb; 10304 peerd = bridgea; 10305 } 10306 10307 if (peera && peerb && peerc && (peerb != peerc)) { 10308 ast_quiet_chan(peera); 10309 ast_quiet_chan(peerb); 10310 ast_quiet_chan(peerc); 10311 ast_quiet_chan(peerd); 10312 10313 if (peera->cdr && peerb->cdr) { 10314 peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); 10315 } else if (peera->cdr) { 10316 peerb->cdr = peera->cdr; 10317 } 10318 peera->cdr = NULL; 10319 10320 if (peerb->cdr && peerc->cdr) { 10321 peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); 10322 } else if (peerc->cdr) { 10323 peerb->cdr = peerc->cdr; 10324 } 10325 peerc->cdr = NULL; 10326 10327 if (ast_channel_masquerade(peerb, peerc)) { 10328 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 10329 res = -1; 10330 } 10331 return res; 10332 } else { 10333 ast_log(LOG_NOTICE, "Transfer attempted with no appropriate bridged calls to transfer\n"); 10334 if (chana) 10335 ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV); 10336 if (chanb) 10337 ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV); 10338 return -1; 10339 } 10340 return 0; 10341 }
|
|
auto_congest: Scheduled congestion on a call ---
Definition at line 1990 of file chan_sip.c. References AST_CONTROL_CONGESTION, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_control(), sip_pvt::initid, ast_channel::lock, sip_pvt::lock, LOG_NOTICE, ast_channel::name, and sip_pvt::owner. 01991 { 01992 struct sip_pvt *p = nothing; 01993 ast_mutex_lock(&p->lock); 01994 p->initid = -1; 01995 if (p->owner) { 01996 if (!ast_mutex_trylock(&p->owner->lock)) { 01997 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 01998 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 01999 ast_mutex_unlock(&p->owner->lock); 02000 } 02001 } 02002 ast_mutex_unlock(&p->lock); 02003 return 0; 02004 }
|
|
build_callid: Build SIP CALLID header ---
Definition at line 3029 of file chan_sip.c. References ast_inet_ntoa(), ast_strlen_zero(), and thread_safe_rand(). Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register(). 03030 { 03031 int res; 03032 int val; 03033 int x; 03034 char iabuf[INET_ADDRSTRLEN]; 03035 for (x=0; x<4; x++) { 03036 val = thread_safe_rand(); 03037 res = snprintf(callid, len, "%08x", val); 03038 len -= res; 03039 callid += res; 03040 } 03041 if (!ast_strlen_zero(fromdomain)) 03042 snprintf(callid, len, "@%s", fromdomain); 03043 else 03044 /* It's not important that we really use our right IP here... */ 03045 snprintf(callid, len, "@%s", ast_inet_ntoa(iabuf, sizeof(iabuf), ourip)); 03046 }
|
|
build_contact: Build contact header - the contact header we send out ---
Definition at line 4707 of file chan_sip.c. References ast_inet_ntoa(), ast_strlen_zero(), sip_pvt::exten, sip_pvt::our_contact, sip_pvt::ourip, and ourport. Referenced by check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register(). 04708 { 04709 char iabuf[INET_ADDRSTRLEN]; 04710 04711 /* Construct Contact: header */ 04712 if (ourport != 5060) /* Needs to be 5060, according to the RFC */ 04713 snprintf(p->our_contact, sizeof(p->our_contact), "<sip:%s%s%s:%d>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport); 04714 else 04715 snprintf(p->our_contact, sizeof(p->our_contact), "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip)); 04716 }
|
|
build_peer: Build peer from config file ---
Definition at line 12197 of file chan_sip.c. References sip_peer::accountcode, add_realm_authentication(), sip_peer::addr, sip_peer::amaflags, ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), 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_INIT, ASTOBJ_UNMARK, ASTOBJ_UNREF, sip_peer::auth, 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, default_context, default_language, DEFAULT_MAXMS, default_qualify, DEFAULT_SIP_PORT, default_subscribecontext, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags_page2, format, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_capability, global_musicclass, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_vmexten, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, LOG_WARNING, sip_peer::mailbox, malloc, sip_peer::maxms, sip_peer::md5secret, sip_peer::musicclass, ast_variable::name, ast_variable::next, option_debug, peerl, sip_peer::pickupgroup, sip_peer::prefs, reg_source_db(), sip_peer::regexten, rpeerobjs, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, sip_destroy_peer(), SIP_FLAGS_TO_COPY, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_REALTIME, SIP_USEREQPHONE, speerobjs, sip_peer::subscribecontext, sip_peer::tohost, sip_peer::username, ast_variable::value, and sip_peer::vmexten. 12198 { 12199 struct sip_peer *peer = NULL; 12200 struct ast_ha *oldha = NULL; 12201 int obproxyfound=0; 12202 int found=0; 12203 int format=0; /* Ama flags */ 12204 time_t regseconds; 12205 char *varname = NULL, *varval = NULL; 12206 struct ast_variable *tmpvar = NULL; 12207 struct ast_flags peerflags = {(0)}; 12208 struct ast_flags mask = {(0)}; 12209 12210 12211 if (!realtime) 12212 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 12213 /* We also use a case-sensitive comparison (unlike find_peer) so 12214 that case changes made to the peer name will be properly handled 12215 during reload 12216 */ 12217 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 12218 12219 if (peer) { 12220 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12221 found++; 12222 } else { 12223 peer = malloc(sizeof(*peer)); 12224 if (peer) { 12225 memset(peer, 0, sizeof(*peer)); 12226 if (realtime) 12227 rpeerobjs++; 12228 else 12229 speerobjs++; 12230 ASTOBJ_INIT(peer); 12231 peer->expire = -1; 12232 peer->pokeexpire = -1; 12233 } else { 12234 ast_log(LOG_WARNING, "Can't allocate SIP peer memory\n"); 12235 } 12236 } 12237 /* Note that our peer HAS had its reference count incrased */ 12238 if (!peer) 12239 return NULL; 12240 12241 peer->lastmsgssent = -1; 12242 if (!found) { 12243 if (name) 12244 ast_copy_string(peer->name, name, sizeof(peer->name)); 12245 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 12246 peer->addr.sin_family = AF_INET; 12247 peer->defaddr.sin_family = AF_INET; 12248 } 12249 /* If we have channel variables, remove them (reload) */ 12250 if (peer->chanvars) { 12251 ast_variables_destroy(peer->chanvars); 12252 peer->chanvars = NULL; 12253 } 12254 strcpy(peer->context, default_context); 12255 strcpy(peer->subscribecontext, default_subscribecontext); 12256 strcpy(peer->vmexten, global_vmexten); 12257 strcpy(peer->language, default_language); 12258 strcpy(peer->musicclass, global_musicclass); 12259 ast_copy_flags(peer, &global_flags, SIP_USEREQPHONE); 12260 peer->secret[0] = '\0'; 12261 peer->md5secret[0] = '\0'; 12262 peer->cid_num[0] = '\0'; 12263 peer->cid_name[0] = '\0'; 12264 peer->fromdomain[0] = '\0'; 12265 peer->fromuser[0] = '\0'; 12266 peer->regexten[0] = '\0'; 12267 peer->mailbox[0] = '\0'; 12268 peer->callgroup = 0; 12269 peer->pickupgroup = 0; 12270 peer->rtpkeepalive = global_rtpkeepalive; 12271 peer->maxms = default_qualify; 12272 peer->prefs = prefs; 12273 oldha = peer->ha; 12274 peer->ha = NULL; 12275 peer->addr.sin_family = AF_INET; 12276 ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY); 12277 peer->capability = global_capability; 12278 peer->rtptimeout = global_rtptimeout; 12279 peer->rtpholdtimeout = global_rtpholdtimeout; 12280 while(v) { 12281 if (handle_common_options(&peerflags, &mask, v)) { 12282 v = v->next; 12283 continue; 12284 } 12285 12286 if (realtime && !strcasecmp(v->name, "regseconds")) { 12287 if (sscanf(v->value, "%ld", (time_t *)®seconds) != 1) 12288 regseconds = 0; 12289 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 12290 inet_aton(v->value, &(peer->addr.sin_addr)); 12291 } else if (realtime && !strcasecmp(v->name, "name")) 12292 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 12293 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 12294 ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact)); 12295 ast_set_flag((&peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT); 12296 } else if (!strcasecmp(v->name, "secret")) 12297 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 12298 else if (!strcasecmp(v->name, "md5secret")) 12299 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 12300 else if (!strcasecmp(v->name, "auth")) 12301 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 12302 else if (!strcasecmp(v->name, "callerid")) { 12303 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 12304 } else if (!strcasecmp(v->name, "context")) { 12305 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 12306 } else if (!strcasecmp(v->name, "subscribecontext")) { 12307 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 12308 } else if (!strcasecmp(v->name, "fromdomain")) 12309 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 12310 else if (!strcasecmp(v->name, "usereqphone")) 12311 ast_set2_flag(peer, ast_true(v->value), SIP_USEREQPHONE); 12312 else if (!strcasecmp(v->name, "fromuser")) 12313 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 12314 else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 12315 if (!strcasecmp(v->value, "dynamic")) { 12316 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 12317 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 12318 } else { 12319 /* They'll register with us */ 12320 ast_set_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC); 12321 if (!found) { 12322 /* Initialize stuff iff we're not found, otherwise 12323 we keep going with what we had */ 12324 memset(&peer->addr.sin_addr, 0, 4); 12325 if (peer->addr.sin_port) { 12326 /* If we've already got a port, make it the default rather than absolute */ 12327 peer->defaddr.sin_port = peer->addr.sin_port; 12328 peer->addr.sin_port = 0; 12329 } 12330 } 12331 } 12332 } else { 12333 /* Non-dynamic. Make sure we become that way if we're not */ 12334 if (peer->expire > -1) 12335 ast_sched_del(sched, peer->expire); 12336 peer->expire = -1; 12337 ast_clear_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC); 12338 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 12339 if (ast_get_ip_or_srv(&peer->addr, v->value, "_sip._udp")) { 12340 ASTOBJ_UNREF(peer, sip_destroy_peer); 12341 return NULL; 12342 } 12343 } 12344 if (!strcasecmp(v->name, "outboundproxy")) 12345 obproxyfound=1; 12346 else { 12347 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 12348 if (!peer->addr.sin_port) 12349 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 12350 } 12351 } 12352 } else if (!strcasecmp(v->name, "defaultip")) { 12353 if (ast_get_ip(&peer->defaddr, v->value)) { 12354 ASTOBJ_UNREF(peer, sip_destroy_peer); 12355 return NULL; 12356 } 12357 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 12358 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 12359 } else if (!strcasecmp(v->name, "port")) { 12360 if (!realtime && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)) 12361 peer->defaddr.sin_port = htons(atoi(v->value)); 12362 else 12363 peer->addr.sin_port = htons(atoi(v->value)); 12364 } else if (!strcasecmp(v->name, "callingpres")) { 12365 peer->callingpres = ast_parse_caller_presentation(v->value); 12366 if (peer->callingpres == -1) 12367 peer->callingpres = atoi(v->value); 12368 } else if (!strcasecmp(v->name, "username")) { 12369 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 12370 } else if (!strcasecmp(v->name, "language")) { 12371 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 12372 } else if (!strcasecmp(v->name, "regexten")) { 12373 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 12374 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 12375 peer->call_limit = atoi(v->value); 12376 if (peer->call_limit < 0) 12377 peer->call_limit = 0; 12378 } else if (!strcasecmp(v->name, "amaflags")) { 12379 format = ast_cdr_amaflags2int(v->value); 12380 if (format < 0) { 12381 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 12382 } else { 12383 peer->amaflags = format; 12384 } 12385 } else if (!strcasecmp(v->name, "accountcode")) { 12386 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 12387 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 12388 ast_copy_string(peer->musicclass, v->value, sizeof(peer->musicclass)); 12389 } else if (!strcasecmp(v->name, "mailbox")) { 12390 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 12391 } else if (!strcasecmp(v->name, "vmexten")) { 12392 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 12393 } else if (!strcasecmp(v->name, "callgroup")) { 12394 peer->callgroup = ast_get_group(v->value); 12395 } else if (!strcasecmp(v->name, "pickupgroup")) { 12396 peer->pickupgroup = ast_get_group(v->value); 12397 } else if (!strcasecmp(v->name, "allow")) { 12398 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 12399 } else if (!strcasecmp(v->name, "disallow")) { 12400 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 12401 } else if (!strcasecmp(v->name, "rtptimeout")) { 12402 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 12403 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12404 peer->rtptimeout = global_rtptimeout; 12405 } 12406 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 12407 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 12408 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12409 peer->rtpholdtimeout = global_rtpholdtimeout; 12410 } 12411 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 12412 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 12413 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 12414 peer->rtpkeepalive = global_rtpkeepalive; 12415 } 12416 } else if (!strcasecmp(v->name, "setvar")) { 12417 /* Set peer channel variable */ 12418 varname = ast_strdupa(v->value); 12419 if (varname && (varval = strchr(varname,'='))) { 12420 *varval = '\0'; 12421 varval++; 12422 if ((tmpvar = ast_variable_new(varname, varval))) { 12423 tmpvar->next = peer->chanvars; 12424 peer->chanvars = tmpvar; 12425 } 12426 } 12427 } else if (!strcasecmp(v->name, "qualify")) { 12428 if (!strcasecmp(v->value, "no")) { 12429 peer->maxms = 0; 12430 } else if (!strcasecmp(v->value, "yes")) { 12431 peer->maxms = DEFAULT_MAXMS; 12432 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 12433 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); 12434 peer->maxms = 0; 12435 } 12436 } 12437 /* else if (strcasecmp(v->name,"type")) 12438 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 12439 */ 12440 v=v->next; 12441 } 12442 if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) && realtime) { 12443 time_t nowtime; 12444 12445 time(&nowtime); 12446 if ((nowtime - regseconds) > 0) { 12447 destroy_association(peer); 12448 memset(&peer->addr, 0, sizeof(peer->addr)); 12449 if (option_debug) 12450 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 12451 } 12452 } 12453 ast_copy_flags(peer, &peerflags, mask.flags); 12454 if (!found && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) && !ast_test_flag(peer, SIP_REALTIME)) 12455 reg_source_db(peer); 12456 ASTOBJ_UNMARK(peer); 12457 ast_free_ha(oldha); 12458 return peer; 12459 }
|
|
build_reply_digest: Build reply digest ---
Definition at line 9108 of file chan_sip.c. References ast_inet_ntoa(), ast_log(), ast_md5_hash(), 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_pvt::peermd5secret, sip_pvt::peersecret, sip_pvt::qop, sip_pvt::realm, sip_pvt::sa, sip_auth::secret, secret, sip_methods, sipdebug, text, thread_safe_rand(), sip_pvt::uri, sip_auth::username, sip_pvt::username, and username. Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth(). 09109 { 09110 char a1[256]; 09111 char a2[256]; 09112 char a1_hash[256]; 09113 char a2_hash[256]; 09114 char resp[256]; 09115 char resp_hash[256]; 09116 char uri[256]; 09117 char cnonce[80]; 09118 char iabuf[INET_ADDRSTRLEN]; 09119 char *username; 09120 char *secret; 09121 char *md5secret; 09122 struct sip_auth *auth = (struct sip_auth *) NULL; /* Realm authentication */ 09123 09124 if (!ast_strlen_zero(p->domain)) 09125 ast_copy_string(uri, p->domain, sizeof(uri)); 09126 else if (!ast_strlen_zero(p->uri)) 09127 ast_copy_string(uri, p->uri, sizeof(uri)); 09128 else 09129 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); 09130 09131 snprintf(cnonce, sizeof(cnonce), "%08x", thread_safe_rand()); 09132 09133 /* Check if we have separate auth credentials */ 09134 if ((auth = find_realm_authentication(authl, p->realm))) { 09135 username = auth->username; 09136 secret = auth->secret; 09137 md5secret = auth->md5secret; 09138 if (sipdebug) 09139 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 09140 } else { 09141 /* No authentication, use peer or register= config */ 09142 username = p->authname; 09143 secret = p->peersecret; 09144 md5secret = p->peermd5secret; 09145 } 09146 if (ast_strlen_zero(username)) /* We have no authentication */ 09147 return -1; 09148 09149 09150 /* Calculate SIP digest response */ 09151 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 09152 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 09153 if (!ast_strlen_zero(md5secret)) 09154 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 09155 else 09156 ast_md5_hash(a1_hash,a1); 09157 ast_md5_hash(a2_hash,a2); 09158 09159 p->noncecount++; 09160 if (!ast_strlen_zero(p->qop)) 09161 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 09162 else 09163 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 09164 ast_md5_hash(resp_hash, resp); 09165 /* XXX We hard code our qop to "auth" for now. XXX */ 09166 if (!ast_strlen_zero(p->qop)) 09167 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\", qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, p->opaque, cnonce, p->noncecount); 09168 else 09169 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\"", username, p->realm, uri, p->nonce, resp_hash, p->opaque); 09170 09171 return 0; 09172 }
|
|
build_route: Build route list from Record-Route header ---
Definition at line 6065 of file chan_sip.c. References __get_header(), ast_log(), ast_strlen_zero(), free_old_route(), get_header(), sip_route::hop, list_route(), LOG_DEBUG, malloc, sip_route::next, sip_pvt::route, sip_pvt::route_persistant, and sip_debug_test_pvt(). Referenced by handle_request_invite(), and handle_response_invite(). 06066 { 06067 struct sip_route *thishop, *head, *tail; 06068 int start = 0; 06069 int len; 06070 char *rr, *contact, *c; 06071 06072 /* Once a persistant route is set, don't fool with it */ 06073 if (p->route && p->route_persistant) { 06074 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 06075 return; 06076 } 06077 06078 if (p->route) { 06079 free_old_route(p->route); 06080 p->route = NULL; 06081 } 06082 06083 p->route_persistant = backwards; 06084 06085 /* We build up head, then assign it to p->route when we're done */ 06086 head = NULL; tail = head; 06087 /* 1st we pass through all the hops in any Record-Route headers */ 06088 for (;;) { 06089 /* Each Record-Route header */ 06090 rr = __get_header(req, "Record-Route", &start); 06091 if (*rr == '\0') break; 06092 for (;;) { 06093 /* Each route entry */ 06094 /* Find < */ 06095 rr = strchr(rr, '<'); 06096 if (!rr) break; /* No more hops */ 06097 ++rr; 06098 len = strcspn(rr, ">") + 1; 06099 /* Make a struct route */ 06100 thishop = malloc(sizeof(*thishop) + len); 06101 if (thishop) { 06102 ast_copy_string(thishop->hop, rr, len); 06103 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 06104 /* Link in */ 06105 if (backwards) { 06106 /* Link in at head so they end up in reverse order */ 06107 thishop->next = head; 06108 head = thishop; 06109 /* If this was the first then it'll be the tail */ 06110 if (!tail) tail = thishop; 06111 } else { 06112 thishop->next = NULL; 06113 /* Link in at the end */ 06114 if (tail) 06115 tail->next = thishop; 06116 else 06117 head = thishop; 06118 tail = thishop; 06119 } 06120 } 06121 rr += len; 06122 } 06123 } 06124 06125 /* Only append the contact if we are dealing with a strict router */ 06126 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 06127 /* 2nd append the Contact: if there is one */ 06128 /* Can be multiple Contact headers, comma separated values - we just take the first */ 06129 contact = get_header(req, "Contact"); 06130 if (!ast_strlen_zero(contact)) { 06131 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 06132 /* Look for <: delimited address */ 06133 c = strchr(contact, '<'); 06134 if (c) { 06135 /* Take to > */ 06136 ++c; 06137 len = strcspn(c, ">") + 1; 06138 } else { 06139 /* No <> - just take the lot */ 06140 c = contact; 06141 len = strlen(contact) + 1; 06142 } 06143 thishop = malloc(sizeof(*thishop) + len); 06144 if (thishop) { 06145 ast_copy_string(thishop->hop, c, len); 06146 thishop->next = NULL; 06147 /* Goes at the end */ 06148 if (tail) 06149 tail->next = thishop; 06150 else 06151 head = thishop; 06152 } 06153 } 06154 } 06155 06156 /* Store as new route */ 06157 p->route = head; 06158 06159 /* For debugging dump what we ended up with */ 06160 if (sip_debug_test_pvt(p)) 06161 list_route(p->route); 06162 }
|
|
build_rpid: Build the Remote Party-ID & From using callingpres options ---
Definition at line 4719 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_strlen_zero(), sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, default_callerid, sip_pvt::fromdomain, sip_pvt::fromuser, LOG_WARNING, sip_pvt::ourip, sip_pvt::owner, sip_pvt::rpid, sip_pvt::rpid_from, strdup, and sip_pvt::tag. Referenced by initreqprep(). 04720 { 04721 int send_pres_tags = 1; 04722 const char *privacy=NULL; 04723 const char *screen=NULL; 04724 char buf[256]; 04725 const char *clid = default_callerid; 04726 const char *clin = NULL; 04727 char iabuf[INET_ADDRSTRLEN]; 04728 const char *fromdomain; 04729 04730 if (p->rpid || p->rpid_from) 04731 return; 04732 04733 if (p->owner && p->owner->cid.cid_num) 04734 clid = p->owner->cid.cid_num; 04735 if (p->owner && p->owner->cid.cid_name) 04736 clin = p->owner->cid.cid_name; 04737 if (ast_strlen_zero(clin)) 04738 clin = clid; 04739 04740 switch (p->callingpres) { 04741 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 04742 privacy = "off"; 04743 screen = "no"; 04744 break; 04745 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 04746 privacy = "off"; 04747 screen = "pass"; 04748 break; 04749 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 04750 privacy = "off"; 04751 screen = "fail"; 04752 break; 04753 case AST_PRES_ALLOWED_NETWORK_NUMBER: 04754 privacy = "off"; 04755 screen = "yes"; 04756 break; 04757 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 04758 privacy = "full"; 04759 screen = "no"; 04760 break; 04761 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 04762 privacy = "full"; 04763 screen = "pass"; 04764 break; 04765 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 04766 privacy = "full"; 04767 screen = "fail"; 04768 break; 04769 case AST_PRES_PROHIB_NETWORK_NUMBER: 04770 privacy = "full"; 04771 screen = "pass"; 04772 break; 04773 case AST_PRES_NUMBER_NOT_AVAILABLE: 04774 send_pres_tags = 0; 04775 break; 04776 default: 04777 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 04778 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 04779 privacy = "full"; 04780 else 04781 privacy = "off"; 04782 screen = "no"; 04783 break; 04784 } 04785 04786 fromdomain = ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain; 04787 04788 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 04789 if (send_pres_tags) 04790 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 04791 p->rpid = strdup(buf); 04792 04793 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>;tag=%s", clin, 04794 ast_strlen_zero(p->fromuser) ? clid : p->fromuser, 04795 fromdomain, p->tag); 04796 p->rpid_from = strdup(buf); 04797 }
|
|
build_user: Initiate a SIP user structure from sip.conf ---
Definition at line 12064 of file chan_sip.c. References ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_copy_flags, ast_free_ha(), ast_get_group(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_strdupa, ast_variable_new(), ASTOBJ_INIT, default_context, default_language, ast_flags::flags, format, global_capability, global_musicclass, handle_common_options(), ast_variable::lineno, LOG_WARNING, malloc, ast_variable::name, ast_variable::next, SIP_FLAGS_TO_COPY, suserobjs, user, and ast_variable::value. 12065 { 12066 struct sip_user *user; 12067 int format; 12068 struct ast_ha *oldha = NULL; 12069 char *varname = NULL, *varval = NULL; 12070 struct ast_variable *tmpvar = NULL; 12071 struct ast_flags userflags = {(0)}; 12072 struct ast_flags mask = {(0)}; 12073 12074 12075 user = (struct sip_user *)malloc(sizeof(struct sip_user)); 12076 if (!user) { 12077 return NULL; 12078 } 12079 memset(user, 0, sizeof(struct sip_user)); 12080 suserobjs++; 12081 ASTOBJ_INIT(user); 12082 ast_copy_string(user->name, name, sizeof(user->name)); 12083 oldha = user->ha; 12084 user->ha = NULL; 12085 ast_copy_flags(user, &global_flags, SIP_FLAGS_TO_COPY); 12086 user->capability = global_capability; 12087 user->prefs = prefs; 12088 /* set default context */ 12089 strcpy(user->context, default_context); 12090 strcpy(user->language, default_language); 12091 strcpy(user->musicclass, global_musicclass); 12092 while(v) { 12093 if (handle_common_options(&userflags, &mask, v)) { 12094 v = v->next; 12095 continue; 12096 } 12097 12098 if (!strcasecmp(v->name, "context")) { 12099 ast_copy_string(user->context, v->value, sizeof(user->context)); 12100 } else if (!strcasecmp(v->name, "subscribecontext")) { 12101 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 12102 } else if (!strcasecmp(v->name, "setvar")) { 12103 varname = ast_strdupa(v->value); 12104 if (varname && (varval = strchr(varname,'='))) { 12105 *varval = '\0'; 12106 varval++; 12107 if ((tmpvar = ast_variable_new(varname, varval))) { 12108 tmpvar->next = user->chanvars; 12109 user->chanvars = tmpvar; 12110 } 12111 } 12112 } else if (!strcasecmp(v->name, "permit") || 12113 !strcasecmp(v->name, "deny")) { 12114 user->ha = ast_append_ha(v->name, v->value, user->ha); 12115 } else if (!strcasecmp(v->name, "secret")) { 12116 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 12117 } else if (!strcasecmp(v->name, "md5secret")) { 12118 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 12119 } else if (!strcasecmp(v->name, "callerid")) { 12120 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 12121 } else if (!strcasecmp(v->name, "callgroup")) { 12122 user->callgroup = ast_get_group(v->value); 12123 } else if (!strcasecmp(v->name, "pickupgroup")) { 12124 user->pickupgroup = ast_get_group(v->value); 12125 } else if (!strcasecmp(v->name, "language")) { 12126 ast_copy_string(user->language, v->value, sizeof(user->language)); 12127 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 12128 ast_copy_string(user->musicclass, v->value, sizeof(user->musicclass)); 12129 } else if (!strcasecmp(v->name, "accountcode")) { 12130 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 12131 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 12132 user->call_limit = atoi(v->value); 12133 if (user->call_limit < 0) 12134 user->call_limit = 0; 12135 } else if (!strcasecmp(v->name, "amaflags")) { 12136 format = ast_cdr_amaflags2int(v->value); 12137 if (format < 0) { 12138 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 12139 } else { 12140 user->amaflags = format; 12141 } 12142 } else if (!strcasecmp(v->name, "allow")) { 12143 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 12144 } else if (!strcasecmp(v->name, "disallow")) { 12145 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 12146 } else if (!strcasecmp(v->name, "callingpres")) { 12147 user->callingpres = ast_parse_caller_presentation(v->value); 12148 if (user->callingpres == -1) 12149 user->callingpres = atoi(v->value); 12150 } 12151 /*else if (strcasecmp(v->name,"type")) 12152 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 12153 */ 12154 v = v->next; 12155 } 12156 ast_copy_flags(user, &userflags, mask.flags); 12157 ast_free_ha(oldha); 12158 return user; 12159 }
|
|
build_via: Build a Via header for a request ---
Definition at line 1081 of file chan_sip.c. References ast_inet_ntoa(), ast_test_flag, sip_pvt::branch, sip_pvt::ourip, ourport, SIP_NAT, and SIP_NAT_RFC3581. Referenced by reqprep(), sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), and transmit_register(). 01082 { 01083 char iabuf[INET_ADDRSTRLEN]; 01084 01085 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01086 if (ast_test_flag(p, SIP_NAT) & SIP_NAT_RFC3581) 01087 snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); 01088 else /* Work around buggy UNIDEN UIP200 firmware */ 01089 snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); 01090 }
|
|
cb_extensionstate: Callback for the devicestate notification (SUBSCRIBE) support subsystem ---
Definition at line 6408 of file chan_sip.c. References append_history(), AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_verbose(), sip_pvt::autokillid, sip_pvt::laststate, NONE, option_debug, sip_cancel_destroy(), 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(). 06409 { 06410 struct sip_pvt *p = data; 06411 06412 switch(state) { 06413 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 06414 case AST_EXTENSION_REMOVED: /* Extension is gone */ 06415 if (p->autokillid > -1) 06416 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 06417 sip_scheddestroy(p, 15000); /* Delete subscription in 15 secs */ 06418 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); 06419 p->stateid = -1; 06420 p->subscribed = NONE; 06421 append_history(p, "Subscribestatus", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 06422 break; 06423 default: /* Tell user */ 06424 p->laststate = state; 06425 break; 06426 } 06427 transmit_state_notify(p, state, 1, 1); 06428 06429 if (option_debug > 1) 06430 ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username); 06431 return 0; 06432 }
|
|
check_auth: Check user authorization from peer definition ---
Definition at line 6183 of file chan_sip.c. References ast_log(), ast_md5_hash(), ast_strlen_zero(), ast_test_flag, check_osptoken(), get_header(), global_allowguest, global_realm, LOG_DEBUG, LOG_NOTICE, sip_methods, SIP_OSPAUTH, SIP_OSPAUTH_EXCLUSIVE, SIP_OSPAUTH_GATEWAY, SIP_OSPAUTH_NO, SIP_OSPAUTH_PROXY, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, text, thread_safe_rand(), and transmit_response_with_auth(). Referenced by check_user_full(), and register_verify(). 06184 { 06185 int res = -1; 06186 char *response = "407 Proxy Authentication Required"; 06187 char *reqheader = "Proxy-Authorization"; 06188 char *respheader = "Proxy-Authenticate"; 06189 char *authtoken; 06190 #ifdef OSP_SUPPORT 06191 char *osptoken; 06192 #endif 06193 /* Always OK if no secret */ 06194 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret) 06195 #ifdef OSP_SUPPORT 06196 && !ast_test_flag(p, SIP_OSPAUTH) 06197 && global_allowguest != 2 06198 #endif 06199 ) 06200 return 0; 06201 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 06202 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 06203 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 06204 different circumstances! What a surprise. */ 06205 response = "401 Unauthorized"; 06206 reqheader = "Authorization"; 06207 respheader = "WWW-Authenticate"; 06208 } 06209 #ifdef OSP_SUPPORT 06210 else { 06211 ast_log (LOG_DEBUG, "Checking OSP Authentication!\n"); 06212 osptoken = get_header (req, "P-OSP-Auth-Token"); 06213 switch (ast_test_flag (p, SIP_OSPAUTH)) { 06214 case SIP_OSPAUTH_NO: 06215 break; 06216 case SIP_OSPAUTH_GATEWAY: 06217 if (ast_strlen_zero (osptoken)) { 06218 if (ast_strlen_zero (secret) && ast_strlen_zero (md5secret)) { 06219 return (0); 06220 } 06221 } 06222 else { 06223 return (check_osptoken (p, osptoken)); 06224 } 06225 break; 06226 case SIP_OSPAUTH_PROXY: 06227 if (ast_strlen_zero (osptoken)) { 06228 return (0); 06229 } 06230 else { 06231 return (check_osptoken (p, osptoken)); 06232 } 06233 break; 06234 case SIP_OSPAUTH_EXCLUSIVE: 06235 if (ast_strlen_zero (osptoken)) { 06236 return (-1); 06237 } 06238 else { 06239 return (check_osptoken (p, osptoken)); 06240 } 06241 break; 06242 default: 06243 return (-1); 06244 } 06245 } 06246 #endif 06247 authtoken = get_header(req, reqheader); 06248 if (ignore && !ast_strlen_zero(randdata) && ast_strlen_zero(authtoken)) { 06249 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 06250 information */ 06251 if (!ast_strlen_zero(randdata)) { 06252 if (!reliable) { 06253 /* Resend message if this was NOT a reliable delivery. Otherwise the 06254 retransmission should get it */ 06255 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06256 /* Schedule auto destroy in 15 seconds */ 06257 sip_scheddestroy(p, 15000); 06258 } 06259 res = 1; 06260 } 06261 } else if (ast_strlen_zero(randdata) || ast_strlen_zero(authtoken)) { 06262 snprintf(randdata, randlen, "%08x", thread_safe_rand()); 06263 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06264 /* Schedule auto destroy in 15 seconds */ 06265 sip_scheddestroy(p, 15000); 06266 res = 1; 06267 } else { 06268 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 06269 an example in the spec of just what it is you're doing a hash on. */ 06270 char a1[256]; 06271 char a2[256]; 06272 char a1_hash[256]; 06273 char a2_hash[256]; 06274 char resp[256]; 06275 char resp_hash[256]=""; 06276 char tmp[256]; 06277 char *c; 06278 char *z; 06279 char *ua_hash =""; 06280 char *resp_uri =""; 06281 char *nonce = ""; 06282 char *digestusername = ""; 06283 int wrongnonce = 0; 06284 char *usednonce = randdata; 06285 06286 /* Find their response among the mess that we'r sent for comparison */ 06287 ast_copy_string(tmp, authtoken, sizeof(tmp)); 06288 c = tmp; 06289 06290 while(c) { 06291 c = ast_skip_blanks(c); 06292 if (!*c) 06293 break; 06294 if (!strncasecmp(c, "response=", strlen("response="))) { 06295 c+= strlen("response="); 06296 if ((*c == '\"')) { 06297 ua_hash=++c; 06298 if ((c = strchr(c,'\"'))) 06299 *c = '\0'; 06300 06301 } else { 06302 ua_hash=c; 06303 if ((c = strchr(c,','))) 06304 *c = '\0'; 06305 } 06306 06307 } else if (!strncasecmp(c, "uri=", strlen("uri="))) { 06308 c+= strlen("uri="); 06309 if ((*c == '\"')) { 06310 resp_uri=++c; 06311 if ((c = strchr(c,'\"'))) 06312 *c = '\0'; 06313 } else { 06314 resp_uri=c; 06315 if ((c = strchr(c,','))) 06316 *c = '\0'; 06317 } 06318 06319 } else if (!strncasecmp(c, "username=", strlen("username="))) { 06320 c+= strlen("username="); 06321 if ((*c == '\"')) { 06322 digestusername=++c; 06323 if((c = strchr(c,'\"'))) 06324 *c = '\0'; 06325 } else { 06326 digestusername=c; 06327 if((c = strchr(c,','))) 06328 *c = '\0'; 06329 } 06330 } else if (!strncasecmp(c, "nonce=", strlen("nonce="))) { 06331 c+= strlen("nonce="); 06332 if ((*c == '\"')) { 06333 nonce=++c; 06334 if ((c = strchr(c,'\"'))) 06335 *c = '\0'; 06336 } else { 06337 nonce=c; 06338 if ((c = strchr(c,','))) 06339 *c = '\0'; 06340 } 06341 06342 } else 06343 if ((z = strchr(c,' ')) || (z = strchr(c,','))) c=z; 06344 if (c) 06345 c++; 06346 } 06347 /* Verify that digest username matches the username we auth as */ 06348 if (strcmp(username, digestusername)) { 06349 /* Oops, we're trying something here */ 06350 return -2; 06351 } 06352 06353 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 06354 if (strncasecmp(randdata, nonce, randlen)) { 06355 wrongnonce = 1; 06356 usednonce = nonce; 06357 } 06358 06359 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 06360 06361 if (!ast_strlen_zero(resp_uri)) 06362 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, resp_uri); 06363 else 06364 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, uri); 06365 06366 if (!ast_strlen_zero(md5secret)) 06367 snprintf(a1_hash, sizeof(a1_hash), "%s", md5secret); 06368 else 06369 ast_md5_hash(a1_hash, a1); 06370 06371 ast_md5_hash(a2_hash, a2); 06372 06373 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 06374 ast_md5_hash(resp_hash, resp); 06375 06376 if (wrongnonce) { 06377 06378 snprintf(randdata, randlen, "%08x", thread_safe_rand()); 06379 if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) { 06380 if (sipdebug) 06381 ast_log(LOG_NOTICE, "stale nonce received from '%s'\n", get_header(req, "To")); 06382 /* We got working auth token, based on stale nonce . */ 06383 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 1); 06384 } else { 06385 /* Everything was wrong, so give the device one more try with a new challenge */ 06386 if (sipdebug) 06387 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 06388 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06389 } 06390 06391 /* Schedule auto destroy in 15 seconds */ 06392 sip_scheddestroy(p, 15000); 06393 return 1; 06394 } 06395 /* resp_hash now has the expected response, compare the two */ 06396 if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) { 06397 /* Auth is OK */ 06398 res = 0; 06399 } 06400 } 06401 /* Failure */ 06402 return res; 06403 }
|
|
check_osptoken: Validate OSP token for user authrroization ---
Definition at line 6166 of file chan_sip.c. References ast_osp_validate(), sip_pvt::cid_num, sip_pvt::exten, sip_pvt::owner, pbx_builtin_setvar_helper(), and sip_pvt::sa. Referenced by check_auth(). 06167 { 06168 char tmp[80]; 06169 06170 if (ast_osp_validate (NULL, token, &p->osphandle, &p->osptimelimit, p->cid_num, p->sa.sin_addr, p->exten) < 1) { 06171 return (-1); 06172 } else { 06173 snprintf (tmp, sizeof (tmp), "%d", p->osphandle); 06174 pbx_builtin_setvar_helper (p->owner, "_OSPHANDLE", tmp); 06175 return (0); 06176 } 06177 }
|
|
check_pendings: Check pending actions on SIP call ---
Definition at line 9546 of file chan_sip.c. References ast_clear_flag, ast_log(), ast_set_flag, ast_test_flag, sip_pvt::callid, LOG_DEBUG, SIP_BYE, SIP_CAN_BYE, SIP_CANCEL, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_scheddestroy(), transmit_reinvite_with_sdp(), and transmit_request_with_auth(). Referenced by handle_request(), and handle_response_invite(). 09547 { 09548 if (ast_test_flag(p, SIP_PENDINGBYE)) { 09549 /* if we can't BYE, then this is really a pending CANCEL */ 09550 if (!ast_test_flag(p, SIP_CAN_BYE)) { 09551 transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0); 09552 /* Actually don't destroy us yet, wait for the 487 on our original 09553 INVITE, but do set an autodestruct just in case we never get it. */ 09554 sip_scheddestroy(p, 32000); 09555 } else { 09556 transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); 09557 ast_set_flag(p, SIP_NEEDDESTROY); 09558 ast_clear_flag(p, SIP_NEEDREINVITE); 09559 } 09560 } else if (ast_test_flag(p, SIP_NEEDREINVITE)) { 09561 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 09562 /* Didn't get to reinvite yet, so do it now */ 09563 transmit_reinvite_with_sdp(p); 09564 ast_clear_flag(p, SIP_NEEDREINVITE); 09565 } 09566 }
|
|
check_sip_domain: Check if domain part of uri is local to our server
Definition at line 11933 of file chan_sip.c. References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, list, and result. Referenced by func_check_sipdomain(), get_destination(), and register_verify(). 11934 { 11935 struct domain *d; 11936 int result = 0; 11937 11938 AST_LIST_LOCK(&domain_list); 11939 AST_LIST_TRAVERSE(&domain_list, d, list) { 11940 if (strcasecmp(d->domain, domain)) 11941 continue; 11942 11943 if (len && !ast_strlen_zero(d->context)) 11944 ast_copy_string(context, d->context, len); 11945 11946 result = 1; 11947 break; 11948 } 11949 AST_LIST_UNLOCK(&domain_list); 11950 11951 return result; 11952 }
|
|
check_user: Find user ---
Definition at line 7330 of file chan_sip.c. References check_user_full(). Referenced by handle_request_invite(). 07331 { 07332 return check_user_full(p, req, sipmethod, uri, reliable, sin, ignore, NULL, 0); 07333 }
|
|
check_user_full: Check if matching user or peer is defined ---
Definition at line 7063 of file chan_sip.c. References sip_peer::accountcode, sip_user::accountcode, sip_peer::amaflags, sip_user::amaflags, ast_apply_ha(), ast_copy_flags, ast_inet_ntoa(), ast_log(), AST_RTP_DTMF, ast_rtp_setnat(), ast_set_flag, ast_shrink_phone_number(), ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_variable_new(), ast_verbose(), ASTOBJ_UNREF, build_contact(), sip_peer::call_limit, sip_user::call_limit, sip_peer::callgroup, sip_user::callgroup, sip_peer::callingpres, sip_user::callingpres, sip_pvt::callingpres, sip_peer::capability, sip_user::capability, sip_peer::chanvars, sip_user::chanvars, check_auth(), sip_peer::cid_name, sip_user::cid_name, sip_pvt::cid_name, sip_peer::cid_num, sip_user::cid_num, sip_pvt::cid_num, sip_peer::context, sip_user::context, debug, sip_pvt::exten, find_peer(), find_user(), sip_pvt::from, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), global_allowguest, global_alwaysauthreject, sip_user::ha, sip_peer::language, sip_user::language, sip_peer::lastms, LOG_DEBUG, LOG_NOTICE, sip_peer::mailbox, sip_peer::maxms, sip_peer::md5secret, sip_user::md5secret, sip_user::musicclass, ast_variable::next, sip_pvt::our_contact, pedanticsipchecking, sip_pvt::peermd5secret, sip_pvt::peersecret, sip_peer::pickupgroup, sip_user::pickupgroup, sip_peer::prefs, sip_user::prefs, sip_pvt::randdata, sip_pvt::recv, sip_pvt::rtp, sip_peer::secret, sip_user::secret, SIP_CALL_LIMIT, sip_cancel_destroy(), sip_debug_test_addr(), sip_destroy_peer(), sip_destroy_user(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_INSECURE_INVITE, SIP_NAT, SIP_NAT_ROUTE, SIP_OSPAUTH, SIP_SUBSCRIBE, SIP_TRUSTRPID, sip_peer::sipoptions, sip_pvt::sipoptions, sip_user::sipoptions, sip_peer::subscribecontext, sip_pvt::subscribecontext, sip_user::subscribecontext, t, sip_pvt::timer_t1, user, sip_peer::username, and sip_pvt::vrtp. Referenced by check_user(), and handle_request_subscribe(). 07064 { 07065 struct sip_user *user = NULL; 07066 struct sip_peer *peer; 07067 char *of, from[256], *c; 07068 char *rpid,rpid_num[50]; 07069 char iabuf[INET_ADDRSTRLEN]; 07070 int res = 0; 07071 char *t; 07072 char calleridname[50]; 07073 int debug=sip_debug_test_addr(sin); 07074 struct ast_variable *tmpvar = NULL, *v = NULL; 07075 07076 /* Terminate URI */ 07077 t = uri; 07078 while(*t && (*t > 32) && (*t != ';')) 07079 t++; 07080 *t = '\0'; 07081 of = get_header(req, "From"); 07082 if (pedanticsipchecking) 07083 ast_uri_decode(of); 07084 07085 ast_copy_string(from, of, sizeof(from)); 07086 07087 memset(calleridname,0,sizeof(calleridname)); 07088 get_calleridname(from, calleridname, sizeof(calleridname)); 07089 if (calleridname[0]) 07090 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 07091 07092 rpid = get_header(req, "Remote-Party-ID"); 07093 memset(rpid_num,0,sizeof(rpid_num)); 07094 if (!ast_strlen_zero(rpid)) 07095 p->callingpres = get_rpid_num(rpid,rpid_num, sizeof(rpid_num)); 07096 07097 of = get_in_brackets(from); 07098 if (ast_strlen_zero(p->exten)) { 07099 t = uri; 07100 if (!strncmp(t, "sip:", 4)) 07101 t+= 4; 07102 ast_copy_string(p->exten, t, sizeof(p->exten)); 07103 t = strchr(p->exten, '@'); 07104 if (t) 07105 *t = '\0'; 07106 if (ast_strlen_zero(p->our_contact)) 07107 build_contact(p); 07108 } 07109 /* save the URI part of the From header */ 07110 ast_copy_string(p->from, of, sizeof(p->from)); 07111 if (strncmp(of, "sip:", 4)) { 07112 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07113 } else 07114 of += 4; 07115 /* Get just the username part */ 07116 if ((c = strchr(of, '@'))) { 07117 *c = '\0'; 07118 if ((c = strchr(of, ':'))) 07119 *c = '\0'; 07120 ast_copy_string(p->cid_num, of, sizeof(p->cid_num)); 07121 ast_shrink_phone_number(p->cid_num); 07122 } 07123 if (ast_strlen_zero(of)) 07124 return 0; 07125 07126 if (!mailbox) /* If it's a mailbox SUBSCRIBE, don't check users */ 07127 user = find_user(of, 1); 07128 07129 /* Find user based on user name in the from header */ 07130 if (user && ast_apply_ha(user->ha, sin)) { 07131 ast_copy_flags(p, user, SIP_FLAGS_TO_COPY); 07132 /* copy channel vars */ 07133 for (v = user->chanvars ; v ; v = v->next) { 07134 if ((tmpvar = ast_variable_new(v->name, v->value))) { 07135 tmpvar->next = p->chanvars; 07136 p->chanvars = tmpvar; 07137 } 07138 } 07139 p->prefs = user->prefs; 07140 /* replace callerid if rpid found, and not restricted */ 07141 if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) { 07142 if (*calleridname) 07143 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 07144 ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num)); 07145 ast_shrink_phone_number(p->cid_num); 07146 } 07147 07148 if (p->rtp) { 07149 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07150 ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07151 } 07152 if (p->vrtp) { 07153 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07154 ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07155 } 07156 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), user->name, user->secret, user->md5secret, sipmethod, uri, reliable, ignore))) { 07157 sip_cancel_destroy(p); 07158 ast_copy_flags(p, user, SIP_FLAGS_TO_COPY); 07159 /* Copy SIP extensions profile from INVITE */ 07160 if (p->sipoptions) 07161 user->sipoptions = p->sipoptions; 07162 07163 /* If we have a call limit, set flag */ 07164 if (user->call_limit) 07165 ast_set_flag(p, SIP_CALL_LIMIT); 07166 if (!ast_strlen_zero(user->context)) 07167 ast_copy_string(p->context, user->context, sizeof(p->context)); 07168 if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) { 07169 ast_copy_string(p->cid_num, user->cid_num, sizeof(p->cid_num)); 07170 ast_shrink_phone_number(p->cid_num); 07171 } 07172 if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) 07173 ast_copy_string(p->cid_name, user->cid_name, sizeof(p->cid_name)); 07174 ast_copy_string(p->peername, user->name, sizeof(p->peername)); 07175 ast_copy_string(p->username, user->name, sizeof(p->username)); 07176 ast_copy_string(p->peersecret, user->secret, sizeof(p->peersecret)); 07177 ast_copy_string(p->subscribecontext, user->subscribecontext, sizeof(p->subscribecontext)); 07178 ast_copy_string(p->peermd5secret, user->md5secret, sizeof(p->peermd5secret)); 07179 ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode)); 07180 ast_copy_string(p->language, user->language, sizeof(p->language)); 07181 ast_copy_string(p->musicclass, user->musicclass, sizeof(p->musicclass)); 07182 p->amaflags = user->amaflags; 07183 p->callgroup = user->callgroup; 07184 p->pickupgroup = user->pickupgroup; 07185 p->callingpres = user->callingpres; 07186 p->capability = user->capability; 07187 p->jointcapability = user->capability; 07188 if (p->peercapability) 07189 p->jointcapability &= p->peercapability; 07190 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO)) 07191 p->noncodeccapability |= AST_RTP_DTMF; 07192 else 07193 p->noncodeccapability &= ~AST_RTP_DTMF; 07194 } 07195 if (user && debug) 07196 ast_verbose("Found user '%s'\n", user->name); 07197 } else { 07198 if (user) { 07199 if (!mailbox && debug) 07200 ast_verbose("Found user '%s', but fails host access\n", user->name); 07201 ASTOBJ_UNREF(user,sip_destroy_user); 07202 } 07203 user = NULL; 07204 } 07205 07206 if (!user) { 07207 /* If we didn't find a user match, check for peers */ 07208 if (sipmethod == SIP_SUBSCRIBE) 07209 /* For subscribes, match on peer name only */ 07210 peer = find_peer(of, NULL, 1); 07211 else 07212 /* Look for peer based on the IP address we received data from */ 07213 /* If peer is registered from this IP address or have this as a default 07214 IP address, this call is from the peer 07215 */ 07216 peer = find_peer(NULL, &p->recv, 1); 07217 07218 if (peer) { 07219 if (debug) 07220 ast_verbose("Found peer '%s'\n", peer->name); 07221 /* Take the peer */ 07222 ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY); 07223 07224 /* Copy SIP extensions profile to peer */ 07225 if (p->sipoptions) 07226 peer->sipoptions = p->sipoptions; 07227 07228 /* replace callerid if rpid found, and not restricted */ 07229 if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) { 07230 if (*calleridname) 07231 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 07232 ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num)); 07233 ast_shrink_phone_number(p->cid_num); 07234 } 07235 if (p->rtp) { 07236 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07237 ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07238 } 07239 if (p->vrtp) { 07240 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07241 ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07242 } 07243 ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret)); 07244 p->peersecret[sizeof(p->peersecret)-1] = '\0'; 07245 ast_copy_string(p->subscribecontext, peer->subscribecontext, sizeof(p->subscribecontext)); 07246 ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret)); 07247 p->peermd5secret[sizeof(p->peermd5secret)-1] = '\0'; 07248 p->callingpres = peer->callingpres; 07249 if (peer->maxms && peer->lastms) 07250 p->timer_t1 = peer->lastms; 07251 if (ast_test_flag(peer, SIP_INSECURE_INVITE)) { 07252 /* Pretend there is no required authentication */ 07253 p->peersecret[0] = '\0'; 07254 p->peermd5secret[0] = '\0'; 07255 } 07256 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, p->peersecret, p->peermd5secret, sipmethod, uri, reliable, ignore))) { 07257 ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY); 07258 /* If we have a call limit, set flag */ 07259 if (peer->call_limit) 07260 ast_set_flag(p, SIP_CALL_LIMIT); 07261 ast_copy_string(p->peername, peer->name, sizeof(p->peername)); 07262 ast_copy_string(p->authname, peer->name, sizeof(p->authname)); 07263 /* copy channel vars */ 07264 for (v = peer->chanvars ; v ; v = v->next) { 07265 if ((tmpvar = ast_variable_new(v->name, v->value))) { 07266 tmpvar->next = p->chanvars; 07267 p->chanvars = tmpvar; 07268 } 07269 } 07270 if (mailbox) 07271 snprintf(mailbox, mailboxlen, ",%s,", peer->mailbox); 07272 if (!ast_strlen_zero(peer->username)) { 07273 ast_copy_string(p->username, peer->username, sizeof(p->username)); 07274 /* Use the default username for authentication on outbound calls */ 07275 ast_copy_string(p->authname, peer->username, sizeof(p->authname)); 07276 } 07277 if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) { 07278 ast_copy_string(p->cid_num, peer->cid_num, sizeof(p->cid_num)); 07279 ast_shrink_phone_number(p->cid_num); 07280 } 07281 if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 07282 ast_copy_string(p->cid_name, peer->cid_name, sizeof(p->cid_name)); 07283 ast_copy_string(p->fullcontact, peer->fullcontact, sizeof(p->fullcontact)); 07284 if (!ast_strlen_zero(peer->context)) 07285 ast_copy_string(p->context, peer->context, sizeof(p->context)); 07286 ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret)); 07287 ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret)); 07288 ast_copy_string(p->language, peer->language, sizeof(p->language)); 07289 ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode)); 07290 p->amaflags = peer->amaflags; 07291 p->callgroup = peer->callgroup; 07292 p->pickupgroup = peer->pickupgroup; 07293 p->capability = peer->capability; 07294 p->prefs = peer->prefs; 07295 p->jointcapability = peer->capability; 07296 if (p->peercapability) 07297 p->jointcapability &= p->peercapability; 07298 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO)) 07299 p->noncodeccapability |= AST_RTP_DTMF; 07300 else 07301 p->noncodeccapability &= ~AST_RTP_DTMF; 07302 } 07303 ASTOBJ_UNREF(peer,sip_destroy_peer); 07304 } else { 07305 if (debug) 07306 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); 07307 07308 /* do we allow guests? */ 07309 if (!global_allowguest) { 07310 if (global_alwaysauthreject) 07311 res = -4; /* reject with fake authorization request */ 07312 else 07313 res = -1; /* we don't want any guests, authentication will fail */ 07314 #ifdef OSP_SUPPORT 07315 } else if (global_allowguest == 2) { 07316 ast_copy_flags(p, &global_flags, SIP_OSPAUTH); 07317 res = check_auth(p, req, p->randdata, sizeof(p->randdata), "", "", "", sipmethod, uri, reliable, ignore); 07318 #endif 07319 } 07320 } 07321 07322 } 07323 07324 if (user) 07325 ASTOBJ_UNREF(user,sip_destroy_user); 07326 return res; 07327 }
|
|
check Via: header for hostname, port and rport request/answer
Definition at line 6939 of file chan_sip.c. References ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_test_flag, ast_verbose(), DEFAULT_SIP_PORT, get_header(), hp, LOG_WARNING, sip_debug_test_pvt(), SIP_NAT, and SIP_NAT_ROUTE. Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), and handle_request_subscribe(). 06940 { 06941 char via[256]; 06942 char iabuf[INET_ADDRSTRLEN]; 06943 char *c, *pt; 06944 struct hostent *hp; 06945 struct ast_hostent ahp; 06946 06947 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 06948 06949 /* Check for rport */ 06950 c = strstr(via, ";rport"); 06951 if (c && (c[6] != '=')) /* rport query, not answer */ 06952 ast_set_flag(p, SIP_NAT_ROUTE); 06953 06954 c = strchr(via, ';'); 06955 if (c) 06956 *c = '\0'; 06957 06958 c = strchr(via, ' '); 06959 if (c) { 06960 *c = '\0'; 06961 c = ast_skip_blanks(c+1); 06962 if (strcasecmp(via, "SIP/2.0/UDP")) { 06963 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 06964 return -1; 06965 } 06966 pt = strchr(c, ':'); 06967 if (pt) 06968 *pt++ = '\0'; /* remember port pointer */ 06969 hp = ast_gethostbyname(c, &ahp); 06970 if (!hp) { 06971 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 06972 return -1; 06973 } 06974 memset(&p->sa, 0, sizeof(p->sa)); 06975 p->sa.sin_family = AF_INET; 06976 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 06977 p->sa.sin_port = htons(pt ? atoi(pt) : DEFAULT_SIP_PORT); 06978 06979 if (sip_debug_test_pvt(p)) { 06980 c = (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? "NAT" : "non-NAT"; 06981 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), c); 06982 } 06983 } 06984 return 0; 06985 }
|
|
clear_realm_authentication: Clear realm authentication list (at reload) ---
Definition at line 12034 of file chan_sip.c. References free, and sip_auth::next. Referenced by sip_destroy_peer(), sip_do_reload(), and unload_module(). 12035 { 12036 struct sip_auth *a = authlist; 12037 struct sip_auth *b; 12038 12039 while (a) { 12040 b = a; 12041 a = a->next; 12042 free(b); 12043 } 12044 12045 return 1; 12046 }
|
|
clear_sip_domains: Clear our domain list (at reload)
Definition at line 11955 of file chan_sip.c. References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free, and list. Referenced by sip_do_reload(), and unload_module(). 11956 { 11957 struct domain *d; 11958 11959 AST_LIST_LOCK(&domain_list); 11960 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 11961 free(d); 11962 AST_LIST_UNLOCK(&domain_list); 11963 }
|
|
complete_sip_debug_peer: Support routine for 'sip debug peer' CLI ---
Definition at line 8490 of file chan_sip.c. References complete_sip_peer(). 08491 { 08492 if (pos == 3) 08493 return complete_sip_peer(word, state, 0); 08494 08495 return NULL; 08496 }
|
|
complete_sip_peer: Do completion on peer name ---
Definition at line 8461 of file chan_sip.c. References ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, peerl, result, and strdup. Referenced by complete_sip_debug_peer(), complete_sip_prune_realtime_peer(), complete_sip_show_peer(), and complete_sipnotify(). 08462 { 08463 char *result = NULL; 08464 int wordlen = strlen(word); 08465 int which = 0; 08466 08467 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 08468 /* locking of the object is not required because only the name and flags are being compared */ 08469 if (!strncasecmp(word, iterator->name, wordlen)) { 08470 if (flags2 && !ast_test_flag((&iterator->flags_page2), flags2)) 08471 continue; 08472 if (++which > state) { 08473 result = strdup(iterator->name); 08474 } 08475 } 08476 } while(0) ); 08477 return result; 08478 }
|
|
complete_sip_prune_realtime_peer: Support routine for 'sip prune realtime peer' CLI ---
Definition at line 8561 of file chan_sip.c. References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS. 08562 { 08563 if (pos == 4) 08564 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 08565 return NULL; 08566 }
|
|
complete_sip_prune_realtime_user: Support routine for 'sip prune realtime user' CLI ---
Definition at line 8569 of file chan_sip.c. References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS. 08570 { 08571 if (pos == 4) 08572 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 08573 08574 return NULL; 08575 }
|
|
complete_sip_show_peer: Support routine for 'sip show peer' CLI ---
Definition at line 8481 of file chan_sip.c. References complete_sip_peer(). 08482 { 08483 if (pos == 3) 08484 return complete_sip_peer(word, state, 0); 08485 08486 return NULL; 08487 }
|
|
complete_sip_show_user: Support routine for 'sip show user' CLI ---
Definition at line 8519 of file chan_sip.c. References complete_sip_user(). 08520 { 08521 if (pos == 3) 08522 return complete_sip_user(word, state, 0); 08523 08524 return NULL; 08525 }
|
|
complete_sip_user: Do completion on user name ---
Definition at line 8499 of file chan_sip.c. References ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, result, strdup, and userl. Referenced by complete_sip_prune_realtime_user(), and complete_sip_show_user(). 08500 { 08501 char *result = NULL; 08502 int wordlen = strlen(word); 08503 int which = 0; 08504 08505 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 08506 /* locking of the object is not required because only the name and flags are being compared */ 08507 if (!strncasecmp(word, iterator->name, wordlen)) { 08508 if (flags2 && !ast_test_flag(&(iterator->flags_page2), flags2)) 08509 continue; 08510 if (++which > state) { 08511 result = strdup(iterator->name); 08512 } 08513 } 08514 } while(0) ); 08515 return result; 08516 }
|
|
complete_sipch: Support routine for 'sip show channel' CLI ---
Definition at line 8439 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::callid, iflist, sip_pvt::next, and strdup. 08440 { 08441 int which=0; 08442 struct sip_pvt *cur; 08443 char *c = NULL; 08444 08445 ast_mutex_lock(&iflock); 08446 cur = iflist; 08447 while(cur) { 08448 if (!strncasecmp(word, cur->callid, strlen(word))) { 08449 if (++which > state) { 08450 c = strdup(cur->callid); 08451 break; 08452 } 08453 } 08454 cur = cur->next; 08455 } 08456 ast_mutex_unlock(&iflock); 08457 return c; 08458 }
|
|
complete_sipnotify: Support routine for 'sip notify' CLI ---
Definition at line 8528 of file chan_sip.c. References ast_category_browse(), complete_sip_peer(), notify_types, and strdup. 08529 { 08530 char *c = NULL; 08531 08532 if (pos == 2) { 08533 int which = 0; 08534 char *cat; 08535 08536 /* do completion for notify type */ 08537 08538 if (!notify_types) 08539 return NULL; 08540 08541 cat = ast_category_browse(notify_types, NULL); 08542 while(cat) { 08543 if (!strncasecmp(word, cat, strlen(word))) { 08544 if (++which > state) { 08545 c = strdup(cat); 08546 break; 08547 } 08548 } 08549 cat = ast_category_browse(notify_types, cat); 08550 } 08551 return c; 08552 } 08553 08554 if (pos > 2) 08555 return complete_sip_peer(word, state, 0); 08556 08557 return NULL; 08558 }
|
|
copy_all_header: Copy all headers from one request to another ---
Definition at line 3855 of file chan_sip.c. References __get_header(), add_header(), and ast_strlen_zero(). Referenced by respprep(). 03856 { 03857 char *tmp; 03858 int start = 0; 03859 int copied = 0; 03860 for (;;) { 03861 tmp = __get_header(orig, field, &start); 03862 if (!ast_strlen_zero(tmp)) { 03863 /* Add what we're responding to */ 03864 add_header(req, field, tmp); 03865 copied++; 03866 } else 03867 break; 03868 } 03869 return copied ? 0 : -1; 03870 }
|
|
copy_header: Copy one header field from one request to another
Definition at line 3842 of file chan_sip.c. References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE. Referenced by reqprep(), and respprep(). 03843 { 03844 char *tmp; 03845 tmp = get_header(orig, field); 03846 if (!ast_strlen_zero(tmp)) { 03847 /* Add what we're responding to */ 03848 return add_header(req, field, tmp); 03849 } 03850 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 03851 return -1; 03852 }
|
|
copy_request: copy SIP request (mostly used to save request for responses) ---
Definition at line 4580 of file chan_sip.c. References offset. Referenced by handle_request_bye(), handle_request_invite(), handle_request_register(), handle_request_subscribe(), sip_park(), sip_park_thread(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_sip_request(). 04581 { 04582 long offset; 04583 int x; 04584 offset = ((void *)dst) - ((void *)src); 04585 /* First copy stuff */ 04586 memcpy(dst, src, sizeof(*dst)); 04587 /* Now fix pointer arithmetic */ 04588 for (x=0; x < src->headers; x++) 04589 dst->header[x] += offset; 04590 for (x=0; x < src->lines; x++) 04591 dst->line[x] += offset; 04592 }
|
|
copy_via_headers: Copy SIP VIA Headers from the request to the response ---
Definition at line 3878 of file chan_sip.c. References __get_header(), add_header(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_test_flag, LOG_NOTICE, sip_pvt::recv, SIP_NAT, and SIP_NAT_ALWAYS. Referenced by respprep(). 03879 { 03880 char tmp[256], *oh, *end; 03881 int start = 0; 03882 int copied = 0; 03883 char iabuf[INET_ADDRSTRLEN]; 03884 03885 for (;;) { 03886 oh = __get_header(orig, field, &start); 03887 if (!ast_strlen_zero(oh)) { 03888 if (!copied) { /* Only check for empty rport in topmost via header */ 03889 char *rport; 03890 char new[256]; 03891 03892 /* Find ;rport; (empty request) */ 03893 rport = strstr(oh, ";rport"); 03894 if (rport && *(rport+6) == '=') 03895 rport = NULL; /* We already have a parameter to rport */ 03896 03897 if (rport && (ast_test_flag(p, SIP_NAT) == SIP_NAT_ALWAYS)) { 03898 /* We need to add received port - rport */ 03899 ast_copy_string(tmp, oh, sizeof(tmp)); 03900 03901 rport = strstr(tmp, ";rport"); 03902 03903 if (rport) { 03904 end = strchr(rport + 1, ';'); 03905 if (end) 03906 memmove(rport, end, strlen(end) + 1); 03907 else 03908 *rport = '\0'; 03909 } 03910 03911 /* Add rport to first VIA header if requested */ 03912 /* Whoo hoo! Now we can indicate port address translation too! Just 03913 another RFC (RFC3581). I'll leave the original comments in for 03914 posterity. */ 03915 snprintf(new, sizeof(new), "%s;received=%s;rport=%d", tmp, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); 03916 } else { 03917 /* We should *always* add a received to the topmost via */ 03918 snprintf(new, sizeof(new), "%s;received=%s", oh, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 03919 } 03920 add_header(req, field, new); 03921 } else { 03922 /* Add the following via headers untouched */ 03923 add_header(req, field, oh); 03924 } 03925 copied++; 03926 } else 03927 break; 03928 } 03929 if (!copied) { 03930 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 03931 return -1; 03932 } 03933 return 0; 03934 }
|
|
create_addr: 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 1926 of file chan_sip.c. References ast_get_srv(), ast_gethostbyname(), ast_log(), ASTOBJ_UNREF, create_addr_from_peer(), DEFAULT_SIP_PORT, find_peer(), host, hp, LOG_WARNING, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), srvlookup, sip_pvt::timer_t1, and sip_pvt::tohost. 01927 { 01928 struct hostent *hp; 01929 struct ast_hostent ahp; 01930 struct sip_peer *p; 01931 int found=0; 01932 char *port; 01933 int portno; 01934 char host[MAXHOSTNAMELEN], *hostn; 01935 char peer[256]; 01936 01937 ast_copy_string(peer, opeer, sizeof(peer)); 01938 port = strchr(peer, ':'); 01939 if (port) { 01940 *port = '\0'; 01941 port++; 01942 } 01943 dialog->sa.sin_family = AF_INET; 01944 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 01945 p = find_peer(peer, NULL, 1); 01946 01947 if (p) { 01948 found++; 01949 if (create_addr_from_peer(dialog, p)) 01950 ASTOBJ_UNREF(p, sip_destroy_peer); 01951 } 01952 if (!p) { 01953 if (found) 01954 return -1; 01955 01956 hostn = peer; 01957 if (port) 01958 portno = atoi(port); 01959 else 01960 portno = DEFAULT_SIP_PORT; 01961 if (srvlookup) { 01962 char service[MAXHOSTNAMELEN]; 01963 int tportno; 01964 int ret; 01965 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 01966 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 01967 if (ret > 0) { 01968 hostn = host; 01969 portno = tportno; 01970 } 01971 } 01972 hp = ast_gethostbyname(hostn, &ahp); 01973 if (hp) { 01974 ast_copy_string(dialog->tohost, peer, sizeof(dialog->tohost)); 01975 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 01976 dialog->sa.sin_port = htons(portno); 01977 memcpy(&dialog->recv, &dialog->sa, sizeof(dialog->recv)); 01978 return 0; 01979 } else { 01980 ast_log(LOG_WARNING, "No such host: %s\n", peer); 01981 return -1; 01982 } 01983 } else { 01984 ASTOBJ_UNREF(p, sip_destroy_peer); 01985 return 0; 01986 } 01987 }
|
|
create_addr_from_peer: create address structure from peer reference ---
Definition at line 1850 of file chan_sip.c. References sip_peer::addr, ast_copy_flags, ast_inet_ntoa(), ast_log(), AST_RTP_DTMF, ast_rtp_setnat(), ast_set_flag, ast_strlen_zero(), ast_test_flag, sip_pvt::authname, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, sip_pvt::callid, sip_peer::capability, sip_pvt::capability, sip_peer::context, sip_pvt::context, sip_peer::defaddr, sip_pvt::fromdomain, sip_peer::fromdomain, sip_pvt::fromuser, sip_peer::fromuser, sip_peer::fullcontact, sip_pvt::fullcontact, sip_request::headers, sip_pvt::initreq, sip_peer::lastms, LOG_DEBUG, sip_peer::maxms, sip_pvt::maxtime, sip_peer::md5secret, sip_pvt::noncodeccapability, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::rtpholdtimeout, sip_pvt::rtpholdtimeout, sip_peer::rtpkeepalive, sip_pvt::rtpkeepalive, sip_peer::rtptimeout, sip_pvt::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_pvt::timer_t1, sip_peer::tohost, sip_pvt::tohost, sip_pvt::username, sip_peer::username, and sip_pvt::vrtp. Referenced by create_addr(), and sip_send_mwi_to_peer(). 01851 { 01852 char *callhost; 01853 01854 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 01855 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 01856 if (peer->addr.sin_addr.s_addr) { 01857 r->sa.sin_family = peer->addr.sin_family; 01858 r->sa.sin_addr = peer->addr.sin_addr; 01859 r->sa.sin_port = peer->addr.sin_port; 01860 } else { 01861 r->sa.sin_family = peer->defaddr.sin_family; 01862 r->sa.sin_addr = peer->defaddr.sin_addr; 01863 r->sa.sin_port = peer->defaddr.sin_port; 01864 } 01865 memcpy(&r->recv, &r->sa, sizeof(r->recv)); 01866 } else { 01867 return -1; 01868 } 01869 01870 ast_copy_flags(r, peer, SIP_FLAGS_TO_COPY); 01871 r->capability = peer->capability; 01872 r->prefs = peer->prefs; 01873 if (r->rtp) { 01874 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE)); 01875 ast_rtp_setnat(r->rtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE)); 01876 } 01877 if (r->vrtp) { 01878 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE)); 01879 ast_rtp_setnat(r->vrtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE)); 01880 } 01881 ast_copy_string(r->peername, peer->username, sizeof(r->peername)); 01882 ast_copy_string(r->authname, peer->username, sizeof(r->authname)); 01883 ast_copy_string(r->username, peer->username, sizeof(r->username)); 01884 ast_copy_string(r->peersecret, peer->secret, sizeof(r->peersecret)); 01885 ast_copy_string(r->peermd5secret, peer->md5secret, sizeof(r->peermd5secret)); 01886 ast_copy_string(r->tohost, peer->tohost, sizeof(r->tohost)); 01887 ast_copy_string(r->fullcontact, peer->fullcontact, sizeof(r->fullcontact)); 01888 if (!r->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 01889 if ((callhost = strchr(r->callid, '@'))) { 01890 strncpy(callhost + 1, peer->fromdomain, sizeof(r->callid) - (callhost - r->callid) - 2); 01891 } 01892 } 01893 if (ast_strlen_zero(r->tohost)) { 01894 if (peer->addr.sin_addr.s_addr) 01895 ast_inet_ntoa(r->tohost, sizeof(r->tohost), peer->addr.sin_addr); 01896 else 01897 ast_inet_ntoa(r->tohost, sizeof(r->tohost), peer->defaddr.sin_addr); 01898 } 01899 if (!ast_strlen_zero(peer->fromdomain)) 01900 ast_copy_string(r->fromdomain, peer->fromdomain, sizeof(r->fromdomain)); 01901 if (!ast_strlen_zero(peer->fromuser)) 01902 ast_copy_string(r->fromuser, peer->fromuser, sizeof(r->fromuser)); 01903 r->maxtime = peer->maxms; 01904 r->callgroup = peer->callgroup; 01905 r->pickupgroup = peer->pickupgroup; 01906 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 01907 if (peer->maxms && peer->lastms) 01908 r->timer_t1 = peer->lastms; 01909 if ((ast_test_flag(r, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(r, SIP_DTMF) == SIP_DTMF_AUTO)) 01910 r->noncodeccapability |= AST_RTP_DTMF; 01911 else 01912 r->noncodeccapability &= ~AST_RTP_DTMF; 01913 ast_copy_string(r->context, peer->context,sizeof(r->context)); 01914 r->rtptimeout = peer->rtptimeout; 01915 r->rtpholdtimeout = peer->rtpholdtimeout; 01916 r->rtpkeepalive = peer->rtpkeepalive; 01917 if (peer->call_limit) 01918 ast_set_flag(r, SIP_CALL_LIMIT); 01919 01920 return 0; 01921 }
|
|
Provides a description of the module.
Definition at line 13473 of file chan_sip.c. References desc. 13474 { 13475 return (char *) desc; 13476 }
|
|
Definition at line 5702 of file chan_sip.c. References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_peer::flags_page2, SIP_PAGE2_IGNOREREGEXPIRE, and SIP_PAGE2_RT_FROMCONTACT. Referenced by build_peer(), expire_register(), and parse_register_contact(). 05703 { 05704 if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE)) { 05705 if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) { 05706 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", NULL); 05707 } else { 05708 ast_db_del("SIP/Registry", peer->name); 05709 } 05710 } 05711 }
|
|
determine_firstline_parts: parse first line of incoming SIP request
Definition at line 4615 of file chan_sip.c. References sip_request::header, sip_request::len, sip_request::rlPart1, and sip_request::rlPart2. Referenced by parse_request(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), and transmit_sip_request(). 04616 { 04617 char *e, *cmd; 04618 int len; 04619 04620 cmd = ast_skip_blanks(req->header[0]); 04621 if (!*cmd) 04622 return -1; 04623 req->rlPart1 = cmd; 04624 e = ast_skip_nonblanks(cmd); 04625 /* Get the command */ 04626 if (*e) 04627 *e++ = '\0'; 04628 e = ast_skip_blanks(e); 04629 if ( !*e ) 04630 return -1; 04631 04632 if ( !strcasecmp(cmd, "SIP/2.0") ) { 04633 /* We have a response */ 04634 req->rlPart2 = e; 04635 len = strlen( req->rlPart2 ); 04636 if ( len < 2 ) { 04637 return -1; 04638 } 04639 ast_trim_blanks(e); 04640 } else { 04641 /* We have a request */ 04642 if ( *e == '<' ) { 04643 e++; 04644 if ( !*e ) { 04645 return -1; 04646 } 04647 } 04648 req->rlPart2 = e; /* URI */ 04649 if ( ( e= strrchr( req->rlPart2, 'S' ) ) == NULL ) { 04650 return -1; 04651 } 04652 /* XXX maybe trim_blanks() ? */ 04653 while( isspace( *(--e) ) ) {} 04654 if ( *e == '>' ) { 04655 *e = '\0'; 04656 } else { 04657 *(++e)= '\0'; 04658 } 04659 } 04660 return 1; 04661 }
|
|
do_monitor: The SIP monitoring thread ---
Definition at line 11395 of file chan_sip.c. References __sip_destroy(), ast_channel::_state, ast_io_add(), AST_IO_IN, ast_io_wait(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_rtp_sendcng(), ast_sched_runq(), ast_sched_wait(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, global_mwitime, iflist, sip_pvt::lastrtprx, sip_pvt::lastrtptx, ast_channel::lock, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, ast_channel::name, sip_pvt::next, option_verbose, sip_pvt::owner, sip_pvt::packets, peerl, sip_pvt::redirip, sip_pvt::rtp, sip_pvt::rtpholdtimeout, sip_pvt::rtpkeepalive, sip_pvt::rtptimeout, sip_destroy_peer(), sip_do_reload(), SIP_NEEDDESTROY, sip_reloading, sip_send_mwi_to_peer(), sipsock, sipsock_read(), t, and VERBOSE_PREFIX_1. 11396 { 11397 int res; 11398 struct sip_pvt *sip; 11399 struct sip_peer *peer = NULL; 11400 time_t t; 11401 int fastrestart =0; 11402 int lastpeernum = -1; 11403 int curpeernum; 11404 int reloading; 11405 11406 /* Add an I/O event to our UDP socket */ 11407 if (sipsock > -1) 11408 ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 11409 11410 /* This thread monitors all the frame relay interfaces which are not yet in use 11411 (and thus do not have a separate thread) indefinitely */ 11412 /* From here on out, we die whenever asked */ 11413 for(;;) { 11414 /* Check for a reload request */ 11415 ast_mutex_lock(&sip_reload_lock); 11416 reloading = sip_reloading; 11417 sip_reloading = 0; 11418 ast_mutex_unlock(&sip_reload_lock); 11419 if (reloading) { 11420 if (option_verbose > 0) 11421 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 11422 sip_do_reload(); 11423 } 11424 /* Check for interfaces needing to be killed */ 11425 ast_mutex_lock(&iflock); 11426 restartsearch: 11427 time(&t); 11428 sip = iflist; 11429 while(sip) { 11430 ast_mutex_lock(&sip->lock); 11431 if (sip->rtp && sip->owner && (sip->owner->_state == AST_STATE_UP) && !sip->redirip.sin_addr.s_addr) { 11432 if (sip->lastrtptx && sip->rtpkeepalive && t > sip->lastrtptx + sip->rtpkeepalive) { 11433 /* Need to send an empty RTP packet */ 11434 time(&sip->lastrtptx); 11435 ast_rtp_sendcng(sip->rtp, 0); 11436 } 11437 if (sip->lastrtprx && (sip->rtptimeout || sip->rtpholdtimeout) && t > sip->lastrtprx + sip->rtptimeout) { 11438 /* Might be a timeout now -- see if we're on hold */ 11439 struct sockaddr_in sin; 11440 ast_rtp_get_peer(sip->rtp, &sin); 11441 if (sin.sin_addr.s_addr || 11442 (sip->rtpholdtimeout && 11443 (t > sip->lastrtprx + sip->rtpholdtimeout))) { 11444 /* Needs a hangup */ 11445 if (sip->rtptimeout) { 11446 while(sip->owner && ast_mutex_trylock(&sip->owner->lock)) { 11447 ast_mutex_unlock(&sip->lock); 11448 usleep(1); 11449 ast_mutex_lock(&sip->lock); 11450 } 11451 if (sip->owner) { 11452 ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", sip->owner->name, (long)(t - sip->lastrtprx)); 11453 /* Issue a softhangup */ 11454 ast_softhangup(sip->owner, AST_SOFTHANGUP_DEV); 11455 ast_mutex_unlock(&sip->owner->lock); 11456 } 11457 } 11458 } 11459 } 11460 } 11461 if (ast_test_flag(sip, SIP_NEEDDESTROY) && !sip->packets && !sip->owner) { 11462 ast_mutex_unlock(&sip->lock); 11463 __sip_destroy(sip, 1); 11464 goto restartsearch; 11465 } 11466 ast_mutex_unlock(&sip->lock); 11467 sip = sip->next; 11468 } 11469 ast_mutex_unlock(&iflock); 11470 /* Don't let anybody kill us right away. Nobody should lock the interface list 11471 and wait for the monitor list, but the other way around is okay. */ 11472 ast_mutex_lock(&monlock); 11473 /* Lock the network interface */ 11474 ast_mutex_lock(&netlock); 11475 /* Okay, now that we know what to do, release the network lock */ 11476 ast_mutex_unlock(&netlock); 11477 /* And from now on, we're okay to be killed, so release the monitor lock as well */ 11478 ast_mutex_unlock(&monlock); 11479 pthread_testcancel(); 11480 /* Wait for sched or io */ 11481 res = ast_sched_wait(sched); 11482 if ((res < 0) || (res > 1000)) 11483 res = 1000; 11484 /* If we might need to send more mailboxes, don't wait long at all.*/ 11485 if (fastrestart) 11486 res = 1; 11487 res = ast_io_wait(io, res); 11488 if (res > 20) 11489 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 11490 ast_mutex_lock(&monlock); 11491 if (res >= 0) { 11492 res = ast_sched_runq(sched); 11493 if (res >= 20) 11494 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 11495 } 11496 11497 /* needs work to send mwi to realtime peers */ 11498 time(&t); 11499 fastrestart = 0; 11500 curpeernum = 0; 11501 peer = NULL; 11502 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 11503 if ((curpeernum > lastpeernum) && !ast_strlen_zero(iterator->mailbox) && ((t - iterator->lastmsgcheck) > global_mwitime)) { 11504 fastrestart = 1; 11505 lastpeernum = curpeernum; 11506 peer = ASTOBJ_REF(iterator); 11507 }; 11508 curpeernum++; 11509 } while (0) 11510 ); 11511 if (peer) { 11512 ASTOBJ_WRLOCK(peer); 11513 sip_send_mwi_to_peer(peer); 11514 ASTOBJ_UNLOCK(peer); 11515 ASTOBJ_UNREF(peer,sip_destroy_peer); 11516 } else { 11517 /* Reset where we come from */ 11518 lastpeernum = -1; 11519 } 11520 ast_mutex_unlock(&monlock); 11521 } 11522 /* Never reached */ 11523 return NULL; 11524 11525 }
|
|
do_proxy_auth: Add authentication on outbound SIP packet ---
Definition at line 9001 of file chan_sip.c. References ast_log(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::authtries, calloc, LOG_DEBUG, LOG_ERROR, option_debug, sip_pvt::options, reply_digest(), SIP_INVITE, sip_methods, cfsip_methods::text, and transmit_invite(). Referenced by handle_response(), and handle_response_invite(). 09002 { 09003 char digest[1024]; 09004 09005 if (!p->options) { 09006 p->options = calloc(1, sizeof(*p->options)); 09007 if (!p->options) { 09008 ast_log(LOG_ERROR, "Out of memory\n"); 09009 return -2; 09010 } 09011 } 09012 09013 p->authtries++; 09014 if (option_debug > 1) 09015 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 09016 memset(digest, 0, sizeof(digest)); 09017 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 09018 /* No way to authenticate */ 09019 return -1; 09020 } 09021 /* Now we have a reply digest */ 09022 p->options->auth = digest; 09023 p->options->authheader = respheader; 09024 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 09025 }
|
|
do_register_auth: Authenticate for outbound registration ---
Definition at line 8977 of file chan_sip.c. References append_history(), ast_verbose(), sip_pvt::authtries, sip_registry::hostname, recordhistory, sip_pvt::registry, reply_digest(), sip_debug_test_pvt(), SIP_REGISTER, and transmit_register(). Referenced by handle_response_register(). 08978 { 08979 char digest[1024]; 08980 p->authtries++; 08981 memset(digest,0,sizeof(digest)); 08982 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 08983 /* There's nothing to use for authentication */ 08984 /* No digest challenge in request */ 08985 if (sip_debug_test_pvt(p) && p->registry) 08986 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 08987 /* No old challenge */ 08988 return -1; 08989 } 08990 if (recordhistory) { 08991 char tmp[80]; 08992 snprintf(tmp, sizeof(tmp), "Try: %d", p->authtries); 08993 append_history(p, "RegistryAuth", tmp); 08994 } 08995 if (sip_debug_test_pvt(p) && p->registry) 08996 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 08997 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 08998 }
|
|
Definition at line 7920 of file chan_sip.c. References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG. Referenced by sip_show_domains(). 07921 { 07922 switch (mode) { 07923 case SIP_DOMAIN_AUTO: 07924 return "[Automatic]"; 07925 case SIP_DOMAIN_CONFIG: 07926 return "[Configured]"; 07927 } 07928 07929 return ""; 07930 }
|
|
dtmfmode2str: Convert DTMF mode to printable string ---
Definition at line 7728 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(). 07729 { 07730 switch (mode) { 07731 case SIP_DTMF_RFC2833: 07732 return "rfc2833"; 07733 case SIP_DTMF_INFO: 07734 return "info"; 07735 case SIP_DTMF_INBAND: 07736 return "inband"; 07737 case SIP_DTMF_AUTO: 07738 return "auto"; 07739 } 07740 return "<error>"; 07741 }
|
|
expire_register: Expire registration of SIP peer ---
Definition at line 5714 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, sip_peer::flags_page2, manager_event(), peerl, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, and SIP_SELFDESTRUCT. Referenced by parse_register_contact(), realtime_peer(), and reg_source_db(). 05715 { 05716 struct sip_peer *peer = data; 05717 05718 if (!peer) /* Hmmm. We have no peer. Weird. */ 05719 return 0; 05720 05721 memset(&peer->addr, 0, sizeof(peer->addr)); 05722 05723 destroy_association(peer); 05724 05725 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 05726 register_peer_exten(peer, 0); /* Remove regexten */ 05727 peer->expire = -1; 05728 ast_device_state_changed("SIP/%s", peer->name); 05729 05730 /* Do we need to release this peer from memory? 05731 Only for realtime peers and autocreated peers 05732 */ 05733 if (ast_test_flag(peer, SIP_SELFDESTRUCT) || ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTAUTOCLEAR)) { 05734 peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); /* Remove from peer list */ 05735 ASTOBJ_UNREF(peer, sip_destroy_peer); 05736 } 05737 05738 return 0; 05739 }
|
|
extract_uri: Check Contact: URI of SIP message ---
Definition at line 4693 of file chan_sip.c. References ast_strlen_zero(), get_header(), get_in_brackets(), n, and sip_pvt::uri. Referenced by handle_request(), and handle_request_invite(). 04694 { 04695 char stripped[256]; 04696 char *c, *n; 04697 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 04698 c = get_in_brackets(stripped); 04699 n = strchr(c, ';'); 04700 if (n) 04701 *n = '\0'; 04702 if (!ast_strlen_zero(c)) 04703 ast_copy_string(p->uri, c, sizeof(p->uri)); 04704 }
|
|
Definition at line 2915 of file chan_sip.c. References aliases. 02916 { 02917 int x; 02918 for (x=0;x<sizeof(aliases) / sizeof(aliases[0]); x++) 02919 if (!strcasecmp(aliases[x].fullname, name)) 02920 return aliases[x].shortname; 02921 return _default; 02922 }
|
|
find_call: Connect incoming SIP message to current dialog or create new dialog structure
Definition at line 3147 of file chan_sip.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), sip_pvt::callid, get_header(), gettag(), iflist, sip_pvt::lock, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, pedanticsipchecking, sip_alloc(), sip_methods, SIP_PKT_WITH_TOTAG, SIP_REGISTER, SIP_RESPONSE, sip_pvt::tag, and sip_pvt::theirtag. Referenced by sipsock_read(). 03148 { 03149 struct sip_pvt *p; 03150 char *callid; 03151 char *tag = ""; 03152 char totag[128]; 03153 char fromtag[128]; 03154 03155 callid = get_header(req, "Call-ID"); 03156 03157 if (pedanticsipchecking) { 03158 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 03159 we need more to identify a branch - so we have to check branch, from 03160 and to tags to identify a call leg. 03161 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 03162 in sip.conf 03163 */ 03164 if (gettag(req, "To", totag, sizeof(totag))) 03165 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 03166 gettag(req, "From", fromtag, sizeof(fromtag)); 03167 03168 if (req->method == SIP_RESPONSE) 03169 tag = totag; 03170 else 03171 tag = fromtag; 03172 03173 03174 if (option_debug > 4 ) 03175 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); 03176 } 03177 03178 ast_mutex_lock(&iflock); 03179 p = iflist; 03180 while(p) { /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 03181 int found = 0; 03182 if (req->method == SIP_REGISTER) 03183 found = (!strcmp(p->callid, callid)); 03184 else 03185 found = (!strcmp(p->callid, callid) && 03186 (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ; 03187 03188 if (option_debug > 4) 03189 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); 03190 03191 /* If we get a new request within an existing to-tag - check the to tag as well */ 03192 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 03193 if (p->tag[0] == '\0' && totag[0]) { 03194 /* We have no to tag, but they have. Wrong dialog */ 03195 found = 0; 03196 } else if (totag[0]) { /* Both have tags, compare them */ 03197 if (strcmp(totag, p->tag)) { 03198 found = 0; /* This is not our packet */ 03199 } 03200 } 03201 if (!found && option_debug > 4) 03202 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); 03203 } 03204 03205 03206 if (found) { 03207 /* Found the call */ 03208 ast_mutex_lock(&p->lock); 03209 ast_mutex_unlock(&iflock); 03210 return p; 03211 } 03212 p = p->next; 03213 } 03214 ast_mutex_unlock(&iflock); 03215 p = sip_alloc(callid, sin, 1, intended_method); 03216 if (p) 03217 ast_mutex_lock(&p->lock); 03218 return p; 03219 }
|
|
find_peer: 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 1757 of file chan_sip.c. References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp(). 01758 { 01759 struct sip_peer *p = NULL; 01760 01761 if (peer) 01762 p = ASTOBJ_CONTAINER_FIND(&peerl,peer); 01763 else 01764 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl,sin,name,sip_addr_hashfunc,1,sip_addrcmp); 01765 01766 if (!p && realtime) { 01767 p = realtime_peer(peer, sin); 01768 } 01769 01770 return p; 01771 }
|
|
find_realm_authentication: Find authentication for a specific realm ---
Definition at line 12049 of file chan_sip.c. References sip_auth::next, and sip_auth::realm. Referenced by build_reply_digest(). 12050 { 12051 struct sip_auth *a = authlist; /* First entry in auth list */ 12052 12053 while (a) { 12054 if (!strcasecmp(a->realm, realm)){ 12055 break; 12056 } 12057 a = a->next; 12058 } 12059 12060 return a; 12061 }
|
|
Determine whether a SIP message contains an SDP in its body.
Definition at line 3419 of file chan_sip.c. References ast_strdupa, ast_strlen_zero(), get_header(), sip_request::line, sip_request::lines, sip_request::sdp_end, sip_request::sdp_start, and strcasestr(). Referenced by handle_request(), handle_request_invite(), handle_response(), and handle_response_invite(). 03420 { 03421 char *content_type; 03422 char *search; 03423 char *boundary; 03424 unsigned int x; 03425 03426 content_type = get_header(req, "Content-Type"); 03427 03428 /* if the body contains only SDP, this is easy */ 03429 if (!strcasecmp(content_type, "application/sdp")) { 03430 req->sdp_start = 0; 03431 req->sdp_end = req->lines; 03432 return 1; 03433 } 03434 03435 /* if it's not multipart/mixed, there cannot be an SDP */ 03436 if (strncasecmp(content_type, "multipart/mixed", 15)) 03437 return 0; 03438 03439 /* if there is no boundary marker, it's invalid */ 03440 if (!(search = strcasestr(content_type, ";boundary="))) 03441 return 0; 03442 03443 search += 10; 03444 03445 if (ast_strlen_zero(search)) 03446 return 0; 03447 03448 /* make a duplicate of the string, with two extra characters 03449 at the beginning */ 03450 boundary = ast_strdupa(search - 2); 03451 boundary[0] = boundary[1] = '-'; 03452 03453 /* search for the boundary marker, but stop when there are not enough 03454 lines left for it, the Content-Type header and at least one line of 03455 body */ 03456 for (x = 0; x < (req->lines - 2); x++) { 03457 if (!strncasecmp(req->line[x], boundary, strlen(boundary)) && 03458 !strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) { 03459 req->sdp_start = x + 2; 03460 /* search for the end of the body part */ 03461 for ( ; x < req->lines; x++) { 03462 if (!strncasecmp(req->line[x], boundary, strlen(boundary))) 03463 break; 03464 } 03465 req->sdp_end = x; 03466 return 1; 03467 } 03468 } 03469 03470 return 0; 03471 }
|
|
find_sip_method: Find SIP method from header Strictly speaking, SIP methods are case SENSITIVE, but we don't check following Jon Postel's rule: Be gentle in what you accept, strict with what you send
Definition at line 977 of file chan_sip.c. References ast_strlen_zero(), sip_methods, and text. Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read(). 00978 { 00979 int i, res = 0; 00980 00981 if (ast_strlen_zero(msg)) 00982 return 0; 00983 00984 for (i = 1; (i < (sizeof(sip_methods) / sizeof(sip_methods[0]))) && !res; i++) { 00985 if (!strcasecmp(sip_methods[i].text, msg)) 00986 res = sip_methods[i].id; 00987 } 00988 return res; 00989 }
|
|
find_subscription_type: Find subscription type in array
Definition at line 8364 of file chan_sip.c. References subscription_types, and type. Referenced by transmit_state_notify(). 08364 { 08365 int i; 08366 08367 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 08368 if (subscription_types[i].type == subtype) { 08369 return &subscription_types[i]; 08370 } 08371 } 08372 return &subscription_types[0]; 08373 }
|
|
find_user: 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 1839 of file chan_sip.c. References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl. 01840 { 01841 struct sip_user *u = NULL; 01842 u = ASTOBJ_CONTAINER_FIND(&userl,name); 01843 if (!u && realtime) { 01844 u = realtime_user(name); 01845 } 01846 return u; 01847 }
|
|
free_old_route: Remove route from route list ---
Definition at line 6041 of file chan_sip.c. References free, and sip_route::next. Referenced by __sip_destroy(), and build_route(). 06042 { 06043 struct sip_route *next; 06044 while (route) { 06045 next = route->next; 06046 free(route); 06047 route = next; 06048 } 06049 }
|
|
function_check_sipdomain: Dial plan function to check if domain is local
Definition at line 9318 of file chan_sip.c. References ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING. 09319 { 09320 if (ast_strlen_zero(data)) { 09321 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 09322 return buf; 09323 } 09324 if (check_sip_domain(data, NULL, 0)) 09325 ast_copy_string(buf, data, len); 09326 else 09327 buf[0] = '\0'; 09328 return buf; 09329 }
|
|
func_header_read: Read SIP header (dialplan function)
Definition at line 9271 of file chan_sip.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), channeltype, get_header(), sip_pvt::initreq, ast_channel::lock, LOG_WARNING, ast_channel::tech_pvt, and ast_channel::type. 09272 { 09273 struct sip_pvt *p; 09274 char *content; 09275 09276 if (!data) { 09277 ast_log(LOG_WARNING, "This function requires a header name.\n"); 09278 return NULL; 09279 } 09280 09281 ast_mutex_lock(&chan->lock); 09282 if (chan->type != channeltype) { 09283 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 09284 ast_mutex_unlock(&chan->lock); 09285 return NULL; 09286 } 09287 09288 p = chan->tech_pvt; 09289 09290 /* If there is no private structure, this channel is no longer alive */ 09291 if (!p) { 09292 ast_mutex_unlock(&chan->lock); 09293 return NULL; 09294 } 09295 09296 content = get_header(&p->initreq, data); 09297 09298 if (ast_strlen_zero(content)) { 09299 ast_mutex_unlock(&chan->lock); 09300 return NULL; 09301 } 09302 09303 ast_copy_string(buf, content, len); 09304 ast_mutex_unlock(&chan->lock); 09305 09306 return buf; 09307 }
|
|
function_sipchaninfo_read: ${SIPCHANINFO()} Dialplan function - reads sip channel data
Definition at line 9445 of file chan_sip.c. References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), channeltype, sip_pvt::from, ast_channel::lock, LOG_WARNING, sip_pvt::peername, sip_pvt::recv, sip_pvt::sa, ast_channel::tech_pvt, ast_channel::type, sip_pvt::uri, and sip_pvt::useragent. 09446 { 09447 struct sip_pvt *p; 09448 char iabuf[INET_ADDRSTRLEN]; 09449 09450 *buf = 0; 09451 09452 if (!data) { 09453 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 09454 return NULL; 09455 } 09456 09457 ast_mutex_lock(&chan->lock); 09458 if (chan->type != channeltype) { 09459 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 09460 ast_mutex_unlock(&chan->lock); 09461 return NULL; 09462 } 09463 09464 /* ast_verbose("function_sipchaninfo_read: %s\n", data); */ 09465 p = chan->tech_pvt; 09466 09467 /* If there is no private structure, this channel is no longer alive */ 09468 if (!p) { 09469 ast_mutex_unlock(&chan->lock); 09470 return NULL; 09471 } 09472 09473 if (!strcasecmp(data, "peerip")) { 09474 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr) : "", len); 09475 } else if (!strcasecmp(data, "recvip")) { 09476 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr) : "", len); 09477 } else if (!strcasecmp(data, "from")) { 09478 ast_copy_string(buf, p->from, len); 09479 } else if (!strcasecmp(data, "uri")) { 09480 ast_copy_string(buf, p->uri, len); 09481 } else if (!strcasecmp(data, "useragent")) { 09482 ast_copy_string(buf, p->useragent, len); 09483 } else if (!strcasecmp(data, "peername")) { 09484 ast_copy_string(buf, p->peername, len); 09485 } else { 09486 ast_mutex_unlock(&chan->lock); 09487 return NULL; 09488 } 09489 ast_mutex_unlock(&chan->lock); 09490 09491 return buf; 09492 }
|
|
function_sippeer: ${SIPPEER()} Dialplan function - reads peer data
Definition at line 9344 of file chan_sip.c. References sip_peer::accountcode, sip_peer::addr, ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_log(), ast_strdupa, 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_page2, sip_peer::inUse, sip_peer::language, LOG_ERROR, sip_peer::mailbox, peer_status(), sip_peer::prefs, sip_peer::regexten, sip_destroy_peer(), SIP_PAGE2_DYNAMIC, and sip_peer::useragent. 09345 { 09346 char *ret = NULL; 09347 struct sip_peer *peer; 09348 char *peername, *colname; 09349 char iabuf[INET_ADDRSTRLEN]; 09350 09351 if (!(peername = ast_strdupa(data))) { 09352 ast_log(LOG_ERROR, "Memory Error!\n"); 09353 return ret; 09354 } 09355 09356 if ((colname = strchr(peername, ':'))) { 09357 *colname = '\0'; 09358 colname++; 09359 } else { 09360 colname = "ip"; 09361 } 09362 if (!(peer = find_peer(peername, NULL, 1))) 09363 return ret; 09364 09365 if (!strcasecmp(colname, "ip")) { 09366 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len); 09367 } else if (!strcasecmp(colname, "status")) { 09368 peer_status(peer, buf, len); 09369 } else if (!strcasecmp(colname, "language")) { 09370 ast_copy_string(buf, peer->language, len); 09371 } else if (!strcasecmp(colname, "regexten")) { 09372 ast_copy_string(buf, peer->regexten, len); 09373 } else if (!strcasecmp(colname, "limit")) { 09374 snprintf(buf, len, "%d", peer->call_limit); 09375 } else if (!strcasecmp(colname, "curcalls")) { 09376 snprintf(buf, len, "%d", peer->inUse); 09377 } else if (!strcasecmp(colname, "accountcode")) { 09378 ast_copy_string(buf, peer->accountcode, len); 09379 } else if (!strcasecmp(colname, "useragent")) { 09380 ast_copy_string(buf, peer->useragent, len); 09381 } else if (!strcasecmp(colname, "mailbox")) { 09382 ast_copy_string(buf, peer->mailbox, len); 09383 } else if (!strcasecmp(colname, "context")) { 09384 ast_copy_string(buf, peer->context, len); 09385 } else if (!strcasecmp(colname, "expire")) { 09386 snprintf(buf, len, "%d", peer->expire); 09387 } else if (!strcasecmp(colname, "dynamic")) { 09388 ast_copy_string(buf, (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 09389 } else if (!strcasecmp(colname, "callerid_name")) { 09390 ast_copy_string(buf, peer->cid_name, len); 09391 } else if (!strcasecmp(colname, "callerid_num")) { 09392 ast_copy_string(buf, peer->cid_num, len); 09393 } else if (!strcasecmp(colname, "codecs")) { 09394 ast_getformatname_multiple(buf, len -1, peer->capability); 09395 } else if (!strncasecmp(colname, "codec[", 6)) { 09396 char *codecnum, *ptr; 09397 int index = 0, codec = 0; 09398 09399 codecnum = strchr(colname, '['); 09400 *codecnum = '\0'; 09401 codecnum++; 09402 if ((ptr = strchr(codecnum, ']'))) { 09403 *ptr = '\0'; 09404 } 09405 index = atoi(codecnum); 09406 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 09407 ast_copy_string(buf, ast_getformatname(codec), len); 09408 } 09409 } 09410 ret = buf; 09411 09412 ASTOBJ_UNREF(peer, sip_destroy_peer); 09413 09414 return ret; 09415 }
|
|
get_also_info: Call transfer support (old way, depreciated)--
Definition at line 6897 of file chan_sip.c. References ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_verbose(), get_header(), get_in_brackets(), LOG_DEBUG, LOG_WARNING, and sip_debug_test_pvt(). Referenced by handle_request_bye(). 06898 { 06899 char tmp[256], *c, *a; 06900 struct sip_request *req; 06901 06902 req = oreq; 06903 if (!req) 06904 req = &p->initreq; 06905 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 06906 06907 c = get_in_brackets(tmp); 06908 06909 06910 if (strncmp(c, "sip:", 4)) { 06911 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 06912 return -1; 06913 } 06914 c += 4; 06915 if ((a = strchr(c, '@'))) 06916 *a = '\0'; 06917 if ((a = strchr(c, ';'))) 06918 *a = '\0'; 06919 06920 if (sip_debug_test_pvt(p)) { 06921 ast_verbose("Looking for %s in %s\n", c, p->context); 06922 } 06923 if (ast_exists_extension(NULL, p->context, c, 1, NULL)) { 06924 /* This is an unsupervised transfer */ 06925 ast_log(LOG_DEBUG,"Assigning Extension %s to REFER-TO\n", c); 06926 ast_copy_string(p->refer_to, c, sizeof(p->refer_to)); 06927 ast_copy_string(p->referred_by, "", sizeof(p->referred_by)); 06928 ast_copy_string(p->refer_contact, "", sizeof(p->refer_contact)); 06929 p->refer_call = NULL; 06930 return 0; 06931 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 06932 return 1; 06933 } 06934 06935 return -1; 06936 }
|
|
get_body: get a specific line from the message body
Definition at line 2901 of file chan_sip.c. References get_body_by_line(), and sip_request::line. Referenced by handle_request_info(). 02902 { 02903 int x; 02904 int len = strlen(name); 02905 char *r; 02906 02907 for (x = 0; x < req->lines; x++) { 02908 r = get_body_by_line(req->line[x], name, len); 02909 if (r[0] != '\0') 02910 return r; 02911 } 02912 return ""; 02913 }
|
|
get_body_by_line: Reads one line of message body
Definition at line 2858 of file chan_sip.c. Referenced by get_body(), get_sdp(), and get_sdp_iterate(). 02859 { 02860 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') { 02861 return ast_skip_blanks(line + nameLen + 1); 02862 } 02863 return ""; 02864 }
|
|
get_calleridname: Get caller id name from SIP headers ---
Definition at line 6988 of file chan_sip.c. Referenced by check_user_full(). 06989 { 06990 char *end = strchr(input,'<'); 06991 char *tmp = strchr(input,'\"'); 06992 int bytes = 0; 06993 int maxbytes = outputsize - 1; 06994 06995 if (!end || (end == input)) return NULL; 06996 /* move away from "<" */ 06997 end--; 06998 /* we found "name" */ 06999 if (tmp && tmp < end) { 07000 end = strchr(tmp+1, '\"'); 07001 if (!end) return NULL; 07002 bytes = (int) (end - tmp); 07003 /* protect the output buffer */ 07004 if (bytes > maxbytes) 07005 bytes = maxbytes; 07006 ast_copy_string(output, tmp + 1, bytes); 07007 } else { 07008 /* we didn't find "name" */ 07009 /* clear the empty characters in the begining*/ 07010 input = ast_skip_blanks(input); 07011 /* clear the empty characters in the end */ 07012 while(*end && (*end < 33) && end > input) 07013 end--; 07014 if (end >= input) { 07015 bytes = (int) (end - input) + 2; 07016 /* protect the output buffer */ 07017 if (bytes > maxbytes) { 07018 bytes = maxbytes; 07019 } 07020 ast_copy_string(output, input, bytes); 07021 } 07022 else 07023 return NULL; 07024 } 07025 return output; 07026 }
|
|
get_destination: Find out who the call is for --
Definition at line 6625 of file chan_sip.c. References allow_external_domains, ast_canmatch_extension(), ast_exists_extension(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strlen_zero(), ast_uri_decode(), ast_verbose(), check_sip_domain(), sip_pvt::context, sip_pvt::domain, sip_pvt::exten, sip_pvt::fromdomain, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, sip_request::method, pedanticsipchecking, sip_request::rlPart2, sip_debug_test_pvt(), SIP_INVITE, sip_methods, and SIP_REFER. Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe(). 06626 { 06627 char tmp[256] = "", *uri, *a; 06628 char tmpf[256], *from; 06629 struct sip_request *req; 06630 char *colon; 06631 06632 req = oreq; 06633 if (!req) 06634 req = &p->initreq; 06635 if (req->rlPart2) 06636 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 06637 uri = get_in_brackets(tmp); 06638 06639 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 06640 06641 from = get_in_brackets(tmpf); 06642 06643 if (strncmp(uri, "sip:", 4)) { 06644 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 06645 return -1; 06646 } 06647 uri += 4; 06648 if (!ast_strlen_zero(from)) { 06649 if (strncmp(from, "sip:", 4)) { 06650 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 06651 return -1; 06652 } 06653 from += 4; 06654 } else 06655 from = NULL; 06656 06657 if (pedanticsipchecking) { 06658 ast_uri_decode(uri); 06659 ast_uri_decode(from); 06660 } 06661 06662 /* Skip any options */ 06663 if ((a = strchr(uri, ';'))) { 06664 *a = '\0'; 06665 } 06666 06667 /* Get the target domain */ 06668 if ((a = strchr(uri, '@'))) { 06669 *a = '\0'; 06670 a++; 06671 } else { /* No username part */ 06672 a = uri; 06673 uri = "s"; /* Set extension to "s" */ 06674 } 06675 colon = strchr(a, ':'); /* Remove :port */ 06676 if (colon) 06677 *colon = '\0'; 06678 06679 ast_copy_string(p->domain, a, sizeof(p->domain)); 06680 06681 if (!AST_LIST_EMPTY(&domain_list)) { 06682 char domain_context[AST_MAX_EXTENSION]; 06683 06684 domain_context[0] = '\0'; 06685 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 06686 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 06687 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 06688 return -2; 06689 } 06690 } 06691 /* If we have a context defined, overwrite the original context */ 06692 if (!ast_strlen_zero(domain_context)) 06693 ast_copy_string(p->context, domain_context, sizeof(p->context)); 06694 } 06695 06696 if (from) { 06697 if ((a = strchr(from, ';'))) 06698 *a = '\0'; 06699 if ((a = strchr(from, '@'))) { 06700 *a = '\0'; 06701 ast_copy_string(p->fromdomain, a + 1, sizeof(p->fromdomain)); 06702 } else 06703 ast_copy_string(p->fromdomain, from, sizeof(p->fromdomain)); 06704 } 06705 if (sip_debug_test_pvt(p)) 06706 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 06707 06708 /* Return 0 if we have a matching extension */ 06709 if (ast_exists_extension(NULL, p->context, uri, 1, from) || 06710 !strcmp(uri, ast_pickup_ext())) { 06711 if (!oreq) 06712 ast_copy_string(p->exten, uri, sizeof(p->exten)); 06713 return 0; 06714 } 06715 06716 /* Return 1 for overlap dialling support */ 06717 if (ast_canmatch_extension(NULL, p->context, uri, 1, from) || 06718 !strncmp(uri, ast_pickup_ext(),strlen(uri))) { 06719 return 1; 06720 } 06721 06722 return -1; 06723 }
|
|
get_header: Get header from SIP request ---
Definition at line 2960 of file chan_sip.c. References __get_header(). 02961 { 02962 int start = 0; 02963 return __get_header(req, name, &start); 02964 }
|
|
get_in_brackets: Pick out text in brackets from character string ---
Definition at line 1539 of file chan_sip.c. References ast_log(), 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(). 01540 { 01541 char *parse; 01542 char *first_quote; 01543 char *first_bracket; 01544 char *second_bracket; 01545 char last_char; 01546 01547 parse = tmp; 01548 while (1) { 01549 first_quote = strchr(parse, '"'); 01550 first_bracket = strchr(parse, '<'); 01551 if (first_quote && first_bracket && (first_quote < first_bracket)) { 01552 last_char = '\0'; 01553 for (parse = first_quote + 1; *parse; parse++) { 01554 if ((*parse == '"') && (last_char != '\\')) 01555 break; 01556 last_char = *parse; 01557 } 01558 if (!*parse) { 01559 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 01560 return tmp; 01561 } 01562 parse++; 01563 continue; 01564 } 01565 if (first_bracket) { 01566 second_bracket = strchr(first_bracket + 1, '>'); 01567 if (second_bracket) { 01568 *second_bracket = '\0'; 01569 return first_bracket + 1; 01570 } else { 01571 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 01572 return tmp; 01573 } 01574 } 01575 return tmp; 01576 } 01577 }
|
|
get_msg_text: Get text out of a SIP MESSAGE packet ---
Definition at line 7336 of file chan_sip.c. References sip_request::line. Referenced by receive_message(). 07337 { 07338 int x; 07339 int y; 07340 07341 buf[0] = '\0'; 07342 y = len - strlen(buf) - 5; 07343 if (y < 0) 07344 y = 0; 07345 for (x=0;x<req->lines;x++) { 07346 strncat(buf, req->line[x], y); /* safe */ 07347 y -= strlen(req->line[x]) + 1; 07348 if (y < 0) 07349 y = 0; 07350 if (y != 0) 07351 strcat(buf, "\n"); /* safe */ 07352 } 07353 return 0; 07354 }
|
|
get_rdnis: get referring dnis ---
Definition at line 6597 of file chan_sip.c. References ast_log(), ast_strlen_zero(), ast_verbose(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, sip_pvt::rdnis, and sip_debug_test_pvt(). Referenced by handle_request_invite(). 06598 { 06599 char tmp[256], *c, *a; 06600 struct sip_request *req; 06601 06602 req = oreq; 06603 if (!req) 06604 req = &p->initreq; 06605 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 06606 if (ast_strlen_zero(tmp)) 06607 return 0; 06608 c = get_in_brackets(tmp); 06609 if (strncmp(c, "sip:", 4)) { 06610 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 06611 return -1; 06612 } 06613 c += 4; 06614 if ((a = strchr(c, '@')) || (a = strchr(c, ';'))) { 06615 *a = '\0'; 06616 } 06617 if (sip_debug_test_pvt(p)) 06618 ast_verbose("RDNIS is %s\n", c); 06619 ast_copy_string(p->rdnis, c, sizeof(p->rdnis)); 06620 06621 return 0; 06622 }
|
|
get_refer_info: Call transfer support (the REFER method) ---
Definition at line 6755 of file chan_sip.c. References ast_bridged_channel(), ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_parking_ext(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), sip_pvt::context, get_header(), get_in_brackets(), get_sip_pvt_byid_locked(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::name, sip_pvt::owner, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), pedanticsipchecking, sip_pvt::refer_to, sip_pvt::referred_by, and sip_debug_test_pvt(). Referenced by handle_request_refer(). 06756 { 06757 06758 char *p_refer_to = NULL, *p_referred_by = NULL, *h_refer_to = NULL, *h_referred_by = NULL, *h_contact = NULL; 06759 char *replace_callid = "", *refer_to = NULL, *referred_by = NULL, *ptr = NULL; 06760 struct sip_request *req = NULL; 06761 struct sip_pvt *sip_pvt_ptr = NULL; 06762 struct ast_channel *chan = NULL, *peer = NULL; 06763 const char *transfercontext; 06764 06765 req = outgoing_req; 06766 06767 if (!req) { 06768 req = &sip_pvt->initreq; 06769 } 06770 06771 if (!( (p_refer_to = get_header(req, "Refer-To")) && (h_refer_to = ast_strdupa(p_refer_to)) )) { 06772 ast_log(LOG_WARNING, "No Refer-To Header That's illegal\n"); 06773 return -1; 06774 } 06775 06776 refer_to = get_in_brackets(h_refer_to); 06777 06778 if (!( (p_referred_by = get_header(req, "Referred-By")) && (h_referred_by = ast_strdupa(p_referred_by)) )) { 06779 ast_log(LOG_WARNING, "No Referrred-By Header That's not illegal\n"); 06780 return -1; 06781 } else { 06782 if (pedanticsipchecking) { 06783 ast_uri_decode(h_referred_by); 06784 } 06785 referred_by = get_in_brackets(h_referred_by); 06786 } 06787 h_contact = get_header(req, "Contact"); 06788 06789 if (strncmp(refer_to, "sip:", 4)) { 06790 ast_log(LOG_WARNING, "Refer-to: Huh? Not a SIP header (%s)?\n", refer_to); 06791 return -1; 06792 } 06793 06794 if (strncmp(referred_by, "sip:", 4)) { 06795 ast_log(LOG_WARNING, "Referred-by: Huh? Not a SIP header (%s) Ignoring?\n", referred_by); 06796 referred_by = NULL; 06797 } 06798 06799 if (refer_to) 06800 refer_to += 4; 06801 06802 if (referred_by) 06803 referred_by += 4; 06804 06805 if ((ptr = strchr(refer_to, '?'))) { 06806 /* Search for arguments */ 06807 *ptr = '\0'; 06808 ptr++; 06809 if (!strncasecmp(ptr, "REPLACES=", 9)) { 06810 char *p; 06811 replace_callid = ast_strdupa(ptr + 9); 06812 /* someday soon to support invite/replaces properly! 06813 replaces_header = ast_strdupa(replace_callid); 06814 -anthm 06815 */ 06816 ast_uri_decode(replace_callid); 06817 if ((ptr = strchr(replace_callid, '%'))) 06818 *ptr = '\0'; 06819 if ((ptr = strchr(replace_callid, ';'))) 06820 *ptr = '\0'; 06821 /* Skip leading whitespace XXX memmove behaviour with overlaps ? */ 06822 p = ast_skip_blanks(replace_callid); 06823 if (p != replace_callid) 06824 memmove(replace_callid, p, strlen(p)); 06825 } 06826 } 06827 06828 if ((ptr = strchr(refer_to, '@'))) /* Skip domain (should be saved in SIPDOMAIN) */ 06829 *ptr = '\0'; 06830 if ((ptr = strchr(refer_to, ';'))) 06831 *ptr = '\0'; 06832 06833 if (referred_by) { 06834 if ((ptr = strchr(referred_by, '@'))) 06835 *ptr = '\0'; 06836 if ((ptr = strchr(referred_by, ';'))) 06837 *ptr = '\0'; 06838 } 06839 06840 transfercontext = pbx_builtin_getvar_helper(sip_pvt->owner, "TRANSFER_CONTEXT"); 06841 if (ast_strlen_zero(transfercontext)) 06842 transfercontext = sip_pvt->context; 06843 06844 if (sip_debug_test_pvt(sip_pvt)) { 06845 ast_verbose("Transfer to %s in %s\n", refer_to, transfercontext); 06846 if (referred_by) 06847 ast_verbose("Transfer from %s in %s\n", referred_by, sip_pvt->context); 06848 } 06849 if (!ast_strlen_zero(replace_callid)) { 06850 /* This is a supervised transfer */ 06851 ast_log(LOG_DEBUG,"Assigning Replace-Call-ID Info %s to REPLACE_CALL_ID\n",replace_callid); 06852 06853 ast_copy_string(sip_pvt->refer_to, "", sizeof(sip_pvt->refer_to)); 06854 ast_copy_string(sip_pvt->referred_by, "", sizeof(sip_pvt->referred_by)); 06855 ast_copy_string(sip_pvt->refer_contact, "", sizeof(sip_pvt->refer_contact)); 06856 sip_pvt->refer_call = NULL; 06857 if ((sip_pvt_ptr = get_sip_pvt_byid_locked(replace_callid))) { 06858 sip_pvt->refer_call = sip_pvt_ptr; 06859 if (sip_pvt->refer_call == sip_pvt) { 06860 ast_log(LOG_NOTICE, "Supervised transfer attempted to transfer into same call id (%s == %s)!\n", replace_callid, sip_pvt->callid); 06861 sip_pvt->refer_call = NULL; 06862 } else 06863 return 0; 06864 } else { 06865 ast_log(LOG_NOTICE, "Supervised transfer requested, but unable to find callid '%s'. Both legs must reside on Asterisk box to transfer at this time.\n", replace_callid); 06866 /* XXX The refer_to could contain a call on an entirely different machine, requiring an 06867 INVITE with a replaces header -anthm XXX */ 06868 /* The only way to find out is to use the dialplan - oej */ 06869 } 06870 } else if (ast_exists_extension(NULL, transfercontext, refer_to, 1, NULL) || !strcmp(refer_to, ast_parking_ext())) { 06871 /* This is an unsupervised transfer (blind transfer) */ 06872 06873 ast_log(LOG_DEBUG,"Unsupervised transfer to (Refer-To): %s\n", refer_to); 06874 if (referred_by) 06875 ast_log(LOG_DEBUG,"Transferred by (Referred-by: ) %s \n", referred_by); 06876 ast_log(LOG_DEBUG,"Transfer Contact Info %s (REFER_CONTACT)\n", h_contact); 06877 ast_copy_string(sip_pvt->refer_to, refer_to, sizeof(sip_pvt->refer_to)); 06878 if (referred_by) 06879 ast_copy_string(sip_pvt->referred_by, referred_by, sizeof(sip_pvt->referred_by)); 06880 if (h_contact) { 06881 ast_copy_string(sip_pvt->refer_contact, h_contact, sizeof(sip_pvt->refer_contact)); 06882 } 06883 sip_pvt->refer_call = NULL; 06884 if ((chan = sip_pvt->owner) && (peer = ast_bridged_channel(sip_pvt->owner))) { 06885 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name); 06886 pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", chan->name); 06887 } 06888 return 0; 06889 } else if (ast_canmatch_extension(NULL, transfercontext, refer_to, 1, NULL)) { 06890 return 1; 06891 } 06892 06893 return -1; 06894 }
|
|
get_rpid_num: 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 7032 of file chan_sip.c. References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED. Referenced by check_user_full(). 07033 { 07034 char *start; 07035 char *end; 07036 07037 start = strchr(input,':'); 07038 if (!start) { 07039 output[0] = '\0'; 07040 return 0; 07041 } 07042 start++; 07043 07044 /* we found "number" */ 07045 ast_copy_string(output,start,maxlen); 07046 output[maxlen-1] = '\0'; 07047 07048 end = strchr(output,'@'); 07049 if (end) 07050 *end = '\0'; 07051 else 07052 output[0] = '\0'; 07053 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 07054 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 07055 07056 return 0; 07057 }
|
|
get_sdp: get a specific line from the SDP
Definition at line 2867 of file chan_sip.c. References get_body_by_line(), sip_request::line, and sip_request::sdp_start. 02868 { 02869 int x; 02870 int len = strlen(name); 02871 char *r; 02872 02873 for (x = req->sdp_start; x < req->sdp_end; x++) { 02874 r = get_body_by_line(req->line[x], name, len); 02875 if (r[0] != '\0') 02876 return r; 02877 } 02878 return ""; 02879 }
|
|
Definition at line 2886 of file chan_sip.c. References get_body_by_line(), and sip_request::line. 02888 { 02889 int len = strlen(name); 02890 char *r; 02891 02892 while (*iterator < req->sdp_end) { 02893 r = get_body_by_line(req->line[(*iterator)++], name, len); 02894 if (r[0] != '\0') 02895 return r; 02896 } 02897 return ""; 02898 }
|
|
get_sip_pvt_byid_locked: Lock interface lock and find matching pvt lock ---
Definition at line 6726 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), sip_pvt::callid, iflist, ast_channel::lock, sip_pvt::lock, sip_pvt::next, and sip_pvt::owner. Referenced by get_refer_info(). 06727 { 06728 struct sip_pvt *sip_pvt_ptr = NULL; 06729 06730 /* Search interfaces and find the match */ 06731 ast_mutex_lock(&iflock); 06732 sip_pvt_ptr = iflist; 06733 while(sip_pvt_ptr) { 06734 if (!strcmp(sip_pvt_ptr->callid, callid)) { 06735 /* Go ahead and lock it (and its owner) before returning */ 06736 ast_mutex_lock(&sip_pvt_ptr->lock); 06737 if (sip_pvt_ptr->owner) { 06738 while(ast_mutex_trylock(&sip_pvt_ptr->owner->lock)) { 06739 ast_mutex_unlock(&sip_pvt_ptr->lock); 06740 usleep(1); 06741 ast_mutex_lock(&sip_pvt_ptr->lock); 06742 if (!sip_pvt_ptr->owner) 06743 break; 06744 } 06745 } 06746 break; 06747 } 06748 sip_pvt_ptr = sip_pvt_ptr->next; 06749 } 06750 ast_mutex_unlock(&iflock); 06751 return sip_pvt_ptr; 06752 }
|
|
gettag: Get tag from packet
Definition at line 10344 of file chan_sip.c. References get_header(), and strcasestr(). Referenced by find_call(), handle_request(), and handle_response(). 10345 { 10346 10347 char *thetag, *sep; 10348 10349 10350 if (!tagbuf) 10351 return NULL; 10352 tagbuf[0] = '\0'; /* reset the buffer */ 10353 thetag = get_header(req, header); 10354 thetag = strcasestr(thetag, ";tag="); 10355 if (thetag) { 10356 thetag += 5; 10357 ast_copy_string(tagbuf, thetag, tagbufsize); 10358 sep = strchr(tagbuf, ';'); 10359 if (sep) 10360 *sep = '\0'; 10361 } 10362 return thetag; 10363 }
|
|
handle_common_options: Handle flag-type options common to users and peers ---
Definition at line 11791 of file chan_sip.c. References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), global_allowguest, ast_variable::lineno, LOG_WARNING, ast_variable::name, ast_channel::next, SIP_CAN_REINVITE, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, SIP_OSPAUTH, SIP_OSPAUTH_EXCLUSIVE, SIP_OSPAUTH_GATEWAY, SIP_OSPAUTH_PROXY, SIP_PROG_INBAND, SIP_PROG_INBAND_NO, SIP_PROG_INBAND_YES, SIP_PROMISCREDIR, SIP_REINVITE, SIP_REINVITE_UPDATE, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USECLIENTCODE, strsep(), and ast_variable::value. Referenced by build_peer(), build_user(), and reload_config(). 11792 { 11793 int res = 0; 11794 11795 if (!strcasecmp(v->name, "trustrpid")) { 11796 ast_set_flag(mask, SIP_TRUSTRPID); 11797 ast_set2_flag(flags, ast_true(v->value), SIP_TRUSTRPID); 11798 res = 1; 11799 } else if (!strcasecmp(v->name, "sendrpid")) { 11800 ast_set_flag(mask, SIP_SENDRPID); 11801 ast_set2_flag(flags, ast_true(v->value), SIP_SENDRPID); 11802 res = 1; 11803 } else if (!strcasecmp(v->name, "useclientcode")) { 11804 ast_set_flag(mask, SIP_USECLIENTCODE); 11805 ast_set2_flag(flags, ast_true(v->value), SIP_USECLIENTCODE); 11806 res = 1; 11807 } else if (!strcasecmp(v->name, "dtmfmode")) { 11808 ast_set_flag(mask, SIP_DTMF); 11809 ast_clear_flag(flags, SIP_DTMF); 11810 if (!strcasecmp(v->value, "inband")) 11811 ast_set_flag(flags, SIP_DTMF_INBAND); 11812 else if (!strcasecmp(v->value, "rfc2833")) 11813 ast_set_flag(flags, SIP_DTMF_RFC2833); 11814 else if (!strcasecmp(v->value, "info")) 11815 ast_set_flag(flags, SIP_DTMF_INFO); 11816 else if (!strcasecmp(v->value, "auto")) 11817 ast_set_flag(flags, SIP_DTMF_AUTO); 11818 else { 11819 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 11820 ast_set_flag(flags, SIP_DTMF_RFC2833); 11821 } 11822 } else if (!strcasecmp(v->name, "nat")) { 11823 ast_set_flag(mask, SIP_NAT); 11824 ast_clear_flag(flags, SIP_NAT); 11825 if (!strcasecmp(v->value, "never")) 11826 ast_set_flag(flags, SIP_NAT_NEVER); 11827 else if (!strcasecmp(v->value, "route")) 11828 ast_set_flag(flags, SIP_NAT_ROUTE); 11829 else if (ast_true(v->value)) 11830 ast_set_flag(flags, SIP_NAT_ALWAYS); 11831 else 11832 ast_set_flag(flags, SIP_NAT_RFC3581); 11833 } else if (!strcasecmp(v->name, "canreinvite")) { 11834 ast_set_flag(mask, SIP_REINVITE); 11835 ast_clear_flag(flags, SIP_REINVITE); 11836 if (!strcasecmp(v->value, "update")) 11837 ast_set_flag(flags, SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 11838 else 11839 ast_set2_flag(flags, ast_true(v->value), SIP_CAN_REINVITE); 11840 } else if (!strcasecmp(v->name, "insecure")) { 11841 ast_set_flag(mask, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11842 ast_clear_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11843 if (!strcasecmp(v->value, "very")) 11844 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11845 else if (ast_true(v->value)) 11846 ast_set_flag(flags, SIP_INSECURE_PORT); 11847 else if (!ast_false(v->value)) { 11848 char buf[64]; 11849 char *word, *next; 11850 11851 ast_copy_string(buf, v->value, sizeof(buf)); 11852 next = buf; 11853 while ((word = strsep(&next, ","))) { 11854 if (!strcasecmp(word, "port")) 11855 ast_set_flag(flags, SIP_INSECURE_PORT); 11856 else if (!strcasecmp(word, "invite")) 11857 ast_set_flag(flags, SIP_INSECURE_INVITE); 11858 else 11859 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", v->value, v->lineno); 11860 } 11861 } 11862 } else if (!strcasecmp(v->name, "progressinband")) { 11863 ast_set_flag(mask, SIP_PROG_INBAND); 11864 ast_clear_flag(flags, SIP_PROG_INBAND); 11865 if (ast_true(v->value)) 11866 ast_set_flag(flags, SIP_PROG_INBAND_YES); 11867 else if (strcasecmp(v->value, "never")) 11868 ast_set_flag(flags, SIP_PROG_INBAND_NO); 11869 } else if (!strcasecmp(v->name, "allowguest")) { 11870 #ifdef OSP_SUPPORT 11871 if (!strcasecmp(v->value, "osp")) 11872 global_allowguest = 2; 11873 else 11874 #endif 11875 if (ast_true(v->value)) 11876 global_allowguest = 1; 11877 else 11878 global_allowguest = 0; 11879 #ifdef OSP_SUPPORT 11880 } else if (!strcasecmp(v->name, "ospauth")) { 11881 ast_set_flag(mask, SIP_OSPAUTH); 11882 ast_clear_flag(flags, SIP_OSPAUTH); 11883 if (!strcasecmp(v->value, "proxy")) 11884 ast_set_flag(flags, SIP_OSPAUTH_PROXY); 11885 else if (!strcasecmp(v->value, "gateway")) 11886 ast_set_flag(flags, SIP_OSPAUTH_GATEWAY); 11887 else if(!strcasecmp (v->value, "exclusive")) 11888 ast_set_flag(flags, SIP_OSPAUTH_EXCLUSIVE); 11889 #endif 11890 } else if (!strcasecmp(v->name, "promiscredir")) { 11891 ast_set_flag(mask, SIP_PROMISCREDIR); 11892 ast_set2_flag(flags, ast_true(v->value), SIP_PROMISCREDIR); 11893 res = 1; 11894 } 11895 11896 return res; 11897 }
|
|
handle_request: Handle SIP requests (methods) ---
Definition at line 11056 of file chan_sip.c. References __sip_ack(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, error(), extract_uri(), find_sdp(), FLAG_RESPONSE, get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::header, sip_request::headers, sip_pvt::icseq, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::lastmsg, sip_request::len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_pvt::method, sip_request::method, sip_pvt::ocseq, option_debug, pedanticsipchecking, sip_pvt::pendinginvite, process_sdp(), sip_pvt::randdata, sip_request::rlPart1, sip_request::rlPart2, sip_pvt::sa, SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_debug_test_pvt(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, SIP_SUBSCRIBE, sip_pvt::theirtag, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and sip_pvt::useragent. 11057 { 11058 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 11059 relatively static */ 11060 struct sip_request resp; 11061 char *cmd; 11062 char *cseq; 11063 char *useragent; 11064 int seqno; 11065 int len; 11066 int ignore=0; 11067 int respid; 11068 int res = 0; 11069 char iabuf[INET_ADDRSTRLEN]; 11070 int debug = sip_debug_test_pvt(p); 11071 char *e; 11072 int error = 0; 11073 11074 /* Clear out potential response */ 11075 memset(&resp, 0, sizeof(resp)); 11076 11077 /* Get Method and Cseq */ 11078 cseq = get_header(req, "Cseq"); 11079 cmd = req->header[0]; 11080 11081 /* Must have Cseq */ 11082 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 11083 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 11084 error = 1; 11085 } 11086 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 11087 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 11088 error = 1; 11089 } 11090 if (error) { 11091 if (!p->initreq.header) /* New call */ 11092 ast_set_flag(p, SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 11093 return -1; 11094 } 11095 /* Get the command XXX */ 11096 11097 cmd = req->rlPart1; 11098 e = req->rlPart2; 11099 11100 /* Save useragent of the client */ 11101 useragent = get_header(req, "User-Agent"); 11102 if (!ast_strlen_zero(useragent)) 11103 ast_copy_string(p->useragent, useragent, sizeof(p->useragent)); 11104 11105 /* Find out SIP method for incoming request */ 11106 if (req->method == SIP_RESPONSE) { /* Response to our request */ 11107 /* Response to our request -- Do some sanity checks */ 11108 if (!p->initreq.headers) { 11109 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 11110 ast_set_flag(p, SIP_NEEDDESTROY); 11111 return 0; 11112 } else if (p->ocseq && (p->ocseq < seqno)) { 11113 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 11114 return -1; 11115 } else if (p->ocseq && (p->ocseq != seqno)) { 11116 /* ignore means "don't do anything with it" but still have to 11117 respond appropriately */ 11118 ignore=1; 11119 } 11120 11121 e = ast_skip_blanks(e); 11122 if (sscanf(e, "%d %n", &respid, &len) != 1) { 11123 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 11124 } else { 11125 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 11126 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 11127 extract_uri(p, req); 11128 handle_response(p, respid, e + len, req, ignore, seqno); 11129 } 11130 return 0; 11131 } 11132 11133 /* New SIP request coming in 11134 (could be new request in existing SIP dialog as well...) 11135 */ 11136 11137 p->method = req->method; /* Find out which SIP method they are using */ 11138 if (option_debug > 2) 11139 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 11140 11141 if (p->icseq && (p->icseq > seqno)) { 11142 if (option_debug) 11143 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 11144 if (req->method != SIP_ACK) 11145 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 11146 return -1; 11147 } else if (p->icseq && (p->icseq == seqno) && req->method != SIP_ACK &&(p->method != SIP_CANCEL|| ast_test_flag(p, SIP_ALREADYGONE))) { 11148 /* ignore means "don't do anything with it" but still have to 11149 respond appropriately. We do this if we receive a repeat of 11150 the last sequence number */ 11151 ignore=2; 11152 if (option_debug > 2) 11153 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 11154 } 11155 11156 if (seqno >= p->icseq) 11157 /* Next should follow monotonically (but not necessarily 11158 incrementally -- thanks again to the genius authors of SIP -- 11159 increasing */ 11160 p->icseq = seqno; 11161 11162 /* Find their tag if we haven't got it */ 11163 if (ast_strlen_zero(p->theirtag)) { 11164 gettag(req, "From", p->theirtag, sizeof(p->theirtag)); 11165 } 11166 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 11167 11168 if (pedanticsipchecking) { 11169 /* If this is a request packet without a from tag, it's not 11170 correct according to RFC 3261 */ 11171 /* Check if this a new request in a new dialog with a totag already attached to it, 11172 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 11173 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 11174 /* If this is a first request and it got a to-tag, it is not for us */ 11175 if (!ignore && req->method == SIP_INVITE) { 11176 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req, 1); 11177 /* Will cease to exist after ACK */ 11178 } else if (req->method != SIP_ACK) { 11179 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 11180 ast_set_flag(p, SIP_NEEDDESTROY); 11181 } 11182 return res; 11183 } 11184 } 11185 11186 /* Handle various incoming SIP methods in requests */ 11187 switch (p->method) { 11188 case SIP_OPTIONS: 11189 res = handle_request_options(p, req, debug); 11190 break; 11191 case SIP_INVITE: 11192 res = handle_request_invite(p, req, debug, ignore, seqno, sin, recount, e); 11193 break; 11194 case SIP_REFER: 11195 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 11196 break; 11197 case SIP_CANCEL: 11198 res = handle_request_cancel(p, req, debug, ignore); 11199 break; 11200 case SIP_BYE: 11201 res = handle_request_bye(p, req, debug, ignore); 11202 break; 11203 case SIP_MESSAGE: 11204 res = handle_request_message(p, req, debug, ignore); 11205 break; 11206 case SIP_SUBSCRIBE: 11207 res = handle_request_subscribe(p, req, debug, ignore, sin, seqno, e); 11208 break; 11209 case SIP_REGISTER: 11210 res = handle_request_register(p, req, debug, ignore, sin, e); 11211 break; 11212 case SIP_INFO: 11213 if (!ignore) { 11214 if (debug) 11215 ast_verbose("Receiving INFO!\n"); 11216 handle_request_info(p, req); 11217 } else { /* if ignoring, transmit response */ 11218 transmit_response(p, "200 OK", req); 11219 } 11220 break; 11221 case SIP_NOTIFY: 11222 /* XXX we get NOTIFY's from some servers. WHY?? Maybe we should 11223 look into this someday XXX */ 11224 transmit_response(p, "200 OK", req); 11225 if (!p->lastinvite) 11226 ast_set_flag(p, SIP_NEEDDESTROY); 11227 break; 11228 case SIP_ACK: 11229 /* Make sure we don't ignore this */ 11230 if (seqno == p->pendinginvite) { 11231 p->pendinginvite = 0; 11232 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 11233 if (find_sdp(req)) { 11234 if (process_sdp(p, req)) 11235 return -1; 11236 } 11237 check_pendings(p); 11238 } 11239 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 11240 ast_set_flag(p, SIP_NEEDDESTROY); 11241 break; 11242 default: 11243 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 11244 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 11245 cmd, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); 11246 /* If this is some new method, and we don't have a call, destroy it now */ 11247 if (!p->initreq.headers) 11248 ast_set_flag(p, SIP_NEEDDESTROY); 11249 break; 11250 } 11251 return res; 11252 }
|
|
handle_request_bye: Handle incoming BYE request ---
Definition at line 10752 of file chan_sip.c. References ast_async_goto(), ast_bridged_channel(), ast_inet_ntoa(), ast_log(), ast_moh_stop(), ast_queue_hangup(), ast_rtp_stop(), ast_set_flag, ast_strlen_zero(), ast_test_flag, check_via(), copy_request(), default_context, get_also_info(), get_header(), sip_pvt::initreq, LOG_NOTICE, LOG_WARNING, sip_pvt::pendinginvite, SIP_ALREADYGONE, SIP_NEEDDESTROY, SIP_OUTGOING, transmit_response(), and transmit_response_reliable(). Referenced by handle_request(). 10753 { 10754 struct ast_channel *c=NULL; 10755 int res; 10756 struct ast_channel *bridged_to; 10757 char iabuf[INET_ADDRSTRLEN]; 10758 10759 if (p->pendinginvite && !ast_test_flag(p, SIP_OUTGOING) && !ignore) 10760 transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1); 10761 10762 copy_request(&p->initreq, req); 10763 check_via(p, req); 10764 ast_set_flag(p, SIP_ALREADYGONE); 10765 if (p->rtp) { 10766 /* Immediately stop RTP */ 10767 ast_rtp_stop(p->rtp); 10768 } 10769 if (p->vrtp) { 10770 /* Immediately stop VRTP */ 10771 ast_rtp_stop(p->vrtp); 10772 } 10773 if (!ast_strlen_zero(get_header(req, "Also"))) { 10774 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 10775 ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 10776 if (ast_strlen_zero(p->context)) 10777 strcpy(p->context, default_context); 10778 res = get_also_info(p, req); 10779 if (!res) { 10780 c = p->owner; 10781 if (c) { 10782 bridged_to = ast_bridged_channel(c); 10783 if (bridged_to) { 10784 /* Don't actually hangup here... */ 10785 ast_moh_stop(bridged_to); 10786 ast_async_goto(bridged_to, p->context, p->refer_to,1); 10787 } else 10788 ast_queue_hangup(p->owner); 10789 } 10790 } else { 10791 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 10792 if (p->owner) 10793 ast_queue_hangup(p->owner); 10794 } 10795 } else if (p->owner) 10796 ast_queue_hangup(p->owner); 10797 else 10798 ast_set_flag(p, SIP_NEEDDESTROY); 10799 transmit_response(p, "200 OK", req); 10800 10801 return 1; 10802 }
|
|
handle_request_cancel: Handle incoming CANCEL request ---
Definition at line 10723 of file chan_sip.c. References ast_queue_hangup(), ast_rtp_stop(), ast_set_flag, check_via(), sip_pvt::initreq, sip_request::len, sip_pvt::owner, sip_pvt::rtp, SIP_ALREADYGONE, SIP_NEEDDESTROY, transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp. Referenced by handle_request(). 10724 { 10725 10726 check_via(p, req); 10727 ast_set_flag(p, SIP_ALREADYGONE); 10728 if (p->rtp) { 10729 /* Immediately stop RTP */ 10730 ast_rtp_stop(p->rtp); 10731 } 10732 if (p->vrtp) { 10733 /* Immediately stop VRTP */ 10734 ast_rtp_stop(p->vrtp); 10735 } 10736 if (p->owner) 10737 ast_queue_hangup(p->owner); 10738 else 10739 ast_set_flag(p, SIP_NEEDDESTROY); 10740 if (p->initreq.len > 0) { 10741 if (!ignore) 10742 transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1); 10743 transmit_response(p, "200 OK", req); 10744 return 1; 10745 } else { 10746 transmit_response(p, "481 Call Leg Does Not Exist", req); 10747 return 0; 10748 } 10749 }
|
|
handle_request_info: Receive SIP INFO Message ---
Definition at line 8717 of file chan_sip.c. References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), ast_queue_control(), ast_queue_frame(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_pvt::callid, ast_channel::cdr, sip_history::event, get_body(), get_header(), LOG_WARNING, sip_pvt::owner, SIP_NEEDDESTROY, SIP_USECLIENTCODE, sipdebug, ast_frame::subclass, and transmit_response(). Referenced by handle_request(). 08718 { 08719 char buf[1024]; 08720 unsigned int event; 08721 char *c; 08722 08723 /* Need to check the media/type */ 08724 if (!strcasecmp(get_header(req, "Content-Type"), "application/dtmf-relay") || 08725 !strcasecmp(get_header(req, "Content-Type"), "application/vnd.nortelnetworks.digits")) { 08726 08727 /* Try getting the "signal=" part */ 08728 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 08729 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 08730 transmit_response(p, "200 OK", req); /* Should return error */ 08731 return; 08732 } else { 08733 ast_copy_string(buf, c, sizeof(buf)); 08734 } 08735 08736 if (!p->owner) { /* not a PBX call */ 08737 transmit_response(p, "481 Call leg/transaction does not exist", req); 08738 ast_set_flag(p, SIP_NEEDDESTROY); 08739 return; 08740 } 08741 08742 if (ast_strlen_zero(buf)) { 08743 transmit_response(p, "200 OK", req); 08744 return; 08745 } 08746 08747 if (buf[0] == '*') 08748 event = 10; 08749 else if (buf[0] == '#') 08750 event = 11; 08751 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 08752 event = 12 + buf[0] - 'A'; 08753 else 08754 event = atoi(buf); 08755 if (event == 16) { 08756 /* send a FLASH event */ 08757 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 08758 ast_queue_frame(p->owner, &f); 08759 if (sipdebug) 08760 ast_verbose("* DTMF-relay event received: FLASH\n"); 08761 } else { 08762 /* send a DTMF event */ 08763 struct ast_frame f = { AST_FRAME_DTMF, }; 08764 if (event < 10) { 08765 f.subclass = '0' + event; 08766 } else if (event < 11) { 08767 f.subclass = '*'; 08768 } else if (event < 12) { 08769 f.subclass = '#'; 08770 } else if (event < 16) { 08771 f.subclass = 'A' + (event - 12); 08772 } 08773 ast_queue_frame(p->owner, &f); 08774 if (sipdebug) 08775 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 08776 } 08777 transmit_response(p, "200 OK", req); 08778 return; 08779 } else if (!strcasecmp(get_header(req, "Content-Type"), "application/media_control+xml")) { 08780 /* Eh, we'll just assume it's a fast picture update for now */ 08781 if (p->owner) 08782 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 08783 transmit_response(p, "200 OK", req); 08784 return; 08785 } else if ((c = get_header(req, "X-ClientCode"))) { 08786 /* Client code (from SNOM phone) */ 08787 if (ast_test_flag(p, SIP_USECLIENTCODE)) { 08788 if (p->owner && p->owner->cdr) 08789 ast_cdr_setuserfield(p->owner, c); 08790 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 08791 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 08792 transmit_response(p, "200 OK", req); 08793 } else { 08794 transmit_response(p, "403 Unauthorized", req); 08795 } 08796 return; 08797 } 08798 /* Other type of INFO message, not really understood by Asterisk */ 08799 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 08800 08801 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 08802 transmit_response(p, "415 Unsupported media type", req); 08803 return; 08804 }
|
|
handle_request_invite: Handle incoming INVITE request
Definition at line 10390 of file chan_sip.c. References ast_channel::_state, ast_channel_setwhentohangup(), ast_clear_flag, AST_FRAME_NULL, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_call(), ast_pickup_ext(), ast_queue_frame(), ast_set_flag, ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_verbose(), build_contact(), build_route(), sip_pvt::callid, sip_pvt::capability, check_user(), check_via(), sip_pvt::context, copy_request(), DEC_CALL_LIMIT, default_context, sip_pvt::exten, extract_uri(), find_sdp(), get_destination(), get_header(), get_rdnis(), INC_CALL_LIMIT, sip_pvt::initreq, sip_pvt::jointcapability, sip_pvt::lastinvite, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), option_debug, sip_pvt::owner, parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::randdata, SIP_ALREADYGONE, sip_cancel_destroy(), SIP_INVITE, SIP_NEEDDESTROY, sip_new(), SIP_OUTGOING, sipdebug, sip_pvt::sipoptions, sip_pvt::tag, sip_pvt::theirtag, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_unsupported(), update_call_counter(), and sip_pvt::username. Referenced by handle_request(). 10391 { 10392 int res = 1; 10393 struct ast_channel *c=NULL; 10394 int gotdest; 10395 struct ast_frame af = { AST_FRAME_NULL, }; 10396 char *supported; 10397 char *required; 10398 unsigned int required_profile = 0; 10399 10400 /* Find out what they support */ 10401 if (!p->sipoptions) { 10402 supported = get_header(req, "Supported"); 10403 if (supported) 10404 parse_sip_options(p, supported); 10405 } 10406 required = get_header(req, "Require"); 10407 if (!ast_strlen_zero(required)) { 10408 required_profile = parse_sip_options(NULL, required); 10409 if (required_profile) { /* They require something */ 10410 /* At this point we support no extensions, so fail */ 10411 transmit_response_with_unsupported(p, "420 Bad extension", req, required); 10412 if (!p->lastinvite) 10413 ast_set_flag(p, SIP_NEEDDESTROY); 10414 return -1; 10415 10416 } 10417 } 10418 10419 /* Check if this is a loop */ 10420 /* This happens since we do not properly support SIP domain 10421 handling yet... -oej */ 10422 if (ast_test_flag(p, SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 10423 /* This is a call to ourself. Send ourselves an error code and stop 10424 processing immediately, as SIP really has no good mechanism for 10425 being able to call yourself */ 10426 transmit_response(p, "482 Loop Detected", req); 10427 /* We do NOT destroy p here, so that our response will be accepted */ 10428 return 0; 10429 } 10430 if (!ignore) { 10431 /* Use this as the basis */ 10432 if (debug) 10433 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 10434 sip_cancel_destroy(p); 10435 /* This call is no longer outgoing if it ever was */ 10436 ast_clear_flag(p, SIP_OUTGOING); 10437 /* This also counts as a pending invite */ 10438 p->pendinginvite = seqno; 10439 copy_request(&p->initreq, req); 10440 check_via(p, req); 10441 if (p->owner) { 10442 /* Handle SDP here if we already have an owner */ 10443 if (find_sdp(req)) { 10444 if (process_sdp(p, req)) { 10445 transmit_response(p, "488 Not acceptable here", req); 10446 if (!p->lastinvite) 10447 ast_set_flag(p, SIP_NEEDDESTROY); 10448 return -1; 10449 } 10450 } else { 10451 p->jointcapability = p->capability; 10452 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 10453 } 10454 } 10455 } else if (debug) 10456 ast_verbose("Ignoring this INVITE request\n"); 10457 if (!p->lastinvite && !ignore && !p->owner) { 10458 /* Handle authentication if this is our first invite */ 10459 res = check_user(p, req, SIP_INVITE, e, 1, sin, ignore); 10460 /* if an authentication challenge was sent, we are done here */ 10461 if (res > 0) 10462 return 0; 10463 if (res < 0) { 10464 if (res == -4) { 10465 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 10466 transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1); 10467 } else { 10468 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 10469 if (ignore) 10470 transmit_response(p, "403 Forbidden", req); 10471 else 10472 transmit_response_reliable(p, "403 Forbidden", req, 1); 10473 } 10474 ast_set_flag(p, SIP_NEEDDESTROY); 10475 p->theirtag[0] = '\0'; /* Forget their to-tag, we'll get a new one */ 10476 return 0; 10477 } 10478 /* Process the SDP portion */ 10479 if (find_sdp(req)) { 10480 if (process_sdp(p, req)) { 10481 transmit_response(p, "488 Not acceptable here", req); 10482 ast_set_flag(p, SIP_NEEDDESTROY); 10483 return -1; 10484 } 10485 } else { 10486 p->jointcapability = p->capability; 10487 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 10488 } 10489 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 10490 if (p->owner) 10491 ast_queue_frame(p->owner, &af); 10492 /* Initialize the context if it hasn't been already */ 10493 if (ast_strlen_zero(p->context)) 10494 strcpy(p->context, default_context); 10495 /* Check number of concurrent calls -vs- incoming limit HERE */ 10496 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 10497 res = update_call_counter(p, INC_CALL_LIMIT); 10498 if (res) { 10499 if (res < 0) { 10500 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 10501 if (ignore) 10502 transmit_response(p, "480 Temporarily Unavailable (Call limit)", req); 10503 else 10504 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req, 1); 10505 ast_set_flag(p, SIP_NEEDDESTROY); 10506 } 10507 return 0; 10508 } 10509 /* Get destination right away */ 10510 gotdest = get_destination(p, NULL); 10511 10512 get_rdnis(p, NULL); 10513 extract_uri(p, req); 10514 build_contact(p); 10515 10516 if (gotdest) { 10517 if (gotdest < 0) { 10518 if (ignore) 10519 transmit_response(p, "404 Not Found", req); 10520 else 10521 transmit_response_reliable(p, "404 Not Found", req, 1); 10522 update_call_counter(p, DEC_CALL_LIMIT); 10523 } else { 10524 if (ignore) 10525 transmit_response(p, "484 Address Incomplete", req); 10526 else 10527 transmit_response_reliable(p, "484 Address Incomplete", req, 1); 10528 update_call_counter(p, DEC_CALL_LIMIT); 10529 } 10530 ast_set_flag(p, SIP_NEEDDESTROY); 10531 } else { 10532 /* If no extension was specified, use the s one */ 10533 if (ast_strlen_zero(p->exten)) 10534 ast_copy_string(p->exten, "s", sizeof(p->exten)); 10535 /* Initialize tag */ 10536 make_our_tag(p->tag, sizeof(p->tag)); 10537 /* First invitation */ 10538 c = sip_new(p, AST_STATE_DOWN, ast_strlen_zero(p->username) ? NULL : p->username ); 10539 *recount = 1; 10540 /* Save Record-Route for any later requests we make on this dialogue */ 10541 build_route(p, req, 0); 10542 if (c) { 10543 /* Pre-lock the call */ 10544 ast_mutex_lock(&c->lock); 10545 } 10546 } 10547 10548 } else { 10549 if (option_debug > 1 && sipdebug) 10550 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 10551 c = p->owner; 10552 } 10553 if (!ignore && p) 10554 p->lastinvite = seqno; 10555 if (c) { 10556 #ifdef OSP_SUPPORT 10557 ast_channel_setwhentohangup (c, p->osptimelimit); 10558 #endif 10559 switch(c->_state) { 10560 case AST_STATE_DOWN: 10561 transmit_response(p, "100 Trying", req); 10562 ast_setstate(c, AST_STATE_RING); 10563 if (strcmp(p->exten, ast_pickup_ext())) { 10564 enum ast_pbx_result res; 10565 10566 res = ast_pbx_start(c); 10567 10568 switch (res) { 10569 case AST_PBX_FAILED: 10570 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 10571 if (ignore) 10572 transmit_response(p, "503 Unavailable", req); 10573 else 10574 transmit_response_reliable(p, "503 Unavailable", req, 1); 10575 break; 10576 case AST_PBX_CALL_LIMIT: 10577 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 10578 if (ignore) 10579 transmit_response(p, "480 Temporarily Unavailable", req); 10580 else 10581 transmit_response_reliable(p, "480 Temporarily Unavailable", req, 1); 10582 break; 10583 case AST_PBX_SUCCESS: 10584 /* nothing to do */ 10585 break; 10586 } 10587 10588 if (res) { 10589 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 10590 /* Unlock locks so ast_hangup can do its magic */ 10591 ast_mutex_unlock(&c->lock); 10592 ast_mutex_unlock(&p->lock); 10593 ast_hangup(c); 10594 ast_mutex_lock(&p->lock); 10595 c = NULL; 10596 } 10597 } else { 10598 ast_mutex_unlock(&c->lock); 10599 if (ast_pickup_call(c)) { 10600 ast_log(LOG_NOTICE, "Nothing to pick up\n"); 10601 if (ignore) 10602 transmit_response(p, "503 Unavailable", req); 10603 else 10604 transmit_response_reliable(p, "503 Unavailable", req, 1); 10605 ast_set_flag(p, SIP_ALREADYGONE); 10606 /* Unlock locks so ast_hangup can do its magic */ 10607 ast_mutex_unlock(&p->lock); 10608 ast_hangup(c); 10609 ast_mutex_lock(&p->lock); 10610 c = NULL; 10611 } else { 10612 ast_mutex_unlock(&p->lock); 10613 ast_setstate(c, AST_STATE_DOWN); 10614 ast_hangup(c); 10615 ast_mutex_lock(&p->lock); 10616 c = NULL; 10617 } 10618 } 10619 break; 10620 case AST_STATE_RING: 10621 transmit_response(p, "100 Trying", req); 10622 break; 10623 case AST_STATE_RINGING: 10624 transmit_response(p, "180 Ringing", req); 10625 break; 10626 case AST_STATE_UP: 10627 transmit_response_with_sdp(p, "200 OK", req, 1); 10628 break; 10629 default: 10630 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 10631 transmit_response(p, "100 Trying", req); 10632 } 10633 } else { 10634 if (p && !ast_test_flag(p, SIP_NEEDDESTROY) && !ignore) { 10635 if (!p->jointcapability) { 10636 if (ignore) 10637 transmit_response(p, "488 Not Acceptable Here (codec error)", req); 10638 else 10639 transmit_response_reliable(p, "488 Not Acceptable Here (codec error)", req, 1); 10640 ast_set_flag(p, SIP_NEEDDESTROY); 10641 } else { 10642 ast_log(LOG_NOTICE, "Unable to create/find channel\n"); 10643 if (ignore) 10644 transmit_response(p, "503 Unavailable", req); 10645 else 10646 transmit_response_reliable(p, "503 Unavailable", req, 1); 10647 ast_set_flag(p, SIP_NEEDDESTROY); 10648 } 10649 } 10650 } 10651 return res; 10652 }
|
|
handle_request_message: Handle incoming MESSAGE request ---
Definition at line 10805 of file chan_sip.c. References ast_verbose(), receive_message(), and transmit_response(). Referenced by handle_request(). 10806 { 10807 if (!ignore) { 10808 if (debug) 10809 ast_verbose("Receiving message!\n"); 10810 receive_message(p, req); 10811 } else { 10812 transmit_response(p, "202 Accepted", req); 10813 } 10814 return 1; 10815 }
|
|
handle_request_options: Handle incoming OPTIONS request
Definition at line 10366 of file chan_sip.c. References ast_set_flag, ast_strlen_zero(), build_contact(), default_context, get_destination(), SIP_NEEDDESTROY, and transmit_response_with_allow(). Referenced by handle_request(). 10367 { 10368 int res; 10369 10370 res = get_destination(p, req); 10371 build_contact(p); 10372 /* XXX Should we authenticate OPTIONS? XXX */ 10373 if (ast_strlen_zero(p->context)) 10374 strcpy(p->context, default_context); 10375 if (res < 0) 10376 transmit_response_with_allow(p, "404 Not Found", req, 0); 10377 else if (res > 0) 10378 transmit_response_with_allow(p, "484 Address Incomplete", req, 0); 10379 else 10380 transmit_response_with_allow(p, "200 OK", req, 0); 10381 /* Destroy if this OPTIONS was the opening request, but not if 10382 it's in the middle of a normal call flow. */ 10383 if (!p->lastinvite) 10384 ast_set_flag(p, SIP_NEEDDESTROY); 10385 10386 return res; 10387 }
|
|
handle_request_refer: Handle incoming REFER request ---
Definition at line 10655 of file chan_sip.c. References ast_async_goto(), ast_bridged_channel(), ast_log(), ast_moh_stop(), ast_mutex_unlock(), ast_parking_ext(), ast_queue_hangup(), ast_set_flag, ast_strlen_zero(), attempt_transfer(), sip_pvt::callid, sip_pvt::context, default_context, get_refer_info(), sip_pvt::lock, ast_channel::lock, LOG_DEBUG, ast_channel::name, option_debug, sip_pvt::owner, sip_pvt::refer_call, sip_pvt::refer_to, SIP_ALREADYGONE, SIP_BYE, SIP_GOTREFER, sip_park(), transmit_notify_with_sipfrag(), transmit_request_with_auth(), and transmit_response(). Referenced by handle_request(). 10656 { 10657 struct ast_channel *c=NULL; 10658 int res; 10659 struct ast_channel *transfer_to; 10660 10661 if (option_debug > 2) 10662 ast_log(LOG_DEBUG, "SIP call transfer received for call %s (REFER)!\n", p->callid); 10663 if (ast_strlen_zero(p->context)) 10664 strcpy(p->context, default_context); 10665 res = get_refer_info(p, req); 10666 if (res < 0) 10667 transmit_response(p, "603 Declined", req); 10668 else if (res > 0) 10669 transmit_response(p, "484 Address Incomplete", req); 10670 else { 10671 int nobye = 0; 10672 if (!ignore) { 10673 if (p->refer_call) { 10674 ast_log(LOG_DEBUG,"202 Accepted (supervised)\n"); 10675 attempt_transfer(p, p->refer_call); 10676 if (p->refer_call->owner) 10677 ast_mutex_unlock(&p->refer_call->owner->lock); 10678 ast_mutex_unlock(&p->refer_call->lock); 10679 p->refer_call = NULL; 10680 ast_set_flag(p, SIP_GOTREFER); 10681 } else { 10682 ast_log(LOG_DEBUG,"202 Accepted (blind)\n"); 10683 c = p->owner; 10684 if (c) { 10685 transfer_to = ast_bridged_channel(c); 10686 if (transfer_to) { 10687 ast_log(LOG_DEBUG, "Got SIP blind transfer, applying to '%s'\n", transfer_to->name); 10688 ast_moh_stop(transfer_to); 10689 if (!strcmp(p->refer_to, ast_parking_ext())) { 10690 /* Must release c's lock now, because it will not longer 10691 be accessible after the transfer! */ 10692 *nounlock = 1; 10693 ast_mutex_unlock(&c->lock); 10694 sip_park(transfer_to, c, req); 10695 nobye = 1; 10696 } else { 10697 /* Must release c's lock now, because it will not longer 10698 be accessible after the transfer! */ 10699 *nounlock = 1; 10700 ast_mutex_unlock(&c->lock); 10701 ast_async_goto(transfer_to,p->context, p->refer_to,1); 10702 } 10703 } else { 10704 ast_log(LOG_DEBUG, "Got SIP blind transfer but nothing to transfer to.\n"); 10705 ast_queue_hangup(p->owner); 10706 } 10707 } 10708 ast_set_flag(p, SIP_GOTREFER); 10709 } 10710 transmit_response(p, "202 Accepted", req); 10711 transmit_notify_with_sipfrag(p, seqno); 10712 /* Always increment on a BYE */ 10713 if (!nobye) { 10714 transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); 10715 ast_set_flag(p, SIP_ALREADYGONE); 10716 } 10717 } 10718 } 10719 return res; 10720 }
|
|
handle_request_register: Handle incoming REGISTER request ---
Definition at line 11034 of file chan_sip.c. References ast_inet_ntoa(), ast_log(), ast_verbose(), check_via(), copy_request(), get_header(), sip_pvt::initreq, LOG_NOTICE, register_verify(), and sip_scheddestroy(). Referenced by handle_request(). 11035 { 11036 int res = 0; 11037 char iabuf[INET_ADDRSTRLEN]; 11038 11039 /* Use this as the basis */ 11040 if (debug) 11041 ast_verbose("Using latest REGISTER request as basis request\n"); 11042 copy_request(&p->initreq, req); 11043 check_via(p, req); 11044 if ((res = register_verify(p, sin, req, e, ignore)) < 0) 11045 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", get_header(req, "To"), ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), (res == -1) ? "Wrong password" : (res == -2 ? "Username/auth name mismatch" : "Not a local SIP domain")); 11046 if (res < 1) { 11047 /* Destroy the session, but keep us around for just a bit in case they don't 11048 get our 200 OK */ 11049 sip_scheddestroy(p, 15*1000); 11050 } 11051 return res; 11052 }
|
|
handle_request_subscribe: Handle incoming SUBSCRIBE request ---
Definition at line 10817 of file chan_sip.c. References append_history(), ast_clear_flag, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_pvt::autokillid, build_contact(), sip_pvt::callid, cb_extensionstate(), check_user_full(), check_via(), sip_pvt::context, copy_request(), CPIM_PIDF_XML, default_context, DIALOG_INFO_XML, sip_pvt::expiry, sip_pvt::exten, get_destination(), get_header(), sip_request::headers, iflist, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, mailbox, make_our_tag(), max_expiry, sip_request::method, sip_pvt::next, NONE, option_debug, PIDF_XML, sip_pvt::randdata, sip_pvt::sa, sip_cancel_destroy(), sip_methods, SIP_NEEDDESTROY, SIP_OUTGOING, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribecontext, sip_pvt::subscribed, sip_pvt::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_state_notify(), sip_pvt::useragent, sip_pvt::username, and XPIDF_XML. Referenced by handle_request(). 10818 { 10819 int gotdest; 10820 int res = 0; 10821 int firststate = AST_EXTENSION_REMOVED; 10822 10823 if (p->initreq.headers) { 10824 /* We already have a dialog */ 10825 if (p->initreq.method != SIP_SUBSCRIBE) { 10826 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 10827 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 10828 transmit_response(p, "403 Forbidden (within dialog)", req); 10829 /* Do not destroy session, since we will break the call if we do */ 10830 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); 10831 return 0; 10832 } else { 10833 if (debug) 10834 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 10835 } 10836 } 10837 if (!ignore && !p->initreq.headers) { 10838 /* Use this as the basis */ 10839 if (debug) 10840 ast_verbose("Using latest SUBSCRIBE request as basis request\n"); 10841 /* This call is no longer outgoing if it ever was */ 10842 ast_clear_flag(p, SIP_OUTGOING); 10843 copy_request(&p->initreq, req); 10844 check_via(p, req); 10845 } else if (debug && ignore) 10846 ast_verbose("Ignoring this SUBSCRIBE request\n"); 10847 10848 if (!p->lastinvite) { 10849 char mailboxbuf[256]=""; 10850 int found = 0; 10851 char *mailbox = NULL; 10852 int mailboxsize = 0; 10853 char *eventparam; 10854 10855 char *event = get_header(req, "Event"); /* Get Event package name */ 10856 char *accept = get_header(req, "Accept"); 10857 10858 /* Find parameters to Event: header value and remove them for now */ 10859 eventparam = strchr(event, ';'); 10860 if (eventparam) { 10861 *eventparam = '\0'; 10862 eventparam++; 10863 } 10864 10865 if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) { 10866 mailbox = mailboxbuf; 10867 mailboxsize = sizeof(mailboxbuf); 10868 } 10869 /* Handle authentication if this is our first subscribe */ 10870 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, ignore, mailbox, mailboxsize); 10871 /* if an authentication challenge was sent, we are done here */ 10872 if (res > 0) 10873 return 0; 10874 if (res < 0) { 10875 if (res == -4) { 10876 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 10877 transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1); 10878 } else { 10879 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 10880 if (ignore) 10881 transmit_response(p, "403 Forbidden", req); 10882 else 10883 transmit_response_reliable(p, "403 Forbidden", req, 1); 10884 } 10885 ast_set_flag(p, SIP_NEEDDESTROY); 10886 return 0; 10887 } 10888 gotdest = get_destination(p, NULL); 10889 /* Initialize the context if it hasn't been already; 10890 note this is done _after_ handling any domain lookups, 10891 because the context specified there is for calls, not 10892 subscriptions 10893 */ 10894 if (!ast_strlen_zero(p->subscribecontext)) 10895 ast_copy_string(p->context, p->subscribecontext, sizeof(p->context)); 10896 else if (ast_strlen_zero(p->context)) 10897 strcpy(p->context, default_context); 10898 /* Get destination right away */ 10899 build_contact(p); 10900 if (gotdest) { 10901 if (gotdest < 0) 10902 transmit_response(p, "404 Not Found", req); 10903 else 10904 transmit_response(p, "484 Address Incomplete", req); /* Overlap dialing on SUBSCRIBE?? */ 10905 ast_set_flag(p, SIP_NEEDDESTROY); 10906 } else { 10907 10908 /* Initialize tag for new subscriptions */ 10909 if (ast_strlen_zero(p->tag)) 10910 make_our_tag(p->tag, sizeof(p->tag)); 10911 10912 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 10913 10914 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 10915 if (strstr(accept, "application/pidf+xml")) { 10916 p->subscribed = PIDF_XML; /* RFC 3863 format */ 10917 } else if (strstr(accept, "application/dialog-info+xml")) { 10918 p->subscribed = DIALOG_INFO_XML; 10919 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 10920 } else if (strstr(accept, "application/cpim-pidf+xml")) { 10921 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 10922 } else if (strstr(accept, "application/xpidf+xml")) { 10923 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 10924 } else if (strstr(p->useragent, "Polycom")) { 10925 p->subscribed = XPIDF_XML; /* Polycoms subscribe for "event: dialog" but don't include an "accept:" header */ 10926 } else { 10927 /* Can't find a format for events that we know about */ 10928 transmit_response(p, "489 Bad Event", req); 10929 ast_set_flag(p, SIP_NEEDDESTROY); 10930 return 0; 10931 } 10932 } else if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) { 10933 /* Looks like they actually want a mailbox status */ 10934 10935 /* At this point, we should check if they subscribe to a mailbox that 10936 has the same extension as the peer or the mailbox id. If we configure 10937 the context to be the same as a SIP domain, we could check mailbox 10938 context as well. To be able to securely accept subscribes on mailbox 10939 IDs, not extensions, we need to check the digest auth user to make 10940 sure that the user has access to the mailbox. 10941 10942 Since we do not act on this subscribe anyway, we might as well 10943 accept any authenticated peer with a mailbox definition in their 10944 config section. 10945 10946 */ 10947 if (!ast_strlen_zero(mailbox)) { 10948 found++; 10949 } 10950 10951 if (found){ 10952 transmit_response(p, "200 OK", req); 10953 ast_set_flag(p, SIP_NEEDDESTROY); 10954 } else { 10955 transmit_response(p, "404 Not found", req); 10956 ast_set_flag(p, SIP_NEEDDESTROY); 10957 } 10958 return 0; 10959 } else { /* At this point, Asterisk does not understand the specified event */ 10960 transmit_response(p, "489 Bad Event", req); 10961 if (option_debug > 1) 10962 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 10963 ast_set_flag(p, SIP_NEEDDESTROY); 10964 return 0; 10965 } 10966 if (p->subscribed != NONE) 10967 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 10968 } 10969 } 10970 10971 if (!ignore && p) 10972 p->lastinvite = seqno; 10973 if (p && !ast_test_flag(p, SIP_NEEDDESTROY)) { 10974 p->expiry = atoi(get_header(req, "Expires")); 10975 10976 /* The next 4 lines can be removed if the SNOM Expires bug is fixed */ 10977 if (p->subscribed == DIALOG_INFO_XML) { 10978 if (p->expiry > max_expiry) 10979 p->expiry = max_expiry; 10980 } 10981 if (sipdebug || option_debug > 1) 10982 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 10983 if (p->autokillid > -1) 10984 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 10985 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 10986 10987 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 10988 char iabuf[INET_ADDRSTRLEN]; 10989 10990 ast_log(LOG_ERROR, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension\n", p->exten, p->context, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); 10991 transmit_response(p, "404 Not found", req); 10992 ast_set_flag(p, SIP_NEEDDESTROY); 10993 return 0; 10994 } else { 10995 struct sip_pvt *p_old; 10996 10997 transmit_response(p, "200 OK", req); 10998 transmit_state_notify(p, firststate, 1, 1); /* Send first notification */ 10999 append_history(p, "Subscribestatus", ast_extension_state2str(firststate)); 11000 11001 /* remove any old subscription from this peer for the same exten/context, 11002 as the peer has obviously forgotten about it and it's wasteful to wait 11003 for it to expire and send NOTIFY messages to the peer only to have them 11004 ignored (or generate errors) 11005 */ 11006 ast_mutex_lock(&iflock); 11007 for (p_old = iflist; p_old; p_old = p_old->next) { 11008 if (p_old == p) 11009 continue; 11010 if (p_old->initreq.method != SIP_SUBSCRIBE) 11011 continue; 11012 if (p_old->subscribed == NONE) 11013 continue; 11014 ast_mutex_lock(&p_old->lock); 11015 if (!strcmp(p_old->username, p->username)) { 11016 if (!strcmp(p_old->exten, p->exten) && 11017 !strcmp(p_old->context, p->context)) { 11018 ast_set_flag(p_old, SIP_NEEDDESTROY); 11019 ast_mutex_unlock(&p_old->lock); 11020 break; 11021 } 11022 } 11023 ast_mutex_unlock(&p_old->lock); 11024 } 11025 ast_mutex_unlock(&iflock); 11026 } 11027 if (!p->expiry) 11028 ast_set_flag(p, SIP_NEEDDESTROY); 11029 } 11030 return 1; 11031 }
|
|
handle_response: Handle SIP response in dialogue ---
Definition at line 9896 of file chan_sip.c. References __sip_ack(), __sip_semi_ack(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_rtp_stop(), ast_sched_del(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_request::debug, DEC_CALL_LIMIT, do_proxy_auth(), find_sdp(), find_sip_method(), get_header(), gettag(), handle_response_invite(), handle_response_peerpoke(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, sip_pvt::initid, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, NONE, option_verbose, sip_pvt::owner, parse_moved_contact(), sip_pvt::peerpoke, process_sdp(), SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OUTGOING, SIP_REFER, SIP_REGISTER, text, sip_pvt::theirtag, transmit_request(), update_call_counter(), and VERBOSE_PREFIX_3. 09897 { 09898 char *msg, *c; 09899 struct ast_channel *owner; 09900 char iabuf[INET_ADDRSTRLEN]; 09901 int sipmethod; 09902 int res = 1; 09903 09904 c = get_header(req, "Cseq"); 09905 msg = strchr(c, ' '); 09906 if (!msg) 09907 msg = ""; 09908 else 09909 msg++; 09910 sipmethod = find_sip_method(msg); 09911 09912 owner = p->owner; 09913 if (owner) 09914 owner->hangupcause = hangup_sip2cause(resp); 09915 09916 /* Acknowledge whatever it is destined for */ 09917 if ((resp >= 100) && (resp <= 199)) 09918 __sip_semi_ack(p, seqno, 0, sipmethod); 09919 else 09920 __sip_ack(p, seqno, 0, sipmethod); 09921 09922 /* Get their tag if we haven't already */ 09923 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 09924 gettag(req, "To", p->theirtag, sizeof(p->theirtag)); 09925 } 09926 if (p->peerpoke) { 09927 /* We don't really care what the response is, just that it replied back. 09928 Well, as long as it's not a 100 response... since we might 09929 need to hang around for something more "definitive" */ 09930 09931 res = handle_response_peerpoke(p, resp, rest, req, ignore, seqno, sipmethod); 09932 } else if (ast_test_flag(p, SIP_OUTGOING)) { 09933 /* Acknowledge sequence number */ 09934 if (p->initid > -1) { 09935 /* Don't auto congest anymore since we've gotten something useful back */ 09936 ast_sched_del(sched, p->initid); 09937 p->initid = -1; 09938 } 09939 switch(resp) { 09940 case 100: /* 100 Trying */ 09941 if (sipmethod == SIP_INVITE) 09942 handle_response_invite(p, resp, rest, req, ignore, seqno); 09943 break; 09944 case 183: /* 183 Session Progress */ 09945 if (sipmethod == SIP_INVITE) 09946 handle_response_invite(p, resp, rest, req, ignore, seqno); 09947 break; 09948 case 180: /* 180 Ringing */ 09949 if (sipmethod == SIP_INVITE) 09950 handle_response_invite(p, resp, rest, req, ignore, seqno); 09951 break; 09952 case 200: /* 200 OK */ 09953 p->authtries = 0; /* Reset authentication counter */ 09954 if (sipmethod == SIP_MESSAGE) { 09955 /* We successfully transmitted a message */ 09956 ast_set_flag(p, SIP_NEEDDESTROY); 09957 } else if (sipmethod == SIP_NOTIFY) { 09958 /* They got the notify, this is the end */ 09959 if (p->owner) { 09960 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 09961 ast_queue_hangup(p->owner); 09962 } else { 09963 if (p->subscribed == NONE) { 09964 ast_set_flag(p, SIP_NEEDDESTROY); 09965 } 09966 } 09967 } else if (sipmethod == SIP_INVITE) { 09968 handle_response_invite(p, resp, rest, req, ignore, seqno); 09969 } else if (sipmethod == SIP_REGISTER) { 09970 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09971 } 09972 break; 09973 case 401: /* Not www-authorized on SIP method */ 09974 if (sipmethod == SIP_INVITE) { 09975 handle_response_invite(p, resp, rest, req, ignore, seqno); 09976 } else if (p->registry && sipmethod == SIP_REGISTER) { 09977 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09978 } else { 09979 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 09980 ast_set_flag(p, SIP_NEEDDESTROY); 09981 } 09982 break; 09983 case 403: /* Forbidden - we failed authentication */ 09984 if (sipmethod == SIP_INVITE) { 09985 handle_response_invite(p, resp, rest, req, ignore, seqno); 09986 } else if (p->registry && sipmethod == SIP_REGISTER) { 09987 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09988 } else { 09989 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for %s\n", msg); 09990 } 09991 break; 09992 case 404: /* Not found */ 09993 if (p->registry && sipmethod == SIP_REGISTER) { 09994 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09995 } else if (sipmethod == SIP_INVITE) { 09996 handle_response_invite(p, resp, rest, req, ignore, seqno); 09997 } else if (owner) 09998 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09999 break; 10000 case 407: /* Proxy auth required */ 10001 if (sipmethod == SIP_INVITE) { 10002 handle_response_invite(p, resp, rest, req, ignore, seqno); 10003 } else if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) { 10004 if (ast_strlen_zero(p->authname)) 10005 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 10006 msg, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); 10007 ast_set_flag(p, SIP_NEEDDESTROY); 10008 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 10009 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 10010 ast_set_flag(p, SIP_NEEDDESTROY); 10011 } 10012 } else if (p->registry && sipmethod == SIP_REGISTER) { 10013 res = handle_response_register(p, resp, rest, req, ignore, seqno); 10014 } else /* We can't handle this, giving up in a bad way */ 10015 ast_set_flag(p, SIP_NEEDDESTROY); 10016 10017 break; 10018 case 491: /* Pending */ 10019 if (sipmethod == SIP_INVITE) { 10020 handle_response_invite(p, resp, rest, req, ignore, seqno); 10021 } 10022 case 501: /* Not Implemented */ 10023 if (sipmethod == SIP_INVITE) { 10024 handle_response_invite(p, resp, rest, req, ignore, seqno); 10025 } else 10026 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), msg); 10027 break; 10028 default: 10029 if ((resp >= 300) && (resp < 700)) { 10030 if ((option_verbose > 2) && (resp != 487)) 10031 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); 10032 ast_set_flag(p, SIP_ALREADYGONE); 10033 if (p->rtp) { 10034 /* Immediately stop RTP */ 10035 ast_rtp_stop(p->rtp); 10036 } 10037 if (p->vrtp) { 10038 /* Immediately stop VRTP */ 10039 ast_rtp_stop(p->vrtp); 10040 } 10041 /* XXX Locking issues?? XXX */ 10042 switch(resp) { 10043 case 300: /* Multiple Choices */ 10044 case 301: /* Moved permenantly */ 10045 case 302: /* Moved temporarily */ 10046 case 305: /* Use Proxy */ 10047 parse_moved_contact(p, req); 10048 /* Fall through */ 10049 case 486: /* Busy here */ 10050 case 600: /* Busy everywhere */ 10051 case 603: /* Decline */ 10052 if (p->owner) 10053 ast_queue_control(p->owner, AST_CONTROL_BUSY); 10054 break; 10055 case 487: 10056 /* channel now destroyed - dec the inUse counter */ 10057 update_call_counter(p, DEC_CALL_LIMIT); 10058 break; 10059 case 482: /* SIP is incapable of performing a hairpin call, which 10060 is yet another failure of not having a layer 2 (again, YAY 10061 IETF for thinking ahead). So we treat this as a call 10062 forward and hope we end up at the right place... */ 10063 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 10064 if (p->owner) 10065 snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "Local/%s@%s", p->username, p->context); 10066 /* Fall through */ 10067 case 488: /* Not acceptable here - codec error */ 10068 case 480: /* Temporarily Unavailable */ 10069 case 404: /* Not Found */ 10070 case 410: /* Gone */ 10071 case 400: /* Bad Request */ 10072 case 500: /* Server error */ 10073 case 503: /* Service Unavailable */ 10074 if (owner) 10075 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 10076 break; 10077 default: 10078 /* Send hangup */ 10079 if (owner) 10080 ast_queue_hangup(p->owner); 10081 break; 10082 } 10083 /* ACK on invite */ 10084 if (sipmethod == SIP_INVITE) 10085 transmit_request(p, SIP_ACK, seqno, 0, 0); 10086 ast_set_flag(p, SIP_ALREADYGONE); 10087 if (!p->owner) 10088 ast_set_flag(p, SIP_NEEDDESTROY); 10089 } else if ((resp >= 100) && (resp < 200)) { 10090 if (sipmethod == SIP_INVITE) { 10091 if (!ignore) 10092 sip_cancel_destroy(p); 10093 if (find_sdp(req)) 10094 process_sdp(p, req); 10095 if (p->owner) { 10096 /* Queue a progress frame */ 10097 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 10098 } 10099 } 10100 } else 10101 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(iabuf, sizeof(iabuf), p->sa.sin_addr)); 10102 } 10103 } else { 10104 /* Responses to OUTGOING SIP requests on INCOMING calls 10105 get handled here. As well as out-of-call message responses */ 10106 if (req->debug) 10107 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 10108 if (resp == 200) { 10109 /* Tags in early session is replaced by the tag in 200 OK, which is 10110 the final reply to our INVITE */ 10111 gettag(req, "To", p->theirtag, sizeof(p->theirtag)); 10112 } 10113 10114 switch(resp) { 10115 case 200: 10116 if (sipmethod == SIP_INVITE) { 10117 handle_response_invite(p, resp, rest, req, ignore, seqno); 10118 } else if (sipmethod == SIP_CANCEL) { 10119 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 10120 } else if (sipmethod == SIP_MESSAGE) 10121 /* We successfully transmitted a message */ 10122 ast_set_flag(p, SIP_NEEDDESTROY); 10123 break; 10124 case 401: /* www-auth */ 10125 case 407: 10126 if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) { 10127 char *auth, *auth2; 10128 10129 if (resp == 407) { 10130 auth = "Proxy-Authenticate"; 10131 auth2 = "Proxy-Authorization"; 10132 } else { 10133 auth = "WWW-Authenticate"; 10134 auth2 = "Authorization"; 10135 } 10136 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 10137 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 10138 ast_set_flag(p, SIP_NEEDDESTROY); 10139 } 10140 } else if (sipmethod == SIP_INVITE) { 10141 handle_response_invite(p, resp, rest, req, ignore, seqno); 10142 } 10143 break; 10144 case 481: /* Call leg does not exist */ 10145 if (sipmethod == SIP_INVITE) { 10146 /* Re-invite failed */ 10147 handle_response_invite(p, resp, rest, req, ignore, seqno); 10148 } 10149 break; 10150 default: /* Errors without handlers */ 10151 if ((resp >= 100) && (resp < 200)) { 10152 if (sipmethod == SIP_INVITE && !ignore) /* re-invite */ 10153 sip_cancel_destroy(p); 10154 10155 } 10156 if ((resp >= 300) && (resp < 700)) { 10157 if ((option_verbose > 2) && (resp != 487)) 10158 ast_verbose(VERBOSE_PREFIX_3 "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); 10159 switch(resp) { 10160 case 488: /* Not acceptable here - codec error */ 10161 case 603: /* Decline */ 10162 case 500: /* Server error */ 10163 case 503: /* Service Unavailable */ 10164 10165 if (sipmethod == SIP_INVITE && !ignore) { /* re-invite failed */ 10166 sip_cancel_destroy(p); 10167 } 10168 break; 10169 } 10170 } 10171 break; 10172 } 10173 } 10174 }
|
|
handle_response_invite: Handle SIP response in dialogue ---
Definition at line 9569 of file chan_sip.c. References ast_channel::_state, AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_FRAME_NULL, ast_log(), ast_queue_control(), ast_queue_frame(), ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_test_flag, authenticate(), build_route(), sip_pvt::callid, check_pendings(), do_proxy_auth(), find_sdp(), get_header(), LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, option_debug, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, SIP_ACK, SIP_ALREADYGONE, SIP_CAN_BYE, sip_cancel_destroy(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PENDINGBYE, transmit_request(), and WWW_AUTH. Referenced by handle_response(). 09570 { 09571 int outgoing = ast_test_flag(p, SIP_OUTGOING); 09572 09573 if (option_debug > 3) { 09574 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 09575 if (reinvite) 09576 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 09577 else 09578 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 09579 } 09580 09581 if (ast_test_flag(p, SIP_ALREADYGONE)) { /* This call is already gone */ 09582 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 09583 return; 09584 } 09585 09586 switch (resp) { 09587 case 100: /* Trying */ 09588 if (!ignore) 09589 sip_cancel_destroy(p); 09590 /* must call check_pendings before setting CAN_BYE, so that 09591 if PENDINGBYE is set it will know to send CANCEL instead */ 09592 check_pendings(p); 09593 ast_set_flag(p, SIP_CAN_BYE); 09594 break; 09595 case 180: /* 180 Ringing */ 09596 if (!ignore) 09597 sip_cancel_destroy(p); 09598 if (!ignore && p->owner) { 09599 ast_queue_control(p->owner, AST_CONTROL_RINGING); 09600 if (p->owner->_state != AST_STATE_UP) 09601 ast_setstate(p->owner, AST_STATE_RINGING); 09602 } 09603 if (find_sdp(req)) { 09604 process_sdp(p, req); 09605 if (!ignore && p->owner) { 09606 /* Queue a progress frame only if we have SDP in 180 */ 09607 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 09608 } 09609 } 09610 /* must call check_pendings before setting CAN_BYE, so that 09611 if PENDINGBYE is set it will know to send CANCEL instead */ 09612 check_pendings(p); 09613 ast_set_flag(p, SIP_CAN_BYE); 09614 break; 09615 case 183: /* Session progress */ 09616 if (!ignore) 09617 sip_cancel_destroy(p); 09618 /* Ignore 183 Session progress without SDP */ 09619 if (find_sdp(req)) { 09620 process_sdp(p, req); 09621 if (!ignore && p->owner) { 09622 /* Queue a progress frame */ 09623 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 09624 } 09625 } 09626 /* must call check_pendings before setting CAN_BYE, so that 09627 if PENDINGBYE is set it will know to send CANCEL instead */ 09628 check_pendings(p); 09629 ast_set_flag(p, SIP_CAN_BYE); 09630 break; 09631 case 200: /* 200 OK on invite - someone's answering our call */ 09632 if (!ignore) 09633 sip_cancel_destroy(p); 09634 p->authtries = 0; 09635 if (find_sdp(req)) { 09636 process_sdp(p, req); 09637 } 09638 09639 /* Parse contact header for continued conversation */ 09640 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 09641 /* This is important when we have a SIP proxy between us and the phone */ 09642 if (outgoing) { 09643 parse_ok_contact(p, req); 09644 09645 /* Save Record-Route for any later requests we make on this dialogue */ 09646 build_route(p, req, 1); 09647 } 09648 09649 if (!ignore && p->owner) { 09650 if (p->owner->_state != AST_STATE_UP) { 09651 #ifdef OSP_SUPPORT 09652 time(&p->ospstart); 09653 #endif 09654 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 09655 } else { /* RE-invite */ 09656 struct ast_frame af = { AST_FRAME_NULL, }; 09657 ast_queue_frame(p->owner, &af); 09658 } 09659 } else { 09660 /* It's possible we're getting an ACK after we've tried to disconnect 09661 by sending CANCEL */ 09662 /* THIS NEEDS TO BE CHECKED: OEJ */ 09663 if (!ignore) 09664 ast_set_flag(p, SIP_PENDINGBYE); 09665 } 09666 /* If I understand this right, the branch is different for a non-200 ACK only */ 09667 transmit_request(p, SIP_ACK, seqno, 0, 1); 09668 check_pendings(p); 09669 break; 09670 case 407: /* Proxy authentication */ 09671 case 401: /* Www auth */ 09672 /* First we ACK */ 09673 transmit_request(p, SIP_ACK, seqno, 0, 0); 09674 if (p->options) 09675 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 09676 09677 /* Then we AUTH */ 09678 p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */ 09679 if (!ignore) { 09680 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 09681 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 09682 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 09683 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 09684 ast_set_flag(p, SIP_NEEDDESTROY); 09685 ast_set_flag(p, SIP_ALREADYGONE); 09686 if (p->owner) 09687 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09688 } 09689 } 09690 break; 09691 case 403: /* Forbidden */ 09692 /* First we ACK */ 09693 transmit_request(p, SIP_ACK, seqno, 0, 0); 09694 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for INVITE to '%s'\n", get_header(&p->initreq, "From")); 09695 if (!ignore && p->owner) 09696 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09697 ast_set_flag(p, SIP_NEEDDESTROY); 09698 ast_set_flag(p, SIP_ALREADYGONE); 09699 break; 09700 case 404: /* Not found */ 09701 transmit_request(p, SIP_ACK, seqno, 0, 0); 09702 if (p->owner && !ignore) 09703 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09704 ast_set_flag(p, SIP_ALREADYGONE); 09705 break; 09706 case 481: /* Call leg does not exist */ 09707 /* Could be REFER or INVITE */ 09708 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 09709 transmit_request(p, SIP_ACK, seqno, 0, 0); 09710 break; 09711 case 491: /* Pending */ 09712 /* we have to wait a while, then retransmit */ 09713 /* Transmission is rescheduled, so everything should be taken care of. 09714 We should support the retry-after at some point */ 09715 break; 09716 case 501: /* Not implemented */ 09717 if (p->owner) 09718 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09719 break; 09720 } 09721 }
|
|
handle_response_peerpoke: Handle qualification responses (OPTIONS)
Definition at line 9840 of file chan_sip.c. References ast_device_state_changed(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, sip_peer::call, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_pvt::peerpoke, sip_peer::pokeexpire, sip_peer::ps, SIP_ACK, SIP_INVITE, SIP_NEEDDESTROY, sip_poke_peer_s(), and transmit_request(). Referenced by handle_response(). 09841 { 09842 struct sip_peer *peer; 09843 int pingtime; 09844 struct timeval tv; 09845 09846 if (resp != 100) { 09847 int statechanged = 0; 09848 int newstate = 0; 09849 peer = p->peerpoke; 09850 gettimeofday(&tv, NULL); 09851 pingtime = ast_tvdiff_ms(tv, peer->ps); 09852 if (pingtime < 1) 09853 pingtime = 1; 09854 if ((peer->lastms < 0) || (peer->lastms > peer->maxms)) { 09855 if (pingtime <= peer->maxms) { 09856 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! (%dms / %dms)\n", peer->name, pingtime, peer->maxms); 09857 statechanged = 1; 09858 newstate = 1; 09859 } 09860 } else if ((peer->lastms > 0) && (peer->lastms <= peer->maxms)) { 09861 if (pingtime > peer->maxms) { 09862 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED! (%dms / %dms)\n", peer->name, pingtime, peer->maxms); 09863 statechanged = 1; 09864 newstate = 2; 09865 } 09866 } 09867 if (!peer->lastms) 09868 statechanged = 1; 09869 peer->lastms = pingtime; 09870 peer->call = NULL; 09871 if (statechanged) { 09872 ast_device_state_changed("SIP/%s", peer->name); 09873 if (newstate == 2) { 09874 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, pingtime); 09875 } else { 09876 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, pingtime); 09877 } 09878 } 09879 09880 if (peer->pokeexpire > -1) 09881 ast_sched_del(sched, peer->pokeexpire); 09882 if (sipmethod == SIP_INVITE) /* Does this really happen? */ 09883 transmit_request(p, SIP_ACK, seqno, 0, 0); 09884 ast_set_flag(p, SIP_NEEDDESTROY); 09885 09886 /* Try again eventually */ 09887 if ((peer->lastms < 0) || (peer->lastms > peer->maxms)) 09888 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 09889 else 09890 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_OK, sip_poke_peer_s, peer); 09891 } 09892 return 1; 09893 }
|
|
handle_response_register: Handle responses on REGISTER to services ---
Definition at line 9724 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_registry::contact, default_expiry, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, EXPIRY_GUARD_LIMIT, EXPIRY_GUARD_MIN, EXPIRY_GUARD_PCT, EXPIRY_GUARD_SECS, get_header(), global_regattempts_max, sip_registry::hostname, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), MAX, MAX_AUTHTRIES, sip_registry::refresh, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, strcasestr(), sip_registry::timeout, and sip_registry::username. Referenced by handle_response(). 09725 { 09726 int expires, expires_ms; 09727 struct sip_registry *r; 09728 r=p->registry; 09729 09730 switch (resp) { 09731 case 401: /* Unauthorized */ 09732 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 09733 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 09734 ast_set_flag(p, SIP_NEEDDESTROY); 09735 } 09736 break; 09737 case 403: /* Forbidden */ 09738 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 09739 if (global_regattempts_max) 09740 p->registry->regattempts = global_regattempts_max+1; 09741 ast_sched_del(sched, r->timeout); 09742 ast_set_flag(p, SIP_NEEDDESTROY); 09743 break; 09744 case 404: /* Not found */ 09745 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 09746 if (global_regattempts_max) 09747 p->registry->regattempts = global_regattempts_max+1; 09748 ast_set_flag(p, SIP_NEEDDESTROY); 09749 r->call = NULL; 09750 ast_sched_del(sched, r->timeout); 09751 break; 09752 case 407: /* Proxy auth */ 09753 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 09754 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 09755 ast_set_flag(p, SIP_NEEDDESTROY); 09756 } 09757 break; 09758 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 09759 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 09760 if (global_regattempts_max) 09761 p->registry->regattempts = global_regattempts_max+1; 09762 ast_set_flag(p, SIP_NEEDDESTROY); 09763 r->call = NULL; 09764 ast_sched_del(sched, r->timeout); 09765 break; 09766 case 200: /* 200 OK */ 09767 if (!r) { 09768 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 09769 ast_set_flag(p, SIP_NEEDDESTROY); 09770 return 0; 09771 } 09772 09773 r->regstate=REG_STATE_REGISTERED; 09774 manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 09775 r->regattempts = 0; 09776 ast_log(LOG_DEBUG, "Registration successful\n"); 09777 if (r->timeout > -1) { 09778 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 09779 ast_sched_del(sched, r->timeout); 09780 } 09781 r->timeout=-1; 09782 r->call = NULL; 09783 p->registry = NULL; 09784 /* Let this one hang around until we have all the responses */ 09785 sip_scheddestroy(p, 32000); 09786 /* ast_set_flag(p, SIP_NEEDDESTROY); */ 09787 09788 /* set us up for re-registering */ 09789 /* figure out how long we got registered for */ 09790 if (r->expire > -1) 09791 ast_sched_del(sched, r->expire); 09792 /* according to section 6.13 of RFC, contact headers override 09793 expires headers, so check those first */ 09794 expires = 0; 09795 if (!ast_strlen_zero(get_header(req, "Contact"))) { 09796 char *contact = NULL; 09797 char *tmptmp = NULL; 09798 int start = 0; 09799 for(;;) { 09800 contact = __get_header(req, "Contact", &start); 09801 /* this loop ensures we get a contact header about our register request */ 09802 if(!ast_strlen_zero(contact)) { 09803 if( (tmptmp=strstr(contact, p->our_contact))) { 09804 contact=tmptmp; 09805 break; 09806 } 09807 } else 09808 break; 09809 } 09810 tmptmp = strcasestr(contact, "expires="); 09811 if (tmptmp) { 09812 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 09813 expires = 0; 09814 } 09815 09816 } 09817 if (!expires) 09818 expires=atoi(get_header(req, "expires")); 09819 if (!expires) 09820 expires=default_expiry; 09821 09822 expires_ms = expires * 1000; 09823 if (expires <= EXPIRY_GUARD_LIMIT) 09824 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 09825 else 09826 expires_ms -= EXPIRY_GUARD_SECS * 1000; 09827 if (sipdebug) 09828 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 09829 09830 r->refresh= (int) expires_ms / 1000; 09831 09832 /* Schedule re-registration before we expire */ 09833 r->expire=ast_sched_add(sched, expires_ms, sip_reregister, r); 09834 ASTOBJ_UNREF(r, sip_registry_destroy); 09835 } 09836 return 1; 09837 }
|
|
hangup_cause2sip: 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 2354 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_USER_BUSY, ast_log(), and LOG_DEBUG. Referenced by sip_hangup(). 02355 { 02356 switch(cause) 02357 { 02358 case AST_CAUSE_UNALLOCATED: /* 1 */ 02359 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 02360 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 02361 return "404 Not Found"; 02362 case AST_CAUSE_CONGESTION: /* 34 */ 02363 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 02364 return "503 Service Unavailable"; 02365 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 02366 return "408 Request Timeout"; 02367 case AST_CAUSE_NO_ANSWER: /* 19 */ 02368 return "480 Temporarily unavailable"; 02369 case AST_CAUSE_CALL_REJECTED: /* 21 */ 02370 return "403 Forbidden"; 02371 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 02372 return "410 Gone"; 02373 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 02374 return "480 Temporarily unavailable"; 02375 case AST_CAUSE_INVALID_NUMBER_FORMAT: 02376 return "484 Address incomplete"; 02377 case AST_CAUSE_USER_BUSY: 02378 return "486 Busy here"; 02379 case AST_CAUSE_FAILURE: 02380 return "500 Server internal failure"; 02381 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 02382 return "501 Not Implemented"; 02383 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 02384 return "503 Service Unavailable"; 02385 /* Used in chan_iax2 */ 02386 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 02387 return "502 Bad Gateway"; 02388 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 02389 return "488 Not Acceptable Here"; 02390 02391 case AST_CAUSE_NOTDEFINED: 02392 default: 02393 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 02394 return NULL; 02395 } 02396 02397 /* Never reached */ 02398 return 0; 02399 }
|
|
hangup_sip2cause: Convert SIP hangup causes to Asterisk hangup causes ---
Definition at line 2286 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_NO_ANSWER, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, and AST_CAUSE_UNALLOCATED. Referenced by handle_response(). 02287 { 02288 /* Possible values taken from causes.h */ 02289 02290 switch(cause) { 02291 case 603: /* Declined */ 02292 case 403: /* Not found */ 02293 return AST_CAUSE_CALL_REJECTED; 02294 case 404: /* Not found */ 02295 return AST_CAUSE_UNALLOCATED; 02296 case 408: /* No reaction */ 02297 return AST_CAUSE_NO_USER_RESPONSE; 02298 case 480: /* No answer */ 02299 return AST_CAUSE_FAILURE; 02300 case 483: /* Too many hops */ 02301 return AST_CAUSE_NO_ANSWER; 02302 case 486: /* Busy everywhere */ 02303 return AST_CAUSE_BUSY; 02304 case 488: /* No codecs approved */ 02305 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 02306 case 500: /* Server internal failure */ 02307 return AST_CAUSE_FAILURE; 02308 case 501: /* Call rejected */ 02309 return AST_CAUSE_FACILITY_REJECTED; 02310 case 502: 02311 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 02312 case 503: /* Service unavailable */ 02313 return AST_CAUSE_CONGESTION; 02314 default: 02315 return AST_CAUSE_NORMAL; 02316 } 02317 /* Never reached */ 02318 return 0; 02319 }
|
|
init_req: Initialize SIP request ---
Definition at line 4042 of file chan_sip.c. References ast_log(), sip_request::data, sip_request::header, sip_request::headers, sip_request::len, LOG_WARNING, sip_request::method, sip_methods, and cfsip_methods::text. 04043 { 04044 /* Initialize a response */ 04045 if (req->headers || req->len) { 04046 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 04047 return -1; 04048 } 04049 req->header[req->headers] = req->data + req->len; 04050 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 04051 req->len += strlen(req->header[req->headers]); 04052 req->headers++; 04053 req->method = sipmethod; 04054 return 0; 04055 }
|
|
init_resp: Initialize SIP response, based on SIP request ---
Definition at line 4026 of file chan_sip.c. References ast_log(), sip_request::data, sip_request::header, sip_request::headers, sip_request::len, LOG_WARNING, sip_request::method, and SIP_RESPONSE. 04027 { 04028 /* Initialize a response */ 04029 if (req->headers || req->len) { 04030 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 04031 return -1; 04032 } 04033 req->method = SIP_RESPONSE; 04034 req->header[req->headers] = req->data + req->len; 04035 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "SIP/2.0 %s\r\n", resp); 04036 req->len += strlen(req->header[req->headers]); 04037 req->headers++; 04038 return 0; 04039 }
|
|
initreqprep: Initiate new SIP request to peer/user ---
Definition at line 4800 of file chan_sip.c. References add_header(), ast_build_string(), AST_DIGIT_ANYNUM, ast_inet_ntoa(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, 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_callerid, DEFAULT_MAX_FORWARDS, default_useragent, sip_pvt::exten, sip_pvt::fromdomain, sip_pvt::fromname, sip_pvt::fromuser, sip_pvt::fullcontact, init_req(), sip_pvt::lastmsg, n, sip_pvt::ocseq, sip_pvt::options, sip_pvt::our_contact, sip_pvt::ourip, ourport, sip_pvt::owner, pedanticsipchecking, sip_pvt::rpid, sip_pvt::sa, SIP_INVITE, sip_methods, SIP_NOTIFY, SIP_SENDRPID, SIP_USEREQPHONE, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, sip_pvt::tohost, sip_pvt::uri, sip_invite_param::uri_options, username, sip_pvt::username, sip_pvt::via, and sip_invite_param::vxml_url. Referenced by sip_notify(), transmit_invite(), and transmit_notify_with_mwi(). 04801 { 04802 char invite_buf[256] = ""; 04803 char *invite = invite_buf; 04804 size_t invite_max = sizeof(invite_buf); 04805 char from[256]; 04806 char to[256]; 04807 char tmp[BUFSIZ/2]; 04808 char tmp2[BUFSIZ/2]; 04809 char iabuf[INET_ADDRSTRLEN]; 04810 char *l = NULL, *n = NULL; 04811 int x; 04812 char urioptions[256]=""; 04813 04814 if (ast_test_flag(p, SIP_USEREQPHONE)) { 04815 char onlydigits = 1; 04816 x=0; 04817 04818 /* Test p->username against allowed characters in AST_DIGIT_ANY 04819 If it matches the allowed characters list, then sipuser = ";user=phone" 04820 If not, then sipuser = "" 04821 */ 04822 /* + is allowed in first position in a tel: uri */ 04823 if (p->username && p->username[0] == '+') 04824 x=1; 04825 04826 for (; x < strlen(p->username); x++) { 04827 if (!strchr(AST_DIGIT_ANYNUM, p->username[x])) { 04828 onlydigits = 0; 04829 break; 04830 } 04831 } 04832 04833 /* If we have only digits, add ;user=phone to the uri */ 04834 if (onlydigits) 04835 strcpy(urioptions, ";user=phone"); 04836 } 04837 04838 04839 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 04840 04841 if (p->owner) { 04842 l = p->owner->cid.cid_num; 04843 n = p->owner->cid.cid_name; 04844 } 04845 /* if we are not sending RPID and user wants his callerid restricted */ 04846 if (!ast_test_flag(p, SIP_SENDRPID) && ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 04847 l = CALLERID_UNKNOWN; 04848 n = l; 04849 } 04850 if (!l) 04851 l = default_callerid; 04852 if (ast_strlen_zero(n)) 04853 n = l; 04854 /* Allow user to be overridden */ 04855 if (!ast_strlen_zero(p->fromuser)) 04856 l = p->fromuser; 04857 else /* Save for any further attempts */ 04858 ast_copy_string(p->fromuser, l, sizeof(p->fromuser)); 04859 04860 /* Allow user to be overridden */ 04861 if (!ast_strlen_zero(p->fromname)) 04862 n = p->fromname; 04863 else /* Save for any further attempts */ 04864 ast_copy_string(p->fromname, n, sizeof(p->fromname)); 04865 04866 if (pedanticsipchecking) { 04867 ast_uri_encode(n, tmp, sizeof(tmp), 0); 04868 n = tmp; 04869 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 04870 l = tmp2; 04871 } 04872 04873 if ((ourport != 5060) && ast_strlen_zero(p->fromdomain)) /* Needs to be 5060 */ 04874 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, ourport, p->tag); 04875 else 04876 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, p->tag); 04877 04878 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 04879 if (!ast_strlen_zero(p->fullcontact)) { 04880 /* If we have full contact, trust it */ 04881 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 04882 } else { 04883 /* Otherwise, use the username while waiting for registration */ 04884 ast_build_string(&invite, &invite_max, "sip:"); 04885 if (!ast_strlen_zero(p->username)) { 04886 n = p->username; 04887 if (pedanticsipchecking) { 04888 ast_uri_encode(n, tmp, sizeof(tmp), 0); 04889 n = tmp; 04890 } 04891 ast_build_string(&invite, &invite_max, "%s@", n); 04892 } 04893 ast_build_string(&invite, &invite_max, "%s", p->tohost); 04894 if (ntohs(p->sa.sin_port) != 5060) /* Needs to be 5060 */ 04895 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 04896 ast_build_string(&invite, &invite_max, "%s", urioptions); 04897 } 04898 04899 /* If custom URI options have been provided, append them */ 04900 if (p->options && p->options->uri_options) 04901 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 04902 04903 ast_copy_string(p->uri, invite_buf, sizeof(p->uri)); 04904 04905 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 04906 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 04907 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag); 04908 } else if (p->options && p->options->vxml_url) { 04909 /* If there is a VXML URL append it to the SIP URL */ 04910 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 04911 } else { 04912 snprintf(to, sizeof(to), "<%s>", p->uri); 04913 } 04914 04915 memset(req, 0, sizeof(struct sip_request)); 04916 init_req(req, sipmethod, p->uri); 04917 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 04918 04919 add_header(req, "Via", p->via); 04920 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 04921 * OTOH, then we won't have anything in p->route anyway */ 04922 /* Build Remote Party-ID and From */ 04923 if (ast_test_flag(p, SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 04924 build_rpid(p); 04925 add_header(req, "From", p->rpid_from); 04926 } else { 04927 add_header(req, "From", from); 04928 } 04929 add_header(req, "To", to); 04930 ast_copy_string(p->exten, l, sizeof(p->exten)); 04931 build_contact(p); 04932 add_header(req, "Contact", p->our_contact); 04933 add_header(req, "Call-ID", p->callid); 04934 add_header(req, "CSeq", tmp); 04935 add_header(req, "User-Agent", default_useragent); 04936 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 04937 if (p->rpid) 04938 add_header(req, "Remote-Party-ID", p->rpid); 04939 }
|
|
insecure2str: Convert Insecure setting to printable string ---
Definition at line 7744 of file chan_sip.c. Referenced by _sip_show_peer(). 07745 { 07746 if (port && invite) 07747 return "port,invite"; 07748 else if (port) 07749 return "port"; 07750 else if (invite) 07751 return "invite"; 07752 else 07753 return "no"; 07754 }
|
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 13468 of file chan_sip.c. References ASTERISK_GPL_KEY. 13469 { 13470 return ASTERISK_GPL_KEY; 13471 }
|
|
list_route: List all routes - mostly for debugging ---
Definition at line 6052 of file chan_sip.c. References ast_verbose(), sip_route::hop, and sip_route::next. Referenced by build_route(). 06053 { 06054 if (!route) { 06055 ast_verbose("list_route: no route\n"); 06056 return; 06057 } 06058 while (route) { 06059 ast_verbose("list_route: hop: <%s>\n", route->hop); 06060 route = route->next; 06061 } 06062 }
|
|
|
lws2sws: Parse multiline SIP headers into one header
Definition at line 3296 of file chan_sip.c. References t. Referenced by sipsock_read(). 03297 { 03298 int h = 0, t = 0; 03299 int lws = 0; 03300 03301 for (; h < len;) { 03302 /* Eliminate all CRs */ 03303 if (msgbuf[h] == '\r') { 03304 h++; 03305 continue; 03306 } 03307 /* Check for end-of-line */ 03308 if (msgbuf[h] == '\n') { 03309 /* Check for end-of-message */ 03310 if (h + 1 == len) 03311 break; 03312 /* Check for a continuation line */ 03313 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 03314 /* Merge continuation line */ 03315 h++; 03316 continue; 03317 } 03318 /* Propagate LF and start new line */ 03319 msgbuf[t++] = msgbuf[h++]; 03320 lws = 0; 03321 continue; 03322 } 03323 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 03324 if (lws) { 03325 h++; 03326 continue; 03327 } 03328 msgbuf[t++] = msgbuf[h++]; 03329 lws = 1; 03330 continue; 03331 } 03332 msgbuf[t++] = msgbuf[h++]; 03333 if (lws) 03334 lws = 0; 03335 } 03336 msgbuf[t] = '\0'; 03337 return t; 03338 }
|
|
Definition at line 3048 of file chan_sip.c. References thread_safe_rand(). Referenced by handle_request_invite(), handle_request_subscribe(), sip_alloc(), and transmit_register(). 03049 { 03050 snprintf(tagbuf, len, "as%08x", thread_safe_rand()); 03051 }
|
|
manager_sip_show_peer: Show SIP peers in the manager API ---
Definition at line 7964 of file chan_sip.c. References _sip_show_peer(), ast_cli(), ast_strlen_zero(), astman_get_header(), astman_send_error(), and mansession::fd. Referenced by load_module(). 07965 { 07966 char *id = astman_get_header(m,"ActionID"); 07967 char *a[4]; 07968 char *peer; 07969 int ret; 07970 07971 peer = astman_get_header(m,"Peer"); 07972 if (ast_strlen_zero(peer)) { 07973 astman_send_error(s, m, "Peer: <name> missing.\n"); 07974 return 0; 07975 } 07976 a[0] = "sip"; 07977 a[1] = "show"; 07978 a[2] = "peer"; 07979 a[3] = peer; 07980 07981 if (!ast_strlen_zero(id)) 07982 ast_cli(s->fd, "ActionID: %s\r\n",id); 07983 ret = _sip_show_peer(1, s->fd, s, m, 4, a ); 07984 ast_cli( s->fd, "\r\n\r\n" ); 07985 return ret; 07986 }
|
|
manager_sip_show_peers: Show SIP peers in the manager API ---
Definition at line 7545 of file chan_sip.c. References _sip_show_peers(), ast_cli(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), mansession::fd, and total. Referenced by load_module(). 07546 { 07547 char *id = astman_get_header(m,"ActionID"); 07548 char *a[] = { "sip", "show", "peers" }; 07549 char idtext[256] = ""; 07550 int total = 0; 07551 07552 if (!ast_strlen_zero(id)) 07553 snprintf(idtext,256,"ActionID: %s\r\n",id); 07554 07555 astman_send_ack(s, m, "Peer status list will follow"); 07556 /* List the peers in separate manager events */ 07557 _sip_show_peers(s->fd, &total, s, m, 3, a); 07558 /* Send final confirmation */ 07559 ast_cli(s->fd, 07560 "Event: PeerlistComplete\r\n" 07561 "ListItems: %d\r\n" 07562 "%s" 07563 "\r\n", total, idtext); 07564 return 0; 07565 }
|
|
nat2str: Convert NAT setting to text string
Definition at line 7447 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(). 07448 { 07449 switch(nat) { 07450 case SIP_NAT_NEVER: 07451 return "No"; 07452 case SIP_NAT_ROUTE: 07453 return "Route"; 07454 case SIP_NAT_ALWAYS: 07455 return "Always"; 07456 case SIP_NAT_RFC3581: 07457 return "RFC3581"; 07458 default: 07459 return "Unknown"; 07460 } 07461 }
|
|
parse_copy: Copy SIP request, parse it
Definition at line 1463 of file chan_sip.c. References sip_request::data, sip_request::len, and parse_request(). Referenced by send_request(), and send_response(). 01464 { 01465 memset(dst, 0, sizeof(*dst)); 01466 memcpy(dst->data, src->data, sizeof(dst->data)); 01467 dst->len = src->len; 01468 parse_request(dst); 01469 }
|
|
parse_moved_contact: Parse 302 Moved temporalily response
Definition at line 9512 of file chan_sip.c. References ast_log(), ast_test_flag, get_header(), get_in_brackets(), LOG_DEBUG, s, and SIP_PROMISCREDIR. Referenced by handle_response(). 09513 { 09514 char tmp[256]; 09515 char *s, *e; 09516 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 09517 s = get_in_brackets(tmp); 09518 e = strchr(s, ';'); 09519 if (e) 09520 *e = '\0'; 09521 if (ast_test_flag(p, SIP_PROMISCREDIR)) { 09522 if (!strncasecmp(s, "sip:", 4)) 09523 s += 4; 09524 e = strchr(s, '/'); 09525 if (e) 09526 *e = '\0'; 09527 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 09528 if (p->owner) 09529 snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "SIP/%s", s); 09530 } else { 09531 e = strchr(tmp, '@'); 09532 if (e) 09533 *e = '\0'; 09534 e = strchr(tmp, '/'); 09535 if (e) 09536 *e = '\0'; 09537 if (!strncasecmp(s, "sip:", 4)) 09538 s += 4; 09539 ast_log(LOG_DEBUG, "Found 302 Redirect to extension '%s'\n", s); 09540 if (p->owner) 09541 ast_copy_string(p->owner->call_forward, s, sizeof(p->owner->call_forward)); 09542 } 09543 }
|
|
parse_ok_contact: Parse contact header for 200 OK on INVITE ---
Definition at line 5813 of file chan_sip.c. References ast_gethostbyname(), ast_log(), ast_test_flag, DEFAULT_SIP_PORT, sip_pvt::fullcontact, get_header(), get_in_brackets(), hp, LOG_NOTICE, LOG_WARNING, n, sip_pvt::okcontacturi, sip_pvt::recv, sip_pvt::sa, SIP_LEN_CONTACT, SIP_NAT, and SIP_NAT_ROUTE. Referenced by handle_response_invite(). 05814 { 05815 char contact[SIP_LEN_CONTACT]; 05816 char *c, *n, *pt; 05817 int port; 05818 struct hostent *hp; 05819 struct ast_hostent ahp; 05820 struct sockaddr_in oldsin; 05821 05822 /* Look for brackets */ 05823 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 05824 c = get_in_brackets(contact); 05825 05826 /* Save full contact to call pvt for later bye or re-invite */ 05827 ast_copy_string(pvt->fullcontact, c, sizeof(pvt->fullcontact)); 05828 05829 /* Save URI for later ACKs, BYE or RE-invites */ 05830 ast_copy_string(pvt->okcontacturi, c, sizeof(pvt->okcontacturi)); 05831 05832 /* Make sure it's a SIP URL */ 05833 if (strncasecmp(c, "sip:", 4)) { 05834 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c); 05835 } else 05836 c += 4; 05837 05838 /* Ditch arguments */ 05839 n = strchr(c, ';'); 05840 if (n) 05841 *n = '\0'; 05842 05843 /* Grab host */ 05844 n = strchr(c, '@'); 05845 if (!n) { 05846 n = c; 05847 c = NULL; 05848 } else { 05849 *n = '\0'; 05850 n++; 05851 } 05852 pt = strchr(n, ':'); 05853 if (pt) { 05854 *pt = '\0'; 05855 pt++; 05856 port = atoi(pt); 05857 } else 05858 port = DEFAULT_SIP_PORT; 05859 05860 memcpy(&oldsin, &pvt->sa, sizeof(oldsin)); 05861 05862 if (!(ast_test_flag(pvt, SIP_NAT) & SIP_NAT_ROUTE)) { 05863 /* XXX This could block for a long time XXX */ 05864 /* We should only do this if it's a name, not an IP */ 05865 hp = ast_gethostbyname(n, &ahp); 05866 if (!hp) { 05867 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 05868 return -1; 05869 } 05870 pvt->sa.sin_family = AF_INET; 05871 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 05872 pvt->sa.sin_port = htons(port); 05873 } else { 05874 /* Don't trust the contact field. Just use what they came to us 05875 with. */ 05876 memcpy(&pvt->sa, &pvt->recv, sizeof(pvt->sa)); 05877 } 05878 return 0; 05879 }
|
|
parse_register_contact: Parse contact header and save registration ---
Definition at line 5889 of file chan_sip.c. References sip_peer::addr, ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, ast_verbose(), default_expiry, DEFAULT_SIP_PORT, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, expiry, sip_peer::flags_page2, sip_peer::fullcontact, get_header(), get_in_brackets(), hp, inaddrcmp(), sip_peer::lastms, LOG_NOTICE, LOG_WARNING, manager_event(), max_expiry, n, option_verbose, sip_pvt::our_contact, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), SIP_NAT, SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), SIP_REALTIME, sip_pvt::sipoptions, sip_peer::sipoptions, strcasestr(), sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3. Referenced by register_verify(). 05890 { 05891 char contact[BUFSIZ]; 05892 char data[BUFSIZ]; 05893 char iabuf[INET_ADDRSTRLEN]; 05894 char *expires = get_header(req, "Expires"); 05895 int expiry = atoi(expires); 05896 char *c, *n, *pt; 05897 int port; 05898 char *useragent; 05899 struct hostent *hp; 05900 struct ast_hostent ahp; 05901 struct sockaddr_in oldsin; 05902 05903 if (ast_strlen_zero(expires)) { /* No expires header */ 05904 expires = strcasestr(get_header(req, "Contact"), ";expires="); 05905 if (expires) { 05906 char *ptr; 05907 if ((ptr = strchr(expires, ';'))) 05908 *ptr = '\0'; 05909 if (sscanf(expires + 9, "%d", &expiry) != 1) 05910 expiry = default_expiry; 05911 } else { 05912 /* Nothing has been specified */ 05913 expiry = default_expiry; 05914 } 05915 } 05916 /* Look for brackets */ 05917 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 05918 if (strchr(contact, '<') == NULL) { /* No <, check for ; and strip it */ 05919 char *ptr = strchr(contact, ';'); /* This is Header options, not URI options */ 05920 if (ptr) 05921 *ptr = '\0'; 05922 } 05923 c = get_in_brackets(contact); 05924 05925 /* if they did not specify Contact: or Expires:, they are querying 05926 what we currently have stored as their contact address, so return 05927 it 05928 */ 05929 if (ast_strlen_zero(c) && ast_strlen_zero(expires)) { 05930 /* If we have an active registration, tell them when the registration is going to expire */ 05931 if ((p->expire > -1) && !ast_strlen_zero(p->fullcontact)) { 05932 pvt->expiry = ast_sched_when(sched, p->expire); 05933 } 05934 return PARSE_REGISTER_QUERY; 05935 } else if (!strcasecmp(c, "*") || !expiry) { /* Unregister this peer */ 05936 /* This means remove all registrations and return OK */ 05937 memset(&p->addr, 0, sizeof(p->addr)); 05938 if (p->expire > -1) 05939 ast_sched_del(sched, p->expire); 05940 p->expire = -1; 05941 05942 destroy_association(p); 05943 05944 register_peer_exten(p, 0); 05945 p->fullcontact[0] = '\0'; 05946 p->useragent[0] = '\0'; 05947 p->sipoptions = 0; 05948 p->lastms = 0; 05949 05950 if (option_verbose > 2) 05951 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", p->name); 05952 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", p->name); 05953 return PARSE_REGISTER_UPDATE; 05954 } 05955 ast_copy_string(p->fullcontact, c, sizeof(p->fullcontact)); 05956 /* For the 200 OK, we should use the received contact */ 05957 snprintf(pvt->our_contact, sizeof(pvt->our_contact) - 1, "<%s>", c); 05958 /* Make sure it's a SIP URL */ 05959 if (strncasecmp(c, "sip:", 4)) { 05960 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c); 05961 } else 05962 c += 4; 05963 /* Ditch q */ 05964 n = strchr(c, ';'); 05965 if (n) { 05966 *n = '\0'; 05967 } 05968 /* Grab host */ 05969 n = strchr(c, '@'); 05970 if (!n) { 05971 n = c; 05972 c = NULL; 05973 } else { 05974 *n = '\0'; 05975 n++; 05976 } 05977 pt = strchr(n, ':'); 05978 if (pt) { 05979 *pt = '\0'; 05980 pt++; 05981 port = atoi(pt); 05982 } else 05983 port = DEFAULT_SIP_PORT; 05984 memcpy(&oldsin, &p->addr, sizeof(oldsin)); 05985 if (!(ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)) { 05986 /* XXX This could block for a long time XXX */ 05987 hp = ast_gethostbyname(n, &ahp); 05988 if (!hp) { 05989 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 05990 return PARSE_REGISTER_FAILED; 05991 } 05992 p->addr.sin_family = AF_INET; 05993 memcpy(&p->addr.sin_addr, hp->h_addr, sizeof(p->addr.sin_addr)); 05994 p->addr.sin_port = htons(port); 05995 } else { 05996 /* Don't trust the contact field. Just use what they came to us 05997 with */ 05998 memcpy(&p->addr, &pvt->recv, sizeof(p->addr)); 05999 } 06000 06001 if (c) /* Overwrite the default username from config at registration */ 06002 ast_copy_string(p->username, c, sizeof(p->username)); 06003 else 06004 p->username[0] = '\0'; 06005 06006 if (p->expire > -1) 06007 ast_sched_del(sched, p->expire); 06008 if ((expiry < 1) || (expiry > max_expiry)) 06009 expiry = max_expiry; 06010 if (!ast_test_flag(p, SIP_REALTIME)) 06011 p->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, p); 06012 else 06013 p->expire = -1; 06014 pvt->expiry = expiry; 06015 snprintf(data, sizeof(data), "%s:%d:%d:%s:%s", ast_inet_ntoa(iabuf, sizeof(iabuf), p->addr.sin_addr), ntohs(p->addr.sin_port), expiry, p->username, p->fullcontact); 06016 if (!ast_test_flag((&p->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 06017 ast_db_put("SIP/Registry", p->name, data); 06018 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", p->name); 06019 if (inaddrcmp(&p->addr, &oldsin)) { 06020 sip_poke_peer(p); 06021 if (option_verbose > 2) 06022 ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s port %d expires %d\n", p->name, ast_inet_ntoa(iabuf, sizeof(iabuf), p->addr.sin_addr), ntohs(p->addr.sin_port), expiry); 06023 register_peer_exten(p, 1); 06024 } 06025 06026 /* Save SIP options profile */ 06027 p->sipoptions = pvt->sipoptions; 06028 06029 /* Save User agent */ 06030 useragent = get_header(req, "User-Agent"); 06031 if (useragent && strcasecmp(useragent, p->useragent)) { 06032 ast_copy_string(p->useragent, useragent, sizeof(p->useragent)); 06033 if (option_verbose > 3) { 06034 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n",p->useragent,p->name); 06035 } 06036 } 06037 return PARSE_REGISTER_UPDATE; 06038 }
|
|
parse_request: Parse a SIP message ----
Definition at line 3341 of file chan_sip.c. References ast_log(), ast_strlen_zero(), determine_firstline_parts(), LOG_DEBUG, LOG_WARNING, option_debug, SIP_MAX_HEADERS, SIP_MAX_LINES, and sipdebug. Referenced by parse_copy(), sipsock_read(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_sip_request(). 03342 { 03343 /* Divide fields by NULL's */ 03344 char *c; 03345 int f = 0; 03346 03347 c = req->data; 03348 03349 /* First header starts immediately */ 03350 req->header[f] = c; 03351 while(*c) { 03352 if (*c == '\n') { 03353 /* We've got a new header */ 03354 *c = 0; 03355 03356 if (sipdebug && option_debug > 3) 03357 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 03358 if (ast_strlen_zero(req->header[f])) { 03359 /* Line by itself means we're now in content */ 03360 c++; 03361 break; 03362 } 03363 if (f >= SIP_MAX_HEADERS - 1) { 03364 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 03365 } else 03366 f++; 03367 req->header[f] = c + 1; 03368 } else if (*c == '\r') { 03369 /* Ignore but eliminate \r's */ 03370 *c = 0; 03371 } 03372 c++; 03373 } 03374 /* Check for last header */ 03375 if (!ast_strlen_zero(req->header[f])) { 03376 if (sipdebug && option_debug > 3) 03377 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 03378 f++; 03379 } 03380 req->headers = f; 03381 /* Now we process any mime content */ 03382 f = 0; 03383 req->line[f] = c; 03384 while(*c) { 03385 if (*c == '\n') { 03386 /* We've got a new line */ 03387 *c = 0; 03388 if (sipdebug && option_debug > 3) 03389 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 03390 if (f >= SIP_MAX_LINES - 1) { 03391 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 03392 } else 03393 f++; 03394 req->line[f] = c + 1; 03395 } else if (*c == '\r') { 03396 /* Ignore and eliminate \r's */ 03397 *c = 0; 03398 } 03399 c++; 03400 } 03401 /* Check for last line */ 03402 if (!ast_strlen_zero(req->line[f])) 03403 f++; 03404 req->lines = f; 03405 if (*c) 03406 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 03407 /* Split up the first line parts */ 03408 determine_firstline_parts(req); 03409 }
|
|
parse_sip_options: Parse supported header in incoming packet
Definition at line 992 of file chan_sip.c. References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_DEBUG, option_debug, sip_options, sipdebug, and text. Referenced by handle_request_invite(). 00993 { 00994 char *next = NULL; 00995 char *sep = NULL; 00996 char *temp = ast_strdupa(supported); 00997 int i; 00998 unsigned int profile = 0; 00999 01000 if (ast_strlen_zero(supported) ) 01001 return 0; 01002 01003 if (option_debug > 2 && sipdebug) 01004 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01005 01006 next = temp; 01007 while (next) { 01008 char res=0; 01009 if ( (sep = strchr(next, ',')) != NULL) { 01010 *sep = '\0'; 01011 sep++; 01012 } 01013 while (*next == ' ') /* Skip spaces */ 01014 next++; 01015 if (option_debug > 2 && sipdebug) 01016 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01017 for (i=0; (i < (sizeof(sip_options) / sizeof(sip_options[0]))) && !res; i++) { 01018 if (!strcasecmp(next, sip_options[i].text)) { 01019 profile |= sip_options[i].id; 01020 res = 1; 01021 if (option_debug > 2 && sipdebug) 01022 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01023 } 01024 } 01025 if (!res) 01026 if (option_debug > 2 && sipdebug) 01027 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01028 next = sep; 01029 } 01030 if (pvt) { 01031 pvt->sipoptions = profile; 01032 if (option_debug) 01033 ast_log(LOG_DEBUG, "* SIP extension value: %d for call %s\n", profile, pvt->callid); 01034 } 01035 return profile; 01036 }
|
|
peer_status: Report Peer status in character string
Definition at line 7465 of file chan_sip.c. References sip_peer::lastms, and sip_peer::maxms. 07466 { 07467 int res = 0; 07468 if (peer->maxms) { 07469 if (peer->lastms < 0) { 07470 ast_copy_string(status, "UNREACHABLE", statuslen); 07471 } else if (peer->lastms > peer->maxms) { 07472 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 07473 res = 1; 07474 } else if (peer->lastms) { 07475 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 07476 res = 1; 07477 } else { 07478 ast_copy_string(status, "UNKNOWN", statuslen); 07479 } 07480 } else { 07481 ast_copy_string(status, "Unmonitored", statuslen); 07482 /* Checking if port is 0 */ 07483 res = -1; 07484 } 07485 return res; 07486 }
|
|
print_codec_to_cli: Print codec list from preference to CLI/manager
Definition at line 7904 of file chan_sip.c. References ast_cli(), ast_codec_pref_index(), and ast_getformatname(). Referenced by _sip_show_peer(), and sip_show_settings(). 07905 { 07906 int x, codec; 07907 07908 for(x = 0; x < 32 ; x++) { 07909 codec = ast_codec_pref_index(pref, x); 07910 if (!codec) 07911 break; 07912 ast_cli(fd, "%s", ast_getformatname(codec)); 07913 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 07914 ast_cli(fd, ","); 07915 } 07916 if (!x) 07917 ast_cli(fd, "none"); 07918 }
|
|
print_group: Print call group and pickup group ---
Definition at line 7721 of file chan_sip.c. References ast_cli(), and ast_print_group(). Referenced by _sip_show_peer(), and sip_show_user(). 07722 { 07723 char buf[256]; 07724 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 07725 }
|
|
process_sdp: Process SIP SDP and activate RTP channels---
Definition at line 3474 of file chan_sip.c. References append_history(), ast_bridged_channel(), ast_clear_flag, ast_codec_choose(), AST_FRAME_NULL, ast_getformatname_multiple(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_moh_start(), ast_moh_stop(), ast_queue_frame(), AST_RTP_DTMF, ast_rtp_get_current_formats(), ast_rtp_lookup_mime_multiple(), ast_rtp_pt_clear(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_set_rtpmap_type(), ast_rtp_stop(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_verbose(), callevents, sip_request::data, debug, EVENT_FLAG_CALL, get_sdp(), get_sdp_iterate(), host, hp, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), noncodeccapability, pedanticsipchecking, portno, sdpLineNum_iterator_init(), SIP_CALL_ONHOLD, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, and SIP_NOVIDEO. 03475 { 03476 char *m; 03477 char *c; 03478 char *a; 03479 char host[258]; 03480 char iabuf[INET_ADDRSTRLEN]; 03481 int len = -1; 03482 int portno = -1; 03483 int vportno = -1; 03484 int peercapability, peernoncodeccapability; 03485 int vpeercapability=0, vpeernoncodeccapability=0; 03486 struct sockaddr_in sin; 03487 char *codecs; 03488 struct hostent *hp; 03489 struct ast_hostent ahp; 03490 int codec; 03491 int destiterator = 0; 03492 int iterator; 03493 int sendonly = 0; 03494 int x,y; 03495 int debug=sip_debug_test_pvt(p); 03496 struct ast_channel *bridgepeer = NULL; 03497 03498 if (!p->rtp) { 03499 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 03500 return -1; 03501 } 03502 03503 /* Update our last rtprx when we receive an SDP, too */ 03504 time(&p->lastrtprx); 03505 time(&p->lastrtptx); 03506 03507 m = get_sdp(req, "m"); 03508 sdpLineNum_iterator_init(&destiterator, req); 03509 c = get_sdp_iterate(&destiterator, req, "c"); 03510 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 03511 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 03512 return -1; 03513 } 03514 if (sscanf(c, "IN IP4 %256s", host) != 1) { 03515 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 03516 return -1; 03517 } 03518 /* XXX This could block for a long time, and block the main thread! XXX */ 03519 hp = ast_gethostbyname(host, &ahp); 03520 if (!hp) { 03521 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 03522 return -1; 03523 } 03524 sdpLineNum_iterator_init(&iterator, req); 03525 ast_set_flag(p, SIP_NOVIDEO); 03526 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 03527 int found = 0; 03528 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &y, &len) == 2) || 03529 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) { 03530 found = 1; 03531 portno = x; 03532 /* Scan through the RTP payload types specified in a "m=" line: */ 03533 ast_rtp_pt_clear(p->rtp); 03534 codecs = m + len; 03535 while(!ast_strlen_zero(codecs)) { 03536 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 03537 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 03538 return -1; 03539 } 03540 if (debug) 03541 ast_verbose("Found RTP audio format %d\n", codec); 03542 ast_rtp_set_m_type(p->rtp, codec); 03543 codecs = ast_skip_blanks(codecs + len); 03544 } 03545 } 03546 if (p->vrtp) 03547 ast_rtp_pt_clear(p->vrtp); /* Must be cleared in case no m=video line exists */ 03548 03549 if (p->vrtp && (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { 03550 found = 1; 03551 ast_clear_flag(p, SIP_NOVIDEO); 03552 vportno = x; 03553 /* Scan through the RTP payload types specified in a "m=" line: */ 03554 codecs = m + len; 03555 while(!ast_strlen_zero(codecs)) { 03556 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 03557 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 03558 return -1; 03559 } 03560 if (debug) 03561 ast_verbose("Found RTP video format %d\n", codec); 03562 ast_rtp_set_m_type(p->vrtp, codec); 03563 codecs = ast_skip_blanks(codecs + len); 03564 } 03565 } 03566 if (!found ) 03567 ast_log(LOG_WARNING, "Unknown SDP media type in offer: %s\n", m); 03568 } 03569 if (portno == -1 && vportno == -1) { 03570 /* No acceptable offer found in SDP */ 03571 return -2; 03572 } 03573 /* Check for Media-description-level-address for audio */ 03574 if (pedanticsipchecking) { 03575 c = get_sdp_iterate(&destiterator, req, "c"); 03576 if (!ast_strlen_zero(c)) { 03577 if (sscanf(c, "IN IP4 %256s", host) != 1) { 03578 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 03579 } else { 03580 /* XXX This could block for a long time, and block the main thread! XXX */ 03581 hp = ast_gethostbyname(host, &ahp); 03582 if (!hp) { 03583 ast_log(LOG_WARNING, "Unable to lookup host in secondary c= line, '%s'\n", c); 03584 } 03585 } 03586 } 03587 } 03588 /* RTP addresses and ports for audio and video */ 03589 sin.sin_family = AF_INET; 03590 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 03591 03592 /* Setup audio port number */ 03593 sin.sin_port = htons(portno); 03594 if (p->rtp && sin.sin_port) { 03595 ast_rtp_set_peer(p->rtp, &sin); 03596 if (debug) { 03597 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 03598 ast_log(LOG_DEBUG,"Peer audio RTP is at port %s:%d\n",ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 03599 } 03600 } 03601 /* Check for Media-description-level-address for video */ 03602 if (pedanticsipchecking) { 03603 c = get_sdp_iterate(&destiterator, req, "c"); 03604 if (!ast_strlen_zero(c)) { 03605 if (sscanf(c, "IN IP4 %256s", host) != 1) { 03606 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 03607 } else { 03608 /* XXX This could block for a long time, and block the main thread! XXX */ 03609 hp = ast_gethostbyname(host, &ahp); 03610 if (!hp) { 03611 ast_log(LOG_WARNING, "Unable to lookup host in secondary c= line, '%s'\n", c); 03612 } 03613 } 03614 } 03615 } 03616 /* Setup video port number */ 03617 sin.sin_port = htons(vportno); 03618 if (p->vrtp && sin.sin_port) { 03619 ast_rtp_set_peer(p->vrtp, &sin); 03620 if (debug) { 03621 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 03622 ast_log(LOG_DEBUG,"Peer video RTP is at port %s:%d\n",ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 03623 } 03624 } 03625 03626 /* Next, scan through each "a=rtpmap:" line, noting each 03627 * specified RTP payload type (with corresponding MIME subtype): 03628 */ 03629 sdpLineNum_iterator_init(&iterator, req); 03630 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 03631 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 03632 if (!strcasecmp(a, "sendonly") || !strcasecmp(a, "inactive")) { 03633 sendonly = 1; 03634 continue; 03635 } 03636 if (!strcasecmp(a, "sendrecv")) { 03637 sendonly = 0; 03638 } 03639 if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue; 03640 if (debug) 03641 ast_verbose("Found description format %s\n", mimeSubtype); 03642 /* Note: should really look at the 'freq' and '#chans' params too */ 03643 ast_rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype); 03644 if (p->vrtp) 03645 ast_rtp_set_rtpmap_type(p->vrtp, codec, "video", mimeSubtype); 03646 } 03647 03648 /* Now gather all of the codecs that were asked for: */ 03649 ast_rtp_get_current_formats(p->rtp, 03650 &peercapability, &peernoncodeccapability); 03651 if (p->vrtp) 03652 ast_rtp_get_current_formats(p->vrtp, 03653 &vpeercapability, &vpeernoncodeccapability); 03654 p->jointcapability = p->capability & (peercapability | vpeercapability); 03655 p->peercapability = (peercapability | vpeercapability); 03656 p->noncodeccapability = noncodeccapability & peernoncodeccapability; 03657 03658 if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO) { 03659 ast_clear_flag(p, SIP_DTMF); 03660 if (p->noncodeccapability & AST_RTP_DTMF) { 03661 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 03662 ast_set_flag(p, SIP_DTMF_RFC2833); 03663 } else { 03664 ast_set_flag(p, SIP_DTMF_INBAND); 03665 } 03666 } 03667 03668 if (debug) { 03669 /* shame on whoever coded this.... */ 03670 const unsigned slen=512; 03671 char s1[slen], s2[slen], s3[slen], s4[slen]; 03672 03673 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 03674 ast_getformatname_multiple(s1, slen, p->capability), 03675 ast_getformatname_multiple(s2, slen, peercapability), 03676 ast_getformatname_multiple(s3, slen, vpeercapability), 03677 ast_getformatname_multiple(s4, slen, p->jointcapability)); 03678 03679 ast_verbose("Non-codec capabilities: us - %s, peer - %s, combined - %s\n", 03680 ast_rtp_lookup_mime_multiple(s1, slen, noncodeccapability, 0), 03681 ast_rtp_lookup_mime_multiple(s2, slen, peernoncodeccapability, 0), 03682 ast_rtp_lookup_mime_multiple(s3, slen, p->noncodeccapability, 0)); 03683 } 03684 if (!p->jointcapability) { 03685 ast_log(LOG_NOTICE, "No compatible codecs!\n"); 03686 return -1; 03687 } 03688 03689 if (!p->owner) /* There's no open channel owning us */ 03690 return 0; 03691 03692 if (!(p->owner->nativeformats & p->jointcapability)) { 03693 const unsigned slen=512; 03694 char s1[slen], s2[slen]; 03695 ast_log(LOG_DEBUG, "Oooh, we need to change our formats since our peer supports only %s and not %s\n", 03696 ast_getformatname_multiple(s1, slen, p->jointcapability), 03697 ast_getformatname_multiple(s2, slen, p->owner->nativeformats)); 03698 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1); 03699 ast_set_read_format(p->owner, p->owner->readformat); 03700 ast_set_write_format(p->owner, p->owner->writeformat); 03701 } 03702 if ((bridgepeer=ast_bridged_channel(p->owner))) { 03703 /* We have a bridge */ 03704 /* Turn on/off music on hold if we are holding/unholding */ 03705 struct ast_frame af = { AST_FRAME_NULL, }; 03706 if (sin.sin_addr.s_addr && !sendonly) { 03707 ast_moh_stop(bridgepeer); 03708 03709 /* Activate a re-invite */ 03710 ast_queue_frame(p->owner, &af); 03711 } else { 03712 /* No address for RTP, we're on hold */ 03713 03714 ast_moh_start(bridgepeer, NULL); 03715 if (sendonly) 03716 ast_rtp_stop(p->rtp); 03717 /* Activate a re-invite */ 03718 ast_queue_frame(p->owner, &af); 03719 } 03720 } 03721 03722 /* Manager Hold and Unhold events must be generated, if necessary */ 03723 if (sin.sin_addr.s_addr && !sendonly) { 03724 append_history(p, "Unhold", req->data); 03725 03726 if (callevents && ast_test_flag(p, SIP_CALL_ONHOLD)) { 03727 manager_event(EVENT_FLAG_CALL, "Unhold", 03728 "Channel: %s\r\n" 03729 "Uniqueid: %s\r\n", 03730 p->owner->name, 03731 p->owner->uniqueid); 03732 03733 } 03734 ast_clear_flag(p, SIP_CALL_ONHOLD); 03735 } else { 03736 /* No address for RTP, we're on hold */ 03737 append_history(p, "Hold", req->data); 03738 03739 if (callevents && !ast_test_flag(p, SIP_CALL_ONHOLD)) { 03740 manager_event(EVENT_FLAG_CALL, "Hold", 03741 "Channel: %s\r\n" 03742 "Uniqueid: %s\r\n", 03743 p->owner->name, 03744 p->owner->uniqueid); 03745 } 03746 ast_set_flag(p, SIP_CALL_ONHOLD); 03747 } 03748 03749 return 0; 03750 }
|
|
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
Definition at line 1677 of file chan_sip.c. References ast_copy_flags, ast_inet_ntoa(), ast_load_realtime(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_test_flag, ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, build_peer(), sip_peer::expire, expire_register(), sip_peer::flags_page2, global_rtautoclear, LOG_WARNING, ast_variable::name, ast_variable::next, peerl, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, ast_variable::value, and var. 01678 { 01679 struct sip_peer *peer=NULL; 01680 struct ast_variable *var; 01681 struct ast_variable *tmp; 01682 char *newpeername = (char *) peername; 01683 char iabuf[80]; 01684 01685 /* First check on peer name */ 01686 if (newpeername) 01687 var = ast_load_realtime("sippeers", "name", peername, NULL); 01688 else if (sin) { /* Then check on IP address */ 01689 ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr); 01690 var = ast_load_realtime("sippeers", "host", iabuf, NULL); /* First check for fixed IP hosts */ 01691 if (!var) 01692 var = ast_load_realtime("sippeers", "ipaddr", iabuf, NULL); /* Then check for registred hosts */ 01693 01694 } else 01695 return NULL; 01696 01697 if (!var) 01698 return NULL; 01699 01700 tmp = var; 01701 /* If this is type=user, then skip this object. */ 01702 while(tmp) { 01703 if (!strcasecmp(tmp->name, "type") && 01704 !strcasecmp(tmp->value, "user")) { 01705 ast_variables_destroy(var); 01706 return NULL; 01707 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 01708 newpeername = tmp->value; 01709 } 01710 tmp = tmp->next; 01711 } 01712 01713 if (!newpeername) { /* Did not find peer in realtime */ 01714 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 01715 ast_variables_destroy(var); 01716 return (struct sip_peer *) NULL; 01717 } 01718 01719 /* Peer found in realtime, now build it in memory */ 01720 peer = build_peer(newpeername, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)); 01721 if (!peer) { 01722 ast_variables_destroy(var); 01723 return (struct sip_peer *) NULL; 01724 } 01725 01726 if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 01727 /* Cache peer */ 01728 ast_copy_flags((&peer->flags_page2),(&global_flags_page2), SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 01729 if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTAUTOCLEAR)) { 01730 if (peer->expire > -1) { 01731 ast_sched_del(sched, peer->expire); 01732 } 01733 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, (void *)peer); 01734 } 01735 ASTOBJ_CONTAINER_LINK(&peerl,peer); 01736 } else { 01737 ast_set_flag(peer, SIP_REALTIME); 01738 } 01739 ast_variables_destroy(var); 01740 01741 return peer; 01742 }
|
|
realtime_update_peer: Update peer object in realtime storage ---
Definition at line 1599 of file chan_sip.c. References ast_inet_ntoa(), ast_update_realtime(), and ipaddr. 01600 { 01601 char port[10]; 01602 char ipaddr[20]; 01603 char regseconds[20]; 01604 time_t nowtime; 01605 01606 time(&nowtime); 01607 nowtime += expirey; 01608 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 01609 ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr); 01610 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 01611 01612 if (fullcontact) 01613 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, "fullcontact", fullcontact, NULL); 01614 else 01615 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, NULL); 01616 }
|
|
realtime_user: 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 1791 of file chan_sip.c. References ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, build_user(), sip_user::flags_page2, ruserobjs, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, suserobjs, user, userl, and var. 01792 { 01793 struct ast_variable *var; 01794 struct ast_variable *tmp; 01795 struct sip_user *user = NULL; 01796 01797 var = ast_load_realtime("sipusers", "name", username, NULL); 01798 01799 if (!var) 01800 return NULL; 01801 01802 tmp = var; 01803 while (tmp) { 01804 if (!strcasecmp(tmp->name, "type") && 01805 !strcasecmp(tmp->value, "peer")) { 01806 ast_variables_destroy(var); 01807 return NULL; 01808 } 01809 tmp = tmp->next; 01810 } 01811 01812 01813 01814 user = build_user(username, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)); 01815 01816 if (!user) { /* No user found */ 01817 ast_variables_destroy(var); 01818 return NULL; 01819 } 01820 01821 if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 01822 ast_set_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS); 01823 suserobjs++; 01824 ASTOBJ_CONTAINER_LINK(&userl,user); 01825 } else { 01826 /* Move counter from s to r... */ 01827 suserobjs--; 01828 ruserobjs++; 01829 ast_set_flag(user, SIP_REALTIME); 01830 } 01831 ast_variables_destroy(var); 01832 return user; 01833 }
|
|
receive_message: Receive SIP MESSAGE method messages ---
Definition at line 7360 of file chan_sip.c. References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_set_flag, ast_verbose(), sip_pvt::callid, get_header(), get_msg_text(), LOG_WARNING, sip_pvt::owner, sip_debug_test_pvt(), SIP_NEEDDESTROY, and transmit_response(). Referenced by handle_request_message(). 07361 { 07362 char buf[1024]; 07363 struct ast_frame f; 07364 char *content_type; 07365 07366 content_type = get_header(req, "Content-Type"); 07367 if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */ 07368 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 07369 ast_set_flag(p, SIP_NEEDDESTROY); 07370 return; 07371 } 07372 07373 if (get_msg_text(buf, sizeof(buf), req)) { 07374 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 07375 transmit_response(p, "202 Accepted", req); 07376 ast_set_flag(p, SIP_NEEDDESTROY); 07377 return; 07378 } 07379 07380 if (p->owner) { 07381 if (sip_debug_test_pvt(p)) 07382 ast_verbose("Message received: '%s'\n", buf); 07383 memset(&f, 0, sizeof(f)); 07384 f.frametype = AST_FRAME_TEXT; 07385 f.subclass = 0; 07386 f.offset = 0; 07387 f.data = buf; 07388 f.datalen = strlen(buf); 07389 ast_queue_frame(p->owner, &f); 07390 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 07391 } else { /* Message outside of a call, we do not support that */ 07392 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); 07393 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 07394 } 07395 ast_set_flag(p, SIP_NEEDDESTROY); 07396 return; 07397 }
|
|
reg_source_db: Get registration details from Asterisk DB ---
Definition at line 5752 of file chan_sip.c. References sip_peer::addr, ast_db_get(), ast_inet_ntoa(), ast_sched_add(), ast_sched_del(), ast_test_flag, ast_verbose(), sip_peer::expire, expire_register(), expiry, sip_peer::flags_page2, sip_peer::fullcontact, option_verbose, sip_peer::pokeexpire, register_peer_exten(), SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, strsep(), thread_safe_rand(), sip_peer::username, username, and VERBOSE_PREFIX_3. 05753 { 05754 char data[256]; 05755 char iabuf[INET_ADDRSTRLEN]; 05756 struct in_addr in; 05757 int expiry; 05758 int port; 05759 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 05760 05761 if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 05762 return; 05763 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 05764 return; 05765 05766 scan = data; 05767 addr = strsep(&scan, ":"); 05768 port_str = strsep(&scan, ":"); 05769 expiry_str = strsep(&scan, ":"); 05770 username = strsep(&scan, ":"); 05771 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 05772 05773 if (!inet_aton(addr, &in)) 05774 return; 05775 05776 if (port_str) 05777 port = atoi(port_str); 05778 else 05779 return; 05780 05781 if (expiry_str) 05782 expiry = atoi(expiry_str); 05783 else 05784 return; 05785 05786 if (username) 05787 ast_copy_string(peer->username, username, sizeof(peer->username)); 05788 if (contact) 05789 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 05790 05791 if (option_verbose > 2) 05792 ast_verbose(VERBOSE_PREFIX_3 "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 05793 peer->name, peer->username, ast_inet_ntoa(iabuf, sizeof(iabuf), in), port, expiry); 05794 05795 memset(&peer->addr, 0, sizeof(peer->addr)); 05796 peer->addr.sin_family = AF_INET; 05797 peer->addr.sin_addr = in; 05798 peer->addr.sin_port = htons(port); 05799 if (sipsock < 0) { 05800 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 05801 if (peer->pokeexpire > -1) 05802 ast_sched_del(sched, peer->pokeexpire); 05803 peer->pokeexpire = ast_sched_add(sched, thread_safe_rand() % 5000 + 1, sip_poke_peer_s, peer); 05804 } else 05805 sip_poke_peer(peer); 05806 if (peer->expire > -1) 05807 ast_sched_del(sched, peer->expire); 05808 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 05809 register_peer_exten(peer, 1); 05810 }
|
|
register_peer_exten: Automatically add peer extension to dial plan ---
Definition at line 1619 of file chan_sip.c. References ast_add_extension(), ast_context_remove_extension(), ast_strlen_zero(), channeltype, free, regcontext, sip_peer::regexten, strdup, and strsep(). 01620 { 01621 char multi[256]; 01622 char *stringp, *ext; 01623 if (!ast_strlen_zero(regcontext)) { 01624 ast_copy_string(multi, ast_strlen_zero(peer->regexten) ? peer->name : peer->regexten, sizeof(multi)); 01625 stringp = multi; 01626 while((ext = strsep(&stringp, "&"))) { 01627 if (onoff) 01628 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), free, channeltype); 01629 else 01630 ast_context_remove_extension(regcontext, ext, 1, NULL); 01631 } 01632 } 01633 }
|
|
register_verify: Verify registration of user
Definition at line 6444 of file chan_sip.c. References ast_apply_ha(), ast_copy_flags, ast_device_state_changed(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, autocreatepeer, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, sip_pvt::exten, find_peer(), sip_peer::flags_page2, get_header(), get_in_brackets(), global_alwaysauthreject, sip_peer::ha, sip_pvt::initreq, sip_peer::lastmsgssent, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), sip_peer::md5secret, name, option_debug, parse_register_contact(), PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, pedanticsipchecking, peerl, sip_pvt::randdata, sip_peer::secret, sip_cancel_destroy(), sip_destroy_peer(), SIP_NAT, SIP_PAGE2_DYNAMIC, SIP_REGISTER, t, temp_peer(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), and update_peer(). 06445 { 06446 int res = -3; 06447 struct sip_peer *peer; 06448 char tmp[256]; 06449 char iabuf[INET_ADDRSTRLEN]; 06450 char *name, *c; 06451 char *t; 06452 char *domain; 06453 06454 /* Terminate URI */ 06455 t = uri; 06456 while(*t && (*t > 32) && (*t != ';')) 06457 t++; 06458 *t = '\0'; 06459 06460 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 06461 if (pedanticsipchecking) 06462 ast_uri_decode(tmp); 06463 06464 c = get_in_brackets(tmp); 06465 /* Ditch ;user=phone */ 06466 name = strchr(c, ';'); 06467 if (name) 06468 *name = '\0'; 06469 06470 if (!strncmp(c, "sip:", 4)) { 06471 name = c + 4; 06472 } else { 06473 name = c; 06474 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 06475 } 06476 06477 /* Strip off the domain name */ 06478 if ((c = strchr(name, '@'))) { 06479 *c++ = '\0'; 06480 domain = c; 06481 if ((c = strchr(domain, ':'))) /* Remove :port */ 06482 *c = '\0'; 06483 if (!AST_LIST_EMPTY(&domain_list)) { 06484 if (!check_sip_domain(domain, NULL, 0)) { 06485 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 06486 return -3; 06487 } 06488 } 06489 } 06490 06491 ast_copy_string(p->exten, name, sizeof(p->exten)); 06492 build_contact(p); 06493 peer = find_peer(name, NULL, 1); 06494 if (!(peer && ast_apply_ha(peer->ha, sin))) { 06495 if (peer) 06496 ASTOBJ_UNREF(peer,sip_destroy_peer); 06497 } 06498 if (peer) { 06499 if (!ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)) { 06500 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 06501 } else { 06502 ast_copy_flags(p, peer, SIP_NAT); 06503 transmit_response(p, "100 Trying", req); 06504 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, 0, ignore))) { 06505 sip_cancel_destroy(p); 06506 switch (parse_register_contact(p, peer, req)) { 06507 case PARSE_REGISTER_FAILED: 06508 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 06509 transmit_response_with_date(p, "400 Bad Request", req); 06510 peer->lastmsgssent = -1; 06511 res = 0; 06512 break; 06513 case PARSE_REGISTER_QUERY: 06514 transmit_response_with_date(p, "200 OK", req); 06515 peer->lastmsgssent = -1; 06516 res = 0; 06517 break; 06518 case PARSE_REGISTER_UPDATE: 06519 update_peer(peer, p->expiry); 06520 /* Say OK and ask subsystem to retransmit msg counter */ 06521 transmit_response_with_date(p, "200 OK", req); 06522 peer->lastmsgssent = -1; 06523 res = 0; 06524 break; 06525 } 06526 } 06527 } 06528 } 06529 if (!peer && autocreatepeer) { 06530 /* Create peer if we have autocreate mode enabled */ 06531 peer = temp_peer(name); 06532 if (peer) { 06533 ASTOBJ_CONTAINER_LINK(&peerl, peer); 06534 sip_cancel_destroy(p); 06535 switch (parse_register_contact(p, peer, req)) { 06536 case PARSE_REGISTER_FAILED: 06537 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 06538 transmit_response_with_date(p, "400 Bad Request", req); 06539 peer->lastmsgssent = -1; 06540 res = 0; 06541 break; 06542 case PARSE_REGISTER_QUERY: 06543 transmit_response_with_date(p, "200 OK", req); 06544 peer->lastmsgssent = -1; 06545 res = 0; 06546 break; 06547 case PARSE_REGISTER_UPDATE: 06548 /* Say OK and ask subsystem to retransmit msg counter */ 06549 transmit_response_with_date(p, "200 OK", req); 06550 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 06551 peer->lastmsgssent = -1; 06552 res = 0; 06553 break; 06554 } 06555 } 06556 } 06557 if (!res) { 06558 ast_device_state_changed("SIP/%s", peer->name); 06559 } 06560 if (res < 0) { 06561 switch (res) { 06562 case -1: 06563 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 06564 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 06565 break; 06566 case -2: 06567 /* Username and digest username does not match. 06568 Asterisk uses the From: username for authentication. We need the 06569 users to use the same authentication user name until we support 06570 proper authentication by digest auth name */ 06571 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 06572 break; 06573 case -3: 06574 if (global_alwaysauthreject) { 06575 transmit_fake_auth_response(p, &p->initreq, p->randdata, sizeof(p->randdata), 1); 06576 } else { 06577 /* URI not found */ 06578 transmit_response(p, "404 Not found", &p->initreq); 06579 } 06580 /* Set res back to -2 because we don't want to return an invalid domain message. That check already happened up above. */ 06581 res = -2; 06582 break; 06583 } 06584 if (option_debug > 1) { 06585 ast_log(LOG_DEBUG, "SIP REGISTER attempt failed for %s : %s\n", 06586 peer->name, 06587 (res == -1) ? "Bad password" : ((res == -2 ) ? "Bad digest user" : "Peer not found")); 06588 } 06589 } 06590 if (peer) 06591 ASTOBJ_UNREF(peer,sip_destroy_peer); 06592 06593 return res; 06594 }
|
|
Definition at line 5292 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. 05293 { 05294 switch(regstate) { 05295 case REG_STATE_FAILED: 05296 return "Failed"; 05297 case REG_STATE_UNREGISTERED: 05298 return "Unregistered"; 05299 case REG_STATE_REGSENT: 05300 return "Request Sent"; 05301 case REG_STATE_AUTHSENT: 05302 return "Auth. Sent"; 05303 case REG_STATE_REGISTERED: 05304 return "Registered"; 05305 case REG_STATE_REJECTED: 05306 return "Rejected"; 05307 case REG_STATE_TIMEOUT: 05308 return "Timeout"; 05309 case REG_STATE_NOAUTH: 05310 return "No Authentication"; 05311 default: 05312 return "Unknown"; 05313 } 05314 }
|
|
Reload stuff. This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.
Definition at line 13280 of file chan_sip.c. References sip_reload(). 13281 { 13282 return sip_reload(0, 0, NULL); 13283 }
|
|
reload_config: Re-read SIP.conf config file ---
Definition at line 12467 of file chan_sip.c. References __ourip, add_realm_authentication(), add_sip_domain(), allow_external_domains, ast_append_ha(), ast_category_browse(), ast_clear_flag, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), ast_find_ourip(), AST_FLAGS_ALL, ast_get_ip_or_srv(), ast_gethostbyname(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_str2tos(), ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, authl, autocreatepeer, bindaddr, build_peer(), build_user(), callevents, cfg, channeltype, compactheaders, config, context, DEFAULT_CALLERID, default_callerid, DEFAULT_CONTEXT, default_context, DEFAULT_DEFAULT_EXPIRY, default_expiry, DEFAULT_EXPIRY, default_fromdomain, default_language, DEFAULT_MAX_EXPIRY, DEFAULT_MAXMS, DEFAULT_MWITIME, DEFAULT_NOTIFYMIME, default_notifymime, default_qualify, DEFAULT_REALM, DEFAULT_REGISTRATION_TIMEOUT, DEFAULT_SIP_PORT, default_subscribecontext, DEFAULT_USERAGENT, default_useragent, DEFAULT_VMEXTEN, dumphistory, expiry, externexpire, externhost, externip, externrefresh, format, global_allowguest, global_alwaysauthreject, global_capability, global_musicclass, global_mwitime, global_notifyringing, global_realm, global_reg_timeout, global_regattempts_max, global_rtautoclear, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, global_vmexten, handle_common_options(), hp, ast_variable::lineno, localaddr, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, max_expiry, ast_variable::name, ast_variable::next, notify_config, notify_types, option_debug, option_verbose, ourport, outboundproxyip, pedanticsipchecking, peerl, recordhistory, regcontext, relaxdtmf, SIP_CAN_REINVITE, SIP_DEBUG_CONFIG, sip_destroy_peer(), sip_destroy_user(), SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG, SIP_DTMF_RFC2833, SIP_NAT_RFC3581, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, sip_register(), SIP_USEREQPHONE, sipdebug, sipsock, srvlookup, tos, user, userl, ast_variable::value, VERBOSE_PREFIX_2, and videosupport. 12468 { 12469 struct ast_config *cfg; 12470 struct ast_variable *v; 12471 struct sip_peer *peer; 12472 struct sip_user *user; 12473 struct ast_hostent ahp; 12474 char *cat; 12475 char *utype; 12476 struct hostent *hp; 12477 int format; 12478 char iabuf[INET_ADDRSTRLEN]; 12479 struct ast_flags dummy; 12480 int auto_sip_domains = 0; 12481 struct sockaddr_in old_bindaddr = bindaddr; 12482 12483 cfg = ast_config_load(config); 12484 12485 /* We *must* have a config file otherwise stop immediately */ 12486 if (!cfg) { 12487 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 12488 return -1; 12489 } 12490 12491 /* Reset IP addresses */ 12492 memset(&bindaddr, 0, sizeof(bindaddr)); 12493 memset(&localaddr, 0, sizeof(localaddr)); 12494 memset(&externip, 0, sizeof(externip)); 12495 memset(&prefs, 0 , sizeof(prefs)); 12496 sipdebug &= ~SIP_DEBUG_CONFIG; 12497 12498 /* Initialize some reasonable defaults at SIP reload */ 12499 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 12500 default_subscribecontext[0] = '\0'; 12501 default_language[0] = '\0'; 12502 default_fromdomain[0] = '\0'; 12503 default_qualify = 0; 12504 allow_external_domains = 1; /* Allow external invites */ 12505 externhost[0] = '\0'; 12506 externexpire = 0; 12507 externrefresh = 10; 12508 ast_copy_string(default_useragent, DEFAULT_USERAGENT, sizeof(default_useragent)); 12509 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 12510 global_notifyringing = 1; 12511 global_alwaysauthreject = 0; 12512 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 12513 ast_copy_string(global_musicclass, "default", sizeof(global_musicclass)); 12514 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 12515 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 12516 outboundproxyip.sin_port = htons(DEFAULT_SIP_PORT); 12517 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 12518 videosupport = 0; 12519 compactheaders = 0; 12520 dumphistory = 0; 12521 recordhistory = 0; 12522 relaxdtmf = 0; 12523 callevents = 0; 12524 ourport = DEFAULT_SIP_PORT; 12525 global_rtptimeout = 0; 12526 global_rtpholdtimeout = 0; 12527 global_rtpkeepalive = 0; 12528 global_rtautoclear = 120; 12529 pedanticsipchecking = 0; 12530 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 12531 global_regattempts_max = 0; 12532 ast_clear_flag(&global_flags, AST_FLAGS_ALL); 12533 ast_clear_flag(&global_flags_page2, AST_FLAGS_ALL); 12534 ast_set_flag(&global_flags, SIP_DTMF_RFC2833); 12535 ast_set_flag(&global_flags, SIP_NAT_RFC3581); 12536 ast_set_flag(&global_flags, SIP_CAN_REINVITE); 12537 ast_set_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE); 12538 global_mwitime = DEFAULT_MWITIME; 12539 strcpy(global_vmexten, DEFAULT_VMEXTEN); 12540 srvlookup = 0; 12541 autocreatepeer = 0; 12542 regcontext[0] = '\0'; 12543 tos = 0; 12544 expiry = DEFAULT_EXPIRY; 12545 global_allowguest = 1; 12546 12547 /* Read the [general] config section of sip.conf (or from realtime config) */ 12548 v = ast_variable_browse(cfg, "general"); 12549 while(v) { 12550 if (handle_common_options(&global_flags, &dummy, v)) { 12551 v = v->next; 12552 continue; 12553 } 12554 12555 /* Create the interface list */ 12556 if (!strcasecmp(v->name, "context")) { 12557 ast_copy_string(default_context, v->value, sizeof(default_context)); 12558 } else if (!strcasecmp(v->name, "realm")) { 12559 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 12560 } else if (!strcasecmp(v->name, "useragent")) { 12561 ast_copy_string(default_useragent, v->value, sizeof(default_useragent)); 12562 ast_log(LOG_DEBUG, "Setting User Agent Name to %s\n", 12563 default_useragent); 12564 } else if (!strcasecmp(v->name, "rtcachefriends")) { 12565 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 12566 } else if (!strcasecmp(v->name, "rtupdate")) { 12567 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTUPDATE); 12568 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 12569 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 12570 } else if (!strcasecmp(v->name, "rtautoclear")) { 12571 int i = atoi(v->value); 12572 if (i > 0) 12573 global_rtautoclear = i; 12574 else 12575 i = 0; 12576 ast_set2_flag((&global_flags_page2), i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 12577 } else if (!strcasecmp(v->name, "usereqphone")) { 12578 ast_set2_flag((&global_flags), ast_true(v->value), SIP_USEREQPHONE); 12579 } else if (!strcasecmp(v->name, "relaxdtmf")) { 12580 relaxdtmf = ast_true(v->value); 12581 } else if (!strcasecmp(v->name, "checkmwi")) { 12582 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 12583 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 12584 global_mwitime = DEFAULT_MWITIME; 12585 } 12586 } else if (!strcasecmp(v->name, "vmexten")) { 12587 ast_copy_string(global_vmexten, v->value, sizeof(global_vmexten)); 12588 } else if (!strcasecmp(v->name, "rtptimeout")) { 12589 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 12590 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12591 global_rtptimeout = 0; 12592 } 12593 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 12594 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 12595 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12596 global_rtpholdtimeout = 0; 12597 } 12598 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 12599 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 12600 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 12601 global_rtpkeepalive = 0; 12602 } 12603 } else if (!strcasecmp(v->name, "videosupport")) { 12604 videosupport = ast_true(v->value); 12605 } else if (!strcasecmp(v->name, "compactheaders")) { 12606 compactheaders = ast_true(v->value); 12607 } else if (!strcasecmp(v->name, "notifymimetype")) { 12608 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 12609 } else if (!strcasecmp(v->name, "notifyringing")) { 12610 global_notifyringing = ast_true(v->value); 12611 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 12612 global_alwaysauthreject = ast_true(v->value); 12613 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 12614 ast_copy_string(global_musicclass, v->value, sizeof(global_musicclass)); 12615 } else if (!strcasecmp(v->name, "language")) { 12616 ast_copy_string(default_language, v->value, sizeof(default_language)); 12617 } else if (!strcasecmp(v->name, "regcontext")) { 12618 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 12619 /* Create context if it doesn't exist already */ 12620 if (!ast_context_find(regcontext)) 12621 ast_context_create(NULL, regcontext, channeltype); 12622 } else if (!strcasecmp(v->name, "callerid")) { 12623 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 12624 } else if (!strcasecmp(v->name, "fromdomain")) { 12625 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 12626 } else if (!strcasecmp(v->name, "outboundproxy")) { 12627 if (ast_get_ip_or_srv(&outboundproxyip, v->value, "_sip._udp") < 0) 12628 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 12629 } else if (!strcasecmp(v->name, "outboundproxyport")) { 12630 /* Port needs to be after IP */ 12631 sscanf(v->value, "%d", &format); 12632 outboundproxyip.sin_port = htons(format); 12633 } else if (!strcasecmp(v->name, "autocreatepeer")) { 12634 autocreatepeer = ast_true(v->value); 12635 } else if (!strcasecmp(v->name, "srvlookup")) { 12636 srvlookup = ast_true(v->value); 12637 } else if (!strcasecmp(v->name, "pedantic")) { 12638 pedanticsipchecking = ast_true(v->value); 12639 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 12640 max_expiry = atoi(v->value); 12641 if (max_expiry < 1) 12642 max_expiry = DEFAULT_MAX_EXPIRY; 12643 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 12644 default_expiry = atoi(v->value); 12645 if (default_expiry < 1) 12646 default_expiry = DEFAULT_DEFAULT_EXPIRY; 12647 } else if (!strcasecmp(v->name, "sipdebug")) { 12648 if (ast_true(v->value)) 12649 sipdebug |= SIP_DEBUG_CONFIG; 12650 } else if (!strcasecmp(v->name, "dumphistory")) { 12651 dumphistory = ast_true(v->value); 12652 } else if (!strcasecmp(v->name, "recordhistory")) { 12653 recordhistory = ast_true(v->value); 12654 } else if (!strcasecmp(v->name, "registertimeout")) { 12655 global_reg_timeout = atoi(v->value); 12656 if (global_reg_timeout < 1) 12657 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 12658 } else if (!strcasecmp(v->name, "registerattempts")) { 12659 global_regattempts_max = atoi(v->value); 12660 } else if (!strcasecmp(v->name, "bindaddr")) { 12661 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 12662 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 12663 } else { 12664 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 12665 } 12666 } else if (!strcasecmp(v->name, "localnet")) { 12667 struct ast_ha *na; 12668 if (!(na = ast_append_ha("d", v->value, localaddr))) 12669 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 12670 else 12671 localaddr = na; 12672 } else if (!strcasecmp(v->name, "localmask")) { 12673 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 12674 } else if (!strcasecmp(v->name, "externip")) { 12675 if (!(hp = ast_gethostbyname(v->value, &ahp))) 12676 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 12677 else 12678 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 12679 externexpire = 0; 12680 } else if (!strcasecmp(v->name, "externhost")) { 12681 ast_copy_string(externhost, v->value, sizeof(externhost)); 12682 if (!(hp = ast_gethostbyname(externhost, &ahp))) 12683 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 12684 else 12685 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 12686 time(&externexpire); 12687 } else if (!strcasecmp(v->name, "externrefresh")) { 12688 if (sscanf(v->value, "%d", &externrefresh) != 1) { 12689 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 12690 externrefresh = 10; 12691 } 12692 } else if (!strcasecmp(v->name, "allow")) { 12693 ast_parse_allow_disallow(&prefs, &global_capability, v->value, 1); 12694 } else if (!strcasecmp(v->name, "disallow")) { 12695 ast_parse_allow_disallow(&prefs, &global_capability, v->value, 0); 12696 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 12697 allow_external_domains = ast_true(v->value); 12698 } else if (!strcasecmp(v->name, "autodomain")) { 12699 auto_sip_domains = ast_true(v->value); 12700 } else if (!strcasecmp(v->name, "domain")) { 12701 char *domain = ast_strdupa(v->value); 12702 char *context = strchr(domain, ','); 12703 12704 if (context) 12705 *context++ = '\0'; 12706 12707 if (option_debug && ast_strlen_zero(context)) 12708 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 12709 if (ast_strlen_zero(domain)) 12710 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 12711 else 12712 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 12713 } else if (!strcasecmp(v->name, "register")) { 12714 sip_register(v->value, v->lineno); 12715 } else if (!strcasecmp(v->name, "tos")) { 12716 if (ast_str2tos(v->value, &tos)) 12717 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 12718 } else if (!strcasecmp(v->name, "bindport")) { 12719 if (sscanf(v->value, "%d", &ourport) == 1) { 12720 bindaddr.sin_port = htons(ourport); 12721 } else { 12722 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 12723 } 12724 } else if (!strcasecmp(v->name, "qualify")) { 12725 if (!strcasecmp(v->value, "no")) { 12726 default_qualify = 0; 12727 } else if (!strcasecmp(v->value, "yes")) { 12728 default_qualify = DEFAULT_MAXMS; 12729 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 12730 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 12731 default_qualify = 0; 12732 } 12733 } else if (!strcasecmp(v->name, "callevents")) { 12734 callevents = ast_true(v->value); 12735 } 12736 /* else if (strcasecmp(v->name,"type")) 12737 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 12738 */ 12739 v = v->next; 12740 } 12741 12742 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 12743 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 12744 allow_external_domains = 1; 12745 } 12746 12747 /* Build list of authentication to various SIP realms, i.e. service providers */ 12748 v = ast_variable_browse(cfg, "authentication"); 12749 while(v) { 12750 /* Format for authentication is auth = username:password@realm */ 12751 if (!strcasecmp(v->name, "auth")) { 12752 authl = add_realm_authentication(authl, v->value, v->lineno); 12753 } 12754 v = v->next; 12755 } 12756 12757 /* Load peers, users and friends */ 12758 cat = ast_category_browse(cfg, NULL); 12759 while(cat) { 12760 if (strcasecmp(cat, "general") && strcasecmp(cat, "authentication")) { 12761 utype = ast_variable_retrieve(cfg, cat, "type"); 12762 if (utype) { 12763 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 12764 user = build_user(cat, ast_variable_browse(cfg, cat), 0); 12765 if (user) { 12766 ASTOBJ_CONTAINER_LINK(&userl,user); 12767 ASTOBJ_UNREF(user, sip_destroy_user); 12768 } 12769 } 12770 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 12771 peer = build_peer(cat, ast_variable_browse(cfg, cat), 0); 12772 if (peer) { 12773 ASTOBJ_CONTAINER_LINK(&peerl,peer); 12774 ASTOBJ_UNREF(peer, sip_destroy_peer); 12775 } 12776 } else if (strcasecmp(utype, "user")) { 12777 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 12778 } 12779 } else 12780 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 12781 } 12782 cat = ast_category_browse(cfg, cat); 12783 } 12784 if (ast_find_ourip(&__ourip, bindaddr)) { 12785 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 12786 return 0; 12787 } 12788 if (!ntohs(bindaddr.sin_port)) 12789 bindaddr.sin_port = ntohs(DEFAULT_SIP_PORT); 12790 bindaddr.sin_family = AF_INET; 12791 ast_mutex_lock(&netlock); 12792 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 12793 close(sipsock); 12794 sipsock = -1; 12795 } 12796 if (sipsock < 0) { 12797 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 12798 if (sipsock < 0) { 12799 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 12800 } else { 12801 /* Allow SIP clients on the same host to access us: */ 12802 const int reuseFlag = 1; 12803 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 12804 (const char*)&reuseFlag, 12805 sizeof reuseFlag); 12806 12807 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 12808 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 12809 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port), 12810 strerror(errno)); 12811 close(sipsock); 12812 sipsock = -1; 12813 } else { 12814 if (option_verbose > 1) { 12815 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 12816 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 12817 ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos); 12818 } 12819 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) 12820 ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos); 12821 } 12822 } 12823 } 12824 ast_mutex_unlock(&netlock); 12825 12826 /* Add default domains - host name, IP address and IP:port */ 12827 /* Only do this if user added any sip domain with "localdomains" */ 12828 /* In order to *not* break backwards compatibility */ 12829 /* Some phones address us at IP only, some with additional port number */ 12830 if (auto_sip_domains) { 12831 char temp[MAXHOSTNAMELEN]; 12832 12833 /* First our default IP address */ 12834 if (bindaddr.sin_addr.s_addr) { 12835 ast_inet_ntoa(temp, sizeof(temp), bindaddr.sin_addr); 12836 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12837 } else { 12838 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 12839 } 12840 12841 /* Our extern IP address, if configured */ 12842 if (externip.sin_addr.s_addr) { 12843 ast_inet_ntoa(temp, sizeof(temp), externip.sin_addr); 12844 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12845 } 12846 12847 /* Extern host name (NAT traversal support) */ 12848 if (!ast_strlen_zero(externhost)) 12849 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 12850 12851 /* Our host name */ 12852 if (!gethostname(temp, sizeof(temp))) 12853 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12854 } 12855 12856 /* Release configuration from memory */ 12857 ast_config_destroy(cfg); 12858 12859 /* Load the list of manual NOTIFY types to support */ 12860 if (notify_types) 12861 ast_config_destroy(notify_types); 12862 notify_types = ast_config_load(notify_config); 12863 12864 return 0; 12865 }
|
|
reply_digest: reply to authentication for outbound registrations ---
Definition at line 9031 of file chan_sip.c. References ast_log(), ast_strlen_zero(), build_reply_digest(), sip_registry::domain, sip_pvt::domain, get_header(), key(), keys, LOG_WARNING, sip_registry::nonce, sip_pvt::nonce, sip_registry::noncecount, sip_pvt::noncecount, sip_registry::opaque, sip_pvt::opaque, sip_registry::qop, sip_pvt::qop, sip_registry::realm, sip_pvt::realm, sip_pvt::registry, and strsep(). Referenced by do_proxy_auth(), and do_register_auth(). 09033 { 09034 char tmp[512]; 09035 char *c; 09036 char oldnonce[256]; 09037 09038 /* table of recognised keywords, and places where they should be copied */ 09039 const struct x { 09040 const char *key; 09041 char *dst; 09042 int dstlen; 09043 } *i, keys[] = { 09044 { "realm=", p->realm, sizeof(p->realm) }, 09045 { "nonce=", p->nonce, sizeof(p->nonce) }, 09046 { "opaque=", p->opaque, sizeof(p->opaque) }, 09047 { "qop=", p->qop, sizeof(p->qop) }, 09048 { "domain=", p->domain, sizeof(p->domain) }, 09049 { NULL, NULL, 0 }, 09050 }; 09051 09052 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 09053 if (ast_strlen_zero(tmp)) 09054 return -1; 09055 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 09056 ast_log(LOG_WARNING, "missing Digest.\n"); 09057 return -1; 09058 } 09059 c = tmp + strlen("Digest "); 09060 for (i = keys; i->key != NULL; i++) 09061 i->dst[0] = '\0'; /* init all to empty strings */ 09062 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 09063 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 09064 for (i = keys; i->key != NULL; i++) { 09065 char *src, *separator; 09066 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 09067 continue; 09068 /* Found. Skip keyword, take text in quotes or up to the separator. */ 09069 c += strlen(i->key); 09070 if (*c == '\"') { 09071 src = ++c; 09072 separator = "\""; 09073 } else { 09074 src = c; 09075 separator = ","; 09076 } 09077 strsep(&c, separator); /* clear separator and move ptr */ 09078 ast_copy_string(i->dst, src, i->dstlen); 09079 break; 09080 } 09081 if (i->key == NULL) /* not found, try ',' */ 09082 strsep(&c, ","); 09083 } 09084 /* Reset nonce count */ 09085 if (strcmp(p->nonce, oldnonce)) 09086 p->noncecount = 0; 09087 09088 /* Save auth data for following registrations */ 09089 if (p->registry) { 09090 struct sip_registry *r = p->registry; 09091 09092 if (strcmp(r->nonce, p->nonce)) { 09093 ast_copy_string(r->realm, p->realm, sizeof(r->realm)); 09094 ast_copy_string(r->nonce, p->nonce, sizeof(r->nonce)); 09095 ast_copy_string(r->domain, p->domain, sizeof(r->domain)); 09096 ast_copy_string(r->opaque, p->opaque, sizeof(r->opaque)); 09097 ast_copy_string(r->qop, p->qop, sizeof(r->qop)); 09098 r->noncecount = 0; 09099 } 09100 } 09101 return build_reply_digest(p, sipmethod, digest, digest_len); 09102 }
|
|
reqprep: Initialize a SIP request response packet ---
Definition at line 4107 of file chan_sip.c. References add_header(), add_route(), ast_strlen_zero(), ast_test_flag, sip_pvt::branch, build_via(), copy_header(), DEFAULT_MAX_FORWARDS, default_useragent, get_header(), get_in_brackets(), sip_route::hop, init_req(), sip_pvt::initreq, sip_pvt::lastmsg, n, 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_CANCEL, sip_methods, SIP_OUTGOING, strcasestr(), text, cfsip_methods::text, thread_safe_rand(), sip_pvt::uri, and sip_pvt::via. 04108 { 04109 struct sip_request *orig = &p->initreq; 04110 char stripped[80]; 04111 char tmp[80]; 04112 char newto[256]; 04113 char *c, *n; 04114 char *ot, *of; 04115 int is_strict = 0; /* Strict routing flag */ 04116 04117 memset(req, 0, sizeof(struct sip_request)); 04118 04119 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 04120 04121 if (!seqno) { 04122 p->ocseq++; 04123 seqno = p->ocseq; 04124 } 04125 04126 if (newbranch) { 04127 p->branch ^= thread_safe_rand(); 04128 build_via(p, p->via, sizeof(p->via)); 04129 } 04130 04131 /* Check for strict or loose router */ 04132 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) 04133 is_strict = 1; 04134 04135 if (sipmethod == SIP_CANCEL) { 04136 c = p->initreq.rlPart2; /* Use original URI */ 04137 } else if (sipmethod == SIP_ACK) { 04138 /* Use URI from Contact: in 200 OK (if INVITE) 04139 (we only have the contacturi on INVITEs) */ 04140 if (!ast_strlen_zero(p->okcontacturi)) 04141 c = is_strict ? p->route->hop : p->okcontacturi; 04142 else 04143 c = p->initreq.rlPart2; 04144 } else if (!ast_strlen_zero(p->okcontacturi)) { 04145 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 04146 } else if (!ast_strlen_zero(p->uri)) { 04147 c = p->uri; 04148 } else { 04149 /* We have no URI, use To: or From: header as URI (depending on direction) */ 04150 c = get_header(orig, (ast_test_flag(p, SIP_OUTGOING)) ? "To" : "From"); 04151 ast_copy_string(stripped, c, sizeof(stripped)); 04152 c = get_in_brackets(stripped); 04153 n = strchr(c, ';'); 04154 if (n) 04155 *n = '\0'; 04156 } 04157 init_req(req, sipmethod, c); 04158 04159 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 04160 04161 add_header(req, "Via", p->via); 04162 if (p->route) { 04163 set_destination(p, p->route->hop); 04164 if (is_strict) 04165 add_route(req, p->route->next); 04166 else 04167 add_route(req, p->route); 04168 } 04169 04170 ot = get_header(orig, "To"); 04171 of = get_header(orig, "From"); 04172 04173 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 04174 as our original request, including tag (or presumably lack thereof) */ 04175 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 04176 /* Add the proper tag if we don't have it already. If they have specified 04177 their tag, use it. Otherwise, use our own tag */ 04178 if (ast_test_flag(p, SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 04179 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 04180 else if (!ast_test_flag(p, SIP_OUTGOING)) 04181 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 04182 else 04183 snprintf(newto, sizeof(newto), "%s", ot); 04184 ot = newto; 04185 } 04186 04187 if (ast_test_flag(p, SIP_OUTGOING)) { 04188 add_header(req, "From", of); 04189 add_header(req, "To", ot); 04190 } else { 04191 add_header(req, "From", ot); 04192 add_header(req, "To", of); 04193 } 04194 add_header(req, "Contact", p->our_contact); 04195 copy_header(req, orig, "Call-ID"); 04196 add_header(req, "CSeq", tmp); 04197 04198 add_header(req, "User-Agent", default_useragent); 04199 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 04200 04201 if (p->rpid) 04202 add_header(req, "Remote-Party-ID", p->rpid); 04203 04204 return 0; 04205 }
|
|
respprep: Prepare SIP response packet ---
Definition at line 4059 of file chan_sip.c. References add_header(), ALLOWED_METHODS, ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), default_useragent, sip_pvt::expiry, get_header(), init_resp(), sip_pvt::method, sip_pvt::our_contact, SIP_LEN_CONTACT, SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, strcasestr(), sip_pvt::tag, and sip_pvt::theirtag. 04060 { 04061 char newto[256], *ot; 04062 04063 memset(resp, 0, sizeof(*resp)); 04064 init_resp(resp, msg, req); 04065 copy_via_headers(p, resp, req, "Via"); 04066 if (msg[0] == '2') 04067 copy_all_header(resp, req, "Record-Route"); 04068 copy_header(resp, req, "From"); 04069 ot = get_header(req, "To"); 04070 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 04071 /* Add the proper tag if we don't have it already. If they have specified 04072 their tag, use it. Otherwise, use our own tag */ 04073 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(p, SIP_OUTGOING)) 04074 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 04075 else if (p->tag && !ast_test_flag(p, SIP_OUTGOING)) 04076 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 04077 else { 04078 ast_copy_string(newto, ot, sizeof(newto)); 04079 newto[sizeof(newto) - 1] = '\0'; 04080 } 04081 ot = newto; 04082 } 04083 add_header(resp, "To", ot); 04084 copy_header(resp, req, "Call-ID"); 04085 copy_header(resp, req, "CSeq"); 04086 add_header(resp, "User-Agent", default_useragent); 04087 add_header(resp, "Allow", ALLOWED_METHODS); 04088 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 04089 /* For registration responses, we also need expiry and 04090 contact info */ 04091 char tmp[256]; 04092 04093 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 04094 add_header(resp, "Expires", tmp); 04095 if (p->expiry) { /* Only add contact if we have an expiry time */ 04096 char contact[SIP_LEN_CONTACT]; 04097 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 04098 add_header(resp, "Contact", contact); /* Not when we unregister */ 04099 } 04100 } else if (p->our_contact[0]) { 04101 add_header(resp, "Contact", p->our_contact); 04102 } 04103 return 0; 04104 }
|
|
restart_monitor: Start the channel monitor thread ---
Definition at line 11528 of file chan_sip.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, LOG_WARNING, and monitor_thread. 11529 { 11530 /* If we're supposed to be stopped -- stay stopped */ 11531 if (monitor_thread == AST_PTHREADT_STOP) 11532 return 0; 11533 if (ast_mutex_lock(&monlock)) { 11534 ast_log(LOG_WARNING, "Unable to lock monitor\n"); 11535 return -1; 11536 } 11537 if (monitor_thread == pthread_self()) { 11538 ast_mutex_unlock(&monlock); 11539 ast_log(LOG_WARNING, "Cannot kill myself\n"); 11540 return -1; 11541 } 11542 if (monitor_thread != AST_PTHREADT_NULL) { 11543 /* Wake up the thread */ 11544 pthread_kill(monitor_thread, SIGURG); 11545 } else { 11546 /* Start a new monitor */ 11547 if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) { 11548 ast_mutex_unlock(&monlock); 11549 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 11550 return -1; 11551 } 11552 } 11553 ast_mutex_unlock(&monlock); 11554 return 0; 11555 }
|
|
retrans_pkt: Retransmit SIP message if no answer ---
Definition at line 1164 of file chan_sip.c. References __sip_xmit(), append_history(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_test_flag, ast_verbose(), sip_pvt::callid, sip_pkt::data, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, free, ast_channel::lock, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, MAX_RETRANS, sip_pkt::method, sip_pkt::next, option_debug, sip_pvt::owner, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pvt::recv, sip_pkt::retrans, sip_pkt::retransid, sip_pvt::sa, SIP_ALREADYGONE, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_NEEDDESTROY, SIP_OPTIONS, sipdebug, sip_pkt::timer_a, and sip_pkt::timer_t1. 01165 { 01166 struct sip_pkt *pkt=data, *prev, *cur = NULL; 01167 char iabuf[INET_ADDRSTRLEN]; 01168 int reschedule = DEFAULT_RETRANS; 01169 01170 /* Lock channel */ 01171 ast_mutex_lock(&pkt->owner->lock); 01172 01173 if (pkt->retrans < MAX_RETRANS) { 01174 char buf[80]; 01175 01176 pkt->retrans++; 01177 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01178 if (sipdebug && option_debug > 3) 01179 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); 01180 } else { 01181 int siptimer_a; 01182 01183 if (sipdebug && option_debug > 3) 01184 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01185 if (!pkt->timer_a) 01186 pkt->timer_a = 2 ; 01187 else 01188 pkt->timer_a = 2 * pkt->timer_a; 01189 01190 /* For non-invites, a maximum of 4 secs */ 01191 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01192 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01193 siptimer_a = 4000; 01194 01195 /* Reschedule re-transmit */ 01196 reschedule = siptimer_a; 01197 if (option_debug > 3) 01198 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); 01199 } 01200 01201 if (pkt->owner && sip_debug_test_pvt(pkt->owner)) { 01202 if (ast_test_flag(pkt->owner, SIP_NAT) & SIP_NAT_ROUTE) 01203 ast_verbose("Retransmitting #%d (NAT) to %s:%d:\n%s\n---\n", pkt->retrans, ast_inet_ntoa(iabuf, sizeof(iabuf), pkt->owner->recv.sin_addr), ntohs(pkt->owner->recv.sin_port), pkt->data); 01204 else 01205 ast_verbose("Retransmitting #%d (no NAT) to %s:%d:\n%s\n---\n", pkt->retrans, ast_inet_ntoa(iabuf, sizeof(iabuf), pkt->owner->sa.sin_addr), ntohs(pkt->owner->sa.sin_port), pkt->data); 01206 } 01207 snprintf(buf, sizeof(buf), "ReTx %d", reschedule); 01208 01209 append_history(pkt->owner, buf, pkt->data); 01210 __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01211 ast_mutex_unlock(&pkt->owner->lock); 01212 return reschedule; 01213 } 01214 /* Too many retries */ 01215 if (pkt->owner && pkt->method != SIP_OPTIONS) { 01216 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01217 ast_log(LOG_WARNING, "Maximum retries exceeded on transmission %s for seqno %d (%s %s)\n", pkt->owner->callid, pkt->seqno, (ast_test_flag(pkt, FLAG_FATAL)) ? "Critical" : "Non-critical", (ast_test_flag(pkt, FLAG_RESPONSE)) ? "Response" : "Request"); 01218 } else { 01219 if (pkt->method == SIP_OPTIONS && sipdebug) 01220 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid); 01221 } 01222 append_history(pkt->owner, "MaxRetries", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01223 01224 pkt->retransid = -1; 01225 01226 if (ast_test_flag(pkt, FLAG_FATAL)) { 01227 while(pkt->owner->owner && ast_mutex_trylock(&pkt->owner->owner->lock)) { 01228 ast_mutex_unlock(&pkt->owner->lock); 01229 usleep(1); 01230 ast_mutex_lock(&pkt->owner->lock); 01231 } 01232 if (pkt->owner->owner) { 01233 ast_set_flag(pkt->owner, SIP_ALREADYGONE); 01234 ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid); 01235 ast_queue_hangup(pkt->owner->owner); 01236 ast_mutex_unlock(&pkt->owner->owner->lock); 01237 } else { 01238 /* If no channel owner, destroy now */ 01239 ast_set_flag(pkt->owner, SIP_NEEDDESTROY); 01240 } 01241 } 01242 /* In any case, go ahead and remove the packet */ 01243 prev = NULL; 01244 cur = pkt->owner->packets; 01245 while(cur) { 01246 if (cur == pkt) 01247 break; 01248 prev = cur; 01249 cur = cur->next; 01250 } 01251 if (cur) { 01252 if (prev) 01253 prev->next = cur->next; 01254 else 01255 pkt->owner->packets = cur->next; 01256 ast_mutex_unlock(&pkt->owner->lock); 01257 free(cur); 01258 pkt = NULL; 01259 } else 01260 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 01261 if (pkt) 01262 ast_mutex_unlock(&pkt->owner->lock); 01263 return 0; 01264 }
|
|
Definition at line 2881 of file chan_sip.c. References sip_request::sdp_start. 02882 { 02883 *iterator = req->sdp_start; 02884 }
|
|
send_request: Send SIP Request to the other part of the dialogue ---
Definition at line 1506 of file chan_sip.c. References __sip_reliable_xmit(), __sip_xmit(), append_history(), ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, get_header(), sip_request::len, sip_request::method, parse_copy(), recordhistory, sip_debug_test_pvt(), SIP_NAT, and SIP_NAT_ROUTE. 01507 { 01508 int res; 01509 char iabuf[INET_ADDRSTRLEN]; 01510 struct sip_request tmp; 01511 char tmpmsg[80]; 01512 01513 if (sip_debug_test_pvt(p)) { 01514 if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) 01515 ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port), req->data); 01516 else 01517 ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), req->data); 01518 } 01519 if (reliable) { 01520 if (recordhistory) { 01521 parse_copy(&tmp, req); 01522 snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq")); 01523 append_history(p, "TxReqRel", tmpmsg); 01524 } 01525 res = __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable > 1), req->method); 01526 } else { 01527 if (recordhistory) { 01528 parse_copy(&tmp, req); 01529 snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq")); 01530 append_history(p, "TxReq", tmpmsg); 01531 } 01532 res = __sip_xmit(p, req->data, req->len); 01533 } 01534 return res; 01535 }
|
|
send_response: Transmit response on SIP request---
Definition at line 1472 of file chan_sip.c. References __sip_reliable_xmit(), __sip_xmit(), append_history(), ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, get_header(), sip_request::len, sip_request::method, parse_copy(), recordhistory, sip_debug_test_pvt(), SIP_NAT, and SIP_NAT_ROUTE. 01473 { 01474 int res; 01475 char iabuf[INET_ADDRSTRLEN]; 01476 struct sip_request tmp; 01477 char tmpmsg[80]; 01478 01479 if (sip_debug_test_pvt(p)) { 01480 if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) 01481 ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port), req->data); 01482 else 01483 ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), req->data); 01484 } 01485 if (reliable) { 01486 if (recordhistory) { 01487 parse_copy(&tmp, req); 01488 snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq")); 01489 append_history(p, "TxRespRel", tmpmsg); 01490 } 01491 res = __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable > 1), req->method); 01492 } else { 01493 if (recordhistory) { 01494 parse_copy(&tmp, req); 01495 snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq")); 01496 append_history(p, "TxResp", tmpmsg); 01497 } 01498 res = __sip_xmit(p, req->data, req->len); 01499 } 01500 if (res > 0) 01501 return 0; 01502 return res; 01503 }
|
|
set_destination: Set destination from SIP URI ---
Definition at line 3963 of file chan_sip.c. References ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_verbose(), debug, DEFAULT_SIP_PORT, hostname, hp, LOG_WARNING, sip_pvt::sa, and sip_debug_test_pvt(). Referenced by reqprep(). 03964 { 03965 char *h, *maddr, hostname[256]; 03966 char iabuf[INET_ADDRSTRLEN]; 03967 int port, hn; 03968 struct hostent *hp; 03969 struct ast_hostent ahp; 03970 int debug=sip_debug_test_pvt(p); 03971 03972 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 03973 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 03974 03975 if (debug) 03976 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 03977 03978 /* Find and parse hostname */ 03979 h = strchr(uri, '@'); 03980 if (h) 03981 ++h; 03982 else { 03983 h = uri; 03984 if (strncmp(h, "sip:", 4) == 0) 03985 h += 4; 03986 else if (strncmp(h, "sips:", 5) == 0) 03987 h += 5; 03988 } 03989 hn = strcspn(h, ":;>") + 1; 03990 if (hn > sizeof(hostname)) 03991 hn = sizeof(hostname); 03992 ast_copy_string(hostname, h, hn); 03993 h += hn - 1; 03994 03995 /* Is "port" present? if not default to DEFAULT_SIP_PORT */ 03996 if (*h == ':') { 03997 /* Parse port */ 03998 ++h; 03999 port = strtol(h, &h, 10); 04000 } 04001 else 04002 port = DEFAULT_SIP_PORT; 04003 04004 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 04005 maddr = strstr(h, "maddr="); 04006 if (maddr) { 04007 maddr += 6; 04008 hn = strspn(maddr, "0123456789.") + 1; 04009 if (hn > sizeof(hostname)) hn = sizeof(hostname); 04010 ast_copy_string(hostname, maddr, hn); 04011 } 04012 04013 hp = ast_gethostbyname(hostname, &ahp); 04014 if (hp == NULL) { 04015 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 04016 return; 04017 } 04018 p->sa.sin_family = AF_INET; 04019 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 04020 p->sa.sin_port = htons(port); 04021 if (debug) 04022 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), port); 04023 }
|
|
sip_addheader: Add a SIP header ---
Definition at line 13018 of file chan_sip.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_channel::lock, LOG_DEBUG, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and sipdebug. Referenced by load_module(). 13019 { 13020 int no = 0; 13021 int ok = 0; 13022 char varbuf[128]; 13023 13024 if (ast_strlen_zero((char *)data)) { 13025 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 13026 return 0; 13027 } 13028 ast_mutex_lock(&chan->lock); 13029 13030 /* Check for headers */ 13031 while (!ok && no <= 50) { 13032 no++; 13033 snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%02d", no); 13034 if (ast_strlen_zero(pbx_builtin_getvar_helper(chan, varbuf + 1))) 13035 ok = 1; 13036 } 13037 if (ok) { 13038 pbx_builtin_setvar_helper (chan, varbuf, (char *)data); 13039 if (sipdebug) 13040 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", (char *) data, varbuf); 13041 } else { 13042 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 13043 } 13044 ast_mutex_unlock(&chan->lock); 13045 return 0; 13046 }
|
|
sip_addrcmp: Support routine for find_peer ---
Definition at line 1745 of file chan_sip.c. References sip_peer::addr, ast_test_flag, inaddrcmp(), and SIP_INSECURE_PORT. Referenced by find_peer(). 01746 { 01747 /* We know name is the first field, so we can cast */ 01748 struct sip_peer *p = (struct sip_peer *)name; 01749 return !(!inaddrcmp(&p->addr, sin) || 01750 (ast_test_flag(p, SIP_INSECURE_PORT) && 01751 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 01752 }
|
|
sip_alloc: Allocate SIP_PVT structure and set defaults ---
Definition at line 3054 of file chan_sip.c. References __ourip, ast_copy_flags, ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_setnat(), ast_rtp_settos(), ast_sip_ouraddrfor(), ast_test_flag, ast_variables_destroy(), build_callid(), build_via(), calloc, default_context, default_fromdomain, free, global_capability, global_musicclass, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, iflist, LOG_DEBUG, LOG_WARNING, make_our_tag(), NONE, option_debug, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_OPTIONS, SIP_REGISTER, text, thread_safe_rand(), tos, and videosupport. Referenced by find_call(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register(). 03055 { 03056 struct sip_pvt *p; 03057 03058 if (!(p = calloc(1, sizeof(*p)))) 03059 return NULL; 03060 03061 ast_mutex_init(&p->lock); 03062 03063 p->method = intended_method; 03064 p->initid = -1; 03065 p->autokillid = -1; 03066 p->subscribed = NONE; 03067 p->stateid = -1; 03068 p->prefs = prefs; 03069 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 03070 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 03071 #ifdef OSP_SUPPORT 03072 p->osphandle = -1; 03073 p->osptimelimit = 0; 03074 #endif 03075 if (sin) { 03076 memcpy(&p->sa, sin, sizeof(p->sa)); 03077 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 03078 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 03079 } else { 03080 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 03081 } 03082 03083 p->branch = thread_safe_rand(); 03084 make_our_tag(p->tag, sizeof(p->tag)); 03085 /* Start with 101 instead of 1 */ 03086 p->ocseq = 101; 03087 03088 if (sip_methods[intended_method].need_rtp) { 03089 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 03090 if (videosupport) 03091 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 03092 if (!p->rtp || (videosupport && !p->vrtp)) { 03093 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", videosupport ? "and video" : "", strerror(errno)); 03094 ast_mutex_destroy(&p->lock); 03095 if (p->chanvars) { 03096 ast_variables_destroy(p->chanvars); 03097 p->chanvars = NULL; 03098 } 03099 free(p); 03100 return NULL; 03101 } 03102 ast_rtp_settos(p->rtp, tos); 03103 if (p->vrtp) 03104 ast_rtp_settos(p->vrtp, tos); 03105 p->rtptimeout = global_rtptimeout; 03106 p->rtpholdtimeout = global_rtpholdtimeout; 03107 p->rtpkeepalive = global_rtpkeepalive; 03108 } 03109 03110 if (useglobal_nat && sin) { 03111 /* Setup NAT structure according to global settings if we have an address */ 03112 ast_copy_flags(p, &global_flags, SIP_NAT); 03113 memcpy(&p->recv, sin, sizeof(p->recv)); 03114 if (p->rtp) 03115 ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 03116 if (p->vrtp) 03117 ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 03118 } 03119 03120 if (p->method != SIP_REGISTER) 03121 ast_copy_string(p->fromdomain, default_fromdomain, sizeof(p->fromdomain)); 03122 build_via(p, p->via, sizeof(p->via)); 03123 if (!callid) 03124 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 03125 else 03126 ast_copy_string(p->callid, callid, sizeof(p->callid)); 03127 ast_copy_flags(p, &global_flags, SIP_FLAGS_TO_COPY); 03128 /* Assign default music on hold class */ 03129 strcpy(p->musicclass, global_musicclass); 03130 p->capability = global_capability; 03131 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO)) 03132 p->noncodeccapability |= AST_RTP_DTMF; 03133 strcpy(p->context, default_context); 03134 03135 /* Add to active dialog list */ 03136 ast_mutex_lock(&iflock); 03137 p->next = iflist; 03138 iflist = p; 03139 ast_mutex_unlock(&iflock); 03140 if (option_debug) 03141 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"); 03142 return p; 03143 }
|
|
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface
Definition at line 2523 of file chan_sip.c. References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, ast_channel::name, option_debug, ast_channel::tech_pvt, transmit_response_with_sdp(), and try_suggested_sip_codec(). 02524 { 02525 int res = 0; 02526 struct sip_pvt *p = ast->tech_pvt; 02527 02528 ast_mutex_lock(&p->lock); 02529 if (ast->_state != AST_STATE_UP) { 02530 #ifdef OSP_SUPPORT 02531 time(&p->ospstart); 02532 #endif 02533 try_suggested_sip_codec(p); 02534 02535 ast_setstate(ast, AST_STATE_UP); 02536 if (option_debug) 02537 ast_log(LOG_DEBUG, "sip_answer(%s)\n", ast->name); 02538 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, 1); 02539 } 02540 ast_mutex_unlock(&p->lock); 02541 return res; 02542 }
|
|
sip_call: Initiate SIP call from PBX used from the dial() application
Definition at line 2011 of file chan_sip.c. References ast_channel::_state, sip_invite_param::addsipheaders, AST_LIST_TRAVERSE, ast_log(), ast_sched_add(), ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_var_name(), ast_var_value(), auto_congest(), sip_pvt::callingpres, sip_pvt::capability, ast_channel::cid, ast_callerid::cid_pres, sip_invite_param::distinctive_ring, INC_CALL_LIMIT, sip_pvt::initid, sip_pvt::jointcapability, LOG_DEBUG, LOG_WARNING, sip_pvt::maxtime, ast_channel::name, sip_pvt::options, sip_invite_param::osptoken, SIP_INVITE, SIP_OUTGOING, ast_channel::tech_pvt, transmit_invite(), update_call_counter(), sip_invite_param::uri_options, sip_pvt::username, ast_channel::varshead, and sip_invite_param::vxml_url. 02012 { 02013 int res; 02014 struct sip_pvt *p; 02015 #ifdef OSP_SUPPORT 02016 char *osphandle = NULL; 02017 #endif 02018 struct varshead *headp; 02019 struct ast_var_t *current; 02020 02021 02022 02023 p = ast->tech_pvt; 02024 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 02025 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 02026 return -1; 02027 } 02028 02029 02030 /* Check whether there is vxml_url, distinctive ring variables */ 02031 02032 headp=&ast->varshead; 02033 AST_LIST_TRAVERSE(headp,current,entries) { 02034 /* Check whether there is a VXML_URL variable */ 02035 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 02036 p->options->vxml_url = ast_var_value(current); 02037 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 02038 p->options->uri_options = ast_var_value(current); 02039 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 02040 /* Check whether there is a ALERT_INFO variable */ 02041 p->options->distinctive_ring = ast_var_value(current); 02042 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 02043 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 02044 p->options->addsipheaders = 1; 02045 } 02046 02047 02048 #ifdef OSP_SUPPORT 02049 else if (!p->options->osptoken && !strcasecmp(ast_var_name(current), "OSPTOKEN")) { 02050 p->options->osptoken = ast_var_value(current); 02051 } else if (!osphandle && !strcasecmp(ast_var_name(current), "OSPHANDLE")) { 02052 osphandle = ast_var_value(current); 02053 } 02054 #endif 02055 } 02056 02057 res = 0; 02058 ast_set_flag(p, SIP_OUTGOING); 02059 #ifdef OSP_SUPPORT 02060 if (!p->options->osptoken || !osphandle || (sscanf(osphandle, "%d", &p->osphandle) != 1)) { 02061 /* Force Disable OSP support */ 02062 ast_log(LOG_DEBUG, "Disabling OSP support for this call. osptoken = %s, osphandle = %s\n", p->options->osptoken, osphandle); 02063 p->options->osptoken = NULL; 02064 osphandle = NULL; 02065 p->osphandle = -1; 02066 } 02067 #endif 02068 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 02069 res = update_call_counter(p, INC_CALL_LIMIT); 02070 if ( res != -1 ) { 02071 p->callingpres = ast->cid.cid_pres; 02072 p->jointcapability = p->capability; 02073 transmit_invite(p, SIP_INVITE, 1, 2); 02074 if (p->maxtime) { 02075 /* Initialize auto-congest time */ 02076 p->initid = ast_sched_add(sched, p->maxtime * 4, auto_congest, p); 02077 } 02078 } 02079 return res; 02080 }
|
|
sip_cancel_destroy: Cancel destruction of SIP call ---
Definition at line 1352 of file chan_sip.c. References append_history(), ast_sched_del(), and sip_pvt::autokillid. Referenced by cb_extensionstate(), check_user_full(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), and register_verify(). 01353 { 01354 if (p->autokillid > -1) 01355 ast_sched_del(sched, p->autokillid); 01356 append_history(p, "CancelDestroy", ""); 01357 p->autokillid = -1; 01358 return 0; 01359 }
|
|
sip_debug_test_addr: See if we pass debug IP filter
Definition at line 1039 of file chan_sip.c. References debugaddr, and sipdebug. Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read(). 01040 { 01041 if (sipdebug == 0) 01042 return 0; 01043 if (debugaddr.sin_addr.s_addr) { 01044 if (((ntohs(debugaddr.sin_port) != 0) 01045 && (debugaddr.sin_port != addr->sin_port)) 01046 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01047 return 0; 01048 } 01049 return 1; 01050 }
|
|
sip_debug_test_pvt: Test PVT for debugging output
Definition at line 1053 of file chan_sip.c. References ast_test_flag, sip_pvt::recv, sip_pvt::sa, sip_debug_test_addr(), SIP_NAT, SIP_NAT_ROUTE, 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(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendtext(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_sip_request(). 01054 { 01055 if (sipdebug == 0) 01056 return 0; 01057 return sip_debug_test_addr(((ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? &p->recv : &p->sa)); 01058 }
|
|
sip_destroy: Destroy SIP call structure ---
Definition at line 2275 of file chan_sip.c. References __sip_destroy(), ast_mutex_lock(), and ast_mutex_unlock(). Referenced by __sip_autodestruct(), sip_destroy_peer(), sip_do_reload(), sip_notify(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register(). 02276 { 02277 ast_mutex_lock(&iflock); 02278 __sip_destroy(p, 1); 02279 ast_mutex_unlock(&iflock); 02280 }
|
|
|
sip_destroy_user: Remove user object from in-memory storage ---
Definition at line 1774 of file chan_sip.c. References ast_free_ha(), ast_test_flag, ast_variables_destroy(), sip_user::chanvars, free, sip_user::ha, ruserobjs, SIP_REALTIME, and suserobjs. Referenced by check_user_full(), reload_config(), sip_prune_realtime(), sip_show_user(), unload_module(), and update_call_counter(). 01775 { 01776 ast_free_ha(user->ha); 01777 if (user->chanvars) { 01778 ast_variables_destroy(user->chanvars); 01779 user->chanvars = NULL; 01780 } 01781 if (ast_test_flag(user, SIP_REALTIME)) 01782 ruserobjs--; 01783 else 01784 suserobjs--; 01785 free(user); 01786 }
|
|
sip_devicestate: Part of PBX channel interface ---
Definition at line 11654 of file chan_sip.c. References sip_peer::addr, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_gethostbyname(), ast_log(), ast_strdupa, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::defaddr, find_peer(), host, hp, sip_peer::inUse, sip_peer::lastms, LOG_DEBUG, sip_peer::maxms, option_debug, and sip_destroy_peer(). 11655 { 11656 char *host; 11657 char *tmp; 11658 11659 struct hostent *hp; 11660 struct ast_hostent ahp; 11661 struct sip_peer *p; 11662 11663 int res = AST_DEVICE_INVALID; 11664 11665 host = ast_strdupa(data); 11666 if ((tmp = strchr(host, '@'))) 11667 host = tmp + 1; 11668 11669 if (option_debug > 2) 11670 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 11671 11672 if ((p = find_peer(host, NULL, 1))) { 11673 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 11674 /* we have an address for the peer */ 11675 /* if qualify is turned on, check the status */ 11676 if (p->maxms && (p->lastms > p->maxms)) { 11677 res = AST_DEVICE_UNAVAILABLE; 11678 } else { 11679 /* qualify is not on, or the peer is responding properly */ 11680 /* check call limit */ 11681 if (p->call_limit && (p->inUse == p->call_limit)) 11682 res = AST_DEVICE_BUSY; 11683 else if (p->call_limit && p->inUse) 11684 res = AST_DEVICE_INUSE; 11685 else if (p->call_limit) 11686 res = AST_DEVICE_NOT_INUSE; 11687 else 11688 res = AST_DEVICE_UNKNOWN; 11689 } 11690 } else { 11691 /* there is no address, it's unavailable */ 11692 res = AST_DEVICE_UNAVAILABLE; 11693 } 11694 ASTOBJ_UNREF(p,sip_destroy_peer); 11695 } else { 11696 hp = ast_gethostbyname(host, &ahp); 11697 if (hp) 11698 res = AST_DEVICE_UNKNOWN; 11699 } 11700 11701 return res; 11702 }
|
|
sip_do_debug: Turn on SIP debugging (CLI command)
Definition at line 8863 of file chan_sip.c. References ast_cli(), debugaddr, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, sip_do_debug_ip(), sip_do_debug_peer(), and sipdebug. 08864 { 08865 int oldsipdebug = sipdebug & SIP_DEBUG_CONSOLE; 08866 if (argc != 2) { 08867 if (argc != 4) 08868 return RESULT_SHOWUSAGE; 08869 else if (strncmp(argv[2], "ip\0", 3) == 0) 08870 return sip_do_debug_ip(fd, argc, argv); 08871 else if (strncmp(argv[2], "peer\0", 5) == 0) 08872 return sip_do_debug_peer(fd, argc, argv); 08873 else return RESULT_SHOWUSAGE; 08874 } 08875 sipdebug |= SIP_DEBUG_CONSOLE; 08876 memset(&debugaddr, 0, sizeof(debugaddr)); 08877 if (oldsipdebug) 08878 ast_cli(fd, "SIP Debugging re-enabled\n"); 08879 else 08880 ast_cli(fd, "SIP Debugging enabled\n"); 08881 return RESULT_SUCCESS; 08882 }
|
|
sip_do_debug: Enable SIP Debugging in CLI ---
Definition at line 8807 of file chan_sip.c. References ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), debugaddr, hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, and sipdebug. Referenced by sip_do_debug(). 08808 { 08809 struct hostent *hp; 08810 struct ast_hostent ahp; 08811 char iabuf[INET_ADDRSTRLEN]; 08812 int port = 0; 08813 char *p, *arg; 08814 08815 if (argc != 4) 08816 return RESULT_SHOWUSAGE; 08817 arg = argv[3]; 08818 p = strstr(arg, ":"); 08819 if (p) { 08820 *p = '\0'; 08821 p++; 08822 port = atoi(p); 08823 } 08824 hp = ast_gethostbyname(arg, &ahp); 08825 if (hp == NULL) { 08826 return RESULT_SHOWUSAGE; 08827 } 08828 debugaddr.sin_family = AF_INET; 08829 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 08830 debugaddr.sin_port = htons(port); 08831 if (port == 0) 08832 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr)); 08833 else 08834 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), port); 08835 sipdebug |= SIP_DEBUG_CONSOLE; 08836 return RESULT_SUCCESS; 08837 }
|
|
sip_do_debug_peer: Turn on SIP debugging with peer mask
Definition at line 8840 of file chan_sip.c. References sip_peer::addr, ast_cli(), ast_inet_ntoa(), ASTOBJ_UNREF, debugaddr, find_peer(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, sip_destroy_peer(), and sipdebug. Referenced by sip_do_debug(). 08841 { 08842 struct sip_peer *peer; 08843 char iabuf[INET_ADDRSTRLEN]; 08844 if (argc != 4) 08845 return RESULT_SHOWUSAGE; 08846 peer = find_peer(argv[3], NULL, 1); 08847 if (peer) { 08848 if (peer->addr.sin_addr.s_addr) { 08849 debugaddr.sin_family = AF_INET; 08850 memcpy(&debugaddr.sin_addr, &peer->addr.sin_addr, sizeof(debugaddr.sin_addr)); 08851 debugaddr.sin_port = peer->addr.sin_port; 08852 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 08853 sipdebug |= SIP_DEBUG_CONSOLE; 08854 } else 08855 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[3]); 08856 ASTOBJ_UNREF(peer,sip_destroy_peer); 08857 } else 08858 ast_cli(fd, "No such peer '%s'\n", argv[3]); 08859 return RESULT_SUCCESS; 08860 }
|
|
sip_do_history: Enable SIP History logging (CLI) ---
Definition at line 8942 of file chan_sip.c. References ast_cli(), recordhistory, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 08943 { 08944 if (argc != 2) { 08945 return RESULT_SHOWUSAGE; 08946 } 08947 recordhistory = 1; 08948 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 08949 return RESULT_SUCCESS; 08950 }
|
|
sip_do_reload: Reload module
Definition at line 13232 of file chan_sip.c. References ast_log(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, authl, clear_realm_authentication(), clear_sip_domains(), LOG_DEBUG, option_debug, regl, and sip_destroy(). Referenced by do_monitor(). 13233 { 13234 clear_realm_authentication(authl); 13235 clear_sip_domains(); 13236 authl = NULL; 13237 13238 /* First, destroy all outstanding registry calls */ 13239 /* This is needed, since otherwise active registry entries will not be destroyed */ 13240 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 13241 ASTOBJ_RDLOCK(iterator); 13242 if (iterator->call) { 13243 if (option_debug > 2) 13244 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 13245 /* This will also remove references to the registry */ 13246 sip_destroy(iterator->call); 13247 } 13248 ASTOBJ_UNLOCK(iterator); 13249 } while(0)); 13250 13251 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 13252 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 13253 ASTOBJ_CONTAINER_MARKALL(&peerl); 13254 reload_config(); 13255 /* Prune peers who still are supposed to be deleted */ 13256 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 13257 13258 sip_poke_all_peers(); 13259 sip_send_all_registers(); 13260 13261 return 0; 13262 }
|
|
sip_dtmfmode: change the DTMFmode for a SIP call (application) ---
Definition at line 12968 of file chan_sip.c. References ast_clear_flag, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, channeltype, DSP_FEATURE_DTMF_DETECT, sip_pvt::lock, ast_channel::lock, LOG_WARNING, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, ast_channel::type, and sip_pvt::vad. Referenced by load_module(). 12969 { 12970 struct sip_pvt *p; 12971 char *mode; 12972 if (data) 12973 mode = (char *)data; 12974 else { 12975 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 12976 return 0; 12977 } 12978 ast_mutex_lock(&chan->lock); 12979 if (chan->type != channeltype) { 12980 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 12981 ast_mutex_unlock(&chan->lock); 12982 return 0; 12983 } 12984 p = chan->tech_pvt; 12985 if (!p) { 12986 ast_mutex_unlock(&chan->lock); 12987 return 0; 12988 } 12989 ast_mutex_lock(&p->lock); 12990 if (!strcasecmp(mode,"info")) { 12991 ast_clear_flag(p, SIP_DTMF); 12992 ast_set_flag(p, SIP_DTMF_INFO); 12993 } else if (!strcasecmp(mode,"rfc2833")) { 12994 ast_clear_flag(p, SIP_DTMF); 12995 ast_set_flag(p, SIP_DTMF_RFC2833); 12996 } else if (!strcasecmp(mode,"inband")) { 12997 ast_clear_flag(p, SIP_DTMF); 12998 ast_set_flag(p, SIP_DTMF_INBAND); 12999 } else 13000 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 13001 if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) { 13002 if (!p->vad) { 13003 p->vad = ast_dsp_new(); 13004 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 13005 } 13006 } else { 13007 if (p->vad) { 13008 ast_dsp_free(p->vad); 13009 p->vad = NULL; 13010 } 13011 } 13012 ast_mutex_unlock(&p->lock); 13013 ast_mutex_unlock(&chan->lock); 13014 return 0; 13015 }
|
|
dump_history: Dump SIP history to debug log file at end of lifespan for SIP dialog
Definition at line 8688 of file chan_sip.c. References ast_log(), sip_pvt::callid, sip_history::event, sip_pvt::history, LOG_DEBUG, sip_history::next, and sip_pvt::subscribed. Referenced by __sip_destroy(). 08689 { 08690 int x; 08691 struct sip_history *hist; 08692 08693 if (!dialog) 08694 return; 08695 08696 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 08697 if (dialog->subscribed) 08698 ast_log(LOG_DEBUG, " * Subscription\n"); 08699 else 08700 ast_log(LOG_DEBUG, " * SIP Call\n"); 08701 x = 0; 08702 hist = dialog->history; 08703 while(hist) { 08704 x++; 08705 ast_log(LOG_DEBUG, " %d. %s\n", x, hist->event); 08706 hist = hist->next; 08707 } 08708 if (!x) 08709 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 08710 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 08711 08712 }
|
|
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links ----
Definition at line 2598 of file chan_sip.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::lock, LOG_WARNING, sip_pvt::owner, and ast_channel::tech_pvt. 02599 { 02600 struct sip_pvt *p = newchan->tech_pvt; 02601 ast_mutex_lock(&p->lock); 02602 if (p->owner != oldchan) { 02603 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 02604 ast_mutex_unlock(&p->lock); 02605 return -1; 02606 } 02607 p->owner = newchan; 02608 ast_mutex_unlock(&p->lock); 02609 return 0; 02610 }
|
|
sip_get_codec: Return SIP UA's codec (part of the RTP interface) ---
Definition at line 13183 of file chan_sip.c. References sip_pvt::peercapability, and ast_channel::tech_pvt. 13184 { 13185 struct sip_pvt *p = chan->tech_pvt; 13186 return p->peercapability; 13187 }
|
|
sip_get_rtp_peer: Returns null if we can't reinvite (part of RTP interface)
Definition at line 12868 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::lock, sip_pvt::rtp, SIP_CAN_REINVITE, and ast_channel::tech_pvt. 12869 { 12870 struct sip_pvt *p; 12871 struct ast_rtp *rtp = NULL; 12872 p = chan->tech_pvt; 12873 if (!p) 12874 return NULL; 12875 ast_mutex_lock(&p->lock); 12876 if (p->rtp && ast_test_flag(p, SIP_CAN_REINVITE)) 12877 rtp = p->rtp; 12878 ast_mutex_unlock(&p->lock); 12879 return rtp; 12880 }
|
|
sip_get_vrtp_peer: Returns null if we can't reinvite video (part of RTP interface)
Definition at line 12883 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::lock, SIP_CAN_REINVITE, ast_channel::tech_pvt, and sip_pvt::vrtp. 12884 { 12885 struct sip_pvt *p; 12886 struct ast_rtp *rtp = NULL; 12887 p = chan->tech_pvt; 12888 if (!p) 12889 return NULL; 12890 12891 ast_mutex_lock(&p->lock); 12892 if (p->vrtp && ast_test_flag(p, SIP_CAN_REINVITE)) 12893 rtp = p->vrtp; 12894 ast_mutex_unlock(&p->lock); 12895 return rtp; 12896 }
|
|
sip_getheader: Get a SIP header (dialplan app) ---
Definition at line 13049 of file chan_sip.c. References ast_goto_if_exists(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_strlen_zero(), ast_verbose(), channeltype, ast_channel::context, dep_warning, get_header(), sip_pvt::initreq, ast_channel::lock, LOG_DEBUG, LOG_WARNING, option_priority_jumping, option_verbose, sip_pvt::options, pbx_builtin_setvar_helper(), strsep(), ast_channel::tech_pvt, ast_channel::type, and VERBOSE_PREFIX_3. Referenced by load_module(). 13050 { 13051 char *argv, *varname = NULL, *header = NULL, *content, *options = NULL; 13052 static int dep_warning = 0; 13053 struct sip_pvt *p; 13054 int priority_jump = 0; 13055 13056 if (!dep_warning) { 13057 ast_log(LOG_WARNING, "SIPGetHeader is deprecated, use the SIP_HEADER function instead.\n"); 13058 dep_warning = 1; 13059 } 13060 13061 argv = ast_strdupa(data); 13062 if (!argv) { 13063 ast_log(LOG_DEBUG, "Memory allocation failed\n"); 13064 return 0; 13065 } 13066 13067 if (strchr (argv, '=') ) { /* Pick out argument */ 13068 varname = strsep (&argv, "="); 13069 if (strchr(argv, '|')) { 13070 header = strsep (&argv, "|"); 13071 options = strsep (&argv, "\0"); 13072 } else { 13073 header = strsep (&argv, "\0"); 13074 } 13075 13076 } 13077 13078 if (!varname || !header) { 13079 ast_log(LOG_DEBUG, "SIPGetHeader: Ignoring command, Syntax error in argument\n"); 13080 return 0; 13081 } 13082 13083 if (options) { 13084 if (strchr(options, 'j')) 13085 priority_jump = 1; 13086 } 13087 13088 ast_mutex_lock(&chan->lock); 13089 if (chan->type != channeltype) { 13090 ast_log(LOG_WARNING, "Call this application only on incoming SIP calls\n"); 13091 ast_mutex_unlock(&chan->lock); 13092 return 0; 13093 } 13094 13095 p = chan->tech_pvt; 13096 content = get_header(&p->initreq, header); /* Get the header */ 13097 if (!ast_strlen_zero(content)) { 13098 pbx_builtin_setvar_helper(chan, varname, content); 13099 if (option_verbose > 2) 13100 ast_verbose(VERBOSE_PREFIX_3 "SIPGetHeader: set variable %s to %s\n", varname, content); 13101 pbx_builtin_setvar_helper(chan, "SIPGETSTATUS", "FOUND"); 13102 } else { 13103 ast_log(LOG_WARNING,"SIP Header %s not found for channel variable %s\n", header, varname); 13104 if (priority_jump || option_priority_jumping) { 13105 /* Goto priority n+101 if it exists, where n is the current priority number */ 13106 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101); 13107 } 13108 pbx_builtin_setvar_helper(chan, "SIPGETSTATUS", "NOTFOUND"); 13109 } 13110 13111 ast_mutex_unlock(&chan->lock); 13112 return 0; 13113 }
|
|
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup
Definition at line 2404 of file chan_sip.c. References __sip_pretend_ack(), ast_channel::_state, AST_CAUSE_NORMAL, ast_clear_flag, ast_copy_flags, ast_dsp_free(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_osp_terminate(), ast_set_flag, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_update_use_count(), sip_pvt::callid, sip_request::data, DEC_CALL_LIMIT, hangup_cause2sip(), ast_channel::hangupcause, INC_CALL_LIMIT, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, option_debug, sip_pvt::owner, sip_pvt::pendinginvite, SIP_ALREADYGONE, SIP_BYE, SIP_CAN_BYE, SIP_CANCEL, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_OUTGOING, SIP_PENDINGBYE, sip_scheddestroy(), ast_channel::tech_pvt, transmit_request_with_auth(), transmit_response_reliable(), update_call_counter(), usecnt, usecnt_lock, sip_pvt::username, and sip_pvt::vad. 02405 { 02406 struct sip_pvt *p = ast->tech_pvt; 02407 int needcancel = 0; 02408 struct ast_flags locflags = {0}; 02409 02410 if (!p) { 02411 ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n"); 02412 return 0; 02413 } 02414 if (option_debug) 02415 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 02416 02417 ast_mutex_lock(&p->lock); 02418 #ifdef OSP_SUPPORT 02419 if ((p->osphandle > -1) && (ast->_state == AST_STATE_UP)) { 02420 ast_osp_terminate(p->osphandle, AST_CAUSE_NORMAL, p->ospstart, time(NULL) - p->ospstart); 02421 } 02422 #endif 02423 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter\n", p->username); 02424 update_call_counter(p, DEC_CALL_LIMIT); 02425 /* Determine how to disconnect */ 02426 if (p->owner != ast) { 02427 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 02428 ast_mutex_unlock(&p->lock); 02429 return 0; 02430 } 02431 /* If the call is not UP, we need to send CANCEL instead of BYE */ 02432 if (ast->_state != AST_STATE_UP) 02433 needcancel = 1; 02434 02435 /* Disconnect */ 02436 p = ast->tech_pvt; 02437 if (p->vad) { 02438 ast_dsp_free(p->vad); 02439 } 02440 p->owner = NULL; 02441 ast->tech_pvt = NULL; 02442 02443 ast_mutex_lock(&usecnt_lock); 02444 usecnt--; 02445 ast_mutex_unlock(&usecnt_lock); 02446 ast_update_use_count(); 02447 02448 ast_set_flag(&locflags, SIP_NEEDDESTROY); 02449 02450 /* Start the process if it's not already started */ 02451 if (!ast_test_flag(p, SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 02452 if (needcancel) { /* Outgoing call, not up */ 02453 if (ast_test_flag(p, SIP_OUTGOING)) { 02454 /* stop retransmitting an INVITE that has not received a response */ 02455 __sip_pretend_ack(p); 02456 02457 /* are we allowed to send CANCEL yet? if not, mark 02458 it pending */ 02459 if (!ast_test_flag(p, SIP_CAN_BYE)) { 02460 ast_set_flag(p, SIP_PENDINGBYE); 02461 } else { 02462 /* Send a new request: CANCEL */ 02463 transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0); 02464 /* Actually don't destroy us yet, wait for the 487 on our original 02465 INVITE, but do set an autodestruct just in case we never get it. */ 02466 ast_clear_flag(&locflags, SIP_NEEDDESTROY); 02467 sip_scheddestroy(p, 32000); 02468 } 02469 if ( p->initid != -1 ) { 02470 /* channel still up - reverse dec of inUse counter 02471 only if the channel is not auto-congested */ 02472 update_call_counter(p, INC_CALL_LIMIT); 02473 } 02474 } else { /* Incoming call, not up */ 02475 char *res; 02476 if (ast->hangupcause && ((res = hangup_cause2sip(ast->hangupcause)))) { 02477 transmit_response_reliable(p, res, &p->initreq, 1); 02478 } else 02479 transmit_response_reliable(p, "603 Declined", &p->initreq, 1); 02480 } 02481 } else { /* Call is in UP state, send BYE */ 02482 if (!p->pendinginvite) { 02483 /* Send a hangup */ 02484 transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); 02485 } else { 02486 /* Note we will need a BYE when this all settles out 02487 but we can't send one while we have "INVITE" outstanding. */ 02488 ast_set_flag(p, SIP_PENDINGBYE); 02489 ast_clear_flag(p, SIP_NEEDREINVITE); 02490 } 02491 } 02492 } 02493 ast_copy_flags(p, (&locflags), SIP_NEEDDESTROY); 02494 ast_mutex_unlock(&p->lock); 02495 return 0; 02496 }
|
|
sip_indicate: 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 2655 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_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, sip_pvt::callid, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, SIP_ALREADYGONE, SIP_NOVIDEO, SIP_OUTGOING, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_YES, SIP_PROGRESS_SENT, SIP_RINGING, sipdebug, ast_channel::tech_pvt, transmit_info_with_vidupdate(), transmit_response(), transmit_response_with_sdp(), and sip_pvt::vrtp. 02656 { 02657 struct sip_pvt *p = ast->tech_pvt; 02658 int res = 0; 02659 02660 ast_mutex_lock(&p->lock); 02661 switch(condition) { 02662 case AST_CONTROL_RINGING: 02663 if (ast->_state == AST_STATE_RING) { 02664 if (!ast_test_flag(p, SIP_PROGRESS_SENT) || 02665 (ast_test_flag(p, SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 02666 /* Send 180 ringing if out-of-band seems reasonable */ 02667 transmit_response(p, "180 Ringing", &p->initreq); 02668 ast_set_flag(p, SIP_RINGING); 02669 if (ast_test_flag(p, SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 02670 break; 02671 } else { 02672 /* Well, if it's not reasonable, just send in-band */ 02673 } 02674 } 02675 res = -1; 02676 break; 02677 case AST_CONTROL_BUSY: 02678 if (ast->_state != AST_STATE_UP) { 02679 transmit_response(p, "486 Busy Here", &p->initreq); 02680 ast_set_flag(p, SIP_ALREADYGONE); 02681 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 02682 break; 02683 } 02684 res = -1; 02685 break; 02686 case AST_CONTROL_CONGESTION: 02687 if (ast->_state != AST_STATE_UP) { 02688 transmit_response(p, "503 Service Unavailable", &p->initreq); 02689 ast_set_flag(p, SIP_ALREADYGONE); 02690 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 02691 break; 02692 } 02693 res = -1; 02694 break; 02695 case AST_CONTROL_PROCEEDING: 02696 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02697 transmit_response(p, "100 Trying", &p->initreq); 02698 break; 02699 } 02700 res = -1; 02701 break; 02702 case AST_CONTROL_PROGRESS: 02703 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02704 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); 02705 ast_set_flag(p, SIP_PROGRESS_SENT); 02706 break; 02707 } 02708 res = -1; 02709 break; 02710 case AST_CONTROL_HOLD: /* The other part of the bridge are put on hold */ 02711 if (sipdebug) 02712 ast_log(LOG_DEBUG, "Bridged channel now on hold%s\n", p->callid); 02713 res = -1; 02714 break; 02715 case AST_CONTROL_UNHOLD: /* The other part of the bridge are back from hold */ 02716 if (sipdebug) 02717 ast_log(LOG_DEBUG, "Bridged channel is back from hold, let's talk! : %s\n", p->callid); 02718 res = -1; 02719 break; 02720 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 02721 if (p->vrtp && !ast_test_flag(p, SIP_NOVIDEO)) { 02722 transmit_info_with_vidupdate(p); 02723 res = 0; 02724 } else 02725 res = -1; 02726 break; 02727 case -1: 02728 res = -1; 02729 break; 02730 default: 02731 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 02732 res = -1; 02733 break; 02734 } 02735 ast_mutex_unlock(&p->lock); 02736 return res; 02737 }
|
|
sip_new: Initiate a call in the SIP channel
Definition at line 2743 of file chan_sip.c. References ast_channel::accountcode, ast_channel::adsicpe, ast_channel::amaflags, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_channel_alloc(), ast_codec_choose(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), ast_hangup(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), ast_set_callerid(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, ast_strlen_zero(), ast_test_flag, ast_channel::callgroup, sip_pvt::capability, channeltype, ast_channel::cid, ast_callerid::cid_dnid, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, ast_channel::fds, fmt, global_capability, sip_pvt::jointcapability, ast_channel::language, sip_pvt::lock, LOG_WARNING, ast_channel::musicclass, ast_variable::name, ast_channel::name, ast_channel::nativeformats, ast_variable::next, pbx_builtin_setvar_helper(), ast_channel::pickupgroup, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, relaxdtmf, ast_channel::rings, SIP_DTMF, SIP_DTMF_INBAND, strdup, ast_channel::tech, ast_channel::tech_pvt, ast_channel::type, usecnt, usecnt_lock, ast_variable::value, and ast_channel::writeformat. Referenced by handle_request_invite(), and sip_request_call(). 02744 { 02745 struct ast_channel *tmp; 02746 struct ast_variable *v = NULL; 02747 int fmt; 02748 #ifdef OSP_SUPPORT 02749 char iabuf[INET_ADDRSTRLEN]; 02750 char peer[MAXHOSTNAMELEN]; 02751 #endif 02752 02753 ast_mutex_unlock(&i->lock); 02754 /* Don't hold a sip pvt lock while we allocate a channel */ 02755 tmp = ast_channel_alloc(1); 02756 ast_mutex_lock(&i->lock); 02757 if (!tmp) { 02758 ast_log(LOG_WARNING, "Unable to allocate SIP channel structure\n"); 02759 return NULL; 02760 } 02761 tmp->tech = &sip_tech; 02762 /* Select our native format based on codec preference until we receive 02763 something from another device to the contrary. */ 02764 if (i->jointcapability) 02765 tmp->nativeformats = ast_codec_choose(&i->prefs, i->jointcapability, 1); 02766 else if (i->capability) 02767 tmp->nativeformats = ast_codec_choose(&i->prefs, i->capability, 1); 02768 else 02769 tmp->nativeformats = ast_codec_choose(&i->prefs, global_capability, 1); 02770 fmt = ast_best_codec(tmp->nativeformats); 02771 02772 if (title) 02773 snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", title, (int)(long) i); 02774 else if (strchr(i->fromdomain,':')) 02775 snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", strchr(i->fromdomain,':') + 1, (int)(long) i); 02776 else 02777 snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", i->fromdomain, (int)(long) i); 02778 02779 tmp->type = channeltype; 02780 if (ast_test_flag(i, SIP_DTMF) == SIP_DTMF_INBAND) { 02781 i->vad = ast_dsp_new(); 02782 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 02783 if (relaxdtmf) 02784 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 02785 } 02786 if (i->rtp) { 02787 tmp->fds[0] = ast_rtp_fd(i->rtp); 02788 tmp->fds[1] = ast_rtcp_fd(i->rtp); 02789 } 02790 if (i->vrtp) { 02791 tmp->fds[2] = ast_rtp_fd(i->vrtp); 02792 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 02793 } 02794 if (state == AST_STATE_RING) 02795 tmp->rings = 1; 02796 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 02797 tmp->writeformat = fmt; 02798 tmp->rawwriteformat = fmt; 02799 tmp->readformat = fmt; 02800 tmp->rawreadformat = fmt; 02801 tmp->tech_pvt = i; 02802 02803 tmp->callgroup = i->callgroup; 02804 tmp->pickupgroup = i->pickupgroup; 02805 tmp->cid.cid_pres = i->callingpres; 02806 if (!ast_strlen_zero(i->accountcode)) 02807 ast_copy_string(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode)); 02808 if (i->amaflags) 02809 tmp->amaflags = i->amaflags; 02810 if (!ast_strlen_zero(i->language)) 02811 ast_copy_string(tmp->language, i->language, sizeof(tmp->language)); 02812 if (!ast_strlen_zero(i->musicclass)) 02813 ast_copy_string(tmp->musicclass, i->musicclass, sizeof(tmp->musicclass)); 02814 i->owner = tmp; 02815 ast_mutex_lock(&usecnt_lock); 02816 usecnt++; 02817 ast_mutex_unlock(&usecnt_lock); 02818 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 02819 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 02820 ast_set_callerid(tmp, i->cid_num, i->cid_name, i->cid_num); 02821 if (!ast_strlen_zero(i->rdnis)) 02822 tmp->cid.cid_rdnis = strdup(i->rdnis); 02823 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 02824 tmp->cid.cid_dnid = strdup(i->exten); 02825 tmp->priority = 1; 02826 if (!ast_strlen_zero(i->uri)) { 02827 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 02828 } 02829 if (!ast_strlen_zero(i->domain)) { 02830 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 02831 } 02832 if (!ast_strlen_zero(i->useragent)) { 02833 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 02834 } 02835 if (!ast_strlen_zero(i->callid)) { 02836 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 02837 } 02838 #ifdef OSP_SUPPORT 02839 snprintf(peer, sizeof(peer), "[%s]:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), i->sa.sin_addr), ntohs(i->sa.sin_port)); 02840 pbx_builtin_setvar_helper(tmp, "OSPPEER", peer); 02841 #endif 02842 ast_setstate(tmp, state); 02843 if (state != AST_STATE_DOWN) { 02844 if (ast_pbx_start(tmp)) { 02845 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 02846 ast_hangup(tmp); 02847 tmp = NULL; 02848 } 02849 } 02850 /* Set channel variables for this call from configuration */ 02851 for (v = i->chanvars ; v ; v = v->next) 02852 pbx_builtin_setvar_helper(tmp,v->name,v->value); 02853 02854 return tmp; 02855 }
|
|
sip_no_debug: Disable SIP Debugging in CLI ---
Definition at line 8964 of file chan_sip.c. References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, and sipdebug. 08966 { 08967 if (argc != 3) 08968 return RESULT_SHOWUSAGE; 08969 sipdebug &= ~SIP_DEBUG_CONSOLE; 08970 ast_cli(fd, "SIP Debugging Disabled\n"); 08971 return RESULT_SUCCESS; 08972 }
|
|
sip_no_history: Disable SIP History logging (CLI) ---
Definition at line 8953 of file chan_sip.c. References ast_cli(), recordhistory, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 08954 { 08955 if (argc != 3) { 08956 return RESULT_SHOWUSAGE; 08957 } 08958 recordhistory = 0; 08959 ast_cli(fd, "SIP History Recording Disabled\n"); 08960 return RESULT_SUCCESS; 08961 }
|
|
sip_notify: Send SIP notify to peer
Definition at line 8885 of file chan_sip.c. References __ourip, add_blank_header(), add_header(), ast_cli(), ast_log(), ast_sip_ouraddrfor(), ast_variable_browse(), build_callid(), build_via(), sip_pvt::callid, create_addr(), sip_pvt::fromdomain, initreqprep(), LOG_WARNING, ast_variable::name, ast_variable::next, notify_config, notify_types, sip_pvt::ourip, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), ast_variable::value, var, and sip_pvt::via. 08886 { 08887 struct ast_variable *varlist; 08888 int i; 08889 08890 if (argc < 4) 08891 return RESULT_SHOWUSAGE; 08892 08893 if (!notify_types) { 08894 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 08895 return RESULT_FAILURE; 08896 } 08897 08898 varlist = ast_variable_browse(notify_types, argv[2]); 08899 08900 if (!varlist) { 08901 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 08902 return RESULT_FAILURE; 08903 } 08904 08905 for (i = 3; i < argc; i++) { 08906 struct sip_pvt *p; 08907 struct sip_request req; 08908 struct ast_variable *var; 08909 08910 p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY); 08911 if (!p) { 08912 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify\n"); 08913 return RESULT_FAILURE; 08914 } 08915 08916 if (create_addr(p, argv[i])) { 08917 /* Maybe they're not registered, etc. */ 08918 sip_destroy(p); 08919 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 08920 continue; 08921 } 08922 08923 initreqprep(&req, p, SIP_NOTIFY); 08924 08925 for (var = varlist; var; var = var->next) 08926 add_header(&req, var->name, var->value); 08927 08928 add_blank_header(&req); 08929 /* Recalculate our side, and recalculate Call ID */ 08930 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 08931 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 08932 build_via(p, p->via, sizeof(p->via)); 08933 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 08934 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 08935 transmit_sip_request(p, &req); 08936 sip_scheddestroy(p, 15000); 08937 } 08938 08939 return RESULT_SUCCESS; 08940 }
|
|
sip_park: Park a call ---
Definition at line 10206 of file chan_sip.c. References ast_channel_alloc(), ast_channel_masquerade(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, ast_channel::context, copy_request(), ast_channel::exten, free, ast_channel::lock, LOG_WARNING, malloc, ast_channel::name, ast_channel::priority, ast_channel::readformat, sip_park_thread(), and ast_channel::writeformat. Referenced by handle_request_refer(). 10207 { 10208 struct sip_dual *d; 10209 struct ast_channel *chan1m, *chan2m; 10210 pthread_t th; 10211 chan1m = ast_channel_alloc(0); 10212 chan2m = ast_channel_alloc(0); 10213 if ((!chan2m) || (!chan1m)) { 10214 if (chan1m) 10215 ast_hangup(chan1m); 10216 if (chan2m) 10217 ast_hangup(chan2m); 10218 return -1; 10219 } 10220 snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name); 10221 /* Make formats okay */ 10222 chan1m->readformat = chan1->readformat; 10223 chan1m->writeformat = chan1->writeformat; 10224 ast_channel_masquerade(chan1m, chan1); 10225 /* Setup the extensions and such */ 10226 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 10227 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 10228 chan1m->priority = chan1->priority; 10229 10230 /* We make a clone of the peer channel too, so we can play 10231 back the announcement */ 10232 snprintf(chan2m->name, sizeof (chan2m->name), "SIPPeer/%s",chan2->name); 10233 /* Make formats okay */ 10234 chan2m->readformat = chan2->readformat; 10235 chan2m->writeformat = chan2->writeformat; 10236 ast_channel_masquerade(chan2m, chan2); 10237 /* Setup the extensions and such */ 10238 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 10239 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 10240 chan2m->priority = chan2->priority; 10241 ast_mutex_lock(&chan2m->lock); 10242 if (ast_do_masquerade(chan2m)) { 10243 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 10244 ast_mutex_unlock(&chan2m->lock); 10245 ast_hangup(chan2m); 10246 return -1; 10247 } 10248 ast_mutex_unlock(&chan2m->lock); 10249 d = malloc(sizeof(struct sip_dual)); 10250 if (d) { 10251 memset(d, 0, sizeof(*d)); 10252 /* Save original request for followup */ 10253 copy_request(&d->req, req); 10254 d->chan1 = chan1m; 10255 d->chan2 = chan2m; 10256 if (!ast_pthread_create(&th, NULL, sip_park_thread, d)) 10257 return 0; 10258 free(d); 10259 } 10260 return -1; 10261 }
|
|
sip_park_thread: Park SIP call support function
Definition at line 10183 of file chan_sip.c. References ast_do_masquerade(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_park_call(), sip_dual::chan1, sip_dual::chan2, copy_request(), free, ast_channel::lock, LOG_DEBUG, and sip_dual::req. Referenced by sip_park(). 10184 { 10185 struct ast_channel *chan1, *chan2; 10186 struct sip_dual *d; 10187 struct sip_request req; 10188 int ext; 10189 int res; 10190 d = stuff; 10191 chan1 = d->chan1; 10192 chan2 = d->chan2; 10193 copy_request(&req, &d->req); 10194 free(d); 10195 ast_mutex_lock(&chan1->lock); 10196 ast_do_masquerade(chan1); 10197 ast_mutex_unlock(&chan1->lock); 10198 res = ast_park_call(chan1, chan2, 0, &ext); 10199 /* Then hangup */ 10200 ast_hangup(chan2); 10201 ast_log(LOG_DEBUG, "Parked on extension '%d'\n", ext); 10202 return NULL; 10203 }
|
|
sip_poke_all_peers: Send a poke to all known peers
Definition at line 13199 of file chan_sip.c. References ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, peerl, and sip_poke_peer(). Referenced by load_module(). 13200 { 13201 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 13202 ASTOBJ_WRLOCK(iterator); 13203 sip_poke_peer(iterator); 13204 ASTOBJ_UNLOCK(iterator); 13205 } while (0) 13206 ); 13207 }
|
|
sip_poke_noanswer: No answer to Qualify poke ---
Definition at line 11558 of file chan_sip.c. References ast_device_state_changed(), ast_log(), ast_sched_add(), sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::pokeexpire, sip_destroy(), and sip_poke_peer_s(). Referenced by sip_poke_peer(). 11559 { 11560 struct sip_peer *peer = data; 11561 11562 peer->pokeexpire = -1; 11563 if (peer->lastms > -1) { 11564 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 11565 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 11566 } 11567 if (peer->call) 11568 sip_destroy(peer->call); 11569 peer->call = NULL; 11570 peer->lastms = -1; 11571 ast_device_state_changed("SIP/%s", peer->name); 11572 /* Try again quickly */ 11573 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 11574 return 0; 11575 }
|
|
sip_poke_peer: Check availability of peer, also keep NAT open ---
Definition at line 11580 of file chan_sip.c. References __ourip, sip_peer::addr, ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_strlen_zero(), build_callid(), build_via(), sip_peer::call, sip_pvt::callid, DEFAULT_MAXMS, sip_pvt::fromdomain, sip_pvt::fullcontact, sip_peer::fullcontact, sip_peer::lastms, LOG_NOTICE, LOG_WARNING, sip_peer::maxms, sip_pvt::ourip, sip_pvt::peerpoke, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::recv, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, sip_poke_noanswer(), sipdebug, sip_pvt::tohost, sip_peer::tohost, transmit_invite(), sip_pvt::username, and sip_pvt::via. Referenced by parse_register_contact(), reg_source_db(), sip_poke_all_peers(), and sip_poke_peer_s(). 11581 { 11582 struct sip_pvt *p; 11583 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 11584 /* IF we have no IP, or this isn't to be monitored, return 11585 imeediately after clearing things out */ 11586 if (peer->pokeexpire > -1) 11587 ast_sched_del(sched, peer->pokeexpire); 11588 peer->lastms = 0; 11589 peer->pokeexpire = -1; 11590 peer->call = NULL; 11591 return 0; 11592 } 11593 if (peer->call > 0) { 11594 if (sipdebug) 11595 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 11596 sip_destroy(peer->call); 11597 } 11598 p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS); 11599 if (!peer->call) { 11600 ast_log(LOG_WARNING, "Unable to allocate dialog for poking peer '%s'\n", peer->name); 11601 return -1; 11602 } 11603 memcpy(&p->sa, &peer->addr, sizeof(p->sa)); 11604 memcpy(&p->recv, &peer->addr, sizeof(p->sa)); 11605 ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY); 11606 11607 /* Send OPTIONs to peer's fullcontact */ 11608 if (!ast_strlen_zero(peer->fullcontact)) { 11609 ast_copy_string (p->fullcontact, peer->fullcontact, sizeof(p->fullcontact)); 11610 } 11611 11612 if (!ast_strlen_zero(peer->tohost)) 11613 ast_copy_string(p->tohost, peer->tohost, sizeof(p->tohost)); 11614 else 11615 ast_inet_ntoa(p->tohost, sizeof(p->tohost), peer->addr.sin_addr); 11616 11617 /* Recalculate our side, and recalculate Call ID */ 11618 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11619 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11620 build_via(p, p->via, sizeof(p->via)); 11621 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11622 11623 if (peer->pokeexpire > -1) 11624 ast_sched_del(sched, peer->pokeexpire); 11625 p->peerpoke = peer; 11626 ast_set_flag(p, SIP_OUTGOING); 11627 #ifdef VOCAL_DATA_HACK 11628 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 11629 transmit_invite(p, SIP_INVITE, 0, 2); 11630 #else 11631 transmit_invite(p, SIP_OPTIONS, 0, 2); 11632 #endif 11633 gettimeofday(&peer->ps, NULL); 11634 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer); 11635 11636 return 0; 11637 }
|
|
Definition at line 5743 of file chan_sip.c. References sip_peer::pokeexpire, and sip_poke_peer(). Referenced by handle_response_peerpoke(), reg_source_db(), and sip_poke_noanswer(). 05744 { 05745 struct sip_peer *peer = data; 05746 peer->pokeexpire = -1; 05747 sip_poke_peer(peer); 05748 return 0; 05749 }
|
|
sip_prune_realtime: Remove temporary realtime objects from memory (CLI) ---
Definition at line 7757 of file chan_sip.c. References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_FIND_UNLINK, ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, ASTOBJ_UNREF, sip_user::flags_page2, sip_peer::flags_page2, name, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_destroy_peer(), sip_destroy_user(), SIP_PAGE2_RTCACHEFRIENDS, user, and userl. 07758 { 07759 struct sip_peer *peer; 07760 struct sip_user *user; 07761 int pruneuser = 0; 07762 int prunepeer = 0; 07763 int multi = 0; 07764 char *name = NULL; 07765 regex_t regexbuf; 07766 07767 switch (argc) { 07768 case 4: 07769 if (!strcasecmp(argv[3], "user")) 07770 return RESULT_SHOWUSAGE; 07771 if (!strcasecmp(argv[3], "peer")) 07772 return RESULT_SHOWUSAGE; 07773 if (!strcasecmp(argv[3], "like")) 07774 return RESULT_SHOWUSAGE; 07775 if (!strcasecmp(argv[3], "all")) { 07776 multi = 1; 07777 pruneuser = prunepeer = 1; 07778 } else { 07779 pruneuser = prunepeer = 1; 07780 name = argv[3]; 07781 } 07782 break; 07783 case 5: 07784 if (!strcasecmp(argv[4], "like")) 07785 return RESULT_SHOWUSAGE; 07786 if (!strcasecmp(argv[3], "all")) 07787 return RESULT_SHOWUSAGE; 07788 if (!strcasecmp(argv[3], "like")) { 07789 multi = 1; 07790 name = argv[4]; 07791 pruneuser = prunepeer = 1; 07792 } else if (!strcasecmp(argv[3], "user")) { 07793 pruneuser = 1; 07794 if (!strcasecmp(argv[4], "all")) 07795 multi = 1; 07796 else 07797 name = argv[4]; 07798 } else if (!strcasecmp(argv[3], "peer")) { 07799 prunepeer = 1; 07800 if (!strcasecmp(argv[4], "all")) 07801 multi = 1; 07802 else 07803 name = argv[4]; 07804 } else 07805 return RESULT_SHOWUSAGE; 07806 break; 07807 case 6: 07808 if (strcasecmp(argv[4], "like")) 07809 return RESULT_SHOWUSAGE; 07810 if (!strcasecmp(argv[3], "user")) { 07811 pruneuser = 1; 07812 name = argv[5]; 07813 } else if (!strcasecmp(argv[3], "peer")) { 07814 prunepeer = 1; 07815 name = argv[5]; 07816 } else 07817 return RESULT_SHOWUSAGE; 07818 break; 07819 default: 07820 return RESULT_SHOWUSAGE; 07821 } 07822 07823 if (multi && name) { 07824 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 07825 return RESULT_SHOWUSAGE; 07826 } 07827 07828 if (multi) { 07829 if (prunepeer) { 07830 int pruned = 0; 07831 07832 ASTOBJ_CONTAINER_WRLOCK(&peerl); 07833 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07834 ASTOBJ_RDLOCK(iterator); 07835 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07836 ASTOBJ_UNLOCK(iterator); 07837 continue; 07838 }; 07839 if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07840 ASTOBJ_MARK(iterator); 07841 pruned++; 07842 } 07843 ASTOBJ_UNLOCK(iterator); 07844 } while (0) ); 07845 if (pruned) { 07846 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 07847 ast_cli(fd, "%d peers pruned.\n", pruned); 07848 } else 07849 ast_cli(fd, "No peers found to prune.\n"); 07850 ASTOBJ_CONTAINER_UNLOCK(&peerl); 07851 } 07852 if (pruneuser) { 07853 int pruned = 0; 07854 07855 ASTOBJ_CONTAINER_WRLOCK(&userl); 07856 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07857 ASTOBJ_RDLOCK(iterator); 07858 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07859 ASTOBJ_UNLOCK(iterator); 07860 continue; 07861 }; 07862 if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07863 ASTOBJ_MARK(iterator); 07864 pruned++; 07865 } 07866 ASTOBJ_UNLOCK(iterator); 07867 } while (0) ); 07868 if (pruned) { 07869 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 07870 ast_cli(fd, "%d users pruned.\n", pruned); 07871 } else 07872 ast_cli(fd, "No users found to prune.\n"); 07873 ASTOBJ_CONTAINER_UNLOCK(&userl); 07874 } 07875 } else { 07876 if (prunepeer) { 07877 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 07878 if (!ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07879 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 07880 ASTOBJ_CONTAINER_LINK(&peerl, peer); 07881 } else 07882 ast_cli(fd, "Peer '%s' pruned.\n", name); 07883 ASTOBJ_UNREF(peer, sip_destroy_peer); 07884 } else 07885 ast_cli(fd, "Peer '%s' not found.\n", name); 07886 } 07887 if (pruneuser) { 07888 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 07889 if (!ast_test_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07890 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 07891 ASTOBJ_CONTAINER_LINK(&userl, user); 07892 } else 07893 ast_cli(fd, "User '%s' pruned.\n", name); 07894 ASTOBJ_UNREF(user, sip_destroy_user); 07895 } else 07896 ast_cli(fd, "User '%s' not found.\n", name); 07897 } 07898 } 07899 07900 return RESULT_SUCCESS; 07901 }
|
|
sip_read: Read SIP RTP from channel
Definition at line 3017 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::lastrtprx, sip_pvt::lock, sip_rtp_read(), and ast_channel::tech_pvt. 03018 { 03019 struct ast_frame *fr; 03020 struct sip_pvt *p = ast->tech_pvt; 03021 ast_mutex_lock(&p->lock); 03022 fr = sip_rtp_read(ast, p); 03023 time(&p->lastrtprx); 03024 ast_mutex_unlock(&p->lock); 03025 return fr; 03026 }
|
|
sip_reg_timeout: Registration timeout, register again
Definition at line 5354 of file chan_sip.c. References __sip_pretend_ack(), ast_log(), ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, EVENT_FLAG_SYSTEM, global_regattempts_max, sip_registry::hostname, LOG_NOTICE, manager_event(), 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(), and sip_registry::username. Referenced by transmit_register(). 05355 { 05356 05357 /* if we are here, our registration timed out, so we'll just do it over */ 05358 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 05359 struct sip_pvt *p; 05360 int res; 05361 05362 /* if we couldn't get a reference to the registry object, punt */ 05363 if (!r) 05364 return 0; 05365 05366 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 05367 if (r->call) { 05368 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 05369 in the single SIP manager thread. */ 05370 p = r->call; 05371 if (p->registry) 05372 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 05373 r->call = NULL; 05374 ast_set_flag(p, SIP_NEEDDESTROY); 05375 /* Pretend to ACK anything just in case */ 05376 __sip_pretend_ack(p); 05377 } 05378 /* If we have a limit, stop registration and give up */ 05379 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 05380 /* Ok, enough is enough. Don't try any more */ 05381 /* We could add an external notification here... 05382 steal it from app_voicemail :-) */ 05383 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 05384 r->regstate=REG_STATE_FAILED; 05385 } else { 05386 r->regstate=REG_STATE_UNREGISTERED; 05387 r->timeout = -1; 05388 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 05389 } 05390 manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate)); 05391 ASTOBJ_UNREF(r,sip_registry_destroy); 05392 return 0; 05393 }
|
|
sip_register: Parse register=> line in sip.conf and add to registry
Definition at line 3222 of file chan_sip.c. References ast_log(), ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, sip_registry::authuser, sip_registry::callid_valid, sip_registry::contact, copy(), default_expiry, sip_registry::expire, sip_registry::hostname, hostname, LOG_ERROR, LOG_WARNING, malloc, sip_registry::ocseq, sip_registry::portno, sip_registry::refresh, regl, regobjs, sip_registry::secret, secret, sip_registry_destroy(), strsep(), sip_registry::timeout, sip_registry::username, and username. Referenced by reload_config(). 03223 { 03224 struct sip_registry *reg; 03225 char copy[256]; 03226 char *username=NULL, *hostname=NULL, *secret=NULL, *authuser=NULL; 03227 char *porta=NULL; 03228 char *contact=NULL; 03229 char *stringp=NULL; 03230 03231 if (!value) 03232 return -1; 03233 ast_copy_string(copy, value, sizeof(copy)); 03234 stringp=copy; 03235 username = stringp; 03236 hostname = strrchr(stringp, '@'); 03237 if (hostname) { 03238 *hostname = '\0'; 03239 hostname++; 03240 } 03241 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 03242 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 03243 return -1; 03244 } 03245 stringp=username; 03246 username = strsep(&stringp, ":"); 03247 if (username) { 03248 secret = strsep(&stringp, ":"); 03249 if (secret) 03250 authuser = strsep(&stringp, ":"); 03251 } 03252 stringp = hostname; 03253 hostname = strsep(&stringp, "/"); 03254 if (hostname) 03255 contact = strsep(&stringp, "/"); 03256 if (ast_strlen_zero(contact)) 03257 contact = "s"; 03258 stringp=hostname; 03259 hostname = strsep(&stringp, ":"); 03260 porta = strsep(&stringp, ":"); 03261 03262 if (porta && !atoi(porta)) { 03263 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 03264 return -1; 03265 } 03266 reg = malloc(sizeof(struct sip_registry)); 03267 if (!reg) { 03268 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 03269 return -1; 03270 } 03271 memset(reg, 0, sizeof(struct sip_registry)); 03272 regobjs++; 03273 ASTOBJ_INIT(reg); 03274 ast_copy_string(reg->contact, contact, sizeof(reg->contact)); 03275 if (username) 03276 ast_copy_string(reg->username, username, sizeof(reg->username)); 03277 if (hostname) 03278 ast_copy_string(reg->hostname, hostname, sizeof(reg->hostname)); 03279 if (authuser) 03280 ast_copy_string(reg->authuser, authuser, sizeof(reg->authuser)); 03281 if (secret) 03282 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 03283 reg->expire = -1; 03284 reg->timeout = -1; 03285 reg->refresh = default_expiry; 03286 reg->portno = porta ? atoi(porta) : 0; 03287 reg->callid_valid = 0; 03288 reg->ocseq = 101; 03289 ASTOBJ_CONTAINER_LINK(®l, reg); 03290 ASTOBJ_UNREF(reg,sip_registry_destroy); 03291 return 0; 03292 }
|
|
sip_registry_destroy: Destroy registry object ---
Definition at line 2084 of file chan_sip.c. References ast_sched_del(), sip_registry::call, sip_registry::expire, free, sip_pvt::registry, regobjs, sip_destroy(), and sip_registry::timeout. Referenced by __sip_destroy(), handle_response_register(), sip_reg_timeout(), sip_register(), sip_reregister(), and unload_module(). 02085 { 02086 /* Really delete */ 02087 if (reg->call) { 02088 /* Clear registry before destroying to ensure 02089 we don't get reentered trying to grab the registry lock */ 02090 reg->call->registry = NULL; 02091 sip_destroy(reg->call); 02092 } 02093 if (reg->expire > -1) 02094 ast_sched_del(sched, reg->expire); 02095 if (reg->timeout > -1) 02096 ast_sched_del(sched, reg->timeout); 02097 regobjs--; 02098 free(reg); 02099 02100 }
|
|
sip_reload: Force reload of module from cli ---
Definition at line 13265 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), restart_monitor(), and sip_reloading. Referenced by reload(). 13266 { 13267 13268 ast_mutex_lock(&sip_reload_lock); 13269 if (sip_reloading) { 13270 ast_verbose("Previous SIP reload not yet done\n"); 13271 } else 13272 sip_reloading = 1; 13273 ast_mutex_unlock(&sip_reload_lock); 13274 restart_monitor(); 13275 13276 return 0; 13277 }
|
|
sip_request: PBX interface function -build SIP pvt structure ---
Definition at line 11706 of file chan_sip.c. References __ourip, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, AST_FORMAT_MAX_AUDIO, ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_strlen_zero(), ast_update_use_count(), build_callid(), build_via(), calloc, create_addr(), global_capability, host, LOG_ERROR, LOG_NOTICE, sip_pvt::options, restart_monitor(), sip_alloc(), sip_destroy(), SIP_INVITE, and sip_new(). 11707 { 11708 int oldformat; 11709 struct sip_pvt *p; 11710 struct ast_channel *tmpc = NULL; 11711 char *ext, *host; 11712 char tmp[256]; 11713 char *dest = data; 11714 11715 oldformat = format; 11716 format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1); 11717 if (!format) { 11718 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)); 11719 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 11720 return NULL; 11721 } 11722 p = sip_alloc(NULL, NULL, 0, SIP_INVITE); 11723 if (!p) { 11724 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory)\n", (char *)data); 11725 *cause = AST_CAUSE_SWITCH_CONGESTION; 11726 return NULL; 11727 } 11728 11729 p->options = calloc(1, sizeof(*p->options)); 11730 if (!p->options) { 11731 sip_destroy(p); 11732 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 11733 *cause = AST_CAUSE_SWITCH_CONGESTION; 11734 return NULL; 11735 } 11736 11737 ast_copy_string(tmp, dest, sizeof(tmp)); 11738 host = strchr(tmp, '@'); 11739 if (host) { 11740 *host = '\0'; 11741 host++; 11742 ext = tmp; 11743 } else { 11744 ext = strchr(tmp, '/'); 11745 if (ext) { 11746 *ext++ = '\0'; 11747 host = tmp; 11748 } 11749 else { 11750 host = tmp; 11751 ext = NULL; 11752 } 11753 } 11754 11755 if (create_addr(p, host)) { 11756 *cause = AST_CAUSE_UNREGISTERED; 11757 sip_destroy(p); 11758 return NULL; 11759 } 11760 if (ast_strlen_zero(p->peername) && ext) 11761 ast_copy_string(p->peername, ext, sizeof(p->peername)); 11762 /* Recalculate our side, and recalculate Call ID */ 11763 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11764 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11765 build_via(p, p->via, sizeof(p->via)); 11766 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11767 11768 /* We have an extension to call, don't use the full contact here */ 11769 /* This to enable dialling registered peers with extension dialling, 11770 like SIP/peername/extension 11771 SIP/peername will still use the full contact */ 11772 if (ext) { 11773 ast_copy_string(p->username, ext, sizeof(p->username)); 11774 p->fullcontact[0] = 0; 11775 } 11776 #if 0 11777 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 11778 #endif 11779 p->prefcodec = format; 11780 ast_mutex_lock(&p->lock); 11781 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 11782 ast_mutex_unlock(&p->lock); 11783 if (!tmpc) 11784 sip_destroy(p); 11785 ast_update_use_count(); 11786 restart_monitor(); 11787 return tmpc; 11788 }
|
|
sip_reregister: Update registration with SIP Proxy---
Definition at line 5319 of file chan_sip.c. References __sip_do_register(), append_history(), ast_log(), ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, sip_registry::expire, sip_registry::hostname, LOG_NOTICE, recordhistory, sip_registry_destroy(), sipdebug, and sip_registry::username. Referenced by handle_response_register(), and sip_send_all_registers(). 05320 { 05321 /* if we are here, we know that we need to reregister. */ 05322 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 05323 05324 /* if we couldn't get a reference to the registry object, punt */ 05325 if (!r) 05326 return 0; 05327 05328 if (r->call && recordhistory) { 05329 char tmp[80]; 05330 snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname); 05331 append_history(r->call, "RegistryRenew", tmp); 05332 } 05333 /* Since registry's are only added/removed by the the monitor thread, this 05334 may be overkill to reference/dereference at all here */ 05335 if (sipdebug) 05336 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 05337 05338 r->expire = -1; 05339 __sip_do_register(r); 05340 ASTOBJ_UNREF(r, sip_registry_destroy); 05341 return 0; 05342 }
|
|
sip_rtp_read: Read RTP from network ---
Definition at line 2967 of file chan_sip.c. References ast_dsp_process(), AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_channel::fdno, ast_frame::frametype, LOG_DEBUG, ast_channel::nativeformats, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, ast_frame::subclass, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat. Referenced by sip_read(). 02968 { 02969 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 02970 struct ast_frame *f; 02971 static struct ast_frame null_frame = { AST_FRAME_NULL, }; 02972 02973 if (!p->rtp) { 02974 /* We have no RTP allocated for this channel */ 02975 return &null_frame; 02976 } 02977 02978 switch(ast->fdno) { 02979 case 0: 02980 f = ast_rtp_read(p->rtp); /* RTP Audio */ 02981 break; 02982 case 1: 02983 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 02984 break; 02985 case 2: 02986 f = ast_rtp_read(p->vrtp); /* RTP Video */ 02987 break; 02988 case 3: 02989 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 02990 break; 02991 default: 02992 f = &null_frame; 02993 } 02994 /* Don't forward RFC2833 if we're not supposed to */ 02995 if (f && (f->frametype == AST_FRAME_DTMF) && (ast_test_flag(p, SIP_DTMF) != SIP_DTMF_RFC2833)) 02996 return &null_frame; 02997 if (p->owner) { 02998 /* We already hold the channel lock */ 02999 if (f->frametype == AST_FRAME_VOICE) { 03000 if (f->subclass != p->owner->nativeformats) { 03001 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 03002 p->owner->nativeformats = f->subclass; 03003 ast_set_read_format(p->owner, p->owner->readformat); 03004 ast_set_write_format(p->owner, p->owner->writeformat); 03005 } 03006 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 03007 f = ast_dsp_process(p->owner, p->vad, f); 03008 if (f && (f->frametype == AST_FRAME_DTMF)) 03009 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 03010 } 03011 } 03012 } 03013 return f; 03014 }
|
|
sip_scheddestroy: Schedule destruction of SIP call ---
Definition at line 1335 of file chan_sip.c. References __sip_autodestruct(), append_history(), ast_sched_add(), ast_sched_del(), ast_verbose(), sip_pvt::autokillid, sip_pvt::callid, recordhistory, and sip_debug_test_pvt(). Referenced by cb_extensionstate(), check_auth(), check_pendings(), handle_request_register(), handle_request_subscribe(), handle_response_register(), sip_hangup(), sip_notify(), and sip_send_mwi_to_peer(). 01336 { 01337 char tmp[80]; 01338 if (sip_debug_test_pvt(p)) 01339 ast_verbose("Scheduling destruction of call '%s' in %d ms\n", p->callid, ms); 01340 if (recordhistory) { 01341 snprintf(tmp, sizeof(tmp), "%d ms", ms); 01342 append_history(p, "SchedDestroy", tmp); 01343 } 01344 01345 if (p->autokillid > -1) 01346 ast_sched_del(sched, p->autokillid); 01347 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 01348 return 0; 01349 }
|
|
sip_send_all_registers: Send all known registrations
Definition at line 13210 of file chan_sip.c. References ast_sched_add(), ast_sched_del(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, default_expiry, regl, regobjs, and sip_reregister(). Referenced by load_module(). 13211 { 13212 int ms; 13213 int regspacing; 13214 if (!regobjs) 13215 return; 13216 regspacing = default_expiry * 1000/regobjs; 13217 if (regspacing > 100) 13218 regspacing = 100; 13219 ms = regspacing; 13220 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 13221 ASTOBJ_WRLOCK(iterator); 13222 if (iterator->expire > -1) 13223 ast_sched_del(sched, iterator->expire); 13224 ms += regspacing; 13225 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 13226 ASTOBJ_UNLOCK(iterator); 13227 } while (0) 13228 ); 13229 }
|
|
sip_send_mwi_to_peer: Send message waiting indication ---
Definition at line 11355 of file chan_sip.c. References __ourip, ast_app_messagecount(), ast_log(), ast_set_flag, ast_sip_ouraddrfor(), build_callid(), build_via(), sip_pvt::callid, create_addr_from_peer(), sip_pvt::fromdomain, sip_peer::lastmsgcheck, sip_peer::lastmsgssent, LOG_WARNING, sip_peer::mailbox, sip_pvt::ourip, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), transmit_notify_with_mwi(), sip_pvt::via, and sip_peer::vmexten. Referenced by do_monitor(). 11356 { 11357 /* Called with peerl lock, but releases it */ 11358 struct sip_pvt *p; 11359 int newmsgs, oldmsgs; 11360 11361 /* Check for messages */ 11362 ast_app_messagecount(peer->mailbox, &newmsgs, &oldmsgs); 11363 11364 time(&peer->lastmsgcheck); 11365 11366 /* Return now if it's the same thing we told them last time */ 11367 if (((newmsgs << 8) | (oldmsgs)) == peer->lastmsgssent) { 11368 return 0; 11369 } 11370 11371 p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY); 11372 if (!p) { 11373 ast_log(LOG_WARNING, "Unable to build sip pvt data for MWI\n"); 11374 return -1; 11375 } 11376 peer->lastmsgssent = ((newmsgs << 8) | (oldmsgs)); 11377 if (create_addr_from_peer(p, peer)) { 11378 /* Maybe they're not registered, etc. */ 11379 sip_destroy(p); 11380 return 0; 11381 } 11382 /* Recalculate our side, and recalculate Call ID */ 11383 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11384 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11385 build_via(p, p->via, sizeof(p->via)); 11386 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11387 /* Send MWI */ 11388 ast_set_flag(p, SIP_OUTGOING); 11389 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 11390 sip_scheddestroy(p, 15000); 11391 return 0; 11392 }
|
|
sip_senddigit: Send DTMF character on SIP channel
Definition at line 2614 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit(), ast_test_flag, sip_pvt::lock, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, and transmit_info_with_digit(). 02615 { 02616 struct sip_pvt *p = ast->tech_pvt; 02617 int res = 0; 02618 ast_mutex_lock(&p->lock); 02619 switch (ast_test_flag(p, SIP_DTMF)) { 02620 case SIP_DTMF_INFO: 02621 transmit_info_with_digit(p, digit); 02622 break; 02623 case SIP_DTMF_RFC2833: 02624 if (p->rtp) 02625 ast_rtp_senddigit(p->rtp, digit); 02626 break; 02627 case SIP_DTMF_INBAND: 02628 res = -1; 02629 break; 02630 } 02631 ast_mutex_unlock(&p->lock); 02632 return res; 02633 }
|
|
sip_sendtext: Send SIP MESSAGE text within a call ---
Definition at line 1581 of file chan_sip.c. References ast_strlen_zero(), ast_verbose(), debug, ast_channel::name, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text(). 01582 { 01583 struct sip_pvt *p = ast->tech_pvt; 01584 int debug=sip_debug_test_pvt(p); 01585 01586 if (debug) 01587 ast_verbose("Sending text %s on %s\n", text, ast->name); 01588 if (!p) 01589 return -1; 01590 if (ast_strlen_zero(text)) 01591 return 0; 01592 if (debug) 01593 ast_verbose("Really sending text %s on %s\n", text, ast->name); 01594 transmit_message_with_text(p, text); 01595 return 0; 01596 }
|
|
sip_set_rtp_peer: Set the RTP peer for this call ---
Definition at line 12899 of file chan_sip.c. References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_set_flag, ast_test_flag, sip_pvt::callid, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), and sip_pvt::vredirip. 12900 { 12901 struct sip_pvt *p; 12902 12903 p = chan->tech_pvt; 12904 if (!p) 12905 return -1; 12906 ast_mutex_lock(&p->lock); 12907 if (rtp) 12908 ast_rtp_get_peer(rtp, &p->redirip); 12909 else 12910 memset(&p->redirip, 0, sizeof(p->redirip)); 12911 if (vrtp) 12912 ast_rtp_get_peer(vrtp, &p->vredirip); 12913 else 12914 memset(&p->vredirip, 0, sizeof(p->vredirip)); 12915 p->redircodecs = codecs; 12916 if (codecs && !ast_test_flag(p, SIP_GOTREFER)) { 12917 if (!p->pendinginvite) { 12918 if (option_debug > 2) { 12919 char iabuf[INET_ADDRSTRLEN]; 12920 ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp ? p->redirip.sin_addr : p->ourip)); 12921 } 12922 transmit_reinvite_with_sdp(p); 12923 } else if (!ast_test_flag(p, SIP_PENDINGBYE)) { 12924 if (option_debug > 2) { 12925 char iabuf[INET_ADDRSTRLEN]; 12926 ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp ? p->redirip.sin_addr : p->ourip)); 12927 } 12928 ast_set_flag(p, SIP_NEEDREINVITE); 12929 } 12930 } 12931 /* Reset lastrtprx timer */ 12932 time(&p->lastrtprx); 12933 time(&p->lastrtptx); 12934 ast_mutex_unlock(&p->lock); 12935 return 0; 12936 }
|
|
sip_show_channel: Show details of one call ---
Definition at line 8578 of file chan_sip.c. References ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::capability, sip_pvt::cid_num, dtmfmode2str(), sip_route::hop, iflist, sip_pvt::jointcapability, sip_pvt::lastmsg, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::peername, sip_pvt::recv, sip_pvt::redirip, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, SIP_NEEDDESTROY, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, sip_pvt::theirtag, sip_pvt::uri, sip_pvt::useragent, and sip_pvt::username. 08579 { 08580 struct sip_pvt *cur; 08581 char iabuf[INET_ADDRSTRLEN]; 08582 size_t len; 08583 int found = 0; 08584 08585 if (argc != 4) 08586 return RESULT_SHOWUSAGE; 08587 len = strlen(argv[3]); 08588 ast_mutex_lock(&iflock); 08589 cur = iflist; 08590 while(cur) { 08591 if (!strncasecmp(cur->callid, argv[3],len)) { 08592 ast_cli(fd,"\n"); 08593 if (cur->subscribed != NONE) 08594 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 08595 else 08596 ast_cli(fd, " * SIP Call\n"); 08597 ast_cli(fd, " Direction: %s\n", ast_test_flag(cur, SIP_OUTGOING)?"Outgoing":"Incoming"); 08598 ast_cli(fd, " Call-ID: %s\n", cur->callid); 08599 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 08600 ast_cli(fd, " Non-Codec Capability: %d\n", cur->noncodeccapability); 08601 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 08602 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 08603 ast_cli(fd, " Format %s\n", ast_getformatname(cur->owner ? cur->owner->nativeformats : 0) ); 08604 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 08605 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 08606 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(cur, SIP_NAT))); 08607 ast_cli(fd, " Audio IP: %s %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" ); 08608 ast_cli(fd, " Our Tag: %s\n", cur->tag); 08609 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 08610 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 08611 if (!ast_strlen_zero(cur->username)) 08612 ast_cli(fd, " Username: %s\n", cur->username); 08613 if (!ast_strlen_zero(cur->peername)) 08614 ast_cli(fd, " Peername: %s\n", cur->peername); 08615 if (!ast_strlen_zero(cur->uri)) 08616 ast_cli(fd, " Original uri: %s\n", cur->uri); 08617 if (!ast_strlen_zero(cur->cid_num)) 08618 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 08619 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(cur, SIP_NEEDDESTROY)); 08620 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 08621 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(cur, SIP_PROMISCREDIR) ? "Yes" : "No"); 08622 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 08623 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(cur, SIP_DTMF))); 08624 ast_cli(fd, " SIP Options: "); 08625 if (cur->sipoptions) { 08626 int x; 08627 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 08628 if (cur->sipoptions & sip_options[x].id) 08629 ast_cli(fd, "%s ", sip_options[x].text); 08630 } 08631 } else 08632 ast_cli(fd, "(none)\n"); 08633 ast_cli(fd, "\n\n"); 08634 found++; 08635 } 08636 cur = cur->next; 08637 } 08638 ast_mutex_unlock(&iflock); 08639 if (!found) 08640 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 08641 return RESULT_SUCCESS; 08642 }
|
|
sip_show_channels: Show active SIP channels ---
Definition at line 8379 of file chan_sip.c. References __sip_show_channels(). 08380 { 08381 return __sip_show_channels(fd, argc, argv, 0); 08382 }
|
|
Definition at line 7934 of file chan_sip.c. References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, domain_mode_to_text(), FORMAT, list, domain::mode, and RESULT_SUCCESS. 07935 { 07936 struct domain *d; 07937 07938 if (AST_LIST_EMPTY(&domain_list)) { 07939 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 07940 return RESULT_SUCCESS; 07941 } else { 07942 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 07943 AST_LIST_LOCK(&domain_list); 07944 AST_LIST_TRAVERSE(&domain_list, d, list) 07945 ast_cli(fd, FORMAT, d->domain, ast_strlen_zero(d->context) ? "(default)": d->context, 07946 domain_mode_to_text(d->mode)); 07947 AST_LIST_UNLOCK(&domain_list); 07948 ast_cli(fd, "\n"); 07949 return RESULT_SUCCESS; 07950 } 07951 }
|
|
sip_show_history: Show history details of one call ---
Definition at line 8645 of file chan_sip.c. References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::callid, sip_history::event, sip_pvt::history, iflist, sip_pvt::next, sip_history::next, NONE, recordhistory, RESULT_SHOWUSAGE, RESULT_SUCCESS, and sip_pvt::subscribed. 08646 { 08647 struct sip_pvt *cur; 08648 struct sip_history *hist; 08649 size_t len; 08650 int x; 08651 int found = 0; 08652 08653 if (argc != 4) 08654 return RESULT_SHOWUSAGE; 08655 if (!recordhistory) 08656 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 08657 len = strlen(argv[3]); 08658 ast_mutex_lock(&iflock); 08659 cur = iflist; 08660 while(cur) { 08661 if (!strncasecmp(cur->callid, argv[3], len)) { 08662 ast_cli(fd,"\n"); 08663 if (cur->subscribed != NONE) 08664 ast_cli(fd, " * Subscription\n"); 08665 else 08666 ast_cli(fd, " * SIP Call\n"); 08667 x = 0; 08668 hist = cur->history; 08669 while(hist) { 08670 x++; 08671 ast_cli(fd, "%d. %s\n", x, hist->event); 08672 hist = hist->next; 08673 } 08674 if (!x) 08675 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 08676 found++; 08677 } 08678 cur = cur->next; 08679 } 08680 ast_mutex_unlock(&iflock); 08681 if (!found) 08682 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 08683 return RESULT_SUCCESS; 08684 }
|
|
sip_show_inuse: CLI Command to show calls within limits set by call_limit ---
Definition at line 7401 of file chan_sip.c. References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, FORMAT2, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl. 07401 { 07402 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 07403 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 07404 char ilimits[40]; 07405 char iused[40]; 07406 int showall = 0; 07407 07408 if (argc < 3) 07409 return RESULT_SHOWUSAGE; 07410 07411 if (argc == 4 && !strcmp(argv[3],"all")) 07412 showall = 1; 07413 07414 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 07415 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07416 ASTOBJ_RDLOCK(iterator); 07417 if (iterator->call_limit) 07418 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 07419 else 07420 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 07421 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 07422 if (showall || iterator->call_limit) 07423 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 07424 ASTOBJ_UNLOCK(iterator); 07425 } while (0) ); 07426 07427 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 07428 07429 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07430 ASTOBJ_RDLOCK(iterator); 07431 if (iterator->call_limit) 07432 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 07433 else 07434 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 07435 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 07436 if (showall || iterator->call_limit) 07437 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 07438 ASTOBJ_UNLOCK(iterator); 07439 } while (0) ); 07440 07441 return RESULT_SUCCESS; 07442 #undef FORMAT 07443 #undef FORMAT2 07444 }
|
|
sip_show_objects: List all allocated SIP Objects ---
Definition at line 7707 of file chan_sip.c. References apeerobjs, ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, regobjs, RESULT_SHOWUSAGE, RESULT_SUCCESS, rpeerobjs, ruserobjs, speerobjs, suserobjs, and userl. 07708 { 07709 char tmp[256]; 07710 if (argc != 3) 07711 return RESULT_SHOWUSAGE; 07712 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 07713 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 07714 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 07715 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 07716 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 07717 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 07718 return RESULT_SUCCESS; 07719 }
|
|
sip_show_peer: Show one peer in detail ---
Definition at line 7991 of file chan_sip.c. References _sip_show_peer(). 07992 { 07993 return _sip_show_peer(0, fd, NULL, NULL, argc, argv); 07994 }
|
|
sip_show_peers: CLI Show Peers command
Definition at line 7568 of file chan_sip.c. References _sip_show_peers(). 07569 { 07570 return _sip_show_peers(fd, NULL, NULL, NULL, argc, argv); 07571 }
|
|
sip_show_registry: Show SIP Registry (registrations with other SIP proxies ---
Definition at line 8243 of file chan_sip.c. References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, DEFAULT_SIP_PORT, FORMAT, FORMAT2, host, regl, regstate2str(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 08244 { 08245 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s\n" 08246 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s\n" 08247 char host[80]; 08248 08249 if (argc != 3) 08250 return RESULT_SHOWUSAGE; 08251 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State"); 08252 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 08253 ASTOBJ_RDLOCK(iterator); 08254 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : DEFAULT_SIP_PORT); 08255 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate)); 08256 ASTOBJ_UNLOCK(iterator); 08257 } while(0)); 08258 return RESULT_SUCCESS; 08259 #undef FORMAT 08260 #undef FORMAT2 08261 }
|
|
sip_show_settings: List global settings for the SIP channel ---
Definition at line 8264 of file chan_sip.c. References allow_external_domains, ast_check_realtime(), ast_cli(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_strlen_zero(), ast_test_flag, authl, autocreatepeer, bindaddr, callevents, compactheaders, default_callerid, default_context, default_expiry, default_fromdomain, default_language, default_notifymime, default_qualify, default_useragent, dtmfmode2str(), global_allowguest, global_alwaysauthreject, global_musicclass, global_mwitime, global_notifyringing, global_realm, global_reg_timeout, global_regattempts_max, global_rtautoclear, global_rtpholdtimeout, global_rtptimeout, global_vmexten, max_expiry, nat2str(), pedanticsipchecking, print_codec_to_cli(), recordhistory, regcontext, relaxdtmf, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DTMF, SIP_NAT, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, srvlookup, tos, and videosupport. 08265 { 08266 char tmp[BUFSIZ]; 08267 int realtimepeers = 0; 08268 int realtimeusers = 0; 08269 08270 realtimepeers = ast_check_realtime("sippeers"); 08271 realtimeusers = ast_check_realtime("sipusers"); 08272 08273 if (argc != 3) 08274 return RESULT_SHOWUSAGE; 08275 ast_cli(fd, "\n\nGlobal Settings:\n"); 08276 ast_cli(fd, "----------------\n"); 08277 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 08278 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(tmp, sizeof(tmp), bindaddr.sin_addr)); 08279 ast_cli(fd, " Videosupport: %s\n", videosupport ? "Yes" : "No"); 08280 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 08281 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 08282 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags, SIP_PROMISCREDIR) ? "Yes" : "No"); 08283 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 08284 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 08285 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags, SIP_USEREQPHONE) ? "Yes" : "No"); 08286 ast_cli(fd, " Our auth realm %s\n", global_realm); 08287 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 08288 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 08289 ast_cli(fd, " User Agent: %s\n", default_useragent); 08290 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 08291 ast_cli(fd, " Reg. context: %s\n", ast_strlen_zero(regcontext) ? "(not set)" : regcontext); 08292 ast_cli(fd, " Caller ID: %s\n", default_callerid); 08293 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 08294 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 08295 ast_cli(fd, " Call Events: %s\n", callevents ? "On" : "Off"); 08296 ast_cli(fd, " IP ToS: 0x%x\n", tos); 08297 #ifdef OSP_SUPPORT 08298 ast_cli(fd, " OSP Support: Yes\n"); 08299 #else 08300 ast_cli(fd, " OSP Support: No\n"); 08301 #endif 08302 if (!realtimepeers && !realtimeusers) 08303 ast_cli(fd, " SIP realtime: Disabled\n" ); 08304 else 08305 ast_cli(fd, " SIP realtime: Enabled\n" ); 08306 08307 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 08308 ast_cli(fd, "---------------------------\n"); 08309 ast_cli(fd, " Codecs: "); 08310 print_codec_to_cli(fd, &prefs); 08311 ast_cli(fd, "\n"); 08312 ast_cli(fd, " Relax DTMF: %s\n", relaxdtmf ? "Yes" : "No"); 08313 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 08314 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 08315 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 08316 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 08317 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 08318 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 08319 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 08320 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 08321 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 08322 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 08323 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 08324 ast_cli(fd, "\nDefault Settings:\n"); 08325 ast_cli(fd, "-----------------\n"); 08326 ast_cli(fd, " Context: %s\n", default_context); 08327 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags, SIP_NAT))); 08328 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags, SIP_DTMF))); 08329 ast_cli(fd, " Qualify: %d\n", default_qualify); 08330 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags, SIP_USECLIENTCODE) ? "Yes" : "No"); 08331 ast_cli(fd, " Progress inband: %s\n", (ast_test_flag(&global_flags, SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (ast_test_flag(&global_flags, SIP_PROG_INBAND) == SIP_PROG_INBAND_NO) ? "No" : "Yes" ); 08332 ast_cli(fd, " Language: %s\n", ast_strlen_zero(default_language) ? "(Defaults to English)" : default_language); 08333 ast_cli(fd, " Musicclass: %s\n", global_musicclass); 08334 ast_cli(fd, " Voice Mail Extension: %s\n", global_vmexten); 08335 08336 08337 if (realtimepeers || realtimeusers) { 08338 ast_cli(fd, "\nRealtime SIP Settings:\n"); 08339 ast_cli(fd, "----------------------\n"); 08340 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 08341 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 08342 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 08343 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 08344 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 08345 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 08346 } 08347 ast_cli(fd, "\n----\n"); 08348 return RESULT_SUCCESS; 08349 }
|
|
sip_show_subscriptions: Show active SIP subscriptions ---
Definition at line 8385 of file chan_sip.c. References __sip_show_channels(). 08386 { 08387 return __sip_show_channels(fd, argc, argv, 1); 08388 }
|
|
sip_show_user: Show one user in detail ---
Definition at line 8179 of file chan_sip.c. References sip_user::accountcode, sip_user::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_strlen_zero(), ASTOBJ_UNREF, sip_user::call_limit, sip_user::callgroup, sip_user::callingpres, sip_user::chanvars, sip_user::cid_name, sip_user::cid_num, sip_user::context, find_user(), sip_user::ha, sip_user::language, sip_user::md5secret, ast_variable::name, ast_variable::next, sip_user::pickupgroup, sip_user::prefs, print_group(), RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_user::secret, sip_destroy_user(), user, and ast_variable::value. 08180 { 08181 char cbuf[256]; 08182 struct sip_user *user; 08183 struct ast_codec_pref *pref; 08184 struct ast_variable *v; 08185 int x = 0, codec = 0, load_realtime = 0; 08186 08187 if (argc < 4) 08188 return RESULT_SHOWUSAGE; 08189 08190 /* Load from realtime storage? */ 08191 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 08192 08193 user = find_user(argv[3], load_realtime); 08194 if (user) { 08195 ast_cli(fd,"\n\n"); 08196 ast_cli(fd, " * Name : %s\n", user->name); 08197 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 08198 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 08199 ast_cli(fd, " Context : %s\n", user->context); 08200 ast_cli(fd, " Language : %s\n", user->language); 08201 if (!ast_strlen_zero(user->accountcode)) 08202 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 08203 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 08204 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 08205 ast_cli(fd, " Call limit : %d\n", user->call_limit); 08206 ast_cli(fd, " Callgroup : "); 08207 print_group(fd, user->callgroup, 0); 08208 ast_cli(fd, " Pickupgroup : "); 08209 print_group(fd, user->pickupgroup, 0); 08210 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 08211 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 08212 ast_cli(fd, " Codec Order : ("); 08213 pref = &user->prefs; 08214 for(x = 0; x < 32 ; x++) { 08215 codec = ast_codec_pref_index(pref,x); 08216 if (!codec) 08217 break; 08218 ast_cli(fd, "%s", ast_getformatname(codec)); 08219 if (x < 31 && ast_codec_pref_index(pref,x+1)) 08220 ast_cli(fd, "|"); 08221 } 08222 08223 if (!x) 08224 ast_cli(fd, "none"); 08225 ast_cli(fd, ")\n"); 08226 08227 if (user->chanvars) { 08228 ast_cli(fd, " Variables :\n"); 08229 for (v = user->chanvars ; v ; v = v->next) 08230 ast_cli(fd, " %s = %s\n", v->name, v->value); 08231 } 08232 ast_cli(fd,"\n"); 08233 ASTOBJ_UNREF(user,sip_destroy_user); 08234 } else { 08235 ast_cli(fd,"User %s not found.\n", argv[3]); 08236 ast_cli(fd,"\n"); 08237 } 08238 08239 return RESULT_SUCCESS; 08240 }
|
|
sip_show_users: CLI Command 'SIP Show Users' ---
Definition at line 7489 of file chan_sip.c. References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, nat2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_NAT, and userl. 07490 { 07491 regex_t regexbuf; 07492 int havepattern = 0; 07493 07494 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 07495 07496 switch (argc) { 07497 case 5: 07498 if (!strcasecmp(argv[3], "like")) { 07499 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 07500 return RESULT_SHOWUSAGE; 07501 havepattern = 1; 07502 } else 07503 return RESULT_SHOWUSAGE; 07504 case 3: 07505 break; 07506 default: 07507 return RESULT_SHOWUSAGE; 07508 } 07509 07510 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 07511 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07512 ASTOBJ_RDLOCK(iterator); 07513 07514 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07515 ASTOBJ_UNLOCK(iterator); 07516 continue; 07517 } 07518 07519 ast_cli(fd, FORMAT, iterator->name, 07520 iterator->secret, 07521 iterator->accountcode, 07522 iterator->context, 07523 iterator->ha ? "Yes" : "No", 07524 nat2str(ast_test_flag(iterator, SIP_NAT))); 07525 ASTOBJ_UNLOCK(iterator); 07526 } while (0) 07527 ); 07528 07529 if (havepattern) 07530 regfree(®exbuf); 07531 07532 return RESULT_SUCCESS; 07533 #undef FORMAT 07534 }
|
|
sip_sipredirect: Transfer call before connect with a 302 redirect ---
Definition at line 13119 of file chan_sip.c. References ast_log(), ast_set_flag, ast_strdupa, ast_strlen_zero(), get_header(), host, sip_pvt::initreq, LOG_ERROR, sip_pvt::our_contact, SIP_ALREADYGONE, strsep(), and transmit_response_reliable(). Referenced by sip_transfer(). 13120 { 13121 char *cdest; 13122 char *extension, *host, *port; 13123 char tmp[80]; 13124 13125 cdest = ast_strdupa(dest); 13126 if (!cdest) { 13127 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 13128 return 0; 13129 } 13130 extension = strsep(&cdest, "@"); 13131 host = strsep(&cdest, ":"); 13132 port = strsep(&cdest, ":"); 13133 if (!extension) { 13134 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 13135 return 0; 13136 } 13137 13138 /* we'll issue the redirect message here */ 13139 if (!host) { 13140 char *localtmp; 13141 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 13142 if (!strlen(tmp)) { 13143 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 13144 return 0; 13145 } 13146 if ((localtmp = strstr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 13147 char lhost[80], lport[80]; 13148 memset(lhost, 0, sizeof(lhost)); 13149 memset(lport, 0, sizeof(lport)); 13150 localtmp++; 13151 /* This is okey because lhost and lport are as big as tmp */ 13152 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 13153 if (!strlen(lhost)) { 13154 ast_log(LOG_ERROR, "Can't find the host address\n"); 13155 return 0; 13156 } 13157 host = ast_strdupa(lhost); 13158 if (!host) { 13159 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 13160 return 0; 13161 } 13162 if (!ast_strlen_zero(lport)) { 13163 port = ast_strdupa(lport); 13164 if (!port) { 13165 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 13166 return 0; 13167 } 13168 } 13169 } 13170 } 13171 13172 snprintf(p->our_contact, sizeof(p->our_contact), "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 13173 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq, 1); 13174 13175 /* this is all that we want to send to that SIP device */ 13176 ast_set_flag(p, SIP_ALREADYGONE); 13177 13178 /* hangup here */ 13179 return -1; 13180 }
|
|
sip_transfer: Transfer SIP call
Definition at line 2638 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(). 02639 { 02640 struct sip_pvt *p = ast->tech_pvt; 02641 int res; 02642 02643 ast_mutex_lock(&p->lock); 02644 if (ast->_state == AST_STATE_RING) 02645 res = sip_sipredirect(p, dest); 02646 else 02647 res = transmit_refer(p, dest); 02648 ast_mutex_unlock(&p->lock); 02649 return res; 02650 }
|
|
sip_write: Send frame to media channel (rtp) ---
Definition at line 2545 of file chan_sip.c. References ast_channel::_state, AST_FRAME_IMAGE, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_frame::frametype, sip_pvt::initreq, sip_pvt::lastrtptx, sip_pvt::lock, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, sip_pvt::rtp, SIP_OUTGOING, SIP_PROGRESS_SENT, ast_frame::subclass, ast_channel::tech_pvt, transmit_response_with_sdp(), sip_pvt::vrtp, and ast_channel::writeformat. 02546 { 02547 struct sip_pvt *p = ast->tech_pvt; 02548 int res = 0; 02549 switch (frame->frametype) { 02550 case AST_FRAME_VOICE: 02551 if (!(frame->subclass & ast->nativeformats)) { 02552 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", 02553 frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat); 02554 return 0; 02555 } 02556 if (p) { 02557 ast_mutex_lock(&p->lock); 02558 if (p->rtp) { 02559 /* If channel is not up, activate early media session */ 02560 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02561 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); 02562 ast_set_flag(p, SIP_PROGRESS_SENT); 02563 } 02564 time(&p->lastrtptx); 02565 res = ast_rtp_write(p->rtp, frame); 02566 } 02567 ast_mutex_unlock(&p->lock); 02568 } 02569 break; 02570 case AST_FRAME_VIDEO: 02571 if (p) { 02572 ast_mutex_lock(&p->lock); 02573 if (p->vrtp) { 02574 /* Activate video early media */ 02575 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02576 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); 02577 ast_set_flag(p, SIP_PROGRESS_SENT); 02578 } 02579 time(&p->lastrtptx); 02580 res = ast_rtp_write(p->vrtp, frame); 02581 } 02582 ast_mutex_unlock(&p->lock); 02583 } 02584 break; 02585 case AST_FRAME_IMAGE: 02586 return 0; 02587 break; 02588 default: 02589 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 02590 return 0; 02591 } 02592 02593 return res; 02594 }
|
|
sipsock_read: Read data from SIP socket ---
Definition at line 11256 of file chan_sip.c. References append_history(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), sip_pvt::callid, find_call(), find_sip_method(), get_header(), handle_request(), sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, lws2sws(), ast_channel::name, sip_pvt::owner, parse_request(), pedanticsipchecking, recordhistory, sip_pvt::recv, sip_debug_test_addr(), SIP_PKT_DEBUG, and sipsock. Referenced by do_monitor(). 11257 { 11258 struct sip_request req; 11259 struct sockaddr_in sin = { 0, }; 11260 struct sip_pvt *p; 11261 int res; 11262 socklen_t len; 11263 int nounlock; 11264 int recount = 0; 11265 char iabuf[INET_ADDRSTRLEN]; 11266 unsigned int lockretry = 100; 11267 11268 len = sizeof(sin); 11269 memset(&req, 0, sizeof(req)); 11270 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 11271 if (res < 0) { 11272 #if !defined(__FreeBSD__) 11273 if (errno == EAGAIN) 11274 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 11275 else 11276 #endif 11277 if (errno != ECONNREFUSED) 11278 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 11279 return 1; 11280 } 11281 if (res == sizeof(req.data)) { 11282 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 11283 req.data[sizeof(req.data) - 1] = '\0'; 11284 } else 11285 req.data[res] = '\0'; 11286 req.len = res; 11287 if(sip_debug_test_addr(&sin)) 11288 ast_set_flag(&req, SIP_PKT_DEBUG); 11289 if (pedanticsipchecking) 11290 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 11291 if (ast_test_flag(&req, SIP_PKT_DEBUG)) { 11292 ast_verbose("\n<-- SIP read from %s:%d: \n%s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), req.data); 11293 } 11294 parse_request(&req); 11295 req.method = find_sip_method(req.rlPart1); 11296 if (ast_test_flag(&req, SIP_PKT_DEBUG)) { 11297 ast_verbose("--- (%d headers %d lines)", req.headers, req.lines); 11298 if (req.headers + req.lines == 0) 11299 ast_verbose(" Nat keepalive "); 11300 ast_verbose("---\n"); 11301 } 11302 11303 if (req.headers < 2) { 11304 /* Must have at least two headers */ 11305 return 1; 11306 } 11307 11308 11309 /* Process request, with netlock held */ 11310 retrylock: 11311 ast_mutex_lock(&netlock); 11312 p = find_call(&req, &sin, req.method); 11313 if (p) { 11314 /* Go ahead and lock the owner if it has one -- we may need it */ 11315 if (p->owner && ast_mutex_trylock(&p->owner->lock)) { 11316 ast_log(LOG_DEBUG, "Failed to grab lock, trying again...\n"); 11317 ast_mutex_unlock(&p->lock); 11318 ast_mutex_unlock(&netlock); 11319 /* Sleep for a very short amount of time */ 11320 usleep(1); 11321 if (--lockretry) 11322 goto retrylock; 11323 } 11324 if (!lockretry) { 11325 ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", p->owner->name); 11326 ast_log(LOG_ERROR, "SIP MESSAGE JUST IGNORED: %s \n", req.data); 11327 ast_log(LOG_ERROR, "BAD! BAD! BAD!\n"); 11328 return 1; 11329 } 11330 memcpy(&p->recv, &sin, sizeof(p->recv)); 11331 if (recordhistory) { 11332 char tmp[80]; 11333 /* This is a response, note what it was for */ 11334 snprintf(tmp, sizeof(tmp), "%s / %s /%s", req.data, get_header(&req, "CSeq"), req.rlPart2); 11335 append_history(p, "Rx", tmp); 11336 } 11337 nounlock = 0; 11338 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 11339 /* Request failed */ 11340 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 11341 } 11342 11343 if (p->owner && !nounlock) 11344 ast_mutex_unlock(&p->owner->lock); 11345 ast_mutex_unlock(&p->lock); 11346 } 11347 ast_mutex_unlock(&netlock); 11348 if (recount) 11349 ast_update_use_count(); 11350 11351 return 1; 11352 }
|
|
subscription_type2str: Show subscription type in string format
Definition at line 8352 of file chan_sip.c. References subscription_types, and type. Referenced by __sip_show_channels(), and sip_show_channel(). 08352 { 08353 int i; 08354 08355 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 08356 if (subscription_types[i].type == subtype) { 08357 return subscription_types[i].text; 08358 } 08359 } 08360 return subscription_types[0].text; 08361 }
|
|
temp_peer: Create temporary peer (used in autocreatepeer mode) ---
Definition at line 12162 of file chan_sip.c. References apeerobjs, ast_copy_flags, ast_set_flag, ASTOBJ_INIT, default_context, default_language, DEFAULT_SIP_PORT, default_subscribecontext, global_capability, global_musicclass, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, malloc, reg_source_db(), SIP_FLAGS_TO_COPY, SIP_PAGE2_DYNAMIC, and SIP_SELFDESTRUCT. Referenced by register_verify(). 12163 { 12164 struct sip_peer *peer; 12165 12166 peer = malloc(sizeof(*peer)); 12167 if (!peer) 12168 return NULL; 12169 12170 memset(peer, 0, sizeof(*peer)); 12171 apeerobjs++; 12172 ASTOBJ_INIT(peer); 12173 12174 peer->expire = -1; 12175 peer->pokeexpire = -1; 12176 ast_copy_string(peer->name, name, sizeof(peer->name)); 12177 ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY); 12178 strcpy(peer->context, default_context); 12179 strcpy(peer->subscribecontext, default_subscribecontext); 12180 strcpy(peer->language, default_language); 12181 strcpy(peer->musicclass, global_musicclass); 12182 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 12183 peer->addr.sin_family = AF_INET; 12184 peer->capability = global_capability; 12185 peer->rtptimeout = global_rtptimeout; 12186 peer->rtpholdtimeout = global_rtpholdtimeout; 12187 peer->rtpkeepalive = global_rtpkeepalive; 12188 ast_set_flag(peer, SIP_SELFDESTRUCT); 12189 ast_set_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC); 12190 peer->prefs = prefs; 12191 reg_source_db(peer); 12192 12193 return peer; 12194 }
|
|
Thread-safe random number generator.
Definition at line 963 of file chan_sip.c. References ast_mutex_lock(), and ast_mutex_unlock(). Referenced by build_callid(), build_reply_digest(), check_auth(), make_our_tag(), reg_source_db(), reqprep(), sip_alloc(), transmit_fake_auth_response(), transmit_invite(), and transmit_register(). 00964 { 00965 int val; 00966 00967 ast_mutex_lock(&rand_lock); 00968 val = rand(); 00969 ast_mutex_unlock(&rand_lock); 00970 00971 return val; 00972 }
|
|
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
Definition at line 6437 of file chan_sip.c. References thread_safe_rand(), and transmit_response_with_auth(). Referenced by handle_request_invite(), handle_request_subscribe(), and register_verify(). 06438 { 06439 snprintf(randdata, randlen, "%08x", thread_safe_rand()); 06440 transmit_response_with_auth(p, "401 Unauthorized", req, randdata, reliable, "WWW-Authenticate", 0); 06441 }
|
|
transmit_info_with_digit: Send SIP INFO dtmf message, see Cisco documentation on cisco.co m ---
Definition at line 5642 of file chan_sip.c. References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_INFO. Referenced by sip_senddigit(). 05643 { 05644 struct sip_request req; 05645 reqprep(&req, p, SIP_INFO, 0, 1); 05646 add_digit(&req, digit); 05647 return send_request(p, &req, 1, p->ocseq); 05648 }
|
|
transmit_info_with_vidupdate: Send SIP INFO with video update request ---
Definition at line 5651 of file chan_sip.c. References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_INFO. Referenced by sip_indicate(). 05652 { 05653 struct sip_request req; 05654 reqprep(&req, p, SIP_INFO, 0, 1); 05655 add_vidupdate(&req); 05656 return send_request(p, &req, 1, p->ocseq); 05657 }
|
|
transmit_invite: Build REFER/INVITE/OPTIONS message and transmit it ---
Definition at line 4942 of file chan_sip.c. References add_blank_header(), add_header(), add_header_contentLength(), add_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), AST_LIST_TRAVERSE, ast_log(), ast_rtp_offered_from_local(), ast_strdupa, ast_strlen_zero(), ast_var_name(), ast_var_value(), ast_verbose(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::branch, build_via(), copy_request(), sip_invite_param::distinctive_ring, sip_request::headers, sip_pvt::initreq, initreqprep(), sip_pvt::lastinvite, sip_request::lines, LOG_DEBUG, LOG_WARNING, sip_request::method, sip_pvt::ocseq, sip_pvt::options, sip_invite_param::osptoken, sip_pvt::owner, parse_request(), sip_pvt::refer_to, sip_pvt::referred_by, reqprep(), sip_pvt::rtp, send_request(), sip_debug_test_pvt(), SIP_OPTIONS, SIP_REFER, sipdebug, thread_safe_rand(), ast_channel::varshead, and sip_pvt::via. Referenced by do_proxy_auth(), sip_call(), and sip_poke_peer(). 04943 { 04944 struct sip_request req; 04945 04946 req.method = sipmethod; 04947 if (init) { 04948 /* Bump branch even on initial requests */ 04949 p->branch ^= thread_safe_rand(); 04950 build_via(p, p->via, sizeof(p->via)); 04951 if (init > 1) 04952 initreqprep(&req, p, sipmethod); 04953 else 04954 reqprep(&req, p, sipmethod, 0, 1); 04955 } else 04956 reqprep(&req, p, sipmethod, 0, 1); 04957 04958 if (p->options && p->options->auth) 04959 add_header(&req, p->options->authheader, p->options->auth); 04960 append_date(&req); 04961 if (sipmethod == SIP_REFER) { /* Call transfer */ 04962 if (!ast_strlen_zero(p->refer_to)) 04963 add_header(&req, "Refer-To", p->refer_to); 04964 if (!ast_strlen_zero(p->referred_by)) 04965 add_header(&req, "Referred-By", p->referred_by); 04966 } 04967 #ifdef OSP_SUPPORT 04968 if ((req.method != SIP_OPTIONS) && p->options && !ast_strlen_zero(p->options->osptoken)) { 04969 ast_log(LOG_DEBUG,"Adding OSP Token: %s\n", p->options->osptoken); 04970 add_header(&req, "P-OSP-Auth-Token", p->options->osptoken); 04971 } 04972 #endif 04973 if (p->options && !ast_strlen_zero(p->options->distinctive_ring)) 04974 { 04975 add_header(&req, "Alert-Info", p->options->distinctive_ring); 04976 } 04977 add_header(&req, "Allow", ALLOWED_METHODS); 04978 if (p->options && p->options->addsipheaders ) { 04979 struct ast_channel *ast; 04980 char *header = (char *) NULL; 04981 char *content = (char *) NULL; 04982 char *end = (char *) NULL; 04983 struct varshead *headp = (struct varshead *) NULL; 04984 struct ast_var_t *current; 04985 04986 ast = p->owner; /* The owner channel */ 04987 if (ast) { 04988 char *headdup; 04989 headp = &ast->varshead; 04990 if (!headp) 04991 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 04992 else { 04993 AST_LIST_TRAVERSE(headp, current, entries) { 04994 /* SIPADDHEADER: Add SIP header to outgoing call */ 04995 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 04996 header = ast_var_value(current); 04997 headdup = ast_strdupa(header); 04998 /* Strip of the starting " (if it's there) */ 04999 if (*headdup == '"') 05000 headdup++; 05001 if ((content = strchr(headdup, ':'))) { 05002 *content = '\0'; 05003 content++; /* Move pointer ahead */ 05004 /* Skip white space */ 05005 while (*content == ' ') 05006 content++; 05007 /* Strip the ending " (if it's there) */ 05008 end = content + strlen(content) -1; 05009 if (*end == '"') 05010 *end = '\0'; 05011 05012 add_header(&req, headdup, content); 05013 if (sipdebug) 05014 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 05015 } 05016 } 05017 } 05018 } 05019 } 05020 } 05021 if (sdp && p->rtp) { 05022 ast_rtp_offered_from_local(p->rtp, 1); 05023 add_sdp(&req, p); 05024 } else { 05025 add_header_contentLength(&req, 0); 05026 add_blank_header(&req); 05027 } 05028 05029 if (!p->initreq.headers) { 05030 /* Use this as the basis */ 05031 copy_request(&p->initreq, &req); 05032 parse_request(&p->initreq); 05033 if (sip_debug_test_pvt(p)) 05034 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05035 } 05036 p->lastinvite = p->ocseq; 05037 return send_request(p, &req, init ? 2 : 1, p->ocseq); 05038 }
|
|
transmit_message_with_text: Transmit text with SIP MESSAGE method ---
Definition at line 5588 of file chan_sip.c. References add_text(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_MESSAGE. Referenced by sip_sendtext(). 05589 { 05590 struct sip_request req; 05591 reqprep(&req, p, SIP_MESSAGE, 0, 1); 05592 add_text(&req, text); 05593 return send_request(p, &req, 1, p->ocseq); 05594 }
|
|
transmit_notify_with_mwi: Notify user of messages waiting in voicemail ---
Definition at line 5213 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_verbose(), copy_request(), default_notifymime, determine_firstline_parts(), sip_pvt::fromdomain, global_vmexten, sip_request::headers, sip_pvt::initreq, initreqprep(), sip_request::lines, LOG_WARNING, sip_pvt::ocseq, sip_pvt::ourip, parse_request(), send_request(), sip_debug_test_pvt(), SIP_NOTIFY, and t. Referenced by sip_send_mwi_to_peer(). 05214 { 05215 struct sip_request req; 05216 char tmp[500]; 05217 char *t = tmp; 05218 size_t maxbytes = sizeof(tmp); 05219 char iabuf[INET_ADDRSTRLEN]; 05220 05221 initreqprep(&req, p, SIP_NOTIFY); 05222 add_header(&req, "Event", "message-summary"); 05223 add_header(&req, "Content-Type", default_notifymime); 05224 05225 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 05226 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", !ast_strlen_zero(vmexten) ? vmexten : global_vmexten, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain); 05227 ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d (0/0)\r\n", newmsgs, oldmsgs); 05228 05229 if (t > tmp + sizeof(tmp)) 05230 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 05231 05232 add_header_contentLength(&req, strlen(tmp)); 05233 add_line(&req, tmp); 05234 05235 if (!p->initreq.headers) { /* Use this as the basis */ 05236 copy_request(&p->initreq, &req); 05237 parse_request(&p->initreq); 05238 if (sip_debug_test_pvt(p)) 05239 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05240 determine_firstline_parts(&p->initreq); 05241 } 05242 05243 return send_request(p, &req, 1, p->ocseq); 05244 }
|
|
transmit_notify_with_sipfrag: Notify a transferring party of the status of trasnfer ---
Definition at line 5266 of file chan_sip.c. References add_header(), add_header_contentLength(), add_line(), ast_verbose(), copy_request(), determine_firstline_parts(), sip_request::headers, sip_pvt::initreq, sip_request::lines, sip_pvt::ocseq, parse_request(), reqprep(), send_request(), sip_debug_test_pvt(), and SIP_NOTIFY. Referenced by handle_request_refer(). 05267 { 05268 struct sip_request req; 05269 char tmp[20]; 05270 reqprep(&req, p, SIP_NOTIFY, 0, 1); 05271 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 05272 add_header(&req, "Event", tmp); 05273 add_header(&req, "Subscription-state", "terminated;reason=noresource"); 05274 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 05275 05276 strcpy(tmp, "SIP/2.0 200 OK"); 05277 add_header_contentLength(&req, strlen(tmp)); 05278 add_line(&req, tmp); 05279 05280 if (!p->initreq.headers) { 05281 /* Use this as the basis */ 05282 copy_request(&p->initreq, &req); 05283 parse_request(&p->initreq); 05284 if (sip_debug_test_pvt(p)) 05285 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05286 determine_firstline_parts(&p->initreq); 05287 } 05288 05289 return send_request(p, &req, 1, p->ocseq); 05290 }
|
|
transmit_refer: Transmit SIP REFER message ---
Definition at line 5597 of file chan_sip.c. References add_blank_header(), add_header(), ast_log(), ast_strlen_zero(), ast_test_flag, sip_pvt::from, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_NOTICE, sip_pvt::ocseq, sip_pvt::our_contact, sip_pvt::refer_to, sip_pvt::referred_by, reqprep(), send_request(), SIP_OUTGOING, and SIP_REFER. Referenced by sip_transfer(). 05598 { 05599 struct sip_request req; 05600 char from[256]; 05601 char *of, *c; 05602 char referto[256]; 05603 05604 if (ast_test_flag(p, SIP_OUTGOING)) 05605 of = get_header(&p->initreq, "To"); 05606 else 05607 of = get_header(&p->initreq, "From"); 05608 ast_copy_string(from, of, sizeof(from)); 05609 of = get_in_brackets(from); 05610 ast_copy_string(p->from,of,sizeof(p->from)); 05611 if (strncmp(of, "sip:", 4)) { 05612 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 05613 } else 05614 of += 4; 05615 /* Get just the username part */ 05616 if ((c = strchr(dest, '@'))) { 05617 c = NULL; 05618 } else if ((c = strchr(of, '@'))) { 05619 *c = '\0'; 05620 c++; 05621 } 05622 if (c) { 05623 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 05624 } else { 05625 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 05626 } 05627 05628 /* save in case we get 407 challenge */ 05629 ast_copy_string(p->refer_to, referto, sizeof(p->refer_to)); 05630 ast_copy_string(p->referred_by, p->our_contact, sizeof(p->referred_by)); 05631 05632 reqprep(&req, p, SIP_REFER, 0, 1); 05633 add_header(&req, "Refer-To", referto); 05634 if (!ast_strlen_zero(p->our_contact)) 05635 add_header(&req, "Referred-By", p->our_contact); 05636 add_blank_header(&req); 05637 return send_request(p, &req, 1, p->ocseq); 05638 }
|
|
transmit_register: Transmit register to SIP proxy or UA ---
Definition at line 5396 of file chan_sip.c. References __ourip, add_blank_header(), add_header(), add_header_contentLength(), append_history(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_strlen_zero(), ast_verbose(), ASTOBJ_REF, sip_pvt::authname, sip_registry::authuser, sip_pvt::branch, build_callid(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_pvt::callid, sip_registry::callid, sip_registry::callid_valid, sip_registry::contact, copy_request(), create_addr(), default_expiry, default_fromdomain, DEFAULT_MAX_FORWARDS, default_useragent, determine_firstline_parts(), sip_registry::domain, sip_pvt::domain, sip_pvt::exten, sip_pvt::fromdomain, sip_pvt::fromuser, global_reg_timeout, sip_request::headers, sip_registry::hostname, init_req(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), sip_registry::md5secret, sip_pvt::nonce, sip_registry::nonce, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::ocseq, sip_registry::ocseq, sip_registry::opaque, sip_pvt::opaque, option_debug, sip_pvt::our_contact, sip_pvt::ourip, parse_request(), sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_registry::portno, sip_registry::qop, sip_pvt::qop, sip_registry::realm, sip_pvt::realm, recordhistory, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sip_pvt::sa, sip_registry::secret, send_request(), sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sipdebug, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, thread_safe_rand(), sip_registry::timeout, sip_pvt::tohost, sip_pvt::uri, sip_pvt::username, and sip_registry::username. Referenced by __sip_do_register(), do_register_auth(), and sip_reg_timeout(). 05397 { 05398 struct sip_request req; 05399 char from[256]; 05400 char to[256]; 05401 char tmp[80]; 05402 char via[80]; 05403 char addr[80]; 05404 struct sip_pvt *p; 05405 05406 /* exit if we are already in process with this registrar ?*/ 05407 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 05408 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 05409 return 0; 05410 } 05411 05412 if (r->call) { /* We have a registration */ 05413 if (!auth) { 05414 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 05415 return 0; 05416 } else { 05417 p = r->call; 05418 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 05419 p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */ 05420 } 05421 } else { 05422 /* Build callid for registration if we haven't registered before */ 05423 if (!r->callid_valid) { 05424 build_callid(r->callid, sizeof(r->callid), __ourip, default_fromdomain); 05425 r->callid_valid = 1; 05426 } 05427 /* Allocate SIP packet for registration */ 05428 p=sip_alloc( r->callid, NULL, 0, SIP_REGISTER); 05429 if (!p) { 05430 ast_log(LOG_WARNING, "Unable to allocate registration call\n"); 05431 return 0; 05432 } 05433 if (recordhistory) { 05434 char tmp[80]; 05435 snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname); 05436 append_history(p, "RegistryInit", tmp); 05437 } 05438 /* Find address to hostname */ 05439 if (create_addr(p, r->hostname)) { 05440 /* we have what we hope is a temporary network error, 05441 * probably DNS. We need to reschedule a registration try */ 05442 sip_destroy(p); 05443 if (r->timeout > -1) { 05444 ast_sched_del(sched, r->timeout); 05445 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 05446 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 05447 } else { 05448 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 05449 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); 05450 } 05451 r->regattempts++; 05452 return 0; 05453 } 05454 /* Copy back Call-ID in case create_addr changed it */ 05455 ast_copy_string(r->callid, p->callid, sizeof(r->callid)); 05456 if (r->portno) 05457 p->sa.sin_port = htons(r->portno); 05458 else /* Set registry port to the port set from the peer definition/srv or default */ 05459 r->portno = ntohs(p->sa.sin_port); 05460 ast_set_flag(p, SIP_OUTGOING); /* Registration is outgoing call */ 05461 r->call=p; /* Save pointer to SIP packet */ 05462 p->registry=ASTOBJ_REF(r); /* Add pointer to registry in packet */ 05463 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 05464 ast_copy_string(p->peersecret, r->secret, sizeof(p->peersecret)); 05465 if (!ast_strlen_zero(r->md5secret)) 05466 ast_copy_string(p->peermd5secret, r->md5secret, sizeof(p->peermd5secret)); 05467 /* User name in this realm 05468 - if authuser is set, use that, otherwise use username */ 05469 if (!ast_strlen_zero(r->authuser)) { 05470 ast_copy_string(p->peername, r->authuser, sizeof(p->peername)); 05471 ast_copy_string(p->authname, r->authuser, sizeof(p->authname)); 05472 } else { 05473 if (!ast_strlen_zero(r->username)) { 05474 ast_copy_string(p->peername, r->username, sizeof(p->peername)); 05475 ast_copy_string(p->authname, r->username, sizeof(p->authname)); 05476 ast_copy_string(p->fromuser, r->username, sizeof(p->fromuser)); 05477 } 05478 } 05479 if (!ast_strlen_zero(r->username)) 05480 ast_copy_string(p->username, r->username, sizeof(p->username)); 05481 /* Save extension in packet */ 05482 ast_copy_string(p->exten, r->contact, sizeof(p->exten)); 05483 05484 /* 05485 check which address we should use in our contact header 05486 based on whether the remote host is on the external or 05487 internal network so we can register through nat 05488 */ 05489 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 05490 memcpy(&p->ourip, &bindaddr.sin_addr, sizeof(p->ourip)); 05491 build_contact(p); 05492 } 05493 05494 /* set up a timeout */ 05495 if (auth == NULL) { 05496 if (r->timeout > -1) { 05497 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 05498 ast_sched_del(sched, r->timeout); 05499 } 05500 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 05501 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 05502 } 05503 05504 if (strchr(r->username, '@')) { 05505 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 05506 if (!ast_strlen_zero(p->theirtag)) 05507 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 05508 else 05509 snprintf(to, sizeof(to), "<sip:%s>", r->username); 05510 } else { 05511 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 05512 if (!ast_strlen_zero(p->theirtag)) 05513 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 05514 else 05515 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 05516 } 05517 05518 /* Fromdomain is what we are registering to, regardless of actual 05519 host name from SRV */ 05520 if (!ast_strlen_zero(p->fromdomain)) 05521 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 05522 else 05523 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 05524 ast_copy_string(p->uri, addr, sizeof(p->uri)); 05525 05526 p->branch ^= thread_safe_rand(); 05527 05528 memset(&req, 0, sizeof(req)); 05529 init_req(&req, sipmethod, addr); 05530 05531 /* Add to CSEQ */ 05532 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 05533 p->ocseq = r->ocseq; 05534 05535 build_via(p, via, sizeof(via)); 05536 add_header(&req, "Via", via); 05537 add_header(&req, "From", from); 05538 add_header(&req, "To", to); 05539 add_header(&req, "Call-ID", p->callid); 05540 add_header(&req, "CSeq", tmp); 05541 add_header(&req, "User-Agent", default_useragent); 05542 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 05543 05544 05545 if (auth) /* Add auth header */ 05546 add_header(&req, authheader, auth); 05547 else if (!ast_strlen_zero(r->nonce)) { 05548 char digest[1024]; 05549 05550 /* We have auth data to reuse, build a digest header! */ 05551 if (sipdebug) 05552 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 05553 ast_copy_string(p->realm, r->realm, sizeof(p->realm)); 05554 ast_copy_string(p->nonce, r->nonce, sizeof(p->nonce)); 05555 ast_copy_string(p->domain, r->domain, sizeof(p->domain)); 05556 ast_copy_string(p->opaque, r->opaque, sizeof(p->opaque)); 05557 ast_copy_string(p->qop, r->qop, sizeof(p->qop)); 05558 p->noncecount = r->noncecount++; 05559 05560 memset(digest,0,sizeof(digest)); 05561 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 05562 add_header(&req, "Authorization", digest); 05563 else 05564 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 05565 05566 } 05567 05568 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 05569 add_header(&req, "Expires", tmp); 05570 add_header(&req, "Contact", p->our_contact); 05571 add_header(&req, "Event", "registration"); 05572 add_header_contentLength(&req, 0); 05573 add_blank_header(&req); 05574 copy_request(&p->initreq, &req); 05575 parse_request(&p->initreq); 05576 if (sip_debug_test_pvt(p)) { 05577 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05578 } 05579 determine_firstline_parts(&p->initreq); 05580 r->regstate=auth?REG_STATE_AUTHSENT:REG_STATE_REGSENT; 05581 r->regattempts++; /* Another attempt */ 05582 if (option_debug > 3) 05583 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 05584 return send_request(p, &req, 2, p->ocseq); 05585 }
|
|
|
transmit_request: transmit generic SIP request ---
Definition at line 5660 of file chan_sip.c. References add_blank_header(), add_header_contentLength(), sip_pvt::ocseq, reqprep(), and send_request(). Referenced by handle_response(), handle_response_invite(), and handle_response_peerpoke(). 05661 { 05662 struct sip_request resp; 05663 reqprep(&resp, p, sipmethod, seqno, newbranch); 05664 add_header_contentLength(&resp, 0); 05665 add_blank_header(&resp); 05666 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 05667 }
|
|
transmit_request_with_auth: Transmit SIP request, auth added ---
Definition at line 5670 of file chan_sip.c. References add_blank_header(), add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), sip_invite_param::auth_type, build_reply_digest(), sip_pvt::callid, ast_channel::hangupcause, LOG_WARNING, sip_pvt::ocseq, sip_pvt::options, sip_pvt::owner, PROXY_AUTH, sip_pvt::realm, reqprep(), send_request(), SIP_BYE, and WWW_AUTH. Referenced by check_pendings(), handle_request_refer(), and sip_hangup(). 05671 { 05672 struct sip_request resp; 05673 05674 reqprep(&resp, p, sipmethod, seqno, newbranch); 05675 if (*p->realm) { 05676 char digest[1024]; 05677 05678 memset(digest, 0, sizeof(digest)); 05679 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 05680 if (p->options && p->options->auth_type == PROXY_AUTH) 05681 add_header(&resp, "Proxy-Authorization", digest); 05682 else if (p->options && p->options->auth_type == WWW_AUTH) 05683 add_header(&resp, "Authorization", digest); 05684 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 05685 add_header(&resp, "Proxy-Authorization", digest); 05686 } else 05687 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 05688 } 05689 /* If we are hanging up and know a cause for that, send it in clear text to make 05690 debugging easier. */ 05691 if (sipmethod == SIP_BYE) { 05692 if (p->owner && p->owner->hangupcause) { 05693 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 05694 } 05695 } 05696 05697 add_header_contentLength(&resp, 0); 05698 add_blank_header(&resp); 05699 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 05700 }
|
|
transmit_response: Transmit response, no retransmits
Definition at line 4229 of file chan_sip.c. References __transmit_response(). 04230 { 04231 return __transmit_response(p, msg, req, 0); 04232 }
|
|
transmit_response_reliable: Transmit response, Make sure you get a reply
Definition at line 4245 of file chan_sip.c. References __transmit_response(). Referenced by handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_subscribe(), sip_hangup(), and sip_sipredirect(). 04246 { 04247 return __transmit_response(p, msg, req, fatal ? 2 : 1); 04248 }
|
|
transmit_response_with_allow: Append Accept header, content length before transmitting response ---
Definition at line 4275 of file chan_sip.c. References add_blank_header(), add_header(), add_header_contentLength(), respprep(), and send_response(). Referenced by handle_request(), and handle_request_options(). 04276 { 04277 struct sip_request resp; 04278 respprep(&resp, p, msg, req); 04279 add_header(&resp, "Accept", "application/sdp"); 04280 add_header_contentLength(&resp, 0); 04281 add_blank_header(&resp); 04282 return send_response(p, &resp, reliable, 0); 04283 }
|
|
Definition at line 4286 of file chan_sip.c. References add_blank_header(), add_header(), add_header_contentLength(), ast_log(), get_header(), global_realm, LOG_WARNING, respprep(), and send_response(). Referenced by check_auth(), and transmit_fake_auth_response(). 04287 { 04288 struct sip_request resp; 04289 char tmp[512]; 04290 int seqno = 0; 04291 04292 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 04293 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 04294 return -1; 04295 } 04296 /* Stale means that they sent us correct authentication, but 04297 based it on an old challenge (nonce) */ 04298 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 04299 respprep(&resp, p, msg, req); 04300 add_header(&resp, header, tmp); 04301 add_header_contentLength(&resp, 0); 04302 add_blank_header(&resp); 04303 return send_response(p, &resp, reliable, seqno); 04304 }
|
|
transmit_response_with_date: Append date and content length before transmitting response ---
Definition at line 4264 of file chan_sip.c. References add_blank_header(), add_header_contentLength(), append_date(), respprep(), and send_response(). Referenced by register_verify(). 04265 { 04266 struct sip_request resp; 04267 respprep(&resp, p, msg, req); 04268 append_date(&resp); 04269 add_header_contentLength(&resp, 0); 04270 add_blank_header(&resp); 04271 return send_response(p, &resp, 0, 0); 04272 }
|
|
transmit_response_with_sdp: Used for 200 OK and 183 early media ---
Definition at line 4595 of file chan_sip.c. References add_sdp(), ast_log(), ast_rtp_offered_from_local(), sip_pvt::callid, get_header(), LOG_ERROR, LOG_WARNING, respprep(), sip_pvt::rtp, send_response(), and try_suggested_sip_codec(). Referenced by handle_request_invite(), sip_answer(), sip_indicate(), and sip_write(). 04596 { 04597 struct sip_request resp; 04598 int seqno; 04599 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 04600 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 04601 return -1; 04602 } 04603 respprep(&resp, p, msg, req); 04604 if (p->rtp) { 04605 ast_rtp_offered_from_local(p->rtp, 0); 04606 try_suggested_sip_codec(p); 04607 add_sdp(&resp, p); 04608 } else { 04609 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 04610 } 04611 return send_response(p, &resp, retrans, seqno); 04612 }
|
|
transmit_response_with_unsupported: Transmit response, no retransmits
Definition at line 4235 of file chan_sip.c. References add_header(), append_date(), respprep(), and send_response(). Referenced by handle_request_invite(). 04236 { 04237 struct sip_request resp; 04238 respprep(&resp, p, msg, req); 04239 append_date(&resp); 04240 add_header(&resp, "Unsupported", unsupported); 04241 return send_response(p, &resp, 0, 0); 04242 }
|
|
transmit_sip_request: Transmit SIP request
Definition at line 5247 of file chan_sip.c. References ast_verbose(), copy_request(), determine_firstline_parts(), sip_request::headers, sip_pvt::initreq, sip_request::lines, sip_pvt::ocseq, parse_request(), send_request(), and sip_debug_test_pvt(). Referenced by sip_notify(). 05248 { 05249 if (!p->initreq.headers) { 05250 /* Use this as the basis */ 05251 copy_request(&p->initreq, req); 05252 parse_request(&p->initreq); 05253 if (sip_debug_test_pvt(p)) 05254 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05255 determine_firstline_parts(&p->initreq); 05256 } 05257 05258 return send_request(p, req, 0, p->ocseq); 05259 }
|
|
transmit_state_notify: Used in the SUBSCRIBE notification subsystem ----
Definition at line 5041 of file chan_sip.c. References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, sip_pvt::context, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, cfsubscription_types::event, sip_pvt::expiry, sip_pvt::exten, find_subscription_type(), get_header(), get_in_brackets(), global_notifyringing, sip_pvt::initreq, LOG_WARNING, cfsubscription_types::mediatype, NONE, sip_pvt::ocseq, PIDF_XML, reqprep(), send_request(), SIP_NOTIFY, sip_pvt::subscribed, t, TIMEOUT, and XPIDF_XML. Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe(). 05042 { 05043 char tmp[4000], from[256], to[256]; 05044 char *t = tmp, *c, *a, *mfrom, *mto; 05045 size_t maxbytes = sizeof(tmp); 05046 struct sip_request req; 05047 char hint[AST_MAX_EXTENSION]; 05048 char *statestring = "terminated"; 05049 const struct cfsubscription_types *subscriptiontype; 05050 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 05051 char *pidfstate = "--"; 05052 char *pidfnote= "Ready"; 05053 05054 memset(from, 0, sizeof(from)); 05055 memset(to, 0, sizeof(to)); 05056 memset(tmp, 0, sizeof(tmp)); 05057 05058 switch (state) { 05059 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 05060 if (global_notifyringing) 05061 statestring = "early"; 05062 else 05063 statestring = "confirmed"; 05064 local_state = NOTIFY_INUSE; 05065 pidfstate = "busy"; 05066 pidfnote = "Ringing"; 05067 break; 05068 case AST_EXTENSION_RINGING: 05069 statestring = "early"; 05070 local_state = NOTIFY_INUSE; 05071 pidfstate = "busy"; 05072 pidfnote = "Ringing"; 05073 break; 05074 case AST_EXTENSION_INUSE: 05075 statestring = "confirmed"; 05076 local_state = NOTIFY_INUSE; 05077 pidfstate = "busy"; 05078 pidfnote = "On the phone"; 05079 break; 05080 case AST_EXTENSION_BUSY: 05081 statestring = "confirmed"; 05082 local_state = NOTIFY_CLOSED; 05083 pidfstate = "busy"; 05084 pidfnote = "On the phone"; 05085 break; 05086 case AST_EXTENSION_UNAVAILABLE: 05087 statestring = "confirmed"; 05088 local_state = NOTIFY_CLOSED; 05089 pidfstate = "away"; 05090 pidfnote = "Unavailable"; 05091 break; 05092 case AST_EXTENSION_NOT_INUSE: 05093 default: 05094 /* Default setting */ 05095 break; 05096 } 05097 05098 subscriptiontype = find_subscription_type(p->subscribed); 05099 05100 /* Check which device/devices we are watching and if they are registered */ 05101 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 05102 /* If they are not registered, we will override notification and show no availability */ 05103 if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) { 05104 local_state = NOTIFY_CLOSED; 05105 pidfstate = "away"; 05106 pidfnote = "Not online"; 05107 } 05108 } 05109 05110 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 05111 c = get_in_brackets(from); 05112 if (strncmp(c, "sip:", 4)) { 05113 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 05114 return -1; 05115 } 05116 if ((a = strchr(c, ';'))) 05117 *a = '\0'; 05118 mfrom = c; 05119 05120 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 05121 c = get_in_brackets(to); 05122 if (strncmp(c, "sip:", 4)) { 05123 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 05124 return -1; 05125 } 05126 if ((a = strchr(c, ';'))) 05127 *a = '\0'; 05128 mto = c; 05129 05130 reqprep(&req, p, SIP_NOTIFY, 0, 1); 05131 05132 05133 add_header(&req, "Event", subscriptiontype->event); 05134 add_header(&req, "Content-Type", subscriptiontype->mediatype); 05135 switch(state) { 05136 case AST_EXTENSION_DEACTIVATED: 05137 if (p->subscribed == TIMEOUT) 05138 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 05139 else { 05140 add_header(&req, "Subscription-State", "terminated;reason=probation"); 05141 add_header(&req, "Retry-After", "60"); 05142 } 05143 break; 05144 case AST_EXTENSION_REMOVED: 05145 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 05146 break; 05147 break; 05148 default: 05149 if (p->expiry) 05150 add_header(&req, "Subscription-State", "active"); 05151 else /* Expired */ 05152 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 05153 } 05154 switch (p->subscribed) { 05155 case XPIDF_XML: 05156 case CPIM_PIDF_XML: 05157 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 05158 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 05159 ast_build_string(&t, &maxbytes, "<presence>\n"); 05160 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 05161 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 05162 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 05163 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 05164 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 05165 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 05166 break; 05167 case PIDF_XML: /* Eyebeam supports this format */ 05168 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 05169 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); 05170 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 05171 if (pidfstate[0] != '-') 05172 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 05173 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 05174 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 05175 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 05176 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 05177 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 05178 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 05179 else 05180 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 05181 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 05182 break; 05183 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 05184 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 05185 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); 05186 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 05187 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 05188 else 05189 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 05190 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 05191 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 05192 break; 05193 case NONE: 05194 default: 05195 break; 05196 } 05197 05198 if (t > tmp + sizeof(tmp)) 05199 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 05200 05201 add_header_contentLength(&req, strlen(tmp)); 05202 add_line(&req, tmp); 05203 05204 return send_request(p, &req, 1, p->ocseq); 05205 }
|
|
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 2499 of file chan_sip.c. References ast_getformatbyname(), ast_log(), sip_pvt::capability, fmt, sip_pvt::jointcapability, LOG_NOTICE, sip_pvt::owner, and pbx_builtin_getvar_helper(). Referenced by sip_answer(), and transmit_response_with_sdp(). 02500 { 02501 int fmt; 02502 char *codec; 02503 02504 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 02505 if (!codec) 02506 return; 02507 02508 fmt = ast_getformatbyname(codec); 02509 if (fmt) { 02510 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC) variable\n",codec); 02511 if (p->jointcapability & fmt) { 02512 p->jointcapability &= fmt; 02513 p->capability &= fmt; 02514 } else 02515 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 02516 } else 02517 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n",codec); 02518 return; 02519 }
|
|
|
update_call_counter: Handle call_limit for SIP users Note: This is going to be replaced by app_groupcount Thought: For realtime, we should propably update storage with inuse counter...
Definition at line 2197 of file chan_sip.c. References ast_log(), ast_set_flag, ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_user::call_limit, DEC_CALL_LIMIT, find_peer(), find_user(), INC_CALL_LIMIT, sip_peer::inUse, sip_user::inUse, inuse, LOG_DEBUG, LOG_ERROR, name, option_debug, sip_pvt::peername, SIP_CALL_LIMIT, sip_destroy_peer(), sip_destroy_user(), SIP_INC_COUNT, SIP_OUTGOING, sipdebug, and sip_pvt::username. Referenced by handle_request_invite(), handle_response(), sip_call(), and sip_hangup(). 02198 { 02199 char name[256]; 02200 int *inuse, *call_limit; 02201 int outgoing = ast_test_flag(fup, SIP_OUTGOING); 02202 struct sip_user *u = NULL; 02203 struct sip_peer *p = NULL; 02204 02205 if (option_debug > 2) 02206 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 02207 /* Test if we need to check call limits, in order to avoid 02208 realtime lookups if we do not need it */ 02209 if (!ast_test_flag(fup, SIP_CALL_LIMIT)) 02210 return 0; 02211 02212 ast_copy_string(name, fup->username, sizeof(name)); 02213 02214 /* Check the list of users */ 02215 u = find_user(name, 1); 02216 if (u) { 02217 inuse = &u->inUse; 02218 call_limit = &u->call_limit; 02219 p = NULL; 02220 } else { 02221 /* Try to find peer */ 02222 if (!p) 02223 p = find_peer(fup->peername, NULL, 1); 02224 if (p) { 02225 inuse = &p->inUse; 02226 call_limit = &p->call_limit; 02227 ast_copy_string(name, fup->peername, sizeof(name)); 02228 } else { 02229 if (option_debug > 1) 02230 ast_log(LOG_DEBUG, "%s is not a local user, no call limit\n", name); 02231 return 0; 02232 } 02233 } 02234 switch(event) { 02235 /* incoming and outgoing affects the inUse counter */ 02236 case DEC_CALL_LIMIT: 02237 if ( *inuse > 0 ) { 02238 if (ast_test_flag(fup,SIP_INC_COUNT)) 02239 (*inuse)--; 02240 } else { 02241 *inuse = 0; 02242 } 02243 if (option_debug > 1 || sipdebug) { 02244 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 02245 } 02246 break; 02247 case INC_CALL_LIMIT: 02248 if (*call_limit > 0 ) { 02249 if (*inuse >= *call_limit) { 02250 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); 02251 if (u) 02252 ASTOBJ_UNREF(u,sip_destroy_user); 02253 else 02254 ASTOBJ_UNREF(p,sip_destroy_peer); 02255 return -1; 02256 } 02257 } 02258 (*inuse)++; 02259 ast_set_flag(fup,SIP_INC_COUNT); 02260 if (option_debug > 1 || sipdebug) { 02261 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 02262 } 02263 break; 02264 default: 02265 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 02266 } 02267 if (u) 02268 ASTOBJ_UNREF(u,sip_destroy_user); 02269 else 02270 ASTOBJ_UNREF(p,sip_destroy_peer); 02271 return 0; 02272 }
|
|
update_peer: Update peer data in database (if used) ---
Definition at line 1665 of file chan_sip.c. References sip_peer::addr, ast_test_flag, sip_peer::flags_page2, sip_peer::fullcontact, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username. Referenced by register_verify(). 01666 { 01667 int rtcachefriends = ast_test_flag(&(p->flags_page2), SIP_PAGE2_RTCACHEFRIENDS); 01668 if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTUPDATE) && 01669 (ast_test_flag(p, SIP_REALTIME) || rtcachefriends)) { 01670 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry); 01671 } 01672 }
|
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 13463 of file chan_sip.c. References usecnt. 13464 { 13465 return usecnt; 13466 }
|
|
Definition at line 413 of file chan_sip.c. |
|
Structure for conversion between compressed SIP and "normal" SIP.
|
|
Accept calls to external SIP domains? Definition at line 501 of file chan_sip.c. Referenced by get_destination(), reload_config(), and sip_show_settings(). |
|
Definition at line 381 of file chan_sip.c. Referenced by sip_destroy_peer(), sip_show_objects(), and temp_peer(). |
|
Definition at line 12940 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 12942 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 12954 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Authentication list Definition at line 884 of file chan_sip.c. Referenced by build_reply_digest(), reload_config(), sip_do_reload(), sip_show_settings(), and unload_module(). |
|
Auto creation of peers at registration? Default off. Definition at line 363 of file chan_sip.c. Referenced by register_verify(), reload_config(), and sip_show_settings(). |
|
Definition at line 874 of file chan_sip.c. |
|
Definition at line 909 of file chan_sip.c. Referenced by process_sdp(), reload_config(), and sip_show_settings(). |
|
Definition at line 145 of file chan_sip.c. |
|
Definition at line 9331 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
send compact sip headers Definition at line 426 of file chan_sip.c. Referenced by add_header(), reload_config(), and sip_show_settings(). |
|
Definition at line 146 of file chan_sip.c. |
|
Definition at line 9230 of file chan_sip.c. |
|
Definition at line 420 of file chan_sip.c. Referenced by sip_debug_test_addr(), sip_do_debug(), sip_do_debug_ip(), and sip_do_debug_peer(). |
|
Definition at line 343 of file chan_sip.c. Referenced by build_rpid(), initreqprep(), reload_config(), and sip_show_settings(). |
|
Definition at line 334 of file chan_sip.c. |
|
Definition at line 121 of file chan_sip.c. Referenced by handle_response_register(), parse_register_contact(), reload_config(), sip_register(), sip_send_all_registers(), sip_show_settings(), and transmit_register(). |
|
Definition at line 345 of file chan_sip.c. Referenced by reload_config(), sip_alloc(), sip_show_settings(), and transmit_register(). |
|
Definition at line 340 of file chan_sip.c. Referenced by build_peer(), build_user(), reload_config(), sip_show_settings(), and temp_peer(). |
|
Definition at line 348 of file chan_sip.c. Referenced by reload_config(), sip_show_settings(), and transmit_notify_with_mwi(). |
|
Default Qualify= setting Definition at line 354 of file chan_sip.c. Referenced by build_peer(), reload_config(), and sip_show_settings(). |
|
Definition at line 335 of file chan_sip.c. Referenced by build_peer(), reload_config(), and temp_peer(). |
|
Definition at line 331 of file chan_sip.c. Referenced by initreqprep(), reload_config(), reqprep(), respprep(), sip_show_settings(), and transmit_register(). |
|
Definition at line 144 of file chan_sip.c. |
|
Definition at line 12939 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 12946 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 12957 of file chan_sip.c. Referenced by load_module(). |
|
Dump history to verbose before destroying SIP dialog Definition at line 429 of file chan_sip.c. Referenced by __sip_destroy(), and reload_config(). |
|
Definition at line 437 of file chan_sip.c. Referenced by complete_dpreply(), parse_register_contact(), reg_source_db(), register_verify(), and reload_config(). |
|
Definition at line 877 of file chan_sip.c. Referenced by ast_sip_ouraddrfor(), and reload_config(). |
|
Definition at line 876 of file chan_sip.c. Referenced by ast_sip_ouraddrfor(), and reload_config(). |
|
Definition at line 875 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 878 of file chan_sip.c. Referenced by ast_sip_ouraddrfor(), and reload_config(). |
|
allow unauthenticated users/peers to connect? Definition at line 384 of file chan_sip.c. Referenced by check_auth(), check_user_full(), handle_common_options(), reload_config(), and sip_show_settings(). |
|
Send 401 Unauthorized for all failing requests Definition at line 352 of file chan_sip.c. Referenced by check_user_full(), register_verify(), reload_config(), and sip_show_settings(). |
|
Codecs that we support by default:.
Definition at line 410 of file chan_sip.c. Referenced by build_peer(), build_user(), reload_config(), sip_alloc(), sip_new(), sip_request_call(), and temp_peer(). |
|
global SIP_ flags Definition at line 356 of file chan_sip.c. |
|
more global SIP_ flags Definition at line 357 of file chan_sip.c. |
|
Global music on hold class Definition at line 431 of file chan_sip.c. Referenced by build_peer(), build_user(), reload_config(), sip_alloc(), sip_show_settings(), and temp_peer(). |
|
Time between MWI checks for peers Definition at line 387 of file chan_sip.c. Referenced by do_monitor(), reload_config(), and sip_show_settings(). |
|
Send notifications on ringing Definition at line 350 of file chan_sip.c. Referenced by reload_config(), sip_show_settings(), and transmit_state_notify(). |
|
Default realm Definition at line 433 of file chan_sip.c. Referenced by check_auth(), reload_config(), sip_show_settings(), and transmit_response_with_auth(). |
|
Definition at line 373 of file chan_sip.c. Referenced by reload_config(), sip_show_settings(), and transmit_register(). |
|
Definition at line 374 of file chan_sip.c. Referenced by handle_response_register(), reload_config(), sip_reg_timeout(), and sip_show_settings(). |
|
Definition at line 589 of file chan_sip.c. |
|
Definition at line 369 of file chan_sip.c. Referenced by build_peer(), reload_config(), sip_alloc(), sip_show_settings(), and temp_peer(). |
|
Definition at line 371 of file chan_sip.c. Referenced by build_peer(), reload_config(), sip_alloc(), and temp_peer(). |
|
Definition at line 367 of file chan_sip.c. Referenced by build_peer(), reload_config(), sip_alloc(), sip_show_settings(), and temp_peer(). |
|
Definition at line 338 of file chan_sip.c. Referenced by build_peer(), reload_config(), sip_show_settings(), and transmit_notify_with_mwi(). |
|
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 9247 of file chan_sip.c. |
|
sip_pvt: PVT structures are used for each SIP conversation, ie. a call
|
|
Definition at line 440 of file chan_sip.c. |
|
Definition at line 879 of file chan_sip.c. Referenced by ast_sip_ouraddrfor(), reload_config(), and unload_module(). |
|
Definition at line 7954 of file chan_sip.c. Referenced by load_module(). |
|
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 7536 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 120 of file chan_sip.c. Referenced by handle_request_subscribe(), parse_register_contact(), reload_config(), and sip_show_settings(). |
|
This is the thread for the monitor which checks for input on the channels which are not currently in use.
Definition at line 405 of file chan_sip.c. |
|
Definition at line 13285 of file chan_sip.c. |
|
Initial value: "Usage: sip no debug\n" " Disables dumping of SIP packets for debugging purposes\n" Definition at line 9239 of file chan_sip.c. |
|
Initial value: "Usage: sip no history\n" " Disables recording of SIP dialog history for debugging purposes\n" Definition at line 9243 of file chan_sip.c. |
|
Definition at line 411 of file chan_sip.c. Referenced by process_sdp(). |
|
Definition at line 147 of file chan_sip.c. Referenced by reload_config(), and sip_notify(). |
|
Definition at line 882 of file chan_sip.c. Referenced by complete_sipnotify(), reload_config(), and sip_notify(). |
|
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 9179 of file chan_sip.c. |
|
Definition at line 415 of file chan_sip.c. |
|
Definition at line 414 of file chan_sip.c. Referenced by reload_config(). |
|
Extra checking ? Default off Definition at line 361 of file chan_sip.c. Referenced by __get_header(), check_user_full(), find_call(), get_destination(), get_refer_info(), handle_request(), initreqprep(), process_sdp(), register_verify(), reload_config(), sip_show_settings(), and sipsock_read(). |
|
The peer list: Peers and Friends ---.
|
|
Definition at line 448 of file chan_sip.c. |
|
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 9221 of file chan_sip.c. |
|
Record SIP history. Off by default Definition at line 428 of file chan_sip.c. Referenced by append_history(), do_register_auth(), reload_config(), send_request(), send_response(), sip_do_history(), sip_no_history(), sip_reregister(), sip_scheddestroy(), sip_show_history(), sip_show_settings(), sipsock_read(), and transmit_register(). |
|
Context for auto-extensions Definition at line 434 of file chan_sip.c. |
|
The register list: Other SIP proxys we register with and call ---.
Referenced by delete_users(), load_module(), sip_do_reload(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module(). |
|
Definition at line 382 of file chan_sip.c. Referenced by sip_register(), sip_registry_destroy(), sip_send_all_registers(), and sip_show_objects(). |
|
Definition at line 365 of file chan_sip.c. Referenced by mkintf(), reload_config(), setup_zap(), sip_new(), and sip_show_settings(). |
|
Definition at line 380 of file chan_sip.c. Referenced by build_peer(), sip_destroy_peer(), and sip_show_objects(). |
|
Definition at line 378 of file chan_sip.c. Referenced by realtime_user(), sip_destroy_user(), and sip_show_objects(). |
|
Definition at line 439 of file chan_sip.c. |
|
Initial value: "Usage: sip show channel <channel>\n" " Provides detailed status on a given SIP channel.\n" Definition at line 9203 of file chan_sip.c. |
|
Initial value: "Usage: sip show channels\n" " Lists all currently active SIP channels.\n" Definition at line 9199 of file chan_sip.c. |
|
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 9174 of file chan_sip.c. |
|
Initial value: "Usage: sip show history <channel>\n" " Provides detailed dialog history on a given SIP channel.\n" Definition at line 9207 of file chan_sip.c. |
|
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 9194 of file chan_sip.c. |
|
Initial value: "Usage: sip show objects\n" " Shows status of known SIP objects\n" Definition at line 9260 of file chan_sip.c. |
|
Initial value: "Usage: sip show peer <name> [load]\n" " Lists all details on one SIP peer and the current status.\n" " Option \"load\" forces lookup of peer in realtime storage.\n" Definition at line 9216 of file chan_sip.c. |
|
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 9211 of file chan_sip.c. |
|
Initial value: "Usage: sip show registry\n" " Lists all registration requests and status.\n" Definition at line 9226 of file chan_sip.c. |
|
Initial value: "Usage: sip show settings\n" " Provides detailed list of the configuration of the SIP channel.\n" Definition at line 9264 of file chan_sip.c. |
|
Initial value: "Usage: sip show subscriptions\n" " Shows active SIP subscriptions for extension states\n" Definition at line 9256 of file chan_sip.c. |
|
Initial value: "Usage: sip show user <name> [load]\n" " Lists all details on one SIP user and the current status.\n" " Option \"load\" forces lookup of peer in realtime storage.\n" Definition at line 9189 of file chan_sip.c. |
|
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 9184 of file chan_sip.c. |
|
Definition at line 9310 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
|
|
XXX Note that sip_methods[i].id == i must hold or the code breaks Referenced by __sip_ack(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), do_proxy_auth(), find_call(), find_sip_method(), get_destination(), handle_request(), handle_request_subscribe(), handle_response(), init_req(), initreqprep(), reqprep(), retrans_pkt(), sip_alloc(), and transmit_register(). |
|
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(). |
|
Initial value: "Usage: sip reload\n" " Reloads SIP configuration from sip.conf\n" Definition at line 9252 of file chan_sip.c. |
|
Definition at line 806 of file chan_sip.c. Referenced by do_monitor(), and sip_reload(). |
|
sip_rtp: Interface structure with callbacks used to connect to rtp module --
Definition at line 13190 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition of this channel for PBX channel registration.
Definition at line 935 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 9495 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
|
Definition at line 9418 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 871 of file chan_sip.c. Referenced by __sip_xmit(), do_monitor(), reg_source_db(), reload_config(), sipsock_read(), and unload_module(). |
|
Definition at line 379 of file chan_sip.c. Referenced by build_peer(), sip_destroy_peer(), and sip_show_objects(). |
|
SRV Lookup on or off. Default is off, RFC behavior is on Definition at line 359 of file chan_sip.c. Referenced by create_addr(), reload_config(), and sip_show_settings(). |
|
Referenced by find_subscription_type(), and subscription_type2str(). |
|
Definition at line 377 of file chan_sip.c. Referenced by build_user(), realtime_user(), sip_destroy_user(), and sip_show_objects(). |
|
Definition at line 12938 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 12943 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 12955 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 422 of file chan_sip.c. |
|
Definition at line 389 of file chan_sip.c. |
|
The user list: Users and friends ---.
|
|
Definition at line 424 of file chan_sip.c. Referenced by reload_config(), sip_alloc(), and sip_show_settings(). |