#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"
Go to the source code of this file.
Data Structures | |
struct | ast_peer_list |
The peer list: Peers and Friends ---. More... | |
struct | ast_register_list |
The register list: Other SIP proxys we register with and call ---. More... | |
struct | ast_user_list |
The user list: Users and friends ---. More... | |
struct | cfalias |
Structure for conversion between compressed SIP and "normal" SIP. More... | |
struct | cfsip_methods |
struct | cfsip_options |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More... | |
struct | cfsubscription_types |
struct | domain |
struct | sip_auth |
sip_auth: Creadentials for authentication to other SIP services More... | |
struct | sip_dual |
struct | sip_history |
sip_history: Structure for saving transactions within a SIP dialog More... | |
struct | sip_invite_param |
Parameters to the transmit_invite function. More... | |
struct | sip_peer |
struct | sip_pkt |
sip packet - read in sipsock_read, transmitted in send_request More... | |
struct | sip_pvt |
sip_pvt: PVT structures are used for each SIP conversation, ie. a call More... | |
struct | sip_registry |
sip_registry: Registrations with other SIP proxies More... | |
struct | sip_request |
sip_request: The data grabbed from the UDP socket More... | |
struct | sip_route |
struct | sip_user |
Structure for SIP user data. User's place calls to us. 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 | FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s\n" |
sip_show_domains: CLI command to list local domains | |
#define | FORMAT "%-30.30s %-12.12s %8d %-20.20s\n" |
sip_show_domains: CLI command to list local domains | |
#define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
sip_show_domains: CLI command to list local domains | |
#define | FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s\n" |
sip_show_domains: CLI command to list local domains | |
#define | FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
sip_show_domains: CLI command to list local domains | |
#define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
sip_show_domains: CLI command to list local domains | |
#define | FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n" |
#define | FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s\n" |
#define | FREE free |
#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 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. | |
static 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, char **transfercontext) |
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 ---- | |
static 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, ast_group_t 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 sdp, 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 seqno, int reliable, int newbranch) |
transmit_request: transmit generic SIP request --- | |
static int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, 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_using_temp (char *callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, struct sip_request *req, char *msg) |
transmit_response_using_temp: Transmit response, no retransmits, using temporary pvt | |
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 * | sipsock_read_id |
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 324 of file chan_sip.c. Referenced by respprep(), transmit_invite(), and transmit_reinvite_with_sdp(). |
|
Definition at line 127 of file chan_sip.c. |
|
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 447 of file chan_sip.c. Referenced by handle_request_invite(), handle_response(), sip_hangup(), and update_call_counter(). |
|
Definition at line 343 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 334 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 437 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 reqprep(), and transmit_register(). |
|
Definition at line 131 of file chan_sip.c. |
|
Definition at line 387 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 348 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 433 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 329 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 338 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 109 of file chan_sip.c. |
|
Definition at line 111 of file chan_sip.c. |
|
Definition at line 115 of file chan_sip.c. |
|
Definition at line 108 of file chan_sip.c. |
|
Definition at line 705 of file chan_sip.c. Referenced by __sip_reliable_xmit(), and retrans_pkt(). |
|
Definition at line 704 of file chan_sip.c. Referenced by __sip_ack(), __sip_pretend_ack(), __sip_semi_ack(), handle_request(), and retrans_pkt(). |
|
sip_show_domains: CLI command to list local domains
Definition at line 7999 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7999 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7999 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7999 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7999 of file chan_sip.c. |
|
sip_show_domains: CLI command to list local domains
Definition at line 7999 of file chan_sip.c. |
|
|
|
|
|
|
|
|
|
Referenced by __sip_show_channels(). |
|
Definition at line 964 of file chan_sip.c. |
|
Definition at line 448 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 268 of file chan_sip.c. |
|
Definition at line 813 of file chan_sip.c. Referenced by registry_rerequest(), regstate2str(), and transmit_register(). |
|
Definition at line 818 of file chan_sip.c. Referenced by regstate2str(), and sip_reg_timeout(). |
|
Definition at line 817 of file chan_sip.c. Referenced by registry_rerequest(), and regstate2str(). |
|
Definition at line 814 of file chan_sip.c. Referenced by handle_response_register(), iax2_ack_registry(), and regstate2str(). |
|
Definition at line 812 of file chan_sip.c. Referenced by iax2_do_register(), regstate2str(), and transmit_register(). |
|
Definition at line 815 of file chan_sip.c. Referenced by regstate2str(), and socket_read(). |
|
Definition at line 816 of file chan_sip.c. Referenced by attempt_transmit(), and regstate2str(). |
|
Definition at line 811 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 520 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 568 of file chan_sip.c. Referenced by check_user_full(), create_addr_from_peer(), and update_call_counter(). |
|
Definition at line 567 of file chan_sip.c. Referenced by __sip_show_channels(), and process_sdp(). |
|
Can we send BYE for this dialog? Definition at line 535 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 550 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 418 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 419 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 537 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 541 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 539 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 540 of file chan_sip.c. Referenced by dtmfmode2str(), handle_common_options(), sip_dtmfmode(), and sip_senddigit(). |
|
RTP DTMF Definition at line 538 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 574 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 527 of file chan_sip.c. Referenced by handle_request_refer(), and sip_set_rtp_peer(). |
|
Definition at line 572 of file chan_sip.c. Referenced by update_call_counter(). |
|
don't require authentication for incoming INVITEs Definition at line 554 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 553 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 444 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 445 of file chan_sip.c. Referenced by add_line(), and parse_request(). |
|
Also from RFC 3261 (2543), should sub headers tho Definition at line 330 of file chan_sip.c. |
|
four settings, uses two bits Definition at line 543 of file chan_sip.c. Referenced by __sip_xmit(), _sip_show_peer(), _sip_show_peers(), 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 transmit_response_using_temp(). |
|
Definition at line 547 of file chan_sip.c. Referenced by copy_via_headers(), handle_common_options(), and nat2str(). |
|
No nat support Definition at line 544 of file chan_sip.c. Referenced by handle_common_options(), and nat2str(). |
|
Definition at line 545 of file chan_sip.c. Referenced by build_via(), handle_common_options(), nat2str(), and reload_config(). |
|
Definition at line 546 of file chan_sip.c. Referenced by __sip_xmit(), _sip_show_peers(), check_user_full(), check_via(), create_addr_from_peer(), handle_common_options(), 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 521 of file chan_sip.c. Referenced by __sip_show_channels(), 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 525 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 522 of file chan_sip.c. Referenced by process_sdp(), and sip_indicate(). |
|
Definition at line 271 of file chan_sip.c. |
|
Definition at line 273 of file chan_sip.c. |
|
Definition at line 281 of file chan_sip.c. |
|
Definition at line 282 of file chan_sip.c. |
|
Definition at line 274 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 276 of file chan_sip.c. |
|
Definition at line 278 of file chan_sip.c. |
|
Definition at line 270 of file chan_sip.c. |
|
Definition at line 279 of file chan_sip.c. |
|
Definition at line 280 of file chan_sip.c. |
|
Definition at line 283 of file chan_sip.c. |
|
Definition at line 272 of file chan_sip.c. |
|
four settings, uses two bits Definition at line 561 of file chan_sip.c. Referenced by check_auth(), check_user_full(), and handle_common_options(). |
|
Definition at line 565 of file chan_sip.c. Referenced by check_auth(), and handle_common_options(). |
|
Definition at line 563 of file chan_sip.c. Referenced by check_auth(), and handle_common_options(). |
|
Definition at line 562 of file chan_sip.c. Referenced by check_auth(). |
|
Definition at line 564 of file chan_sip.c. Referenced by check_auth(), and handle_common_options(). |
|
Is this an outgoing call? Definition at line 533 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 585 of file chan_sip.c. Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), function_sippeer(), register_verify(), and temp_peer(). |
|
Definition at line 583 of file chan_sip.c. Referenced by build_peer(), destroy_association(), reload_config(), and sip_show_settings(). |
|
Definition at line 584 of file chan_sip.c. Referenced by build_peer(), destroy_association(), parse_register_contact(), and reg_source_db(). |
|
Definition at line 582 of file chan_sip.c. Referenced by expire_register(), realtime_peer(), and reload_config(). |
|
Definition at line 580 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 581 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 526 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 588 of file chan_sip.c. Referenced by sipsock_read(). |
|
This packet has a to-tag Definition at line 589 of file chan_sip.c. Referenced by find_call(), and handle_request(). |
|
three settings, uses two bits Definition at line 556 of file chan_sip.c. Referenced by handle_common_options(), sip_indicate(), and sip_show_settings(). |
|
Definition at line 557 of file chan_sip.c. Referenced by sip_indicate(), and sip_show_settings(). |
|
Definition at line 558 of file chan_sip.c. Referenced by handle_common_options(), and sip_show_settings(). |
|
Definition at line 559 of file chan_sip.c. Referenced by handle_common_options(), and sip_indicate(). |
|
Have sent 183 message progress Definition at line 524 of file chan_sip.c. Referenced by sip_indicate(), and sip_write(). |
|
Promiscuous redirection Definition at line 528 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 531 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 549 of file chan_sip.c. Referenced by handle_common_options(). |
|
use UPDATE (RFC3311) when reinviting this peer Definition at line 551 of file chan_sip.c. Referenced by handle_common_options(), and transmit_reinvite_with_sdp(). |
|
Have sent 180 ringing Definition at line 523 of file chan_sip.c. Referenced by sip_indicate(). |
|
This is an autocreated peer Definition at line 534 of file chan_sip.c. Referenced by expire_register(), sip_destroy_peer(), and temp_peer(). |
|
Definition at line 570 of file chan_sip.c. Referenced by _sip_show_peer(), and handle_common_options(). |
|
Trust RPID headers? Definition at line 529 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 532 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 530 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 267 of file chan_sip.c. |
|
SIP Extensions we support.
Definition at line 327 of file chan_sip.c. |
|
Definition at line 93 of file chan_sip.c. |
|
Definition at line 489 of file chan_sip.c. 00489 { 00490 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00491 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00492 };
|
|
Definition at line 5945 of file chan_sip.c. 05945 { 05946 PARSE_REGISTER_FAILED, 05947 PARSE_REGISTER_UPDATE, 05948 PARSE_REGISTER_QUERY, 05949 };
|
|
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 2951 of file chan_sip.c. References sip_request::header, sip_request::headers, pass, and pedanticsipchecking. 02952 { 02953 int pass; 02954 02955 /* 02956 * Technically you can place arbitrary whitespace both before and after the ':' in 02957 * a header, although RFC3261 clearly says you shouldn't before, and place just 02958 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 02959 * a good idea to say you can do it, and if you can do it, why in the hell would. 02960 * you say you shouldn't. 02961 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 02962 * and we always allow spaces after that for compatibility. 02963 */ 02964 for (pass = 0; name && pass < 2;pass++) { 02965 int x, len = strlen(name); 02966 for (x=*start; x<req->headers; x++) { 02967 if (!strncasecmp(req->header[x], name, len)) { 02968 char *r = req->header[x] + len; /* skip name */ 02969 if (pedanticsipchecking) 02970 r = ast_skip_blanks(r); 02971 02972 if (*r == ':') { 02973 *start = x+1; 02974 return ast_skip_blanks(r+1); 02975 } 02976 } 02977 } 02978 if (pass == 0) /* Try aliases */ 02979 name = find_alias(name, NULL); 02980 } 02981 02982 /* Don't return NULL, so get_header is always a valid pointer */ 02983 return ""; 02984 }
|
|
__sip_ack: Acknowledges receipt of a packet and stops retransmission ---
Definition at line 1373 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, sched, sip_pkt::seqno, sip_methods, and cfsip_methods::text. Referenced by __sip_pretend_ack(), handle_request(), and handle_response(). 01374 { 01375 struct sip_pkt *cur, *prev = NULL; 01376 int res = -1; 01377 int resetinvite = 0; 01378 /* Just in case... */ 01379 char *msg; 01380 01381 msg = sip_methods[sipmethod].text; 01382 01383 ast_mutex_lock(&p->lock); 01384 cur = p->packets; 01385 while(cur) { 01386 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 01387 ((ast_test_flag(cur, FLAG_RESPONSE)) || 01388 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 01389 if (!resp && (seqno == p->pendinginvite)) { 01390 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 01391 p->pendinginvite = 0; 01392 resetinvite = 1; 01393 } 01394 /* this is our baby */ 01395 if (prev) 01396 prev->next = cur->next; 01397 else 01398 p->packets = cur->next; 01399 if (cur->retransid > -1) { 01400 if (sipdebug && option_debug > 3) 01401 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 01402 ast_sched_del(sched, cur->retransid); 01403 } 01404 free(cur); 01405 res = 0; 01406 break; 01407 } 01408 prev = cur; 01409 cur = cur->next; 01410 } 01411 ast_mutex_unlock(&p->lock); 01412 ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found"); 01413 return res; 01414 }
|
|
__sip_autodestruct: Kill a call (called by scheduler) ---
Definition at line 1317 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(). 01318 { 01319 struct sip_pvt *p = data; 01320 01321 01322 /* If this is a subscription, tell the phone that we got a timeout */ 01323 if (p->subscribed) { 01324 p->subscribed = TIMEOUT; 01325 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, 1); /* Send first notification */ 01326 p->subscribed = NONE; 01327 append_history(p, "Subscribestatus", "timeout"); 01328 return 10000; /* Reschedule this destruction so that we know that it's gone */ 01329 } 01330 01331 /* This scheduled event is now considered done. */ 01332 p->autokillid = -1; 01333 01334 ast_log(LOG_DEBUG, "Auto destroying call '%s'\n", p->callid); 01335 append_history(p, "AutoDestroy", ""); 01336 if (p->owner) { 01337 ast_log(LOG_WARNING, "Autodestruct on call '%s' with owner in place\n", p->callid); 01338 ast_queue_hangup(p->owner); 01339 } else { 01340 sip_destroy(p); 01341 } 01342 return 0; 01343 }
|
|
__sip_destroy: Execute destrucion of call structure, release memory---
Definition at line 2114 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, free, free_old_route(), iflist, LOG_DEBUG, LOG_WARNING, sip_pvt::next, oh323_pvt::next, sip_history::next, sip_pkt::retransid, sched, sip_debug_test_pvt(), sip_dump_history(), and sip_registry_destroy(). Referenced by do_monitor(), and sip_destroy(). 02115 { 02116 struct sip_pvt *cur, *prev = NULL; 02117 struct sip_pkt *cp; 02118 struct sip_history *hist; 02119 02120 if (sip_debug_test_pvt(p)) 02121 ast_verbose("Destroying call '%s'\n", p->callid); 02122 02123 if (dumphistory) 02124 sip_dump_history(p); 02125 02126 if (p->options) 02127 free(p->options); 02128 02129 if (p->stateid > -1) 02130 ast_extension_state_del(p->stateid, NULL); 02131 if (p->initid > -1) 02132 ast_sched_del(sched, p->initid); 02133 if (p->autokillid > -1) 02134 ast_sched_del(sched, p->autokillid); 02135 02136 if (p->rtp) { 02137 ast_rtp_destroy(p->rtp); 02138 } 02139 if (p->vrtp) { 02140 ast_rtp_destroy(p->vrtp); 02141 } 02142 if (p->route) { 02143 free_old_route(p->route); 02144 p->route = NULL; 02145 } 02146 if (p->registry) { 02147 if (p->registry->call == p) 02148 p->registry->call = NULL; 02149 ASTOBJ_UNREF(p->registry,sip_registry_destroy); 02150 } 02151 02152 if (p->rpid) 02153 free(p->rpid); 02154 02155 if (p->rpid_from) 02156 free(p->rpid_from); 02157 02158 /* Unlink us from the owner if we have one */ 02159 if (p->owner) { 02160 if (lockowner) 02161 ast_mutex_lock(&p->owner->lock); 02162 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 02163 p->owner->tech_pvt = NULL; 02164 if (lockowner) 02165 ast_mutex_unlock(&p->owner->lock); 02166 } 02167 /* Clear history */ 02168 while(p->history) { 02169 hist = p->history; 02170 p->history = p->history->next; 02171 free(hist); 02172 } 02173 02174 cur = iflist; 02175 while(cur) { 02176 if (cur == p) { 02177 if (prev) 02178 prev->next = cur->next; 02179 else 02180 iflist = cur->next; 02181 break; 02182 } 02183 prev = cur; 02184 cur = cur->next; 02185 } 02186 if (!cur) { 02187 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 02188 return; 02189 } 02190 while((cp = p->packets)) { 02191 p->packets = p->packets->next; 02192 if (cp->retransid > -1) { 02193 ast_sched_del(sched, cp->retransid); 02194 } 02195 free(cp); 02196 } 02197 if (p->chanvars) { 02198 ast_variables_destroy(p->chanvars); 02199 p->chanvars = NULL; 02200 } 02201 ast_mutex_destroy(&p->lock); 02202 free(p); 02203 }
|
|
__sip_do_register: Register with SIP proxy ---
Definition at line 5408 of file chan_sip.c. References SIP_REGISTER, and transmit_register(). Referenced by sip_reregister(). 05409 { 05410 int res; 05411 05412 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 05413 return res; 05414 }
|
|
Definition at line 1417 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(). 01418 { 01419 struct sip_pkt *cur=NULL; 01420 01421 while(p->packets) { 01422 if (cur == p->packets) { 01423 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 01424 return -1; 01425 } 01426 cur = p->packets; 01427 if (cur->method) 01428 __sip_ack(p, p->packets->seqno, (ast_test_flag(p->packets, FLAG_RESPONSE)), cur->method); 01429 else { /* Unknown packet type */ 01430 char *c; 01431 char method[128]; 01432 ast_copy_string(method, p->packets->data, sizeof(method)); 01433 c = ast_skip_blanks(method); /* XXX what ? */ 01434 *c = '\0'; 01435 __sip_ack(p, p->packets->seqno, (ast_test_flag(p->packets, FLAG_RESPONSE)), find_sip_method(method)); 01436 } 01437 } 01438 return 0; 01439 }
|
|
__sip_reliable_xmit: transmit packet with retransmits ---
Definition at line 1278 of file chan_sip.c. References __sip_xmit(), ast_log(), ast_sched_add_variable(), ast_set_flag, sip_pkt::data, DEFAULT_RETRANS, FLAG_FATAL, sip_pkt::flags, LOG_DEBUG, malloc, sip_pkt::method, sip_pkt::next, option_debug, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), sched, sip_pkt::seqno, SIP_INVITE, sip_pvt::timer_t1, and sip_pkt::timer_t1. Referenced by send_request(), and send_response(). 01279 { 01280 struct sip_pkt *pkt; 01281 int siptimer_a = DEFAULT_RETRANS; 01282 01283 pkt = malloc(sizeof(struct sip_pkt) + len + 1); 01284 if (!pkt) 01285 return -1; 01286 memset(pkt, 0, sizeof(struct sip_pkt)); 01287 memcpy(pkt->data, data, len); 01288 pkt->method = sipmethod; 01289 pkt->packetlen = len; 01290 pkt->next = p->packets; 01291 pkt->owner = p; 01292 pkt->seqno = seqno; 01293 pkt->flags = resp; 01294 pkt->data[len] = '\0'; 01295 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 01296 if (fatal) 01297 ast_set_flag(pkt, FLAG_FATAL); 01298 if (pkt->timer_t1) 01299 siptimer_a = pkt->timer_t1 * 2; 01300 01301 /* Schedule retransmission */ 01302 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 01303 if (option_debug > 3 && sipdebug) 01304 ast_log(LOG_DEBUG, "*** SIP TIMER: Initalizing retransmit timer on packet: Id #%d\n", pkt->retransid); 01305 pkt->next = p->packets; 01306 p->packets = pkt; 01307 01308 __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 01309 if (sipmethod == SIP_INVITE) { 01310 /* Note this is a pending invite */ 01311 p->pendinginvite = seqno; 01312 } 01313 return 0; 01314 }
|
|
__sip_semi_ack: Acks receipt of packet, keep it around (used for provisional responses) ---
Definition at line 1442 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, sched, sip_pkt::seqno, sip_methods, and cfsip_methods::text. Referenced by handle_response(). 01443 { 01444 struct sip_pkt *cur; 01445 int res = -1; 01446 char *msg = sip_methods[sipmethod].text; 01447 01448 cur = p->packets; 01449 while(cur) { 01450 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 01451 ((ast_test_flag(cur, FLAG_RESPONSE)) || 01452 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 01453 /* this is our baby */ 01454 if (cur->retransid > -1) { 01455 if (option_debug > 3 && sipdebug) 01456 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, msg); 01457 ast_sched_del(sched, cur->retransid); 01458 } 01459 cur->retransid = -1; 01460 res = 0; 01461 break; 01462 } 01463 cur = cur->next; 01464 } 01465 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"); 01466 return res; 01467 }
|
|
Definition at line 8456 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, FORMAT3, 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(). 08457 { 08458 #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s\n" 08459 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n" 08460 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s\n" 08461 struct sip_pvt *cur; 08462 char iabuf[INET_ADDRSTRLEN]; 08463 int numchans = 0; 08464 if (argc != 3) 08465 return RESULT_SHOWUSAGE; 08466 ast_mutex_lock(&iflock); 08467 cur = iflist; 08468 if (!subscriptions) 08469 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 08470 else 08471 ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type"); 08472 while (cur) { 08473 if (cur->subscribed == NONE && !subscriptions) { 08474 ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), 08475 ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 08476 cur->callid, 08477 cur->ocseq, cur->icseq, 08478 ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 08479 ast_test_flag(cur, SIP_CALL_ONHOLD) ? "Yes" : "No", 08480 ast_test_flag(cur, SIP_NEEDDESTROY) ? "(d)" : "", 08481 cur->lastmsg ); 08482 numchans++; 08483 } 08484 if (cur->subscribed != NONE && subscriptions) { 08485 ast_cli(fd, FORMAT3, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), 08486 ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 08487 cur->callid, cur->exten, ast_extension_state2str(cur->laststate), 08488 subscription_type2str(cur->subscribed)); 08489 numchans++; 08490 } 08491 cur = cur->next; 08492 } 08493 ast_mutex_unlock(&iflock); 08494 if (!subscriptions) 08495 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 08496 else 08497 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 08498 return RESULT_SUCCESS; 08499 #undef FORMAT 08500 #undef FORMAT2 08501 #undef FORMAT3 08502 }
|
|
__sip_xmit: Transmit SIP message ---
Definition at line 1073 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(). 01074 { 01075 int res; 01076 char iabuf[INET_ADDRSTRLEN]; 01077 01078 if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) 01079 res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->recv, sizeof(struct sockaddr_in)); 01080 else 01081 res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_in)); 01082 01083 if (res != len) { 01084 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)); 01085 } 01086 return res; 01087 }
|
|
__transmit_response: Base transmit response function
Definition at line 4239 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(), transmit_response_reliable(), and transmit_response_using_temp(). 04240 { 04241 struct sip_request resp; 04242 int seqno = 0; 04243 04244 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 04245 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 04246 return -1; 04247 } 04248 respprep(&resp, p, msg, req); 04249 add_header_contentLength(&resp, 0); 04250 /* If we are cancelling an incoming invite for some reason, add information 04251 about the reason why we are doing this in clear text */ 04252 if (msg[0] != '1' && p->owner && p->owner->hangupcause) { 04253 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 04254 } 04255 add_blank_header(&resp); 04256 return send_response(p, &resp, reliable, seqno); 04257 }
|
|
Definition at line 8062 of file chan_sip.c. References sip_peer::accountcode, sip_peer::addr, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_describe_caller_presentation(), 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, 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, s, 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(). 08063 { 08064 char status[30] = ""; 08065 char cbuf[256]; 08066 char iabuf[INET_ADDRSTRLEN]; 08067 struct sip_peer *peer; 08068 char codec_buf[512]; 08069 struct ast_codec_pref *pref; 08070 struct ast_variable *v; 08071 struct sip_auth *auth; 08072 int x = 0, codec = 0, load_realtime = 0; 08073 08074 if (argc < 4) 08075 return RESULT_SHOWUSAGE; 08076 08077 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 08078 peer = find_peer(argv[3], NULL, load_realtime); 08079 if (s) { /* Manager */ 08080 if (peer) 08081 ast_cli(s->fd, "Response: Success\r\n"); 08082 else { 08083 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); 08084 astman_send_error(s, m, cbuf); 08085 return 0; 08086 } 08087 } 08088 if (peer && type==0 ) { /* Normal listing */ 08089 ast_cli(fd,"\n\n"); 08090 ast_cli(fd, " * Name : %s\n", peer->name); 08091 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 08092 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 08093 auth = peer->auth; 08094 while(auth) { 08095 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 08096 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 08097 auth = auth->next; 08098 } 08099 ast_cli(fd, " Context : %s\n", peer->context); 08100 ast_cli(fd, " Subscr.Cont. : %s\n", ast_strlen_zero(peer->subscribecontext)?"<Not set>":peer->subscribecontext); 08101 ast_cli(fd, " Language : %s\n", peer->language); 08102 if (!ast_strlen_zero(peer->accountcode)) 08103 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 08104 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 08105 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 08106 if (!ast_strlen_zero(peer->fromuser)) 08107 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 08108 if (!ast_strlen_zero(peer->fromdomain)) 08109 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 08110 ast_cli(fd, " Callgroup : "); 08111 print_group(fd, peer->callgroup, 0); 08112 ast_cli(fd, " Pickupgroup : "); 08113 print_group(fd, peer->pickupgroup, 0); 08114 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 08115 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 08116 ast_cli(fd, " LastMsgsSent : %d\n", peer->lastmsgssent); 08117 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 08118 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)?"Yes":"No")); 08119 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 08120 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 08121 ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE))); 08122 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(peer, SIP_NAT))); 08123 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 08124 ast_cli(fd, " CanReinvite : %s\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Yes":"No")); 08125 ast_cli(fd, " PromiscRedir : %s\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Yes":"No")); 08126 ast_cli(fd, " User=Phone : %s\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Yes":"No")); 08127 ast_cli(fd, " Trust RPID : %s\n", (ast_test_flag(peer, SIP_TRUSTRPID) ? "Yes" : "No")); 08128 ast_cli(fd, " Send RPID : %s\n", (ast_test_flag(peer, SIP_SENDRPID) ? "Yes" : "No")); 08129 08130 /* - is enumerated */ 08131 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF))); 08132 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 08133 ast_cli(fd, " ToHost : %s\n", peer->tohost); 08134 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)); 08135 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 08136 ast_cli(fd, " Def. Username: %s\n", peer->username); 08137 ast_cli(fd, " SIP Options : "); 08138 if (peer->sipoptions) { 08139 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 08140 if (peer->sipoptions & sip_options[x].id) 08141 ast_cli(fd, "%s ", sip_options[x].text); 08142 } 08143 } else 08144 ast_cli(fd, "(none)"); 08145 08146 ast_cli(fd, "\n"); 08147 ast_cli(fd, " Codecs : "); 08148 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 08149 ast_cli(fd, "%s\n", codec_buf); 08150 ast_cli(fd, " Codec Order : ("); 08151 print_codec_to_cli(fd, &peer->prefs); 08152 08153 ast_cli(fd, ")\n"); 08154 08155 ast_cli(fd, " Status : "); 08156 peer_status(peer, status, sizeof(status)); 08157 ast_cli(fd, "%s\n",status); 08158 ast_cli(fd, " Useragent : %s\n", peer->useragent); 08159 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 08160 if (peer->chanvars) { 08161 ast_cli(fd, " Variables :\n"); 08162 for (v = peer->chanvars ; v ; v = v->next) 08163 ast_cli(fd, " %s = %s\n", v->name, v->value); 08164 } 08165 ast_cli(fd,"\n"); 08166 ASTOBJ_UNREF(peer,sip_destroy_peer); 08167 } else if (peer && type == 1) { /* manager listing */ 08168 ast_cli(fd, "Channeltype: SIP\r\n"); 08169 ast_cli(fd, "ObjectName: %s\r\n", peer->name); 08170 ast_cli(fd, "ChanObjectType: peer\r\n"); 08171 ast_cli(fd, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 08172 ast_cli(fd, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 08173 ast_cli(fd, "Context: %s\r\n", peer->context); 08174 ast_cli(fd, "Language: %s\r\n", peer->language); 08175 if (!ast_strlen_zero(peer->accountcode)) 08176 ast_cli(fd, "Accountcode: %s\r\n", peer->accountcode); 08177 ast_cli(fd, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 08178 ast_cli(fd, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 08179 if (!ast_strlen_zero(peer->fromuser)) 08180 ast_cli(fd, "SIP-FromUser: %s\r\n", peer->fromuser); 08181 if (!ast_strlen_zero(peer->fromdomain)) 08182 ast_cli(fd, "SIP-FromDomain: %s\r\n", peer->fromdomain); 08183 ast_cli(fd, "Callgroup: "); 08184 print_group(fd, peer->callgroup, 1); 08185 ast_cli(fd, "Pickupgroup: "); 08186 print_group(fd, peer->pickupgroup, 1); 08187 ast_cli(fd, "VoiceMailbox: %s\r\n", peer->mailbox); 08188 ast_cli(fd, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 08189 ast_cli(fd, "Call limit: %d\r\n", peer->call_limit); 08190 ast_cli(fd, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)?"Y":"N")); 08191 ast_cli(fd, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 08192 ast_cli(fd, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 08193 ast_cli(fd, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE))); 08194 ast_cli(fd, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(peer, SIP_NAT))); 08195 ast_cli(fd, "ACL: %s\r\n", (peer->ha?"Y":"N")); 08196 ast_cli(fd, "SIP-CanReinvite: %s\r\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Y":"N")); 08197 ast_cli(fd, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Y":"N")); 08198 ast_cli(fd, "SIP-UserPhone: %s\r\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Y":"N")); 08199 08200 /* - is enumerated */ 08201 ast_cli(fd, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF))); 08202 ast_cli(fd, "SIPLastMsg: %d\r\n", peer->lastmsg); 08203 ast_cli(fd, "ToHost: %s\r\n", peer->tohost); 08204 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)); 08205 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)); 08206 ast_cli(fd, "Default-Username: %s\r\n", peer->username); 08207 ast_cli(fd, "Codecs: "); 08208 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 08209 ast_cli(fd, "%s\r\n", codec_buf); 08210 ast_cli(fd, "CodecOrder: "); 08211 pref = &peer->prefs; 08212 for(x = 0; x < 32 ; x++) { 08213 codec = ast_codec_pref_index(pref,x); 08214 if (!codec) 08215 break; 08216 ast_cli(fd, "%s", ast_getformatname(codec)); 08217 if (x < 31 && ast_codec_pref_index(pref,x+1)) 08218 ast_cli(fd, ","); 08219 } 08220 08221 ast_cli(fd, "\r\n"); 08222 ast_cli(fd, "Status: "); 08223 peer_status(peer, status, sizeof(status)); 08224 ast_cli(fd, "%s\r\n", status); 08225 ast_cli(fd, "SIP-Useragent: %s\r\n", peer->useragent); 08226 ast_cli(fd, "Reg-Contact : %s\r\n", peer->fullcontact); 08227 if (peer->chanvars) { 08228 for (v = peer->chanvars ; v ; v = v->next) { 08229 ast_cli(fd, "ChanVariable:\n"); 08230 ast_cli(fd, " %s,%s\r\n", v->name, v->value); 08231 } 08232 } 08233 08234 ASTOBJ_UNREF(peer,sip_destroy_peer); 08235 08236 } else { 08237 ast_cli(fd,"Peer %s not found.\n", argv[3]); 08238 ast_cli(fd,"\n"); 08239 } 08240 08241 return RESULT_SUCCESS; 08242 }
|
|
_sip_show_peers: Execute sip show peers command
Definition at line 7640 of file chan_sip.c. References ast_cli(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_get_header(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, FORMAT2, id, name, peer_status(), peerl, RESULT_SHOWUSAGE, s, SIP_NAT, SIP_NAT_ROUTE, and SIP_PAGE2_DYNAMIC. Referenced by manager_sip_show_peers(), and sip_show_peers(). 07641 { 07642 regex_t regexbuf; 07643 int havepattern = 0; 07644 07645 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s\n" 07646 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s\n" 07647 07648 char name[256]; 07649 char iabuf[INET_ADDRSTRLEN]; 07650 int total_peers = 0; 07651 int peers_online = 0; 07652 int peers_offline = 0; 07653 char *id; 07654 char idtext[256] = ""; 07655 07656 if (s) { /* Manager - get ActionID */ 07657 id = astman_get_header(m,"ActionID"); 07658 if (!ast_strlen_zero(id)) 07659 snprintf(idtext,256,"ActionID: %s\r\n",id); 07660 } 07661 07662 switch (argc) { 07663 case 5: 07664 if (!strcasecmp(argv[3], "like")) { 07665 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 07666 return RESULT_SHOWUSAGE; 07667 havepattern = 1; 07668 } else 07669 return RESULT_SHOWUSAGE; 07670 case 3: 07671 break; 07672 default: 07673 return RESULT_SHOWUSAGE; 07674 } 07675 07676 if (!s) { /* Normal list */ 07677 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status"); 07678 } 07679 07680 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07681 char status[20] = ""; 07682 char srch[2000]; 07683 char pstatus; 07684 07685 ASTOBJ_RDLOCK(iterator); 07686 07687 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07688 ASTOBJ_UNLOCK(iterator); 07689 continue; 07690 } 07691 07692 if (!ast_strlen_zero(iterator->username) && !s) 07693 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 07694 else 07695 ast_copy_string(name, iterator->name, sizeof(name)); 07696 07697 pstatus = peer_status(iterator, status, sizeof(status)); 07698 if (pstatus) 07699 peers_online++; 07700 else { 07701 if (pstatus == 0) 07702 peers_offline++; 07703 else { /* Unmonitored */ 07704 /* Checking if port is 0 */ 07705 if ( ntohs(iterator->addr.sin_port) == 0 ) { 07706 peers_offline++; 07707 } else { 07708 peers_online++; 07709 } 07710 } 07711 } 07712 07713 snprintf(srch, sizeof(srch), FORMAT, name, 07714 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", 07715 ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 07716 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 07717 iterator->ha ? " A " : " ", /* permit/deny */ 07718 ntohs(iterator->addr.sin_port), status); 07719 07720 if (!s) {/* Normal CLI list */ 07721 ast_cli(fd, FORMAT, name, 07722 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", 07723 ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 07724 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 07725 iterator->ha ? " A " : " ", /* permit/deny */ 07726 07727 ntohs(iterator->addr.sin_port), status); 07728 } else { /* Manager format */ 07729 /* The names here need to be the same as other channels */ 07730 ast_cli(fd, 07731 "Event: PeerEntry\r\n%s" 07732 "Channeltype: SIP\r\n" 07733 "ObjectName: %s\r\n" 07734 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 07735 "IPaddress: %s\r\n" 07736 "IPport: %d\r\n" 07737 "Dynamic: %s\r\n" 07738 "Natsupport: %s\r\n" 07739 "ACL: %s\r\n" 07740 "Status: %s\r\n\r\n", 07741 idtext, 07742 iterator->name, 07743 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "-none-", 07744 ntohs(iterator->addr.sin_port), 07745 ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 07746 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 07747 iterator->ha ? "yes" : "no", /* permit/deny */ 07748 status); 07749 } 07750 07751 ASTOBJ_UNLOCK(iterator); 07752 07753 total_peers++; 07754 } while(0) ); 07755 07756 if (!s) { 07757 ast_cli(fd,"%d sip peers [%d online , %d offline]\n",total_peers,peers_online,peers_offline); 07758 } 07759 07760 if (havepattern) 07761 regfree(®exbuf); 07762 07763 if (total) 07764 *total = total_peers; 07765 07766 07767 return RESULT_SUCCESS; 07768 #undef FORMAT 07769 #undef FORMAT2 07770 }
|
|
add_blank_header: Add blank header to SIP message
Definition at line 3828 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(). 03829 { 03830 if (req->headers == SIP_MAX_HEADERS) { 03831 ast_log(LOG_WARNING, "Out of SIP header space\n"); 03832 return -1; 03833 } 03834 if (req->lines) { 03835 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 03836 return -1; 03837 } 03838 if (req->len >= sizeof(req->data) - 4) { 03839 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 03840 return -1; 03841 } 03842 req->header[req->headers] = req->data + req->len; 03843 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "\r\n"); 03844 req->len += strlen(req->header[req->headers]); 03845 req->headers++; 03846 return 0; 03847 }
|
|
Definition at line 4412 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(). 04415 { 04416 int rtp_code; 04417 04418 if (debug) 04419 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 04420 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 04421 return; 04422 04423 ast_build_string(m_buf, m_size, " %d", rtp_code); 04424 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 04425 ast_rtp_lookup_mime_subtype(1, codec), 04426 sample_rate); 04427 if (codec == AST_FORMAT_G729A) 04428 /* Indicate that we don't support VAD (G.729 annex B) */ 04429 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 04430 }
|
|
add_digit: add DTMF INFO tone to sip message ---
Definition at line 4381 of file chan_sip.c. References add_header(), add_header_contentLength(), and add_line(). Referenced by transmit_info_with_digit(). 04382 { 04383 char tmp[256]; 04384 04385 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=250\r\n", digit); 04386 add_header(req, "Content-Type", "application/dtmf-relay"); 04387 add_header_contentLength(req, strlen(tmp)); 04388 add_line(req, tmp); 04389 return 0; 04390 }
|
|
add_header: Add header to SIP message
Definition at line 3784 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. 03785 { 03786 int x = 0; 03787 03788 if (req->headers == SIP_MAX_HEADERS) { 03789 ast_log(LOG_WARNING, "Out of SIP header space\n"); 03790 return -1; 03791 } 03792 03793 if (req->lines) { 03794 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 03795 return -1; 03796 } 03797 03798 if (req->len >= sizeof(req->data) - 4) { 03799 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 03800 return -1; 03801 } 03802 03803 req->header[req->headers] = req->data + req->len; 03804 03805 if (compactheaders) { 03806 for (x = 0; x < (sizeof(aliases) / sizeof(aliases[0])); x++) 03807 if (!strcasecmp(aliases[x].fullname, var)) 03808 var = aliases[x].shortname; 03809 } 03810 03811 snprintf(req->header[req->headers], sizeof(req->data) - req->len - 4, "%s: %s\r\n", var, value); 03812 req->len += strlen(req->header[req->headers]); 03813 req->headers++; 03814 03815 return 0; 03816 }
|
|
add_header_contentLen: Add 'Content-Length' header to SIP message
Definition at line 3819 of file chan_sip.c. References add_header(). Referenced by __transmit_response(), add_digit(), 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(). 03820 { 03821 char clen[10]; 03822 03823 snprintf(clen, sizeof(clen), "%d", len); 03824 return add_header(req, "Content-Length", clen); 03825 }
|
|
add_line: Add content (not header) to SIP message
Definition at line 3850 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. 03851 { 03852 if (req->lines == SIP_MAX_LINES) { 03853 ast_log(LOG_WARNING, "Out of SIP line space\n"); 03854 return -1; 03855 } 03856 if (!req->lines) { 03857 /* Add extra empty return */ 03858 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 03859 req->len += strlen(req->data + req->len); 03860 } 03861 if (req->len >= sizeof(req->data) - 4) { 03862 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 03863 return -1; 03864 } 03865 req->line[req->lines] = req->data + req->len; 03866 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 03867 req->len += strlen(req->line[req->lines]); 03868 req->lines++; 03869 return 0; 03870 }
|
|
Definition at line 4432 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. 04435 { 04436 int rtp_code; 04437 04438 if (debug) 04439 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format)); 04440 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 04441 return; 04442 04443 ast_build_string(m_buf, m_size, " %d", rtp_code); 04444 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 04445 ast_rtp_lookup_mime_subtype(0, format), 04446 sample_rate); 04447 if (format == AST_RTP_DTMF) 04448 /* Indicate we support DTMF and FLASH... */ 04449 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 04450 }
|
|
add_realm_authentication: Add realm authentication in list ---
Definition at line 12064 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(). 12065 { 12066 char authcopy[256]; 12067 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 12068 char *stringp; 12069 struct sip_auth *auth; 12070 struct sip_auth *b = NULL, *a = authlist; 12071 12072 if (ast_strlen_zero(configuration)) 12073 return authlist; 12074 12075 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 12076 12077 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 12078 stringp = authcopy; 12079 12080 username = stringp; 12081 realm = strrchr(stringp, '@'); 12082 if (realm) { 12083 *realm = '\0'; 12084 realm++; 12085 } 12086 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 12087 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 12088 return authlist; 12089 } 12090 stringp = username; 12091 username = strsep(&stringp, ":"); 12092 if (username) { 12093 secret = strsep(&stringp, ":"); 12094 if (!secret) { 12095 stringp = username; 12096 md5secret = strsep(&stringp,"#"); 12097 } 12098 } 12099 auth = malloc(sizeof(struct sip_auth)); 12100 if (auth) { 12101 memset(auth, 0, sizeof(struct sip_auth)); 12102 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 12103 ast_copy_string(auth->username, username, sizeof(auth->username)); 12104 if (secret) 12105 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 12106 if (md5secret) 12107 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 12108 } else { 12109 ast_log(LOG_ERROR, "Allocation of auth structure failed, Out of memory\n"); 12110 return authlist; 12111 } 12112 12113 /* Add authentication to authl */ 12114 if (!authlist) { /* No existing list */ 12115 return auth; 12116 } 12117 while(a) { 12118 b = a; 12119 a = a->next; 12120 } 12121 b->next = auth; /* Add structure add end of list */ 12122 12123 if (option_verbose > 2) 12124 ast_verbose("Added authentication for realm %s\n", realm); 12125 12126 return authlist; 12127 12128 }
|
|
add_route: Add route header into request per learned route ---
Definition at line 3968 of file chan_sip.c. References add_header(), sip_route::hop, n, and sip_route::next. Referenced by reqprep(). 03969 { 03970 char r[BUFSIZ*2], *p; 03971 int n, rem = sizeof(r); 03972 03973 if (!route) return; 03974 03975 p = r; 03976 while (route) { 03977 n = strlen(route->hop); 03978 if ((n+3)>rem) break; 03979 if (p != r) { 03980 *p++ = ','; 03981 --rem; 03982 } 03983 *p++ = '<'; 03984 ast_copy_string(p, route->hop, rem); p += n; 03985 *p++ = '>'; 03986 rem -= (n+2); 03987 route = route->next; 03988 } 03989 *p = '\0'; 03990 add_header(req, "Route", r); 03991 }
|
|
add_sdp: Add Session Description Protocol message ---
Definition at line 4453 of file chan_sip.c. References add_codec_to_sdp(), ast_build_string(), ast_codec_pref_index(), AST_FORMAT_MAX_AUDIO, ast_inet_ntoa(), ast_log(), ast_rtp_get_us(), ast_verbose(), capability, debug, sip_pvt::jointcapability, sip_request::len, LOG_WARNING, 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(), t, sip_pvt::vredirip, and sip_pvt::vrtp. 04454 { 04455 int len = 0; 04456 int pref_codec; 04457 int alreadysent = 0; 04458 struct sockaddr_in sin; 04459 struct sockaddr_in vsin; 04460 char v[256]; 04461 char s[256]; 04462 char o[256]; 04463 char c[256]; 04464 char t[256]; 04465 char m_audio[256]; 04466 char m_video[256]; 04467 char a_audio[1024]; 04468 char a_video[1024]; 04469 char *m_audio_next = m_audio; 04470 char *m_video_next = m_video; 04471 size_t m_audio_left = sizeof(m_audio); 04472 size_t m_video_left = sizeof(m_video); 04473 char *a_audio_next = a_audio; 04474 char *a_video_next = a_video; 04475 size_t a_audio_left = sizeof(a_audio); 04476 size_t a_video_left = sizeof(a_video); 04477 char iabuf[INET_ADDRSTRLEN]; 04478 int x; 04479 int capability; 04480 struct sockaddr_in dest; 04481 struct sockaddr_in vdest = { 0, }; 04482 int debug; 04483 04484 debug = sip_debug_test_pvt(p); 04485 04486 len = 0; 04487 if (!p->rtp) { 04488 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 04489 return -1; 04490 } 04491 capability = p->jointcapability; 04492 04493 if (!p->sessionid) { 04494 p->sessionid = getpid(); 04495 p->sessionversion = p->sessionid; 04496 } else 04497 p->sessionversion++; 04498 ast_rtp_get_us(p->rtp, &sin); 04499 if (p->vrtp) 04500 ast_rtp_get_us(p->vrtp, &vsin); 04501 04502 if (p->redirip.sin_addr.s_addr) { 04503 dest.sin_port = p->redirip.sin_port; 04504 dest.sin_addr = p->redirip.sin_addr; 04505 if (p->redircodecs) 04506 capability = p->redircodecs; 04507 } else { 04508 dest.sin_addr = p->ourip; 04509 dest.sin_port = sin.sin_port; 04510 } 04511 04512 /* Determine video destination */ 04513 if (p->vrtp) { 04514 if (p->vredirip.sin_addr.s_addr) { 04515 vdest.sin_port = p->vredirip.sin_port; 04516 vdest.sin_addr = p->vredirip.sin_addr; 04517 } else { 04518 vdest.sin_addr = p->ourip; 04519 vdest.sin_port = vsin.sin_port; 04520 } 04521 } 04522 if (debug){ 04523 ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(sin.sin_port)); 04524 if (p->vrtp) 04525 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(vsin.sin_port)); 04526 } 04527 04528 /* We break with the "recommendation" and send our IP, in order that our 04529 peer doesn't have to ast_gethostbyname() us */ 04530 04531 snprintf(v, sizeof(v), "v=0\r\n"); 04532 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)); 04533 snprintf(s, sizeof(s), "s=session\r\n"); 04534 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr)); 04535 snprintf(t, sizeof(t), "t=0 0\r\n"); 04536 04537 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 04538 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 04539 04540 /* Prefer the codec we were requested to use, first, no matter what */ 04541 if (capability & p->prefcodec) { 04542 if (p->prefcodec <= AST_FORMAT_MAX_AUDIO) 04543 add_codec_to_sdp(p, p->prefcodec, 8000, 04544 &m_audio_next, &m_audio_left, 04545 &a_audio_next, &a_audio_left, 04546 debug); 04547 else 04548 add_codec_to_sdp(p, p->prefcodec, 90000, 04549 &m_video_next, &m_video_left, 04550 &a_video_next, &a_video_left, 04551 debug); 04552 alreadysent |= p->prefcodec; 04553 } 04554 04555 /* Start by sending our preferred codecs */ 04556 for (x = 0; x < 32; x++) { 04557 if (!(pref_codec = ast_codec_pref_index(&p->prefs, x))) 04558 break; 04559 04560 if (!(capability & pref_codec)) 04561 continue; 04562 04563 if (alreadysent & pref_codec) 04564 continue; 04565 04566 if (pref_codec <= AST_FORMAT_MAX_AUDIO) 04567 add_codec_to_sdp(p, pref_codec, 8000, 04568 &m_audio_next, &m_audio_left, 04569 &a_audio_next, &a_audio_left, 04570 debug); 04571 else 04572 add_codec_to_sdp(p, pref_codec, 90000, 04573 &m_video_next, &m_video_left, 04574 &a_video_next, &a_video_left, 04575 debug); 04576 alreadysent |= pref_codec; 04577 } 04578 04579 /* Now send any other common codecs, and non-codec formats: */ 04580 for (x = 1; x <= ((videosupport && p->vrtp) ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 04581 if (!(capability & x)) 04582 continue; 04583 04584 if (alreadysent & x) 04585 continue; 04586 04587 if (x <= AST_FORMAT_MAX_AUDIO) 04588 add_codec_to_sdp(p, x, 8000, 04589 &m_audio_next, &m_audio_left, 04590 &a_audio_next, &a_audio_left, 04591 debug); 04592 else 04593 add_codec_to_sdp(p, x, 90000, 04594 &m_video_next, &m_video_left, 04595 &a_video_next, &a_video_left, 04596 debug); 04597 } 04598 04599 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 04600 if (!(p->noncodeccapability & x)) 04601 continue; 04602 04603 add_noncodec_to_sdp(p, x, 8000, 04604 &m_audio_next, &m_audio_left, 04605 &a_audio_next, &a_audio_left, 04606 debug); 04607 } 04608 04609 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 04610 04611 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 04612 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 04613 04614 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 04615 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 04616 04617 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_audio) + strlen(a_audio); 04618 if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) /* only if video response is appropriate */ 04619 len += strlen(m_video) + strlen(a_video); 04620 04621 add_header(resp, "Content-Type", "application/sdp"); 04622 add_header_contentLength(resp, len); 04623 add_line(resp, v); 04624 add_line(resp, o); 04625 add_line(resp, s); 04626 add_line(resp, c); 04627 add_line(resp, t); 04628 add_line(resp, m_audio); 04629 add_line(resp, a_audio); 04630 if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) { /* only if video response is appropriate */ 04631 add_line(resp, m_video); 04632 add_line(resp, a_video); 04633 } 04634 04635 /* Update lastrtprx when we send our SDP */ 04636 time(&p->lastrtprx); 04637 time(&p->lastrtptx); 04638 04639 return 0; 04640 }
|
|
add_sip_domain: Add SIP domain to list of domains we are responsible for
Definition at line 11997 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(). 11998 { 11999 struct domain *d; 12000 12001 if (ast_strlen_zero(domain)) { 12002 ast_log(LOG_WARNING, "Zero length domain.\n"); 12003 return 1; 12004 } 12005 12006 d = calloc(1, sizeof(*d)); 12007 if (!d) { 12008 ast_log(LOG_ERROR, "Allocation of domain structure failed, Out of memory\n"); 12009 return 0; 12010 } 12011 12012 ast_copy_string(d->domain, domain, sizeof(d->domain)); 12013 12014 if (!ast_strlen_zero(context)) 12015 ast_copy_string(d->context, context, sizeof(d->context)); 12016 12017 d->mode = mode; 12018 12019 AST_LIST_LOCK(&domain_list); 12020 AST_LIST_INSERT_TAIL(&domain_list, d, list); 12021 AST_LIST_UNLOCK(&domain_list); 12022 12023 if (sipdebug) 12024 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 12025 12026 return 1; 12027 }
|
|
add_text: Add text body to SIP message ---
Definition at line 4370 of file chan_sip.c. References add_header(), add_header_contentLength(), and add_line(). Referenced by transmit_message_with_text(). 04371 { 04372 /* XXX Convert \n's to \r\n's XXX */ 04373 add_header(req, "Content-Type", "text/plain"); 04374 add_header_contentLength(req, strlen(text)); 04375 add_line(req, text); 04376 return 0; 04377 }
|
|
add_vidupdate: add XML encoded media control with update ---
Definition at line 4394 of file chan_sip.c. References add_header(), add_header_contentLength(), and add_line(). Referenced by transmit_info_with_vidupdate(). 04395 { 04396 const char *xml_is_a_huge_waste_of_space = 04397 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 04398 " <media_control>\r\n" 04399 " <vc_primitive>\r\n" 04400 " <to_encoder>\r\n" 04401 " <picture_fast_update>\r\n" 04402 " </picture_fast_update>\r\n" 04403 " </to_encoder>\r\n" 04404 " </vc_primitive>\r\n" 04405 " </media_control>\r\n"; 04406 add_header(req, "Content-Type", "application/media_control+xml"); 04407 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 04408 add_line(req, xml_is_a_huge_waste_of_space); 04409 return 0; 04410 }
|
|
append_date: Append date to SIP message ---
Definition at line 4314 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(). 04315 { 04316 char tmpdat[256]; 04317 struct tm tm; 04318 time_t t; 04319 04320 time(&t); 04321 gmtime_r(&t, &tm); 04322 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 04323 add_header(req, "Date", tmpdat); 04324 }
|
|
append_history: Append to SIP dialog history
Definition at line 1140 of file chan_sip.c. References ast_log(), sip_history::event, sip_pvt::history, LOG_WARNING, malloc, and sip_history::next. 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(). 01141 { 01142 struct sip_history *hist, *prev; 01143 char *c; 01144 01145 if (!recordhistory || !p) 01146 return 0; 01147 if(!(hist = malloc(sizeof(struct sip_history)))) { 01148 ast_log(LOG_WARNING, "Can't allocate memory for history\n"); 01149 return 0; 01150 } 01151 memset(hist, 0, sizeof(struct sip_history)); 01152 snprintf(hist->event, sizeof(hist->event), "%-15s %s", event, data); 01153 /* Trim up nicely */ 01154 c = hist->event; 01155 while(*c) { 01156 if ((*c == '\r') || (*c == '\n')) { 01157 *c = '\0'; 01158 break; 01159 } 01160 c++; 01161 } 01162 /* Enqueue into history */ 01163 prev = p->history; 01164 if (prev) { 01165 while(prev->next) 01166 prev = prev->next; 01167 prev->next = hist; 01168 } else { 01169 p->history = hist; 01170 } 01171 return 0; 01172 }
|
|
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 10339 of file chan_sip.c. References ast_channel::_state, ast_deactivate_generator(), AST_STATE_UP, and ast_channel::generatordata. Referenced by attempt_transfer(). 10340 { 10341 if (chan && chan->_state == AST_STATE_UP) { 10342 if (chan->generatordata) 10343 ast_deactivate_generator(chan); 10344 } 10345 }
|
|
ast_sip_ouraddrfor: NAT fix - decide which IP address to use for ASterisk server? ---
Definition at line 1105 of file chan_sip.c. References ahp, ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), bindaddr, externexpire, externhost, externip, 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(), transmit_register(), and transmit_response_using_temp(). 01106 { 01107 /* 01108 * Using the localaddr structure built up with localnet statements 01109 * apply it to their address to see if we need to substitute our 01110 * externip or can get away with our internal bindaddr 01111 */ 01112 struct sockaddr_in theirs; 01113 theirs.sin_addr = *them; 01114 if (localaddr && externip.sin_addr.s_addr && 01115 ast_apply_ha(localaddr, &theirs)) { 01116 char iabuf[INET_ADDRSTRLEN]; 01117 if (externexpire && (time(NULL) >= externexpire)) { 01118 struct ast_hostent ahp; 01119 struct hostent *hp; 01120 time(&externexpire); 01121 externexpire += externrefresh; 01122 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01123 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01124 } else 01125 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01126 } 01127 memcpy(us, &externip.sin_addr, sizeof(struct in_addr)); 01128 ast_inet_ntoa(iabuf, sizeof(iabuf), *(struct in_addr *)&them->s_addr); 01129 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", iabuf); 01130 } 01131 else if (bindaddr.sin_addr.s_addr) 01132 memcpy(us, &bindaddr.sin_addr, sizeof(struct in_addr)); 01133 else 01134 return ast_ouraddrfor(them, us); 01135 return 0; 01136 }
|
|
attempt_transfer: Attempt transfer of SIP call ---
Definition at line 10348 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. 10349 { 10350 int res = 0; 10351 struct ast_channel 10352 *chana = NULL, 10353 *chanb = NULL, 10354 *bridgea = NULL, 10355 *bridgeb = NULL, 10356 *peera = NULL, 10357 *peerb = NULL, 10358 *peerc = NULL, 10359 *peerd = NULL; 10360 10361 if (!p1->owner || !p2->owner) { 10362 ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n"); 10363 return -1; 10364 } 10365 chana = p1->owner; 10366 chanb = p2->owner; 10367 bridgea = ast_bridged_channel(chana); 10368 bridgeb = ast_bridged_channel(chanb); 10369 10370 if (bridgea) { 10371 peera = chana; 10372 peerb = chanb; 10373 peerc = bridgea; 10374 peerd = bridgeb; 10375 } else if (bridgeb) { 10376 peera = chanb; 10377 peerb = chana; 10378 peerc = bridgeb; 10379 peerd = bridgea; 10380 } 10381 10382 if (peera && peerb && peerc && (peerb != peerc)) { 10383 ast_quiet_chan(peera); 10384 ast_quiet_chan(peerb); 10385 ast_quiet_chan(peerc); 10386 ast_quiet_chan(peerd); 10387 10388 if (peera->cdr && peerb->cdr) { 10389 peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); 10390 } else if (peera->cdr) { 10391 peerb->cdr = peera->cdr; 10392 } 10393 peera->cdr = NULL; 10394 10395 if (peerb->cdr && peerc->cdr) { 10396 peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); 10397 } else if (peerc->cdr) { 10398 peerb->cdr = peerc->cdr; 10399 } 10400 peerc->cdr = NULL; 10401 10402 if (ast_channel_masquerade(peerb, peerc)) { 10403 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 10404 res = -1; 10405 } 10406 return res; 10407 } else { 10408 ast_log(LOG_NOTICE, "Transfer attempted with no appropriate bridged calls to transfer\n"); 10409 if (chana) 10410 ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV); 10411 if (chanb) 10412 ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV); 10413 return -1; 10414 } 10415 return 0; 10416 }
|
|
auto_congest: Scheduled congestion on a call ---
Definition at line 2001 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. 02002 { 02003 struct sip_pvt *p = nothing; 02004 ast_mutex_lock(&p->lock); 02005 p->initid = -1; 02006 if (p->owner) { 02007 if (!ast_mutex_trylock(&p->owner->lock)) { 02008 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 02009 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 02010 ast_mutex_unlock(&p->owner->lock); 02011 } 02012 } 02013 ast_mutex_unlock(&p->lock); 02014 return 0; 02015 }
|
|
build_callid: Build SIP CALLID header ---
Definition at line 3056 of file chan_sip.c. References thread_safe_rand(). Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register(). 03057 { 03058 int res; 03059 int val; 03060 int x; 03061 char iabuf[INET_ADDRSTRLEN]; 03062 for (x=0; x<4; x++) { 03063 val = thread_safe_rand(); 03064 res = snprintf(callid, len, "%08x", val); 03065 len -= res; 03066 callid += res; 03067 } 03068 if (!ast_strlen_zero(fromdomain)) 03069 snprintf(callid, len, "@%s", fromdomain); 03070 else 03071 /* It's not important that we really use our right IP here... */ 03072 snprintf(callid, len, "@%s", ast_inet_ntoa(iabuf, sizeof(iabuf), ourip)); 03073 }
|
|
build_contact: Build contact header - the contact header we send out ---
Definition at line 4770 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(), register_verify(), and transmit_register(). 04771 { 04772 char iabuf[INET_ADDRSTRLEN]; 04773 04774 /* Construct Contact: header */ 04775 if (ourport != 5060) /* Needs to be 5060, according to the RFC */ 04776 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); 04777 else 04778 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)); 04779 }
|
|
build_peer: Build peer from config file ---
Definition at line 12294 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, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_capability, global_flags, global_flags_page2, 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, prefs, 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, srvlookup, sip_peer::subscribecontext, sip_peer::tohost, sip_peer::username, ast_variable::value, and sip_peer::vmexten. 12295 { 12296 struct sip_peer *peer = NULL; 12297 struct ast_ha *oldha = NULL; 12298 int obproxyfound=0; 12299 int found=0; 12300 int format=0; /* Ama flags */ 12301 time_t regseconds; 12302 char *varname = NULL, *varval = NULL; 12303 struct ast_variable *tmpvar = NULL; 12304 struct ast_flags peerflags = {(0)}; 12305 struct ast_flags mask = {(0)}; 12306 12307 12308 if (!realtime) 12309 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 12310 /* We also use a case-sensitive comparison (unlike find_peer) so 12311 that case changes made to the peer name will be properly handled 12312 during reload 12313 */ 12314 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 12315 12316 if (peer) { 12317 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12318 found++; 12319 } else { 12320 peer = malloc(sizeof(*peer)); 12321 if (peer) { 12322 memset(peer, 0, sizeof(*peer)); 12323 if (realtime) 12324 rpeerobjs++; 12325 else 12326 speerobjs++; 12327 ASTOBJ_INIT(peer); 12328 peer->expire = -1; 12329 peer->pokeexpire = -1; 12330 } else { 12331 ast_log(LOG_WARNING, "Can't allocate SIP peer memory\n"); 12332 } 12333 } 12334 /* Note that our peer HAS had its reference count incrased */ 12335 if (!peer) 12336 return NULL; 12337 12338 peer->lastmsgssent = -1; 12339 if (!found) { 12340 if (name) 12341 ast_copy_string(peer->name, name, sizeof(peer->name)); 12342 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 12343 peer->addr.sin_family = AF_INET; 12344 peer->defaddr.sin_family = AF_INET; 12345 } 12346 /* If we have channel variables, remove them (reload) */ 12347 if (peer->chanvars) { 12348 ast_variables_destroy(peer->chanvars); 12349 peer->chanvars = NULL; 12350 } 12351 strcpy(peer->context, default_context); 12352 strcpy(peer->subscribecontext, default_subscribecontext); 12353 strcpy(peer->vmexten, global_vmexten); 12354 strcpy(peer->language, default_language); 12355 strcpy(peer->musicclass, global_musicclass); 12356 ast_copy_flags(peer, &global_flags, SIP_USEREQPHONE); 12357 peer->secret[0] = '\0'; 12358 peer->md5secret[0] = '\0'; 12359 peer->cid_num[0] = '\0'; 12360 peer->cid_name[0] = '\0'; 12361 peer->fromdomain[0] = '\0'; 12362 peer->fromuser[0] = '\0'; 12363 peer->regexten[0] = '\0'; 12364 peer->mailbox[0] = '\0'; 12365 peer->callgroup = 0; 12366 peer->pickupgroup = 0; 12367 peer->rtpkeepalive = global_rtpkeepalive; 12368 peer->maxms = default_qualify; 12369 peer->prefs = prefs; 12370 oldha = peer->ha; 12371 peer->ha = NULL; 12372 peer->addr.sin_family = AF_INET; 12373 ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY); 12374 peer->capability = global_capability; 12375 peer->rtptimeout = global_rtptimeout; 12376 peer->rtpholdtimeout = global_rtpholdtimeout; 12377 while(v) { 12378 if (handle_common_options(&peerflags, &mask, v)) { 12379 v = v->next; 12380 continue; 12381 } 12382 12383 if (realtime && !strcasecmp(v->name, "regseconds")) { 12384 if (sscanf(v->value, "%ld", (time_t *)®seconds) != 1) 12385 regseconds = 0; 12386 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 12387 inet_aton(v->value, &(peer->addr.sin_addr)); 12388 } else if (realtime && !strcasecmp(v->name, "name")) 12389 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 12390 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 12391 ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact)); 12392 ast_set_flag((&peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT); 12393 } else if (!strcasecmp(v->name, "secret")) 12394 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 12395 else if (!strcasecmp(v->name, "md5secret")) 12396 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 12397 else if (!strcasecmp(v->name, "auth")) 12398 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 12399 else if (!strcasecmp(v->name, "callerid")) { 12400 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 12401 } else if (!strcasecmp(v->name, "context")) { 12402 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 12403 } else if (!strcasecmp(v->name, "subscribecontext")) { 12404 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 12405 } else if (!strcasecmp(v->name, "fromdomain")) 12406 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 12407 else if (!strcasecmp(v->name, "usereqphone")) 12408 ast_set2_flag(peer, ast_true(v->value), SIP_USEREQPHONE); 12409 else if (!strcasecmp(v->name, "fromuser")) 12410 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 12411 else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 12412 if (!strcasecmp(v->value, "dynamic")) { 12413 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 12414 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 12415 } else { 12416 /* They'll register with us */ 12417 ast_set_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC); 12418 if (!found) { 12419 /* Initialize stuff iff we're not found, otherwise 12420 we keep going with what we had */ 12421 memset(&peer->addr.sin_addr, 0, 4); 12422 if (peer->addr.sin_port) { 12423 /* If we've already got a port, make it the default rather than absolute */ 12424 peer->defaddr.sin_port = peer->addr.sin_port; 12425 peer->addr.sin_port = 0; 12426 } 12427 } 12428 } 12429 } else { 12430 /* Non-dynamic. Make sure we become that way if we're not */ 12431 if (peer->expire > -1) 12432 ast_sched_del(sched, peer->expire); 12433 peer->expire = -1; 12434 ast_clear_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC); 12435 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 12436 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 12437 ASTOBJ_UNREF(peer, sip_destroy_peer); 12438 return NULL; 12439 } 12440 } 12441 if (!strcasecmp(v->name, "outboundproxy")) 12442 obproxyfound=1; 12443 else { 12444 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 12445 if (!peer->addr.sin_port) 12446 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 12447 } 12448 } 12449 } else if (!strcasecmp(v->name, "defaultip")) { 12450 if (ast_get_ip(&peer->defaddr, v->value)) { 12451 ASTOBJ_UNREF(peer, sip_destroy_peer); 12452 return NULL; 12453 } 12454 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 12455 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 12456 } else if (!strcasecmp(v->name, "port")) { 12457 if (!realtime && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)) 12458 peer->defaddr.sin_port = htons(atoi(v->value)); 12459 else 12460 peer->addr.sin_port = htons(atoi(v->value)); 12461 } else if (!strcasecmp(v->name, "callingpres")) { 12462 peer->callingpres = ast_parse_caller_presentation(v->value); 12463 if (peer->callingpres == -1) 12464 peer->callingpres = atoi(v->value); 12465 } else if (!strcasecmp(v->name, "username")) { 12466 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 12467 } else if (!strcasecmp(v->name, "language")) { 12468 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 12469 } else if (!strcasecmp(v->name, "regexten")) { 12470 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 12471 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 12472 peer->call_limit = atoi(v->value); 12473 if (peer->call_limit < 0) 12474 peer->call_limit = 0; 12475 } else if (!strcasecmp(v->name, "amaflags")) { 12476 format = ast_cdr_amaflags2int(v->value); 12477 if (format < 0) { 12478 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 12479 } else { 12480 peer->amaflags = format; 12481 } 12482 } else if (!strcasecmp(v->name, "accountcode")) { 12483 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 12484 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 12485 ast_copy_string(peer->musicclass, v->value, sizeof(peer->musicclass)); 12486 } else if (!strcasecmp(v->name, "mailbox")) { 12487 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 12488 } else if (!strcasecmp(v->name, "vmexten")) { 12489 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 12490 } else if (!strcasecmp(v->name, "callgroup")) { 12491 peer->callgroup = ast_get_group(v->value); 12492 } else if (!strcasecmp(v->name, "pickupgroup")) { 12493 peer->pickupgroup = ast_get_group(v->value); 12494 } else if (!strcasecmp(v->name, "allow")) { 12495 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 12496 } else if (!strcasecmp(v->name, "disallow")) { 12497 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 12498 } else if (!strcasecmp(v->name, "rtptimeout")) { 12499 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 12500 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12501 peer->rtptimeout = global_rtptimeout; 12502 } 12503 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 12504 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 12505 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12506 peer->rtpholdtimeout = global_rtpholdtimeout; 12507 } 12508 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 12509 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 12510 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 12511 peer->rtpkeepalive = global_rtpkeepalive; 12512 } 12513 } else if (!strcasecmp(v->name, "setvar")) { 12514 /* Set peer channel variable */ 12515 varname = ast_strdupa(v->value); 12516 if (varname && (varval = strchr(varname,'='))) { 12517 *varval = '\0'; 12518 varval++; 12519 if ((tmpvar = ast_variable_new(varname, varval))) { 12520 tmpvar->next = peer->chanvars; 12521 peer->chanvars = tmpvar; 12522 } 12523 } 12524 } else if (!strcasecmp(v->name, "qualify")) { 12525 if (!strcasecmp(v->value, "no")) { 12526 peer->maxms = 0; 12527 } else if (!strcasecmp(v->value, "yes")) { 12528 peer->maxms = DEFAULT_MAXMS; 12529 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 12530 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); 12531 peer->maxms = 0; 12532 } 12533 } 12534 /* else if (strcasecmp(v->name,"type")) 12535 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 12536 */ 12537 v=v->next; 12538 } 12539 if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) && realtime) { 12540 time_t nowtime; 12541 12542 time(&nowtime); 12543 if ((nowtime - regseconds) > 0) { 12544 destroy_association(peer); 12545 memset(&peer->addr, 0, sizeof(peer->addr)); 12546 if (option_debug) 12547 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 12548 } 12549 } 12550 ast_copy_flags(peer, &peerflags, mask.flags); 12551 if (!found && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) && !ast_test_flag(peer, SIP_REALTIME)) 12552 reg_source_db(peer); 12553 ASTOBJ_UNMARK(peer); 12554 ast_free_ha(oldha); 12555 return peer; 12556 }
|
|
build_reply_digest: Build reply digest ---
Definition at line 9174 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 transmit_register(), and transmit_request_with_auth(). 09175 { 09176 char a1[256]; 09177 char a2[256]; 09178 char a1_hash[256]; 09179 char a2_hash[256]; 09180 char resp[256]; 09181 char resp_hash[256]; 09182 char uri[256]; 09183 char cnonce[80]; 09184 char iabuf[INET_ADDRSTRLEN]; 09185 char *username; 09186 char *secret; 09187 char *md5secret; 09188 struct sip_auth *auth = (struct sip_auth *) NULL; /* Realm authentication */ 09189 09190 if (!ast_strlen_zero(p->domain)) 09191 ast_copy_string(uri, p->domain, sizeof(uri)); 09192 else if (!ast_strlen_zero(p->uri)) 09193 ast_copy_string(uri, p->uri, sizeof(uri)); 09194 else 09195 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); 09196 09197 snprintf(cnonce, sizeof(cnonce), "%08x", thread_safe_rand()); 09198 09199 /* Check if we have separate auth credentials */ 09200 if ((auth = find_realm_authentication(authl, p->realm))) { 09201 username = auth->username; 09202 secret = auth->secret; 09203 md5secret = auth->md5secret; 09204 if (sipdebug) 09205 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 09206 } else { 09207 /* No authentication, use peer or register= config */ 09208 username = p->authname; 09209 secret = p->peersecret; 09210 md5secret = p->peermd5secret; 09211 } 09212 if (ast_strlen_zero(username)) /* We have no authentication */ 09213 return -1; 09214 09215 09216 /* Calculate SIP digest response */ 09217 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 09218 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 09219 if (!ast_strlen_zero(md5secret)) 09220 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 09221 else 09222 ast_md5_hash(a1_hash,a1); 09223 ast_md5_hash(a2_hash,a2); 09224 09225 p->noncecount++; 09226 if (!ast_strlen_zero(p->qop)) 09227 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 09228 else 09229 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 09230 ast_md5_hash(resp_hash, resp); 09231 /* XXX We hard code our qop to "auth" for now. XXX */ 09232 if (!ast_strlen_zero(p->qop)) 09233 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); 09234 else 09235 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); 09236 09237 return 0; 09238 }
|
|
build_route: Build route list from Record-Route header ---
Definition at line 6128 of file chan_sip.c. References __get_header(), ast_log(), free_old_route(), sip_route::hop, LOG_DEBUG, malloc, sip_route::next, sip_pvt::route, and sip_pvt::route_persistant. Referenced by handle_request_invite(), and handle_response_invite(). 06129 { 06130 struct sip_route *thishop, *head, *tail; 06131 int start = 0; 06132 int len; 06133 char *rr, *contact, *c; 06134 06135 /* Once a persistant route is set, don't fool with it */ 06136 if (p->route && p->route_persistant) { 06137 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 06138 return; 06139 } 06140 06141 if (p->route) { 06142 free_old_route(p->route); 06143 p->route = NULL; 06144 } 06145 06146 p->route_persistant = backwards; 06147 06148 /* We build up head, then assign it to p->route when we're done */ 06149 head = NULL; tail = head; 06150 /* 1st we pass through all the hops in any Record-Route headers */ 06151 for (;;) { 06152 /* Each Record-Route header */ 06153 rr = __get_header(req, "Record-Route", &start); 06154 if (*rr == '\0') break; 06155 for (;;) { 06156 /* Each route entry */ 06157 /* Find < */ 06158 rr = strchr(rr, '<'); 06159 if (!rr) break; /* No more hops */ 06160 ++rr; 06161 len = strcspn(rr, ">") + 1; 06162 /* Make a struct route */ 06163 thishop = malloc(sizeof(*thishop) + len); 06164 if (thishop) { 06165 ast_copy_string(thishop->hop, rr, len); 06166 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 06167 /* Link in */ 06168 if (backwards) { 06169 /* Link in at head so they end up in reverse order */ 06170 thishop->next = head; 06171 head = thishop; 06172 /* If this was the first then it'll be the tail */ 06173 if (!tail) tail = thishop; 06174 } else { 06175 thishop->next = NULL; 06176 /* Link in at the end */ 06177 if (tail) 06178 tail->next = thishop; 06179 else 06180 head = thishop; 06181 tail = thishop; 06182 } 06183 } 06184 rr += len; 06185 } 06186 } 06187 06188 /* Only append the contact if we are dealing with a strict router */ 06189 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 06190 /* 2nd append the Contact: if there is one */ 06191 /* Can be multiple Contact headers, comma separated values - we just take the first */ 06192 contact = get_header(req, "Contact"); 06193 if (!ast_strlen_zero(contact)) { 06194 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 06195 /* Look for <: delimited address */ 06196 c = strchr(contact, '<'); 06197 if (c) { 06198 /* Take to > */ 06199 ++c; 06200 len = strcspn(c, ">") + 1; 06201 } else { 06202 /* No <> - just take the lot */ 06203 c = contact; 06204 len = strlen(contact) + 1; 06205 } 06206 thishop = malloc(sizeof(*thishop) + len); 06207 if (thishop) { 06208 ast_copy_string(thishop->hop, c, len); 06209 thishop->next = NULL; 06210 /* Goes at the end */ 06211 if (tail) 06212 tail->next = thishop; 06213 else 06214 head = thishop; 06215 } 06216 } 06217 } 06218 06219 /* Store as new route */ 06220 p->route = head; 06221 06222 /* For debugging dump what we ended up with */ 06223 if (sip_debug_test_pvt(p)) 06224 list_route(p->route); 06225 }
|
|
build_rpid: Build the Remote Party-ID & From using callingpres options ---
Definition at line 4782 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. 04783 { 04784 int send_pres_tags = 1; 04785 const char *privacy = NULL; 04786 const char *screen = NULL; 04787 char buf[256]; 04788 const char *clid = default_callerid; 04789 const char *clin = NULL; 04790 char iabuf[INET_ADDRSTRLEN]; 04791 const char *fromdomain; 04792 04793 if (p->rpid || p->rpid_from) 04794 return; 04795 04796 if (p->owner && p->owner->cid.cid_num) 04797 clid = p->owner->cid.cid_num; 04798 if (p->owner && p->owner->cid.cid_name) 04799 clin = p->owner->cid.cid_name; 04800 if (ast_strlen_zero(clin)) 04801 clin = clid; 04802 04803 switch (p->callingpres) { 04804 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 04805 privacy = "off"; 04806 screen = "no"; 04807 break; 04808 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 04809 privacy = "off"; 04810 screen = "yes"; 04811 break; 04812 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 04813 privacy = "off"; 04814 screen = "no"; 04815 break; 04816 case AST_PRES_ALLOWED_NETWORK_NUMBER: 04817 privacy = "off"; 04818 screen = "yes"; 04819 break; 04820 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 04821 privacy = "full"; 04822 screen = "no"; 04823 break; 04824 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 04825 privacy = "full"; 04826 screen = "yes"; 04827 break; 04828 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 04829 privacy = "full"; 04830 screen = "no"; 04831 break; 04832 case AST_PRES_PROHIB_NETWORK_NUMBER: 04833 privacy = "full"; 04834 screen = "yes"; 04835 break; 04836 case AST_PRES_NUMBER_NOT_AVAILABLE: 04837 send_pres_tags = 0; 04838 break; 04839 default: 04840 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 04841 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 04842 privacy = "full"; 04843 else 04844 privacy = "off"; 04845 screen = "no"; 04846 break; 04847 } 04848 04849 fromdomain = ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain; 04850 04851 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 04852 if (send_pres_tags) 04853 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 04854 p->rpid = strdup(buf); 04855 04856 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>;tag=%s", clin, 04857 ast_strlen_zero(p->fromuser) ? clid : p->fromuser, 04858 fromdomain, p->tag); 04859 p->rpid_from = strdup(buf); 04860 }
|
|
build_user: Initiate a SIP user structure from sip.conf ---
Definition at line 12161 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_flags, global_musicclass, handle_common_options(), ast_variable::lineno, LOG_WARNING, malloc, ast_variable::name, ast_variable::next, prefs, SIP_FLAGS_TO_COPY, suserobjs, user, and ast_variable::value. 12162 { 12163 struct sip_user *user; 12164 int format; 12165 struct ast_ha *oldha = NULL; 12166 char *varname = NULL, *varval = NULL; 12167 struct ast_variable *tmpvar = NULL; 12168 struct ast_flags userflags = {(0)}; 12169 struct ast_flags mask = {(0)}; 12170 12171 12172 user = (struct sip_user *)malloc(sizeof(struct sip_user)); 12173 if (!user) { 12174 return NULL; 12175 } 12176 memset(user, 0, sizeof(struct sip_user)); 12177 suserobjs++; 12178 ASTOBJ_INIT(user); 12179 ast_copy_string(user->name, name, sizeof(user->name)); 12180 oldha = user->ha; 12181 user->ha = NULL; 12182 ast_copy_flags(user, &global_flags, SIP_FLAGS_TO_COPY); 12183 user->capability = global_capability; 12184 user->prefs = prefs; 12185 /* set default context */ 12186 strcpy(user->context, default_context); 12187 strcpy(user->language, default_language); 12188 strcpy(user->musicclass, global_musicclass); 12189 while(v) { 12190 if (handle_common_options(&userflags, &mask, v)) { 12191 v = v->next; 12192 continue; 12193 } 12194 12195 if (!strcasecmp(v->name, "context")) { 12196 ast_copy_string(user->context, v->value, sizeof(user->context)); 12197 } else if (!strcasecmp(v->name, "subscribecontext")) { 12198 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 12199 } else if (!strcasecmp(v->name, "setvar")) { 12200 varname = ast_strdupa(v->value); 12201 if (varname && (varval = strchr(varname,'='))) { 12202 *varval = '\0'; 12203 varval++; 12204 if ((tmpvar = ast_variable_new(varname, varval))) { 12205 tmpvar->next = user->chanvars; 12206 user->chanvars = tmpvar; 12207 } 12208 } 12209 } else if (!strcasecmp(v->name, "permit") || 12210 !strcasecmp(v->name, "deny")) { 12211 user->ha = ast_append_ha(v->name, v->value, user->ha); 12212 } else if (!strcasecmp(v->name, "secret")) { 12213 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 12214 } else if (!strcasecmp(v->name, "md5secret")) { 12215 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 12216 } else if (!strcasecmp(v->name, "callerid")) { 12217 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 12218 } else if (!strcasecmp(v->name, "callgroup")) { 12219 user->callgroup = ast_get_group(v->value); 12220 } else if (!strcasecmp(v->name, "pickupgroup")) { 12221 user->pickupgroup = ast_get_group(v->value); 12222 } else if (!strcasecmp(v->name, "language")) { 12223 ast_copy_string(user->language, v->value, sizeof(user->language)); 12224 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 12225 ast_copy_string(user->musicclass, v->value, sizeof(user->musicclass)); 12226 } else if (!strcasecmp(v->name, "accountcode")) { 12227 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 12228 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 12229 user->call_limit = atoi(v->value); 12230 if (user->call_limit < 0) 12231 user->call_limit = 0; 12232 } else if (!strcasecmp(v->name, "amaflags")) { 12233 format = ast_cdr_amaflags2int(v->value); 12234 if (format < 0) { 12235 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 12236 } else { 12237 user->amaflags = format; 12238 } 12239 } else if (!strcasecmp(v->name, "allow")) { 12240 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 12241 } else if (!strcasecmp(v->name, "disallow")) { 12242 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 12243 } else if (!strcasecmp(v->name, "callingpres")) { 12244 user->callingpres = ast_parse_caller_presentation(v->value); 12245 if (user->callingpres == -1) 12246 user->callingpres = atoi(v->value); 12247 } 12248 /*else if (strcasecmp(v->name,"type")) 12249 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 12250 */ 12251 v = v->next; 12252 } 12253 ast_copy_flags(user, &userflags, mask.flags); 12254 ast_free_ha(oldha); 12255 return user; 12256 }
|
|
build_via: Build a Via header for a request ---
Definition at line 1092 of file chan_sip.c. References ast_inet_ntoa(), ast_test_flag, sip_pvt::branch, sip_pvt::ourip, 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(), transmit_register(), and transmit_response_using_temp(). 01093 { 01094 char iabuf[INET_ADDRSTRLEN]; 01095 01096 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01097 if (ast_test_flag(p, SIP_NAT) & SIP_NAT_RFC3581) 01098 snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); 01099 else /* Work around buggy UNIDEN UIP200 firmware */ 01100 snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); 01101 }
|
|
cb_extensionstate: Callback for the devicestate notification (SUBSCRIBE) support subsystem ---
Definition at line 6471 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_verbose, 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(). 06472 { 06473 struct sip_pvt *p = data; 06474 06475 switch(state) { 06476 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 06477 case AST_EXTENSION_REMOVED: /* Extension is gone */ 06478 if (p->autokillid > -1) 06479 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 06480 sip_scheddestroy(p, 15000); /* Delete subscription in 15 secs */ 06481 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); 06482 p->stateid = -1; 06483 p->subscribed = NONE; 06484 append_history(p, "Subscribestatus", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 06485 break; 06486 default: /* Tell user */ 06487 p->laststate = state; 06488 break; 06489 } 06490 transmit_state_notify(p, state, 1, 1); 06491 06492 if (option_verbose > 1) 06493 ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username); 06494 return 0; 06495 }
|
|
check_auth: Check user authorization from peer definition ---
Definition at line 6246 of file chan_sip.c. References ast_log(), ast_md5_hash(), ast_strlen_zero(), ast_test_flag, 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(). 06247 { 06248 int res = -1; 06249 char *response = "407 Proxy Authentication Required"; 06250 char *reqheader = "Proxy-Authorization"; 06251 char *respheader = "Proxy-Authenticate"; 06252 char *authtoken; 06253 #ifdef OSP_SUPPORT 06254 char *osptoken; 06255 #endif 06256 /* Always OK if no secret */ 06257 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret) 06258 #ifdef OSP_SUPPORT 06259 && !ast_test_flag(p, SIP_OSPAUTH) 06260 && global_allowguest != 2 06261 #endif 06262 ) 06263 return 0; 06264 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 06265 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 06266 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 06267 different circumstances! What a surprise. */ 06268 response = "401 Unauthorized"; 06269 reqheader = "Authorization"; 06270 respheader = "WWW-Authenticate"; 06271 } 06272 #ifdef OSP_SUPPORT 06273 else { 06274 ast_log (LOG_DEBUG, "Checking OSP Authentication!\n"); 06275 osptoken = get_header (req, "P-OSP-Auth-Token"); 06276 switch (ast_test_flag (p, SIP_OSPAUTH)) { 06277 case SIP_OSPAUTH_NO: 06278 break; 06279 case SIP_OSPAUTH_GATEWAY: 06280 if (ast_strlen_zero (osptoken)) { 06281 if (ast_strlen_zero (secret) && ast_strlen_zero (md5secret)) { 06282 return (0); 06283 } 06284 } 06285 else { 06286 return (check_osptoken (p, osptoken)); 06287 } 06288 break; 06289 case SIP_OSPAUTH_PROXY: 06290 if (ast_strlen_zero (osptoken)) { 06291 return (0); 06292 } 06293 else { 06294 return (check_osptoken (p, osptoken)); 06295 } 06296 break; 06297 case SIP_OSPAUTH_EXCLUSIVE: 06298 if (ast_strlen_zero (osptoken)) { 06299 return (-1); 06300 } 06301 else { 06302 return (check_osptoken (p, osptoken)); 06303 } 06304 break; 06305 default: 06306 return (-1); 06307 } 06308 } 06309 #endif 06310 authtoken = get_header(req, reqheader); 06311 if (ignore && !ast_strlen_zero(randdata) && ast_strlen_zero(authtoken)) { 06312 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 06313 information */ 06314 if (!ast_strlen_zero(randdata)) { 06315 if (!reliable) { 06316 /* Resend message if this was NOT a reliable delivery. Otherwise the 06317 retransmission should get it */ 06318 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06319 /* Schedule auto destroy in 15 seconds */ 06320 sip_scheddestroy(p, 15000); 06321 } 06322 res = 1; 06323 } 06324 } else if (ast_strlen_zero(randdata) || ast_strlen_zero(authtoken)) { 06325 snprintf(randdata, randlen, "%08x", thread_safe_rand()); 06326 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06327 /* Schedule auto destroy in 15 seconds */ 06328 sip_scheddestroy(p, 15000); 06329 res = 1; 06330 } else { 06331 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 06332 an example in the spec of just what it is you're doing a hash on. */ 06333 char a1[256]; 06334 char a2[256]; 06335 char a1_hash[256]; 06336 char a2_hash[256]; 06337 char resp[256]; 06338 char resp_hash[256]=""; 06339 char tmp[256]; 06340 char *c; 06341 char *z; 06342 char *ua_hash =""; 06343 char *resp_uri =""; 06344 char *nonce = ""; 06345 char *digestusername = ""; 06346 int wrongnonce = 0; 06347 char *usednonce = randdata; 06348 06349 /* Find their response among the mess that we'r sent for comparison */ 06350 ast_copy_string(tmp, authtoken, sizeof(tmp)); 06351 c = tmp; 06352 06353 while(c) { 06354 c = ast_skip_blanks(c); 06355 if (!*c) 06356 break; 06357 if (!strncasecmp(c, "response=", strlen("response="))) { 06358 c+= strlen("response="); 06359 if ((*c == '\"')) { 06360 ua_hash=++c; 06361 if ((c = strchr(c,'\"'))) 06362 *c = '\0'; 06363 06364 } else { 06365 ua_hash=c; 06366 if ((c = strchr(c,','))) 06367 *c = '\0'; 06368 } 06369 06370 } else if (!strncasecmp(c, "uri=", strlen("uri="))) { 06371 c+= strlen("uri="); 06372 if ((*c == '\"')) { 06373 resp_uri=++c; 06374 if ((c = strchr(c,'\"'))) 06375 *c = '\0'; 06376 } else { 06377 resp_uri=c; 06378 if ((c = strchr(c,','))) 06379 *c = '\0'; 06380 } 06381 06382 } else if (!strncasecmp(c, "username=", strlen("username="))) { 06383 c+= strlen("username="); 06384 if ((*c == '\"')) { 06385 digestusername=++c; 06386 if((c = strchr(c,'\"'))) 06387 *c = '\0'; 06388 } else { 06389 digestusername=c; 06390 if((c = strchr(c,','))) 06391 *c = '\0'; 06392 } 06393 } else if (!strncasecmp(c, "nonce=", strlen("nonce="))) { 06394 c+= strlen("nonce="); 06395 if ((*c == '\"')) { 06396 nonce=++c; 06397 if ((c = strchr(c,'\"'))) 06398 *c = '\0'; 06399 } else { 06400 nonce=c; 06401 if ((c = strchr(c,','))) 06402 *c = '\0'; 06403 } 06404 06405 } else 06406 if ((z = strchr(c,' ')) || (z = strchr(c,','))) c=z; 06407 if (c) 06408 c++; 06409 } 06410 /* Verify that digest username matches the username we auth as */ 06411 if (strcmp(username, digestusername)) { 06412 /* Oops, we're trying something here */ 06413 return -2; 06414 } 06415 06416 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 06417 if (strncasecmp(randdata, nonce, randlen)) { 06418 wrongnonce = 1; 06419 usednonce = nonce; 06420 } 06421 06422 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 06423 06424 if (!ast_strlen_zero(resp_uri)) 06425 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, resp_uri); 06426 else 06427 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, uri); 06428 06429 if (!ast_strlen_zero(md5secret)) 06430 snprintf(a1_hash, sizeof(a1_hash), "%s", md5secret); 06431 else 06432 ast_md5_hash(a1_hash, a1); 06433 06434 ast_md5_hash(a2_hash, a2); 06435 06436 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 06437 ast_md5_hash(resp_hash, resp); 06438 06439 if (wrongnonce) { 06440 06441 snprintf(randdata, randlen, "%08x", thread_safe_rand()); 06442 if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) { 06443 if (sipdebug) 06444 ast_log(LOG_NOTICE, "stale nonce received from '%s'\n", get_header(req, "To")); 06445 /* We got working auth token, based on stale nonce . */ 06446 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 1); 06447 } else { 06448 /* Everything was wrong, so give the device one more try with a new challenge */ 06449 if (sipdebug) 06450 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 06451 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06452 } 06453 06454 /* Schedule auto destroy in 15 seconds */ 06455 sip_scheddestroy(p, 15000); 06456 return 1; 06457 } 06458 /* resp_hash now has the expected response, compare the two */ 06459 if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) { 06460 /* Auth is OK */ 06461 res = 0; 06462 } 06463 } 06464 /* Failure */ 06465 return res; 06466 }
|
|
check_pendings: Check pending actions on SIP call ---
Definition at line 9612 of file chan_sip.c. References ast_clear_flag, ast_log(), ast_test_flag, sip_pvt::callid, LOG_DEBUG, SIP_BYE, SIP_CAN_BYE, SIP_CANCEL, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_scheddestroy(), transmit_reinvite_with_sdp(), and transmit_request_with_auth(). Referenced by handle_request(), and handle_response_invite(). 09613 { 09614 if (ast_test_flag(p, SIP_PENDINGBYE)) { 09615 /* if we can't BYE, then this is really a pending CANCEL */ 09616 if (!ast_test_flag(p, SIP_CAN_BYE)) 09617 transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0); 09618 /* Actually don't destroy us yet, wait for the 487 on our original 09619 INVITE, but do set an autodestruct just in case we never get it. */ 09620 else 09621 transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); 09622 ast_clear_flag(p, SIP_PENDINGBYE); 09623 sip_scheddestroy(p, 32000); 09624 } else if (ast_test_flag(p, SIP_NEEDREINVITE)) { 09625 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 09626 /* Didn't get to reinvite yet, so do it now */ 09627 transmit_reinvite_with_sdp(p); 09628 ast_clear_flag(p, SIP_NEEDREINVITE); 09629 } 09630 }
|
|
check_sip_domain: Check if domain part of uri is local to our server
Definition at line 12030 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(). 12031 { 12032 struct domain *d; 12033 int result = 0; 12034 12035 AST_LIST_LOCK(&domain_list); 12036 AST_LIST_TRAVERSE(&domain_list, d, list) { 12037 if (strcasecmp(d->domain, domain)) 12038 continue; 12039 12040 if (len && !ast_strlen_zero(d->context)) 12041 ast_copy_string(context, d->context, len); 12042 12043 result = 1; 12044 break; 12045 } 12046 AST_LIST_UNLOCK(&domain_list); 12047 12048 return result; 12049 }
|
|
check_user: Find user ---
Definition at line 7396 of file chan_sip.c. References check_user_full(). Referenced by handle_request_invite(). 07397 { 07398 return check_user_full(p, req, sipmethod, uri, reliable, sin, ignore, NULL, 0); 07399 }
|
|
check_user_full: Check if matching user or peer is defined ---
Definition at line 7128 of file chan_sip.c. References sip_peer::accountcode, sip_peer::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_strdupa, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_variable_new(), ast_verbose(), ASTOBJ_UNREF, build_contact(), sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_pvt::callingpres, sip_peer::capability, sip_peer::chanvars, check_auth(), sip_peer::cid_name, sip_pvt::cid_name, sip_peer::cid_num, sip_pvt::cid_num, sip_peer::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, global_flags, sip_peer::language, sip_peer::lastms, LOG_DEBUG, LOG_NOTICE, sip_peer::mailbox, sip_peer::maxms, sip_peer::md5secret, ast_variable::next, sip_pvt::our_contact, pedanticsipchecking, sip_pvt::peermd5secret, sip_pvt::peersecret, sip_peer::pickupgroup, sip_peer::prefs, sip_pvt::randdata, sip_pvt::recv, sip_pvt::rtp, sip_peer::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_peer::subscribecontext, sip_pvt::subscribecontext, t, sip_pvt::timer_t1, user, sip_peer::username, and sip_pvt::vrtp. Referenced by check_user(), and handle_request_subscribe(). 07129 { 07130 struct sip_user *user = NULL; 07131 struct sip_peer *peer; 07132 char *of, from[256], *c; 07133 char *rpid,rpid_num[50]; 07134 char iabuf[INET_ADDRSTRLEN]; 07135 int res = 0; 07136 char *t; 07137 char calleridname[50]; 07138 int debug=sip_debug_test_addr(sin); 07139 struct ast_variable *tmpvar = NULL, *v = NULL; 07140 char *uri2 = ast_strdupa(uri); 07141 07142 /* Terminate URI */ 07143 t = uri2; 07144 while(*t && (*t > 32) && (*t != ';')) 07145 t++; 07146 *t = '\0'; 07147 of = get_header(req, "From"); 07148 if (pedanticsipchecking) 07149 ast_uri_decode(of); 07150 07151 ast_copy_string(from, of, sizeof(from)); 07152 07153 memset(calleridname,0,sizeof(calleridname)); 07154 get_calleridname(from, calleridname, sizeof(calleridname)); 07155 if (calleridname[0]) 07156 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 07157 07158 rpid = get_header(req, "Remote-Party-ID"); 07159 memset(rpid_num, 0, sizeof(rpid_num)); 07160 if (!ast_strlen_zero(rpid)) 07161 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 07162 07163 of = get_in_brackets(from); 07164 if (ast_strlen_zero(p->exten)) { 07165 t = uri2; 07166 if (!strncmp(t, "sip:", 4)) 07167 t+= 4; 07168 ast_copy_string(p->exten, t, sizeof(p->exten)); 07169 t = strchr(p->exten, '@'); 07170 if (t) 07171 *t = '\0'; 07172 if (ast_strlen_zero(p->our_contact)) 07173 build_contact(p); 07174 } 07175 /* save the URI part of the From header */ 07176 ast_copy_string(p->from, of, sizeof(p->from)); 07177 if (strncmp(of, "sip:", 4)) { 07178 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07179 } else 07180 of += 4; 07181 /* Get just the username part */ 07182 if ((c = strchr(of, '@'))) { 07183 *c = '\0'; 07184 if ((c = strchr(of, ':'))) 07185 *c = '\0'; 07186 ast_copy_string(p->cid_num, of, sizeof(p->cid_num)); 07187 ast_shrink_phone_number(p->cid_num); 07188 } 07189 if (ast_strlen_zero(of)) 07190 return 0; 07191 07192 if (!mailbox) /* If it's a mailbox SUBSCRIBE, don't check users */ 07193 user = find_user(of, 1); 07194 07195 /* Find user based on user name in the from header */ 07196 if (user && ast_apply_ha(user->ha, sin)) { 07197 ast_copy_flags(p, user, SIP_FLAGS_TO_COPY); 07198 /* copy channel vars */ 07199 for (v = user->chanvars ; v ; v = v->next) { 07200 if ((tmpvar = ast_variable_new(v->name, v->value))) { 07201 tmpvar->next = p->chanvars; 07202 p->chanvars = tmpvar; 07203 } 07204 } 07205 p->prefs = user->prefs; 07206 /* replace callerid if rpid found, and not restricted */ 07207 if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) { 07208 if (*calleridname) 07209 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 07210 ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num)); 07211 ast_shrink_phone_number(p->cid_num); 07212 } 07213 07214 if (p->rtp) { 07215 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07216 ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07217 } 07218 if (p->vrtp) { 07219 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07220 ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07221 } 07222 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ignore))) { 07223 sip_cancel_destroy(p); 07224 ast_copy_flags(p, user, SIP_FLAGS_TO_COPY); 07225 /* Copy SIP extensions profile from INVITE */ 07226 if (p->sipoptions) 07227 user->sipoptions = p->sipoptions; 07228 07229 /* If we have a call limit, set flag */ 07230 if (user->call_limit) 07231 ast_set_flag(p, SIP_CALL_LIMIT); 07232 if (!ast_strlen_zero(user->context)) 07233 ast_copy_string(p->context, user->context, sizeof(p->context)); 07234 if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) { 07235 ast_copy_string(p->cid_num, user->cid_num, sizeof(p->cid_num)); 07236 ast_shrink_phone_number(p->cid_num); 07237 } 07238 if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) 07239 ast_copy_string(p->cid_name, user->cid_name, sizeof(p->cid_name)); 07240 ast_copy_string(p->peername, user->name, sizeof(p->peername)); 07241 ast_copy_string(p->username, user->name, sizeof(p->username)); 07242 ast_copy_string(p->peersecret, user->secret, sizeof(p->peersecret)); 07243 ast_copy_string(p->subscribecontext, user->subscribecontext, sizeof(p->subscribecontext)); 07244 ast_copy_string(p->peermd5secret, user->md5secret, sizeof(p->peermd5secret)); 07245 ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode)); 07246 ast_copy_string(p->language, user->language, sizeof(p->language)); 07247 ast_copy_string(p->musicclass, user->musicclass, sizeof(p->musicclass)); 07248 p->amaflags = user->amaflags; 07249 p->callgroup = user->callgroup; 07250 p->pickupgroup = user->pickupgroup; 07251 p->callingpres = user->callingpres; 07252 p->capability = user->capability; 07253 p->jointcapability = user->capability; 07254 if (p->peercapability) 07255 p->jointcapability &= p->peercapability; 07256 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO)) 07257 p->noncodeccapability |= AST_RTP_DTMF; 07258 else 07259 p->noncodeccapability &= ~AST_RTP_DTMF; 07260 } 07261 if (user && debug) 07262 ast_verbose("Found user '%s'\n", user->name); 07263 } else { 07264 if (user) { 07265 if (!mailbox && debug) 07266 ast_verbose("Found user '%s', but fails host access\n", user->name); 07267 ASTOBJ_UNREF(user,sip_destroy_user); 07268 } 07269 user = NULL; 07270 } 07271 07272 if (!user) { 07273 /* If we didn't find a user match, check for peers */ 07274 if (sipmethod == SIP_SUBSCRIBE) 07275 /* For subscribes, match on peer name only */ 07276 peer = find_peer(of, NULL, 1); 07277 else 07278 /* Look for peer based on the IP address we received data from */ 07279 /* If peer is registered from this IP address or have this as a default 07280 IP address, this call is from the peer 07281 */ 07282 peer = find_peer(NULL, &p->recv, 1); 07283 07284 if (peer) { 07285 if (debug) 07286 ast_verbose("Found peer '%s'\n", peer->name); 07287 /* Take the peer */ 07288 ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY); 07289 07290 /* Copy SIP extensions profile to peer */ 07291 if (p->sipoptions) 07292 peer->sipoptions = p->sipoptions; 07293 07294 /* replace callerid if rpid found, and not restricted */ 07295 if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) { 07296 if (*calleridname) 07297 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 07298 ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num)); 07299 ast_shrink_phone_number(p->cid_num); 07300 } 07301 if (p->rtp) { 07302 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07303 ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07304 } 07305 if (p->vrtp) { 07306 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07307 ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07308 } 07309 ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret)); 07310 p->peersecret[sizeof(p->peersecret)-1] = '\0'; 07311 ast_copy_string(p->subscribecontext, peer->subscribecontext, sizeof(p->subscribecontext)); 07312 ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret)); 07313 p->peermd5secret[sizeof(p->peermd5secret)-1] = '\0'; 07314 p->callingpres = peer->callingpres; 07315 if (peer->maxms && peer->lastms) 07316 p->timer_t1 = peer->lastms; 07317 if (ast_test_flag(peer, SIP_INSECURE_INVITE)) { 07318 /* Pretend there is no required authentication */ 07319 p->peersecret[0] = '\0'; 07320 p->peermd5secret[0] = '\0'; 07321 } 07322 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ignore))) { 07323 ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY); 07324 /* If we have a call limit, set flag */ 07325 if (peer->call_limit) 07326 ast_set_flag(p, SIP_CALL_LIMIT); 07327 ast_copy_string(p->peername, peer->name, sizeof(p->peername)); 07328 ast_copy_string(p->authname, peer->name, sizeof(p->authname)); 07329 /* copy channel vars */ 07330 for (v = peer->chanvars ; v ; v = v->next) { 07331 if ((tmpvar = ast_variable_new(v->name, v->value))) { 07332 tmpvar->next = p->chanvars; 07333 p->chanvars = tmpvar; 07334 } 07335 } 07336 if (mailbox) 07337 snprintf(mailbox, mailboxlen, ",%s,", peer->mailbox); 07338 if (!ast_strlen_zero(peer->username)) { 07339 ast_copy_string(p->username, peer->username, sizeof(p->username)); 07340 /* Use the default username for authentication on outbound calls */ 07341 ast_copy_string(p->authname, peer->username, sizeof(p->authname)); 07342 } 07343 if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) { 07344 ast_copy_string(p->cid_num, peer->cid_num, sizeof(p->cid_num)); 07345 ast_shrink_phone_number(p->cid_num); 07346 } 07347 if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 07348 ast_copy_string(p->cid_name, peer->cid_name, sizeof(p->cid_name)); 07349 ast_copy_string(p->fullcontact, peer->fullcontact, sizeof(p->fullcontact)); 07350 if (!ast_strlen_zero(peer->context)) 07351 ast_copy_string(p->context, peer->context, sizeof(p->context)); 07352 ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret)); 07353 ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret)); 07354 ast_copy_string(p->language, peer->language, sizeof(p->language)); 07355 ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode)); 07356 p->amaflags = peer->amaflags; 07357 p->callgroup = peer->callgroup; 07358 p->pickupgroup = peer->pickupgroup; 07359 p->capability = peer->capability; 07360 p->prefs = peer->prefs; 07361 p->jointcapability = peer->capability; 07362 if (p->peercapability) 07363 p->jointcapability &= p->peercapability; 07364 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO)) 07365 p->noncodeccapability |= AST_RTP_DTMF; 07366 else 07367 p->noncodeccapability &= ~AST_RTP_DTMF; 07368 } 07369 ASTOBJ_UNREF(peer,sip_destroy_peer); 07370 } else { 07371 if (debug) 07372 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)); 07373 07374 /* do we allow guests? */ 07375 if (!global_allowguest) { 07376 if (global_alwaysauthreject) 07377 res = -4; /* reject with fake authorization request */ 07378 else 07379 res = -1; /* we don't want any guests, authentication will fail */ 07380 #ifdef OSP_SUPPORT 07381 } else if (global_allowguest == 2) { 07382 ast_copy_flags(p, &global_flags, SIP_OSPAUTH); 07383 res = check_auth(p, req, p->randdata, sizeof(p->randdata), "", "", "", sipmethod, uri2, reliable, ignore); 07384 #endif 07385 } 07386 } 07387 07388 } 07389 07390 if (user) 07391 ASTOBJ_UNREF(user,sip_destroy_user); 07392 return res; 07393 }
|
|
check Via: header for hostname, port and rport request/answer
Definition at line 7004 of file chan_sip.c. References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_test_flag, ast_verbose(), DEFAULT_SIP_PORT, get_header(), hp, LOG_WARNING, sip_pvt::sa, 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(). 07005 { 07006 char via[256]; 07007 char iabuf[INET_ADDRSTRLEN]; 07008 char *c, *pt; 07009 struct hostent *hp; 07010 struct ast_hostent ahp; 07011 07012 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 07013 07014 /* Check for rport */ 07015 c = strstr(via, ";rport"); 07016 if (c && (c[6] != '=')) /* rport query, not answer */ 07017 ast_set_flag(p, SIP_NAT_ROUTE); 07018 07019 c = strchr(via, ';'); 07020 if (c) 07021 *c = '\0'; 07022 07023 c = strchr(via, ' '); 07024 if (c) { 07025 *c = '\0'; 07026 c = ast_skip_blanks(c+1); 07027 if (strcasecmp(via, "SIP/2.0/UDP")) { 07028 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 07029 return -1; 07030 } 07031 pt = strchr(c, ':'); 07032 if (pt) 07033 *pt++ = '\0'; /* remember port pointer */ 07034 hp = ast_gethostbyname(c, &ahp); 07035 if (!hp) { 07036 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 07037 return -1; 07038 } 07039 memset(&p->sa, 0, sizeof(p->sa)); 07040 p->sa.sin_family = AF_INET; 07041 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 07042 p->sa.sin_port = htons(pt ? atoi(pt) : DEFAULT_SIP_PORT); 07043 07044 if (sip_debug_test_pvt(p)) { 07045 c = (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? "NAT" : "non-NAT"; 07046 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), c); 07047 } 07048 } 07049 return 0; 07050 }
|
|
clear_realm_authentication: Clear realm authentication list (at reload) ---
Definition at line 12131 of file chan_sip.c. References free, and sip_auth::next. Referenced by sip_destroy_peer(), sip_do_reload(), and unload_module(). 12132 { 12133 struct sip_auth *a = authlist; 12134 struct sip_auth *b; 12135 12136 while (a) { 12137 b = a; 12138 a = a->next; 12139 free(b); 12140 } 12141 12142 return 1; 12143 }
|
|
clear_sip_domains: Clear our domain list (at reload)
Definition at line 12052 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(). 12053 { 12054 struct domain *d; 12055 12056 AST_LIST_LOCK(&domain_list); 12057 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 12058 free(d); 12059 AST_LIST_UNLOCK(&domain_list); 12060 }
|
|
complete_sip_debug_peer: Support routine for 'sip debug peer' CLI ---
Definition at line 8556 of file chan_sip.c. References complete_sip_peer(). 08557 { 08558 if (pos == 3) 08559 return complete_sip_peer(word, state, 0); 08560 08561 return NULL; 08562 }
|
|
complete_sip_peer: Do completion on peer name ---
Definition at line 8527 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(). 08528 { 08529 char *result = NULL; 08530 int wordlen = strlen(word); 08531 int which = 0; 08532 08533 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 08534 /* locking of the object is not required because only the name and flags are being compared */ 08535 if (!strncasecmp(word, iterator->name, wordlen)) { 08536 if (flags2 && !ast_test_flag((&iterator->flags_page2), flags2)) 08537 continue; 08538 if (++which > state) { 08539 result = strdup(iterator->name); 08540 } 08541 } 08542 } while(0) ); 08543 return result; 08544 }
|
|
complete_sip_prune_realtime_peer: Support routine for 'sip prune realtime peer' CLI ---
Definition at line 8627 of file chan_sip.c. References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS. 08628 { 08629 if (pos == 4) 08630 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 08631 return NULL; 08632 }
|
|
complete_sip_prune_realtime_user: Support routine for 'sip prune realtime user' CLI ---
Definition at line 8635 of file chan_sip.c. References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS. 08636 { 08637 if (pos == 4) 08638 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 08639 08640 return NULL; 08641 }
|
|
complete_sip_show_peer: Support routine for 'sip show peer' CLI ---
Definition at line 8547 of file chan_sip.c. References complete_sip_peer(). 08548 { 08549 if (pos == 3) 08550 return complete_sip_peer(word, state, 0); 08551 08552 return NULL; 08553 }
|
|
complete_sip_show_user: Support routine for 'sip show user' CLI ---
Definition at line 8585 of file chan_sip.c. References complete_sip_user(). 08586 { 08587 if (pos == 3) 08588 return complete_sip_user(word, state, 0); 08589 08590 return NULL; 08591 }
|
|
complete_sip_user: Do completion on user name ---
Definition at line 8565 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(). 08566 { 08567 char *result = NULL; 08568 int wordlen = strlen(word); 08569 int which = 0; 08570 08571 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 08572 /* locking of the object is not required because only the name and flags are being compared */ 08573 if (!strncasecmp(word, iterator->name, wordlen)) { 08574 if (flags2 && !ast_test_flag(&(iterator->flags_page2), flags2)) 08575 continue; 08576 if (++which > state) { 08577 result = strdup(iterator->name); 08578 } 08579 } 08580 } while(0) ); 08581 return result; 08582 }
|
|
complete_sipch: Support routine for 'sip show channel' CLI ---
Definition at line 8505 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::callid, iflist, sip_pvt::next, and strdup. 08506 { 08507 int which=0; 08508 struct sip_pvt *cur; 08509 char *c = NULL; 08510 08511 ast_mutex_lock(&iflock); 08512 cur = iflist; 08513 while(cur) { 08514 if (!strncasecmp(word, cur->callid, strlen(word))) { 08515 if (++which > state) { 08516 c = strdup(cur->callid); 08517 break; 08518 } 08519 } 08520 cur = cur->next; 08521 } 08522 ast_mutex_unlock(&iflock); 08523 return c; 08524 }
|
|
complete_sipnotify: Support routine for 'sip notify' CLI ---
Definition at line 8594 of file chan_sip.c. References ast_category_browse(), complete_sip_peer(), notify_types, and strdup. 08595 { 08596 char *c = NULL; 08597 08598 if (pos == 2) { 08599 int which = 0; 08600 char *cat; 08601 08602 /* do completion for notify type */ 08603 08604 if (!notify_types) 08605 return NULL; 08606 08607 cat = ast_category_browse(notify_types, NULL); 08608 while(cat) { 08609 if (!strncasecmp(word, cat, strlen(word))) { 08610 if (++which > state) { 08611 c = strdup(cat); 08612 break; 08613 } 08614 } 08615 cat = ast_category_browse(notify_types, cat); 08616 } 08617 return c; 08618 } 08619 08620 if (pos > 2) 08621 return complete_sip_peer(word, state, 0); 08622 08623 return NULL; 08624 }
|
|
copy_all_header: Copy all headers from one request to another ---
Definition at line 3886 of file chan_sip.c. References __get_header(), add_header(), and ast_strlen_zero(). Referenced by respprep(). 03887 { 03888 char *tmp; 03889 int start = 0; 03890 int copied = 0; 03891 for (;;) { 03892 tmp = __get_header(orig, field, &start); 03893 if (!ast_strlen_zero(tmp)) { 03894 /* Add what we're responding to */ 03895 add_header(req, field, tmp); 03896 copied++; 03897 } else 03898 break; 03899 } 03900 return copied ? 0 : -1; 03901 }
|
|
copy_header: Copy one header field from one request to another
Definition at line 3873 of file chan_sip.c. References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE. Referenced by reqprep(), and respprep(). 03874 { 03875 char *tmp; 03876 tmp = get_header(orig, field); 03877 if (!ast_strlen_zero(tmp)) { 03878 /* Add what we're responding to */ 03879 return add_header(req, field, tmp); 03880 } 03881 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 03882 return -1; 03883 }
|
|
copy_request: copy SIP request (mostly used to save request for responses) ---
Definition at line 4643 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(). 04644 { 04645 long offset; 04646 int x; 04647 offset = ((void *)dst) - ((void *)src); 04648 /* First copy stuff */ 04649 memcpy(dst, src, sizeof(*dst)); 04650 /* Now fix pointer arithmetic */ 04651 for (x=0; x < src->headers; x++) 04652 dst->header[x] += offset; 04653 for (x=0; x < src->lines; x++) 04654 dst->line[x] += offset; 04655 }
|
|
copy_via_headers: Copy SIP VIA Headers from the request to the response ---
Definition at line 3909 of file chan_sip.c. References __get_header(), add_header(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, sip_pvt::recv, SIP_NAT, and SIP_NAT_ALWAYS. Referenced by respprep(). 03910 { 03911 char tmp[256], *oh, *end; 03912 int start = 0; 03913 int copied = 0; 03914 char iabuf[INET_ADDRSTRLEN]; 03915 03916 for (;;) { 03917 oh = __get_header(orig, field, &start); 03918 if (!ast_strlen_zero(oh)) { 03919 if (!copied) { /* Only check for empty rport in topmost via header */ 03920 char *rport; 03921 char new[256]; 03922 03923 /* Find ;rport; (empty request) */ 03924 rport = strstr(oh, ";rport"); 03925 if (rport && *(rport+6) == '=') 03926 rport = NULL; /* We already have a parameter to rport */ 03927 03928 if (rport && (ast_test_flag(p, SIP_NAT) == SIP_NAT_ALWAYS)) { 03929 /* We need to add received port - rport */ 03930 ast_copy_string(tmp, oh, sizeof(tmp)); 03931 03932 rport = strstr(tmp, ";rport"); 03933 03934 if (rport) { 03935 end = strchr(rport + 1, ';'); 03936 if (end) 03937 memmove(rport, end, strlen(end) + 1); 03938 else 03939 *rport = '\0'; 03940 } 03941 03942 /* Add rport to first VIA header if requested */ 03943 /* Whoo hoo! Now we can indicate port address translation too! Just 03944 another RFC (RFC3581). I'll leave the original comments in for 03945 posterity. */ 03946 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)); 03947 } else { 03948 /* We should *always* add a received to the topmost via */ 03949 snprintf(new, sizeof(new), "%s;received=%s", oh, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 03950 } 03951 add_header(req, field, new); 03952 } else { 03953 /* Add the following via headers untouched */ 03954 add_header(req, field, oh); 03955 } 03956 copied++; 03957 } else 03958 break; 03959 } 03960 if (!copied) { 03961 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 03962 return -1; 03963 } 03964 return 0; 03965 }
|
|
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 1937 of file chan_sip.c. References ahp, 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(), sip_pvt::timer_t1, and sip_pvt::tohost. 01938 { 01939 struct hostent *hp; 01940 struct ast_hostent ahp; 01941 struct sip_peer *p; 01942 int found=0; 01943 char *port; 01944 int portno; 01945 char host[MAXHOSTNAMELEN], *hostn; 01946 char peer[256]; 01947 01948 ast_copy_string(peer, opeer, sizeof(peer)); 01949 port = strchr(peer, ':'); 01950 if (port) { 01951 *port = '\0'; 01952 port++; 01953 } 01954 dialog->sa.sin_family = AF_INET; 01955 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 01956 p = find_peer(peer, NULL, 1); 01957 01958 if (p) { 01959 found++; 01960 if (create_addr_from_peer(dialog, p)) 01961 ASTOBJ_UNREF(p, sip_destroy_peer); 01962 } 01963 if (!p) { 01964 if (found) 01965 return -1; 01966 01967 hostn = peer; 01968 if (port) 01969 portno = atoi(port); 01970 else 01971 portno = DEFAULT_SIP_PORT; 01972 if (srvlookup) { 01973 char service[MAXHOSTNAMELEN]; 01974 int tportno; 01975 int ret; 01976 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 01977 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 01978 if (ret > 0) { 01979 hostn = host; 01980 portno = tportno; 01981 } 01982 } 01983 hp = ast_gethostbyname(hostn, &ahp); 01984 if (hp) { 01985 ast_copy_string(dialog->tohost, peer, sizeof(dialog->tohost)); 01986 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 01987 dialog->sa.sin_port = htons(portno); 01988 memcpy(&dialog->recv, &dialog->sa, sizeof(dialog->recv)); 01989 return 0; 01990 } else { 01991 ast_log(LOG_WARNING, "No such host: %s\n", peer); 01992 return -1; 01993 } 01994 } else { 01995 ASTOBJ_UNREF(p, sip_destroy_peer); 01996 return 0; 01997 } 01998 }
|
|
create_addr_from_peer: create address structure from peer reference ---
Definition at line 1861 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(). 01862 { 01863 char *callhost; 01864 01865 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 01866 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 01867 if (peer->addr.sin_addr.s_addr) { 01868 r->sa.sin_family = peer->addr.sin_family; 01869 r->sa.sin_addr = peer->addr.sin_addr; 01870 r->sa.sin_port = peer->addr.sin_port; 01871 } else { 01872 r->sa.sin_family = peer->defaddr.sin_family; 01873 r->sa.sin_addr = peer->defaddr.sin_addr; 01874 r->sa.sin_port = peer->defaddr.sin_port; 01875 } 01876 memcpy(&r->recv, &r->sa, sizeof(r->recv)); 01877 } else { 01878 return -1; 01879 } 01880 01881 ast_copy_flags(r, peer, SIP_FLAGS_TO_COPY); 01882 r->capability = peer->capability; 01883 r->prefs = peer->prefs; 01884 if (r->rtp) { 01885 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE)); 01886 ast_rtp_setnat(r->rtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE)); 01887 } 01888 if (r->vrtp) { 01889 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE)); 01890 ast_rtp_setnat(r->vrtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE)); 01891 } 01892 ast_copy_string(r->peername, peer->username, sizeof(r->peername)); 01893 ast_copy_string(r->authname, peer->username, sizeof(r->authname)); 01894 ast_copy_string(r->username, peer->username, sizeof(r->username)); 01895 ast_copy_string(r->peersecret, peer->secret, sizeof(r->peersecret)); 01896 ast_copy_string(r->peermd5secret, peer->md5secret, sizeof(r->peermd5secret)); 01897 ast_copy_string(r->tohost, peer->tohost, sizeof(r->tohost)); 01898 ast_copy_string(r->fullcontact, peer->fullcontact, sizeof(r->fullcontact)); 01899 if (!r->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 01900 if ((callhost = strchr(r->callid, '@'))) { 01901 strncpy(callhost + 1, peer->fromdomain, sizeof(r->callid) - (callhost - r->callid) - 2); 01902 } 01903 } 01904 if (ast_strlen_zero(r->tohost)) { 01905 if (peer->addr.sin_addr.s_addr) 01906 ast_inet_ntoa(r->tohost, sizeof(r->tohost), peer->addr.sin_addr); 01907 else 01908 ast_inet_ntoa(r->tohost, sizeof(r->tohost), peer->defaddr.sin_addr); 01909 } 01910 if (!ast_strlen_zero(peer->fromdomain)) 01911 ast_copy_string(r->fromdomain, peer->fromdomain, sizeof(r->fromdomain)); 01912 if (!ast_strlen_zero(peer->fromuser)) 01913 ast_copy_string(r->fromuser, peer->fromuser, sizeof(r->fromuser)); 01914 r->maxtime = peer->maxms; 01915 r->callgroup = peer->callgroup; 01916 r->pickupgroup = peer->pickupgroup; 01917 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 01918 if (peer->maxms && peer->lastms) 01919 r->timer_t1 = peer->lastms; 01920 if ((ast_test_flag(r, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(r, SIP_DTMF) == SIP_DTMF_AUTO)) 01921 r->noncodeccapability |= AST_RTP_DTMF; 01922 else 01923 r->noncodeccapability &= ~AST_RTP_DTMF; 01924 ast_copy_string(r->context, peer->context,sizeof(r->context)); 01925 r->rtptimeout = peer->rtptimeout; 01926 r->rtpholdtimeout = peer->rtpholdtimeout; 01927 r->rtpkeepalive = peer->rtpkeepalive; 01928 if (peer->call_limit) 01929 ast_set_flag(r, SIP_CALL_LIMIT); 01930 01931 return 0; 01932 }
|
|
Provides a description of the module.
Definition at line 13581 of file chan_sip.c. References desc. 13582 { 13583 return (char *) desc; 13584 }
|
|
Definition at line 5765 of file chan_sip.c. References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_peer::flags_page2, global_flags_page2, SIP_PAGE2_IGNOREREGEXPIRE, and SIP_PAGE2_RT_FROMCONTACT. Referenced by build_peer(), expire_register(), and parse_register_contact(). 05766 { 05767 if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE)) { 05768 if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) { 05769 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", NULL); 05770 } else { 05771 ast_db_del("SIP/Registry", peer->name); 05772 } 05773 } 05774 }
|
|
determine_firstline_parts: parse first line of incoming SIP request
Definition at line 4678 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(). 04679 { 04680 char *e, *cmd; 04681 int len; 04682 04683 cmd = ast_skip_blanks(req->header[0]); 04684 if (!*cmd) 04685 return -1; 04686 req->rlPart1 = cmd; 04687 e = ast_skip_nonblanks(cmd); 04688 /* Get the command */ 04689 if (*e) 04690 *e++ = '\0'; 04691 e = ast_skip_blanks(e); 04692 if ( !*e ) 04693 return -1; 04694 04695 if ( !strcasecmp(cmd, "SIP/2.0") ) { 04696 /* We have a response */ 04697 req->rlPart2 = e; 04698 len = strlen( req->rlPart2 ); 04699 if ( len < 2 ) { 04700 return -1; 04701 } 04702 ast_trim_blanks(e); 04703 } else { 04704 /* We have a request */ 04705 if ( *e == '<' ) { 04706 e++; 04707 if ( !*e ) { 04708 return -1; 04709 } 04710 } 04711 req->rlPart2 = e; /* URI */ 04712 if ( ( e= strrchr( req->rlPart2, 'S' ) ) == NULL ) { 04713 return -1; 04714 } 04715 /* XXX maybe trim_blanks() ? */ 04716 while( isspace( *(--e) ) ) {} 04717 if ( *e == '>' ) { 04718 *e = '\0'; 04719 } else { 04720 *(++e)= '\0'; 04721 } 04722 } 04723 return 1; 04724 }
|
|
do_monitor: The SIP monitoring thread ---
Definition at line 11478 of file chan_sip.c. References __sip_destroy(), ast_channel::_state, ast_io_add(), ast_io_change(), 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_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, global_mwitime, iflist, io, 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_do_reload(), SIP_NEEDDESTROY, sip_reloading, sipsock, sipsock_read(), sipsock_read_id, t, and VERBOSE_PREFIX_1. 11479 { 11480 int res; 11481 struct sip_pvt *sip; 11482 struct sip_peer *peer = NULL; 11483 time_t t; 11484 int fastrestart =0; 11485 int lastpeernum = -1; 11486 int curpeernum; 11487 int reloading; 11488 11489 /* Add an I/O event to our UDP socket */ 11490 if (sipsock > -1) 11491 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 11492 11493 /* This thread monitors all the frame relay interfaces which are not yet in use 11494 (and thus do not have a separate thread) indefinitely */ 11495 /* From here on out, we die whenever asked */ 11496 for(;;) { 11497 /* Check for a reload request */ 11498 ast_mutex_lock(&sip_reload_lock); 11499 reloading = sip_reloading; 11500 sip_reloading = 0; 11501 ast_mutex_unlock(&sip_reload_lock); 11502 if (reloading) { 11503 if (option_verbose > 0) 11504 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 11505 sip_do_reload(); 11506 11507 /* Change the I/O fd of our UDP socket */ 11508 if (sipsock > -1) 11509 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 11510 } 11511 /* Check for interfaces needing to be killed */ 11512 ast_mutex_lock(&iflock); 11513 restartsearch: 11514 time(&t); 11515 sip = iflist; 11516 /* don't scan the interface list if it hasn't been a reasonable period 11517 of time since the last time we did it (when MWI is being sent, we can 11518 get back to this point every millisecond or less) 11519 */ 11520 while(!fastrestart && sip) { 11521 ast_mutex_lock(&sip->lock); 11522 if (sip->rtp && sip->owner && (sip->owner->_state == AST_STATE_UP) && !sip->redirip.sin_addr.s_addr) { 11523 if (sip->lastrtptx && sip->rtpkeepalive && t > sip->lastrtptx + sip->rtpkeepalive) { 11524 /* Need to send an empty RTP packet */ 11525 time(&sip->lastrtptx); 11526 ast_rtp_sendcng(sip->rtp, 0); 11527 } 11528 if (sip->lastrtprx && (sip->rtptimeout || sip->rtpholdtimeout) && t > sip->lastrtprx + sip->rtptimeout) { 11529 /* Might be a timeout now -- see if we're on hold */ 11530 struct sockaddr_in sin; 11531 ast_rtp_get_peer(sip->rtp, &sin); 11532 if (sin.sin_addr.s_addr || 11533 (sip->rtpholdtimeout && 11534 (t > sip->lastrtprx + sip->rtpholdtimeout))) { 11535 /* Needs a hangup */ 11536 if (sip->rtptimeout) { 11537 while(sip->owner && ast_mutex_trylock(&sip->owner->lock)) { 11538 ast_mutex_unlock(&sip->lock); 11539 usleep(1); 11540 ast_mutex_lock(&sip->lock); 11541 } 11542 if (sip->owner) { 11543 ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", sip->owner->name, (long)(t - sip->lastrtprx)); 11544 /* Issue a softhangup */ 11545 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 11546 ast_mutex_unlock(&sip->owner->lock); 11547 /* forget the timeouts for this call, since a hangup 11548 has already been requested and we don't want to 11549 repeatedly request hangups 11550 */ 11551 sip->rtptimeout = 0; 11552 sip->rtpholdtimeout = 0; 11553 } 11554 } 11555 } 11556 } 11557 } 11558 if (ast_test_flag(sip, SIP_NEEDDESTROY) && !sip->packets && !sip->owner) { 11559 ast_mutex_unlock(&sip->lock); 11560 __sip_destroy(sip, 1); 11561 goto restartsearch; 11562 } 11563 ast_mutex_unlock(&sip->lock); 11564 sip = sip->next; 11565 } 11566 ast_mutex_unlock(&iflock); 11567 /* Don't let anybody kill us right away. Nobody should lock the interface list 11568 and wait for the monitor list, but the other way around is okay. */ 11569 ast_mutex_lock(&monlock); 11570 /* Lock the network interface */ 11571 ast_mutex_lock(&netlock); 11572 /* Okay, now that we know what to do, release the network lock */ 11573 ast_mutex_unlock(&netlock); 11574 /* And from now on, we're okay to be killed, so release the monitor lock as well */ 11575 ast_mutex_unlock(&monlock); 11576 pthread_testcancel(); 11577 /* Wait for sched or io */ 11578 res = ast_sched_wait(sched); 11579 if ((res < 0) || (res > 1000)) 11580 res = 1000; 11581 /* If we might need to send more mailboxes, don't wait long at all.*/ 11582 if (fastrestart) 11583 res = 1; 11584 res = ast_io_wait(io, res); 11585 if (res > 20) 11586 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 11587 ast_mutex_lock(&monlock); 11588 if (res >= 0) { 11589 res = ast_sched_runq(sched); 11590 if (res >= 20) 11591 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 11592 } 11593 11594 /* needs work to send mwi to realtime peers */ 11595 time(&t); 11596 fastrestart = 0; 11597 curpeernum = 0; 11598 peer = NULL; 11599 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 11600 if ((curpeernum > lastpeernum) && !ast_strlen_zero(iterator->mailbox) && ((t - iterator->lastmsgcheck) > global_mwitime)) { 11601 fastrestart = 1; 11602 lastpeernum = curpeernum; 11603 peer = ASTOBJ_REF(iterator); 11604 }; 11605 curpeernum++; 11606 } while (0) 11607 ); 11608 if (peer) { 11609 ASTOBJ_WRLOCK(peer); 11610 sip_send_mwi_to_peer(peer); 11611 ASTOBJ_UNLOCK(peer); 11612 ASTOBJ_UNREF(peer,sip_destroy_peer); 11613 } else { 11614 /* Reset where we come from */ 11615 lastpeernum = -1; 11616 } 11617 ast_mutex_unlock(&monlock); 11618 } 11619 /* Never reached */ 11620 return NULL; 11621 11622 }
|
|
do_proxy_auth: Add authentication on outbound SIP packet ---
Definition at line 9067 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(). 09068 { 09069 char digest[1024]; 09070 09071 if (!p->options) { 09072 p->options = calloc(1, sizeof(*p->options)); 09073 if (!p->options) { 09074 ast_log(LOG_ERROR, "Out of memory\n"); 09075 return -2; 09076 } 09077 } 09078 09079 p->authtries++; 09080 if (option_debug > 1) 09081 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 09082 memset(digest, 0, sizeof(digest)); 09083 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 09084 /* No way to authenticate */ 09085 return -1; 09086 } 09087 /* Now we have a reply digest */ 09088 p->options->auth = digest; 09089 p->options->authheader = respheader; 09090 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 09091 }
|
|
do_register_auth: Authenticate for outbound registration ---
Definition at line 9043 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(). 09044 { 09045 char digest[1024]; 09046 p->authtries++; 09047 memset(digest,0,sizeof(digest)); 09048 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 09049 /* There's nothing to use for authentication */ 09050 /* No digest challenge in request */ 09051 if (sip_debug_test_pvt(p) && p->registry) 09052 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 09053 /* No old challenge */ 09054 return -1; 09055 } 09056 if (recordhistory) { 09057 char tmp[80]; 09058 snprintf(tmp, sizeof(tmp), "Try: %d", p->authtries); 09059 append_history(p, "RegistryAuth", tmp); 09060 } 09061 if (sip_debug_test_pvt(p) && p->registry) 09062 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 09063 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 09064 }
|
|
Definition at line 7986 of file chan_sip.c. References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG. Referenced by sip_show_domains(). 07987 { 07988 switch (mode) { 07989 case SIP_DOMAIN_AUTO: 07990 return "[Automatic]"; 07991 case SIP_DOMAIN_CONFIG: 07992 return "[Configured]"; 07993 } 07994 07995 return ""; 07996 }
|
|
dtmfmode2str: Convert DTMF mode to printable string ---
Definition at line 7794 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(). 07795 { 07796 switch (mode) { 07797 case SIP_DTMF_RFC2833: 07798 return "rfc2833"; 07799 case SIP_DTMF_INFO: 07800 return "info"; 07801 case SIP_DTMF_INBAND: 07802 return "inband"; 07803 case SIP_DTMF_AUTO: 07804 return "auto"; 07805 } 07806 return "<error>"; 07807 }
|
|
expire_register: Expire registration of SIP peer ---
Definition at line 5777 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(). 05778 { 05779 struct sip_peer *peer = data; 05780 05781 if (!peer) /* Hmmm. We have no peer. Weird. */ 05782 return 0; 05783 05784 memset(&peer->addr, 0, sizeof(peer->addr)); 05785 05786 destroy_association(peer); 05787 05788 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 05789 register_peer_exten(peer, 0); /* Remove regexten */ 05790 peer->expire = -1; 05791 ast_device_state_changed("SIP/%s", peer->name); 05792 05793 /* Do we need to release this peer from memory? 05794 Only for realtime peers and autocreated peers 05795 */ 05796 if (ast_test_flag(peer, SIP_SELFDESTRUCT) || ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTAUTOCLEAR)) { 05797 peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); /* Remove from peer list */ 05798 ASTOBJ_UNREF(peer, sip_destroy_peer); 05799 } 05800 05801 return 0; 05802 }
|
|
extract_uri: Check Contact: URI of SIP message ---
Definition at line 4756 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(). 04757 { 04758 char stripped[256]; 04759 char *c, *n; 04760 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 04761 c = get_in_brackets(stripped); 04762 n = strchr(c, ';'); 04763 if (n) 04764 *n = '\0'; 04765 if (!ast_strlen_zero(c)) 04766 ast_copy_string(p->uri, c, sizeof(p->uri)); 04767 }
|
|
Definition at line 2942 of file chan_sip.c. References aliases. 02943 { 02944 int x; 02945 for (x=0;x<sizeof(aliases) / sizeof(aliases[0]); x++) 02946 if (!strcasecmp(aliases[x].fullname, name)) 02947 return aliases[x].shortname; 02948 return _default; 02949 }
|
|
find_call: Connect incoming SIP message to current dialog or create new dialog structure
Definition at line 3174 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, sip_pvt::theirtag, and transmit_response_using_temp(). Referenced by sipsock_read(). 03175 { 03176 struct sip_pvt *p = NULL; 03177 char *callid; 03178 char *tag = ""; 03179 char totag[128]; 03180 char fromtag[128]; 03181 03182 callid = get_header(req, "Call-ID"); 03183 03184 if (pedanticsipchecking) { 03185 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 03186 we need more to identify a branch - so we have to check branch, from 03187 and to tags to identify a call leg. 03188 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 03189 in sip.conf 03190 */ 03191 if (gettag(req, "To", totag, sizeof(totag))) 03192 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 03193 gettag(req, "From", fromtag, sizeof(fromtag)); 03194 03195 if (req->method == SIP_RESPONSE) 03196 tag = totag; 03197 else 03198 tag = fromtag; 03199 03200 03201 if (option_debug > 4 ) 03202 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); 03203 } 03204 03205 ast_mutex_lock(&iflock); 03206 p = iflist; 03207 while(p) { /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 03208 int found = 0; 03209 if (req->method == SIP_REGISTER) 03210 found = (!strcmp(p->callid, callid)); 03211 else 03212 found = (!strcmp(p->callid, callid) && 03213 (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ; 03214 03215 if (option_debug > 4) 03216 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); 03217 03218 /* If we get a new request within an existing to-tag - check the to tag as well */ 03219 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 03220 if (p->tag[0] == '\0' && totag[0]) { 03221 /* We have no to tag, but they have. Wrong dialog */ 03222 found = 0; 03223 } else if (totag[0]) { /* Both have tags, compare them */ 03224 if (strcmp(totag, p->tag)) { 03225 found = 0; /* This is not our packet */ 03226 } 03227 } 03228 if (!found && option_debug > 4) 03229 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); 03230 } 03231 03232 03233 if (found) { 03234 /* Found the call */ 03235 ast_mutex_lock(&p->lock); 03236 ast_mutex_unlock(&iflock); 03237 return p; 03238 } 03239 p = p->next; 03240 } 03241 ast_mutex_unlock(&iflock); 03242 03243 /* If this is a response and we have ignoring of out of dialog responses turned on, then drop it */ 03244 if (!sip_methods[intended_method].can_create) { 03245 if (intended_method != SIP_RESPONSE) 03246 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 03247 } else { 03248 p = sip_alloc(callid, sin, 1, intended_method); 03249 if (p) 03250 ast_mutex_lock(&p->lock); 03251 } 03252 03253 return p; 03254 }
|
|
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 1768 of file chan_sip.c. References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp(). 01769 { 01770 struct sip_peer *p = NULL; 01771 01772 if (peer) 01773 p = ASTOBJ_CONTAINER_FIND(&peerl,peer); 01774 else 01775 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl,sin,name,sip_addr_hashfunc,1,sip_addrcmp); 01776 01777 if (!p && realtime) { 01778 p = realtime_peer(peer, sin); 01779 } 01780 01781 return p; 01782 }
|
|
find_realm_authentication: Find authentication for a specific realm ---
Definition at line 12146 of file chan_sip.c. References sip_auth::next, and sip_auth::realm. Referenced by build_reply_digest(). 12147 { 12148 struct sip_auth *a = authlist; /* First entry in auth list */ 12149 12150 while (a) { 12151 if (!strcasecmp(a->realm, realm)){ 12152 break; 12153 } 12154 a = a->next; 12155 } 12156 12157 return a; 12158 }
|
|
Determine whether a SIP message contains an SDP in its body.
Definition at line 3454 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(). 03455 { 03456 char *content_type; 03457 char *search; 03458 char *boundary; 03459 unsigned int x; 03460 03461 content_type = get_header(req, "Content-Type"); 03462 03463 /* if the body contains only SDP, this is easy */ 03464 if (!strcasecmp(content_type, "application/sdp")) { 03465 req->sdp_start = 0; 03466 req->sdp_end = req->lines; 03467 return 1; 03468 } 03469 03470 /* if it's not multipart/mixed, there cannot be an SDP */ 03471 if (strncasecmp(content_type, "multipart/mixed", 15)) 03472 return 0; 03473 03474 /* if there is no boundary marker, it's invalid */ 03475 if (!(search = strcasestr(content_type, ";boundary="))) 03476 return 0; 03477 03478 search += 10; 03479 03480 if (ast_strlen_zero(search)) 03481 return 0; 03482 03483 /* make a duplicate of the string, with two extra characters 03484 at the beginning */ 03485 boundary = ast_strdupa(search - 2); 03486 boundary[0] = boundary[1] = '-'; 03487 03488 /* search for the boundary marker, but stop when there are not enough 03489 lines left for it, the Content-Type header and at least one line of 03490 body */ 03491 for (x = 0; x < (req->lines - 2); x++) { 03492 if (!strncasecmp(req->line[x], boundary, strlen(boundary)) && 03493 !strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) { 03494 req->sdp_start = x + 2; 03495 /* search for the end of the body part */ 03496 for ( ; x < req->lines; x++) { 03497 if (!strncasecmp(req->line[x], boundary, strlen(boundary))) 03498 break; 03499 } 03500 req->sdp_end = x; 03501 return 1; 03502 } 03503 } 03504 03505 return 0; 03506 }
|
|
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 988 of file chan_sip.c. References ast_strlen_zero(), sip_methods, and text. Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read(). 00989 { 00990 int i, res = 0; 00991 00992 if (ast_strlen_zero(msg)) 00993 return 0; 00994 00995 for (i = 1; (i < (sizeof(sip_methods) / sizeof(sip_methods[0]))) && !res; i++) { 00996 if (!strcasecmp(sip_methods[i].text, msg)) 00997 res = sip_methods[i].id; 00998 } 00999 return res; 01000 }
|
|
find_subscription_type: Find subscription type in array
Definition at line 8430 of file chan_sip.c. References subscription_types, and type. Referenced by transmit_state_notify(). 08430 { 08431 int i; 08432 08433 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 08434 if (subscription_types[i].type == subtype) { 08435 return &subscription_types[i]; 08436 } 08437 } 08438 return &subscription_types[0]; 08439 }
|
|
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 1850 of file chan_sip.c. References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl. 01851 { 01852 struct sip_user *u = NULL; 01853 u = ASTOBJ_CONTAINER_FIND(&userl,name); 01854 if (!u && realtime) { 01855 u = realtime_user(name); 01856 } 01857 return u; 01858 }
|
|
free_old_route: Remove route from route list ---
Definition at line 6104 of file chan_sip.c. References free, and sip_route::next. Referenced by __sip_destroy(), and build_route(). 06105 { 06106 struct sip_route *next; 06107 while (route) { 06108 next = route->next; 06109 free(route); 06110 route = next; 06111 } 06112 }
|
|
function_check_sipdomain: Dial plan function to check if domain is local
Definition at line 9384 of file chan_sip.c. References ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING. 09385 { 09386 if (ast_strlen_zero(data)) { 09387 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 09388 return buf; 09389 } 09390 if (check_sip_domain(data, NULL, 0)) 09391 ast_copy_string(buf, data, len); 09392 else 09393 buf[0] = '\0'; 09394 return buf; 09395 }
|
|
func_header_read: Read SIP header (dialplan function)
Definition at line 9337 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. 09338 { 09339 struct sip_pvt *p; 09340 char *content; 09341 09342 if (!data) { 09343 ast_log(LOG_WARNING, "This function requires a header name.\n"); 09344 return NULL; 09345 } 09346 09347 ast_mutex_lock(&chan->lock); 09348 if (chan->type != channeltype) { 09349 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 09350 ast_mutex_unlock(&chan->lock); 09351 return NULL; 09352 } 09353 09354 p = chan->tech_pvt; 09355 09356 /* If there is no private structure, this channel is no longer alive */ 09357 if (!p) { 09358 ast_mutex_unlock(&chan->lock); 09359 return NULL; 09360 } 09361 09362 content = get_header(&p->initreq, data); 09363 09364 if (ast_strlen_zero(content)) { 09365 ast_mutex_unlock(&chan->lock); 09366 return NULL; 09367 } 09368 09369 ast_copy_string(buf, content, len); 09370 ast_mutex_unlock(&chan->lock); 09371 09372 return buf; 09373 }
|
|
function_sipchaninfo_read: ${SIPCHANINFO()} Dialplan function - reads sip channel data
Definition at line 9511 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. 09512 { 09513 struct sip_pvt *p; 09514 char iabuf[INET_ADDRSTRLEN]; 09515 09516 *buf = 0; 09517 09518 if (!data) { 09519 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 09520 return NULL; 09521 } 09522 09523 ast_mutex_lock(&chan->lock); 09524 if (chan->type != channeltype) { 09525 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 09526 ast_mutex_unlock(&chan->lock); 09527 return NULL; 09528 } 09529 09530 /* ast_verbose("function_sipchaninfo_read: %s\n", data); */ 09531 p = chan->tech_pvt; 09532 09533 /* If there is no private structure, this channel is no longer alive */ 09534 if (!p) { 09535 ast_mutex_unlock(&chan->lock); 09536 return NULL; 09537 } 09538 09539 if (!strcasecmp(data, "peerip")) { 09540 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr) : "", len); 09541 } else if (!strcasecmp(data, "recvip")) { 09542 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr) : "", len); 09543 } else if (!strcasecmp(data, "from")) { 09544 ast_copy_string(buf, p->from, len); 09545 } else if (!strcasecmp(data, "uri")) { 09546 ast_copy_string(buf, p->uri, len); 09547 } else if (!strcasecmp(data, "useragent")) { 09548 ast_copy_string(buf, p->useragent, len); 09549 } else if (!strcasecmp(data, "peername")) { 09550 ast_copy_string(buf, p->peername, len); 09551 } else { 09552 ast_mutex_unlock(&chan->lock); 09553 return NULL; 09554 } 09555 ast_mutex_unlock(&chan->lock); 09556 09557 return buf; 09558 }
|
|
function_sippeer: ${SIPPEER()} Dialplan function - reads peer data
Definition at line 9410 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. 09411 { 09412 char *ret = NULL; 09413 struct sip_peer *peer; 09414 char *peername, *colname; 09415 char iabuf[INET_ADDRSTRLEN]; 09416 09417 if (!(peername = ast_strdupa(data))) { 09418 ast_log(LOG_ERROR, "Memory Error!\n"); 09419 return ret; 09420 } 09421 09422 if ((colname = strchr(peername, ':'))) { 09423 *colname = '\0'; 09424 colname++; 09425 } else { 09426 colname = "ip"; 09427 } 09428 if (!(peer = find_peer(peername, NULL, 1))) 09429 return ret; 09430 09431 if (!strcasecmp(colname, "ip")) { 09432 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len); 09433 } else if (!strcasecmp(colname, "status")) { 09434 peer_status(peer, buf, len); 09435 } else if (!strcasecmp(colname, "language")) { 09436 ast_copy_string(buf, peer->language, len); 09437 } else if (!strcasecmp(colname, "regexten")) { 09438 ast_copy_string(buf, peer->regexten, len); 09439 } else if (!strcasecmp(colname, "limit")) { 09440 snprintf(buf, len, "%d", peer->call_limit); 09441 } else if (!strcasecmp(colname, "curcalls")) { 09442 snprintf(buf, len, "%d", peer->inUse); 09443 } else if (!strcasecmp(colname, "accountcode")) { 09444 ast_copy_string(buf, peer->accountcode, len); 09445 } else if (!strcasecmp(colname, "useragent")) { 09446 ast_copy_string(buf, peer->useragent, len); 09447 } else if (!strcasecmp(colname, "mailbox")) { 09448 ast_copy_string(buf, peer->mailbox, len); 09449 } else if (!strcasecmp(colname, "context")) { 09450 ast_copy_string(buf, peer->context, len); 09451 } else if (!strcasecmp(colname, "expire")) { 09452 snprintf(buf, len, "%d", peer->expire); 09453 } else if (!strcasecmp(colname, "dynamic")) { 09454 ast_copy_string(buf, (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 09455 } else if (!strcasecmp(colname, "callerid_name")) { 09456 ast_copy_string(buf, peer->cid_name, len); 09457 } else if (!strcasecmp(colname, "callerid_num")) { 09458 ast_copy_string(buf, peer->cid_num, len); 09459 } else if (!strcasecmp(colname, "codecs")) { 09460 ast_getformatname_multiple(buf, len -1, peer->capability); 09461 } else if (!strncasecmp(colname, "codec[", 6)) { 09462 char *codecnum, *ptr; 09463 int index = 0, codec = 0; 09464 09465 codecnum = strchr(colname, '['); 09466 *codecnum = '\0'; 09467 codecnum++; 09468 if ((ptr = strchr(codecnum, ']'))) { 09469 *ptr = '\0'; 09470 } 09471 index = atoi(codecnum); 09472 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 09473 ast_copy_string(buf, ast_getformatname(codec), len); 09474 } 09475 } 09476 ret = buf; 09477 09478 ASTOBJ_UNREF(peer, sip_destroy_peer); 09479 09480 return ret; 09481 }
|
|
get_also_info: Call transfer support (old way, depreciated)--
Definition at line 6962 of file chan_sip.c. References ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_verbose(), sip_pvt::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, sip_pvt::refer_call, sip_pvt::refer_contact, sip_pvt::refer_to, sip_pvt::referred_by, and sip_debug_test_pvt(). Referenced by handle_request_bye(). 06963 { 06964 char tmp[256], *c, *a; 06965 struct sip_request *req; 06966 06967 req = oreq; 06968 if (!req) 06969 req = &p->initreq; 06970 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 06971 06972 c = get_in_brackets(tmp); 06973 06974 06975 if (strncmp(c, "sip:", 4)) { 06976 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 06977 return -1; 06978 } 06979 c += 4; 06980 if ((a = strchr(c, '@'))) 06981 *a = '\0'; 06982 if ((a = strchr(c, ';'))) 06983 *a = '\0'; 06984 06985 if (sip_debug_test_pvt(p)) { 06986 ast_verbose("Looking for %s in %s\n", c, p->context); 06987 } 06988 if (ast_exists_extension(NULL, p->context, c, 1, NULL)) { 06989 /* This is an unsupervised transfer */ 06990 ast_log(LOG_DEBUG,"Assigning Extension %s to REFER-TO\n", c); 06991 ast_copy_string(p->refer_to, c, sizeof(p->refer_to)); 06992 ast_copy_string(p->referred_by, "", sizeof(p->referred_by)); 06993 ast_copy_string(p->refer_contact, "", sizeof(p->refer_contact)); 06994 p->refer_call = NULL; 06995 return 0; 06996 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 06997 return 1; 06998 } 06999 07000 return -1; 07001 }
|
|
get_body: get a specific line from the message body
Definition at line 2928 of file chan_sip.c. References get_body_by_line(), sip_request::line, and sip_request::lines. Referenced by handle_request_info(). 02929 { 02930 int x; 02931 int len = strlen(name); 02932 char *r; 02933 02934 for (x = 0; x < req->lines; x++) { 02935 r = get_body_by_line(req->line[x], name, len); 02936 if (r[0] != '\0') 02937 return r; 02938 } 02939 return ""; 02940 }
|
|
get_body_by_line: Reads one line of message body
Definition at line 2885 of file chan_sip.c. Referenced by get_body(), get_sdp(), and get_sdp_iterate(). 02886 { 02887 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') { 02888 return ast_skip_blanks(line + nameLen + 1); 02889 } 02890 return ""; 02891 }
|
|
get_calleridname: Get caller id name from SIP headers ---
Definition at line 7053 of file chan_sip.c. Referenced by check_user_full(). 07054 { 07055 char *end = strchr(input,'<'); 07056 char *tmp = strchr(input,'\"'); 07057 int bytes = 0; 07058 int maxbytes = outputsize - 1; 07059 07060 if (!end || (end == input)) return NULL; 07061 /* move away from "<" */ 07062 end--; 07063 /* we found "name" */ 07064 if (tmp && tmp < end) { 07065 end = strchr(tmp+1, '\"'); 07066 if (!end) return NULL; 07067 bytes = (int) (end - tmp); 07068 /* protect the output buffer */ 07069 if (bytes > maxbytes) 07070 bytes = maxbytes; 07071 ast_copy_string(output, tmp + 1, bytes); 07072 } else { 07073 /* we didn't find "name" */ 07074 /* clear the empty characters in the begining*/ 07075 input = ast_skip_blanks(input); 07076 /* clear the empty characters in the end */ 07077 while(*end && (*end < 33) && end > input) 07078 end--; 07079 if (end >= input) { 07080 bytes = (int) (end - input) + 2; 07081 /* protect the output buffer */ 07082 if (bytes > maxbytes) { 07083 bytes = maxbytes; 07084 } 07085 ast_copy_string(output, input, bytes); 07086 } 07087 else 07088 return NULL; 07089 } 07090 return output; 07091 }
|
|
get_destination: Find out who the call is for --
Definition at line 6688 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, SIP_REFER, and user. Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe(). 06689 { 06690 char tmp[256] = "", *uri, *a, *user, *domain, *opts; 06691 char tmpf[256], *from; 06692 struct sip_request *req; 06693 char *colon; 06694 06695 req = oreq; 06696 if (!req) 06697 req = &p->initreq; 06698 if (req->rlPart2) 06699 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 06700 uri = get_in_brackets(tmp); 06701 06702 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 06703 06704 from = get_in_brackets(tmpf); 06705 06706 if (strncmp(uri, "sip:", 4)) { 06707 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 06708 return -1; 06709 } 06710 uri += 4; 06711 if (!ast_strlen_zero(from)) { 06712 if (strncmp(from, "sip:", 4)) { 06713 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 06714 return -1; 06715 } 06716 from += 4; 06717 } else 06718 from = NULL; 06719 06720 if (pedanticsipchecking) { 06721 ast_uri_decode(uri); 06722 ast_uri_decode(from); 06723 } 06724 06725 /* Get the target domain first and user */ 06726 if ((domain = strchr(uri, '@'))) { 06727 *domain++ = '\0'; 06728 user = uri; 06729 } else { 06730 /* No user portion present */ 06731 domain = uri; 06732 user = "s"; 06733 } 06734 06735 /* Strip port from domain if present */ 06736 if ((colon = strchr(domain, ':'))) { 06737 *colon = '\0'; 06738 } 06739 06740 /* Strip any params or options from user */ 06741 if ((opts = strchr(user, ';'))) { 06742 *opts = '\0'; 06743 } 06744 06745 ast_copy_string(p->domain, domain, sizeof(p->domain)); 06746 06747 if (!AST_LIST_EMPTY(&domain_list)) { 06748 char domain_context[AST_MAX_EXTENSION]; 06749 06750 domain_context[0] = '\0'; 06751 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 06752 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 06753 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 06754 return -2; 06755 } 06756 } 06757 /* If we have a context defined, overwrite the original context */ 06758 if (!ast_strlen_zero(domain_context)) 06759 ast_copy_string(p->context, domain_context, sizeof(p->context)); 06760 } 06761 06762 if (from) { 06763 if ((a = strchr(from, ';'))) 06764 *a = '\0'; 06765 if ((a = strchr(from, '@'))) { 06766 *a = '\0'; 06767 ast_copy_string(p->fromdomain, a + 1, sizeof(p->fromdomain)); 06768 } else 06769 ast_copy_string(p->fromdomain, from, sizeof(p->fromdomain)); 06770 } 06771 if (sip_debug_test_pvt(p)) 06772 ast_verbose("Looking for %s in %s (domain %s)\n", user, p->context, p->domain); 06773 06774 /* Return 0 if we have a matching extension */ 06775 if (ast_exists_extension(NULL, p->context, user, 1, from) || 06776 !strcmp(uri, ast_pickup_ext())) { 06777 if (!oreq) 06778 ast_copy_string(p->exten, user, sizeof(p->exten)); 06779 return 0; 06780 } 06781 06782 /* Return 1 for overlap dialling support */ 06783 if (ast_canmatch_extension(NULL, p->context, user, 1, from) || 06784 !strncmp(user, ast_pickup_ext(),strlen(user))) { 06785 return 1; 06786 } 06787 06788 return -1; 06789 }
|
|
get_header: Get header from SIP request ---
Definition at line 2987 of file chan_sip.c. References __get_header(). 02988 { 02989 int start = 0; 02990 return __get_header(req, name, &start); 02991 }
|
|
get_in_brackets: Pick out text in brackets from character string ---
Definition at line 1550 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(). 01551 { 01552 char *parse; 01553 char *first_quote; 01554 char *first_bracket; 01555 char *second_bracket; 01556 char last_char; 01557 01558 parse = tmp; 01559 while (1) { 01560 first_quote = strchr(parse, '"'); 01561 first_bracket = strchr(parse, '<'); 01562 if (first_quote && first_bracket && (first_quote < first_bracket)) { 01563 last_char = '\0'; 01564 for (parse = first_quote + 1; *parse; parse++) { 01565 if ((*parse == '"') && (last_char != '\\')) 01566 break; 01567 last_char = *parse; 01568 } 01569 if (!*parse) { 01570 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 01571 return tmp; 01572 } 01573 parse++; 01574 continue; 01575 } 01576 if (first_bracket) { 01577 second_bracket = strchr(first_bracket + 1, '>'); 01578 if (second_bracket) { 01579 *second_bracket = '\0'; 01580 return first_bracket + 1; 01581 } else { 01582 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 01583 return tmp; 01584 } 01585 } 01586 return tmp; 01587 } 01588 }
|
|
get_msg_text: Get text out of a SIP MESSAGE packet ---
Definition at line 7402 of file chan_sip.c. References sip_request::line, and sip_request::lines. Referenced by receive_message(). 07403 { 07404 int x; 07405 int y; 07406 07407 buf[0] = '\0'; 07408 y = len - strlen(buf) - 5; 07409 if (y < 0) 07410 y = 0; 07411 for (x=0;x<req->lines;x++) { 07412 strncat(buf, req->line[x], y); /* safe */ 07413 y -= strlen(req->line[x]) + 1; 07414 if (y < 0) 07415 y = 0; 07416 if (y != 0) 07417 strcat(buf, "\n"); /* safe */ 07418 } 07419 return 0; 07420 }
|
|
get_rdnis: get referring dnis ---
Definition at line 6660 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(). 06661 { 06662 char tmp[256], *c, *a; 06663 struct sip_request *req; 06664 06665 req = oreq; 06666 if (!req) 06667 req = &p->initreq; 06668 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 06669 if (ast_strlen_zero(tmp)) 06670 return 0; 06671 c = get_in_brackets(tmp); 06672 if (strncmp(c, "sip:", 4)) { 06673 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 06674 return -1; 06675 } 06676 c += 4; 06677 if ((a = strchr(c, '@')) || (a = strchr(c, ';'))) { 06678 *a = '\0'; 06679 } 06680 if (sip_debug_test_pvt(p)) 06681 ast_verbose("RDNIS is %s\n", c); 06682 ast_copy_string(p->rdnis, c, sizeof(p->rdnis)); 06683 06684 return 0; 06685 }
|
|
get_refer_info: Call transfer support (the REFER method) ---
Definition at line 6821 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::callid, 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_call, sip_pvt::refer_contact, sip_pvt::refer_to, sip_pvt::referred_by, and sip_debug_test_pvt(). Referenced by handle_request_refer(). 06822 { 06823 06824 char *p_refer_to = NULL, *p_referred_by = NULL, *h_refer_to = NULL, *h_referred_by = NULL, *h_contact = NULL; 06825 char *replace_callid = "", *refer_to = NULL, *referred_by = NULL, *ptr = NULL; 06826 struct sip_request *req = NULL; 06827 struct sip_pvt *sip_pvt_ptr = NULL; 06828 struct ast_channel *chan = NULL, *peer = NULL; 06829 06830 req = outgoing_req; 06831 06832 if (!req) { 06833 req = &sip_pvt->initreq; 06834 } 06835 06836 if (!( (p_refer_to = get_header(req, "Refer-To")) && (h_refer_to = ast_strdupa(p_refer_to)) )) { 06837 ast_log(LOG_WARNING, "No Refer-To Header That's illegal\n"); 06838 return -1; 06839 } 06840 06841 refer_to = get_in_brackets(h_refer_to); 06842 06843 if (!( (p_referred_by = get_header(req, "Referred-By")) && (h_referred_by = ast_strdupa(p_referred_by)) )) { 06844 ast_log(LOG_WARNING, "No Referrred-By Header That's not illegal\n"); 06845 return -1; 06846 } else { 06847 if (pedanticsipchecking) { 06848 ast_uri_decode(h_referred_by); 06849 } 06850 referred_by = get_in_brackets(h_referred_by); 06851 } 06852 h_contact = get_header(req, "Contact"); 06853 06854 if (strncmp(refer_to, "sip:", 4)) { 06855 ast_log(LOG_WARNING, "Refer-to: Huh? Not a SIP header (%s)?\n", refer_to); 06856 return -1; 06857 } 06858 06859 if (strncmp(referred_by, "sip:", 4)) { 06860 ast_log(LOG_WARNING, "Referred-by: Huh? Not a SIP header (%s) Ignoring?\n", referred_by); 06861 referred_by = NULL; 06862 } 06863 06864 if (refer_to) 06865 refer_to += 4; 06866 06867 if (referred_by) 06868 referred_by += 4; 06869 06870 if ((ptr = strchr(refer_to, '?'))) { 06871 /* Search for arguments */ 06872 *ptr = '\0'; 06873 ptr++; 06874 if (!strncasecmp(ptr, "REPLACES=", 9)) { 06875 char *p; 06876 replace_callid = ast_strdupa(ptr + 9); 06877 /* someday soon to support invite/replaces properly! 06878 replaces_header = ast_strdupa(replace_callid); 06879 -anthm 06880 */ 06881 ast_uri_decode(replace_callid); 06882 if ((ptr = strchr(replace_callid, '%'))) 06883 *ptr = '\0'; 06884 if ((ptr = strchr(replace_callid, ';'))) 06885 *ptr = '\0'; 06886 /* Skip leading whitespace XXX memmove behaviour with overlaps ? */ 06887 p = ast_skip_blanks(replace_callid); 06888 if (p != replace_callid) 06889 memmove(replace_callid, p, strlen(p)); 06890 } 06891 } 06892 06893 if ((ptr = strchr(refer_to, '@'))) /* Skip domain (should be saved in SIPDOMAIN) */ 06894 *ptr = '\0'; 06895 if ((ptr = strchr(refer_to, ';'))) 06896 *ptr = '\0'; 06897 06898 if (referred_by) { 06899 if ((ptr = strchr(referred_by, '@'))) 06900 *ptr = '\0'; 06901 if ((ptr = strchr(referred_by, ';'))) 06902 *ptr = '\0'; 06903 } 06904 06905 *transfercontext = pbx_builtin_getvar_helper(sip_pvt->owner, "TRANSFER_CONTEXT"); 06906 if (ast_strlen_zero(*transfercontext)) 06907 *transfercontext = sip_pvt->context; 06908 06909 if (sip_debug_test_pvt(sip_pvt)) { 06910 ast_verbose("Transfer to %s in %s\n", refer_to, *transfercontext); 06911 if (referred_by) 06912 ast_verbose("Transfer from %s in %s\n", referred_by, sip_pvt->context); 06913 } 06914 if (!ast_strlen_zero(replace_callid)) { 06915 /* This is a supervised transfer */ 06916 ast_log(LOG_DEBUG,"Assigning Replace-Call-ID Info %s to REPLACE_CALL_ID\n",replace_callid); 06917 06918 ast_copy_string(sip_pvt->refer_to, "", sizeof(sip_pvt->refer_to)); 06919 ast_copy_string(sip_pvt->referred_by, "", sizeof(sip_pvt->referred_by)); 06920 ast_copy_string(sip_pvt->refer_contact, "", sizeof(sip_pvt->refer_contact)); 06921 sip_pvt->refer_call = NULL; 06922 if ((sip_pvt_ptr = get_sip_pvt_byid_locked(replace_callid))) { 06923 sip_pvt->refer_call = sip_pvt_ptr; 06924 if (sip_pvt->refer_call == sip_pvt) { 06925 ast_log(LOG_NOTICE, "Supervised transfer attempted to transfer into same call id (%s == %s)!\n", replace_callid, sip_pvt->callid); 06926 sip_pvt->refer_call = NULL; 06927 } else 06928 return 0; 06929 } else { 06930 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); 06931 /* XXX The refer_to could contain a call on an entirely different machine, requiring an 06932 INVITE with a replaces header -anthm XXX */ 06933 /* The only way to find out is to use the dialplan - oej */ 06934 } 06935 } else if (ast_exists_extension(NULL, *transfercontext, refer_to, 1, NULL) || !strcmp(refer_to, ast_parking_ext())) { 06936 /* This is an unsupervised transfer (blind transfer) */ 06937 06938 ast_log(LOG_DEBUG,"Unsupervised transfer to (Refer-To): %s\n", refer_to); 06939 if (referred_by) 06940 ast_log(LOG_DEBUG,"Transferred by (Referred-by: ) %s \n", referred_by); 06941 ast_log(LOG_DEBUG,"Transfer Contact Info %s (REFER_CONTACT)\n", h_contact); 06942 ast_copy_string(sip_pvt->refer_to, refer_to, sizeof(sip_pvt->refer_to)); 06943 if (referred_by) 06944 ast_copy_string(sip_pvt->referred_by, referred_by, sizeof(sip_pvt->referred_by)); 06945 if (h_contact) { 06946 ast_copy_string(sip_pvt->refer_contact, h_contact, sizeof(sip_pvt->refer_contact)); 06947 } 06948 sip_pvt->refer_call = NULL; 06949 if ((chan = sip_pvt->owner) && (peer = ast_bridged_channel(sip_pvt->owner))) { 06950 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name); 06951 pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", chan->name); 06952 } 06953 return 0; 06954 } else if (ast_canmatch_extension(NULL, *transfercontext, refer_to, 1, NULL)) { 06955 return 1; 06956 } 06957 06958 return -1; 06959 }
|
|
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 7097 of file chan_sip.c. References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED. Referenced by check_user_full(). 07098 { 07099 char *start; 07100 char *end; 07101 07102 start = strchr(input,':'); 07103 if (!start) { 07104 output[0] = '\0'; 07105 return 0; 07106 } 07107 start++; 07108 07109 /* we found "number" */ 07110 ast_copy_string(output,start,maxlen); 07111 output[maxlen-1] = '\0'; 07112 07113 end = strchr(output,'@'); 07114 if (end) 07115 *end = '\0'; 07116 else 07117 output[0] = '\0'; 07118 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 07119 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 07120 07121 return 0; 07122 }
|
|
get_sdp: get a specific line from the SDP
Definition at line 2894 of file chan_sip.c. References get_body_by_line(), sip_request::line, and sip_request::sdp_start. 02895 { 02896 int x; 02897 int len = strlen(name); 02898 char *r; 02899 02900 for (x = req->sdp_start; x < req->sdp_end; x++) { 02901 r = get_body_by_line(req->line[x], name, len); 02902 if (r[0] != '\0') 02903 return r; 02904 } 02905 return ""; 02906 }
|
|
Definition at line 2913 of file chan_sip.c. References get_body_by_line(), and sip_request::line. 02915 { 02916 int len = strlen(name); 02917 char *r; 02918 02919 while (*iterator < req->sdp_end) { 02920 r = get_body_by_line(req->line[(*iterator)++], name, len); 02921 if (r[0] != '\0') 02922 return r; 02923 } 02924 return ""; 02925 }
|
|
get_sip_pvt_byid_locked: Lock interface lock and find matching pvt lock ---
Definition at line 6792 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(). 06793 { 06794 struct sip_pvt *sip_pvt_ptr = NULL; 06795 06796 /* Search interfaces and find the match */ 06797 ast_mutex_lock(&iflock); 06798 sip_pvt_ptr = iflist; 06799 while(sip_pvt_ptr) { 06800 if (!strcmp(sip_pvt_ptr->callid, callid)) { 06801 /* Go ahead and lock it (and its owner) before returning */ 06802 ast_mutex_lock(&sip_pvt_ptr->lock); 06803 if (sip_pvt_ptr->owner) { 06804 while(ast_mutex_trylock(&sip_pvt_ptr->owner->lock)) { 06805 ast_mutex_unlock(&sip_pvt_ptr->lock); 06806 usleep(1); 06807 ast_mutex_lock(&sip_pvt_ptr->lock); 06808 if (!sip_pvt_ptr->owner) 06809 break; 06810 } 06811 } 06812 break; 06813 } 06814 sip_pvt_ptr = sip_pvt_ptr->next; 06815 } 06816 ast_mutex_unlock(&iflock); 06817 return sip_pvt_ptr; 06818 }
|
|
gettag: Get tag from packet
Definition at line 10419 of file chan_sip.c. References get_header(), and strcasestr(). Referenced by find_call(), handle_request(), and handle_response(). 10420 { 10421 10422 char *thetag, *sep; 10423 10424 10425 if (!tagbuf) 10426 return NULL; 10427 tagbuf[0] = '\0'; /* reset the buffer */ 10428 thetag = get_header(req, header); 10429 thetag = strcasestr(thetag, ";tag="); 10430 if (thetag) { 10431 thetag += 5; 10432 ast_copy_string(tagbuf, thetag, tagbufsize); 10433 sep = strchr(tagbuf, ';'); 10434 if (sep) 10435 *sep = '\0'; 10436 } 10437 return thetag; 10438 }
|
|
handle_common_options: Handle flag-type options common to users and peers ---
Definition at line 11888 of file chan_sip.c. References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_channel::flags, 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_NAT_ROUTE, 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(). 11889 { 11890 int res = 0; 11891 11892 if (!strcasecmp(v->name, "trustrpid")) { 11893 ast_set_flag(mask, SIP_TRUSTRPID); 11894 ast_set2_flag(flags, ast_true(v->value), SIP_TRUSTRPID); 11895 res = 1; 11896 } else if (!strcasecmp(v->name, "sendrpid")) { 11897 ast_set_flag(mask, SIP_SENDRPID); 11898 ast_set2_flag(flags, ast_true(v->value), SIP_SENDRPID); 11899 res = 1; 11900 } else if (!strcasecmp(v->name, "useclientcode")) { 11901 ast_set_flag(mask, SIP_USECLIENTCODE); 11902 ast_set2_flag(flags, ast_true(v->value), SIP_USECLIENTCODE); 11903 res = 1; 11904 } else if (!strcasecmp(v->name, "dtmfmode")) { 11905 ast_set_flag(mask, SIP_DTMF); 11906 ast_clear_flag(flags, SIP_DTMF); 11907 if (!strcasecmp(v->value, "inband")) 11908 ast_set_flag(flags, SIP_DTMF_INBAND); 11909 else if (!strcasecmp(v->value, "rfc2833")) 11910 ast_set_flag(flags, SIP_DTMF_RFC2833); 11911 else if (!strcasecmp(v->value, "info")) 11912 ast_set_flag(flags, SIP_DTMF_INFO); 11913 else if (!strcasecmp(v->value, "auto")) 11914 ast_set_flag(flags, SIP_DTMF_AUTO); 11915 else { 11916 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 11917 ast_set_flag(flags, SIP_DTMF_RFC2833); 11918 } 11919 } else if (!strcasecmp(v->name, "nat")) { 11920 ast_set_flag(mask, SIP_NAT); 11921 ast_clear_flag(flags, SIP_NAT); 11922 if (!strcasecmp(v->value, "never")) 11923 ast_set_flag(flags, SIP_NAT_NEVER); 11924 else if (!strcasecmp(v->value, "route")) 11925 ast_set_flag(flags, SIP_NAT_ROUTE); 11926 else if (ast_true(v->value)) 11927 ast_set_flag(flags, SIP_NAT_ALWAYS); 11928 else 11929 ast_set_flag(flags, SIP_NAT_RFC3581); 11930 } else if (!strcasecmp(v->name, "canreinvite")) { 11931 ast_set_flag(mask, SIP_REINVITE); 11932 ast_clear_flag(flags, SIP_REINVITE); 11933 if (!strcasecmp(v->value, "update")) 11934 ast_set_flag(flags, SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 11935 else 11936 ast_set2_flag(flags, ast_true(v->value), SIP_CAN_REINVITE); 11937 } else if (!strcasecmp(v->name, "insecure")) { 11938 ast_set_flag(mask, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11939 ast_clear_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11940 if (!strcasecmp(v->value, "very")) 11941 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11942 else if (ast_true(v->value)) 11943 ast_set_flag(flags, SIP_INSECURE_PORT); 11944 else if (!ast_false(v->value)) { 11945 char buf[64]; 11946 char *word, *next; 11947 11948 ast_copy_string(buf, v->value, sizeof(buf)); 11949 next = buf; 11950 while ((word = strsep(&next, ","))) { 11951 if (!strcasecmp(word, "port")) 11952 ast_set_flag(flags, SIP_INSECURE_PORT); 11953 else if (!strcasecmp(word, "invite")) 11954 ast_set_flag(flags, SIP_INSECURE_INVITE); 11955 else 11956 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", v->value, v->lineno); 11957 } 11958 } 11959 } else if (!strcasecmp(v->name, "progressinband")) { 11960 ast_set_flag(mask, SIP_PROG_INBAND); 11961 ast_clear_flag(flags, SIP_PROG_INBAND); 11962 if (ast_true(v->value)) 11963 ast_set_flag(flags, SIP_PROG_INBAND_YES); 11964 else if (strcasecmp(v->value, "never")) 11965 ast_set_flag(flags, SIP_PROG_INBAND_NO); 11966 } else if (!strcasecmp(v->name, "allowguest")) { 11967 #ifdef OSP_SUPPORT 11968 if (!strcasecmp(v->value, "osp")) 11969 global_allowguest = 2; 11970 else 11971 #endif 11972 if (ast_true(v->value)) 11973 global_allowguest = 1; 11974 else 11975 global_allowguest = 0; 11976 #ifdef OSP_SUPPORT 11977 } else if (!strcasecmp(v->name, "ospauth")) { 11978 ast_set_flag(mask, SIP_OSPAUTH); 11979 ast_clear_flag(flags, SIP_OSPAUTH); 11980 if (!strcasecmp(v->value, "proxy")) 11981 ast_set_flag(flags, SIP_OSPAUTH_PROXY); 11982 else if (!strcasecmp(v->value, "gateway")) 11983 ast_set_flag(flags, SIP_OSPAUTH_GATEWAY); 11984 else if(!strcasecmp (v->value, "exclusive")) 11985 ast_set_flag(flags, SIP_OSPAUTH_EXCLUSIVE); 11986 #endif 11987 } else if (!strcasecmp(v->name, "promiscredir")) { 11988 ast_set_flag(mask, SIP_PROMISCREDIR); 11989 ast_set2_flag(flags, ast_true(v->value), SIP_PROMISCREDIR); 11990 res = 1; 11991 } 11992 11993 return res; 11994 }
|
|
handle_request: Handle SIP requests (methods) ---
Definition at line 11142 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. 11143 { 11144 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 11145 relatively static */ 11146 struct sip_request resp; 11147 char *cmd; 11148 char *cseq; 11149 char *useragent; 11150 int seqno; 11151 int len; 11152 int ignore=0; 11153 int respid; 11154 int res = 0; 11155 char iabuf[INET_ADDRSTRLEN]; 11156 int debug = sip_debug_test_pvt(p); 11157 char *e; 11158 int error = 0; 11159 11160 /* Clear out potential response */ 11161 memset(&resp, 0, sizeof(resp)); 11162 11163 /* Get Method and Cseq */ 11164 cseq = get_header(req, "Cseq"); 11165 cmd = req->header[0]; 11166 11167 /* Must have Cseq */ 11168 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 11169 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 11170 error = 1; 11171 } 11172 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 11173 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 11174 error = 1; 11175 } 11176 if (error) { 11177 if (!p->initreq.header) /* New call */ 11178 ast_set_flag(p, SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 11179 return -1; 11180 } 11181 /* Get the command XXX */ 11182 11183 cmd = req->rlPart1; 11184 e = req->rlPart2; 11185 11186 /* Save useragent of the client */ 11187 useragent = get_header(req, "User-Agent"); 11188 if (!ast_strlen_zero(useragent)) 11189 ast_copy_string(p->useragent, useragent, sizeof(p->useragent)); 11190 11191 /* Find out SIP method for incoming request */ 11192 if (req->method == SIP_RESPONSE) { /* Response to our request */ 11193 /* Response to our request -- Do some sanity checks */ 11194 if (!p->initreq.headers) { 11195 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 11196 ast_set_flag(p, SIP_NEEDDESTROY); 11197 return 0; 11198 } else if (p->ocseq && (p->ocseq < seqno)) { 11199 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 11200 return -1; 11201 } else if (p->ocseq && (p->ocseq != seqno)) { 11202 /* ignore means "don't do anything with it" but still have to 11203 respond appropriately */ 11204 ignore=1; 11205 } 11206 11207 e = ast_skip_blanks(e); 11208 if (sscanf(e, "%d %n", &respid, &len) != 1) { 11209 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 11210 } else { 11211 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 11212 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 11213 extract_uri(p, req); 11214 handle_response(p, respid, e + len, req, ignore, seqno); 11215 } 11216 return 0; 11217 } 11218 11219 /* New SIP request coming in 11220 (could be new request in existing SIP dialog as well...) 11221 */ 11222 11223 p->method = req->method; /* Find out which SIP method they are using */ 11224 if (option_debug > 2) 11225 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 11226 11227 if (p->icseq && (p->icseq > seqno)) { 11228 if (option_debug) 11229 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 11230 if (req->method != SIP_ACK) 11231 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 11232 return -1; 11233 } else if (p->icseq && (p->icseq == seqno) && req->method != SIP_ACK &&(p->method != SIP_CANCEL|| ast_test_flag(p, SIP_ALREADYGONE))) { 11234 /* ignore means "don't do anything with it" but still have to 11235 respond appropriately. We do this if we receive a repeat of 11236 the last sequence number */ 11237 ignore=2; 11238 if (option_debug > 2) 11239 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 11240 } 11241 11242 if (seqno >= p->icseq) 11243 /* Next should follow monotonically (but not necessarily 11244 incrementally -- thanks again to the genius authors of SIP -- 11245 increasing */ 11246 p->icseq = seqno; 11247 11248 /* Find their tag if we haven't got it */ 11249 if (ast_strlen_zero(p->theirtag)) { 11250 gettag(req, "From", p->theirtag, sizeof(p->theirtag)); 11251 } 11252 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 11253 11254 if (pedanticsipchecking) { 11255 /* If this is a request packet without a from tag, it's not 11256 correct according to RFC 3261 */ 11257 /* Check if this a new request in a new dialog with a totag already attached to it, 11258 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 11259 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 11260 /* If this is a first request and it got a to-tag, it is not for us */ 11261 if (!ignore && req->method == SIP_INVITE) { 11262 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req, 1); 11263 /* Will cease to exist after ACK */ 11264 } else if (req->method != SIP_ACK) { 11265 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 11266 ast_set_flag(p, SIP_NEEDDESTROY); 11267 } 11268 return res; 11269 } 11270 } 11271 11272 /* Handle various incoming SIP methods in requests */ 11273 switch (p->method) { 11274 case SIP_OPTIONS: 11275 res = handle_request_options(p, req, debug); 11276 break; 11277 case SIP_INVITE: 11278 res = handle_request_invite(p, req, debug, ignore, seqno, sin, recount, e); 11279 break; 11280 case SIP_REFER: 11281 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 11282 break; 11283 case SIP_CANCEL: 11284 res = handle_request_cancel(p, req, debug, ignore); 11285 break; 11286 case SIP_BYE: 11287 res = handle_request_bye(p, req, debug, ignore); 11288 break; 11289 case SIP_MESSAGE: 11290 res = handle_request_message(p, req, debug, ignore); 11291 break; 11292 case SIP_SUBSCRIBE: 11293 res = handle_request_subscribe(p, req, debug, ignore, sin, seqno, e); 11294 break; 11295 case SIP_REGISTER: 11296 res = handle_request_register(p, req, debug, ignore, sin, e); 11297 break; 11298 case SIP_INFO: 11299 if (!ignore) { 11300 if (debug) 11301 ast_verbose("Receiving INFO!\n"); 11302 handle_request_info(p, req); 11303 } else { /* if ignoring, transmit response */ 11304 transmit_response(p, "200 OK", req); 11305 } 11306 break; 11307 case SIP_NOTIFY: 11308 /* XXX we get NOTIFY's from some servers. WHY?? Maybe we should 11309 look into this someday XXX */ 11310 transmit_response(p, "200 OK", req); 11311 if (!p->lastinvite) 11312 ast_set_flag(p, SIP_NEEDDESTROY); 11313 break; 11314 case SIP_ACK: 11315 /* Make sure we don't ignore this */ 11316 if (seqno == p->pendinginvite) { 11317 p->pendinginvite = 0; 11318 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 11319 if (find_sdp(req)) { 11320 if (process_sdp(p, req)) 11321 return -1; 11322 } 11323 check_pendings(p); 11324 } 11325 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 11326 ast_set_flag(p, SIP_NEEDDESTROY); 11327 break; 11328 default: 11329 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 11330 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 11331 cmd, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); 11332 /* If this is some new method, and we don't have a call, destroy it now */ 11333 if (!p->initreq.headers) 11334 ast_set_flag(p, SIP_NEEDDESTROY); 11335 break; 11336 } 11337 return res; 11338 }
|
|
handle_request_bye: Handle incoming BYE request ---
Definition at line 10830 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_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::pendinginvite, SIP_ALREADYGONE, SIP_NEEDDESTROY, SIP_OUTGOING, transmit_response(), and transmit_response_reliable(). Referenced by handle_request(). 10831 { 10832 struct ast_channel *c=NULL; 10833 int res; 10834 struct ast_channel *bridged_to; 10835 char iabuf[INET_ADDRSTRLEN]; 10836 10837 if (p->pendinginvite && !ast_test_flag(p, SIP_OUTGOING) && !ignore) 10838 transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1); 10839 10840 copy_request(&p->initreq, req); 10841 check_via(p, req); 10842 ast_set_flag(p, SIP_ALREADYGONE); 10843 if (p->rtp) { 10844 /* Immediately stop RTP */ 10845 ast_rtp_stop(p->rtp); 10846 } 10847 if (p->vrtp) { 10848 /* Immediately stop VRTP */ 10849 ast_rtp_stop(p->vrtp); 10850 } 10851 if (!ast_strlen_zero(get_header(req, "Also"))) { 10852 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 10853 ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 10854 if (ast_strlen_zero(p->context)) 10855 strcpy(p->context, default_context); 10856 res = get_also_info(p, req); 10857 if (!res) { 10858 c = p->owner; 10859 if (c) { 10860 bridged_to = ast_bridged_channel(c); 10861 if (bridged_to) { 10862 /* Don't actually hangup here... */ 10863 ast_moh_stop(bridged_to); 10864 ast_async_goto(bridged_to, p->context, p->refer_to,1); 10865 } else 10866 ast_queue_hangup(p->owner); 10867 } 10868 } else { 10869 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 10870 if (p->owner) 10871 ast_queue_hangup(p->owner); 10872 } 10873 } else if (p->owner) { 10874 ast_queue_hangup(p->owner); 10875 if (option_debug > 2) 10876 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n."); 10877 } else { 10878 ast_set_flag(p, SIP_NEEDDESTROY); 10879 if (option_debug > 2) 10880 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n."); 10881 } 10882 transmit_response(p, "200 OK", req); 10883 10884 return 1; 10885 }
|
|
handle_request_cancel: Handle incoming CANCEL request ---
Definition at line 10801 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(). 10802 { 10803 10804 check_via(p, req); 10805 ast_set_flag(p, SIP_ALREADYGONE); 10806 if (p->rtp) { 10807 /* Immediately stop RTP */ 10808 ast_rtp_stop(p->rtp); 10809 } 10810 if (p->vrtp) { 10811 /* Immediately stop VRTP */ 10812 ast_rtp_stop(p->vrtp); 10813 } 10814 if (p->owner) 10815 ast_queue_hangup(p->owner); 10816 else 10817 ast_set_flag(p, SIP_NEEDDESTROY); 10818 if (p->initreq.len > 0) { 10819 if (!ignore) 10820 transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1); 10821 transmit_response(p, "200 OK", req); 10822 return 1; 10823 } else { 10824 transmit_response(p, "481 Call Leg Does Not Exist", req); 10825 return 0; 10826 } 10827 }
|
|
handle_request_info: Receive SIP INFO Message ---
Definition at line 8783 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(). 08784 { 08785 char buf[1024]; 08786 unsigned int event; 08787 char *c; 08788 08789 /* Need to check the media/type */ 08790 if (!strcasecmp(get_header(req, "Content-Type"), "application/dtmf-relay") || 08791 !strcasecmp(get_header(req, "Content-Type"), "application/vnd.nortelnetworks.digits")) { 08792 08793 /* Try getting the "signal=" part */ 08794 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 08795 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 08796 transmit_response(p, "200 OK", req); /* Should return error */ 08797 return; 08798 } else { 08799 ast_copy_string(buf, c, sizeof(buf)); 08800 } 08801 08802 if (!p->owner) { /* not a PBX call */ 08803 transmit_response(p, "481 Call leg/transaction does not exist", req); 08804 ast_set_flag(p, SIP_NEEDDESTROY); 08805 return; 08806 } 08807 08808 if (ast_strlen_zero(buf)) { 08809 transmit_response(p, "200 OK", req); 08810 return; 08811 } 08812 08813 if (buf[0] == '*') 08814 event = 10; 08815 else if (buf[0] == '#') 08816 event = 11; 08817 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 08818 event = 12 + buf[0] - 'A'; 08819 else 08820 event = atoi(buf); 08821 if (event == 16) { 08822 /* send a FLASH event */ 08823 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 08824 ast_queue_frame(p->owner, &f); 08825 if (sipdebug) 08826 ast_verbose("* DTMF-relay event received: FLASH\n"); 08827 } else { 08828 /* send a DTMF event */ 08829 struct ast_frame f = { AST_FRAME_DTMF, }; 08830 if (event < 10) { 08831 f.subclass = '0' + event; 08832 } else if (event < 11) { 08833 f.subclass = '*'; 08834 } else if (event < 12) { 08835 f.subclass = '#'; 08836 } else if (event < 16) { 08837 f.subclass = 'A' + (event - 12); 08838 } 08839 ast_queue_frame(p->owner, &f); 08840 if (sipdebug) 08841 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 08842 } 08843 transmit_response(p, "200 OK", req); 08844 return; 08845 } else if (!strcasecmp(get_header(req, "Content-Type"), "application/media_control+xml")) { 08846 /* Eh, we'll just assume it's a fast picture update for now */ 08847 if (p->owner) 08848 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 08849 transmit_response(p, "200 OK", req); 08850 return; 08851 } else if ((c = get_header(req, "X-ClientCode"))) { 08852 /* Client code (from SNOM phone) */ 08853 if (ast_test_flag(p, SIP_USECLIENTCODE)) { 08854 if (p->owner && p->owner->cdr) 08855 ast_cdr_setuserfield(p->owner, c); 08856 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 08857 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 08858 transmit_response(p, "200 OK", req); 08859 } else { 08860 transmit_response(p, "403 Unauthorized", req); 08861 } 08862 return; 08863 } 08864 /* Other type of INFO message, not really understood by Asterisk */ 08865 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 08866 08867 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 08868 transmit_response(p, "415 Unsupported media type", req); 08869 return; 08870 }
|
|
handle_request_invite: Handle incoming INVITE request
Definition at line 10465 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(). 10466 { 10467 int res = 1; 10468 struct ast_channel *c=NULL; 10469 int gotdest; 10470 struct ast_frame af = { AST_FRAME_NULL, }; 10471 char *supported; 10472 char *required; 10473 unsigned int required_profile = 0; 10474 10475 /* Find out what they support */ 10476 if (!p->sipoptions) { 10477 supported = get_header(req, "Supported"); 10478 if (supported) 10479 parse_sip_options(p, supported); 10480 } 10481 required = get_header(req, "Require"); 10482 if (!ast_strlen_zero(required)) { 10483 required_profile = parse_sip_options(NULL, required); 10484 if (required_profile) { /* They require something */ 10485 /* At this point we support no extensions, so fail */ 10486 transmit_response_with_unsupported(p, "420 Bad extension", req, required); 10487 if (!p->lastinvite) 10488 ast_set_flag(p, SIP_NEEDDESTROY); 10489 return -1; 10490 10491 } 10492 } 10493 10494 /* Check if this is a loop */ 10495 /* This happens since we do not properly support SIP domain 10496 handling yet... -oej */ 10497 if (ast_test_flag(p, SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 10498 /* This is a call to ourself. Send ourselves an error code and stop 10499 processing immediately, as SIP really has no good mechanism for 10500 being able to call yourself */ 10501 transmit_response(p, "482 Loop Detected", req); 10502 /* We do NOT destroy p here, so that our response will be accepted */ 10503 return 0; 10504 } 10505 if (!ignore) { 10506 /* Use this as the basis */ 10507 if (debug) 10508 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 10509 sip_cancel_destroy(p); 10510 /* This call is no longer outgoing if it ever was */ 10511 ast_clear_flag(p, SIP_OUTGOING); 10512 /* This also counts as a pending invite */ 10513 p->pendinginvite = seqno; 10514 copy_request(&p->initreq, req); 10515 check_via(p, req); 10516 if (p->owner) { 10517 /* Handle SDP here if we already have an owner */ 10518 if (find_sdp(req)) { 10519 if (process_sdp(p, req)) { 10520 transmit_response(p, "488 Not acceptable here", req); 10521 if (!p->lastinvite) 10522 ast_set_flag(p, SIP_NEEDDESTROY); 10523 return -1; 10524 } 10525 } else { 10526 p->jointcapability = p->capability; 10527 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 10528 } 10529 } 10530 } else if (debug) 10531 ast_verbose("Ignoring this INVITE request\n"); 10532 if (!p->lastinvite && !ignore && !p->owner) { 10533 /* Handle authentication if this is our first invite */ 10534 res = check_user(p, req, SIP_INVITE, e, 1, sin, ignore); 10535 /* if an authentication challenge was sent, we are done here */ 10536 if (res > 0) 10537 return 0; 10538 if (res < 0) { 10539 if (res == -4) { 10540 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 10541 transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1); 10542 } else { 10543 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 10544 if (ignore) 10545 transmit_response(p, "403 Forbidden", req); 10546 else 10547 transmit_response_reliable(p, "403 Forbidden", req, 1); 10548 } 10549 ast_set_flag(p, SIP_NEEDDESTROY); 10550 p->theirtag[0] = '\0'; /* Forget their to-tag, we'll get a new one */ 10551 return 0; 10552 } 10553 /* Process the SDP portion */ 10554 if (find_sdp(req)) { 10555 if (process_sdp(p, req)) { 10556 transmit_response(p, "488 Not acceptable here", req); 10557 ast_set_flag(p, SIP_NEEDDESTROY); 10558 return -1; 10559 } 10560 } else { 10561 p->jointcapability = p->capability; 10562 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 10563 } 10564 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 10565 if (p->owner) 10566 ast_queue_frame(p->owner, &af); 10567 /* Initialize the context if it hasn't been already */ 10568 if (ast_strlen_zero(p->context)) 10569 strcpy(p->context, default_context); 10570 /* Check number of concurrent calls -vs- incoming limit HERE */ 10571 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 10572 res = update_call_counter(p, INC_CALL_LIMIT); 10573 if (res) { 10574 if (res < 0) { 10575 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 10576 if (ignore) 10577 transmit_response(p, "480 Temporarily Unavailable (Call limit)", req); 10578 else 10579 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req, 1); 10580 ast_set_flag(p, SIP_NEEDDESTROY); 10581 } 10582 return 0; 10583 } 10584 /* Get destination right away */ 10585 gotdest = get_destination(p, NULL); 10586 10587 get_rdnis(p, NULL); 10588 extract_uri(p, req); 10589 build_contact(p); 10590 10591 if (gotdest) { 10592 if (gotdest < 0) { 10593 if (ignore) 10594 transmit_response(p, "404 Not Found", req); 10595 else 10596 transmit_response_reliable(p, "404 Not Found", req, 1); 10597 update_call_counter(p, DEC_CALL_LIMIT); 10598 } else { 10599 if (ignore) 10600 transmit_response(p, "484 Address Incomplete", req); 10601 else 10602 transmit_response_reliable(p, "484 Address Incomplete", req, 1); 10603 update_call_counter(p, DEC_CALL_LIMIT); 10604 } 10605 ast_set_flag(p, SIP_NEEDDESTROY); 10606 } else { 10607 /* If no extension was specified, use the s one */ 10608 if (ast_strlen_zero(p->exten)) 10609 ast_copy_string(p->exten, "s", sizeof(p->exten)); 10610 /* Initialize tag */ 10611 make_our_tag(p->tag, sizeof(p->tag)); 10612 /* First invitation */ 10613 c = sip_new(p, AST_STATE_DOWN, ast_strlen_zero(p->username) ? NULL : p->username ); 10614 *recount = 1; 10615 /* Save Record-Route for any later requests we make on this dialogue */ 10616 build_route(p, req, 0); 10617 if (c) { 10618 /* Pre-lock the call */ 10619 ast_mutex_lock(&c->lock); 10620 } 10621 } 10622 10623 } else { 10624 if (option_debug > 1 && sipdebug) 10625 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 10626 c = p->owner; 10627 } 10628 if (!ignore && p) 10629 p->lastinvite = seqno; 10630 if (c) { 10631 #ifdef OSP_SUPPORT 10632 ast_channel_setwhentohangup (c, p->osptimelimit); 10633 #endif 10634 switch(c->_state) { 10635 case AST_STATE_DOWN: 10636 transmit_response(p, "100 Trying", req); 10637 ast_setstate(c, AST_STATE_RING); 10638 if (strcmp(p->exten, ast_pickup_ext())) { 10639 enum ast_pbx_result res; 10640 10641 res = ast_pbx_start(c); 10642 10643 switch (res) { 10644 case AST_PBX_FAILED: 10645 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 10646 if (ignore) 10647 transmit_response(p, "503 Unavailable", req); 10648 else 10649 transmit_response_reliable(p, "503 Unavailable", req, 1); 10650 break; 10651 case AST_PBX_CALL_LIMIT: 10652 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 10653 if (ignore) 10654 transmit_response(p, "480 Temporarily Unavailable", req); 10655 else 10656 transmit_response_reliable(p, "480 Temporarily Unavailable", req, 1); 10657 break; 10658 case AST_PBX_SUCCESS: 10659 /* nothing to do */ 10660 break; 10661 } 10662 10663 if (res) { 10664 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 10665 /* Unlock locks so ast_hangup can do its magic */ 10666 ast_mutex_unlock(&c->lock); 10667 ast_mutex_unlock(&p->lock); 10668 ast_hangup(c); 10669 ast_mutex_lock(&p->lock); 10670 c = NULL; 10671 } 10672 } else { 10673 ast_mutex_unlock(&c->lock); 10674 if (ast_pickup_call(c)) { 10675 ast_log(LOG_NOTICE, "Nothing to pick up\n"); 10676 if (ignore) 10677 transmit_response(p, "503 Unavailable", req); 10678 else 10679 transmit_response_reliable(p, "503 Unavailable", req, 1); 10680 ast_set_flag(p, SIP_ALREADYGONE); 10681 /* Unlock locks so ast_hangup can do its magic */ 10682 ast_mutex_unlock(&p->lock); 10683 ast_hangup(c); 10684 ast_mutex_lock(&p->lock); 10685 c = NULL; 10686 } else { 10687 ast_mutex_unlock(&p->lock); 10688 ast_setstate(c, AST_STATE_DOWN); 10689 ast_hangup(c); 10690 ast_mutex_lock(&p->lock); 10691 c = NULL; 10692 } 10693 } 10694 break; 10695 case AST_STATE_RING: 10696 transmit_response(p, "100 Trying", req); 10697 break; 10698 case AST_STATE_RINGING: 10699 transmit_response(p, "180 Ringing", req); 10700 break; 10701 case AST_STATE_UP: 10702 transmit_response_with_sdp(p, "200 OK", req, 1); 10703 break; 10704 default: 10705 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 10706 transmit_response(p, "100 Trying", req); 10707 } 10708 } else { 10709 if (p && !ast_test_flag(p, SIP_NEEDDESTROY) && !ignore) { 10710 if (!p->jointcapability) { 10711 if (ignore) 10712 transmit_response(p, "488 Not Acceptable Here (codec error)", req); 10713 else 10714 transmit_response_reliable(p, "488 Not Acceptable Here (codec error)", req, 1); 10715 ast_set_flag(p, SIP_NEEDDESTROY); 10716 } else { 10717 ast_log(LOG_NOTICE, "Unable to create/find channel\n"); 10718 if (ignore) 10719 transmit_response(p, "503 Unavailable", req); 10720 else 10721 transmit_response_reliable(p, "503 Unavailable", req, 1); 10722 ast_set_flag(p, SIP_NEEDDESTROY); 10723 } 10724 } 10725 } 10726 return res; 10727 }
|
|
handle_request_message: Handle incoming MESSAGE request ---
Definition at line 10888 of file chan_sip.c. References ast_verbose(), receive_message(), and transmit_response(). Referenced by handle_request(). 10889 { 10890 if (!ignore) { 10891 if (debug) 10892 ast_verbose("Receiving message!\n"); 10893 receive_message(p, req); 10894 } else { 10895 transmit_response(p, "202 Accepted", req); 10896 } 10897 return 1; 10898 }
|
|
handle_request_options: Handle incoming OPTIONS request
Definition at line 10441 of file chan_sip.c. References ast_set_flag, ast_strlen_zero(), build_contact(), sip_pvt::context, default_context, get_destination(), sip_pvt::lastinvite, SIP_NEEDDESTROY, and transmit_response_with_allow(). Referenced by handle_request(). 10442 { 10443 int res; 10444 10445 res = get_destination(p, req); 10446 build_contact(p); 10447 /* XXX Should we authenticate OPTIONS? XXX */ 10448 if (ast_strlen_zero(p->context)) 10449 strcpy(p->context, default_context); 10450 if (res < 0) 10451 transmit_response_with_allow(p, "404 Not Found", req, 0); 10452 else if (res > 0) 10453 transmit_response_with_allow(p, "484 Address Incomplete", req, 0); 10454 else 10455 transmit_response_with_allow(p, "200 OK", req, 0); 10456 /* Destroy if this OPTIONS was the opening request, but not if 10457 it's in the middle of a normal call flow. */ 10458 if (!p->lastinvite) 10459 ast_set_flag(p, SIP_NEEDDESTROY); 10460 10461 return res; 10462 }
|
|
handle_request_refer: Handle incoming REFER request ---
Definition at line 10730 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(). 10731 { 10732 struct ast_channel *c=NULL; 10733 int res; 10734 struct ast_channel *transfer_to; 10735 char *transfercontext = NULL; 10736 10737 if (option_debug > 2) 10738 ast_log(LOG_DEBUG, "SIP call transfer received for call %s (REFER)!\n", p->callid); 10739 res = get_refer_info(p, req, &transfercontext); 10740 if (ast_strlen_zero(p->context)) 10741 strcpy(p->context, default_context); 10742 if (ast_strlen_zero(transfercontext)) 10743 transfercontext = p->context; 10744 if (res < 0) 10745 transmit_response(p, "603 Declined", req); 10746 else if (res > 0) 10747 transmit_response(p, "484 Address Incomplete", req); 10748 else { 10749 int nobye = 0; 10750 if (!ignore) { 10751 if (p->refer_call) { 10752 ast_log(LOG_DEBUG,"202 Accepted (supervised)\n"); 10753 attempt_transfer(p, p->refer_call); 10754 if (p->refer_call->owner) 10755 ast_mutex_unlock(&p->refer_call->owner->lock); 10756 ast_mutex_unlock(&p->refer_call->lock); 10757 p->refer_call = NULL; 10758 ast_set_flag(p, SIP_GOTREFER); 10759 } else { 10760 ast_log(LOG_DEBUG,"202 Accepted (blind)\n"); 10761 c = p->owner; 10762 if (c) { 10763 transfer_to = ast_bridged_channel(c); 10764 if (transfer_to) { 10765 ast_log(LOG_DEBUG, "Got SIP blind transfer, applying to '%s'\n", transfer_to->name); 10766 ast_moh_stop(transfer_to); 10767 if (!strcmp(p->refer_to, ast_parking_ext())) { 10768 /* Must release c's lock now, because it will not longer 10769 be accessible after the transfer! */ 10770 *nounlock = 1; 10771 ast_mutex_unlock(&c->lock); 10772 sip_park(transfer_to, c, req); 10773 nobye = 1; 10774 } else { 10775 /* Must release c's lock now, because it will not longer 10776 be accessible after the transfer! */ 10777 *nounlock = 1; 10778 ast_mutex_unlock(&c->lock); 10779 ast_async_goto(transfer_to, transfercontext, p->refer_to,1); 10780 } 10781 } else { 10782 ast_log(LOG_DEBUG, "Got SIP blind transfer but nothing to transfer to.\n"); 10783 ast_queue_hangup(p->owner); 10784 } 10785 } 10786 ast_set_flag(p, SIP_GOTREFER); 10787 } 10788 transmit_response(p, "202 Accepted", req); 10789 transmit_notify_with_sipfrag(p, seqno); 10790 /* Always increment on a BYE */ 10791 if (!nobye) { 10792 transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); 10793 ast_set_flag(p, SIP_ALREADYGONE); 10794 } 10795 } 10796 } 10797 return res; 10798 }
|
|
handle_request_register: Handle incoming REGISTER request ---
Definition at line 11120 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(). 11121 { 11122 int res = 0; 11123 char iabuf[INET_ADDRSTRLEN]; 11124 11125 /* Use this as the basis */ 11126 if (debug) 11127 ast_verbose("Using latest REGISTER request as basis request\n"); 11128 copy_request(&p->initreq, req); 11129 check_via(p, req); 11130 if ((res = register_verify(p, sin, req, e, ignore)) < 0) 11131 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")); 11132 if (res < 1) { 11133 /* Destroy the session, but keep us around for just a bit in case they don't 11134 get our 200 OK */ 11135 sip_scheddestroy(p, 15*1000); 11136 } 11137 return res; 11138 }
|
|
handle_request_subscribe: Handle incoming SUBSCRIBE request ---
Definition at line 10900 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(). 10901 { 10902 int gotdest; 10903 int res = 0; 10904 int firststate = AST_EXTENSION_REMOVED; 10905 10906 if (p->initreq.headers) { 10907 /* We already have a dialog */ 10908 if (p->initreq.method != SIP_SUBSCRIBE) { 10909 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 10910 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 10911 transmit_response(p, "403 Forbidden (within dialog)", req); 10912 /* Do not destroy session, since we will break the call if we do */ 10913 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); 10914 return 0; 10915 } else { 10916 if (debug) 10917 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 10918 } 10919 } 10920 if (!ignore && !p->initreq.headers) { 10921 /* Use this as the basis */ 10922 if (debug) 10923 ast_verbose("Using latest SUBSCRIBE request as basis request\n"); 10924 /* This call is no longer outgoing if it ever was */ 10925 ast_clear_flag(p, SIP_OUTGOING); 10926 copy_request(&p->initreq, req); 10927 check_via(p, req); 10928 } else if (debug && ignore) 10929 ast_verbose("Ignoring this SUBSCRIBE request\n"); 10930 10931 if (!p->lastinvite) { 10932 char mailboxbuf[256]=""; 10933 int found = 0; 10934 char *mailbox = NULL; 10935 int mailboxsize = 0; 10936 char *eventparam; 10937 10938 char *event = get_header(req, "Event"); /* Get Event package name */ 10939 char *accept = get_header(req, "Accept"); 10940 10941 /* Find parameters to Event: header value and remove them for now */ 10942 eventparam = strchr(event, ';'); 10943 if (eventparam) { 10944 *eventparam = '\0'; 10945 eventparam++; 10946 } 10947 10948 if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) { 10949 mailbox = mailboxbuf; 10950 mailboxsize = sizeof(mailboxbuf); 10951 } 10952 /* Handle authentication if this is our first subscribe */ 10953 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, ignore, mailbox, mailboxsize); 10954 /* if an authentication challenge was sent, we are done here */ 10955 if (res > 0) 10956 return 0; 10957 if (res < 0) { 10958 if (res == -4) { 10959 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 10960 transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1); 10961 } else { 10962 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 10963 if (ignore) 10964 transmit_response(p, "403 Forbidden", req); 10965 else 10966 transmit_response_reliable(p, "403 Forbidden", req, 1); 10967 } 10968 ast_set_flag(p, SIP_NEEDDESTROY); 10969 return 0; 10970 } 10971 gotdest = get_destination(p, NULL); 10972 /* Initialize the context if it hasn't been already; 10973 note this is done _after_ handling any domain lookups, 10974 because the context specified there is for calls, not 10975 subscriptions 10976 */ 10977 if (!ast_strlen_zero(p->subscribecontext)) 10978 ast_copy_string(p->context, p->subscribecontext, sizeof(p->context)); 10979 else if (ast_strlen_zero(p->context)) 10980 strcpy(p->context, default_context); 10981 /* Get destination right away */ 10982 build_contact(p); 10983 if (gotdest) { 10984 if (gotdest < 0) 10985 transmit_response(p, "404 Not Found", req); 10986 else 10987 transmit_response(p, "484 Address Incomplete", req); /* Overlap dialing on SUBSCRIBE?? */ 10988 ast_set_flag(p, SIP_NEEDDESTROY); 10989 } else { 10990 10991 /* Initialize tag for new subscriptions */ 10992 if (ast_strlen_zero(p->tag)) 10993 make_our_tag(p->tag, sizeof(p->tag)); 10994 10995 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 10996 10997 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 10998 /* Polycom phones only handle xpidf+xml, even if they say they can 10999 handle pidf+xml as well 11000 */ 11001 if (strstr(p->useragent, "Polycom")) { 11002 p->subscribed = XPIDF_XML; 11003 } else if (strstr(accept, "application/pidf+xml")) { 11004 p->subscribed = PIDF_XML; /* RFC 3863 format */ 11005 } else if (strstr(accept, "application/dialog-info+xml")) { 11006 p->subscribed = DIALOG_INFO_XML; 11007 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 11008 } else if (strstr(accept, "application/cpim-pidf+xml")) { 11009 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 11010 } else if (strstr(accept, "application/xpidf+xml")) { 11011 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 11012 } else { 11013 /* Can't find a format for events that we know about */ 11014 transmit_response(p, "489 Bad Event", req); 11015 ast_set_flag(p, SIP_NEEDDESTROY); 11016 return 0; 11017 } 11018 } else if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) { 11019 /* Looks like they actually want a mailbox status */ 11020 11021 /* At this point, we should check if they subscribe to a mailbox that 11022 has the same extension as the peer or the mailbox id. If we configure 11023 the context to be the same as a SIP domain, we could check mailbox 11024 context as well. To be able to securely accept subscribes on mailbox 11025 IDs, not extensions, we need to check the digest auth user to make 11026 sure that the user has access to the mailbox. 11027 11028 Since we do not act on this subscribe anyway, we might as well 11029 accept any authenticated peer with a mailbox definition in their 11030 config section. 11031 11032 */ 11033 if (!ast_strlen_zero(mailbox)) { 11034 found++; 11035 } 11036 11037 if (found){ 11038 transmit_response(p, "200 OK", req); 11039 ast_set_flag(p, SIP_NEEDDESTROY); 11040 } else { 11041 transmit_response(p, "404 Not found", req); 11042 ast_set_flag(p, SIP_NEEDDESTROY); 11043 } 11044 return 0; 11045 } else { /* At this point, Asterisk does not understand the specified event */ 11046 transmit_response(p, "489 Bad Event", req); 11047 if (option_debug > 1) 11048 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 11049 ast_set_flag(p, SIP_NEEDDESTROY); 11050 return 0; 11051 } 11052 if (p->subscribed != NONE) 11053 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 11054 } 11055 } 11056 11057 if (!ignore && p) 11058 p->lastinvite = seqno; 11059 if (p && !ast_test_flag(p, SIP_NEEDDESTROY)) { 11060 p->expiry = atoi(get_header(req, "Expires")); 11061 11062 /* The next 4 lines can be removed if the SNOM Expires bug is fixed */ 11063 if (p->subscribed == DIALOG_INFO_XML) { 11064 if (p->expiry > max_expiry) 11065 p->expiry = max_expiry; 11066 } 11067 if (sipdebug || option_debug > 1) 11068 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 11069 if (p->autokillid > -1) 11070 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 11071 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 11072 11073 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 11074 char iabuf[INET_ADDRSTRLEN]; 11075 11076 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)); 11077 transmit_response(p, "404 Not found", req); 11078 ast_set_flag(p, SIP_NEEDDESTROY); 11079 return 0; 11080 } else { 11081 struct sip_pvt *p_old; 11082 11083 transmit_response(p, "200 OK", req); 11084 transmit_state_notify(p, firststate, 1, 1); /* Send first notification */ 11085 append_history(p, "Subscribestatus", ast_extension_state2str(firststate)); 11086 11087 /* remove any old subscription from this peer for the same exten/context, 11088 as the peer has obviously forgotten about it and it's wasteful to wait 11089 for it to expire and send NOTIFY messages to the peer only to have them 11090 ignored (or generate errors) 11091 */ 11092 ast_mutex_lock(&iflock); 11093 for (p_old = iflist; p_old; p_old = p_old->next) { 11094 if (p_old == p) 11095 continue; 11096 if (p_old->initreq.method != SIP_SUBSCRIBE) 11097 continue; 11098 if (p_old->subscribed == NONE) 11099 continue; 11100 ast_mutex_lock(&p_old->lock); 11101 if (!strcmp(p_old->username, p->username)) { 11102 if (!strcmp(p_old->exten, p->exten) && 11103 !strcmp(p_old->context, p->context)) { 11104 ast_set_flag(p_old, SIP_NEEDDESTROY); 11105 ast_mutex_unlock(&p_old->lock); 11106 break; 11107 } 11108 } 11109 ast_mutex_unlock(&p_old->lock); 11110 } 11111 ast_mutex_unlock(&iflock); 11112 } 11113 if (!p->expiry) 11114 ast_set_flag(p, SIP_NEEDDESTROY); 11115 } 11116 return 1; 11117 }
|
|
handle_response: Handle SIP response in dialogue ---
Definition at line 9963 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. 09964 { 09965 char *msg, *c; 09966 struct ast_channel *owner; 09967 char iabuf[INET_ADDRSTRLEN]; 09968 int sipmethod; 09969 int res = 1; 09970 09971 c = get_header(req, "Cseq"); 09972 msg = strchr(c, ' '); 09973 if (!msg) 09974 msg = ""; 09975 else 09976 msg++; 09977 sipmethod = find_sip_method(msg); 09978 09979 owner = p->owner; 09980 if (owner) 09981 owner->hangupcause = hangup_sip2cause(resp); 09982 09983 /* Acknowledge whatever it is destined for */ 09984 if ((resp >= 100) && (resp <= 199)) 09985 __sip_semi_ack(p, seqno, 0, sipmethod); 09986 else 09987 __sip_ack(p, seqno, 0, sipmethod); 09988 09989 /* Get their tag if we haven't already */ 09990 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 09991 gettag(req, "To", p->theirtag, sizeof(p->theirtag)); 09992 } 09993 if (p->peerpoke) { 09994 /* We don't really care what the response is, just that it replied back. 09995 Well, as long as it's not a 100 response... since we might 09996 need to hang around for something more "definitive" */ 09997 09998 res = handle_response_peerpoke(p, resp, rest, req, ignore, seqno, sipmethod); 09999 } else if (ast_test_flag(p, SIP_OUTGOING)) { 10000 /* Acknowledge sequence number */ 10001 if (p->initid > -1) { 10002 /* Don't auto congest anymore since we've gotten something useful back */ 10003 ast_sched_del(sched, p->initid); 10004 p->initid = -1; 10005 } 10006 switch(resp) { 10007 case 100: /* 100 Trying */ 10008 if (sipmethod == SIP_INVITE) 10009 handle_response_invite(p, resp, rest, req, ignore, seqno); 10010 break; 10011 case 183: /* 183 Session Progress */ 10012 if (sipmethod == SIP_INVITE) 10013 handle_response_invite(p, resp, rest, req, ignore, seqno); 10014 break; 10015 case 180: /* 180 Ringing */ 10016 if (sipmethod == SIP_INVITE) 10017 handle_response_invite(p, resp, rest, req, ignore, seqno); 10018 break; 10019 case 200: /* 200 OK */ 10020 p->authtries = 0; /* Reset authentication counter */ 10021 if (sipmethod == SIP_MESSAGE) { 10022 /* We successfully transmitted a message */ 10023 ast_set_flag(p, SIP_NEEDDESTROY); 10024 } else if (sipmethod == SIP_NOTIFY) { 10025 /* They got the notify, this is the end */ 10026 if (p->owner) { 10027 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 10028 ast_queue_hangup(p->owner); 10029 } else { 10030 if (p->subscribed == NONE) { 10031 ast_set_flag(p, SIP_NEEDDESTROY); 10032 } 10033 } 10034 } else if (sipmethod == SIP_INVITE) { 10035 handle_response_invite(p, resp, rest, req, ignore, seqno); 10036 } else if (sipmethod == SIP_REGISTER) { 10037 res = handle_response_register(p, resp, rest, req, ignore, seqno); 10038 } else if (sipmethod == SIP_BYE) { 10039 /* Ok, we're ready to go */ 10040 ast_set_flag(p, SIP_NEEDDESTROY); 10041 } 10042 break; 10043 case 401: /* Not www-authorized on SIP method */ 10044 if (sipmethod == SIP_INVITE) { 10045 handle_response_invite(p, resp, rest, req, ignore, seqno); 10046 } else if (p->registry && sipmethod == SIP_REGISTER) { 10047 res = handle_response_register(p, resp, rest, req, ignore, seqno); 10048 } else { 10049 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 10050 ast_set_flag(p, SIP_NEEDDESTROY); 10051 } 10052 break; 10053 case 403: /* Forbidden - we failed authentication */ 10054 if (sipmethod == SIP_INVITE) { 10055 handle_response_invite(p, resp, rest, req, ignore, seqno); 10056 } else if (p->registry && sipmethod == SIP_REGISTER) { 10057 res = handle_response_register(p, resp, rest, req, ignore, seqno); 10058 } else { 10059 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for %s\n", msg); 10060 } 10061 break; 10062 case 404: /* Not found */ 10063 if (p->registry && sipmethod == SIP_REGISTER) { 10064 res = handle_response_register(p, resp, rest, req, ignore, seqno); 10065 } else if (sipmethod == SIP_INVITE) { 10066 handle_response_invite(p, resp, rest, req, ignore, seqno); 10067 } else if (owner) 10068 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 10069 break; 10070 case 407: /* Proxy auth required */ 10071 if (sipmethod == SIP_INVITE) { 10072 handle_response_invite(p, resp, rest, req, ignore, seqno); 10073 } else if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) { 10074 if (ast_strlen_zero(p->authname)) 10075 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 10076 msg, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); 10077 ast_set_flag(p, SIP_NEEDDESTROY); 10078 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 10079 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 10080 ast_set_flag(p, SIP_NEEDDESTROY); 10081 } 10082 } else if (p->registry && sipmethod == SIP_REGISTER) { 10083 res = handle_response_register(p, resp, rest, req, ignore, seqno); 10084 } else /* We can't handle this, giving up in a bad way */ 10085 ast_set_flag(p, SIP_NEEDDESTROY); 10086 10087 break; 10088 case 491: /* Pending */ 10089 if (sipmethod == SIP_INVITE) { 10090 handle_response_invite(p, resp, rest, req, ignore, seqno); 10091 } 10092 case 501: /* Not Implemented */ 10093 if (sipmethod == SIP_INVITE) { 10094 handle_response_invite(p, resp, rest, req, ignore, seqno); 10095 } else 10096 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), msg); 10097 break; 10098 default: 10099 if ((resp >= 300) && (resp < 700)) { 10100 if ((option_verbose > 2) && (resp != 487)) 10101 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)); 10102 ast_set_flag(p, SIP_ALREADYGONE); 10103 if (p->rtp) { 10104 /* Immediately stop RTP */ 10105 ast_rtp_stop(p->rtp); 10106 } 10107 if (p->vrtp) { 10108 /* Immediately stop VRTP */ 10109 ast_rtp_stop(p->vrtp); 10110 } 10111 /* XXX Locking issues?? XXX */ 10112 switch(resp) { 10113 case 300: /* Multiple Choices */ 10114 case 301: /* Moved permenantly */ 10115 case 302: /* Moved temporarily */ 10116 case 305: /* Use Proxy */ 10117 parse_moved_contact(p, req); 10118 /* Fall through */ 10119 case 486: /* Busy here */ 10120 case 600: /* Busy everywhere */ 10121 case 603: /* Decline */ 10122 if (p->owner) 10123 ast_queue_control(p->owner, AST_CONTROL_BUSY); 10124 break; 10125 case 487: 10126 /* channel now destroyed - dec the inUse counter */ 10127 if (owner) 10128 ast_queue_hangup(p->owner); 10129 update_call_counter(p, DEC_CALL_LIMIT); 10130 break; 10131 case 482: /* SIP is incapable of performing a hairpin call, which 10132 is yet another failure of not having a layer 2 (again, YAY 10133 IETF for thinking ahead). So we treat this as a call 10134 forward and hope we end up at the right place... */ 10135 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 10136 if (p->owner) 10137 snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "Local/%s@%s", p->username, p->context); 10138 /* Fall through */ 10139 case 488: /* Not acceptable here - codec error */ 10140 case 480: /* Temporarily Unavailable */ 10141 case 404: /* Not Found */ 10142 case 410: /* Gone */ 10143 case 400: /* Bad Request */ 10144 case 500: /* Server error */ 10145 case 503: /* Service Unavailable */ 10146 if (owner) 10147 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 10148 break; 10149 default: 10150 /* Send hangup */ 10151 if (owner) 10152 ast_queue_hangup(p->owner); 10153 break; 10154 } 10155 /* ACK on invite */ 10156 if (sipmethod == SIP_INVITE) 10157 transmit_request(p, SIP_ACK, seqno, 0, 0); 10158 ast_set_flag(p, SIP_ALREADYGONE); 10159 if (!p->owner) 10160 ast_set_flag(p, SIP_NEEDDESTROY); 10161 } else if ((resp >= 100) && (resp < 200)) { 10162 if (sipmethod == SIP_INVITE) { 10163 if (!ignore) 10164 sip_cancel_destroy(p); 10165 if (find_sdp(req)) 10166 process_sdp(p, req); 10167 if (p->owner) { 10168 /* Queue a progress frame */ 10169 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 10170 } 10171 } 10172 } else 10173 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)); 10174 } 10175 } else { 10176 /* Responses to OUTGOING SIP requests on INCOMING calls 10177 get handled here. As well as out-of-call message responses */ 10178 if (req->debug) 10179 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 10180 if (resp == 200) { 10181 /* Tags in early session is replaced by the tag in 200 OK, which is 10182 the final reply to our INVITE */ 10183 gettag(req, "To", p->theirtag, sizeof(p->theirtag)); 10184 } 10185 10186 switch(resp) { 10187 case 200: 10188 if (sipmethod == SIP_INVITE) { 10189 handle_response_invite(p, resp, rest, req, ignore, seqno); 10190 } else if (sipmethod == SIP_CANCEL) { 10191 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 10192 } else if (sipmethod == SIP_MESSAGE) 10193 /* We successfully transmitted a message */ 10194 ast_set_flag(p, SIP_NEEDDESTROY); 10195 else if (sipmethod == SIP_BYE) 10196 /* Ok, we're ready to go */ 10197 ast_set_flag(p, SIP_NEEDDESTROY); 10198 break; 10199 case 401: /* www-auth */ 10200 case 407: 10201 if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) { 10202 char *auth, *auth2; 10203 10204 if (resp == 407) { 10205 auth = "Proxy-Authenticate"; 10206 auth2 = "Proxy-Authorization"; 10207 } else { 10208 auth = "WWW-Authenticate"; 10209 auth2 = "Authorization"; 10210 } 10211 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 10212 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 10213 ast_set_flag(p, SIP_NEEDDESTROY); 10214 } 10215 } else if (sipmethod == SIP_INVITE) { 10216 handle_response_invite(p, resp, rest, req, ignore, seqno); 10217 } 10218 break; 10219 case 481: /* Call leg does not exist */ 10220 if (sipmethod == SIP_INVITE) { 10221 /* Re-invite failed */ 10222 handle_response_invite(p, resp, rest, req, ignore, seqno); 10223 } 10224 break; 10225 default: /* Errors without handlers */ 10226 if ((resp >= 100) && (resp < 200)) { 10227 if (sipmethod == SIP_INVITE && !ignore) /* re-invite */ 10228 sip_cancel_destroy(p); 10229 10230 } 10231 if ((resp >= 300) && (resp < 700)) { 10232 if ((option_verbose > 2) && (resp != 487)) 10233 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)); 10234 switch(resp) { 10235 case 488: /* Not acceptable here - codec error */ 10236 case 603: /* Decline */ 10237 case 500: /* Server error */ 10238 case 503: /* Service Unavailable */ 10239 10240 if (sipmethod == SIP_INVITE && !ignore) { /* re-invite failed */ 10241 sip_cancel_destroy(p); 10242 } 10243 break; 10244 } 10245 } 10246 break; 10247 } 10248 } 10249 }
|
|
handle_response_invite: Handle SIP response in dialogue ---
Definition at line 9633 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(). 09634 { 09635 int outgoing = ast_test_flag(p, SIP_OUTGOING); 09636 09637 if (option_debug > 3) { 09638 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 09639 if (reinvite) 09640 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 09641 else 09642 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 09643 } 09644 09645 if (ast_test_flag(p, SIP_ALREADYGONE)) { /* This call is already gone */ 09646 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 09647 return; 09648 } 09649 09650 /* RFC3261 says we must treat every 1xx response (but not 100) 09651 that we don't recognize as if it was 183. 09652 */ 09653 if ((resp > 100) && 09654 (resp < 200) && 09655 (resp != 180) && 09656 (resp != 183)) 09657 resp = 183; 09658 09659 switch (resp) { 09660 case 100: /* Trying */ 09661 if (!ignore) 09662 sip_cancel_destroy(p); 09663 check_pendings(p); 09664 break; 09665 case 180: /* 180 Ringing */ 09666 if (!ignore) 09667 sip_cancel_destroy(p); 09668 if (!ignore && p->owner) { 09669 ast_queue_control(p->owner, AST_CONTROL_RINGING); 09670 if (p->owner->_state != AST_STATE_UP) 09671 ast_setstate(p->owner, AST_STATE_RINGING); 09672 } 09673 if (find_sdp(req)) { 09674 process_sdp(p, req); 09675 if (!ignore && p->owner) { 09676 /* Queue a progress frame only if we have SDP in 180 */ 09677 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 09678 } 09679 } 09680 ast_set_flag(p, SIP_CAN_BYE); 09681 check_pendings(p); 09682 break; 09683 case 183: /* Session progress */ 09684 if (!ignore) 09685 sip_cancel_destroy(p); 09686 /* Ignore 183 Session progress without SDP */ 09687 if (find_sdp(req)) { 09688 process_sdp(p, req); 09689 if (!ignore && p->owner) { 09690 /* Queue a progress frame */ 09691 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 09692 } 09693 } 09694 ast_set_flag(p, SIP_CAN_BYE); 09695 check_pendings(p); 09696 break; 09697 case 200: /* 200 OK on invite - someone's answering our call */ 09698 if (!ignore) 09699 sip_cancel_destroy(p); 09700 p->authtries = 0; 09701 if (find_sdp(req)) { 09702 process_sdp(p, req); 09703 } 09704 09705 /* Parse contact header for continued conversation */ 09706 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 09707 /* This is important when we have a SIP proxy between us and the phone */ 09708 if (outgoing) { 09709 parse_ok_contact(p, req); 09710 09711 /* Save Record-Route for any later requests we make on this dialogue */ 09712 build_route(p, req, 1); 09713 } 09714 09715 if (!ignore && p->owner) { 09716 if (p->owner->_state != AST_STATE_UP) { 09717 #ifdef OSP_SUPPORT 09718 time(&p->ospstart); 09719 #endif 09720 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 09721 } else { /* RE-invite */ 09722 struct ast_frame af = { AST_FRAME_NULL, }; 09723 ast_queue_frame(p->owner, &af); 09724 } 09725 } else { 09726 /* It's possible we're getting an ACK after we've tried to disconnect 09727 by sending CANCEL */ 09728 /* THIS NEEDS TO BE CHECKED: OEJ */ 09729 if (!ignore) 09730 ast_set_flag(p, SIP_PENDINGBYE); 09731 } 09732 /* If I understand this right, the branch is different for a non-200 ACK only */ 09733 transmit_request(p, SIP_ACK, seqno, 0, 1); 09734 ast_set_flag(p, SIP_CAN_BYE); 09735 check_pendings(p); 09736 break; 09737 case 407: /* Proxy authentication */ 09738 case 401: /* Www auth */ 09739 /* First we ACK */ 09740 transmit_request(p, SIP_ACK, seqno, 0, 0); 09741 if (p->options) 09742 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 09743 09744 /* Then we AUTH */ 09745 p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */ 09746 if (!ignore) { 09747 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 09748 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 09749 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 09750 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 09751 ast_set_flag(p, SIP_NEEDDESTROY); 09752 ast_set_flag(p, SIP_ALREADYGONE); 09753 if (p->owner) 09754 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09755 } 09756 } 09757 break; 09758 case 403: /* Forbidden */ 09759 /* First we ACK */ 09760 transmit_request(p, SIP_ACK, seqno, 0, 0); 09761 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for INVITE to '%s'\n", get_header(&p->initreq, "From")); 09762 if (!ignore && p->owner) 09763 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09764 ast_set_flag(p, SIP_NEEDDESTROY); 09765 ast_set_flag(p, SIP_ALREADYGONE); 09766 break; 09767 case 404: /* Not found */ 09768 transmit_request(p, SIP_ACK, seqno, 0, 0); 09769 if (p->owner && !ignore) 09770 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09771 ast_set_flag(p, SIP_ALREADYGONE); 09772 break; 09773 case 481: /* Call leg does not exist */ 09774 /* Could be REFER or INVITE */ 09775 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 09776 transmit_request(p, SIP_ACK, seqno, 0, 0); 09777 break; 09778 case 491: /* Pending */ 09779 /* we have to wait a while, then retransmit */ 09780 /* Transmission is rescheduled, so everything should be taken care of. 09781 We should support the retry-after at some point */ 09782 break; 09783 case 501: /* Not implemented */ 09784 if (p->owner) 09785 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09786 break; 09787 } 09788 }
|
|
handle_response_peerpoke: Handle qualification responses (OPTIONS)
Definition at line 9907 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(). 09908 { 09909 struct sip_peer *peer; 09910 int pingtime; 09911 struct timeval tv; 09912 09913 if (resp != 100) { 09914 int statechanged = 0; 09915 int newstate = 0; 09916 peer = p->peerpoke; 09917 gettimeofday(&tv, NULL); 09918 pingtime = ast_tvdiff_ms(tv, peer->ps); 09919 if (pingtime < 1) 09920 pingtime = 1; 09921 if ((peer->lastms < 0) || (peer->lastms > peer->maxms)) { 09922 if (pingtime <= peer->maxms) { 09923 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! (%dms / %dms)\n", peer->name, pingtime, peer->maxms); 09924 statechanged = 1; 09925 newstate = 1; 09926 } 09927 } else if ((peer->lastms > 0) && (peer->lastms <= peer->maxms)) { 09928 if (pingtime > peer->maxms) { 09929 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED! (%dms / %dms)\n", peer->name, pingtime, peer->maxms); 09930 statechanged = 1; 09931 newstate = 2; 09932 } 09933 } 09934 if (!peer->lastms) 09935 statechanged = 1; 09936 peer->lastms = pingtime; 09937 peer->call = NULL; 09938 if (statechanged) { 09939 ast_device_state_changed("SIP/%s", peer->name); 09940 if (newstate == 2) { 09941 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, pingtime); 09942 } else { 09943 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, pingtime); 09944 } 09945 } 09946 09947 if (peer->pokeexpire > -1) 09948 ast_sched_del(sched, peer->pokeexpire); 09949 if (sipmethod == SIP_INVITE) /* Does this really happen? */ 09950 transmit_request(p, SIP_ACK, seqno, 0, 0); 09951 ast_set_flag(p, SIP_NEEDDESTROY); 09952 09953 /* Try again eventually */ 09954 if ((peer->lastms < 0) || (peer->lastms > peer->maxms)) 09955 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 09956 else 09957 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_OK, sip_poke_peer_s, peer); 09958 } 09959 return 1; 09960 }
|
|
handle_response_register: Handle responses on REGISTER to services ---
Definition at line 9791 of file chan_sip.c. References __get_header(), ast_log(), ast_sched_del(), ast_set_flag, ast_strlen_zero(), sip_pvt::authtries, sip_registry::call, sip_registry::contact, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, get_header(), global_regattempts_max, sip_registry::hostname, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), MAX_AUTHTRIES, sip_pvt::our_contact, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, sip_scheddestroy(), sip_registry::timeout, and sip_registry::username. Referenced by handle_response(). 09792 { 09793 int expires, expires_ms; 09794 struct sip_registry *r; 09795 r=p->registry; 09796 09797 switch (resp) { 09798 case 401: /* Unauthorized */ 09799 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 09800 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 09801 ast_set_flag(p, SIP_NEEDDESTROY); 09802 } 09803 break; 09804 case 403: /* Forbidden */ 09805 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 09806 if (global_regattempts_max) 09807 p->registry->regattempts = global_regattempts_max+1; 09808 ast_sched_del(sched, r->timeout); 09809 ast_set_flag(p, SIP_NEEDDESTROY); 09810 break; 09811 case 404: /* Not found */ 09812 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 09813 if (global_regattempts_max) 09814 p->registry->regattempts = global_regattempts_max+1; 09815 ast_set_flag(p, SIP_NEEDDESTROY); 09816 r->call = NULL; 09817 ast_sched_del(sched, r->timeout); 09818 break; 09819 case 407: /* Proxy auth */ 09820 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 09821 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 09822 ast_set_flag(p, SIP_NEEDDESTROY); 09823 } 09824 break; 09825 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 09826 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 09827 if (global_regattempts_max) 09828 p->registry->regattempts = global_regattempts_max+1; 09829 ast_set_flag(p, SIP_NEEDDESTROY); 09830 r->call = NULL; 09831 ast_sched_del(sched, r->timeout); 09832 break; 09833 case 200: /* 200 OK */ 09834 if (!r) { 09835 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 09836 ast_set_flag(p, SIP_NEEDDESTROY); 09837 return 0; 09838 } 09839 09840 r->regstate=REG_STATE_REGISTERED; 09841 manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 09842 r->regattempts = 0; 09843 ast_log(LOG_DEBUG, "Registration successful\n"); 09844 if (r->timeout > -1) { 09845 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 09846 ast_sched_del(sched, r->timeout); 09847 } 09848 r->timeout=-1; 09849 r->call = NULL; 09850 p->registry = NULL; 09851 /* Let this one hang around until we have all the responses */ 09852 sip_scheddestroy(p, 32000); 09853 /* ast_set_flag(p, SIP_NEEDDESTROY); */ 09854 09855 /* set us up for re-registering */ 09856 /* figure out how long we got registered for */ 09857 if (r->expire > -1) 09858 ast_sched_del(sched, r->expire); 09859 /* according to section 6.13 of RFC, contact headers override 09860 expires headers, so check those first */ 09861 expires = 0; 09862 if (!ast_strlen_zero(get_header(req, "Contact"))) { 09863 char *contact = NULL; 09864 char *tmptmp = NULL; 09865 int start = 0; 09866 for(;;) { 09867 contact = __get_header(req, "Contact", &start); 09868 /* this loop ensures we get a contact header about our register request */ 09869 if(!ast_strlen_zero(contact)) { 09870 if( (tmptmp=strstr(contact, p->our_contact))) { 09871 contact=tmptmp; 09872 break; 09873 } 09874 } else 09875 break; 09876 } 09877 tmptmp = strcasestr(contact, "expires="); 09878 if (tmptmp) { 09879 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 09880 expires = 0; 09881 } 09882 09883 } 09884 if (!expires) 09885 expires=atoi(get_header(req, "expires")); 09886 if (!expires) 09887 expires=default_expiry; 09888 09889 expires_ms = expires * 1000; 09890 if (expires <= EXPIRY_GUARD_LIMIT) 09891 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 09892 else 09893 expires_ms -= EXPIRY_GUARD_SECS * 1000; 09894 if (sipdebug) 09895 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 09896 09897 r->refresh= (int) expires_ms / 1000; 09898 09899 /* Schedule re-registration before we expire */ 09900 r->expire=ast_sched_add(sched, expires_ms, sip_reregister, r); 09901 ASTOBJ_UNREF(r, sip_registry_destroy); 09902 } 09903 return 1; 09904 }
|
|
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 2366 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(). 02367 { 02368 switch(cause) 02369 { 02370 case AST_CAUSE_UNALLOCATED: /* 1 */ 02371 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 02372 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 02373 return "404 Not Found"; 02374 case AST_CAUSE_CONGESTION: /* 34 */ 02375 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 02376 return "503 Service Unavailable"; 02377 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 02378 return "408 Request Timeout"; 02379 case AST_CAUSE_NO_ANSWER: /* 19 */ 02380 return "480 Temporarily unavailable"; 02381 case AST_CAUSE_CALL_REJECTED: /* 21 */ 02382 return "403 Forbidden"; 02383 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 02384 return "410 Gone"; 02385 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 02386 return "480 Temporarily unavailable"; 02387 case AST_CAUSE_INVALID_NUMBER_FORMAT: 02388 return "484 Address incomplete"; 02389 case AST_CAUSE_USER_BUSY: 02390 return "486 Busy here"; 02391 case AST_CAUSE_FAILURE: 02392 return "500 Server internal failure"; 02393 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 02394 return "501 Not Implemented"; 02395 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 02396 return "503 Service Unavailable"; 02397 /* Used in chan_iax2 */ 02398 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 02399 return "502 Bad Gateway"; 02400 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 02401 return "488 Not Acceptable Here"; 02402 02403 case AST_CAUSE_NOTDEFINED: 02404 default: 02405 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 02406 return NULL; 02407 } 02408 02409 /* Never reached */ 02410 return 0; 02411 }
|
|
hangup_sip2cause: Convert SIP hangup causes to Asterisk hangup causes ---
Definition at line 2297 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(). 02298 { 02299 /* Possible values taken from causes.h */ 02300 02301 switch(cause) { 02302 case 603: /* Declined */ 02303 case 403: /* Not found */ 02304 case 487: /* Call cancelled */ 02305 return AST_CAUSE_CALL_REJECTED; 02306 case 404: /* Not found */ 02307 return AST_CAUSE_UNALLOCATED; 02308 case 408: /* No reaction */ 02309 return AST_CAUSE_NO_USER_RESPONSE; 02310 case 480: /* No answer */ 02311 return AST_CAUSE_FAILURE; 02312 case 483: /* Too many hops */ 02313 return AST_CAUSE_NO_ANSWER; 02314 case 486: /* Busy everywhere */ 02315 return AST_CAUSE_BUSY; 02316 case 488: /* No codecs approved */ 02317 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 02318 case 500: /* Server internal failure */ 02319 return AST_CAUSE_FAILURE; 02320 case 501: /* Call rejected */ 02321 return AST_CAUSE_FACILITY_REJECTED; 02322 case 502: 02323 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 02324 case 503: /* Service unavailable */ 02325 return AST_CAUSE_CONGESTION; 02326 default: 02327 return AST_CAUSE_NORMAL; 02328 } 02329 /* Never reached */ 02330 return 0; 02331 }
|
|
init_req: Initialize SIP request ---
Definition at line 4073 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. 04074 { 04075 /* Initialize a response */ 04076 if (req->headers || req->len) { 04077 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 04078 return -1; 04079 } 04080 req->header[req->headers] = req->data + req->len; 04081 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 04082 req->len += strlen(req->header[req->headers]); 04083 req->headers++; 04084 req->method = sipmethod; 04085 return 0; 04086 }
|
|
init_resp: Initialize SIP response, based on SIP request ---
Definition at line 4057 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. 04058 { 04059 /* Initialize a response */ 04060 if (req->headers || req->len) { 04061 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 04062 return -1; 04063 } 04064 req->method = SIP_RESPONSE; 04065 req->header[req->headers] = req->data + req->len; 04066 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "SIP/2.0 %s\r\n", resp); 04067 req->len += strlen(req->header[req->headers]); 04068 req->headers++; 04069 return 0; 04070 }
|
|
initreqprep: Initiate new SIP request to peer/user ---
Definition at line 4863 of file chan_sip.c. References AST_DIGIT_ANYNUM, ast_test_flag, n, SIP_USEREQPHONE, and sip_pvt::username. Referenced by sip_notify(), transmit_invite(), and transmit_notify_with_mwi(). 04864 { 04865 char invite_buf[256] = ""; 04866 char *invite = invite_buf; 04867 size_t invite_max = sizeof(invite_buf); 04868 char from[256]; 04869 char to[256]; 04870 char tmp[BUFSIZ/2]; 04871 char tmp2[BUFSIZ/2]; 04872 char iabuf[INET_ADDRSTRLEN]; 04873 char *l = NULL, *n = NULL; 04874 int x; 04875 char urioptions[256]=""; 04876 04877 if (ast_test_flag(p, SIP_USEREQPHONE)) { 04878 char onlydigits = 1; 04879 x=0; 04880 04881 /* Test p->username against allowed characters in AST_DIGIT_ANY 04882 If it matches the allowed characters list, then sipuser = ";user=phone" 04883 If not, then sipuser = "" 04884 */ 04885 /* + is allowed in first position in a tel: uri */ 04886 if (p->username && p->username[0] == '+') 04887 x=1; 04888 04889 for (; x < strlen(p->username); x++) { 04890 if (!strchr(AST_DIGIT_ANYNUM, p->username[x])) { 04891 onlydigits = 0; 04892 break; 04893 } 04894 } 04895 04896 /* If we have only digits, add ;user=phone to the uri */ 04897 if (onlydigits) 04898 strcpy(urioptions, ";user=phone"); 04899 } 04900 04901 04902 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 04903 04904 if (p->owner) { 04905 l = p->owner->cid.cid_num; 04906 n = p->owner->cid.cid_name; 04907 } 04908 /* if we are not sending RPID and user wants his callerid restricted */ 04909 if (!ast_test_flag(p, SIP_SENDRPID) && ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 04910 l = CALLERID_UNKNOWN; 04911 n = l; 04912 } 04913 if (ast_strlen_zero(l)) 04914 l = default_callerid; 04915 if (ast_strlen_zero(n)) 04916 n = l; 04917 /* Allow user to be overridden */ 04918 if (!ast_strlen_zero(p->fromuser)) 04919 l = p->fromuser; 04920 else /* Save for any further attempts */ 04921 ast_copy_string(p->fromuser, l, sizeof(p->fromuser)); 04922 04923 /* Allow user to be overridden */ 04924 if (!ast_strlen_zero(p->fromname)) 04925 n = p->fromname; 04926 else /* Save for any further attempts */ 04927 ast_copy_string(p->fromname, n, sizeof(p->fromname)); 04928 04929 if (pedanticsipchecking) { 04930 ast_uri_encode(n, tmp, sizeof(tmp), 0); 04931 n = tmp; 04932 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 04933 l = tmp2; 04934 } 04935 04936 if ((ourport != 5060) && ast_strlen_zero(p->fromdomain)) /* Needs to be 5060 */ 04937 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); 04938 else 04939 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); 04940 04941 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 04942 if (!ast_strlen_zero(p->fullcontact)) { 04943 /* If we have full contact, trust it */ 04944 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 04945 } else { 04946 /* Otherwise, use the username while waiting for registration */ 04947 ast_build_string(&invite, &invite_max, "sip:"); 04948 if (!ast_strlen_zero(p->username)) { 04949 n = p->username; 04950 if (pedanticsipchecking) { 04951 ast_uri_encode(n, tmp, sizeof(tmp), 0); 04952 n = tmp; 04953 } 04954 ast_build_string(&invite, &invite_max, "%s@", n); 04955 } 04956 ast_build_string(&invite, &invite_max, "%s", p->tohost); 04957 if (ntohs(p->sa.sin_port) != 5060) /* Needs to be 5060 */ 04958 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 04959 ast_build_string(&invite, &invite_max, "%s", urioptions); 04960 } 04961 04962 /* If custom URI options have been provided, append them */ 04963 if (p->options && p->options->uri_options) 04964 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 04965 04966 ast_copy_string(p->uri, invite_buf, sizeof(p->uri)); 04967 04968 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 04969 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 04970 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag); 04971 } else if (p->options && p->options->vxml_url) { 04972 /* If there is a VXML URL append it to the SIP URL */ 04973 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 04974 } else { 04975 snprintf(to, sizeof(to), "<%s>", p->uri); 04976 } 04977 04978 memset(req, 0, sizeof(struct sip_request)); 04979 init_req(req, sipmethod, p->uri); 04980 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 04981 04982 add_header(req, "Via", p->via); 04983 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 04984 * OTOH, then we won't have anything in p->route anyway */ 04985 /* Build Remote Party-ID and From */ 04986 if (ast_test_flag(p, SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 04987 build_rpid(p); 04988 add_header(req, "From", p->rpid_from); 04989 } else { 04990 add_header(req, "From", from); 04991 } 04992 add_header(req, "To", to); 04993 ast_copy_string(p->exten, l, sizeof(p->exten)); 04994 build_contact(p); 04995 add_header(req, "Contact", p->our_contact); 04996 add_header(req, "Call-ID", p->callid); 04997 add_header(req, "CSeq", tmp); 04998 add_header(req, "User-Agent", default_useragent); 04999 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 05000 if (p->rpid) 05001 add_header(req, "Remote-Party-ID", p->rpid); 05002 }
|
|
insecure2str: Convert Insecure setting to printable string ---
Definition at line 7810 of file chan_sip.c. Referenced by _sip_show_peer(). 07811 { 07812 if (port && invite) 07813 return "port,invite"; 07814 else if (port) 07815 return "port"; 07816 else if (invite) 07817 return "invite"; 07818 else 07819 return "no"; 07820 }
|
|
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 13576 of file chan_sip.c. References ASTERISK_GPL_KEY. 13577 { 13578 return ASTERISK_GPL_KEY; 13579 }
|
|
list_route: List all routes - mostly for debugging ---
Definition at line 6115 of file chan_sip.c. References ast_verbose(), sip_route::hop, and sip_route::next. 06116 { 06117 if (!route) { 06118 ast_verbose("list_route: no route\n"); 06119 return; 06120 } 06121 while (route) { 06122 ast_verbose("list_route: hop: <%s>\n", route->hop); 06123 route = route->next; 06124 } 06125 }
|
|
|
lws2sws: Parse multiline SIP headers into one header
Definition at line 3331 of file chan_sip.c. References t. Referenced by sipsock_read(). 03332 { 03333 int h = 0, t = 0; 03334 int lws = 0; 03335 03336 for (; h < len;) { 03337 /* Eliminate all CRs */ 03338 if (msgbuf[h] == '\r') { 03339 h++; 03340 continue; 03341 } 03342 /* Check for end-of-line */ 03343 if (msgbuf[h] == '\n') { 03344 /* Check for end-of-message */ 03345 if (h + 1 == len) 03346 break; 03347 /* Check for a continuation line */ 03348 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 03349 /* Merge continuation line */ 03350 h++; 03351 continue; 03352 } 03353 /* Propagate LF and start new line */ 03354 msgbuf[t++] = msgbuf[h++]; 03355 lws = 0; 03356 continue; 03357 } 03358 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 03359 if (lws) { 03360 h++; 03361 continue; 03362 } 03363 msgbuf[t++] = msgbuf[h++]; 03364 lws = 1; 03365 continue; 03366 } 03367 msgbuf[t++] = msgbuf[h++]; 03368 if (lws) 03369 lws = 0; 03370 } 03371 msgbuf[t] = '\0'; 03372 return t; 03373 }
|
|
Definition at line 3075 of file chan_sip.c. References thread_safe_rand(). Referenced by handle_request_invite(), handle_request_subscribe(), sip_alloc(), transmit_register(), and transmit_response_using_temp(). 03076 { 03077 snprintf(tagbuf, len, "as%08x", thread_safe_rand()); 03078 }
|
|
manager_sip_show_peer: Show SIP peers in the manager API ---
Definition at line 8030 of file chan_sip.c. References _sip_show_peer(), ast_cli(), ast_strlen_zero(), astman_get_header(), astman_send_error(), and s. Referenced by load_module(). 08031 { 08032 char *id = astman_get_header(m,"ActionID"); 08033 char *a[4]; 08034 char *peer; 08035 int ret; 08036 08037 peer = astman_get_header(m,"Peer"); 08038 if (ast_strlen_zero(peer)) { 08039 astman_send_error(s, m, "Peer: <name> missing.\n"); 08040 return 0; 08041 } 08042 a[0] = "sip"; 08043 a[1] = "show"; 08044 a[2] = "peer"; 08045 a[3] = peer; 08046 08047 if (!ast_strlen_zero(id)) 08048 ast_cli(s->fd, "ActionID: %s\r\n",id); 08049 ret = _sip_show_peer(1, s->fd, s, m, 4, a ); 08050 ast_cli( s->fd, "\r\n\r\n" ); 08051 return ret; 08052 }
|
|
manager_sip_show_peers: Show SIP peers in the manager API ---
Definition at line 7611 of file chan_sip.c. References _sip_show_peers(), ast_cli(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), s, and total. Referenced by load_module(). 07612 { 07613 char *id = astman_get_header(m,"ActionID"); 07614 char *a[] = { "sip", "show", "peers" }; 07615 char idtext[256] = ""; 07616 int total = 0; 07617 07618 if (!ast_strlen_zero(id)) 07619 snprintf(idtext,256,"ActionID: %s\r\n",id); 07620 07621 astman_send_ack(s, m, "Peer status list will follow"); 07622 /* List the peers in separate manager events */ 07623 _sip_show_peers(s->fd, &total, s, m, 3, a); 07624 /* Send final confirmation */ 07625 ast_cli(s->fd, 07626 "Event: PeerlistComplete\r\n" 07627 "ListItems: %d\r\n" 07628 "%s" 07629 "\r\n", total, idtext); 07630 return 0; 07631 }
|
|
nat2str: Convert NAT setting to text string
Definition at line 7513 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(), and sip_show_settings(). 07514 { 07515 switch(nat) { 07516 case SIP_NAT_NEVER: 07517 return "No"; 07518 case SIP_NAT_ROUTE: 07519 return "Route"; 07520 case SIP_NAT_ALWAYS: 07521 return "Always"; 07522 case SIP_NAT_RFC3581: 07523 return "RFC3581"; 07524 default: 07525 return "Unknown"; 07526 } 07527 }
|
|
parse_copy: Copy SIP request, parse it
Definition at line 1474 of file chan_sip.c. References sip_request::data, sip_request::len, and parse_request(). Referenced by send_request(), and send_response(). 01475 { 01476 memset(dst, 0, sizeof(*dst)); 01477 memcpy(dst->data, src->data, sizeof(dst->data)); 01478 dst->len = src->len; 01479 parse_request(dst); 01480 }
|
|
parse_moved_contact: Parse 302 Moved temporalily response
Definition at line 9578 of file chan_sip.c. References ast_log(), ast_test_flag, ast_channel::call_forward, get_header(), get_in_brackets(), LOG_DEBUG, sip_pvt::owner, s, and SIP_PROMISCREDIR. Referenced by handle_response(). 09579 { 09580 char tmp[256]; 09581 char *s, *e; 09582 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 09583 s = get_in_brackets(tmp); 09584 e = strchr(s, ';'); 09585 if (e) 09586 *e = '\0'; 09587 if (ast_test_flag(p, SIP_PROMISCREDIR)) { 09588 if (!strncasecmp(s, "sip:", 4)) 09589 s += 4; 09590 e = strchr(s, '/'); 09591 if (e) 09592 *e = '\0'; 09593 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 09594 if (p->owner) 09595 snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "SIP/%s", s); 09596 } else { 09597 e = strchr(tmp, '@'); 09598 if (e) 09599 *e = '\0'; 09600 e = strchr(tmp, '/'); 09601 if (e) 09602 *e = '\0'; 09603 if (!strncasecmp(s, "sip:", 4)) 09604 s += 4; 09605 ast_log(LOG_DEBUG, "Found 302 Redirect to extension '%s'\n", s); 09606 if (p->owner) 09607 ast_copy_string(p->owner->call_forward, s, sizeof(p->owner->call_forward)); 09608 } 09609 }
|
|
parse_ok_contact: Parse contact header for 200 OK on INVITE ---
Definition at line 5876 of file chan_sip.c. References ahp, ast_gethostbyname(), ast_log(), ast_test_flag, DEFAULT_SIP_PORT, sip_pvt::fullcontact, get_header(), get_in_brackets(), hp, LOG_NOTICE, LOG_WARNING, sip_pvt::okcontacturi, sip_pvt::recv, sip_pvt::sa, SIP_LEN_CONTACT, SIP_NAT, and SIP_NAT_ROUTE. Referenced by handle_response_invite(). 05877 { 05878 char contact[SIP_LEN_CONTACT]; 05879 char *c, *n, *pt; 05880 int port; 05881 struct hostent *hp; 05882 struct ast_hostent ahp; 05883 struct sockaddr_in oldsin; 05884 05885 /* Look for brackets */ 05886 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 05887 c = get_in_brackets(contact); 05888 05889 /* Save full contact to call pvt for later bye or re-invite */ 05890 ast_copy_string(pvt->fullcontact, c, sizeof(pvt->fullcontact)); 05891 05892 /* Save URI for later ACKs, BYE or RE-invites */ 05893 ast_copy_string(pvt->okcontacturi, c, sizeof(pvt->okcontacturi)); 05894 05895 /* Make sure it's a SIP URL */ 05896 if (strncasecmp(c, "sip:", 4)) { 05897 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c); 05898 } else 05899 c += 4; 05900 05901 /* Ditch arguments */ 05902 n = strchr(c, ';'); 05903 if (n) 05904 *n = '\0'; 05905 05906 /* Grab host */ 05907 n = strchr(c, '@'); 05908 if (!n) { 05909 n = c; 05910 c = NULL; 05911 } else { 05912 *n = '\0'; 05913 n++; 05914 } 05915 pt = strchr(n, ':'); 05916 if (pt) { 05917 *pt = '\0'; 05918 pt++; 05919 port = atoi(pt); 05920 } else 05921 port = DEFAULT_SIP_PORT; 05922 05923 memcpy(&oldsin, &pvt->sa, sizeof(oldsin)); 05924 05925 if (!(ast_test_flag(pvt, SIP_NAT) & SIP_NAT_ROUTE)) { 05926 /* XXX This could block for a long time XXX */ 05927 /* We should only do this if it's a name, not an IP */ 05928 hp = ast_gethostbyname(n, &ahp); 05929 if (!hp) { 05930 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 05931 return -1; 05932 } 05933 pvt->sa.sin_family = AF_INET; 05934 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 05935 pvt->sa.sin_port = htons(port); 05936 } else { 05937 /* Don't trust the contact field. Just use what they came to us 05938 with. */ 05939 memcpy(&pvt->sa, &pvt->recv, sizeof(pvt->sa)); 05940 } 05941 return 0; 05942 }
|
|
parse_register_contact: Parse contact header and save registration ---
Definition at line 5952 of file chan_sip.c. References sip_peer::addr, ahp, 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, 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(). 05953 { 05954 char contact[BUFSIZ]; 05955 char data[BUFSIZ]; 05956 char iabuf[INET_ADDRSTRLEN]; 05957 char *expires = get_header(req, "Expires"); 05958 int expiry = atoi(expires); 05959 char *c, *n, *pt; 05960 int port; 05961 char *useragent; 05962 struct hostent *hp; 05963 struct ast_hostent ahp; 05964 struct sockaddr_in oldsin; 05965 05966 if (ast_strlen_zero(expires)) { /* No expires header */ 05967 expires = strcasestr(get_header(req, "Contact"), ";expires="); 05968 if (expires) { 05969 char *ptr; 05970 if ((ptr = strchr(expires, ';'))) 05971 *ptr = '\0'; 05972 if (sscanf(expires + 9, "%d", &expiry) != 1) 05973 expiry = default_expiry; 05974 } else { 05975 /* Nothing has been specified */ 05976 expiry = default_expiry; 05977 } 05978 } 05979 /* Look for brackets */ 05980 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 05981 if (strchr(contact, '<') == NULL) { /* No <, check for ; and strip it */ 05982 char *ptr = strchr(contact, ';'); /* This is Header options, not URI options */ 05983 if (ptr) 05984 *ptr = '\0'; 05985 } 05986 c = get_in_brackets(contact); 05987 05988 /* if they did not specify Contact: or Expires:, they are querying 05989 what we currently have stored as their contact address, so return 05990 it 05991 */ 05992 if (ast_strlen_zero(c) && ast_strlen_zero(expires)) { 05993 /* If we have an active registration, tell them when the registration is going to expire */ 05994 if ((p->expire > -1) && !ast_strlen_zero(p->fullcontact)) { 05995 pvt->expiry = ast_sched_when(sched, p->expire); 05996 } 05997 return PARSE_REGISTER_QUERY; 05998 } else if (!strcasecmp(c, "*") || !expiry) { /* Unregister this peer */ 05999 /* This means remove all registrations and return OK */ 06000 memset(&p->addr, 0, sizeof(p->addr)); 06001 if (p->expire > -1) 06002 ast_sched_del(sched, p->expire); 06003 p->expire = -1; 06004 06005 destroy_association(p); 06006 06007 register_peer_exten(p, 0); 06008 p->fullcontact[0] = '\0'; 06009 p->useragent[0] = '\0'; 06010 p->sipoptions = 0; 06011 p->lastms = 0; 06012 06013 if (option_verbose > 2) 06014 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", p->name); 06015 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", p->name); 06016 return PARSE_REGISTER_UPDATE; 06017 } 06018 ast_copy_string(p->fullcontact, c, sizeof(p->fullcontact)); 06019 /* For the 200 OK, we should use the received contact */ 06020 snprintf(pvt->our_contact, sizeof(pvt->our_contact) - 1, "<%s>", c); 06021 /* Make sure it's a SIP URL */ 06022 if (strncasecmp(c, "sip:", 4)) { 06023 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c); 06024 } else 06025 c += 4; 06026 /* Ditch q */ 06027 n = strchr(c, ';'); 06028 if (n) { 06029 *n = '\0'; 06030 } 06031 /* Grab host */ 06032 n = strchr(c, '@'); 06033 if (!n) { 06034 n = c; 06035 c = NULL; 06036 } else { 06037 *n = '\0'; 06038 n++; 06039 } 06040 pt = strchr(n, ':'); 06041 if (pt) { 06042 *pt = '\0'; 06043 pt++; 06044 port = atoi(pt); 06045 } else 06046 port = DEFAULT_SIP_PORT; 06047 memcpy(&oldsin, &p->addr, sizeof(oldsin)); 06048 if (!(ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)) { 06049 /* XXX This could block for a long time XXX */ 06050 hp = ast_gethostbyname(n, &ahp); 06051 if (!hp) { 06052 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 06053 return PARSE_REGISTER_FAILED; 06054 } 06055 p->addr.sin_family = AF_INET; 06056 memcpy(&p->addr.sin_addr, hp->h_addr, sizeof(p->addr.sin_addr)); 06057 p->addr.sin_port = htons(port); 06058 } else { 06059 /* Don't trust the contact field. Just use what they came to us 06060 with */ 06061 memcpy(&p->addr, &pvt->recv, sizeof(p->addr)); 06062 } 06063 06064 if (c) /* Overwrite the default username from config at registration */ 06065 ast_copy_string(p->username, c, sizeof(p->username)); 06066 else 06067 p->username[0] = '\0'; 06068 06069 if (p->expire > -1) 06070 ast_sched_del(sched, p->expire); 06071 if ((expiry < 1) || (expiry > max_expiry)) 06072 expiry = max_expiry; 06073 if (!ast_test_flag(p, SIP_REALTIME)) 06074 p->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, p); 06075 else 06076 p->expire = -1; 06077 pvt->expiry = expiry; 06078 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); 06079 if (!ast_test_flag((&p->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 06080 ast_db_put("SIP/Registry", p->name, data); 06081 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", p->name); 06082 if (inaddrcmp(&p->addr, &oldsin)) { 06083 sip_poke_peer(p); 06084 if (option_verbose > 2) 06085 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); 06086 register_peer_exten(p, 1); 06087 } 06088 06089 /* Save SIP options profile */ 06090 p->sipoptions = pvt->sipoptions; 06091 06092 /* Save User agent */ 06093 useragent = get_header(req, "User-Agent"); 06094 if (useragent && strcasecmp(useragent, p->useragent)) { 06095 ast_copy_string(p->useragent, useragent, sizeof(p->useragent)); 06096 if (option_verbose > 3) { 06097 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n",p->useragent,p->name); 06098 } 06099 } 06100 return PARSE_REGISTER_UPDATE; 06101 }
|
|
parse_request: Parse a SIP message ----
Definition at line 3376 of file chan_sip.c. References ast_log(), ast_strlen_zero(), sip_request::data, determine_firstline_parts(), sip_request::header, sip_request::headers, sip_request::line, sip_request::lines, LOG_DEBUG, LOG_WARNING, option_debug, SIP_MAX_HEADERS, SIP_MAX_LINES, and sipdebug. Referenced by parse_copy(), sipsock_read(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_sip_request(). 03377 { 03378 /* Divide fields by NULL's */ 03379 char *c; 03380 int f = 0; 03381 03382 c = req->data; 03383 03384 /* First header starts immediately */ 03385 req->header[f] = c; 03386 while(*c) { 03387 if (*c == '\n') { 03388 /* We've got a new header */ 03389 *c = 0; 03390 03391 if (sipdebug && option_debug > 3) 03392 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 03393 if (ast_strlen_zero(req->header[f])) { 03394 /* Line by itself means we're now in content */ 03395 c++; 03396 break; 03397 } 03398 if (f >= SIP_MAX_HEADERS - 1) { 03399 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 03400 } else 03401 f++; 03402 req->header[f] = c + 1; 03403 } else if (*c == '\r') { 03404 /* Ignore but eliminate \r's */ 03405 *c = 0; 03406 } 03407 c++; 03408 } 03409 /* Check for last header */ 03410 if (!ast_strlen_zero(req->header[f])) { 03411 if (sipdebug && option_debug > 3) 03412 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 03413 f++; 03414 } 03415 req->headers = f; 03416 /* Now we process any mime content */ 03417 f = 0; 03418 req->line[f] = c; 03419 while(*c) { 03420 if (*c == '\n') { 03421 /* We've got a new line */ 03422 *c = 0; 03423 if (sipdebug && option_debug > 3) 03424 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 03425 if (f >= SIP_MAX_LINES - 1) { 03426 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 03427 } else 03428 f++; 03429 req->line[f] = c + 1; 03430 } else if (*c == '\r') { 03431 /* Ignore and eliminate \r's */ 03432 *c = 0; 03433 } 03434 c++; 03435 } 03436 /* Check for last line */ 03437 if (!ast_strlen_zero(req->line[f])) 03438 f++; 03439 req->lines = f; 03440 if (*c) 03441 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 03442 /* Split up the first line parts */ 03443 determine_firstline_parts(req); 03444 }
|
|
parse_sip_options: Parse supported header in incoming packet
Definition at line 1003 of file chan_sip.c. References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_DEBUG, option_debug, sip_options, and text. Referenced by handle_request_invite(). 01004 { 01005 char *next = NULL; 01006 char *sep = NULL; 01007 char *temp = ast_strdupa(supported); 01008 int i; 01009 unsigned int profile = 0; 01010 01011 if (ast_strlen_zero(supported) ) 01012 return 0; 01013 01014 if (option_debug > 2 && sipdebug) 01015 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01016 01017 next = temp; 01018 while (next) { 01019 char res=0; 01020 if ( (sep = strchr(next, ',')) != NULL) { 01021 *sep = '\0'; 01022 sep++; 01023 } 01024 while (*next == ' ') /* Skip spaces */ 01025 next++; 01026 if (option_debug > 2 && sipdebug) 01027 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01028 for (i=0; (i < (sizeof(sip_options) / sizeof(sip_options[0]))) && !res; i++) { 01029 if (!strcasecmp(next, sip_options[i].text)) { 01030 profile |= sip_options[i].id; 01031 res = 1; 01032 if (option_debug > 2 && sipdebug) 01033 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01034 } 01035 } 01036 if (!res) 01037 if (option_debug > 2 && sipdebug) 01038 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01039 next = sep; 01040 } 01041 if (pvt) { 01042 pvt->sipoptions = profile; 01043 if (option_debug) 01044 ast_log(LOG_DEBUG, "* SIP extension value: %d for call %s\n", profile, pvt->callid); 01045 } 01046 return profile; 01047 }
|
|
peer_status: Report Peer status in character string
Definition at line 7531 of file chan_sip.c. References sip_peer::lastms, and sip_peer::maxms. 07532 { 07533 int res = 0; 07534 if (peer->maxms) { 07535 if (peer->lastms < 0) { 07536 ast_copy_string(status, "UNREACHABLE", statuslen); 07537 } else if (peer->lastms > peer->maxms) { 07538 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 07539 res = 1; 07540 } else if (peer->lastms) { 07541 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 07542 res = 1; 07543 } else { 07544 ast_copy_string(status, "UNKNOWN", statuslen); 07545 } 07546 } else { 07547 ast_copy_string(status, "Unmonitored", statuslen); 07548 /* Checking if port is 0 */ 07549 res = -1; 07550 } 07551 return res; 07552 }
|
|
print_codec_to_cli: Print codec list from preference to CLI/manager
Definition at line 7970 of file chan_sip.c. References ast_cli(), ast_codec_pref_index(), and ast_getformatname(). Referenced by _sip_show_peer(), and sip_show_settings(). 07971 { 07972 int x, codec; 07973 07974 for(x = 0; x < 32 ; x++) { 07975 codec = ast_codec_pref_index(pref, x); 07976 if (!codec) 07977 break; 07978 ast_cli(fd, "%s", ast_getformatname(codec)); 07979 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 07980 ast_cli(fd, ","); 07981 } 07982 if (!x) 07983 ast_cli(fd, "none"); 07984 }
|
|
print_group: Print call group and pickup group ---
Definition at line 7787 of file chan_sip.c. References ast_cli(), and ast_print_group(). Referenced by _sip_show_peer(), and sip_show_user(). 07788 { 07789 char buf[256]; 07790 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 07791 }
|
|
process_sdp: Process SIP SDP and activate RTP channels---
Definition at line 3509 of file chan_sip.c. References ahp, 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_pvt::capability, sip_request::data, debug, EVENT_FLAG_CALL, get_sdp(), get_sdp_iterate(), host, hp, sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), ast_channel::name, ast_channel::nativeformats, noncodeccapability, sip_pvt::noncodeccapability, sip_pvt::owner, sip_pvt::peercapability, portno, sip_pvt::prefs, ast_channel::readformat, sip_pvt::rtp, sdpLineNum_iterator_init(), SIP_CALL_ONHOLD, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_NOVIDEO, ast_channel::uniqueid, sip_pvt::vrtp, and ast_channel::writeformat. 03510 { 03511 char *m; 03512 char *c; 03513 char *a; 03514 char host[258]; 03515 char iabuf[INET_ADDRSTRLEN]; 03516 int len = -1; 03517 int portno = -1; 03518 int vportno = -1; 03519 int peercapability, peernoncodeccapability; 03520 int vpeercapability=0, vpeernoncodeccapability=0; 03521 struct sockaddr_in sin; 03522 char *codecs; 03523 struct hostent *hp; 03524 struct ast_hostent ahp; 03525 int codec; 03526 int destiterator = 0; 03527 int iterator; 03528 int sendonly = 0; 03529 int x,y; 03530 int debug=sip_debug_test_pvt(p); 03531 struct ast_channel *bridgepeer = NULL; 03532 03533 if (!p->rtp) { 03534 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 03535 return -1; 03536 } 03537 03538 /* Update our last rtprx when we receive an SDP, too */ 03539 time(&p->lastrtprx); 03540 time(&p->lastrtptx); 03541 03542 m = get_sdp(req, "m"); 03543 sdpLineNum_iterator_init(&destiterator, req); 03544 c = get_sdp_iterate(&destiterator, req, "c"); 03545 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 03546 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 03547 return -1; 03548 } 03549 if (sscanf(c, "IN IP4 %256s", host) != 1) { 03550 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 03551 return -1; 03552 } 03553 /* XXX This could block for a long time, and block the main thread! XXX */ 03554 hp = ast_gethostbyname(host, &ahp); 03555 if (!hp) { 03556 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 03557 return -1; 03558 } 03559 sdpLineNum_iterator_init(&iterator, req); 03560 ast_set_flag(p, SIP_NOVIDEO); 03561 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 03562 int found = 0; 03563 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &y, &len) == 2) || 03564 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) { 03565 found = 1; 03566 portno = x; 03567 /* Scan through the RTP payload types specified in a "m=" line: */ 03568 ast_rtp_pt_clear(p->rtp); 03569 codecs = m + len; 03570 while(!ast_strlen_zero(codecs)) { 03571 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 03572 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 03573 return -1; 03574 } 03575 if (debug) 03576 ast_verbose("Found RTP audio format %d\n", codec); 03577 ast_rtp_set_m_type(p->rtp, codec); 03578 codecs = ast_skip_blanks(codecs + len); 03579 } 03580 } 03581 if (p->vrtp) 03582 ast_rtp_pt_clear(p->vrtp); /* Must be cleared in case no m=video line exists */ 03583 03584 if (p->vrtp && (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { 03585 found = 1; 03586 ast_clear_flag(p, SIP_NOVIDEO); 03587 vportno = x; 03588 /* Scan through the RTP payload types specified in a "m=" line: */ 03589 codecs = m + len; 03590 while(!ast_strlen_zero(codecs)) { 03591 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 03592 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 03593 return -1; 03594 } 03595 if (debug) 03596 ast_verbose("Found RTP video format %d\n", codec); 03597 ast_rtp_set_m_type(p->vrtp, codec); 03598 codecs = ast_skip_blanks(codecs + len); 03599 } 03600 } 03601 if (!found ) 03602 ast_log(LOG_WARNING, "Unknown SDP media type in offer: %s\n", m); 03603 } 03604 if (portno == -1 && vportno == -1) { 03605 /* No acceptable offer found in SDP */ 03606 return -2; 03607 } 03608 /* Check for Media-description-level-address for audio */ 03609 c = get_sdp_iterate(&destiterator, req, "c"); 03610 if (!ast_strlen_zero(c)) { 03611 if (sscanf(c, "IN IP4 %256s", host) != 1) { 03612 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 03613 } else { 03614 /* XXX This could block for a long time, and block the main thread! XXX */ 03615 hp = ast_gethostbyname(host, &ahp); 03616 if (!hp) { 03617 ast_log(LOG_WARNING, "Unable to lookup host in secondary c= line, '%s'\n", c); 03618 } 03619 } 03620 } 03621 /* RTP addresses and ports for audio and video */ 03622 sin.sin_family = AF_INET; 03623 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 03624 03625 /* Setup audio port number */ 03626 sin.sin_port = htons(portno); 03627 if (p->rtp && sin.sin_port) { 03628 ast_rtp_set_peer(p->rtp, &sin); 03629 if (debug) { 03630 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 03631 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)); 03632 } 03633 } 03634 /* Check for Media-description-level-address for video */ 03635 c = get_sdp_iterate(&destiterator, req, "c"); 03636 if (!ast_strlen_zero(c)) { 03637 if (sscanf(c, "IN IP4 %256s", host) != 1) { 03638 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 03639 } else { 03640 /* XXX This could block for a long time, and block the main thread! XXX */ 03641 hp = ast_gethostbyname(host, &ahp); 03642 if (!hp) { 03643 ast_log(LOG_WARNING, "Unable to lookup host in secondary c= line, '%s'\n", c); 03644 } 03645 } 03646 } 03647 /* Setup video port number */ 03648 sin.sin_port = htons(vportno); 03649 if (p->vrtp && sin.sin_port) { 03650 ast_rtp_set_peer(p->vrtp, &sin); 03651 if (debug) { 03652 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 03653 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)); 03654 } 03655 } 03656 03657 /* Next, scan through each "a=rtpmap:" line, noting each 03658 * specified RTP payload type (with corresponding MIME subtype): 03659 */ 03660 sdpLineNum_iterator_init(&iterator, req); 03661 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 03662 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 03663 if (!strcasecmp(a, "sendonly") || !strcasecmp(a, "inactive")) { 03664 sendonly = 1; 03665 continue; 03666 } 03667 if (!strcasecmp(a, "sendrecv")) { 03668 sendonly = 0; 03669 } 03670 if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue; 03671 if (debug) 03672 ast_verbose("Found description format %s\n", mimeSubtype); 03673 /* Note: should really look at the 'freq' and '#chans' params too */ 03674 ast_rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype); 03675 if (p->vrtp) 03676 ast_rtp_set_rtpmap_type(p->vrtp, codec, "video", mimeSubtype); 03677 } 03678 03679 /* Now gather all of the codecs that were asked for: */ 03680 ast_rtp_get_current_formats(p->rtp, 03681 &peercapability, &peernoncodeccapability); 03682 if (p->vrtp) 03683 ast_rtp_get_current_formats(p->vrtp, 03684 &vpeercapability, &vpeernoncodeccapability); 03685 p->jointcapability = p->capability & (peercapability | vpeercapability); 03686 p->peercapability = (peercapability | vpeercapability); 03687 p->noncodeccapability = noncodeccapability & peernoncodeccapability; 03688 03689 if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO) { 03690 ast_clear_flag(p, SIP_DTMF); 03691 if (p->noncodeccapability & AST_RTP_DTMF) { 03692 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 03693 ast_set_flag(p, SIP_DTMF_RFC2833); 03694 } else { 03695 ast_set_flag(p, SIP_DTMF_INBAND); 03696 } 03697 } 03698 03699 if (debug) { 03700 /* shame on whoever coded this.... */ 03701 const unsigned slen=512; 03702 char s1[slen], s2[slen], s3[slen], s4[slen]; 03703 03704 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 03705 ast_getformatname_multiple(s1, slen, p->capability), 03706 ast_getformatname_multiple(s2, slen, peercapability), 03707 ast_getformatname_multiple(s3, slen, vpeercapability), 03708 ast_getformatname_multiple(s4, slen, p->jointcapability)); 03709 03710 ast_verbose("Non-codec capabilities: us - %s, peer - %s, combined - %s\n", 03711 ast_rtp_lookup_mime_multiple(s1, slen, noncodeccapability, 0), 03712 ast_rtp_lookup_mime_multiple(s2, slen, peernoncodeccapability, 0), 03713 ast_rtp_lookup_mime_multiple(s3, slen, p->noncodeccapability, 0)); 03714 } 03715 if (!p->jointcapability) { 03716 ast_log(LOG_NOTICE, "No compatible codecs!\n"); 03717 return -1; 03718 } 03719 03720 if (!p->owner) /* There's no open channel owning us */ 03721 return 0; 03722 03723 if (!(p->owner->nativeformats & p->jointcapability)) { 03724 const unsigned slen=512; 03725 char s1[slen], s2[slen]; 03726 ast_log(LOG_DEBUG, "Oooh, we need to change our formats since our peer supports only %s and not %s\n", 03727 ast_getformatname_multiple(s1, slen, p->jointcapability), 03728 ast_getformatname_multiple(s2, slen, p->owner->nativeformats)); 03729 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1); 03730 ast_set_read_format(p->owner, p->owner->readformat); 03731 ast_set_write_format(p->owner, p->owner->writeformat); 03732 } 03733 if ((bridgepeer=ast_bridged_channel(p->owner))) { 03734 /* We have a bridge */ 03735 /* Turn on/off music on hold if we are holding/unholding */ 03736 struct ast_frame af = { AST_FRAME_NULL, }; 03737 if (sin.sin_addr.s_addr && !sendonly) { 03738 ast_moh_stop(bridgepeer); 03739 03740 /* Activate a re-invite */ 03741 ast_queue_frame(p->owner, &af); 03742 } else { 03743 /* No address for RTP, we're on hold */ 03744 03745 ast_moh_start(bridgepeer, NULL); 03746 if (sendonly) 03747 ast_rtp_stop(p->rtp); 03748 /* Activate a re-invite */ 03749 ast_queue_frame(p->owner, &af); 03750 } 03751 } 03752 03753 /* Manager Hold and Unhold events must be generated, if necessary */ 03754 if (sin.sin_addr.s_addr && !sendonly) { 03755 append_history(p, "Unhold", req->data); 03756 03757 if (callevents && ast_test_flag(p, SIP_CALL_ONHOLD)) { 03758 manager_event(EVENT_FLAG_CALL, "Unhold", 03759 "Channel: %s\r\n" 03760 "Uniqueid: %s\r\n", 03761 p->owner->name, 03762 p->owner->uniqueid); 03763 03764 } 03765 ast_clear_flag(p, SIP_CALL_ONHOLD); 03766 } else { 03767 /* No address for RTP, we're on hold */ 03768 append_history(p, "Hold", req->data); 03769 03770 if (callevents && !ast_test_flag(p, SIP_CALL_ONHOLD)) { 03771 manager_event(EVENT_FLAG_CALL, "Hold", 03772 "Channel: %s\r\n" 03773 "Uniqueid: %s\r\n", 03774 p->owner->name, 03775 p->owner->uniqueid); 03776 } 03777 ast_set_flag(p, SIP_CALL_ONHOLD); 03778 } 03779 03780 return 0; 03781 }
|
|
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
Definition at line 1688 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_flags_page2, global_rtautoclear, LOG_WARNING, ast_variable::name, ast_variable::next, peerl, sched, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, ast_variable::value, and var. 01689 { 01690 struct sip_peer *peer=NULL; 01691 struct ast_variable *var; 01692 struct ast_variable *tmp; 01693 char *newpeername = (char *) peername; 01694 char iabuf[80]; 01695 01696 /* First check on peer name */ 01697 if (newpeername) 01698 var = ast_load_realtime("sippeers", "name", peername, NULL); 01699 else if (sin) { /* Then check on IP address */ 01700 ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr); 01701 var = ast_load_realtime("sippeers", "host", iabuf, NULL); /* First check for fixed IP hosts */ 01702 if (!var) 01703 var = ast_load_realtime("sippeers", "ipaddr", iabuf, NULL); /* Then check for registred hosts */ 01704 01705 } else 01706 return NULL; 01707 01708 if (!var) 01709 return NULL; 01710 01711 tmp = var; 01712 /* If this is type=user, then skip this object. */ 01713 while(tmp) { 01714 if (!strcasecmp(tmp->name, "type") && 01715 !strcasecmp(tmp->value, "user")) { 01716 ast_variables_destroy(var); 01717 return NULL; 01718 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 01719 newpeername = tmp->value; 01720 } 01721 tmp = tmp->next; 01722 } 01723 01724 if (!newpeername) { /* Did not find peer in realtime */ 01725 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 01726 ast_variables_destroy(var); 01727 return (struct sip_peer *) NULL; 01728 } 01729 01730 /* Peer found in realtime, now build it in memory */ 01731 peer = build_peer(newpeername, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)); 01732 if (!peer) { 01733 ast_variables_destroy(var); 01734 return (struct sip_peer *) NULL; 01735 } 01736 01737 if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 01738 /* Cache peer */ 01739 ast_copy_flags((&peer->flags_page2),(&global_flags_page2), SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 01740 if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTAUTOCLEAR)) { 01741 if (peer->expire > -1) { 01742 ast_sched_del(sched, peer->expire); 01743 } 01744 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, (void *)peer); 01745 } 01746 ASTOBJ_CONTAINER_LINK(&peerl,peer); 01747 } else { 01748 ast_set_flag(peer, SIP_REALTIME); 01749 } 01750 ast_variables_destroy(var); 01751 01752 return peer; 01753 }
|
|
realtime_update_peer: Update peer object in realtime storage ---
Definition at line 1610 of file chan_sip.c. References ast_inet_ntoa(), ast_update_realtime(), and ipaddr. 01611 { 01612 char port[10]; 01613 char ipaddr[20]; 01614 char regseconds[20]; 01615 time_t nowtime; 01616 01617 time(&nowtime); 01618 nowtime += expirey; 01619 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 01620 ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr); 01621 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 01622 01623 if (fullcontact) 01624 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, "fullcontact", fullcontact, NULL); 01625 else 01626 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, NULL); 01627 }
|
|
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 1802 of file chan_sip.c. References ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, build_user(), global_flags_page2, ast_variable::name, ast_variable::next, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, user, userl, ast_variable::value, and var. 01803 { 01804 struct ast_variable *var; 01805 struct ast_variable *tmp; 01806 struct sip_user *user = NULL; 01807 01808 var = ast_load_realtime("sipusers", "name", username, NULL); 01809 01810 if (!var) 01811 return NULL; 01812 01813 tmp = var; 01814 while (tmp) { 01815 if (!strcasecmp(tmp->name, "type") && 01816 !strcasecmp(tmp->value, "peer")) { 01817 ast_variables_destroy(var); 01818 return NULL; 01819 } 01820 tmp = tmp->next; 01821 } 01822 01823 01824 01825 user = build_user(username, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)); 01826 01827 if (!user) { /* No user found */ 01828 ast_variables_destroy(var); 01829 return NULL; 01830 } 01831 01832 if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 01833 ast_set_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS); 01834 suserobjs++; 01835 ASTOBJ_CONTAINER_LINK(&userl,user); 01836 } else { 01837 /* Move counter from s to r... */ 01838 suserobjs--; 01839 ruserobjs++; 01840 ast_set_flag(user, SIP_REALTIME); 01841 } 01842 ast_variables_destroy(var); 01843 return user; 01844 }
|
|
receive_message: Receive SIP MESSAGE method messages ---
Definition at line 7426 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(). 07427 { 07428 char buf[1024]; 07429 struct ast_frame f; 07430 char *content_type; 07431 07432 content_type = get_header(req, "Content-Type"); 07433 if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */ 07434 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 07435 ast_set_flag(p, SIP_NEEDDESTROY); 07436 return; 07437 } 07438 07439 if (get_msg_text(buf, sizeof(buf), req)) { 07440 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 07441 transmit_response(p, "202 Accepted", req); 07442 ast_set_flag(p, SIP_NEEDDESTROY); 07443 return; 07444 } 07445 07446 if (p->owner) { 07447 if (sip_debug_test_pvt(p)) 07448 ast_verbose("Message received: '%s'\n", buf); 07449 memset(&f, 0, sizeof(f)); 07450 f.frametype = AST_FRAME_TEXT; 07451 f.subclass = 0; 07452 f.offset = 0; 07453 f.data = buf; 07454 f.datalen = strlen(buf); 07455 ast_queue_frame(p->owner, &f); 07456 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 07457 } else { /* Message outside of a call, we do not support that */ 07458 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); 07459 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 07460 } 07461 ast_set_flag(p, SIP_NEEDDESTROY); 07462 return; 07463 }
|
|
reg_source_db: Get registration details from Asterisk DB ---
Definition at line 5815 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. 05816 { 05817 char data[256]; 05818 char iabuf[INET_ADDRSTRLEN]; 05819 struct in_addr in; 05820 int expiry; 05821 int port; 05822 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 05823 05824 if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 05825 return; 05826 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 05827 return; 05828 05829 scan = data; 05830 addr = strsep(&scan, ":"); 05831 port_str = strsep(&scan, ":"); 05832 expiry_str = strsep(&scan, ":"); 05833 username = strsep(&scan, ":"); 05834 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 05835 05836 if (!inet_aton(addr, &in)) 05837 return; 05838 05839 if (port_str) 05840 port = atoi(port_str); 05841 else 05842 return; 05843 05844 if (expiry_str) 05845 expiry = atoi(expiry_str); 05846 else 05847 return; 05848 05849 if (username) 05850 ast_copy_string(peer->username, username, sizeof(peer->username)); 05851 if (contact) 05852 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 05853 05854 if (option_verbose > 2) 05855 ast_verbose(VERBOSE_PREFIX_3 "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 05856 peer->name, peer->username, ast_inet_ntoa(iabuf, sizeof(iabuf), in), port, expiry); 05857 05858 memset(&peer->addr, 0, sizeof(peer->addr)); 05859 peer->addr.sin_family = AF_INET; 05860 peer->addr.sin_addr = in; 05861 peer->addr.sin_port = htons(port); 05862 if (sipsock < 0) { 05863 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 05864 if (peer->pokeexpire > -1) 05865 ast_sched_del(sched, peer->pokeexpire); 05866 peer->pokeexpire = ast_sched_add(sched, thread_safe_rand() % 5000 + 1, sip_poke_peer_s, peer); 05867 } else 05868 sip_poke_peer(peer); 05869 if (peer->expire > -1) 05870 ast_sched_del(sched, peer->expire); 05871 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 05872 register_peer_exten(peer, 1); 05873 }
|
|
register_peer_exten: Automatically add peer extension to dial plan ---
Definition at line 1630 of file chan_sip.c. References ast_add_extension(), ast_context_remove_extension(), ast_strlen_zero(), FREE, sip_peer::regexten, strdup, and strsep(). 01631 { 01632 char multi[256]; 01633 char *stringp, *ext; 01634 if (!ast_strlen_zero(regcontext)) { 01635 ast_copy_string(multi, ast_strlen_zero(peer->regexten) ? peer->name : peer->regexten, sizeof(multi)); 01636 stringp = multi; 01637 while((ext = strsep(&stringp, "&"))) { 01638 if (onoff) 01639 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), FREE, channeltype); 01640 else 01641 ast_context_remove_extension(regcontext, ext, 1, NULL); 01642 } 01643 } 01644 }
|
|
register_verify: Verify registration of user
Definition at line 6507 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(). 06508 { 06509 int res = -3; 06510 struct sip_peer *peer; 06511 char tmp[256]; 06512 char iabuf[INET_ADDRSTRLEN]; 06513 char *name, *c; 06514 char *t; 06515 char *domain; 06516 06517 /* Terminate URI */ 06518 t = uri; 06519 while(*t && (*t > 32) && (*t != ';')) 06520 t++; 06521 *t = '\0'; 06522 06523 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 06524 if (pedanticsipchecking) 06525 ast_uri_decode(tmp); 06526 06527 c = get_in_brackets(tmp); 06528 /* Ditch ;user=phone */ 06529 name = strchr(c, ';'); 06530 if (name) 06531 *name = '\0'; 06532 06533 if (!strncmp(c, "sip:", 4)) { 06534 name = c + 4; 06535 } else { 06536 name = c; 06537 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)); 06538 } 06539 06540 /* Strip off the domain name */ 06541 if ((c = strchr(name, '@'))) { 06542 *c++ = '\0'; 06543 domain = c; 06544 if ((c = strchr(domain, ':'))) /* Remove :port */ 06545 *c = '\0'; 06546 if (!AST_LIST_EMPTY(&domain_list)) { 06547 if (!check_sip_domain(domain, NULL, 0)) { 06548 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 06549 return -3; 06550 } 06551 } 06552 } 06553 06554 ast_copy_string(p->exten, name, sizeof(p->exten)); 06555 build_contact(p); 06556 peer = find_peer(name, NULL, 1); 06557 if (!(peer && ast_apply_ha(peer->ha, sin))) { 06558 if (peer) 06559 ASTOBJ_UNREF(peer,sip_destroy_peer); 06560 } 06561 if (peer) { 06562 if (!ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)) { 06563 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 06564 } else { 06565 ast_copy_flags(p, peer, SIP_NAT); 06566 transmit_response(p, "100 Trying", req); 06567 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, 0, ignore))) { 06568 sip_cancel_destroy(p); 06569 switch (parse_register_contact(p, peer, req)) { 06570 case PARSE_REGISTER_FAILED: 06571 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 06572 transmit_response_with_date(p, "400 Bad Request", req); 06573 peer->lastmsgssent = -1; 06574 res = 0; 06575 break; 06576 case PARSE_REGISTER_QUERY: 06577 transmit_response_with_date(p, "200 OK", req); 06578 peer->lastmsgssent = -1; 06579 res = 0; 06580 break; 06581 case PARSE_REGISTER_UPDATE: 06582 update_peer(peer, p->expiry); 06583 /* Say OK and ask subsystem to retransmit msg counter */ 06584 transmit_response_with_date(p, "200 OK", req); 06585 peer->lastmsgssent = -1; 06586 res = 0; 06587 break; 06588 } 06589 } 06590 } 06591 } 06592 if (!peer && autocreatepeer) { 06593 /* Create peer if we have autocreate mode enabled */ 06594 peer = temp_peer(name); 06595 if (peer) { 06596 ASTOBJ_CONTAINER_LINK(&peerl, peer); 06597 sip_cancel_destroy(p); 06598 switch (parse_register_contact(p, peer, req)) { 06599 case PARSE_REGISTER_FAILED: 06600 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 06601 transmit_response_with_date(p, "400 Bad Request", req); 06602 peer->lastmsgssent = -1; 06603 res = 0; 06604 break; 06605 case PARSE_REGISTER_QUERY: 06606 transmit_response_with_date(p, "200 OK", req); 06607 peer->lastmsgssent = -1; 06608 res = 0; 06609 break; 06610 case PARSE_REGISTER_UPDATE: 06611 /* Say OK and ask subsystem to retransmit msg counter */ 06612 transmit_response_with_date(p, "200 OK", req); 06613 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 06614 peer->lastmsgssent = -1; 06615 res = 0; 06616 break; 06617 } 06618 } 06619 } 06620 if (!res) { 06621 ast_device_state_changed("SIP/%s", peer->name); 06622 } 06623 if (res < 0) { 06624 switch (res) { 06625 case -1: 06626 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 06627 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 06628 break; 06629 case -2: 06630 /* Username and digest username does not match. 06631 Asterisk uses the From: username for authentication. We need the 06632 users to use the same authentication user name until we support 06633 proper authentication by digest auth name */ 06634 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 06635 break; 06636 case -3: 06637 if (global_alwaysauthreject) { 06638 transmit_fake_auth_response(p, &p->initreq, p->randdata, sizeof(p->randdata), 1); 06639 } else { 06640 /* URI not found */ 06641 transmit_response(p, "404 Not found", &p->initreq); 06642 } 06643 /* Set res back to -2 because we don't want to return an invalid domain message. That check already happened up above. */ 06644 res = -2; 06645 break; 06646 } 06647 if (option_debug > 1) { 06648 ast_log(LOG_DEBUG, "SIP REGISTER attempt failed for %s : %s\n", 06649 peer->name, 06650 (res == -1) ? "Bad password" : ((res == -2 ) ? "Bad digest user" : "Peer not found")); 06651 } 06652 } 06653 if (peer) 06654 ASTOBJ_UNREF(peer,sip_destroy_peer); 06655 06656 return res; 06657 }
|
|
Definition at line 5355 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. 05356 { 05357 switch(regstate) { 05358 case REG_STATE_FAILED: 05359 return "Failed"; 05360 case REG_STATE_UNREGISTERED: 05361 return "Unregistered"; 05362 case REG_STATE_REGSENT: 05363 return "Request Sent"; 05364 case REG_STATE_AUTHSENT: 05365 return "Auth. Sent"; 05366 case REG_STATE_REGISTERED: 05367 return "Registered"; 05368 case REG_STATE_REJECTED: 05369 return "Rejected"; 05370 case REG_STATE_TIMEOUT: 05371 return "Timeout"; 05372 case REG_STATE_NOAUTH: 05373 return "No Authentication"; 05374 default: 05375 return "Unknown"; 05376 } 05377 }
|
|
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 13388 of file chan_sip.c. References sip_reload(). 13389 { 13390 return sip_reload(0, 0, NULL); 13391 }
|
|
reload_config: Re-read SIP.conf config file ---
Definition at line 12564 of file chan_sip.c. References __ourip, add_realm_authentication(), add_sip_domain(), ahp, 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_enable_packet_fragmentation(), 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, global_allowguest, global_alwaysauthreject, global_capability, global_flags, global_flags_page2, 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, prefs, 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. 12565 { 12566 struct ast_config *cfg; 12567 struct ast_variable *v; 12568 struct sip_peer *peer; 12569 struct sip_user *user; 12570 struct ast_hostent ahp; 12571 char *cat; 12572 char *utype; 12573 struct hostent *hp; 12574 int format; 12575 char iabuf[INET_ADDRSTRLEN]; 12576 struct ast_flags dummy; 12577 int auto_sip_domains = 0; 12578 struct sockaddr_in old_bindaddr = bindaddr; 12579 12580 cfg = ast_config_load(config); 12581 12582 /* We *must* have a config file otherwise stop immediately */ 12583 if (!cfg) { 12584 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 12585 return -1; 12586 } 12587 12588 /* Reset IP addresses */ 12589 memset(&bindaddr, 0, sizeof(bindaddr)); 12590 memset(&localaddr, 0, sizeof(localaddr)); 12591 memset(&externip, 0, sizeof(externip)); 12592 memset(&prefs, 0 , sizeof(prefs)); 12593 sipdebug &= ~SIP_DEBUG_CONFIG; 12594 12595 /* Initialize some reasonable defaults at SIP reload */ 12596 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 12597 default_subscribecontext[0] = '\0'; 12598 default_language[0] = '\0'; 12599 default_fromdomain[0] = '\0'; 12600 default_qualify = 0; 12601 allow_external_domains = 1; /* Allow external invites */ 12602 externhost[0] = '\0'; 12603 externexpire = 0; 12604 externrefresh = 10; 12605 ast_copy_string(default_useragent, DEFAULT_USERAGENT, sizeof(default_useragent)); 12606 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 12607 global_notifyringing = 1; 12608 global_alwaysauthreject = 0; 12609 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 12610 ast_copy_string(global_musicclass, "default", sizeof(global_musicclass)); 12611 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 12612 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 12613 outboundproxyip.sin_port = htons(DEFAULT_SIP_PORT); 12614 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 12615 videosupport = 0; 12616 compactheaders = 0; 12617 dumphistory = 0; 12618 recordhistory = 0; 12619 relaxdtmf = 0; 12620 callevents = 0; 12621 ourport = DEFAULT_SIP_PORT; 12622 global_rtptimeout = 0; 12623 global_rtpholdtimeout = 0; 12624 global_rtpkeepalive = 0; 12625 global_rtautoclear = 120; 12626 pedanticsipchecking = 0; 12627 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 12628 global_regattempts_max = 0; 12629 ast_clear_flag(&global_flags, AST_FLAGS_ALL); 12630 ast_clear_flag(&global_flags_page2, AST_FLAGS_ALL); 12631 ast_set_flag(&global_flags, SIP_DTMF_RFC2833); 12632 ast_set_flag(&global_flags, SIP_NAT_RFC3581); 12633 ast_set_flag(&global_flags, SIP_CAN_REINVITE); 12634 ast_set_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE); 12635 global_mwitime = DEFAULT_MWITIME; 12636 strcpy(global_vmexten, DEFAULT_VMEXTEN); 12637 srvlookup = 0; 12638 autocreatepeer = 0; 12639 regcontext[0] = '\0'; 12640 tos = 0; 12641 expiry = DEFAULT_EXPIRY; 12642 global_allowguest = 1; 12643 12644 /* Read the [general] config section of sip.conf (or from realtime config) */ 12645 v = ast_variable_browse(cfg, "general"); 12646 while(v) { 12647 if (handle_common_options(&global_flags, &dummy, v)) { 12648 v = v->next; 12649 continue; 12650 } 12651 12652 /* Create the interface list */ 12653 if (!strcasecmp(v->name, "context")) { 12654 ast_copy_string(default_context, v->value, sizeof(default_context)); 12655 } else if (!strcasecmp(v->name, "realm")) { 12656 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 12657 } else if (!strcasecmp(v->name, "useragent")) { 12658 ast_copy_string(default_useragent, v->value, sizeof(default_useragent)); 12659 ast_log(LOG_DEBUG, "Setting User Agent Name to %s\n", 12660 default_useragent); 12661 } else if (!strcasecmp(v->name, "rtcachefriends")) { 12662 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 12663 } else if (!strcasecmp(v->name, "rtupdate")) { 12664 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTUPDATE); 12665 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 12666 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 12667 } else if (!strcasecmp(v->name, "rtautoclear")) { 12668 int i = atoi(v->value); 12669 if (i > 0) 12670 global_rtautoclear = i; 12671 else 12672 i = 0; 12673 ast_set2_flag((&global_flags_page2), i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 12674 } else if (!strcasecmp(v->name, "usereqphone")) { 12675 ast_set2_flag((&global_flags), ast_true(v->value), SIP_USEREQPHONE); 12676 } else if (!strcasecmp(v->name, "relaxdtmf")) { 12677 relaxdtmf = ast_true(v->value); 12678 } else if (!strcasecmp(v->name, "checkmwi")) { 12679 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 12680 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 12681 global_mwitime = DEFAULT_MWITIME; 12682 } 12683 } else if (!strcasecmp(v->name, "vmexten")) { 12684 ast_copy_string(global_vmexten, v->value, sizeof(global_vmexten)); 12685 } else if (!strcasecmp(v->name, "rtptimeout")) { 12686 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 12687 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12688 global_rtptimeout = 0; 12689 } 12690 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 12691 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 12692 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12693 global_rtpholdtimeout = 0; 12694 } 12695 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 12696 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 12697 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 12698 global_rtpkeepalive = 0; 12699 } 12700 } else if (!strcasecmp(v->name, "videosupport")) { 12701 videosupport = ast_true(v->value); 12702 } else if (!strcasecmp(v->name, "compactheaders")) { 12703 compactheaders = ast_true(v->value); 12704 } else if (!strcasecmp(v->name, "notifymimetype")) { 12705 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 12706 } else if (!strcasecmp(v->name, "notifyringing")) { 12707 global_notifyringing = ast_true(v->value); 12708 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 12709 global_alwaysauthreject = ast_true(v->value); 12710 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 12711 ast_copy_string(global_musicclass, v->value, sizeof(global_musicclass)); 12712 } else if (!strcasecmp(v->name, "language")) { 12713 ast_copy_string(default_language, v->value, sizeof(default_language)); 12714 } else if (!strcasecmp(v->name, "regcontext")) { 12715 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 12716 /* Create context if it doesn't exist already */ 12717 if (!ast_context_find(regcontext)) 12718 ast_context_create(NULL, regcontext, channeltype); 12719 } else if (!strcasecmp(v->name, "callerid")) { 12720 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 12721 } else if (!strcasecmp(v->name, "fromdomain")) { 12722 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 12723 } else if (!strcasecmp(v->name, "outboundproxy")) { 12724 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 12725 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 12726 } else if (!strcasecmp(v->name, "outboundproxyport")) { 12727 /* Port needs to be after IP */ 12728 sscanf(v->value, "%d", &format); 12729 outboundproxyip.sin_port = htons(format); 12730 } else if (!strcasecmp(v->name, "autocreatepeer")) { 12731 autocreatepeer = ast_true(v->value); 12732 } else if (!strcasecmp(v->name, "srvlookup")) { 12733 srvlookup = ast_true(v->value); 12734 } else if (!strcasecmp(v->name, "pedantic")) { 12735 pedanticsipchecking = ast_true(v->value); 12736 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 12737 max_expiry = atoi(v->value); 12738 if (max_expiry < 1) 12739 max_expiry = DEFAULT_MAX_EXPIRY; 12740 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 12741 default_expiry = atoi(v->value); 12742 if (default_expiry < 1) 12743 default_expiry = DEFAULT_DEFAULT_EXPIRY; 12744 } else if (!strcasecmp(v->name, "sipdebug")) { 12745 if (ast_true(v->value)) 12746 sipdebug |= SIP_DEBUG_CONFIG; 12747 } else if (!strcasecmp(v->name, "dumphistory")) { 12748 dumphistory = ast_true(v->value); 12749 } else if (!strcasecmp(v->name, "recordhistory")) { 12750 recordhistory = ast_true(v->value); 12751 } else if (!strcasecmp(v->name, "registertimeout")) { 12752 global_reg_timeout = atoi(v->value); 12753 if (global_reg_timeout < 1) 12754 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 12755 } else if (!strcasecmp(v->name, "registerattempts")) { 12756 global_regattempts_max = atoi(v->value); 12757 } else if (!strcasecmp(v->name, "bindaddr")) { 12758 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 12759 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 12760 } else { 12761 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 12762 } 12763 } else if (!strcasecmp(v->name, "localnet")) { 12764 struct ast_ha *na; 12765 if (!(na = ast_append_ha("d", v->value, localaddr))) 12766 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 12767 else 12768 localaddr = na; 12769 } else if (!strcasecmp(v->name, "localmask")) { 12770 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 12771 } else if (!strcasecmp(v->name, "externip")) { 12772 if (!(hp = ast_gethostbyname(v->value, &ahp))) 12773 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 12774 else 12775 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 12776 externexpire = 0; 12777 } else if (!strcasecmp(v->name, "externhost")) { 12778 ast_copy_string(externhost, v->value, sizeof(externhost)); 12779 if (!(hp = ast_gethostbyname(externhost, &ahp))) 12780 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 12781 else 12782 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 12783 time(&externexpire); 12784 } else if (!strcasecmp(v->name, "externrefresh")) { 12785 if (sscanf(v->value, "%d", &externrefresh) != 1) { 12786 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 12787 externrefresh = 10; 12788 } 12789 } else if (!strcasecmp(v->name, "allow")) { 12790 ast_parse_allow_disallow(&prefs, &global_capability, v->value, 1); 12791 } else if (!strcasecmp(v->name, "disallow")) { 12792 ast_parse_allow_disallow(&prefs, &global_capability, v->value, 0); 12793 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 12794 allow_external_domains = ast_true(v->value); 12795 } else if (!strcasecmp(v->name, "autodomain")) { 12796 auto_sip_domains = ast_true(v->value); 12797 } else if (!strcasecmp(v->name, "domain")) { 12798 char *domain = ast_strdupa(v->value); 12799 char *context = strchr(domain, ','); 12800 12801 if (context) 12802 *context++ = '\0'; 12803 12804 if (option_debug && ast_strlen_zero(context)) 12805 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 12806 if (ast_strlen_zero(domain)) 12807 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 12808 else 12809 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 12810 } else if (!strcasecmp(v->name, "register")) { 12811 sip_register(v->value, v->lineno); 12812 } else if (!strcasecmp(v->name, "tos")) { 12813 if (ast_str2tos(v->value, &tos)) 12814 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 12815 } else if (!strcasecmp(v->name, "bindport")) { 12816 if (sscanf(v->value, "%d", &ourport) == 1) { 12817 bindaddr.sin_port = htons(ourport); 12818 } else { 12819 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 12820 } 12821 } else if (!strcasecmp(v->name, "qualify")) { 12822 if (!strcasecmp(v->value, "no")) { 12823 default_qualify = 0; 12824 } else if (!strcasecmp(v->value, "yes")) { 12825 default_qualify = DEFAULT_MAXMS; 12826 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 12827 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 12828 default_qualify = 0; 12829 } 12830 } else if (!strcasecmp(v->name, "callevents")) { 12831 callevents = ast_true(v->value); 12832 } 12833 /* else if (strcasecmp(v->name,"type")) 12834 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 12835 */ 12836 v = v->next; 12837 } 12838 12839 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 12840 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 12841 allow_external_domains = 1; 12842 } 12843 12844 /* Build list of authentication to various SIP realms, i.e. service providers */ 12845 v = ast_variable_browse(cfg, "authentication"); 12846 while(v) { 12847 /* Format for authentication is auth = username:password@realm */ 12848 if (!strcasecmp(v->name, "auth")) { 12849 authl = add_realm_authentication(authl, v->value, v->lineno); 12850 } 12851 v = v->next; 12852 } 12853 12854 /* Load peers, users and friends */ 12855 cat = ast_category_browse(cfg, NULL); 12856 while(cat) { 12857 if (strcasecmp(cat, "general") && strcasecmp(cat, "authentication")) { 12858 utype = ast_variable_retrieve(cfg, cat, "type"); 12859 if (utype) { 12860 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 12861 user = build_user(cat, ast_variable_browse(cfg, cat), 0); 12862 if (user) { 12863 ASTOBJ_CONTAINER_LINK(&userl,user); 12864 ASTOBJ_UNREF(user, sip_destroy_user); 12865 } 12866 } 12867 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 12868 peer = build_peer(cat, ast_variable_browse(cfg, cat), 0); 12869 if (peer) { 12870 ASTOBJ_CONTAINER_LINK(&peerl,peer); 12871 ASTOBJ_UNREF(peer, sip_destroy_peer); 12872 } 12873 } else if (strcasecmp(utype, "user")) { 12874 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 12875 } 12876 } else 12877 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 12878 } 12879 cat = ast_category_browse(cfg, cat); 12880 } 12881 if (ast_find_ourip(&__ourip, bindaddr)) { 12882 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 12883 return 0; 12884 } 12885 if (!ntohs(bindaddr.sin_port)) 12886 bindaddr.sin_port = ntohs(DEFAULT_SIP_PORT); 12887 bindaddr.sin_family = AF_INET; 12888 ast_mutex_lock(&netlock); 12889 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 12890 close(sipsock); 12891 sipsock = -1; 12892 } 12893 if (sipsock < 0) { 12894 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 12895 if (sipsock < 0) { 12896 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 12897 } else { 12898 /* Allow SIP clients on the same host to access us: */ 12899 const int reuseFlag = 1; 12900 12901 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 12902 (const char*)&reuseFlag, 12903 sizeof reuseFlag); 12904 12905 ast_enable_packet_fragmentation(sipsock); 12906 12907 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 12908 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 12909 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port), 12910 strerror(errno)); 12911 close(sipsock); 12912 sipsock = -1; 12913 } else { 12914 if (option_verbose > 1) { 12915 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 12916 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 12917 ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos); 12918 } 12919 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) 12920 ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos); 12921 } 12922 } 12923 } 12924 ast_mutex_unlock(&netlock); 12925 12926 /* Add default domains - host name, IP address and IP:port */ 12927 /* Only do this if user added any sip domain with "localdomains" */ 12928 /* In order to *not* break backwards compatibility */ 12929 /* Some phones address us at IP only, some with additional port number */ 12930 if (auto_sip_domains) { 12931 char temp[MAXHOSTNAMELEN]; 12932 12933 /* First our default IP address */ 12934 if (bindaddr.sin_addr.s_addr) { 12935 ast_inet_ntoa(temp, sizeof(temp), bindaddr.sin_addr); 12936 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12937 } else { 12938 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 12939 } 12940 12941 /* Our extern IP address, if configured */ 12942 if (externip.sin_addr.s_addr) { 12943 ast_inet_ntoa(temp, sizeof(temp), externip.sin_addr); 12944 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12945 } 12946 12947 /* Extern host name (NAT traversal support) */ 12948 if (!ast_strlen_zero(externhost)) 12949 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 12950 12951 /* Our host name */ 12952 if (!gethostname(temp, sizeof(temp))) 12953 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12954 } 12955 12956 /* Release configuration from memory */ 12957 ast_config_destroy(cfg); 12958 12959 /* Load the list of manual NOTIFY types to support */ 12960 if (notify_types) 12961 ast_config_destroy(notify_types); 12962 notify_types = ast_config_load(notify_config); 12963 12964 return 0; 12965 }
|
|
reply_digest: reply to authentication for outbound registrations ---
Definition at line 9097 of file chan_sip.c. References ast_log(), ast_strlen_zero(), sip_pvt::domain, get_header(), key(), keys, LOG_WARNING, sip_pvt::nonce, sip_pvt::opaque, sip_pvt::qop, sip_pvt::realm, and strsep(). Referenced by do_proxy_auth(), and do_register_auth(). 09099 { 09100 char tmp[512]; 09101 char *c; 09102 char oldnonce[256]; 09103 09104 /* table of recognised keywords, and places where they should be copied */ 09105 const struct x { 09106 const char *key; 09107 char *dst; 09108 int dstlen; 09109 } *i, keys[] = { 09110 { "realm=", p->realm, sizeof(p->realm) }, 09111 { "nonce=", p->nonce, sizeof(p->nonce) }, 09112 { "opaque=", p->opaque, sizeof(p->opaque) }, 09113 { "qop=", p->qop, sizeof(p->qop) }, 09114 { "domain=", p->domain, sizeof(p->domain) }, 09115 { NULL, NULL, 0 }, 09116 }; 09117 09118 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 09119 if (ast_strlen_zero(tmp)) 09120 return -1; 09121 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 09122 ast_log(LOG_WARNING, "missing Digest.\n"); 09123 return -1; 09124 } 09125 c = tmp + strlen("Digest "); 09126 for (i = keys; i->key != NULL; i++) 09127 i->dst[0] = '\0'; /* init all to empty strings */ 09128 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 09129 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 09130 for (i = keys; i->key != NULL; i++) { 09131 char *src, *separator; 09132 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 09133 continue; 09134 /* Found. Skip keyword, take text in quotes or up to the separator. */ 09135 c += strlen(i->key); 09136 if (*c == '\"') { 09137 src = ++c; 09138 separator = "\""; 09139 } else { 09140 src = c; 09141 separator = ","; 09142 } 09143 strsep(&c, separator); /* clear separator and move ptr */ 09144 ast_copy_string(i->dst, src, i->dstlen); 09145 break; 09146 } 09147 if (i->key == NULL) /* not found, try ',' */ 09148 strsep(&c, ","); 09149 } 09150 /* Reset nonce count */ 09151 if (strcmp(p->nonce, oldnonce)) 09152 p->noncecount = 0; 09153 09154 /* Save auth data for following registrations */ 09155 if (p->registry) { 09156 struct sip_registry *r = p->registry; 09157 09158 if (strcmp(r->nonce, p->nonce)) { 09159 ast_copy_string(r->realm, p->realm, sizeof(r->realm)); 09160 ast_copy_string(r->nonce, p->nonce, sizeof(r->nonce)); 09161 ast_copy_string(r->domain, p->domain, sizeof(r->domain)); 09162 ast_copy_string(r->opaque, p->opaque, sizeof(r->opaque)); 09163 ast_copy_string(r->qop, p->qop, sizeof(r->qop)); 09164 r->noncecount = 0; 09165 } 09166 } 09167 return build_reply_digest(p, sipmethod, digest, digest_len); 09168 }
|
|
reqprep: Initialize a SIP request response packet ---
Definition at line 4138 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. 04139 { 04140 struct sip_request *orig = &p->initreq; 04141 char stripped[80]; 04142 char tmp[80]; 04143 char newto[256]; 04144 char *c, *n; 04145 char *ot, *of; 04146 int is_strict = 0; /* Strict routing flag */ 04147 04148 memset(req, 0, sizeof(struct sip_request)); 04149 04150 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 04151 04152 if (!seqno) { 04153 p->ocseq++; 04154 seqno = p->ocseq; 04155 } 04156 04157 if (newbranch) { 04158 p->branch ^= thread_safe_rand(); 04159 build_via(p, p->via, sizeof(p->via)); 04160 } 04161 04162 /* Check for strict or loose router */ 04163 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) 04164 is_strict = 1; 04165 04166 if (sipmethod == SIP_CANCEL) { 04167 c = p->initreq.rlPart2; /* Use original URI */ 04168 } else if (sipmethod == SIP_ACK) { 04169 /* Use URI from Contact: in 200 OK (if INVITE) 04170 (we only have the contacturi on INVITEs) */ 04171 if (!ast_strlen_zero(p->okcontacturi)) 04172 c = is_strict ? p->route->hop : p->okcontacturi; 04173 else 04174 c = p->initreq.rlPart2; 04175 } else if (!ast_strlen_zero(p->okcontacturi)) { 04176 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 04177 } else if (!ast_strlen_zero(p->uri)) { 04178 c = p->uri; 04179 } else { 04180 /* We have no URI, use To: or From: header as URI (depending on direction) */ 04181 c = get_header(orig, (ast_test_flag(p, SIP_OUTGOING)) ? "To" : "From"); 04182 ast_copy_string(stripped, c, sizeof(stripped)); 04183 c = get_in_brackets(stripped); 04184 n = strchr(c, ';'); 04185 if (n) 04186 *n = '\0'; 04187 } 04188 init_req(req, sipmethod, c); 04189 04190 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 04191 04192 add_header(req, "Via", p->via); 04193 if (p->route) { 04194 set_destination(p, p->route->hop); 04195 if (is_strict) 04196 add_route(req, p->route->next); 04197 else 04198 add_route(req, p->route); 04199 } 04200 04201 ot = get_header(orig, "To"); 04202 of = get_header(orig, "From"); 04203 04204 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 04205 as our original request, including tag (or presumably lack thereof) */ 04206 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 04207 /* Add the proper tag if we don't have it already. If they have specified 04208 their tag, use it. Otherwise, use our own tag */ 04209 if (ast_test_flag(p, SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 04210 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 04211 else if (!ast_test_flag(p, SIP_OUTGOING)) 04212 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 04213 else 04214 snprintf(newto, sizeof(newto), "%s", ot); 04215 ot = newto; 04216 } 04217 04218 if (ast_test_flag(p, SIP_OUTGOING)) { 04219 add_header(req, "From", of); 04220 add_header(req, "To", ot); 04221 } else { 04222 add_header(req, "From", ot); 04223 add_header(req, "To", of); 04224 } 04225 add_header(req, "Contact", p->our_contact); 04226 copy_header(req, orig, "Call-ID"); 04227 add_header(req, "CSeq", tmp); 04228 04229 add_header(req, "User-Agent", default_useragent); 04230 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 04231 04232 if (p->rpid) 04233 add_header(req, "Remote-Party-ID", p->rpid); 04234 04235 return 0; 04236 }
|
|
respprep: Prepare SIP response packet ---
Definition at line 4090 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. 04091 { 04092 char newto[256], *ot; 04093 04094 memset(resp, 0, sizeof(*resp)); 04095 init_resp(resp, msg, req); 04096 copy_via_headers(p, resp, req, "Via"); 04097 if (msg[0] == '2') 04098 copy_all_header(resp, req, "Record-Route"); 04099 copy_header(resp, req, "From"); 04100 ot = get_header(req, "To"); 04101 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 04102 /* Add the proper tag if we don't have it already. If they have specified 04103 their tag, use it. Otherwise, use our own tag */ 04104 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(p, SIP_OUTGOING)) 04105 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 04106 else if (p->tag && !ast_test_flag(p, SIP_OUTGOING)) 04107 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 04108 else { 04109 ast_copy_string(newto, ot, sizeof(newto)); 04110 newto[sizeof(newto) - 1] = '\0'; 04111 } 04112 ot = newto; 04113 } 04114 add_header(resp, "To", ot); 04115 copy_header(resp, req, "Call-ID"); 04116 copy_header(resp, req, "CSeq"); 04117 add_header(resp, "User-Agent", default_useragent); 04118 add_header(resp, "Allow", ALLOWED_METHODS); 04119 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 04120 /* For registration responses, we also need expiry and 04121 contact info */ 04122 char tmp[256]; 04123 04124 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 04125 add_header(resp, "Expires", tmp); 04126 if (p->expiry) { /* Only add contact if we have an expiry time */ 04127 char contact[SIP_LEN_CONTACT]; 04128 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 04129 add_header(resp, "Contact", contact); /* Not when we unregister */ 04130 } 04131 } else if (msg[0] != '4' && p->our_contact[0]) { 04132 add_header(resp, "Contact", p->our_contact); 04133 } 04134 return 0; 04135 }
|
|
restart_monitor: Start the channel monitor thread ---
Definition at line 11625 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. 11626 { 11627 /* If we're supposed to be stopped -- stay stopped */ 11628 if (monitor_thread == AST_PTHREADT_STOP) 11629 return 0; 11630 if (ast_mutex_lock(&monlock)) { 11631 ast_log(LOG_WARNING, "Unable to lock monitor\n"); 11632 return -1; 11633 } 11634 if (monitor_thread == pthread_self()) { 11635 ast_mutex_unlock(&monlock); 11636 ast_log(LOG_WARNING, "Cannot kill myself\n"); 11637 return -1; 11638 } 11639 if (monitor_thread != AST_PTHREADT_NULL) { 11640 /* Wake up the thread */ 11641 pthread_kill(monitor_thread, SIGURG); 11642 } else { 11643 /* Start a new monitor */ 11644 if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) { 11645 ast_mutex_unlock(&monlock); 11646 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 11647 return -1; 11648 } 11649 } 11650 ast_mutex_unlock(&monlock); 11651 return 0; 11652 }
|
|
retrans_pkt: Retransmit SIP message if no answer ---
Definition at line 1175 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, sip_pkt::timer_a, and sip_pkt::timer_t1. 01176 { 01177 struct sip_pkt *pkt=data, *prev, *cur = NULL; 01178 char iabuf[INET_ADDRSTRLEN]; 01179 int reschedule = DEFAULT_RETRANS; 01180 01181 /* Lock channel */ 01182 ast_mutex_lock(&pkt->owner->lock); 01183 01184 if (pkt->retrans < MAX_RETRANS) { 01185 char buf[80]; 01186 01187 pkt->retrans++; 01188 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01189 if (sipdebug && option_debug > 3) 01190 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); 01191 } else { 01192 int siptimer_a; 01193 01194 if (sipdebug && option_debug > 3) 01195 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01196 if (!pkt->timer_a) 01197 pkt->timer_a = 2 ; 01198 else 01199 pkt->timer_a = 2 * pkt->timer_a; 01200 01201 /* For non-invites, a maximum of 4 secs */ 01202 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01203 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01204 siptimer_a = 4000; 01205 01206 /* Reschedule re-transmit */ 01207 reschedule = siptimer_a; 01208 if (option_debug > 3) 01209 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); 01210 } 01211 01212 if (pkt->owner && sip_debug_test_pvt(pkt->owner)) { 01213 if (ast_test_flag(pkt->owner, SIP_NAT) & SIP_NAT_ROUTE) 01214 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); 01215 else 01216 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); 01217 } 01218 snprintf(buf, sizeof(buf), "ReTx %d", reschedule); 01219 01220 append_history(pkt->owner, buf, pkt->data); 01221 __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01222 ast_mutex_unlock(&pkt->owner->lock); 01223 return reschedule; 01224 } 01225 /* Too many retries */ 01226 if (pkt->owner && pkt->method != SIP_OPTIONS) { 01227 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01228 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"); 01229 } else { 01230 if (pkt->method == SIP_OPTIONS && sipdebug) 01231 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid); 01232 } 01233 append_history(pkt->owner, "MaxRetries", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01234 01235 pkt->retransid = -1; 01236 01237 if (ast_test_flag(pkt, FLAG_FATAL)) { 01238 while(pkt->owner->owner && ast_mutex_trylock(&pkt->owner->owner->lock)) { 01239 ast_mutex_unlock(&pkt->owner->lock); 01240 usleep(1); 01241 ast_mutex_lock(&pkt->owner->lock); 01242 } 01243 if (pkt->owner->owner) { 01244 ast_set_flag(pkt->owner, SIP_ALREADYGONE); 01245 ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid); 01246 ast_queue_hangup(pkt->owner->owner); 01247 ast_mutex_unlock(&pkt->owner->owner->lock); 01248 } else { 01249 /* If no channel owner, destroy now */ 01250 ast_set_flag(pkt->owner, SIP_NEEDDESTROY); 01251 } 01252 } 01253 /* In any case, go ahead and remove the packet */ 01254 prev = NULL; 01255 cur = pkt->owner->packets; 01256 while(cur) { 01257 if (cur == pkt) 01258 break; 01259 prev = cur; 01260 cur = cur->next; 01261 } 01262 if (cur) { 01263 if (prev) 01264 prev->next = cur->next; 01265 else 01266 pkt->owner->packets = cur->next; 01267 ast_mutex_unlock(&pkt->owner->lock); 01268 free(cur); 01269 pkt = NULL; 01270 } else 01271 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 01272 if (pkt) 01273 ast_mutex_unlock(&pkt->owner->lock); 01274 return 0; 01275 }
|
|
Definition at line 2908 of file chan_sip.c. References sip_request::sdp_start. 02909 { 02910 *iterator = req->sdp_start; 02911 }
|
|
send_request: Send SIP Request to the other part of the dialogue ---
Definition at line 1517 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(), sip_debug_test_pvt(), SIP_NAT, and SIP_NAT_ROUTE. 01518 { 01519 int res; 01520 char iabuf[INET_ADDRSTRLEN]; 01521 struct sip_request tmp; 01522 char tmpmsg[80]; 01523 01524 if (sip_debug_test_pvt(p)) { 01525 if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) 01526 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); 01527 else 01528 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); 01529 } 01530 if (reliable) { 01531 if (recordhistory) { 01532 parse_copy(&tmp, req); 01533 snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq")); 01534 append_history(p, "TxReqRel", tmpmsg); 01535 } 01536 res = __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable > 1), req->method); 01537 } else { 01538 if (recordhistory) { 01539 parse_copy(&tmp, req); 01540 snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq")); 01541 append_history(p, "TxReq", tmpmsg); 01542 } 01543 res = __sip_xmit(p, req->data, req->len); 01544 } 01545 return res; 01546 }
|
|
send_response: Transmit response on SIP request---
Definition at line 1483 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(), sip_debug_test_pvt(), SIP_NAT, and SIP_NAT_ROUTE. 01484 { 01485 int res; 01486 char iabuf[INET_ADDRSTRLEN]; 01487 struct sip_request tmp; 01488 char tmpmsg[80]; 01489 01490 if (sip_debug_test_pvt(p)) { 01491 if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) 01492 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); 01493 else 01494 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); 01495 } 01496 if (reliable) { 01497 if (recordhistory) { 01498 parse_copy(&tmp, req); 01499 snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq")); 01500 append_history(p, "TxRespRel", tmpmsg); 01501 } 01502 res = __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable > 1), req->method); 01503 } else { 01504 if (recordhistory) { 01505 parse_copy(&tmp, req); 01506 snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq")); 01507 append_history(p, "TxResp", tmpmsg); 01508 } 01509 res = __sip_xmit(p, req->data, req->len); 01510 } 01511 if (res > 0) 01512 return 0; 01513 return res; 01514 }
|
|
set_destination: Set destination from SIP URI ---
Definition at line 3994 of file chan_sip.c. References ahp, 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(). 03995 { 03996 char *h, *maddr, hostname[256]; 03997 char iabuf[INET_ADDRSTRLEN]; 03998 int port, hn; 03999 struct hostent *hp; 04000 struct ast_hostent ahp; 04001 int debug=sip_debug_test_pvt(p); 04002 04003 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 04004 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 04005 04006 if (debug) 04007 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 04008 04009 /* Find and parse hostname */ 04010 h = strchr(uri, '@'); 04011 if (h) 04012 ++h; 04013 else { 04014 h = uri; 04015 if (strncmp(h, "sip:", 4) == 0) 04016 h += 4; 04017 else if (strncmp(h, "sips:", 5) == 0) 04018 h += 5; 04019 } 04020 hn = strcspn(h, ":;>") + 1; 04021 if (hn > sizeof(hostname)) 04022 hn = sizeof(hostname); 04023 ast_copy_string(hostname, h, hn); 04024 h += hn - 1; 04025 04026 /* Is "port" present? if not default to DEFAULT_SIP_PORT */ 04027 if (*h == ':') { 04028 /* Parse port */ 04029 ++h; 04030 port = strtol(h, &h, 10); 04031 } 04032 else 04033 port = DEFAULT_SIP_PORT; 04034 04035 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 04036 maddr = strstr(h, "maddr="); 04037 if (maddr) { 04038 maddr += 6; 04039 hn = strspn(maddr, "0123456789.") + 1; 04040 if (hn > sizeof(hostname)) hn = sizeof(hostname); 04041 ast_copy_string(hostname, maddr, hn); 04042 } 04043 04044 hp = ast_gethostbyname(hostname, &ahp); 04045 if (hp == NULL) { 04046 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 04047 return; 04048 } 04049 p->sa.sin_family = AF_INET; 04050 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 04051 p->sa.sin_port = htons(port); 04052 if (debug) 04053 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), port); 04054 }
|
|
sip_addheader: Add a SIP header ---
Definition at line 13126 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(). 13127 { 13128 int no = 0; 13129 int ok = 0; 13130 char varbuf[128]; 13131 13132 if (ast_strlen_zero((char *)data)) { 13133 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 13134 return 0; 13135 } 13136 ast_mutex_lock(&chan->lock); 13137 13138 /* Check for headers */ 13139 while (!ok && no <= 50) { 13140 no++; 13141 snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%02d", no); 13142 if (ast_strlen_zero(pbx_builtin_getvar_helper(chan, varbuf + 1))) 13143 ok = 1; 13144 } 13145 if (ok) { 13146 pbx_builtin_setvar_helper (chan, varbuf, (char *)data); 13147 if (sipdebug) 13148 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", (char *) data, varbuf); 13149 } else { 13150 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 13151 } 13152 ast_mutex_unlock(&chan->lock); 13153 return 0; 13154 }
|
|
sip_addrcmp: Support routine for find_peer ---
Definition at line 1756 of file chan_sip.c. References sip_peer::addr, ast_test_flag, inaddrcmp(), and SIP_INSECURE_PORT. Referenced by find_peer(). 01757 { 01758 /* We know name is the first field, so we can cast */ 01759 struct sip_peer *p = (struct sip_peer *)name; 01760 return !(!inaddrcmp(&p->addr, sin) || 01761 (ast_test_flag(p, SIP_INSECURE_PORT) && 01762 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 01763 }
|
|
sip_alloc: Allocate SIP_PVT structure and set defaults ---
Definition at line 3081 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(), bindaddr, build_callid(), build_via(), calloc, default_context, default_fromdomain, free, global_capability, global_flags, global_musicclass, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, iflist, io, LOG_DEBUG, LOG_WARNING, make_our_tag(), NONE, option_debug, prefs, 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(). 03082 { 03083 struct sip_pvt *p; 03084 03085 if (!(p = calloc(1, sizeof(*p)))) 03086 return NULL; 03087 03088 ast_mutex_init(&p->lock); 03089 03090 p->method = intended_method; 03091 p->initid = -1; 03092 p->autokillid = -1; 03093 p->subscribed = NONE; 03094 p->stateid = -1; 03095 p->prefs = prefs; 03096 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 03097 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 03098 #ifdef OSP_SUPPORT 03099 p->osphandle = -1; 03100 p->osptimelimit = 0; 03101 #endif 03102 if (sin) { 03103 memcpy(&p->sa, sin, sizeof(p->sa)); 03104 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 03105 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 03106 } else { 03107 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 03108 } 03109 03110 p->branch = thread_safe_rand(); 03111 make_our_tag(p->tag, sizeof(p->tag)); 03112 /* Start with 101 instead of 1 */ 03113 p->ocseq = 101; 03114 03115 if (sip_methods[intended_method].need_rtp) { 03116 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 03117 if (videosupport) 03118 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 03119 if (!p->rtp || (videosupport && !p->vrtp)) { 03120 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", videosupport ? "and video" : "", strerror(errno)); 03121 ast_mutex_destroy(&p->lock); 03122 if (p->chanvars) { 03123 ast_variables_destroy(p->chanvars); 03124 p->chanvars = NULL; 03125 } 03126 free(p); 03127 return NULL; 03128 } 03129 ast_rtp_settos(p->rtp, tos); 03130 if (p->vrtp) 03131 ast_rtp_settos(p->vrtp, tos); 03132 p->rtptimeout = global_rtptimeout; 03133 p->rtpholdtimeout = global_rtpholdtimeout; 03134 p->rtpkeepalive = global_rtpkeepalive; 03135 } 03136 03137 if (useglobal_nat && sin) { 03138 /* Setup NAT structure according to global settings if we have an address */ 03139 ast_copy_flags(p, &global_flags, SIP_NAT); 03140 memcpy(&p->recv, sin, sizeof(p->recv)); 03141 if (p->rtp) 03142 ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 03143 if (p->vrtp) 03144 ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 03145 } 03146 03147 if (p->method != SIP_REGISTER) 03148 ast_copy_string(p->fromdomain, default_fromdomain, sizeof(p->fromdomain)); 03149 build_via(p, p->via, sizeof(p->via)); 03150 if (!callid) 03151 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 03152 else 03153 ast_copy_string(p->callid, callid, sizeof(p->callid)); 03154 ast_copy_flags(p, &global_flags, SIP_FLAGS_TO_COPY); 03155 /* Assign default music on hold class */ 03156 strcpy(p->musicclass, global_musicclass); 03157 p->capability = global_capability; 03158 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO)) 03159 p->noncodeccapability |= AST_RTP_DTMF; 03160 strcpy(p->context, default_context); 03161 03162 /* Add to active dialog list */ 03163 ast_mutex_lock(&iflock); 03164 p->next = iflist; 03165 iflist = p; 03166 ast_mutex_unlock(&iflock); 03167 if (option_debug) 03168 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"); 03169 return p; 03170 }
|
|
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface
Definition at line 2543 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(). 02544 { 02545 int res = 0; 02546 struct sip_pvt *p = ast->tech_pvt; 02547 02548 ast_mutex_lock(&p->lock); 02549 if (ast->_state != AST_STATE_UP) { 02550 #ifdef OSP_SUPPORT 02551 time(&p->ospstart); 02552 #endif 02553 try_suggested_sip_codec(p); 02554 02555 ast_setstate(ast, AST_STATE_UP); 02556 if (option_debug) 02557 ast_log(LOG_DEBUG, "sip_answer(%s)\n", ast->name); 02558 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, 1); 02559 } 02560 ast_mutex_unlock(&p->lock); 02561 return res; 02562 }
|
|
sip_call: Initiate SIP call from PBX used from the dial() application
Definition at line 2022 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, sched, 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. 02023 { 02024 int res; 02025 struct sip_pvt *p; 02026 #ifdef OSP_SUPPORT 02027 char *osphandle = NULL; 02028 #endif 02029 struct varshead *headp; 02030 struct ast_var_t *current; 02031 02032 02033 02034 p = ast->tech_pvt; 02035 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 02036 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 02037 return -1; 02038 } 02039 02040 02041 /* Check whether there is vxml_url, distinctive ring variables */ 02042 02043 headp=&ast->varshead; 02044 AST_LIST_TRAVERSE(headp,current,entries) { 02045 /* Check whether there is a VXML_URL variable */ 02046 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 02047 p->options->vxml_url = ast_var_value(current); 02048 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 02049 p->options->uri_options = ast_var_value(current); 02050 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 02051 /* Check whether there is a ALERT_INFO variable */ 02052 p->options->distinctive_ring = ast_var_value(current); 02053 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 02054 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 02055 p->options->addsipheaders = 1; 02056 } 02057 02058 02059 #ifdef OSP_SUPPORT 02060 else if (!p->options->osptoken && !strcasecmp(ast_var_name(current), "OSPTOKEN")) { 02061 p->options->osptoken = ast_var_value(current); 02062 } else if (!osphandle && !strcasecmp(ast_var_name(current), "OSPHANDLE")) { 02063 osphandle = ast_var_value(current); 02064 } 02065 #endif 02066 } 02067 02068 res = 0; 02069 ast_set_flag(p, SIP_OUTGOING); 02070 #ifdef OSP_SUPPORT 02071 if (!p->options->osptoken || !osphandle || (sscanf(osphandle, "%d", &p->osphandle) != 1)) { 02072 /* Force Disable OSP support */ 02073 ast_log(LOG_DEBUG, "Disabling OSP support for this call. osptoken = %s, osphandle = %s\n", p->options->osptoken, osphandle); 02074 p->options->osptoken = NULL; 02075 osphandle = NULL; 02076 p->osphandle = -1; 02077 } 02078 #endif 02079 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 02080 res = update_call_counter(p, INC_CALL_LIMIT); 02081 if ( res != -1 ) { 02082 p->callingpres = ast->cid.cid_pres; 02083 p->jointcapability = p->capability; 02084 transmit_invite(p, SIP_INVITE, 1, 2); 02085 if (p->maxtime) { 02086 /* Initialize auto-congest time */ 02087 p->initid = ast_sched_add(sched, p->maxtime * 4, auto_congest, p); 02088 } 02089 } 02090 return res; 02091 }
|
|
sip_cancel_destroy: Cancel destruction of SIP call ---
Definition at line 1363 of file chan_sip.c. References append_history(), ast_sched_del(), sip_pvt::autokillid, and sched. Referenced by cb_extensionstate(), check_user_full(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), and register_verify(). 01364 { 01365 if (p->autokillid > -1) 01366 ast_sched_del(sched, p->autokillid); 01367 append_history(p, "CancelDestroy", ""); 01368 p->autokillid = -1; 01369 return 0; 01370 }
|
|
sip_debug_test_addr: See if we pass debug IP filter
Definition at line 1050 of file chan_sip.c. Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read(). 01051 { 01052 if (sipdebug == 0) 01053 return 0; 01054 if (debugaddr.sin_addr.s_addr) { 01055 if (((ntohs(debugaddr.sin_port) != 0) 01056 && (debugaddr.sin_port != addr->sin_port)) 01057 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01058 return 0; 01059 } 01060 return 1; 01061 }
|
|
sip_debug_test_pvt: Test PVT for debugging output
Definition at line 1064 of file chan_sip.c. References ast_test_flag, sip_pvt::recv, sip_pvt::sa, sip_debug_test_addr(), SIP_NAT, and SIP_NAT_ROUTE. Referenced by __sip_destroy(), add_sdp(), 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(). 01065 { 01066 if (sipdebug == 0) 01067 return 0; 01068 return sip_debug_test_addr(((ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? &p->recv : &p->sa)); 01069 }
|
|
sip_destroy: Destroy SIP call structure ---
Definition at line 2286 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(). 02287 { 02288 ast_mutex_lock(&iflock); 02289 __sip_destroy(p, 1); 02290 ast_mutex_unlock(&iflock); 02291 }
|
|
|
sip_destroy_user: Remove user object from in-memory storage ---
Definition at line 1785 of file chan_sip.c. References ast_free_ha(), ast_test_flag, ast_variables_destroy(), free, SIP_REALTIME, and user. Referenced by check_user_full(), reload_config(), sip_show_user(), unload_module(), and update_call_counter(). 01786 { 01787 ast_free_ha(user->ha); 01788 if (user->chanvars) { 01789 ast_variables_destroy(user->chanvars); 01790 user->chanvars = NULL; 01791 } 01792 if (ast_test_flag(user, SIP_REALTIME)) 01793 ruserobjs--; 01794 else 01795 suserobjs--; 01796 free(user); 01797 }
|
|
sip_devicestate: Part of PBX channel interface ---
Definition at line 11751 of file chan_sip.c. References sip_peer::addr, ahp, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_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(). 11752 { 11753 char *host; 11754 char *tmp; 11755 11756 struct hostent *hp; 11757 struct ast_hostent ahp; 11758 struct sip_peer *p; 11759 11760 int res = AST_DEVICE_INVALID; 11761 11762 host = ast_strdupa(data); 11763 if ((tmp = strchr(host, '@'))) 11764 host = tmp + 1; 11765 11766 if (option_debug > 2) 11767 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 11768 11769 if ((p = find_peer(host, NULL, 1))) { 11770 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 11771 /* we have an address for the peer */ 11772 /* if qualify is turned on, check the status */ 11773 if (p->maxms && (p->lastms > p->maxms)) { 11774 res = AST_DEVICE_UNAVAILABLE; 11775 } else { 11776 /* qualify is not on, or the peer is responding properly */ 11777 /* check call limit */ 11778 if (p->call_limit && (p->inUse == p->call_limit)) 11779 res = AST_DEVICE_BUSY; 11780 else if (p->call_limit && p->inUse) 11781 res = AST_DEVICE_INUSE; 11782 else if (p->call_limit) 11783 res = AST_DEVICE_NOT_INUSE; 11784 else 11785 res = AST_DEVICE_UNKNOWN; 11786 } 11787 } else { 11788 /* there is no address, it's unavailable */ 11789 res = AST_DEVICE_UNAVAILABLE; 11790 } 11791 ASTOBJ_UNREF(p,sip_destroy_peer); 11792 } else { 11793 hp = ast_gethostbyname(host, &ahp); 11794 if (hp) 11795 res = AST_DEVICE_UNKNOWN; 11796 } 11797 11798 return res; 11799 }
|
|
sip_do_debug: Turn on SIP debugging (CLI command)
Definition at line 8929 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. 08930 { 08931 int oldsipdebug = sipdebug & SIP_DEBUG_CONSOLE; 08932 if (argc != 2) { 08933 if (argc != 4) 08934 return RESULT_SHOWUSAGE; 08935 else if (strncmp(argv[2], "ip\0", 3) == 0) 08936 return sip_do_debug_ip(fd, argc, argv); 08937 else if (strncmp(argv[2], "peer\0", 5) == 0) 08938 return sip_do_debug_peer(fd, argc, argv); 08939 else return RESULT_SHOWUSAGE; 08940 } 08941 sipdebug |= SIP_DEBUG_CONSOLE; 08942 memset(&debugaddr, 0, sizeof(debugaddr)); 08943 if (oldsipdebug) 08944 ast_cli(fd, "SIP Debugging re-enabled\n"); 08945 else 08946 ast_cli(fd, "SIP Debugging enabled\n"); 08947 return RESULT_SUCCESS; 08948 }
|
|
sip_do_debug: Enable SIP Debugging in CLI ---
Definition at line 8873 of file chan_sip.c. References ahp, ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), debugaddr, hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, and sipdebug. Referenced by sip_do_debug(). 08874 { 08875 struct hostent *hp; 08876 struct ast_hostent ahp; 08877 char iabuf[INET_ADDRSTRLEN]; 08878 int port = 0; 08879 char *p, *arg; 08880 08881 if (argc != 4) 08882 return RESULT_SHOWUSAGE; 08883 arg = argv[3]; 08884 p = strstr(arg, ":"); 08885 if (p) { 08886 *p = '\0'; 08887 p++; 08888 port = atoi(p); 08889 } 08890 hp = ast_gethostbyname(arg, &ahp); 08891 if (hp == NULL) { 08892 return RESULT_SHOWUSAGE; 08893 } 08894 debugaddr.sin_family = AF_INET; 08895 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 08896 debugaddr.sin_port = htons(port); 08897 if (port == 0) 08898 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr)); 08899 else 08900 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), port); 08901 sipdebug |= SIP_DEBUG_CONSOLE; 08902 return RESULT_SUCCESS; 08903 }
|
|
sip_do_debug_peer: Turn on SIP debugging with peer mask
Definition at line 8906 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(). 08907 { 08908 struct sip_peer *peer; 08909 char iabuf[INET_ADDRSTRLEN]; 08910 if (argc != 4) 08911 return RESULT_SHOWUSAGE; 08912 peer = find_peer(argv[3], NULL, 1); 08913 if (peer) { 08914 if (peer->addr.sin_addr.s_addr) { 08915 debugaddr.sin_family = AF_INET; 08916 memcpy(&debugaddr.sin_addr, &peer->addr.sin_addr, sizeof(debugaddr.sin_addr)); 08917 debugaddr.sin_port = peer->addr.sin_port; 08918 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 08919 sipdebug |= SIP_DEBUG_CONSOLE; 08920 } else 08921 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[3]); 08922 ASTOBJ_UNREF(peer,sip_destroy_peer); 08923 } else 08924 ast_cli(fd, "No such peer '%s'\n", argv[3]); 08925 return RESULT_SUCCESS; 08926 }
|
|
sip_do_history: Enable SIP History logging (CLI) ---
Definition at line 9008 of file chan_sip.c. References ast_cli(), recordhistory, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 09009 { 09010 if (argc != 2) { 09011 return RESULT_SHOWUSAGE; 09012 } 09013 recordhistory = 1; 09014 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 09015 return RESULT_SUCCESS; 09016 }
|
|
sip_do_reload: Reload module
Definition at line 13340 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(). 13341 { 13342 clear_realm_authentication(authl); 13343 clear_sip_domains(); 13344 authl = NULL; 13345 13346 /* First, destroy all outstanding registry calls */ 13347 /* This is needed, since otherwise active registry entries will not be destroyed */ 13348 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 13349 ASTOBJ_RDLOCK(iterator); 13350 if (iterator->call) { 13351 if (option_debug > 2) 13352 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 13353 /* This will also remove references to the registry */ 13354 sip_destroy(iterator->call); 13355 } 13356 ASTOBJ_UNLOCK(iterator); 13357 } while(0)); 13358 13359 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 13360 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 13361 ASTOBJ_CONTAINER_MARKALL(&peerl); 13362 reload_config(); 13363 /* Prune peers who still are supposed to be deleted */ 13364 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 13365 13366 sip_poke_all_peers(); 13367 sip_send_all_registers(); 13368 13369 return 0; 13370 }
|
|
sip_dtmfmode: change the DTMFmode for a SIP call (application) ---
Definition at line 13076 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(). 13077 { 13078 struct sip_pvt *p; 13079 char *mode; 13080 if (data) 13081 mode = (char *)data; 13082 else { 13083 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 13084 return 0; 13085 } 13086 ast_mutex_lock(&chan->lock); 13087 if (chan->type != channeltype) { 13088 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 13089 ast_mutex_unlock(&chan->lock); 13090 return 0; 13091 } 13092 p = chan->tech_pvt; 13093 if (!p) { 13094 ast_mutex_unlock(&chan->lock); 13095 return 0; 13096 } 13097 ast_mutex_lock(&p->lock); 13098 if (!strcasecmp(mode,"info")) { 13099 ast_clear_flag(p, SIP_DTMF); 13100 ast_set_flag(p, SIP_DTMF_INFO); 13101 } else if (!strcasecmp(mode,"rfc2833")) { 13102 ast_clear_flag(p, SIP_DTMF); 13103 ast_set_flag(p, SIP_DTMF_RFC2833); 13104 } else if (!strcasecmp(mode,"inband")) { 13105 ast_clear_flag(p, SIP_DTMF); 13106 ast_set_flag(p, SIP_DTMF_INBAND); 13107 } else 13108 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 13109 if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) { 13110 if (!p->vad) { 13111 p->vad = ast_dsp_new(); 13112 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 13113 } 13114 } else { 13115 if (p->vad) { 13116 ast_dsp_free(p->vad); 13117 p->vad = NULL; 13118 } 13119 } 13120 ast_mutex_unlock(&p->lock); 13121 ast_mutex_unlock(&chan->lock); 13122 return 0; 13123 }
|
|
dump_history: Dump SIP history to debug log file at end of lifespan for SIP dialog
Definition at line 8754 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(). 08755 { 08756 int x; 08757 struct sip_history *hist; 08758 08759 if (!dialog) 08760 return; 08761 08762 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 08763 if (dialog->subscribed) 08764 ast_log(LOG_DEBUG, " * Subscription\n"); 08765 else 08766 ast_log(LOG_DEBUG, " * SIP Call\n"); 08767 x = 0; 08768 hist = dialog->history; 08769 while(hist) { 08770 x++; 08771 ast_log(LOG_DEBUG, " %d. %s\n", x, hist->event); 08772 hist = hist->next; 08773 } 08774 if (!x) 08775 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 08776 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 08777 08778 }
|
|
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links ----
Definition at line 2618 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. 02619 { 02620 struct sip_pvt *p = newchan->tech_pvt; 02621 ast_mutex_lock(&p->lock); 02622 if (p->owner != oldchan) { 02623 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 02624 ast_mutex_unlock(&p->lock); 02625 return -1; 02626 } 02627 p->owner = newchan; 02628 ast_mutex_unlock(&p->lock); 02629 return 0; 02630 }
|
|
sip_get_codec: Return SIP UA's codec (part of the RTP interface) ---
Definition at line 13291 of file chan_sip.c. References sip_pvt::peercapability, and ast_channel::tech_pvt. 13292 { 13293 struct sip_pvt *p = chan->tech_pvt; 13294 return p->peercapability; 13295 }
|
|
sip_get_rtp_peer: Returns null if we can't reinvite (part of RTP interface)
Definition at line 12968 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. 12969 { 12970 struct sip_pvt *p; 12971 struct ast_rtp *rtp = NULL; 12972 p = chan->tech_pvt; 12973 if (!p) 12974 return NULL; 12975 ast_mutex_lock(&p->lock); 12976 if (p->rtp && ast_test_flag(p, SIP_CAN_REINVITE)) 12977 rtp = p->rtp; 12978 ast_mutex_unlock(&p->lock); 12979 return rtp; 12980 }
|
|
sip_get_vrtp_peer: Returns null if we can't reinvite video (part of RTP interface)
Definition at line 12983 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. 12984 { 12985 struct sip_pvt *p; 12986 struct ast_rtp *rtp = NULL; 12987 p = chan->tech_pvt; 12988 if (!p) 12989 return NULL; 12990 12991 ast_mutex_lock(&p->lock); 12992 if (p->vrtp && ast_test_flag(p, SIP_CAN_REINVITE)) 12993 rtp = p->vrtp; 12994 ast_mutex_unlock(&p->lock); 12995 return rtp; 12996 }
|
|
sip_getheader: Get a SIP header (dialplan app) ---
Definition at line 13157 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(). 13158 { 13159 char *argv, *varname = NULL, *header = NULL, *content, *options = NULL; 13160 static int dep_warning = 0; 13161 struct sip_pvt *p; 13162 int priority_jump = 0; 13163 13164 if (!dep_warning) { 13165 ast_log(LOG_WARNING, "SIPGetHeader is deprecated, use the SIP_HEADER function instead.\n"); 13166 dep_warning = 1; 13167 } 13168 13169 argv = ast_strdupa(data); 13170 if (!argv) { 13171 ast_log(LOG_DEBUG, "Memory allocation failed\n"); 13172 return 0; 13173 } 13174 13175 if (strchr (argv, '=') ) { /* Pick out argument */ 13176 varname = strsep (&argv, "="); 13177 if (strchr(argv, '|')) { 13178 header = strsep (&argv, "|"); 13179 options = strsep (&argv, "\0"); 13180 } else { 13181 header = strsep (&argv, "\0"); 13182 } 13183 13184 } 13185 13186 if (!varname || !header) { 13187 ast_log(LOG_DEBUG, "SIPGetHeader: Ignoring command, Syntax error in argument\n"); 13188 return 0; 13189 } 13190 13191 if (options) { 13192 if (strchr(options, 'j')) 13193 priority_jump = 1; 13194 } 13195 13196 ast_mutex_lock(&chan->lock); 13197 if (chan->type != channeltype) { 13198 ast_log(LOG_WARNING, "Call this application only on incoming SIP calls\n"); 13199 ast_mutex_unlock(&chan->lock); 13200 return 0; 13201 } 13202 13203 p = chan->tech_pvt; 13204 content = get_header(&p->initreq, header); /* Get the header */ 13205 if (!ast_strlen_zero(content)) { 13206 pbx_builtin_setvar_helper(chan, varname, content); 13207 if (option_verbose > 2) 13208 ast_verbose(VERBOSE_PREFIX_3 "SIPGetHeader: set variable %s to %s\n", varname, content); 13209 pbx_builtin_setvar_helper(chan, "SIPGETSTATUS", "FOUND"); 13210 } else { 13211 ast_log(LOG_WARNING,"SIP Header %s not found for channel variable %s\n", header, varname); 13212 if (priority_jump || option_priority_jumping) { 13213 /* Goto priority n+101 if it exists, where n is the current priority number */ 13214 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101); 13215 } 13216 pbx_builtin_setvar_helper(chan, "SIPGETSTATUS", "NOTFOUND"); 13217 } 13218 13219 ast_mutex_unlock(&chan->lock); 13220 return 0; 13221 }
|
|
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup
Definition at line 2416 of file chan_sip.c. References __sip_pretend_ack(), ast_channel::_state, AST_CAUSE_NORMAL, ast_clear_flag, 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_lock, sip_pvt::username, and sip_pvt::vad. 02417 { 02418 struct sip_pvt *p = ast->tech_pvt; 02419 int needcancel = 0; 02420 int needdestroy = 0; 02421 02422 if (!p) { 02423 ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n"); 02424 return 0; 02425 } 02426 if (option_debug) 02427 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 02428 02429 ast_mutex_lock(&p->lock); 02430 #ifdef OSP_SUPPORT 02431 if ((p->osphandle > -1) && (ast->_state == AST_STATE_UP)) { 02432 ast_osp_terminate(p->osphandle, AST_CAUSE_NORMAL, p->ospstart, time(NULL) - p->ospstart); 02433 } 02434 #endif 02435 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter\n", p->username); 02436 update_call_counter(p, DEC_CALL_LIMIT); 02437 /* Determine how to disconnect */ 02438 if (p->owner != ast) { 02439 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 02440 ast_mutex_unlock(&p->lock); 02441 return 0; 02442 } 02443 /* If the call is not UP, we need to send CANCEL instead of BYE */ 02444 if (ast->_state != AST_STATE_UP) 02445 needcancel = 1; 02446 02447 /* Disconnect */ 02448 if (p->vad) { 02449 ast_dsp_free(p->vad); 02450 } 02451 p->owner = NULL; 02452 ast->tech_pvt = NULL; 02453 02454 ast_mutex_lock(&usecnt_lock); 02455 usecnt--; 02456 ast_mutex_unlock(&usecnt_lock); 02457 ast_update_use_count(); 02458 02459 /* Do not destroy this pvt until we have timeout or 02460 get an answer to the BYE or INVITE/CANCEL 02461 If we get no answer during retransmit period, drop the call anyway. 02462 (Sorry, mother-in-law, you can't deny a hangup by sending 02463 603 declined to BYE...) 02464 */ 02465 if (ast_test_flag(p, SIP_ALREADYGONE)) 02466 needdestroy = 1; /* Set destroy flag at end of this function */ 02467 else 02468 sip_scheddestroy(p, 32000); 02469 02470 /* Start the process if it's not already started */ 02471 if (!ast_test_flag(p, SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 02472 if (needcancel) { /* Outgoing call, not up */ 02473 if (ast_test_flag(p, SIP_OUTGOING)) { 02474 /* stop retransmitting an INVITE that has not received a response */ 02475 __sip_pretend_ack(p); 02476 02477 /* are we allowed to send CANCEL yet? if not, mark 02478 it pending */ 02479 if (!ast_test_flag(p, SIP_CAN_BYE)) { 02480 ast_set_flag(p, SIP_PENDINGBYE); 02481 /* Do we need a timer here if we don't hear from them at all? */ 02482 } else { 02483 /* Send a new request: CANCEL */ 02484 transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0); 02485 /* Actually don't destroy us yet, wait for the 487 on our original 02486 INVITE, but do set an autodestruct just in case we never get it. */ 02487 } 02488 if ( p->initid != -1 ) { 02489 /* channel still up - reverse dec of inUse counter 02490 only if the channel is not auto-congested */ 02491 update_call_counter(p, INC_CALL_LIMIT); 02492 } 02493 } else { /* Incoming call, not up */ 02494 char *res; 02495 if (ast->hangupcause && ((res = hangup_cause2sip(ast->hangupcause)))) { 02496 transmit_response_reliable(p, res, &p->initreq, 1); 02497 } else 02498 transmit_response_reliable(p, "603 Declined", &p->initreq, 1); 02499 } 02500 } else { /* Call is in UP state, send BYE */ 02501 if (!p->pendinginvite) { 02502 /* Send a hangup */ 02503 transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); 02504 } else { 02505 /* Note we will need a BYE when this all settles out 02506 but we can't send one while we have "INVITE" outstanding. */ 02507 ast_set_flag(p, SIP_PENDINGBYE); 02508 ast_clear_flag(p, SIP_NEEDREINVITE); 02509 } 02510 } 02511 } 02512 if (needdestroy) 02513 ast_set_flag(p, SIP_NEEDDESTROY); 02514 ast_mutex_unlock(&p->lock); 02515 return 0; 02516 }
|
|
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 2675 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, ast_channel::tech_pvt, transmit_info_with_vidupdate(), transmit_response(), transmit_response_with_sdp(), and sip_pvt::vrtp. 02676 { 02677 struct sip_pvt *p = ast->tech_pvt; 02678 int res = 0; 02679 02680 ast_mutex_lock(&p->lock); 02681 switch(condition) { 02682 case AST_CONTROL_RINGING: 02683 if (ast->_state == AST_STATE_RING) { 02684 if (!ast_test_flag(p, SIP_PROGRESS_SENT) || 02685 (ast_test_flag(p, SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 02686 /* Send 180 ringing if out-of-band seems reasonable */ 02687 transmit_response(p, "180 Ringing", &p->initreq); 02688 ast_set_flag(p, SIP_RINGING); 02689 if (ast_test_flag(p, SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 02690 break; 02691 } else { 02692 /* Well, if it's not reasonable, just send in-band */ 02693 } 02694 } 02695 res = -1; 02696 break; 02697 case AST_CONTROL_BUSY: 02698 if (ast->_state != AST_STATE_UP) { 02699 transmit_response(p, "486 Busy Here", &p->initreq); 02700 ast_set_flag(p, SIP_ALREADYGONE); 02701 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 02702 break; 02703 } 02704 res = -1; 02705 break; 02706 case AST_CONTROL_CONGESTION: 02707 if (ast->_state != AST_STATE_UP) { 02708 transmit_response(p, "503 Service Unavailable", &p->initreq); 02709 ast_set_flag(p, SIP_ALREADYGONE); 02710 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 02711 break; 02712 } 02713 res = -1; 02714 break; 02715 case AST_CONTROL_PROCEEDING: 02716 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02717 transmit_response(p, "100 Trying", &p->initreq); 02718 break; 02719 } 02720 res = -1; 02721 break; 02722 case AST_CONTROL_PROGRESS: 02723 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02724 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); 02725 ast_set_flag(p, SIP_PROGRESS_SENT); 02726 break; 02727 } 02728 res = -1; 02729 break; 02730 case AST_CONTROL_HOLD: /* The other part of the bridge are put on hold */ 02731 if (sipdebug) 02732 ast_log(LOG_DEBUG, "Bridged channel now on hold%s\n", p->callid); 02733 res = -1; 02734 break; 02735 case AST_CONTROL_UNHOLD: /* The other part of the bridge are back from hold */ 02736 if (sipdebug) 02737 ast_log(LOG_DEBUG, "Bridged channel is back from hold, let's talk! : %s\n", p->callid); 02738 res = -1; 02739 break; 02740 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 02741 if (p->vrtp && !ast_test_flag(p, SIP_NOVIDEO)) { 02742 transmit_info_with_vidupdate(p); 02743 res = 0; 02744 } else 02745 res = -1; 02746 break; 02747 case -1: 02748 res = -1; 02749 break; 02750 default: 02751 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 02752 res = -1; 02753 break; 02754 } 02755 ast_mutex_unlock(&p->lock); 02756 return res; 02757 }
|
|
sip_new: Initiate a call in the SIP channel
Definition at line 2763 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_setstate(), AST_STATE_DOWN, AST_STATE_RING, ast_strlen_zero(), ast_test_flag, ast_update_use_count(), ast_channel::callgroup, sip_pvt::capability, ast_channel::cid, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, 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, 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, ast_channel::rings, SIP_DTMF, SIP_DTMF_INBAND, sip_tech, strdup, ast_channel::tech, ast_channel::tech_pvt, ast_channel::type, usecnt_lock, ast_variable::value, and ast_channel::writeformat. Referenced by handle_request_invite(), and sip_request_call(). 02764 { 02765 struct ast_channel *tmp; 02766 struct ast_variable *v = NULL; 02767 int fmt; 02768 #ifdef OSP_SUPPORT 02769 char iabuf[INET_ADDRSTRLEN]; 02770 char peer[MAXHOSTNAMELEN]; 02771 #endif 02772 02773 ast_mutex_unlock(&i->lock); 02774 /* Don't hold a sip pvt lock while we allocate a channel */ 02775 tmp = ast_channel_alloc(1); 02776 ast_mutex_lock(&i->lock); 02777 if (!tmp) { 02778 ast_log(LOG_WARNING, "Unable to allocate SIP channel structure\n"); 02779 return NULL; 02780 } 02781 tmp->tech = &sip_tech; 02782 /* Select our native format based on codec preference until we receive 02783 something from another device to the contrary. */ 02784 if (i->jointcapability) 02785 tmp->nativeformats = ast_codec_choose(&i->prefs, i->jointcapability, 1); 02786 else if (i->capability) 02787 tmp->nativeformats = ast_codec_choose(&i->prefs, i->capability, 1); 02788 else 02789 tmp->nativeformats = ast_codec_choose(&i->prefs, global_capability, 1); 02790 fmt = ast_best_codec(tmp->nativeformats); 02791 02792 if (title) 02793 snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", title, (int)(long) i); 02794 else if (strchr(i->fromdomain,':')) 02795 snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", strchr(i->fromdomain,':') + 1, (int)(long) i); 02796 else 02797 snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", i->fromdomain, (int)(long) i); 02798 02799 tmp->type = channeltype; 02800 if (ast_test_flag(i, SIP_DTMF) == SIP_DTMF_INBAND) { 02801 i->vad = ast_dsp_new(); 02802 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 02803 if (relaxdtmf) 02804 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 02805 } 02806 if (i->rtp) { 02807 tmp->fds[0] = ast_rtp_fd(i->rtp); 02808 tmp->fds[1] = ast_rtcp_fd(i->rtp); 02809 } 02810 if (i->vrtp) { 02811 tmp->fds[2] = ast_rtp_fd(i->vrtp); 02812 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 02813 } 02814 if (state == AST_STATE_RING) 02815 tmp->rings = 1; 02816 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 02817 tmp->writeformat = fmt; 02818 tmp->rawwriteformat = fmt; 02819 tmp->readformat = fmt; 02820 tmp->rawreadformat = fmt; 02821 tmp->tech_pvt = i; 02822 02823 tmp->callgroup = i->callgroup; 02824 tmp->pickupgroup = i->pickupgroup; 02825 tmp->cid.cid_pres = i->callingpres; 02826 if (!ast_strlen_zero(i->accountcode)) 02827 ast_copy_string(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode)); 02828 if (i->amaflags) 02829 tmp->amaflags = i->amaflags; 02830 if (!ast_strlen_zero(i->language)) 02831 ast_copy_string(tmp->language, i->language, sizeof(tmp->language)); 02832 if (!ast_strlen_zero(i->musicclass)) 02833 ast_copy_string(tmp->musicclass, i->musicclass, sizeof(tmp->musicclass)); 02834 i->owner = tmp; 02835 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 02836 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 02837 02838 if (!ast_strlen_zero(i->cid_num)) 02839 tmp->cid.cid_num = strdup(i->cid_num); 02840 if (!ast_strlen_zero(i->cid_name)) 02841 tmp->cid.cid_name = strdup(i->cid_name); 02842 if (!ast_strlen_zero(i->rdnis)) 02843 tmp->cid.cid_rdnis = strdup(i->rdnis); 02844 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 02845 tmp->cid.cid_dnid = strdup(i->exten); 02846 02847 tmp->priority = 1; 02848 if (!ast_strlen_zero(i->uri)) { 02849 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 02850 } 02851 if (!ast_strlen_zero(i->domain)) { 02852 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 02853 } 02854 if (!ast_strlen_zero(i->useragent)) { 02855 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 02856 } 02857 if (!ast_strlen_zero(i->callid)) { 02858 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 02859 } 02860 #ifdef OSP_SUPPORT 02861 snprintf(peer, sizeof(peer), "[%s]:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), i->sa.sin_addr), ntohs(i->sa.sin_port)); 02862 pbx_builtin_setvar_helper(tmp, "OSPPEER", peer); 02863 #endif 02864 ast_setstate(tmp, state); 02865 if (state != AST_STATE_DOWN) { 02866 if (ast_pbx_start(tmp)) { 02867 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 02868 ast_hangup(tmp); 02869 tmp = NULL; 02870 } 02871 } 02872 /* Set channel variables for this call from configuration */ 02873 for (v = i->chanvars ; v ; v = v->next) 02874 pbx_builtin_setvar_helper(tmp,v->name,v->value); 02875 02876 ast_mutex_lock(&usecnt_lock); 02877 usecnt++; 02878 ast_mutex_unlock(&usecnt_lock); 02879 ast_update_use_count(); 02880 02881 return tmp; 02882 }
|
|
sip_no_debug: Disable SIP Debugging in CLI ---
Definition at line 9030 of file chan_sip.c. References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, and sipdebug. 09032 { 09033 if (argc != 3) 09034 return RESULT_SHOWUSAGE; 09035 sipdebug &= ~SIP_DEBUG_CONSOLE; 09036 ast_cli(fd, "SIP Debugging Disabled\n"); 09037 return RESULT_SUCCESS; 09038 }
|
|
sip_no_history: Disable SIP History logging (CLI) ---
Definition at line 9019 of file chan_sip.c. References ast_cli(), recordhistory, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 09020 { 09021 if (argc != 3) { 09022 return RESULT_SHOWUSAGE; 09023 } 09024 recordhistory = 0; 09025 ast_cli(fd, "SIP History Recording Disabled\n"); 09026 return RESULT_SUCCESS; 09027 }
|
|
sip_notify: Send SIP notify to peer
Definition at line 8951 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(), create_addr(), initreqprep(), LOG_WARNING, notify_config, notify_types, sip_pvt::ourip, RESULT_FAILURE, RESULT_SHOWUSAGE, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), var, and sip_pvt::via. 08952 { 08953 struct ast_variable *varlist; 08954 int i; 08955 08956 if (argc < 4) 08957 return RESULT_SHOWUSAGE; 08958 08959 if (!notify_types) { 08960 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 08961 return RESULT_FAILURE; 08962 } 08963 08964 varlist = ast_variable_browse(notify_types, argv[2]); 08965 08966 if (!varlist) { 08967 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 08968 return RESULT_FAILURE; 08969 } 08970 08971 for (i = 3; i < argc; i++) { 08972 struct sip_pvt *p; 08973 struct sip_request req; 08974 struct ast_variable *var; 08975 08976 p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY); 08977 if (!p) { 08978 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify\n"); 08979 return RESULT_FAILURE; 08980 } 08981 08982 if (create_addr(p, argv[i])) { 08983 /* Maybe they're not registered, etc. */ 08984 sip_destroy(p); 08985 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 08986 continue; 08987 } 08988 08989 initreqprep(&req, p, SIP_NOTIFY); 08990 08991 for (var = varlist; var; var = var->next) 08992 add_header(&req, var->name, var->value); 08993 08994 add_blank_header(&req); 08995 /* Recalculate our side, and recalculate Call ID */ 08996 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 08997 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 08998 build_via(p, p->via, sizeof(p->via)); 08999 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 09000 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 09001 transmit_sip_request(p, &req); 09002 sip_scheddestroy(p, 15000); 09003 } 09004 09005 return RESULT_SUCCESS; 09006 }
|
|
sip_park: Park a call ---
Definition at line 10281 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(). 10282 { 10283 struct sip_dual *d; 10284 struct ast_channel *chan1m, *chan2m; 10285 pthread_t th; 10286 chan1m = ast_channel_alloc(0); 10287 chan2m = ast_channel_alloc(0); 10288 if ((!chan2m) || (!chan1m)) { 10289 if (chan1m) 10290 ast_hangup(chan1m); 10291 if (chan2m) 10292 ast_hangup(chan2m); 10293 return -1; 10294 } 10295 snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name); 10296 /* Make formats okay */ 10297 chan1m->readformat = chan1->readformat; 10298 chan1m->writeformat = chan1->writeformat; 10299 ast_channel_masquerade(chan1m, chan1); 10300 /* Setup the extensions and such */ 10301 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 10302 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 10303 chan1m->priority = chan1->priority; 10304 10305 /* We make a clone of the peer channel too, so we can play 10306 back the announcement */ 10307 snprintf(chan2m->name, sizeof (chan2m->name), "SIPPeer/%s",chan2->name); 10308 /* Make formats okay */ 10309 chan2m->readformat = chan2->readformat; 10310 chan2m->writeformat = chan2->writeformat; 10311 ast_channel_masquerade(chan2m, chan2); 10312 /* Setup the extensions and such */ 10313 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 10314 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 10315 chan2m->priority = chan2->priority; 10316 ast_mutex_lock(&chan2m->lock); 10317 if (ast_do_masquerade(chan2m)) { 10318 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 10319 ast_mutex_unlock(&chan2m->lock); 10320 ast_hangup(chan2m); 10321 return -1; 10322 } 10323 ast_mutex_unlock(&chan2m->lock); 10324 d = malloc(sizeof(struct sip_dual)); 10325 if (d) { 10326 memset(d, 0, sizeof(*d)); 10327 /* Save original request for followup */ 10328 copy_request(&d->req, req); 10329 d->chan1 = chan1m; 10330 d->chan2 = chan2m; 10331 if (!ast_pthread_create(&th, NULL, sip_park_thread, d)) 10332 return 0; 10333 free(d); 10334 } 10335 return -1; 10336 }
|
|
sip_park_thread: Park SIP call support function
Definition at line 10258 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(). 10259 { 10260 struct ast_channel *chan1, *chan2; 10261 struct sip_dual *d; 10262 struct sip_request req; 10263 int ext; 10264 int res; 10265 d = stuff; 10266 chan1 = d->chan1; 10267 chan2 = d->chan2; 10268 copy_request(&req, &d->req); 10269 free(d); 10270 ast_mutex_lock(&chan1->lock); 10271 ast_do_masquerade(chan1); 10272 ast_mutex_unlock(&chan1->lock); 10273 res = ast_park_call(chan1, chan2, 0, &ext); 10274 /* Then hangup */ 10275 ast_hangup(chan2); 10276 ast_log(LOG_DEBUG, "Parked on extension '%d'\n", ext); 10277 return NULL; 10278 }
|
|
sip_poke_all_peers: Send a poke to all known peers
Definition at line 13307 of file chan_sip.c. References ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, peerl, and sip_poke_peer(). Referenced by load_module(). 13308 { 13309 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 13310 ASTOBJ_WRLOCK(iterator); 13311 sip_poke_peer(iterator); 13312 ASTOBJ_UNLOCK(iterator); 13313 } while (0) 13314 ); 13315 }
|
|
sip_poke_noanswer: No answer to Qualify poke ---
Definition at line 11655 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(). 11656 { 11657 struct sip_peer *peer = data; 11658 11659 peer->pokeexpire = -1; 11660 if (peer->lastms > -1) { 11661 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 11662 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 11663 } 11664 if (peer->call) 11665 sip_destroy(peer->call); 11666 peer->call = NULL; 11667 peer->lastms = -1; 11668 ast_device_state_changed("SIP/%s", peer->name); 11669 /* Try again quickly */ 11670 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 11671 return 0; 11672 }
|
|
sip_poke_peer: Check availability of peer, also keep NAT open ---
Definition at line 11677 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(). 11678 { 11679 struct sip_pvt *p; 11680 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 11681 /* IF we have no IP, or this isn't to be monitored, return 11682 imeediately after clearing things out */ 11683 if (peer->pokeexpire > -1) 11684 ast_sched_del(sched, peer->pokeexpire); 11685 peer->lastms = 0; 11686 peer->pokeexpire = -1; 11687 peer->call = NULL; 11688 return 0; 11689 } 11690 if (peer->call > 0) { 11691 if (sipdebug) 11692 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 11693 sip_destroy(peer->call); 11694 } 11695 p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS); 11696 if (!peer->call) { 11697 ast_log(LOG_WARNING, "Unable to allocate dialog for poking peer '%s'\n", peer->name); 11698 return -1; 11699 } 11700 memcpy(&p->sa, &peer->addr, sizeof(p->sa)); 11701 memcpy(&p->recv, &peer->addr, sizeof(p->sa)); 11702 ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY); 11703 11704 /* Send OPTIONs to peer's fullcontact */ 11705 if (!ast_strlen_zero(peer->fullcontact)) { 11706 ast_copy_string (p->fullcontact, peer->fullcontact, sizeof(p->fullcontact)); 11707 } 11708 11709 if (!ast_strlen_zero(peer->tohost)) 11710 ast_copy_string(p->tohost, peer->tohost, sizeof(p->tohost)); 11711 else 11712 ast_inet_ntoa(p->tohost, sizeof(p->tohost), peer->addr.sin_addr); 11713 11714 /* Recalculate our side, and recalculate Call ID */ 11715 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11716 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11717 build_via(p, p->via, sizeof(p->via)); 11718 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11719 11720 if (peer->pokeexpire > -1) 11721 ast_sched_del(sched, peer->pokeexpire); 11722 p->peerpoke = peer; 11723 ast_set_flag(p, SIP_OUTGOING); 11724 #ifdef VOCAL_DATA_HACK 11725 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 11726 transmit_invite(p, SIP_INVITE, 0, 2); 11727 #else 11728 transmit_invite(p, SIP_OPTIONS, 0, 2); 11729 #endif 11730 gettimeofday(&peer->ps, NULL); 11731 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer); 11732 11733 return 0; 11734 }
|
|
Definition at line 5806 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(). 05807 { 05808 struct sip_peer *peer = data; 05809 peer->pokeexpire = -1; 05810 sip_poke_peer(peer); 05811 return 0; 05812 }
|
|
sip_prune_realtime: Remove temporary realtime objects from memory (CLI) ---
Definition at line 7823 of file chan_sip.c. References ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, name, peerl, RESULT_SHOWUSAGE, SIP_PAGE2_RTCACHEFRIENDS, and user. 07824 { 07825 struct sip_peer *peer; 07826 struct sip_user *user; 07827 int pruneuser = 0; 07828 int prunepeer = 0; 07829 int multi = 0; 07830 char *name = NULL; 07831 regex_t regexbuf; 07832 07833 switch (argc) { 07834 case 4: 07835 if (!strcasecmp(argv[3], "user")) 07836 return RESULT_SHOWUSAGE; 07837 if (!strcasecmp(argv[3], "peer")) 07838 return RESULT_SHOWUSAGE; 07839 if (!strcasecmp(argv[3], "like")) 07840 return RESULT_SHOWUSAGE; 07841 if (!strcasecmp(argv[3], "all")) { 07842 multi = 1; 07843 pruneuser = prunepeer = 1; 07844 } else { 07845 pruneuser = prunepeer = 1; 07846 name = argv[3]; 07847 } 07848 break; 07849 case 5: 07850 if (!strcasecmp(argv[4], "like")) 07851 return RESULT_SHOWUSAGE; 07852 if (!strcasecmp(argv[3], "all")) 07853 return RESULT_SHOWUSAGE; 07854 if (!strcasecmp(argv[3], "like")) { 07855 multi = 1; 07856 name = argv[4]; 07857 pruneuser = prunepeer = 1; 07858 } else if (!strcasecmp(argv[3], "user")) { 07859 pruneuser = 1; 07860 if (!strcasecmp(argv[4], "all")) 07861 multi = 1; 07862 else 07863 name = argv[4]; 07864 } else if (!strcasecmp(argv[3], "peer")) { 07865 prunepeer = 1; 07866 if (!strcasecmp(argv[4], "all")) 07867 multi = 1; 07868 else 07869 name = argv[4]; 07870 } else 07871 return RESULT_SHOWUSAGE; 07872 break; 07873 case 6: 07874 if (strcasecmp(argv[4], "like")) 07875 return RESULT_SHOWUSAGE; 07876 if (!strcasecmp(argv[3], "user")) { 07877 pruneuser = 1; 07878 name = argv[5]; 07879 } else if (!strcasecmp(argv[3], "peer")) { 07880 prunepeer = 1; 07881 name = argv[5]; 07882 } else 07883 return RESULT_SHOWUSAGE; 07884 break; 07885 default: 07886 return RESULT_SHOWUSAGE; 07887 } 07888 07889 if (multi && name) { 07890 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 07891 return RESULT_SHOWUSAGE; 07892 } 07893 07894 if (multi) { 07895 if (prunepeer) { 07896 int pruned = 0; 07897 07898 ASTOBJ_CONTAINER_WRLOCK(&peerl); 07899 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07900 ASTOBJ_RDLOCK(iterator); 07901 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07902 ASTOBJ_UNLOCK(iterator); 07903 continue; 07904 }; 07905 if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07906 ASTOBJ_MARK(iterator); 07907 pruned++; 07908 } 07909 ASTOBJ_UNLOCK(iterator); 07910 } while (0) ); 07911 if (pruned) { 07912 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 07913 ast_cli(fd, "%d peers pruned.\n", pruned); 07914 } else 07915 ast_cli(fd, "No peers found to prune.\n"); 07916 ASTOBJ_CONTAINER_UNLOCK(&peerl); 07917 } 07918 if (pruneuser) { 07919 int pruned = 0; 07920 07921 ASTOBJ_CONTAINER_WRLOCK(&userl); 07922 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07923 ASTOBJ_RDLOCK(iterator); 07924 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07925 ASTOBJ_UNLOCK(iterator); 07926 continue; 07927 }; 07928 if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07929 ASTOBJ_MARK(iterator); 07930 pruned++; 07931 } 07932 ASTOBJ_UNLOCK(iterator); 07933 } while (0) ); 07934 if (pruned) { 07935 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 07936 ast_cli(fd, "%d users pruned.\n", pruned); 07937 } else 07938 ast_cli(fd, "No users found to prune.\n"); 07939 ASTOBJ_CONTAINER_UNLOCK(&userl); 07940 } 07941 } else { 07942 if (prunepeer) { 07943 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 07944 if (!ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07945 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 07946 ASTOBJ_CONTAINER_LINK(&peerl, peer); 07947 } else 07948 ast_cli(fd, "Peer '%s' pruned.\n", name); 07949 ASTOBJ_UNREF(peer, sip_destroy_peer); 07950 } else 07951 ast_cli(fd, "Peer '%s' not found.\n", name); 07952 } 07953 if (pruneuser) { 07954 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 07955 if (!ast_test_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07956 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 07957 ASTOBJ_CONTAINER_LINK(&userl, user); 07958 } else 07959 ast_cli(fd, "User '%s' pruned.\n", name); 07960 ASTOBJ_UNREF(user, sip_destroy_user); 07961 } else 07962 ast_cli(fd, "User '%s' not found.\n", name); 07963 } 07964 } 07965 07966 return RESULT_SUCCESS; 07967 }
|
|
sip_read: Read SIP RTP from channel
Definition at line 3044 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. 03045 { 03046 struct ast_frame *fr; 03047 struct sip_pvt *p = ast->tech_pvt; 03048 ast_mutex_lock(&p->lock); 03049 fr = sip_rtp_read(ast, p); 03050 time(&p->lastrtprx); 03051 ast_mutex_unlock(&p->lock); 03052 return fr; 03053 }
|
|
sip_reg_timeout: Registration timeout, register again
Definition at line 5417 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(). 05418 { 05419 05420 /* if we are here, our registration timed out, so we'll just do it over */ 05421 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 05422 struct sip_pvt *p; 05423 int res; 05424 05425 /* if we couldn't get a reference to the registry object, punt */ 05426 if (!r) 05427 return 0; 05428 05429 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 05430 if (r->call) { 05431 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 05432 in the single SIP manager thread. */ 05433 p = r->call; 05434 if (p->registry) 05435 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 05436 r->call = NULL; 05437 ast_set_flag(p, SIP_NEEDDESTROY); 05438 /* Pretend to ACK anything just in case */ 05439 __sip_pretend_ack(p); 05440 } 05441 /* If we have a limit, stop registration and give up */ 05442 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 05443 /* Ok, enough is enough. Don't try any more */ 05444 /* We could add an external notification here... 05445 steal it from app_voicemail :-) */ 05446 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 05447 r->regstate=REG_STATE_FAILED; 05448 } else { 05449 r->regstate=REG_STATE_UNREGISTERED; 05450 r->timeout = -1; 05451 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 05452 } 05453 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)); 05454 ASTOBJ_UNREF(r,sip_registry_destroy); 05455 return 0; 05456 }
|
|
sip_register: Parse register=> line in sip.conf and add to registry
Definition at line 3257 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(). 03258 { 03259 struct sip_registry *reg; 03260 char copy[256]; 03261 char *username=NULL, *hostname=NULL, *secret=NULL, *authuser=NULL; 03262 char *porta=NULL; 03263 char *contact=NULL; 03264 char *stringp=NULL; 03265 03266 if (!value) 03267 return -1; 03268 ast_copy_string(copy, value, sizeof(copy)); 03269 stringp=copy; 03270 username = stringp; 03271 hostname = strrchr(stringp, '@'); 03272 if (hostname) { 03273 *hostname = '\0'; 03274 hostname++; 03275 } 03276 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 03277 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 03278 return -1; 03279 } 03280 stringp=username; 03281 username = strsep(&stringp, ":"); 03282 if (username) { 03283 secret = strsep(&stringp, ":"); 03284 if (secret) 03285 authuser = strsep(&stringp, ":"); 03286 } 03287 stringp = hostname; 03288 hostname = strsep(&stringp, "/"); 03289 if (hostname) 03290 contact = strsep(&stringp, "/"); 03291 if (ast_strlen_zero(contact)) 03292 contact = "s"; 03293 stringp=hostname; 03294 hostname = strsep(&stringp, ":"); 03295 porta = strsep(&stringp, ":"); 03296 03297 if (porta && !atoi(porta)) { 03298 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 03299 return -1; 03300 } 03301 reg = malloc(sizeof(struct sip_registry)); 03302 if (!reg) { 03303 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 03304 return -1; 03305 } 03306 memset(reg, 0, sizeof(struct sip_registry)); 03307 regobjs++; 03308 ASTOBJ_INIT(reg); 03309 ast_copy_string(reg->contact, contact, sizeof(reg->contact)); 03310 if (username) 03311 ast_copy_string(reg->username, username, sizeof(reg->username)); 03312 if (hostname) 03313 ast_copy_string(reg->hostname, hostname, sizeof(reg->hostname)); 03314 if (authuser) 03315 ast_copy_string(reg->authuser, authuser, sizeof(reg->authuser)); 03316 if (secret) 03317 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 03318 reg->expire = -1; 03319 reg->timeout = -1; 03320 reg->refresh = default_expiry; 03321 reg->portno = porta ? atoi(porta) : 0; 03322 reg->callid_valid = 0; 03323 reg->ocseq = 101; 03324 ASTOBJ_CONTAINER_LINK(®l, reg); 03325 ASTOBJ_UNREF(reg,sip_registry_destroy); 03326 return 0; 03327 }
|
|
sip_registry_destroy: Destroy registry object ---
Definition at line 2095 of file chan_sip.c. References ast_sched_del(), sip_registry::call, sip_registry::expire, free, sip_pvt::registry, sched, sip_destroy(), and sip_registry::timeout. Referenced by __sip_destroy(), sip_reg_timeout(), sip_register(), sip_reregister(), and unload_module(). 02096 { 02097 /* Really delete */ 02098 if (reg->call) { 02099 /* Clear registry before destroying to ensure 02100 we don't get reentered trying to grab the registry lock */ 02101 reg->call->registry = NULL; 02102 sip_destroy(reg->call); 02103 } 02104 if (reg->expire > -1) 02105 ast_sched_del(sched, reg->expire); 02106 if (reg->timeout > -1) 02107 ast_sched_del(sched, reg->timeout); 02108 regobjs--; 02109 free(reg); 02110 02111 }
|
|
sip_reload: Force reload of module from cli ---
Definition at line 13373 of file chan_sip.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), restart_monitor(), and sip_reloading. Referenced by reload(). 13374 { 13375 13376 ast_mutex_lock(&sip_reload_lock); 13377 if (sip_reloading) { 13378 ast_verbose("Previous SIP reload not yet done\n"); 13379 } else 13380 sip_reloading = 1; 13381 ast_mutex_unlock(&sip_reload_lock); 13382 restart_monitor(); 13383 13384 return 0; 13385 }
|
|
sip_request: PBX interface function -build SIP pvt structure ---
Definition at line 11803 of file chan_sip.c. References __ourip, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, 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(), sip_pvt::callid, calloc, create_addr(), sip_pvt::fromdomain, sip_pvt::fullcontact, global_capability, host, sip_pvt::lock, LOG_ERROR, LOG_NOTICE, sip_pvt::options, sip_pvt::ourip, sip_pvt::peername, sip_pvt::prefcodec, restart_monitor(), sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), sip_pvt::username, and sip_pvt::via. 11804 { 11805 int oldformat; 11806 struct sip_pvt *p; 11807 struct ast_channel *tmpc = NULL; 11808 char *ext, *host; 11809 char tmp[256]; 11810 char *dest = data; 11811 11812 oldformat = format; 11813 format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1); 11814 if (!format) { 11815 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)); 11816 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 11817 return NULL; 11818 } 11819 p = sip_alloc(NULL, NULL, 0, SIP_INVITE); 11820 if (!p) { 11821 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory)\n", (char *)data); 11822 *cause = AST_CAUSE_SWITCH_CONGESTION; 11823 return NULL; 11824 } 11825 11826 p->options = calloc(1, sizeof(*p->options)); 11827 if (!p->options) { 11828 sip_destroy(p); 11829 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 11830 *cause = AST_CAUSE_SWITCH_CONGESTION; 11831 return NULL; 11832 } 11833 11834 ast_copy_string(tmp, dest, sizeof(tmp)); 11835 host = strchr(tmp, '@'); 11836 if (host) { 11837 *host = '\0'; 11838 host++; 11839 ext = tmp; 11840 } else { 11841 ext = strchr(tmp, '/'); 11842 if (ext) { 11843 *ext++ = '\0'; 11844 host = tmp; 11845 } 11846 else { 11847 host = tmp; 11848 ext = NULL; 11849 } 11850 } 11851 11852 if (create_addr(p, host)) { 11853 *cause = AST_CAUSE_UNREGISTERED; 11854 sip_destroy(p); 11855 return NULL; 11856 } 11857 if (ast_strlen_zero(p->peername) && ext) 11858 ast_copy_string(p->peername, ext, sizeof(p->peername)); 11859 /* Recalculate our side, and recalculate Call ID */ 11860 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11861 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11862 build_via(p, p->via, sizeof(p->via)); 11863 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11864 11865 /* We have an extension to call, don't use the full contact here */ 11866 /* This to enable dialling registered peers with extension dialling, 11867 like SIP/peername/extension 11868 SIP/peername will still use the full contact */ 11869 if (ext) { 11870 ast_copy_string(p->username, ext, sizeof(p->username)); 11871 p->fullcontact[0] = 0; 11872 } 11873 #if 0 11874 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 11875 #endif 11876 p->prefcodec = format; 11877 ast_mutex_lock(&p->lock); 11878 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 11879 ast_mutex_unlock(&p->lock); 11880 if (!tmpc) 11881 sip_destroy(p); 11882 ast_update_use_count(); 11883 restart_monitor(); 11884 return tmpc; 11885 }
|
|
sip_reregister: Update registration with SIP Proxy---
Definition at line 5382 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 sip_send_all_registers(). 05383 { 05384 /* if we are here, we know that we need to reregister. */ 05385 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 05386 05387 /* if we couldn't get a reference to the registry object, punt */ 05388 if (!r) 05389 return 0; 05390 05391 if (r->call && recordhistory) { 05392 char tmp[80]; 05393 snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname); 05394 append_history(r->call, "RegistryRenew", tmp); 05395 } 05396 /* Since registry's are only added/removed by the the monitor thread, this 05397 may be overkill to reference/dereference at all here */ 05398 if (sipdebug) 05399 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 05400 05401 r->expire = -1; 05402 __sip_do_register(r); 05403 ASTOBJ_UNREF(r, sip_registry_destroy); 05404 return 0; 05405 }
|
|
sip_rtp_read: Read RTP from network ---
Definition at line 2994 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(). 02995 { 02996 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 02997 struct ast_frame *f; 02998 static struct ast_frame null_frame = { AST_FRAME_NULL, }; 02999 03000 if (!p->rtp) { 03001 /* We have no RTP allocated for this channel */ 03002 return &null_frame; 03003 } 03004 03005 switch(ast->fdno) { 03006 case 0: 03007 f = ast_rtp_read(p->rtp); /* RTP Audio */ 03008 break; 03009 case 1: 03010 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 03011 break; 03012 case 2: 03013 f = ast_rtp_read(p->vrtp); /* RTP Video */ 03014 break; 03015 case 3: 03016 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 03017 break; 03018 default: 03019 f = &null_frame; 03020 } 03021 /* Don't forward RFC2833 if we're not supposed to */ 03022 if (f && (f->frametype == AST_FRAME_DTMF) && (ast_test_flag(p, SIP_DTMF) != SIP_DTMF_RFC2833)) 03023 return &null_frame; 03024 if (p->owner) { 03025 /* We already hold the channel lock */ 03026 if (f->frametype == AST_FRAME_VOICE) { 03027 if (f->subclass != p->owner->nativeformats) { 03028 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 03029 p->owner->nativeformats = f->subclass; 03030 ast_set_read_format(p->owner, p->owner->readformat); 03031 ast_set_write_format(p->owner, p->owner->writeformat); 03032 } 03033 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 03034 f = ast_dsp_process(p->owner, p->vad, f); 03035 if (f && (f->frametype == AST_FRAME_DTMF)) 03036 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 03037 } 03038 } 03039 } 03040 return f; 03041 }
|
|
sip_scheddestroy: Schedule destruction of SIP call ---
Definition at line 1346 of file chan_sip.c. References __sip_autodestruct(), append_history(), ast_sched_add(), ast_sched_del(), ast_verbose(), sip_pvt::autokillid, sip_pvt::callid, sched, 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(). 01347 { 01348 char tmp[80]; 01349 if (sip_debug_test_pvt(p)) 01350 ast_verbose("Scheduling destruction of call '%s' in %d ms\n", p->callid, ms); 01351 if (recordhistory) { 01352 snprintf(tmp, sizeof(tmp), "%d ms", ms); 01353 append_history(p, "SchedDestroy", tmp); 01354 } 01355 01356 if (p->autokillid > -1) 01357 ast_sched_del(sched, p->autokillid); 01358 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 01359 return 0; 01360 }
|
|
sip_send_all_registers: Send all known registrations
Definition at line 13318 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(). 13319 { 13320 int ms; 13321 int regspacing; 13322 if (!regobjs) 13323 return; 13324 regspacing = default_expiry * 1000/regobjs; 13325 if (regspacing > 100) 13326 regspacing = 100; 13327 ms = regspacing; 13328 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 13329 ASTOBJ_WRLOCK(iterator); 13330 if (iterator->expire > -1) 13331 ast_sched_del(sched, iterator->expire); 13332 ms += regspacing; 13333 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 13334 ASTOBJ_UNLOCK(iterator); 13335 } while (0) 13336 ); 13337 }
|
|
sip_send_mwi_to_peer: Send message waiting indication ---
Definition at line 11438 of file chan_sip.c. References __ourip, ast_app_messagecount(), ast_log(), ast_set_flag, ast_sip_ouraddrfor(), build_callid(), build_via(), create_addr_from_peer(), sip_peer::lastmsgcheck, sip_peer::lastmsgssent, LOG_WARNING, sip_peer::mailbox, sip_alloc(), sip_destroy(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), transmit_notify_with_mwi(), and sip_peer::vmexten. 11439 { 11440 /* Called with peerl lock, but releases it */ 11441 struct sip_pvt *p; 11442 int newmsgs, oldmsgs; 11443 11444 /* Check for messages */ 11445 ast_app_messagecount(peer->mailbox, &newmsgs, &oldmsgs); 11446 11447 time(&peer->lastmsgcheck); 11448 11449 /* Return now if it's the same thing we told them last time */ 11450 if (((newmsgs << 8) | (oldmsgs)) == peer->lastmsgssent) { 11451 return 0; 11452 } 11453 11454 p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY); 11455 if (!p) { 11456 ast_log(LOG_WARNING, "Unable to build sip pvt data for MWI\n"); 11457 return -1; 11458 } 11459 peer->lastmsgssent = ((newmsgs << 8) | (oldmsgs)); 11460 if (create_addr_from_peer(p, peer)) { 11461 /* Maybe they're not registered, etc. */ 11462 sip_destroy(p); 11463 return 0; 11464 } 11465 /* Recalculate our side, and recalculate Call ID */ 11466 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11467 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11468 build_via(p, p->via, sizeof(p->via)); 11469 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11470 /* Send MWI */ 11471 ast_set_flag(p, SIP_OUTGOING); 11472 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 11473 sip_scheddestroy(p, 15000); 11474 return 0; 11475 }
|
|
sip_senddigit: Send DTMF character on SIP channel
Definition at line 2634 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(). 02635 { 02636 struct sip_pvt *p = ast->tech_pvt; 02637 int res = 0; 02638 ast_mutex_lock(&p->lock); 02639 switch (ast_test_flag(p, SIP_DTMF)) { 02640 case SIP_DTMF_INFO: 02641 transmit_info_with_digit(p, digit); 02642 break; 02643 case SIP_DTMF_RFC2833: 02644 if (p->rtp) 02645 ast_rtp_senddigit(p->rtp, digit); 02646 break; 02647 case SIP_DTMF_INBAND: 02648 res = -1; 02649 break; 02650 } 02651 ast_mutex_unlock(&p->lock); 02652 return res; 02653 }
|
|
sip_sendtext: Send SIP MESSAGE text within a call ---
Definition at line 1592 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(). 01593 { 01594 struct sip_pvt *p = ast->tech_pvt; 01595 int debug=sip_debug_test_pvt(p); 01596 01597 if (debug) 01598 ast_verbose("Sending text %s on %s\n", text, ast->name); 01599 if (!p) 01600 return -1; 01601 if (ast_strlen_zero(text)) 01602 return 0; 01603 if (debug) 01604 ast_verbose("Really sending text %s on %s\n", text, ast->name); 01605 transmit_message_with_text(p, text); 01606 return 0; 01607 }
|
|
sip_set_rtp_peer: Set the RTP peer for this call ---
Definition at line 12999 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_pvt::rtp, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), sip_pvt::vredirip, and sip_pvt::vrtp. 13000 { 13001 struct sip_pvt *p; 13002 int changed = 0; 13003 13004 p = chan->tech_pvt; 13005 if (!p) 13006 return -1; 13007 ast_mutex_lock(&p->lock); 13008 if (rtp) { 13009 changed |= ast_rtp_get_peer(rtp, &p->redirip); 13010 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 13011 memset(&p->redirip, 0, sizeof(p->redirip)); 13012 changed = 1; 13013 } 13014 if (vrtp) { 13015 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 13016 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 13017 memset(&p->vredirip, 0, sizeof(p->vredirip)); 13018 changed = 1; 13019 } 13020 if (codecs && (p->redircodecs != codecs)) { 13021 p->redircodecs = codecs; 13022 changed = 1; 13023 } 13024 if (changed && !ast_test_flag(p, SIP_GOTREFER)) { 13025 if (!p->pendinginvite) { 13026 if (option_debug > 2) { 13027 char iabuf[INET_ADDRSTRLEN]; 13028 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)); 13029 } 13030 transmit_reinvite_with_sdp(p); 13031 } else if (!ast_test_flag(p, SIP_PENDINGBYE)) { 13032 if (option_debug > 2) { 13033 char iabuf[INET_ADDRSTRLEN]; 13034 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)); 13035 } 13036 ast_set_flag(p, SIP_NEEDREINVITE); 13037 } 13038 } 13039 /* Reset lastrtprx timer */ 13040 time(&p->lastrtprx); 13041 time(&p->lastrtptx); 13042 ast_mutex_unlock(&p->lock); 13043 return 0; 13044 }
|
|
sip_show_channel: Show details of one call ---
Definition at line 8644 of file chan_sip.c. References ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), 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, 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. 08645 { 08646 struct sip_pvt *cur; 08647 char iabuf[INET_ADDRSTRLEN]; 08648 size_t len; 08649 int found = 0; 08650 08651 if (argc != 4) 08652 return RESULT_SHOWUSAGE; 08653 len = strlen(argv[3]); 08654 ast_mutex_lock(&iflock); 08655 cur = iflist; 08656 while(cur) { 08657 if (!strncasecmp(cur->callid, argv[3],len)) { 08658 ast_cli(fd,"\n"); 08659 if (cur->subscribed != NONE) 08660 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 08661 else 08662 ast_cli(fd, " * SIP Call\n"); 08663 ast_cli(fd, " Direction: %s\n", ast_test_flag(cur, SIP_OUTGOING)?"Outgoing":"Incoming"); 08664 ast_cli(fd, " Call-ID: %s\n", cur->callid); 08665 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 08666 ast_cli(fd, " Non-Codec Capability: %d\n", cur->noncodeccapability); 08667 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 08668 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 08669 ast_cli(fd, " Format %s\n", ast_getformatname(cur->owner ? cur->owner->nativeformats : 0) ); 08670 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 08671 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 08672 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(cur, SIP_NAT))); 08673 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)" ); 08674 ast_cli(fd, " Our Tag: %s\n", cur->tag); 08675 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 08676 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 08677 if (!ast_strlen_zero(cur->username)) 08678 ast_cli(fd, " Username: %s\n", cur->username); 08679 if (!ast_strlen_zero(cur->peername)) 08680 ast_cli(fd, " Peername: %s\n", cur->peername); 08681 if (!ast_strlen_zero(cur->uri)) 08682 ast_cli(fd, " Original uri: %s\n", cur->uri); 08683 if (!ast_strlen_zero(cur->cid_num)) 08684 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 08685 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(cur, SIP_NEEDDESTROY)); 08686 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 08687 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(cur, SIP_PROMISCREDIR) ? "Yes" : "No"); 08688 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 08689 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(cur, SIP_DTMF))); 08690 ast_cli(fd, " SIP Options: "); 08691 if (cur->sipoptions) { 08692 int x; 08693 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 08694 if (cur->sipoptions & sip_options[x].id) 08695 ast_cli(fd, "%s ", sip_options[x].text); 08696 } 08697 } else 08698 ast_cli(fd, "(none)\n"); 08699 ast_cli(fd, "\n\n"); 08700 found++; 08701 } 08702 cur = cur->next; 08703 } 08704 ast_mutex_unlock(&iflock); 08705 if (!found) 08706 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 08707 return RESULT_SUCCESS; 08708 }
|
|
sip_show_channels: Show active SIP channels ---
Definition at line 8445 of file chan_sip.c. References __sip_show_channels(). 08446 { 08447 return __sip_show_channels(fd, argc, argv, 0); 08448 }
|
|
Definition at line 8000 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. 08001 { 08002 struct domain *d; 08003 08004 if (AST_LIST_EMPTY(&domain_list)) { 08005 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 08006 return RESULT_SUCCESS; 08007 } else { 08008 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 08009 AST_LIST_LOCK(&domain_list); 08010 AST_LIST_TRAVERSE(&domain_list, d, list) 08011 ast_cli(fd, FORMAT, d->domain, ast_strlen_zero(d->context) ? "(default)": d->context, 08012 domain_mode_to_text(d->mode)); 08013 AST_LIST_UNLOCK(&domain_list); 08014 ast_cli(fd, "\n"); 08015 return RESULT_SUCCESS; 08016 } 08017 }
|
|
sip_show_history: Show history details of one call ---
Definition at line 8711 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. 08712 { 08713 struct sip_pvt *cur; 08714 struct sip_history *hist; 08715 size_t len; 08716 int x; 08717 int found = 0; 08718 08719 if (argc != 4) 08720 return RESULT_SHOWUSAGE; 08721 if (!recordhistory) 08722 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 08723 len = strlen(argv[3]); 08724 ast_mutex_lock(&iflock); 08725 cur = iflist; 08726 while(cur) { 08727 if (!strncasecmp(cur->callid, argv[3], len)) { 08728 ast_cli(fd,"\n"); 08729 if (cur->subscribed != NONE) 08730 ast_cli(fd, " * Subscription\n"); 08731 else 08732 ast_cli(fd, " * SIP Call\n"); 08733 x = 0; 08734 hist = cur->history; 08735 while(hist) { 08736 x++; 08737 ast_cli(fd, "%d. %s\n", x, hist->event); 08738 hist = hist->next; 08739 } 08740 if (!x) 08741 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 08742 found++; 08743 } 08744 cur = cur->next; 08745 } 08746 ast_mutex_unlock(&iflock); 08747 if (!found) 08748 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 08749 return RESULT_SUCCESS; 08750 }
|
|
sip_show_inuse: CLI Command to show calls within limits set by call_limit ---
Definition at line 7467 of file chan_sip.c. References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, FORMAT2, RESULT_SHOWUSAGE, and userl. 07467 { 07468 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 07469 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 07470 char ilimits[40]; 07471 char iused[40]; 07472 int showall = 0; 07473 07474 if (argc < 3) 07475 return RESULT_SHOWUSAGE; 07476 07477 if (argc == 4 && !strcmp(argv[3],"all")) 07478 showall = 1; 07479 07480 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 07481 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07482 ASTOBJ_RDLOCK(iterator); 07483 if (iterator->call_limit) 07484 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 07485 else 07486 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 07487 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 07488 if (showall || iterator->call_limit) 07489 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 07490 ASTOBJ_UNLOCK(iterator); 07491 } while (0) ); 07492 07493 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 07494 07495 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07496 ASTOBJ_RDLOCK(iterator); 07497 if (iterator->call_limit) 07498 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 07499 else 07500 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 07501 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 07502 if (showall || iterator->call_limit) 07503 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 07504 ASTOBJ_UNLOCK(iterator); 07505 } while (0) ); 07506 07507 return RESULT_SUCCESS; 07508 #undef FORMAT 07509 #undef FORMAT2 07510 }
|
|
sip_show_objects: List all allocated SIP Objects ---
Definition at line 7773 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. 07774 { 07775 char tmp[256]; 07776 if (argc != 3) 07777 return RESULT_SHOWUSAGE; 07778 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 07779 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 07780 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 07781 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 07782 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 07783 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 07784 return RESULT_SUCCESS; 07785 }
|
|
sip_show_peer: Show one peer in detail ---
Definition at line 8057 of file chan_sip.c. References _sip_show_peer(). 08058 { 08059 return _sip_show_peer(0, fd, NULL, NULL, argc, argv); 08060 }
|
|
sip_show_peers: CLI Show Peers command
Definition at line 7634 of file chan_sip.c. References _sip_show_peers(). 07635 { 07636 return _sip_show_peers(fd, NULL, NULL, NULL, argc, argv); 07637 }
|
|
sip_show_registry: Show SIP Registry (registrations with other SIP proxies ---
Definition at line 8309 of file chan_sip.c. References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, DEFAULT_SIP_PORT, FORMAT, FORMAT2, host, regl, regstate2str(), and RESULT_SHOWUSAGE. 08310 { 08311 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s\n" 08312 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s\n" 08313 char host[80]; 08314 08315 if (argc != 3) 08316 return RESULT_SHOWUSAGE; 08317 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State"); 08318 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 08319 ASTOBJ_RDLOCK(iterator); 08320 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : DEFAULT_SIP_PORT); 08321 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate)); 08322 ASTOBJ_UNLOCK(iterator); 08323 } while(0)); 08324 return RESULT_SUCCESS; 08325 #undef FORMAT 08326 #undef FORMAT2 08327 }
|
|
sip_show_settings: List global settings for the SIP channel ---
Definition at line 8330 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_flags, global_flags_page2, 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, prefs, 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. 08331 { 08332 char tmp[BUFSIZ]; 08333 int realtimepeers = 0; 08334 int realtimeusers = 0; 08335 08336 realtimepeers = ast_check_realtime("sippeers"); 08337 realtimeusers = ast_check_realtime("sipusers"); 08338 08339 if (argc != 3) 08340 return RESULT_SHOWUSAGE; 08341 ast_cli(fd, "\n\nGlobal Settings:\n"); 08342 ast_cli(fd, "----------------\n"); 08343 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 08344 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(tmp, sizeof(tmp), bindaddr.sin_addr)); 08345 ast_cli(fd, " Videosupport: %s\n", videosupport ? "Yes" : "No"); 08346 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 08347 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 08348 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags, SIP_PROMISCREDIR) ? "Yes" : "No"); 08349 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 08350 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 08351 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags, SIP_USEREQPHONE) ? "Yes" : "No"); 08352 ast_cli(fd, " Our auth realm %s\n", global_realm); 08353 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 08354 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 08355 ast_cli(fd, " User Agent: %s\n", default_useragent); 08356 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 08357 ast_cli(fd, " Reg. context: %s\n", ast_strlen_zero(regcontext) ? "(not set)" : regcontext); 08358 ast_cli(fd, " Caller ID: %s\n", default_callerid); 08359 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 08360 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 08361 ast_cli(fd, " Call Events: %s\n", callevents ? "On" : "Off"); 08362 ast_cli(fd, " IP ToS: 0x%x\n", tos); 08363 #ifdef OSP_SUPPORT 08364 ast_cli(fd, " OSP Support: Yes\n"); 08365 #else 08366 ast_cli(fd, " OSP Support: No\n"); 08367 #endif 08368 if (!realtimepeers && !realtimeusers) 08369 ast_cli(fd, " SIP realtime: Disabled\n" ); 08370 else 08371 ast_cli(fd, " SIP realtime: Enabled\n" ); 08372 08373 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 08374 ast_cli(fd, "---------------------------\n"); 08375 ast_cli(fd, " Codecs: "); 08376 print_codec_to_cli(fd, &prefs); 08377 ast_cli(fd, "\n"); 08378 ast_cli(fd, " Relax DTMF: %s\n", relaxdtmf ? "Yes" : "No"); 08379 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 08380 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 08381 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 08382 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 08383 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 08384 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 08385 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 08386 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 08387 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 08388 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 08389 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 08390 ast_cli(fd, "\nDefault Settings:\n"); 08391 ast_cli(fd, "-----------------\n"); 08392 ast_cli(fd, " Context: %s\n", default_context); 08393 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags, SIP_NAT))); 08394 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags, SIP_DTMF))); 08395 ast_cli(fd, " Qualify: %d\n", default_qualify); 08396 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags, SIP_USECLIENTCODE) ? "Yes" : "No"); 08397 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" ); 08398 ast_cli(fd, " Language: %s\n", ast_strlen_zero(default_language) ? "(Defaults to English)" : default_language); 08399 ast_cli(fd, " Musicclass: %s\n", global_musicclass); 08400 ast_cli(fd, " Voice Mail Extension: %s\n", global_vmexten); 08401 08402 08403 if (realtimepeers || realtimeusers) { 08404 ast_cli(fd, "\nRealtime SIP Settings:\n"); 08405 ast_cli(fd, "----------------------\n"); 08406 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 08407 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 08408 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 08409 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 08410 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 08411 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 08412 } 08413 ast_cli(fd, "\n----\n"); 08414 return RESULT_SUCCESS; 08415 }
|
|
sip_show_subscriptions: Show active SIP subscriptions ---
Definition at line 8451 of file chan_sip.c. References __sip_show_channels(). 08452 { 08453 return __sip_show_channels(fd, argc, argv, 1); 08454 }
|
|
sip_show_user: Show one user in detail ---
Definition at line 8245 of file chan_sip.c. References ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_strlen_zero(), ASTOBJ_UNREF, find_user(), ast_variable::name, ast_variable::next, print_group(), RESULT_SHOWUSAGE, sip_destroy_user(), user, and ast_variable::value. 08246 { 08247 char cbuf[256]; 08248 struct sip_user *user; 08249 struct ast_codec_pref *pref; 08250 struct ast_variable *v; 08251 int x = 0, codec = 0, load_realtime = 0; 08252 08253 if (argc < 4) 08254 return RESULT_SHOWUSAGE; 08255 08256 /* Load from realtime storage? */ 08257 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 08258 08259 user = find_user(argv[3], load_realtime); 08260 if (user) { 08261 ast_cli(fd,"\n\n"); 08262 ast_cli(fd, " * Name : %s\n", user->name); 08263 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 08264 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 08265 ast_cli(fd, " Context : %s\n", user->context); 08266 ast_cli(fd, " Language : %s\n", user->language); 08267 if (!ast_strlen_zero(user->accountcode)) 08268 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 08269 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 08270 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 08271 ast_cli(fd, " Call limit : %d\n", user->call_limit); 08272 ast_cli(fd, " Callgroup : "); 08273 print_group(fd, user->callgroup, 0); 08274 ast_cli(fd, " Pickupgroup : "); 08275 print_group(fd, user->pickupgroup, 0); 08276 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 08277 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 08278 ast_cli(fd, " Codec Order : ("); 08279 pref = &user->prefs; 08280 for(x = 0; x < 32 ; x++) { 08281 codec = ast_codec_pref_index(pref,x); 08282 if (!codec) 08283 break; 08284 ast_cli(fd, "%s", ast_getformatname(codec)); 08285 if (x < 31 && ast_codec_pref_index(pref,x+1)) 08286 ast_cli(fd, "|"); 08287 } 08288 08289 if (!x) 08290 ast_cli(fd, "none"); 08291 ast_cli(fd, ")\n"); 08292 08293 if (user->chanvars) { 08294 ast_cli(fd, " Variables :\n"); 08295 for (v = user->chanvars ; v ; v = v->next) 08296 ast_cli(fd, " %s = %s\n", v->name, v->value); 08297 } 08298 ast_cli(fd,"\n"); 08299 ASTOBJ_UNREF(user,sip_destroy_user); 08300 } else { 08301 ast_cli(fd,"User %s not found.\n", argv[3]); 08302 ast_cli(fd,"\n"); 08303 } 08304 08305 return RESULT_SUCCESS; 08306 }
|
|
sip_show_users: CLI Command 'SIP Show Users' ---
Definition at line 7555 of file chan_sip.c. References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, RESULT_SHOWUSAGE, and userl. 07556 { 07557 regex_t regexbuf; 07558 int havepattern = 0; 07559 07560 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 07561 07562 switch (argc) { 07563 case 5: 07564 if (!strcasecmp(argv[3], "like")) { 07565 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 07566 return RESULT_SHOWUSAGE; 07567 havepattern = 1; 07568 } else 07569 return RESULT_SHOWUSAGE; 07570 case 3: 07571 break; 07572 default: 07573 return RESULT_SHOWUSAGE; 07574 } 07575 07576 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 07577 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07578 ASTOBJ_RDLOCK(iterator); 07579 07580 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07581 ASTOBJ_UNLOCK(iterator); 07582 continue; 07583 } 07584 07585 ast_cli(fd, FORMAT, iterator->name, 07586 iterator->secret, 07587 iterator->accountcode, 07588 iterator->context, 07589 iterator->ha ? "Yes" : "No", 07590 nat2str(ast_test_flag(iterator, SIP_NAT))); 07591 ASTOBJ_UNLOCK(iterator); 07592 } while (0) 07593 ); 07594 07595 if (havepattern) 07596 regfree(®exbuf); 07597 07598 return RESULT_SUCCESS; 07599 #undef FORMAT 07600 }
|
|
sip_sipredirect: Transfer call before connect with a 302 redirect ---
Definition at line 13227 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(). 13228 { 13229 char *cdest; 13230 char *extension, *host, *port; 13231 char tmp[80]; 13232 13233 cdest = ast_strdupa(dest); 13234 if (!cdest) { 13235 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 13236 return 0; 13237 } 13238 extension = strsep(&cdest, "@"); 13239 host = strsep(&cdest, ":"); 13240 port = strsep(&cdest, ":"); 13241 if (!extension) { 13242 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 13243 return 0; 13244 } 13245 13246 /* we'll issue the redirect message here */ 13247 if (!host) { 13248 char *localtmp; 13249 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 13250 if (!strlen(tmp)) { 13251 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 13252 return 0; 13253 } 13254 if ((localtmp = strstr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 13255 char lhost[80], lport[80]; 13256 memset(lhost, 0, sizeof(lhost)); 13257 memset(lport, 0, sizeof(lport)); 13258 localtmp++; 13259 /* This is okey because lhost and lport are as big as tmp */ 13260 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 13261 if (!strlen(lhost)) { 13262 ast_log(LOG_ERROR, "Can't find the host address\n"); 13263 return 0; 13264 } 13265 host = ast_strdupa(lhost); 13266 if (!host) { 13267 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 13268 return 0; 13269 } 13270 if (!ast_strlen_zero(lport)) { 13271 port = ast_strdupa(lport); 13272 if (!port) { 13273 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 13274 return 0; 13275 } 13276 } 13277 } 13278 } 13279 13280 snprintf(p->our_contact, sizeof(p->our_contact), "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 13281 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq, 1); 13282 13283 /* this is all that we want to send to that SIP device */ 13284 ast_set_flag(p, SIP_ALREADYGONE); 13285 13286 /* hangup here */ 13287 return -1; 13288 }
|
|
sip_transfer: Transfer SIP call
Definition at line 2658 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(). 02659 { 02660 struct sip_pvt *p = ast->tech_pvt; 02661 int res; 02662 02663 ast_mutex_lock(&p->lock); 02664 if (ast->_state == AST_STATE_RING) 02665 res = sip_sipredirect(p, dest); 02666 else 02667 res = transmit_refer(p, dest); 02668 ast_mutex_unlock(&p->lock); 02669 return res; 02670 }
|
|
sip_write: Send frame to media channel (rtp) ---
Definition at line 2565 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. 02566 { 02567 struct sip_pvt *p = ast->tech_pvt; 02568 int res = 0; 02569 switch (frame->frametype) { 02570 case AST_FRAME_VOICE: 02571 if (!(frame->subclass & ast->nativeformats)) { 02572 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", 02573 frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat); 02574 return 0; 02575 } 02576 if (p) { 02577 ast_mutex_lock(&p->lock); 02578 if (p->rtp) { 02579 /* If channel is not up, activate early media session */ 02580 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02581 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); 02582 ast_set_flag(p, SIP_PROGRESS_SENT); 02583 } 02584 time(&p->lastrtptx); 02585 res = ast_rtp_write(p->rtp, frame); 02586 } 02587 ast_mutex_unlock(&p->lock); 02588 } 02589 break; 02590 case AST_FRAME_VIDEO: 02591 if (p) { 02592 ast_mutex_lock(&p->lock); 02593 if (p->vrtp) { 02594 /* Activate video early media */ 02595 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02596 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); 02597 ast_set_flag(p, SIP_PROGRESS_SENT); 02598 } 02599 time(&p->lastrtptx); 02600 res = ast_rtp_write(p->vrtp, frame); 02601 } 02602 ast_mutex_unlock(&p->lock); 02603 } 02604 break; 02605 case AST_FRAME_IMAGE: 02606 return 0; 02607 break; 02608 default: 02609 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 02610 return 0; 02611 } 02612 02613 return res; 02614 }
|
|
sipsock_read: Read data from SIP socket ---
Definition at line 11342 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(). 11343 { 11344 struct sip_request req; 11345 struct sockaddr_in sin = { 0, }; 11346 struct sip_pvt *p; 11347 int res; 11348 socklen_t len; 11349 int nounlock; 11350 int recount = 0; 11351 char iabuf[INET_ADDRSTRLEN]; 11352 unsigned int lockretry = 100; 11353 11354 len = sizeof(sin); 11355 memset(&req, 0, sizeof(req)); 11356 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 11357 if (res < 0) { 11358 #if !defined(__FreeBSD__) 11359 if (errno == EAGAIN) 11360 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 11361 else 11362 #endif 11363 if (errno != ECONNREFUSED) 11364 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 11365 return 1; 11366 } 11367 if (res == sizeof(req.data)) { 11368 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 11369 req.data[sizeof(req.data) - 1] = '\0'; 11370 } else 11371 req.data[res] = '\0'; 11372 req.len = res; 11373 if(sip_debug_test_addr(&sin)) 11374 ast_set_flag(&req, SIP_PKT_DEBUG); 11375 if (pedanticsipchecking) 11376 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 11377 if (ast_test_flag(&req, SIP_PKT_DEBUG)) { 11378 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); 11379 } 11380 parse_request(&req); 11381 req.method = find_sip_method(req.rlPart1); 11382 if (ast_test_flag(&req, SIP_PKT_DEBUG)) { 11383 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 11384 } 11385 11386 if (req.headers < 2) { 11387 /* Must have at least two headers */ 11388 return 1; 11389 } 11390 11391 11392 /* Process request, with netlock held */ 11393 retrylock: 11394 ast_mutex_lock(&netlock); 11395 p = find_call(&req, &sin, req.method); 11396 if (p) { 11397 /* Go ahead and lock the owner if it has one -- we may need it */ 11398 if (p->owner && ast_mutex_trylock(&p->owner->lock)) { 11399 ast_log(LOG_DEBUG, "Failed to grab lock, trying again...\n"); 11400 ast_mutex_unlock(&p->lock); 11401 ast_mutex_unlock(&netlock); 11402 /* Sleep for a very short amount of time */ 11403 usleep(1); 11404 if (--lockretry) 11405 goto retrylock; 11406 } 11407 if (!lockretry) { 11408 ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", p->owner->name); 11409 ast_log(LOG_ERROR, "SIP MESSAGE JUST IGNORED: %s \n", req.data); 11410 ast_log(LOG_ERROR, "BAD! BAD! BAD!\n"); 11411 return 1; 11412 } 11413 memcpy(&p->recv, &sin, sizeof(p->recv)); 11414 if (recordhistory) { 11415 char tmp[80]; 11416 /* This is a response, note what it was for */ 11417 snprintf(tmp, sizeof(tmp), "%s / %s /%s", req.data, get_header(&req, "CSeq"), req.rlPart2); 11418 append_history(p, "Rx", tmp); 11419 } 11420 nounlock = 0; 11421 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 11422 /* Request failed */ 11423 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 11424 } 11425 11426 if (p->owner && !nounlock) 11427 ast_mutex_unlock(&p->owner->lock); 11428 ast_mutex_unlock(&p->lock); 11429 } 11430 ast_mutex_unlock(&netlock); 11431 if (recount) 11432 ast_update_use_count(); 11433 11434 return 1; 11435 }
|
|
subscription_type2str: Show subscription type in string format
Definition at line 8418 of file chan_sip.c. References subscription_types, and type. Referenced by __sip_show_channels(), and sip_show_channel(). 08418 { 08419 int i; 08420 08421 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 08422 if (subscription_types[i].type == subtype) { 08423 return subscription_types[i].text; 08424 } 08425 } 08426 return subscription_types[0].text; 08427 }
|
|
temp_peer: Create temporary peer (used in autocreatepeer mode) ---
Definition at line 12259 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_flags, global_musicclass, global_rtpholdtimeout, global_rtpkeepalive, global_rtptimeout, malloc, prefs, reg_source_db(), SIP_FLAGS_TO_COPY, SIP_PAGE2_DYNAMIC, and SIP_SELFDESTRUCT. Referenced by register_verify(). 12260 { 12261 struct sip_peer *peer; 12262 12263 peer = malloc(sizeof(*peer)); 12264 if (!peer) 12265 return NULL; 12266 12267 memset(peer, 0, sizeof(*peer)); 12268 apeerobjs++; 12269 ASTOBJ_INIT(peer); 12270 12271 peer->expire = -1; 12272 peer->pokeexpire = -1; 12273 ast_copy_string(peer->name, name, sizeof(peer->name)); 12274 ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY); 12275 strcpy(peer->context, default_context); 12276 strcpy(peer->subscribecontext, default_subscribecontext); 12277 strcpy(peer->language, default_language); 12278 strcpy(peer->musicclass, global_musicclass); 12279 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 12280 peer->addr.sin_family = AF_INET; 12281 peer->capability = global_capability; 12282 peer->rtptimeout = global_rtptimeout; 12283 peer->rtpholdtimeout = global_rtpholdtimeout; 12284 peer->rtpkeepalive = global_rtpkeepalive; 12285 ast_set_flag(peer, SIP_SELFDESTRUCT); 12286 ast_set_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC); 12287 peer->prefs = prefs; 12288 reg_source_db(peer); 12289 12290 return peer; 12291 }
|
|
Thread-safe random number generator.
Definition at line 974 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(), transmit_register(), and transmit_response_using_temp(). 00975 { 00976 int val; 00977 00978 ast_mutex_lock(&rand_lock); 00979 val = rand(); 00980 ast_mutex_unlock(&rand_lock); 00981 00982 return val; 00983 }
|
|
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
Definition at line 6500 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(). 06501 { 06502 snprintf(randdata, randlen, "%08x", thread_safe_rand()); 06503 transmit_response_with_auth(p, "401 Unauthorized", req, randdata, reliable, "WWW-Authenticate", 0); 06504 }
|
|
transmit_info_with_digit: Send SIP INFO dtmf message, see Cisco documentation on cisco.co m ---
Definition at line 5705 of file chan_sip.c. References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_INFO. Referenced by sip_senddigit(). 05706 { 05707 struct sip_request req; 05708 reqprep(&req, p, SIP_INFO, 0, 1); 05709 add_digit(&req, digit); 05710 return send_request(p, &req, 1, p->ocseq); 05711 }
|
|
transmit_info_with_vidupdate: Send SIP INFO with video update request ---
Definition at line 5714 of file chan_sip.c. References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_INFO. Referenced by sip_indicate(). 05715 { 05716 struct sip_request req; 05717 reqprep(&req, p, SIP_INFO, 0, 1); 05718 add_vidupdate(&req); 05719 return send_request(p, &req, 1, p->ocseq); 05720 }
|
|
transmit_invite: Build REFER/INVITE/OPTIONS message and transmit it ---
Definition at line 5005 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(). 05006 { 05007 struct sip_request req; 05008 05009 req.method = sipmethod; 05010 if (init) { 05011 /* Bump branch even on initial requests */ 05012 p->branch ^= thread_safe_rand(); 05013 build_via(p, p->via, sizeof(p->via)); 05014 if (init > 1) 05015 initreqprep(&req, p, sipmethod); 05016 else 05017 reqprep(&req, p, sipmethod, 0, 1); 05018 } else 05019 reqprep(&req, p, sipmethod, 0, 1); 05020 05021 if (p->options && p->options->auth) 05022 add_header(&req, p->options->authheader, p->options->auth); 05023 append_date(&req); 05024 if (sipmethod == SIP_REFER) { /* Call transfer */ 05025 if (!ast_strlen_zero(p->refer_to)) 05026 add_header(&req, "Refer-To", p->refer_to); 05027 if (!ast_strlen_zero(p->referred_by)) 05028 add_header(&req, "Referred-By", p->referred_by); 05029 } 05030 #ifdef OSP_SUPPORT 05031 if ((req.method != SIP_OPTIONS) && p->options && !ast_strlen_zero(p->options->osptoken)) { 05032 ast_log(LOG_DEBUG,"Adding OSP Token: %s\n", p->options->osptoken); 05033 add_header(&req, "P-OSP-Auth-Token", p->options->osptoken); 05034 } 05035 #endif 05036 if (p->options && !ast_strlen_zero(p->options->distinctive_ring)) 05037 { 05038 add_header(&req, "Alert-Info", p->options->distinctive_ring); 05039 } 05040 add_header(&req, "Allow", ALLOWED_METHODS); 05041 if (p->options && p->options->addsipheaders ) { 05042 struct ast_channel *ast; 05043 char *header = (char *) NULL; 05044 char *content = (char *) NULL; 05045 char *end = (char *) NULL; 05046 struct varshead *headp = (struct varshead *) NULL; 05047 struct ast_var_t *current; 05048 05049 ast = p->owner; /* The owner channel */ 05050 if (ast) { 05051 char *headdup; 05052 headp = &ast->varshead; 05053 if (!headp) 05054 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 05055 else { 05056 AST_LIST_TRAVERSE(headp, current, entries) { 05057 /* SIPADDHEADER: Add SIP header to outgoing call */ 05058 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 05059 header = ast_var_value(current); 05060 headdup = ast_strdupa(header); 05061 /* Strip of the starting " (if it's there) */ 05062 if (*headdup == '"') 05063 headdup++; 05064 if ((content = strchr(headdup, ':'))) { 05065 *content = '\0'; 05066 content++; /* Move pointer ahead */ 05067 /* Skip white space */ 05068 while (*content == ' ') 05069 content++; 05070 /* Strip the ending " (if it's there) */ 05071 end = content + strlen(content) -1; 05072 if (*end == '"') 05073 *end = '\0'; 05074 05075 add_header(&req, headdup, content); 05076 if (sipdebug) 05077 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 05078 } 05079 } 05080 } 05081 } 05082 } 05083 } 05084 if (sdp && p->rtp) { 05085 ast_rtp_offered_from_local(p->rtp, 1); 05086 add_sdp(&req, p); 05087 } else { 05088 add_header_contentLength(&req, 0); 05089 add_blank_header(&req); 05090 } 05091 05092 if (!p->initreq.headers) { 05093 /* Use this as the basis */ 05094 copy_request(&p->initreq, &req); 05095 parse_request(&p->initreq); 05096 if (sip_debug_test_pvt(p)) 05097 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05098 } 05099 p->lastinvite = p->ocseq; 05100 return send_request(p, &req, init ? 2 : 1, p->ocseq); 05101 }
|
|
transmit_message_with_text: Transmit text with SIP MESSAGE method ---
Definition at line 5651 of file chan_sip.c. References add_text(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_MESSAGE. Referenced by sip_sendtext(). 05652 { 05653 struct sip_request req; 05654 reqprep(&req, p, SIP_MESSAGE, 0, 1); 05655 add_text(&req, text); 05656 return send_request(p, &req, 1, p->ocseq); 05657 }
|
|
transmit_notify_with_mwi: Notify user of messages waiting in voicemail ---
Definition at line 5276 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(). 05277 { 05278 struct sip_request req; 05279 char tmp[500]; 05280 char *t = tmp; 05281 size_t maxbytes = sizeof(tmp); 05282 char iabuf[INET_ADDRSTRLEN]; 05283 05284 initreqprep(&req, p, SIP_NOTIFY); 05285 add_header(&req, "Event", "message-summary"); 05286 add_header(&req, "Content-Type", default_notifymime); 05287 05288 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 05289 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); 05290 ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d (0/0)\r\n", newmsgs, oldmsgs); 05291 05292 if (t > tmp + sizeof(tmp)) 05293 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 05294 05295 add_header_contentLength(&req, strlen(tmp)); 05296 add_line(&req, tmp); 05297 05298 if (!p->initreq.headers) { /* Use this as the basis */ 05299 copy_request(&p->initreq, &req); 05300 parse_request(&p->initreq); 05301 if (sip_debug_test_pvt(p)) 05302 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05303 determine_firstline_parts(&p->initreq); 05304 } 05305 05306 return send_request(p, &req, 1, p->ocseq); 05307 }
|
|
transmit_notify_with_sipfrag: Notify a transferring party of the status of trasnfer ---
Definition at line 5329 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(). 05330 { 05331 struct sip_request req; 05332 char tmp[20]; 05333 reqprep(&req, p, SIP_NOTIFY, 0, 1); 05334 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 05335 add_header(&req, "Event", tmp); 05336 add_header(&req, "Subscription-state", "terminated;reason=noresource"); 05337 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 05338 05339 strcpy(tmp, "SIP/2.0 200 OK"); 05340 add_header_contentLength(&req, strlen(tmp)); 05341 add_line(&req, tmp); 05342 05343 if (!p->initreq.headers) { 05344 /* Use this as the basis */ 05345 copy_request(&p->initreq, &req); 05346 parse_request(&p->initreq); 05347 if (sip_debug_test_pvt(p)) 05348 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05349 determine_firstline_parts(&p->initreq); 05350 } 05351 05352 return send_request(p, &req, 1, p->ocseq); 05353 }
|
|
transmit_refer: Transmit SIP REFER message ---
Definition at line 5660 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(). 05661 { 05662 struct sip_request req; 05663 char from[256]; 05664 char *of, *c; 05665 char referto[256]; 05666 05667 if (ast_test_flag(p, SIP_OUTGOING)) 05668 of = get_header(&p->initreq, "To"); 05669 else 05670 of = get_header(&p->initreq, "From"); 05671 ast_copy_string(from, of, sizeof(from)); 05672 of = get_in_brackets(from); 05673 ast_copy_string(p->from,of,sizeof(p->from)); 05674 if (strncmp(of, "sip:", 4)) { 05675 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 05676 } else 05677 of += 4; 05678 /* Get just the username part */ 05679 if ((c = strchr(dest, '@'))) { 05680 c = NULL; 05681 } else if ((c = strchr(of, '@'))) { 05682 *c = '\0'; 05683 c++; 05684 } 05685 if (c) { 05686 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 05687 } else { 05688 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 05689 } 05690 05691 /* save in case we get 407 challenge */ 05692 ast_copy_string(p->refer_to, referto, sizeof(p->refer_to)); 05693 ast_copy_string(p->referred_by, p->our_contact, sizeof(p->referred_by)); 05694 05695 reqprep(&req, p, SIP_REFER, 0, 1); 05696 add_header(&req, "Refer-To", referto); 05697 if (!ast_strlen_zero(p->our_contact)) 05698 add_header(&req, "Referred-By", p->our_contact); 05699 add_blank_header(&req); 05700 return send_request(p, &req, 1, p->ocseq); 05701 }
|
|
transmit_register: Transmit register to SIP proxy or UA ---
Definition at line 5459 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, bindaddr, 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(). 05460 { 05461 struct sip_request req; 05462 char from[256]; 05463 char to[256]; 05464 char tmp[80]; 05465 char via[80]; 05466 char addr[80]; 05467 struct sip_pvt *p; 05468 05469 /* exit if we are already in process with this registrar ?*/ 05470 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 05471 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 05472 return 0; 05473 } 05474 05475 if (r->call) { /* We have a registration */ 05476 if (!auth) { 05477 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 05478 return 0; 05479 } else { 05480 p = r->call; 05481 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 05482 p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */ 05483 } 05484 } else { 05485 /* Build callid for registration if we haven't registered before */ 05486 if (!r->callid_valid) { 05487 build_callid(r->callid, sizeof(r->callid), __ourip, default_fromdomain); 05488 r->callid_valid = 1; 05489 } 05490 /* Allocate SIP packet for registration */ 05491 p=sip_alloc( r->callid, NULL, 0, SIP_REGISTER); 05492 if (!p) { 05493 ast_log(LOG_WARNING, "Unable to allocate registration call\n"); 05494 return 0; 05495 } 05496 if (recordhistory) { 05497 char tmp[80]; 05498 snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname); 05499 append_history(p, "RegistryInit", tmp); 05500 } 05501 /* Find address to hostname */ 05502 if (create_addr(p, r->hostname)) { 05503 /* we have what we hope is a temporary network error, 05504 * probably DNS. We need to reschedule a registration try */ 05505 sip_destroy(p); 05506 if (r->timeout > -1) { 05507 ast_sched_del(sched, r->timeout); 05508 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 05509 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 05510 } else { 05511 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 05512 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); 05513 } 05514 r->regattempts++; 05515 return 0; 05516 } 05517 /* Copy back Call-ID in case create_addr changed it */ 05518 ast_copy_string(r->callid, p->callid, sizeof(r->callid)); 05519 if (r->portno) 05520 p->sa.sin_port = htons(r->portno); 05521 else /* Set registry port to the port set from the peer definition/srv or default */ 05522 r->portno = ntohs(p->sa.sin_port); 05523 ast_set_flag(p, SIP_OUTGOING); /* Registration is outgoing call */ 05524 r->call=p; /* Save pointer to SIP packet */ 05525 p->registry=ASTOBJ_REF(r); /* Add pointer to registry in packet */ 05526 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 05527 ast_copy_string(p->peersecret, r->secret, sizeof(p->peersecret)); 05528 if (!ast_strlen_zero(r->md5secret)) 05529 ast_copy_string(p->peermd5secret, r->md5secret, sizeof(p->peermd5secret)); 05530 /* User name in this realm 05531 - if authuser is set, use that, otherwise use username */ 05532 if (!ast_strlen_zero(r->authuser)) { 05533 ast_copy_string(p->peername, r->authuser, sizeof(p->peername)); 05534 ast_copy_string(p->authname, r->authuser, sizeof(p->authname)); 05535 } else { 05536 if (!ast_strlen_zero(r->username)) { 05537 ast_copy_string(p->peername, r->username, sizeof(p->peername)); 05538 ast_copy_string(p->authname, r->username, sizeof(p->authname)); 05539 ast_copy_string(p->fromuser, r->username, sizeof(p->fromuser)); 05540 } 05541 } 05542 if (!ast_strlen_zero(r->username)) 05543 ast_copy_string(p->username, r->username, sizeof(p->username)); 05544 /* Save extension in packet */ 05545 ast_copy_string(p->exten, r->contact, sizeof(p->exten)); 05546 05547 /* 05548 check which address we should use in our contact header 05549 based on whether the remote host is on the external or 05550 internal network so we can register through nat 05551 */ 05552 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 05553 memcpy(&p->ourip, &bindaddr.sin_addr, sizeof(p->ourip)); 05554 build_contact(p); 05555 } 05556 05557 /* set up a timeout */ 05558 if (auth == NULL) { 05559 if (r->timeout > -1) { 05560 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 05561 ast_sched_del(sched, r->timeout); 05562 } 05563 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 05564 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 05565 } 05566 05567 if (strchr(r->username, '@')) { 05568 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 05569 if (!ast_strlen_zero(p->theirtag)) 05570 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 05571 else 05572 snprintf(to, sizeof(to), "<sip:%s>", r->username); 05573 } else { 05574 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 05575 if (!ast_strlen_zero(p->theirtag)) 05576 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 05577 else 05578 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 05579 } 05580 05581 /* Fromdomain is what we are registering to, regardless of actual 05582 host name from SRV */ 05583 if (!ast_strlen_zero(p->fromdomain)) 05584 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 05585 else 05586 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 05587 ast_copy_string(p->uri, addr, sizeof(p->uri)); 05588 05589 p->branch ^= thread_safe_rand(); 05590 05591 memset(&req, 0, sizeof(req)); 05592 init_req(&req, sipmethod, addr); 05593 05594 /* Add to CSEQ */ 05595 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 05596 p->ocseq = r->ocseq; 05597 05598 build_via(p, via, sizeof(via)); 05599 add_header(&req, "Via", via); 05600 add_header(&req, "From", from); 05601 add_header(&req, "To", to); 05602 add_header(&req, "Call-ID", p->callid); 05603 add_header(&req, "CSeq", tmp); 05604 add_header(&req, "User-Agent", default_useragent); 05605 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 05606 05607 05608 if (auth) /* Add auth header */ 05609 add_header(&req, authheader, auth); 05610 else if (!ast_strlen_zero(r->nonce)) { 05611 char digest[1024]; 05612 05613 /* We have auth data to reuse, build a digest header! */ 05614 if (sipdebug) 05615 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 05616 ast_copy_string(p->realm, r->realm, sizeof(p->realm)); 05617 ast_copy_string(p->nonce, r->nonce, sizeof(p->nonce)); 05618 ast_copy_string(p->domain, r->domain, sizeof(p->domain)); 05619 ast_copy_string(p->opaque, r->opaque, sizeof(p->opaque)); 05620 ast_copy_string(p->qop, r->qop, sizeof(p->qop)); 05621 p->noncecount = r->noncecount++; 05622 05623 memset(digest,0,sizeof(digest)); 05624 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 05625 add_header(&req, "Authorization", digest); 05626 else 05627 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 05628 05629 } 05630 05631 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 05632 add_header(&req, "Expires", tmp); 05633 add_header(&req, "Contact", p->our_contact); 05634 add_header(&req, "Event", "registration"); 05635 add_header_contentLength(&req, 0); 05636 add_blank_header(&req); 05637 copy_request(&p->initreq, &req); 05638 parse_request(&p->initreq); 05639 if (sip_debug_test_pvt(p)) { 05640 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05641 } 05642 determine_firstline_parts(&p->initreq); 05643 r->regstate=auth?REG_STATE_AUTHSENT:REG_STATE_REGSENT; 05644 r->regattempts++; /* Another attempt */ 05645 if (option_debug > 3) 05646 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 05647 return send_request(p, &req, 2, p->ocseq); 05648 }
|
|
transmit_reinvite_with_sdp: Transmit reinvite with SDP :-) ---
Definition at line 4732 of file chan_sip.c. References add_header(), add_sdp(), ALLOWED_METHODS, ast_rtp_offered_from_local(), ast_set_flag, ast_test_flag, ast_verbose(), copy_request(), sip_request::headers, sip_pvt::initreq, sip_pvt::lastinvite, sip_request::lines, sip_pvt::ocseq, parse_request(), reqprep(), sip_pvt::rtp, send_request(), sip_debug_test_pvt(), SIP_INVITE, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, and sipdebug. Referenced by check_pendings(), and sip_set_rtp_peer(). 04733 { 04734 struct sip_request req; 04735 if (ast_test_flag(p, SIP_REINVITE_UPDATE)) 04736 reqprep(&req, p, SIP_UPDATE, 0, 1); 04737 else 04738 reqprep(&req, p, SIP_INVITE, 0, 1); 04739 04740 add_header(&req, "Allow", ALLOWED_METHODS); 04741 if (sipdebug) 04742 add_header(&req, "X-asterisk-info", "SIP re-invite (RTP bridge)"); 04743 ast_rtp_offered_from_local(p->rtp, 1); 04744 add_sdp(&req, p); 04745 /* Use this as the basis */ 04746 copy_request(&p->initreq, &req); 04747 parse_request(&p->initreq); 04748 if (sip_debug_test_pvt(p)) 04749 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 04750 p->lastinvite = p->ocseq; 04751 ast_set_flag(p, SIP_OUTGOING); 04752 return send_request(p, &req, 1, p->ocseq); 04753 }
|
|
transmit_request: transmit generic SIP request ---
Definition at line 5723 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(). 05724 { 05725 struct sip_request resp; 05726 reqprep(&resp, p, sipmethod, seqno, newbranch); 05727 add_header_contentLength(&resp, 0); 05728 add_blank_header(&resp); 05729 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 05730 }
|
|
transmit_request_with_auth: Transmit SIP request, auth added ---
Definition at line 5733 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(). 05734 { 05735 struct sip_request resp; 05736 05737 reqprep(&resp, p, sipmethod, seqno, newbranch); 05738 if (*p->realm) { 05739 char digest[1024]; 05740 05741 memset(digest, 0, sizeof(digest)); 05742 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 05743 if (p->options && p->options->auth_type == PROXY_AUTH) 05744 add_header(&resp, "Proxy-Authorization", digest); 05745 else if (p->options && p->options->auth_type == WWW_AUTH) 05746 add_header(&resp, "Authorization", digest); 05747 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 05748 add_header(&resp, "Proxy-Authorization", digest); 05749 } else 05750 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 05751 } 05752 /* If we are hanging up and know a cause for that, send it in clear text to make 05753 debugging easier. */ 05754 if (sipmethod == SIP_BYE) { 05755 if (p->owner && p->owner->hangupcause) { 05756 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 05757 } 05758 } 05759 05760 add_header_contentLength(&resp, 0); 05761 add_blank_header(&resp); 05762 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 05763 }
|
|
transmit_response: Transmit response, no retransmits
Definition at line 4292 of file chan_sip.c. References __transmit_response(). 04293 { 04294 return __transmit_response(p, msg, req, 0); 04295 }
|
|
transmit_response_reliable: Transmit response, Make sure you get a reply
Definition at line 4308 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(). 04309 { 04310 return __transmit_response(p, msg, req, fatal ? 2 : 1); 04311 }
|
|
transmit_response_using_temp: Transmit response, no retransmits, using temporary pvt
Definition at line 4260 of file chan_sip.c. References __ourip, __transmit_response(), ast_copy_flags, ast_sip_ouraddrfor(), build_via(), default_fromdomain, global_flags, make_our_tag(), SIP_NAT, and thread_safe_rand(). Referenced by find_call(). 04261 { 04262 struct sip_pvt *p = alloca(sizeof(*p)); 04263 04264 memset(p, 0, sizeof(*p)); 04265 04266 p->method = intended_method; 04267 if (sin) { 04268 p->sa = *sin; 04269 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04270 p->ourip = __ourip; 04271 } else 04272 p->ourip = __ourip; 04273 p->branch = thread_safe_rand(); 04274 make_our_tag(p->tag, sizeof(p->tag)); 04275 p->ocseq = 101; 04276 04277 if (useglobal_nat && sin) { 04278 ast_copy_flags(p, &global_flags, SIP_NAT); 04279 memcpy(&p->recv, sin, sizeof(p->recv)); 04280 } 04281 04282 ast_copy_string(p->fromdomain, default_fromdomain, sizeof(p->fromdomain)); 04283 build_via(p, p->via, sizeof(p->via)); 04284 ast_copy_string(p->callid, callid, sizeof(p->callid)); 04285 04286 __transmit_response(p, msg, req, 0); 04287 04288 return 0; 04289 }
|
|
transmit_response_with_allow: Append Accept header, content length before transmitting response ---
Definition at line 4338 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(). 04339 { 04340 struct sip_request resp; 04341 respprep(&resp, p, msg, req); 04342 add_header(&resp, "Accept", "application/sdp"); 04343 add_header_contentLength(&resp, 0); 04344 add_blank_header(&resp); 04345 return send_response(p, &resp, reliable, 0); 04346 }
|
|
Definition at line 4349 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(). 04350 { 04351 struct sip_request resp; 04352 char tmp[512]; 04353 int seqno = 0; 04354 04355 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 04356 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 04357 return -1; 04358 } 04359 /* Stale means that they sent us correct authentication, but 04360 based it on an old challenge (nonce) */ 04361 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 04362 respprep(&resp, p, msg, req); 04363 add_header(&resp, header, tmp); 04364 add_header_contentLength(&resp, 0); 04365 add_blank_header(&resp); 04366 return send_response(p, &resp, reliable, seqno); 04367 }
|
|
transmit_response_with_date: Append date and content length before transmitting response ---
Definition at line 4327 of file chan_sip.c. References add_blank_header(), add_header_contentLength(), append_date(), respprep(), and send_response(). Referenced by register_verify(). 04328 { 04329 struct sip_request resp; 04330 respprep(&resp, p, msg, req); 04331 append_date(&resp); 04332 add_header_contentLength(&resp, 0); 04333 add_blank_header(&resp); 04334 return send_response(p, &resp, 0, 0); 04335 }
|
|
transmit_response_with_sdp: Used for 200 OK and 183 early media ---
Definition at line 4658 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(). 04659 { 04660 struct sip_request resp; 04661 int seqno; 04662 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 04663 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 04664 return -1; 04665 } 04666 respprep(&resp, p, msg, req); 04667 if (p->rtp) { 04668 ast_rtp_offered_from_local(p->rtp, 0); 04669 try_suggested_sip_codec(p); 04670 add_sdp(&resp, p); 04671 } else { 04672 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 04673 } 04674 return send_response(p, &resp, retrans, seqno); 04675 }
|
|
transmit_response_with_unsupported: Transmit response, no retransmits
Definition at line 4298 of file chan_sip.c. References add_header(), append_date(), respprep(), and send_response(). Referenced by handle_request_invite(). 04299 { 04300 struct sip_request resp; 04301 respprep(&resp, p, msg, req); 04302 append_date(&resp); 04303 add_header(&resp, "Unsupported", unsupported); 04304 return send_response(p, &resp, 0, 0); 04305 }
|
|
transmit_sip_request: Transmit SIP request
Definition at line 5310 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(). 05311 { 05312 if (!p->initreq.headers) { 05313 /* Use this as the basis */ 05314 copy_request(&p->initreq, req); 05315 parse_request(&p->initreq); 05316 if (sip_debug_test_pvt(p)) 05317 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05318 determine_firstline_parts(&p->initreq); 05319 } 05320 05321 return send_request(p, req, 0, p->ocseq); 05322 }
|
|
transmit_state_notify: Used in the SUBSCRIBE notification subsystem ----
Definition at line 5104 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, sip_pvt::expiry, sip_pvt::exten, find_subscription_type(), get_header(), get_in_brackets(), global_notifyringing, sip_pvt::initreq, LOG_WARNING, 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(). 05105 { 05106 char tmp[4000], from[256], to[256]; 05107 char *t = tmp, *c, *a, *mfrom, *mto; 05108 size_t maxbytes = sizeof(tmp); 05109 struct sip_request req; 05110 char hint[AST_MAX_EXTENSION]; 05111 char *statestring = "terminated"; 05112 const struct cfsubscription_types *subscriptiontype; 05113 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 05114 char *pidfstate = "--"; 05115 char *pidfnote= "Ready"; 05116 05117 memset(from, 0, sizeof(from)); 05118 memset(to, 0, sizeof(to)); 05119 memset(tmp, 0, sizeof(tmp)); 05120 05121 switch (state) { 05122 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 05123 if (global_notifyringing) 05124 statestring = "early"; 05125 else 05126 statestring = "confirmed"; 05127 local_state = NOTIFY_INUSE; 05128 pidfstate = "busy"; 05129 pidfnote = "Ringing"; 05130 break; 05131 case AST_EXTENSION_RINGING: 05132 statestring = "early"; 05133 local_state = NOTIFY_INUSE; 05134 pidfstate = "busy"; 05135 pidfnote = "Ringing"; 05136 break; 05137 case AST_EXTENSION_INUSE: 05138 statestring = "confirmed"; 05139 local_state = NOTIFY_INUSE; 05140 pidfstate = "busy"; 05141 pidfnote = "On the phone"; 05142 break; 05143 case AST_EXTENSION_BUSY: 05144 statestring = "confirmed"; 05145 local_state = NOTIFY_CLOSED; 05146 pidfstate = "busy"; 05147 pidfnote = "On the phone"; 05148 break; 05149 case AST_EXTENSION_UNAVAILABLE: 05150 statestring = "confirmed"; 05151 local_state = NOTIFY_CLOSED; 05152 pidfstate = "away"; 05153 pidfnote = "Unavailable"; 05154 break; 05155 case AST_EXTENSION_NOT_INUSE: 05156 default: 05157 /* Default setting */ 05158 break; 05159 } 05160 05161 subscriptiontype = find_subscription_type(p->subscribed); 05162 05163 /* Check which device/devices we are watching and if they are registered */ 05164 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 05165 /* If they are not registered, we will override notification and show no availability */ 05166 if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) { 05167 local_state = NOTIFY_CLOSED; 05168 pidfstate = "away"; 05169 pidfnote = "Not online"; 05170 } 05171 } 05172 05173 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 05174 c = get_in_brackets(from); 05175 if (strncmp(c, "sip:", 4)) { 05176 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 05177 return -1; 05178 } 05179 if ((a = strchr(c, ';'))) 05180 *a = '\0'; 05181 mfrom = c; 05182 05183 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 05184 c = get_in_brackets(to); 05185 if (strncmp(c, "sip:", 4)) { 05186 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 05187 return -1; 05188 } 05189 if ((a = strchr(c, ';'))) 05190 *a = '\0'; 05191 mto = c; 05192 05193 reqprep(&req, p, SIP_NOTIFY, 0, 1); 05194 05195 05196 add_header(&req, "Event", subscriptiontype->event); 05197 add_header(&req, "Content-Type", subscriptiontype->mediatype); 05198 switch(state) { 05199 case AST_EXTENSION_DEACTIVATED: 05200 if (p->subscribed == TIMEOUT) 05201 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 05202 else { 05203 add_header(&req, "Subscription-State", "terminated;reason=probation"); 05204 add_header(&req, "Retry-After", "60"); 05205 } 05206 break; 05207 case AST_EXTENSION_REMOVED: 05208 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 05209 break; 05210 break; 05211 default: 05212 if (p->expiry) 05213 add_header(&req, "Subscription-State", "active"); 05214 else /* Expired */ 05215 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 05216 } 05217 switch (p->subscribed) { 05218 case XPIDF_XML: 05219 case CPIM_PIDF_XML: 05220 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 05221 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 05222 ast_build_string(&t, &maxbytes, "<presence>\n"); 05223 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 05224 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 05225 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 05226 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 05227 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 05228 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 05229 break; 05230 case PIDF_XML: /* Eyebeam supports this format */ 05231 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 05232 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); 05233 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 05234 if (pidfstate[0] != '-') 05235 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 05236 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 05237 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 05238 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 05239 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 05240 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 05241 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 05242 else 05243 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 05244 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 05245 break; 05246 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 05247 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 05248 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); 05249 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 05250 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 05251 else 05252 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 05253 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 05254 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 05255 break; 05256 case NONE: 05257 default: 05258 break; 05259 } 05260 05261 if (t > tmp + sizeof(tmp)) 05262 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 05263 05264 add_header_contentLength(&req, strlen(tmp)); 05265 add_line(&req, tmp); 05266 05267 return send_request(p, &req, 1, p->ocseq); 05268 }
|
|
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 2519 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(). 02520 { 02521 int fmt; 02522 char *codec; 02523 02524 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 02525 if (!codec) 02526 return; 02527 02528 fmt = ast_getformatbyname(codec); 02529 if (fmt) { 02530 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC) variable\n",codec); 02531 if (p->jointcapability & fmt) { 02532 p->jointcapability &= fmt; 02533 p->capability &= fmt; 02534 } else 02535 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 02536 } else 02537 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n",codec); 02538 return; 02539 }
|
|
|
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 2208 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, and sip_pvt::username. Referenced by handle_request_invite(), handle_response(), sip_call(), and sip_hangup(). 02209 { 02210 char name[256]; 02211 int *inuse, *call_limit; 02212 int outgoing = ast_test_flag(fup, SIP_OUTGOING); 02213 struct sip_user *u = NULL; 02214 struct sip_peer *p = NULL; 02215 02216 if (option_debug > 2) 02217 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 02218 /* Test if we need to check call limits, in order to avoid 02219 realtime lookups if we do not need it */ 02220 if (!ast_test_flag(fup, SIP_CALL_LIMIT)) 02221 return 0; 02222 02223 ast_copy_string(name, fup->username, sizeof(name)); 02224 02225 /* Check the list of users */ 02226 u = find_user(name, 1); 02227 if (u) { 02228 inuse = &u->inUse; 02229 call_limit = &u->call_limit; 02230 p = NULL; 02231 } else { 02232 /* Try to find peer */ 02233 if (!p) 02234 p = find_peer(fup->peername, NULL, 1); 02235 if (p) { 02236 inuse = &p->inUse; 02237 call_limit = &p->call_limit; 02238 ast_copy_string(name, fup->peername, sizeof(name)); 02239 } else { 02240 if (option_debug > 1) 02241 ast_log(LOG_DEBUG, "%s is not a local user, no call limit\n", name); 02242 return 0; 02243 } 02244 } 02245 switch(event) { 02246 /* incoming and outgoing affects the inUse counter */ 02247 case DEC_CALL_LIMIT: 02248 if ( *inuse > 0 ) { 02249 if (ast_test_flag(fup,SIP_INC_COUNT)) 02250 (*inuse)--; 02251 } else { 02252 *inuse = 0; 02253 } 02254 if (option_debug > 1 || sipdebug) { 02255 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 02256 } 02257 break; 02258 case INC_CALL_LIMIT: 02259 if (*call_limit > 0 ) { 02260 if (*inuse >= *call_limit) { 02261 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); 02262 if (u) 02263 ASTOBJ_UNREF(u,sip_destroy_user); 02264 else 02265 ASTOBJ_UNREF(p,sip_destroy_peer); 02266 return -1; 02267 } 02268 } 02269 (*inuse)++; 02270 ast_set_flag(fup,SIP_INC_COUNT); 02271 if (option_debug > 1 || sipdebug) { 02272 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 02273 } 02274 break; 02275 default: 02276 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 02277 } 02278 if (u) 02279 ASTOBJ_UNREF(u,sip_destroy_user); 02280 else 02281 ASTOBJ_UNREF(p,sip_destroy_peer); 02282 return 0; 02283 }
|
|
update_peer: Update peer data in database (if used) ---
Definition at line 1676 of file chan_sip.c. References sip_peer::addr, ast_test_flag, sip_peer::flags_page2, sip_peer::fullcontact, global_flags_page2, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username. Referenced by register_verify(). 01677 { 01678 int rtcachefriends = ast_test_flag(&(p->flags_page2), SIP_PAGE2_RTCACHEFRIENDS); 01679 if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTUPDATE) && 01680 (ast_test_flag(p, SIP_REALTIME) || rtcachefriends)) { 01681 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry); 01682 } 01683 }
|
|
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 13571 of file chan_sip.c. References usecnt. 13572 { 13573 return usecnt; 13574 }
|
|
Definition at line 414 of file chan_sip.c. |
|
Structure for conversion between compressed SIP and "normal" SIP.
|
|
Accept calls to external SIP domains? Definition at line 503 of file chan_sip.c. Referenced by get_destination(), reload_config(), and sip_show_settings(). |
|
Definition at line 382 of file chan_sip.c. Referenced by sip_show_objects(), and temp_peer(). |
|
Definition at line 13048 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 13050 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 13062 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Authentication list Definition at line 886 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 364 of file chan_sip.c. Referenced by register_verify(), reload_config(), and sip_show_settings(). |
|
Definition at line 876 of file chan_sip.c. |
|
Definition at line 911 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 9397 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
send compact sip headers Definition at line 427 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 9296 of file chan_sip.c. |
|
Definition at line 421 of file chan_sip.c. Referenced by sip_do_debug(), sip_do_debug_ip(), and sip_do_debug_peer(). |
|
Definition at line 344 of file chan_sip.c. Referenced by build_rpid(), reload_config(), and sip_show_settings(). |
|
Definition at line 335 of file chan_sip.c. |
|
Definition at line 121 of file chan_sip.c. Referenced by parse_register_contact(), reload_config(), sip_register(), sip_send_all_registers(), sip_show_settings(), and transmit_register(). |
|
Definition at line 346 of file chan_sip.c. Referenced by reload_config(), sip_alloc(), sip_show_settings(), transmit_register(), and transmit_response_using_temp(). |
|
Definition at line 341 of file chan_sip.c. Referenced by build_peer(), build_user(), reload_config(), sip_show_settings(), and temp_peer(). |
|
Definition at line 349 of file chan_sip.c. Referenced by reload_config(), sip_show_settings(), and transmit_notify_with_mwi(). |
|
Default Qualify= setting Definition at line 355 of file chan_sip.c. Referenced by build_peer(), reload_config(), and sip_show_settings(). |
|
Definition at line 336 of file chan_sip.c. Referenced by build_peer(), reload_config(), and temp_peer(). |
|
Definition at line 332 of file chan_sip.c. Referenced by reload_config(), reqprep(), respprep(), sip_show_settings(), and transmit_register(). |
|
Definition at line 144 of file chan_sip.c. |
|
Definition at line 13047 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 13054 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 13065 of file chan_sip.c. Referenced by load_module(). |
|
Dump history to verbose before destroying SIP dialog Definition at line 430 of file chan_sip.c. Referenced by reload_config(). |
|
Definition at line 438 of file chan_sip.c. Referenced by complete_dpreply(), parse_register_contact(), reg_source_db(), and reload_config(). |
|
Definition at line 879 of file chan_sip.c. Referenced by ast_sip_ouraddrfor(), and reload_config(). |
|
Definition at line 878 of file chan_sip.c. Referenced by ast_sip_ouraddrfor(), and reload_config(). |
|
Definition at line 877 of file chan_sip.c. Referenced by ast_sip_ouraddrfor(), and reload_config(). |
|
Definition at line 880 of file chan_sip.c. Referenced by ast_sip_ouraddrfor(), and reload_config(). |
|
allow unauthenticated users/peers to connect? Definition at line 385 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 353 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 411 of file chan_sip.c. Referenced by build_peer(), build_user(), reload_config(), sip_alloc(), sip_request_call(), and temp_peer(). |
|
global SIP_ flags Definition at line 357 of file chan_sip.c. Referenced by build_peer(), build_user(), check_user_full(), reload_config(), sip_alloc(), sip_show_settings(), temp_peer(), and transmit_response_using_temp(). |
|
more global SIP_ flags Definition at line 358 of file chan_sip.c. Referenced by build_peer(), destroy_association(), realtime_peer(), realtime_user(), reload_config(), sip_show_settings(), and update_peer(). |
|
Global music on hold class Definition at line 432 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 388 of file chan_sip.c. Referenced by do_monitor(), reload_config(), and sip_show_settings(). |
|
Send notifications on ringing Definition at line 351 of file chan_sip.c. Referenced by reload_config(), sip_show_settings(), and transmit_state_notify(). |
|
Default realm Definition at line 434 of file chan_sip.c. Referenced by check_auth(), reload_config(), sip_show_settings(), and transmit_response_with_auth(). |
|
Definition at line 374 of file chan_sip.c. Referenced by reload_config(), sip_show_settings(), and transmit_register(). |
|
Definition at line 375 of file chan_sip.c. Referenced by handle_response_register(), reload_config(), sip_reg_timeout(), and sip_show_settings(). |
|
Definition at line 591 of file chan_sip.c. |
|
Definition at line 370 of file chan_sip.c. Referenced by build_peer(), reload_config(), sip_alloc(), sip_show_settings(), and temp_peer(). |
|
Definition at line 372 of file chan_sip.c. Referenced by build_peer(), reload_config(), sip_alloc(), and temp_peer(). |
|
Definition at line 368 of file chan_sip.c. Referenced by build_peer(), reload_config(), sip_alloc(), sip_show_settings(), and temp_peer(). |
|
Definition at line 339 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 9313 of file chan_sip.c. |
|
sip_pvt: PVT structures are used for each SIP conversation, ie. a call
|
|
Definition at line 441 of file chan_sip.c. |
|
Definition at line 881 of file chan_sip.c. Referenced by ast_sip_ouraddrfor(), reload_config(), and unload_module(). |
|
Definition at line 8020 of file chan_sip.c. |
|
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 7602 of file chan_sip.c. |
|
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 406 of file chan_sip.c. |
|
Definition at line 13393 of file chan_sip.c. |
|
Initial value: "Usage: sip no debug\n" " Disables dumping of SIP packets for debugging purposes\n" Definition at line 9305 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 9309 of file chan_sip.c. |
|
Definition at line 412 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 884 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 9245 of file chan_sip.c. |
|
Definition at line 416 of file chan_sip.c. |
|
Definition at line 415 of file chan_sip.c. Referenced by reload_config(). |
|
Extra checking ? Default off Definition at line 362 of file chan_sip.c. Referenced by __get_header(), check_user_full(), find_call(), get_destination(), get_refer_info(), handle_request(), register_verify(), reload_config(), sip_show_settings(), and sipsock_read(). |
|
The peer list: Peers and Friends ---.
|
|
Definition at line 450 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 9287 of file chan_sip.c. |
|
Record SIP history. Off by default Definition at line 429 of file chan_sip.c. Referenced by do_register_auth(), reload_config(), sip_do_history(), sip_no_history(), sip_reregister(), sip_show_history(), sip_show_settings(), sipsock_read(), and transmit_register(). |
|
Context for auto-extensions Definition at line 435 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 383 of file chan_sip.c. Referenced by sip_register(), sip_send_all_registers(), and sip_show_objects(). |
|
Definition at line 366 of file chan_sip.c. Referenced by reload_config(), and sip_show_settings(). |
|
Definition at line 381 of file chan_sip.c. Referenced by build_peer(), and sip_show_objects(). |
|
Definition at line 379 of file chan_sip.c. Referenced by sip_show_objects(). |
|
Definition at line 440 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 9269 of file chan_sip.c. |
|
Initial value: "Usage: sip show channels\n" " Lists all currently active SIP channels.\n" Definition at line 9265 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 9240 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 9273 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 9260 of file chan_sip.c. |
|
Initial value: "Usage: sip show objects\n" " Shows status of known SIP objects\n" Definition at line 9326 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 9282 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 9277 of file chan_sip.c. |
|
Initial value: "Usage: sip show registry\n" " Lists all registration requests and status.\n" Definition at line 9292 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 9330 of file chan_sip.c. |
|
Initial value: "Usage: sip show subscriptions\n" " Shows active SIP subscriptions for extension states\n" Definition at line 9322 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 9255 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 9250 of file chan_sip.c. |
|
Definition at line 9376 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(), 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 9318 of file chan_sip.c. |
|
Definition at line 808 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 13298 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition of this channel for PBX channel registration.
Definition at line 937 of file chan_sip.c. Referenced by load_module(), sip_new(), and unload_module(). |
|
Definition at line 9561 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
|
Definition at line 9484 of file chan_sip.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 873 of file chan_sip.c. Referenced by __sip_xmit(), do_monitor(), reg_source_db(), reload_config(), sipsock_read(), and unload_module(). |
|
Definition at line 442 of file chan_sip.c. Referenced by do_monitor(). |
|
Definition at line 380 of file chan_sip.c. Referenced by build_peer(), and sip_show_objects(). |
|
SRV Lookup on or off. Default is off, RFC behavior is on Definition at line 360 of file chan_sip.c. Referenced by build_peer(), reload_config(), and sip_show_settings(). |
|
Referenced by find_subscription_type(), and subscription_type2str(). |
|
Definition at line 378 of file chan_sip.c. Referenced by build_user(), and sip_show_objects(). |
|
Definition at line 13046 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 13051 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 13063 of file chan_sip.c. Referenced by load_module(). |
|
Definition at line 423 of file chan_sip.c. |
|
Definition at line 390 of file chan_sip.c. |
|
The user list: Users and friends ---.
|
|
Definition at line 425 of file chan_sip.c. Referenced by reload_config(), sip_alloc(), and sip_show_settings(). |