#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. | |
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 struct cfsubscription_types * | find_subscription_type (enum subscriptiontype subtype) |
find_subscription_type: Find subscription type in array | |
static struct sip_user * | find_user (const char *name, int realtime) |
find_user: Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf) | |
static void | free_old_route (struct sip_route *route) |
free_old_route: Remove route from route list --- | |
static char * | func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
function_check_sipdomain: Dial plan function to check if domain is local | |
static char * | func_header_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
func_header_read: Read SIP header (dialplan function) | |
static char * | function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
function_sipchaninfo_read: ${SIPCHANINFO()} Dialplan function - reads sip channel data | |
static char * | function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
function_sippeer: ${SIPPEER()} Dialplan function - reads peer data | |
static int | get_also_info (struct sip_pvt *p, struct sip_request *oreq) |
get_also_info: Call transfer support (old way, depreciated)-- | |
static char * | get_body (struct sip_request *req, char *name) |
get_body: get a specific line from the message body | |
static char * | get_body_by_line (char *line, char *name, int nameLen) |
get_body_by_line: Reads one line of message body | |
static char * | get_calleridname (char *input, char *output, size_t outputsize) |
get_calleridname: Get caller id name from SIP headers --- | |
static int | get_destination (struct sip_pvt *p, struct sip_request *oreq) |
get_destination: Find out who the call is for -- | |
static char * | get_header (struct sip_request *req, char *name) |
get_header: Get header from SIP request --- | |
static char * | get_in_brackets (char *tmp) |
get_in_brackets: Pick out text in brackets from character string --- | |
static int | get_msg_text (char *buf, int len, struct sip_request *req) |
get_msg_text: Get text out of a SIP MESSAGE packet --- | |
static int | get_rdnis (struct sip_pvt *p, struct sip_request *oreq) |
get_rdnis: get referring dnis --- | |
static int | get_refer_info (struct sip_pvt *sip_pvt, struct sip_request *outgoing_req) |
get_refer_info: Call transfer support (the REFER method) --- | |
static int | get_rpid_num (char *input, char *output, int maxlen) |
get_rpid_num: Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found | |
static char * | get_sdp (struct sip_request *req, char *name) |
get_sdp: get a specific line from the SDP | |
static char * | get_sdp_iterate (int *iterator, struct sip_request *req, char *name) |
static struct sip_pvt * | get_sip_pvt_byid_locked (char *callid) |
get_sip_pvt_byid_locked: Lock interface lock and find matching pvt lock --- | |
static char * | gettag (struct sip_request *req, char *header, char *tagbuf, int tagbufsize) |
gettag: Get tag from packet | |
static int | handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v) |
handle_common_options: Handle flag-type options common to users and peers --- | |
static int | handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock) |
handle_request: Handle SIP requests (methods) --- | |
static int | handle_request_bye (struct sip_pvt *p, struct sip_request *req, int debug, int ignore) |
handle_request_bye: Handle incoming BYE request --- | |
static int | handle_request_cancel (struct sip_pvt *p, struct sip_request *req, int debug, int ignore) |
handle_request_cancel: Handle incoming CANCEL request --- | |
static void | handle_request_info (struct sip_pvt *p, struct sip_request *req) |
handle_request_info: Receive SIP INFO Message --- | |
static int | handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin, int *recount, char *e) |
handle_request_invite: Handle incoming INVITE request | |
static int | handle_request_message (struct sip_pvt *p, struct sip_request *req, int debug, int ignore) |
handle_request_message: Handle incoming MESSAGE request --- | |
static int | handle_request_options (struct sip_pvt *p, struct sip_request *req, int debug) |
handle_request_options: Handle incoming OPTIONS request | |
static int | handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock) |
handle_request_refer: Handle incoming REFER request --- | |
static int | handle_request_register (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, struct sockaddr_in *sin, char *e) |
handle_request_register: Handle incoming REGISTER request --- | |
static int | handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, struct sockaddr_in *sin, int seqno, char *e) |
handle_request_subscribe: Handle incoming SUBSCRIBE request --- | |
static void | handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
handle_response: Handle SIP response in dialogue --- | |
static void | handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
handle_response_invite: Handle SIP response in dialogue --- | |
static int | handle_response_peerpoke (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno, int sipmethod) |
handle_response_peerpoke: Handle qualification responses (OPTIONS) | |
static int | handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
handle_response_register: Handle responses on REGISTER to services --- | |
static char * | hangup_cause2sip (int cause) |
hangup_cause2sip: Convert Asterisk hangup causes to SIP codes | |
static int | hangup_sip2cause (int cause) |
hangup_sip2cause: Convert SIP hangup causes to Asterisk hangup causes --- | |
static int | init_req (struct sip_request *req, int sipmethod, char *recip) |
init_req: Initialize SIP request --- | |
static int | init_resp (struct sip_request *req, char *resp, struct sip_request *orig) |
init_resp: Initialize SIP response, based on SIP request --- | |
static void | initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod) |
initreqprep: Initiate new SIP request to peer/user --- | |
static const char * | insecure2str (int port, int invite) |
insecure2str: Convert Insecure setting to printable string --- | |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
static void | list_route (struct sip_route *route) |
list_route: List all routes - mostly for debugging --- | |
int | load_module () |
Initialize the module. | |
static int | lws2sws (char *msgbuf, int len) |
lws2sws: Parse multiline SIP headers into one header | |
static void | make_our_tag (char *tagbuf, size_t len) |
static int | manager_sip_show_peer (struct mansession *s, struct message *m) |
manager_sip_show_peer: Show SIP peers in the manager API --- | |
static int | manager_sip_show_peers (struct mansession *s, struct message *m) |
manager_sip_show_peers: Show SIP peers in the manager API --- | |
static char * | nat2str (int nat) |
nat2str: Convert NAT setting to text string | |
static void | parse_copy (struct sip_request *dst, struct sip_request *src) |
parse_copy: Copy SIP request, parse it | |
static void | parse_moved_contact (struct sip_pvt *p, struct sip_request *req) |
parse_moved_contact: Parse 302 Moved temporalily response | |
static int | parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req) |
parse_ok_contact: Parse contact header for 200 OK on INVITE --- | |
static enum parse_register_result | parse_register_contact (struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req) |
parse_register_contact: Parse contact header and save registration --- | |
static void | parse_request (struct sip_request *req) |
parse_request: Parse a SIP message ---- | |
unsigned int | parse_sip_options (struct sip_pvt *pvt, char *supported) |
parse_sip_options: Parse supported header in incoming packet | |
static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
peer_status: Report Peer status in character string | |
static void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
print_codec_to_cli: Print codec list from preference to CLI/manager | |
static void | print_group (int fd, unsigned int group, int crlf) |
print_group: Print call group and pickup group --- | |
static int | process_sdp (struct sip_pvt *p, struct sip_request *req) |
process_sdp: Process SIP SDP and activate RTP channels--- | |
static struct sip_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf | |
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey) |
realtime_update_peer: Update peer object in realtime storage --- | |
static struct sip_user * | realtime_user (const char *username) |
realtime_user: Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped) | |
static void | receive_message (struct sip_pvt *p, struct sip_request *req) |
receive_message: Receive SIP MESSAGE method messages --- | |
static void | reg_source_db (struct sip_peer *peer) |
reg_source_db: Get registration details from Asterisk DB --- | |
static void | register_peer_exten (struct sip_peer *peer, int onoff) |
register_peer_exten: Automatically add peer extension to dial plan --- | |
static int | register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri, int ignore) |
register_verify: Verify registration of user | |
static char * | regstate2str (int regstate) |
int | reload (void) |
Reload stuff. | |
static int | reload_config (void) |
reload_config: Re-read SIP.conf config file --- | |
static int | reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len) |
reply_digest: reply to authentication for outbound registrations --- | |
static int | reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch) |
reqprep: Initialize a SIP request response packet --- | |
static int | respprep (struct sip_request *resp, struct sip_pvt *p, char *msg, struct sip_request *req) |
respprep: Prepare SIP response packet --- | |
static int | restart_monitor (void) |
restart_monitor: Start the channel monitor thread --- | |
static int | retrans_pkt (void *data) |
retrans_pkt: Retransmit SIP message if no answer --- | |
static void | sdpLineNum_iterator_init (int *iterator, struct sip_request *req) |
static int | send_request (struct sip_pvt *p, struct sip_request *req, int reliable, int seqno) |
send_request: Send SIP Request to the other part of the dialogue --- | |
static int | send_response (struct sip_pvt *p, struct sip_request *req, int reliable, int seqno) |
send_response: Transmit response on SIP request--- | |
static void | set_destination (struct sip_pvt *p, char *uri) |
set_destination: Set destination from SIP URI --- | |
static int | sip_addheader (struct ast_channel *chan, void *data) |
sip_addheader: Add a SIP header --- | |
static int | sip_addrcmp (char *name, struct sockaddr_in *sin) |
sip_addrcmp: Support routine for find_peer --- | |
static struct sip_pvt * | sip_alloc (char *callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method) |
sip_alloc: Allocate SIP_PVT structure and set defaults --- | |
static int | sip_answer (struct ast_channel *ast) |
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface | |
static int | sip_call (struct ast_channel *ast, char *dest, int timeout) |
sip_call: Initiate SIP call from PBX used from the dial() application | |
static int | sip_cancel_destroy (struct sip_pvt *p) |
sip_cancel_destroy: Cancel destruction of SIP call --- | |
static int | sip_debug_test_addr (struct sockaddr_in *addr) |
sip_debug_test_addr: See if we pass debug IP filter | |
static int | sip_debug_test_pvt (struct sip_pvt *p) |
sip_debug_test_pvt: Test PVT for debugging output | |
static void | sip_destroy (struct sip_pvt *p) |
sip_destroy: Destroy SIP call structure --- | |
static void | sip_destroy_peer (struct sip_peer *peer) |
sip_destroy_peer: Destroy peer object from memory | |
static void | sip_destroy_user (struct sip_user *user) |
sip_destroy_user: Remove user object from in-memory storage --- | |
static int | sip_devicestate (void *data) |
sip_devicestate: Part of PBX channel interface --- | |
static int | sip_do_debug (int fd, int argc, char *argv[]) |
sip_do_debug: Turn on SIP debugging (CLI command) | |
static int | sip_do_debug_ip (int fd, int argc, char *argv[]) |
sip_do_debug: Enable SIP Debugging in CLI --- | |
static int | sip_do_debug_peer (int fd, int argc, char *argv[]) |
sip_do_debug_peer: Turn on SIP debugging with peer mask | |
static int | sip_do_history (int fd, int argc, char *argv[]) |
sip_do_history: Enable SIP History logging (CLI) --- | |
static int | sip_do_reload (void) |
sip_do_reload: Reload module | |
static int | sip_dtmfmode (struct ast_channel *chan, void *data) |
sip_dtmfmode: change the DTMFmode for a SIP call (application) --- | |
static void | sip_dump_history (struct sip_pvt *dialog) |
dump_history: Dump SIP history to debug log file at end of lifespan for SIP dialog | |
static int | sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links ---- | |
static int | sip_get_codec (struct ast_channel *chan) |
sip_get_codec: Return SIP UA's codec (part of the RTP interface) --- | |
static struct ast_rtp * | sip_get_rtp_peer (struct ast_channel *chan) |
sip_get_rtp_peer: Returns null if we can't reinvite (part of RTP interface) | |
static struct ast_rtp * | sip_get_vrtp_peer (struct ast_channel *chan) |
sip_get_vrtp_peer: Returns null if we can't reinvite video (part of RTP interface) | |
static int | sip_getheader (struct ast_channel *chan, void *data) |
sip_getheader: Get a SIP header (dialplan app) --- | |
static int | sip_hangup (struct ast_channel *ast) |
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup | |
static int | sip_indicate (struct ast_channel *ast, int condition) |
sip_indicate: Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc | |
static struct ast_channel * | sip_new (struct sip_pvt *i, int state, char *title) |
sip_new: Initiate a call in the SIP channel | |
static int | sip_no_debug (int fd, int argc, char *argv[]) |
sip_no_debug: Disable SIP Debugging in CLI --- | |
static int | sip_no_history (int fd, int argc, char *argv[]) |
sip_no_history: Disable SIP History logging (CLI) --- | |
static int | sip_notify (int fd, int argc, char *argv[]) |
sip_notify: Send SIP notify to peer | |
static int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req) |
sip_park: Park a call --- | |
static void * | sip_park_thread (void *stuff) |
sip_park_thread: Park SIP call support function | |
static void | sip_poke_all_peers (void) |
sip_poke_all_peers: Send a poke to all known peers | |
static int | sip_poke_noanswer (void *data) |
sip_poke_noanswer: No answer to Qualify poke --- | |
static int | sip_poke_peer (struct sip_peer *peer) |
sip_poke_peer: Check availability of peer, also keep NAT open --- | |
static int | sip_poke_peer_s (void *data) |
static int | sip_prune_realtime (int fd, int argc, char *argv[]) |
sip_prune_realtime: Remove temporary realtime objects from memory (CLI) --- | |
static struct ast_frame * | sip_read (struct ast_channel *ast) |
sip_read: Read SIP RTP from channel | |
static int | sip_reg_timeout (void *data) |
sip_reg_timeout: Registration timeout, register again | |
static int | sip_register (char *value, int lineno) |
sip_register: Parse register=> line in sip.conf and add to registry | |
static void | sip_registry_destroy (struct sip_registry *reg) |
sip_registry_destroy: Destroy registry object --- | |
static int | sip_reload (int fd, int argc, char *argv[]) |
sip_reload: Force reload of module from cli --- | |
static struct ast_channel * | sip_request_call (const char *type, int format, void *data, int *cause) |
sip_request: PBX interface function -build SIP pvt structure --- | |
static int | sip_reregister (void *data) |
sip_reregister: Update registration with SIP Proxy--- | |
static struct ast_frame * | sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p) |
sip_rtp_read: Read RTP from network --- | |
static int | sip_scheddestroy (struct sip_pvt *p, int ms) |
sip_scheddestroy: Schedule destruction of SIP call --- | |
static void | sip_send_all_registers (void) |
sip_send_all_registers: Send all known registrations | |
static int | sip_send_mwi_to_peer (struct sip_peer *peer) |
sip_send_mwi_to_peer: Send message waiting indication --- | |
static int | sip_senddigit (struct ast_channel *ast, char digit) |
sip_senddigit: Send DTMF character on SIP channel | |
static int | sip_sendtext (struct ast_channel *ast, const char *text) |
sip_sendtext: Send SIP MESSAGE text within a call --- | |
static int | sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active) |
sip_set_rtp_peer: Set the RTP peer for this call --- | |
static int | sip_show_channel (int fd, int argc, char *argv[]) |
sip_show_channel: Show details of one call --- | |
static int | sip_show_channels (int fd, int argc, char *argv[]) |
sip_show_channels: Show active SIP channels --- | |
static int | sip_show_domains (int fd, int argc, char *argv[]) |
static int | sip_show_history (int fd, int argc, char *argv[]) |
sip_show_history: Show history details of one call --- | |
static int | sip_show_inuse (int fd, int argc, char *argv[]) |
sip_show_inuse: CLI Command to show calls within limits set by call_limit --- | |
static int | sip_show_objects (int fd, int argc, char *argv[]) |
sip_show_objects: List all allocated SIP Objects --- | |
static int | sip_show_peer (int fd, int argc, char *argv[]) |
sip_show_peer: Show one peer in detail --- | |
static int | sip_show_peers (int fd, int argc, char *argv[]) |
sip_show_peers: CLI Show Peers command | |
static int | sip_show_registry (int fd, int argc, char *argv[]) |
sip_show_registry: Show SIP Registry (registrations with other SIP proxies --- | |
static int | sip_show_settings (int fd, int argc, char *argv[]) |
sip_show_settings: List global settings for the SIP channel --- | |
static int | sip_show_subscriptions (int fd, int argc, char *argv[]) |
sip_show_subscriptions: Show active SIP subscriptions --- | |
static int | sip_show_user (int fd, int argc, char *argv[]) |
sip_show_user: Show one user in detail --- | |
static int | sip_show_users (int fd, int argc, char *argv[]) |
sip_show_users: CLI Command 'SIP Show Users' --- | |
static int | sip_sipredirect (struct sip_pvt *p, const char *dest) |
sip_sipredirect: Transfer call before connect with a 302 redirect --- | |
static int | sip_transfer (struct ast_channel *ast, const char *dest) |
sip_transfer: Transfer SIP call | |
static int | sip_write (struct ast_channel *ast, struct ast_frame *frame) |
sip_write: Send frame to media channel (rtp) --- | |
static int | sipsock_read (int *id, int fd, short events, void *ignore) |
sipsock_read: Read data from SIP socket --- | |
static const char * | subscription_type2str (enum subscriptiontype subtype) |
subscription_type2str: Show subscription type in string format | |
static struct sip_peer * | temp_peer (const char *name) |
temp_peer: Create temporary peer (used in autocreatepeer mode) --- | |
static force_inline int | thread_safe_rand (void) |
Thread-safe random number generator. | |
static void | transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, char *randdata, int randlen, int reliable) |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers. | |
static int | transmit_info_with_digit (struct sip_pvt *p, char digit) |
transmit_info_with_digit: Send SIP INFO dtmf message, see Cisco documentation on cisco.co m --- | |
static int | transmit_info_with_vidupdate (struct sip_pvt *p) |
transmit_info_with_vidupdate: Send SIP INFO with video update request --- | |
static int | transmit_invite (struct sip_pvt *p, int sipmethod, int 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_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 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 struct cfsip_methods | sip_methods [] |
static struct cfsip_options | sip_options [] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. | |
static 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 struct ast_channel_tech | sip_tech |
Definition of this channel for PBX channel registration. | |
static struct ast_custom_function | sipchaninfo_function |
static int | sipdebug = 0 |
ast_custom_function | sippeer_function |
static int | sipsock = -1 |
static int | speerobjs = 0 |
static int | srvlookup = 0 |
static 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.
#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support.
Definition at line 323 of file chan_sip.c.
Referenced by respprep(), transmit_invite(), and transmit_reinvite_with_sdp().
#define CALLERID_UNKNOWN "Unknown" |
#define DEBUG_READ 0 |
#define DEBUG_SEND 1 |
Definition at line 142 of file chan_sip.c.
#define DEC_CALL_LIMIT 0 |
Definition at line 445 of file chan_sip.c.
Referenced by handle_request_invite(), handle_response(), sip_hangup(), and update_call_counter().
#define DEFAULT_CALLERID "asterisk" |
#define DEFAULT_CONTEXT "default" |
#define DEFAULT_DEFAULT_EXPIRY 120 |
#define DEFAULT_EXPIRY 900 |
Expire slowly
Definition at line 436 of file chan_sip.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 133 of file chan_sip.c.
#define DEFAULT_FREQ_OK 60 * 1000 |
Definition at line 132 of file chan_sip.c.
#define DEFAULT_MAX_EXPIRY 3600 |
#define DEFAULT_MAX_FORWARDS "70" |
Definition at line 104 of file chan_sip.c.
Referenced by initreqprep(), reqprep(), and transmit_register().
#define DEFAULT_MAXMS 2000 |
Definition at line 131 of file chan_sip.c.
#define DEFAULT_MWITIME 10 |
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define DEFAULT_REALM "asterisk" |
#define DEFAULT_REGISTRATION_TIMEOUT 20 |
#define DEFAULT_RETRANS 1000 |
Definition at line 135 of file chan_sip.c.
#define DEFAULT_SIP_PORT 5060 |
From RFC 3261 (former 2543)
Definition at line 328 of file chan_sip.c.
Referenced by build_peer(), check_via(), create_addr(), parse_ok_contact(), parse_register_contact(), reload_config(), set_destination(), sip_show_registry(), and temp_peer().
#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) |
Definition at line 702 of file chan_sip.c.
Referenced by __sip_ack(), __sip_pretend_ack(), __sip_semi_ack(), handle_request(), and retrans_pkt().
#define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s\n" |
#define FORMAT "%-30.30s %-12.12s %8d %-20.20s\n" |
#define FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define FORMAT2 "%-15.15s %-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" |
Referenced by __sip_show_channels().
#define FREE free |
Definition at line 962 of file chan_sip.c.
#define INC_CALL_LIMIT 1 |
Definition at line 446 of file chan_sip.c.
Referenced by handle_request_invite(), sip_call(), sip_hangup(), and update_call_counter().
#define IPTOS_MINCOST 0x02 |
Definition at line 95 of file chan_sip.c.
#define MAX | ( | a, | |||
b | ) | ((a) > (b) ? (a) : (b)) |
Definition at line 124 of file chan_sip.c.
#define MAX_AUTHTRIES 3 |
Definition at line 138 of file chan_sip.c.
Referenced by handle_response(), handle_response_invite(), and handle_response_register().
#define MAX_RETRANS 6 |
Definition at line 137 of file chan_sip.c.
#define NO_RTP 0 |
Definition at line 150 of file chan_sip.c.
#define NOT_SUPPORTED 0 |
Definition at line 267 of file chan_sip.c.
#define REG_STATE_AUTHSENT 2 |
Definition at line 811 of file chan_sip.c.
Referenced by registry_rerequest(), regstate2str(), and transmit_register().
#define REG_STATE_FAILED 7 |
#define REG_STATE_NOAUTH 6 |
#define REG_STATE_REGISTERED 3 |
Definition at line 812 of file chan_sip.c.
Referenced by handle_response_register(), iax2_ack_registry(), and regstate2str().
#define REG_STATE_REGSENT 1 |
Definition at line 810 of file chan_sip.c.
Referenced by iax2_do_register(), regstate2str(), and transmit_register().
#define REG_STATE_REJECTED 4 |
#define REG_STATE_TIMEOUT 5 |
#define REG_STATE_UNREGISTERED 0 |
#define RTP 1 |
Definition at line 149 of file chan_sip.c.
#define SIP_ALREADYGONE (1 << 0) |
Whether or not we've already been destroyed by our peer
Definition at line 518 of file chan_sip.c.
Referenced by handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), retrans_pkt(), sip_hangup(), sip_indicate(), and sip_sipredirect().
#define SIP_CALL_LIMIT (1 << 29) |
Definition at line 566 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), and update_call_counter().
#define SIP_CALL_ONHOLD (1 << 28) |
#define SIP_CAN_BYE (1 << 15) |
Can we send BYE for this dialog?
Definition at line 533 of file chan_sip.c.
Referenced by check_pendings(), handle_response_invite(), and sip_hangup().
#define SIP_CAN_REINVITE (1 << 20) |
allow peers to be reinvited to send media directly p2p
Definition at line 548 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), reload_config(), sip_get_rtp_peer(), and sip_get_vrtp_peer().
#define SIP_DEBUG_CONFIG 1 << 0 |
#define SIP_DEBUG_CONSOLE 1 << 1 |
Definition at line 418 of file chan_sip.c.
Referenced by sip_do_debug(), sip_do_debug_ip(), sip_do_debug_peer(), and sip_no_debug().
#define SIP_DTMF (3 << 16) |
three settings, uses two bits
Definition at line 535 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), create_addr_from_peer(), handle_common_options(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit(), sip_show_channel(), and sip_show_settings().
#define SIP_DTMF_AUTO (3 << 16) |
AUTO switch between rfc2833 and in-band DTMF
Definition at line 539 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), and sip_alloc().
#define SIP_DTMF_INBAND (1 << 16) |
Inband audio, only for ULAW/ALAW
Definition at line 537 of file chan_sip.c.
Referenced by dtmfmode2str(), handle_common_options(), process_sdp(), sip_dtmfmode(), sip_new(), sip_rtp_read(), and sip_senddigit().
#define SIP_DTMF_INFO (2 << 16) |
SIP Info messages
Definition at line 538 of file chan_sip.c.
Referenced by dtmfmode2str(), handle_common_options(), sip_dtmfmode(), and sip_senddigit().
#define SIP_DTMF_RFC2833 (0 << 16) |
RTP DTMF
Definition at line 536 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), reload_config(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), and sip_senddigit().
#define SIP_FLAGS_TO_COPY |
Value:
(SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \ SIP_PROG_INBAND | SIP_OSPAUTH | SIP_USECLIENTCODE | SIP_NAT | \ SIP_USEREQPHONE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE)
Definition at line 572 of file chan_sip.c.
Referenced by build_peer(), build_user(), check_user_full(), create_addr_from_peer(), sip_alloc(), sip_poke_peer(), and temp_peer().
#define SIP_GOTREFER (1 << 7) |
Got a refer?
Definition at line 525 of file chan_sip.c.
Referenced by handle_request_refer(), and sip_set_rtp_peer().
#define SIP_INC_COUNT (1 << 31) |
#define SIP_INSECURE_INVITE (1 << 23) |
don't require authentication for incoming INVITEs
Definition at line 552 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), and handle_common_options().
#define SIP_INSECURE_PORT (1 << 22) |
don't require matching port for incoming requests
Definition at line 551 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and sip_addrcmp().
#define SIP_LEN_CONTACT 256 |
#define SIP_MAX_HEADERS 64 |
Max amount of SIP headers to read
Definition at line 442 of file chan_sip.c.
Referenced by add_blank_header(), add_header(), and parse_request().
#define SIP_MAX_LINES 64 |
Max amount of lines in SIP attachment (like SDP)
Definition at line 443 of file chan_sip.c.
Referenced by add_line(), and parse_request().
#define SIP_MAX_PACKET 4096 |
Also from RFC 3261 (2543), should sub headers tho
Definition at line 329 of file chan_sip.c.
#define SIP_NAT (3 << 18) |
four settings, uses two bits
Definition at line 541 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 sip_show_users().
#define SIP_NAT_ALWAYS (3 << 18) |
Definition at line 545 of file chan_sip.c.
Referenced by copy_via_headers(), handle_common_options(), and nat2str().
#define SIP_NAT_NEVER (0 << 18) |
No nat support
Definition at line 542 of file chan_sip.c.
Referenced by handle_common_options(), and nat2str().
#define SIP_NAT_RFC3581 (1 << 18) |
Definition at line 543 of file chan_sip.c.
Referenced by build_via(), handle_common_options(), nat2str(), and reload_config().
#define SIP_NAT_ROUTE (2 << 18) |
Definition at line 544 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().
#define SIP_NEEDDESTROY (1 << 1) |
if we need to be destroyed
Definition at line 519 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().
#define SIP_NEEDREINVITE (1 << 5) |
Do we need to send another reinvite?
Definition at line 523 of file chan_sip.c.
Referenced by check_pendings(), sip_hangup(), and sip_set_rtp_peer().
#define SIP_NOVIDEO (1 << 2) |
Didn't get video in invite, don't offer
Definition at line 520 of file chan_sip.c.
Referenced by add_sdp(), process_sdp(), and sip_indicate().
#define SIP_OPT_100REL (1 << 1) |
Definition at line 270 of file chan_sip.c.
#define SIP_OPT_EARLY_SESSION (1 << 3) |
Definition at line 272 of file chan_sip.c.
#define SIP_OPT_EVENTLIST (1 << 11) |
Definition at line 280 of file chan_sip.c.
#define SIP_OPT_GRUU (1 << 12) |
Definition at line 281 of file chan_sip.c.
#define SIP_OPT_JOIN (1 << 4) |
Definition at line 273 of file chan_sip.c.
#define SIP_OPT_PATH (1 << 5) |
Definition at line 274 of file chan_sip.c.
#define SIP_OPT_PRECONDITION (1 << 7) |
Definition at line 276 of file chan_sip.c.
#define SIP_OPT_PREF (1 << 6) |
Definition at line 275 of file chan_sip.c.
#define SIP_OPT_PRIVACY (1 << 8) |
Definition at line 277 of file chan_sip.c.
#define SIP_OPT_REPLACES (1 << 0) |
Definition at line 269 of file chan_sip.c.
#define SIP_OPT_SDP_ANAT (1 << 9) |
Definition at line 278 of file chan_sip.c.
#define SIP_OPT_SEC_AGREE (1 << 10) |
Definition at line 279 of file chan_sip.c.
#define SIP_OPT_TARGET_DIALOG (1 << 13) |
Definition at line 282 of file chan_sip.c.
#define SIP_OPT_TIMER (1 << 2) |
Definition at line 271 of file chan_sip.c.
#define SIP_OSPAUTH (3 << 26) |
four settings, uses two bits
Definition at line 559 of file chan_sip.c.
Referenced by check_auth(), check_user_full(), and handle_common_options().
#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) |
Is this an outgoing call?
Definition at line 531 of file chan_sip.c.
Referenced by handle_request_bye(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), reqprep(), respprep(), sip_call(), sip_hangup(), sip_indicate(), sip_poke_peer(), sip_send_mwi_to_peer(), sip_show_channel(), sip_write(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), and update_call_counter().
#define SIP_PAGE2_DYNAMIC (1 << 5) |
Is this a dynamic peer?
Definition at line 583 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), function_sippeer(), register_verify(), and temp_peer().
#define SIP_PAGE2_IGNOREREGEXPIRE (1 << 3) |
Definition at line 581 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
Definition at line 582 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), parse_register_contact(), and reg_source_db().
#define SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
Definition at line 580 of file chan_sip.c.
Referenced by expire_register(), realtime_peer(), and reload_config().
#define SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
Definition at line 578 of file chan_sip.c.
Referenced by complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), realtime_peer(), realtime_user(), reload_config(), sip_prune_realtime(), sip_show_settings(), and update_peer().
#define SIP_PAGE2_RTUPDATE (1 << 1) |
Definition at line 579 of file chan_sip.c.
Referenced by reload_config(), sip_show_settings(), and update_peer().
#define SIP_PENDINGBYE (1 << 6) |
Need to send bye after we ack?
Definition at line 524 of file chan_sip.c.
Referenced by check_pendings(), handle_response_invite(), sip_hangup(), and sip_set_rtp_peer().
#define SIP_PKT_DEBUG (1 << 0) |
#define SIP_PKT_WITH_TOTAG (1 << 1) |
This packet has a to-tag
Definition at line 587 of file chan_sip.c.
Referenced by find_call(), and handle_request().
#define SIP_PROG_INBAND (3 << 24) |
three settings, uses two bits
Definition at line 554 of file chan_sip.c.
Referenced by handle_common_options(), sip_indicate(), and sip_show_settings().
#define SIP_PROG_INBAND_NEVER (0 << 24) |
#define SIP_PROG_INBAND_NO (1 << 24) |
Definition at line 556 of file chan_sip.c.
Referenced by handle_common_options(), and sip_show_settings().
#define SIP_PROG_INBAND_YES (2 << 24) |
Definition at line 557 of file chan_sip.c.
Referenced by handle_common_options(), and sip_indicate().
#define SIP_PROGRESS_SENT (1 << 4) |
Have sent 183 message progress
Definition at line 522 of file chan_sip.c.
Referenced by sip_indicate(), and sip_write().
#define SIP_PROMISCREDIR (1 << 8) |
Promiscuous redirection
Definition at line 526 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), parse_moved_contact(), sip_show_channel(), and sip_show_settings().
#define SIP_REALTIME (1 << 11) |
Flag for realtime users
Definition at line 529 of file chan_sip.c.
Referenced by build_peer(), parse_register_contact(), realtime_peer(), realtime_user(), sip_destroy_peer(), sip_destroy_user(), and update_peer().
#define SIP_REINVITE (3 << 20) |
#define SIP_REINVITE_UPDATE (2 << 20) |
use UPDATE (RFC3311) when reinviting this peer
Definition at line 549 of file chan_sip.c.
Referenced by handle_common_options(), and transmit_reinvite_with_sdp().
#define SIP_RINGING (1 << 3) |
#define SIP_SELFDESTRUCT (1 << 14) |
This is an autocreated peer
Definition at line 532 of file chan_sip.c.
Referenced by expire_register(), sip_destroy_peer(), and temp_peer().
#define SIP_SENDRPID (1 << 30) |
Definition at line 568 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and initreqprep().
#define SIP_TRUSTRPID (1 << 9) |
Trust RPID headers?
Definition at line 527 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), and handle_common_options().
#define SIP_USECLIENTCODE (1 << 12) |
Trust X-ClientCode info message
Definition at line 530 of file chan_sip.c.
Referenced by handle_common_options(), handle_request_info(), and sip_show_settings().
#define SIP_USEREQPHONE (1 << 10) |
Add user=phone to numeric URI. Default off
Definition at line 528 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), initreqprep(), reload_config(), and sip_show_settings().
#define SIPDUMPER |
Definition at line 100 of file chan_sip.c.
#define SUPPORTED 1 |
Define SIP option tags, used in Require: and Supported: headers We need to be aware of these properties in the phones to use the replace: header. We should not do that without knowing that the other end supports it... This is nothing we can configure, we learn by the dialog Supported: header on the REGISTER (peer) or the INVITE (other devices) We are not using many of these today, but will in the future. This is documented in RFC 3261
Definition at line 266 of file chan_sip.c.
#define SUPPORTED_EXTENSIONS "replaces" |
#define VIDEO_CODEC_MASK 0x1fc0000 |
enum domain_mode |
SIP_DOMAIN_AUTO | This domain is auto-configured |
SIP_DOMAIN_CONFIG | This domain is from configuration |
Definition at line 487 of file chan_sip.c.
00487 { 00488 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00489 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00490 };
Definition at line 5903 of file chan_sip.c.
05903 { 05904 PARSE_REGISTER_FAILED, 05905 PARSE_REGISTER_UPDATE, 05906 PARSE_REGISTER_QUERY, 05907 };
enum sip_auth_type |
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 |
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;
enum subscriptiontype |
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 };
static char* __get_header | ( | struct sip_request * | req, | |
char * | name, | |||
int * | start | |||
) | [static] |
Definition at line 2949 of file chan_sip.c.
References find_alias(), sip_request::header, sip_request::headers, and pass.
02950 { 02951 int pass; 02952 02953 /* 02954 * Technically you can place arbitrary whitespace both before and after the ':' in 02955 * a header, although RFC3261 clearly says you shouldn't before, and place just 02956 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 02957 * a good idea to say you can do it, and if you can do it, why in the hell would. 02958 * you say you shouldn't. 02959 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 02960 * and we always allow spaces after that for compatibility. 02961 */ 02962 for (pass = 0; name && pass < 2;pass++) { 02963 int x, len = strlen(name); 02964 for (x=*start; x<req->headers; x++) { 02965 if (!strncasecmp(req->header[x], name, len)) { 02966 char *r = req->header[x] + len; /* skip name */ 02967 if (pedanticsipchecking) 02968 r = ast_skip_blanks(r); 02969 02970 if (*r == ':') { 02971 *start = x+1; 02972 return ast_skip_blanks(r+1); 02973 } 02974 } 02975 } 02976 if (pass == 0) /* Try aliases */ 02977 name = find_alias(name, NULL); 02978 } 02979 02980 /* Don't return NULL, so get_header is always a valid pointer */ 02981 return ""; 02982 }
static int __sip_ack | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
int | sipmethod | |||
) | [static] |
__sip_ack: Acknowledges receipt of a packet and stops retransmission ---
Definition at line 1371 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().
01372 { 01373 struct sip_pkt *cur, *prev = NULL; 01374 int res = -1; 01375 int resetinvite = 0; 01376 /* Just in case... */ 01377 char *msg; 01378 01379 msg = sip_methods[sipmethod].text; 01380 01381 ast_mutex_lock(&p->lock); 01382 cur = p->packets; 01383 while(cur) { 01384 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 01385 ((ast_test_flag(cur, FLAG_RESPONSE)) || 01386 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 01387 if (!resp && (seqno == p->pendinginvite)) { 01388 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 01389 p->pendinginvite = 0; 01390 resetinvite = 1; 01391 } 01392 /* this is our baby */ 01393 if (prev) 01394 prev->next = cur->next; 01395 else 01396 p->packets = cur->next; 01397 if (cur->retransid > -1) { 01398 if (sipdebug && option_debug > 3) 01399 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 01400 ast_sched_del(sched, cur->retransid); 01401 } 01402 free(cur); 01403 res = 0; 01404 break; 01405 } 01406 prev = cur; 01407 cur = cur->next; 01408 } 01409 ast_mutex_unlock(&p->lock); 01410 ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found"); 01411 return res; 01412 }
static int __sip_autodestruct | ( | void * | data | ) | [static] |
__sip_autodestruct: Kill a call (called by scheduler) ---
Definition at line 1315 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().
01316 { 01317 struct sip_pvt *p = data; 01318 01319 01320 /* If this is a subscription, tell the phone that we got a timeout */ 01321 if (p->subscribed) { 01322 p->subscribed = TIMEOUT; 01323 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, 1); /* Send first notification */ 01324 p->subscribed = NONE; 01325 append_history(p, "Subscribestatus", "timeout"); 01326 return 10000; /* Reschedule this destruction so that we know that it's gone */ 01327 } 01328 01329 /* This scheduled event is now considered done. */ 01330 p->autokillid = -1; 01331 01332 ast_log(LOG_DEBUG, "Auto destroying call '%s'\n", p->callid); 01333 append_history(p, "AutoDestroy", ""); 01334 if (p->owner) { 01335 ast_log(LOG_WARNING, "Autodestruct on call '%s' with owner in place\n", p->callid); 01336 ast_queue_hangup(p->owner); 01337 } else { 01338 sip_destroy(p); 01339 } 01340 return 0; 01341 }
static void __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
__sip_destroy: Execute destrucion of call structure, release memory---
Definition at line 2112 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().
02113 { 02114 struct sip_pvt *cur, *prev = NULL; 02115 struct sip_pkt *cp; 02116 struct sip_history *hist; 02117 02118 if (sip_debug_test_pvt(p)) 02119 ast_verbose("Destroying call '%s'\n", p->callid); 02120 02121 if (dumphistory) 02122 sip_dump_history(p); 02123 02124 if (p->options) 02125 free(p->options); 02126 02127 if (p->stateid > -1) 02128 ast_extension_state_del(p->stateid, NULL); 02129 if (p->initid > -1) 02130 ast_sched_del(sched, p->initid); 02131 if (p->autokillid > -1) 02132 ast_sched_del(sched, p->autokillid); 02133 02134 if (p->rtp) { 02135 ast_rtp_destroy(p->rtp); 02136 } 02137 if (p->vrtp) { 02138 ast_rtp_destroy(p->vrtp); 02139 } 02140 if (p->route) { 02141 free_old_route(p->route); 02142 p->route = NULL; 02143 } 02144 if (p->registry) { 02145 if (p->registry->call == p) 02146 p->registry->call = NULL; 02147 ASTOBJ_UNREF(p->registry,sip_registry_destroy); 02148 } 02149 02150 if (p->rpid) 02151 free(p->rpid); 02152 02153 if (p->rpid_from) 02154 free(p->rpid_from); 02155 02156 /* Unlink us from the owner if we have one */ 02157 if (p->owner) { 02158 if (lockowner) 02159 ast_mutex_lock(&p->owner->lock); 02160 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 02161 p->owner->tech_pvt = NULL; 02162 if (lockowner) 02163 ast_mutex_unlock(&p->owner->lock); 02164 } 02165 /* Clear history */ 02166 while(p->history) { 02167 hist = p->history; 02168 p->history = p->history->next; 02169 free(hist); 02170 } 02171 02172 cur = iflist; 02173 while(cur) { 02174 if (cur == p) { 02175 if (prev) 02176 prev->next = cur->next; 02177 else 02178 iflist = cur->next; 02179 break; 02180 } 02181 prev = cur; 02182 cur = cur->next; 02183 } 02184 if (!cur) { 02185 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 02186 return; 02187 } 02188 while((cp = p->packets)) { 02189 p->packets = p->packets->next; 02190 if (cp->retransid > -1) { 02191 ast_sched_del(sched, cp->retransid); 02192 } 02193 free(cp); 02194 } 02195 if (p->chanvars) { 02196 ast_variables_destroy(p->chanvars); 02197 p->chanvars = NULL; 02198 } 02199 ast_mutex_destroy(&p->lock); 02200 free(p); 02201 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
__sip_do_register: Register with SIP proxy ---
Definition at line 5366 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
05367 { 05368 int res; 05369 05370 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 05371 return res; 05372 }
static int __sip_pretend_ack | ( | struct sip_pvt * | p | ) | [static] |
Definition at line 1415 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().
01416 { 01417 struct sip_pkt *cur=NULL; 01418 01419 while(p->packets) { 01420 if (cur == p->packets) { 01421 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 01422 return -1; 01423 } 01424 cur = p->packets; 01425 if (cur->method) 01426 __sip_ack(p, p->packets->seqno, (ast_test_flag(p->packets, FLAG_RESPONSE)), cur->method); 01427 else { /* Unknown packet type */ 01428 char *c; 01429 char method[128]; 01430 ast_copy_string(method, p->packets->data, sizeof(method)); 01431 c = ast_skip_blanks(method); /* XXX what ? */ 01432 *c = '\0'; 01433 __sip_ack(p, p->packets->seqno, (ast_test_flag(p->packets, FLAG_RESPONSE)), find_sip_method(method)); 01434 } 01435 } 01436 return 0; 01437 }
static int __sip_reliable_xmit | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
char * | data, | |||
int | len, | |||
int | fatal, | |||
int | sipmethod | |||
) | [static] |
__sip_reliable_xmit: transmit packet with retransmits ---
Definition at line 1276 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().
01277 { 01278 struct sip_pkt *pkt; 01279 int siptimer_a = DEFAULT_RETRANS; 01280 01281 pkt = malloc(sizeof(struct sip_pkt) + len + 1); 01282 if (!pkt) 01283 return -1; 01284 memset(pkt, 0, sizeof(struct sip_pkt)); 01285 memcpy(pkt->data, data, len); 01286 pkt->method = sipmethod; 01287 pkt->packetlen = len; 01288 pkt->next = p->packets; 01289 pkt->owner = p; 01290 pkt->seqno = seqno; 01291 pkt->flags = resp; 01292 pkt->data[len] = '\0'; 01293 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 01294 if (fatal) 01295 ast_set_flag(pkt, FLAG_FATAL); 01296 if (pkt->timer_t1) 01297 siptimer_a = pkt->timer_t1 * 2; 01298 01299 /* Schedule retransmission */ 01300 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 01301 if (option_debug > 3 && sipdebug) 01302 ast_log(LOG_DEBUG, "*** SIP TIMER: Initalizing retransmit timer on packet: Id #%d\n", pkt->retransid); 01303 pkt->next = p->packets; 01304 p->packets = pkt; 01305 01306 __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 01307 if (sipmethod == SIP_INVITE) { 01308 /* Note this is a pending invite */ 01309 p->pendinginvite = seqno; 01310 } 01311 return 0; 01312 }
static int __sip_semi_ack | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
int | sipmethod | |||
) | [static] |
__sip_semi_ack: Acks receipt of packet, keep it around (used for provisional responses) ---
Definition at line 1440 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().
01441 { 01442 struct sip_pkt *cur; 01443 int res = -1; 01444 char *msg = sip_methods[sipmethod].text; 01445 01446 cur = p->packets; 01447 while(cur) { 01448 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 01449 ((ast_test_flag(cur, FLAG_RESPONSE)) || 01450 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 01451 /* this is our baby */ 01452 if (cur->retransid > -1) { 01453 if (option_debug > 3 && sipdebug) 01454 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, msg); 01455 ast_sched_del(sched, cur->retransid); 01456 } 01457 cur->retransid = -1; 01458 res = 0; 01459 break; 01460 } 01461 cur = cur->next; 01462 } 01463 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"); 01464 return res; 01465 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
Definition at line 8415 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().
08416 { 08417 #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s\n" 08418 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n" 08419 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s\n" 08420 struct sip_pvt *cur; 08421 char iabuf[INET_ADDRSTRLEN]; 08422 int numchans = 0; 08423 if (argc != 3) 08424 return RESULT_SHOWUSAGE; 08425 ast_mutex_lock(&iflock); 08426 cur = iflist; 08427 if (!subscriptions) 08428 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 08429 else 08430 ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type"); 08431 while (cur) { 08432 if (cur->subscribed == NONE && !subscriptions) { 08433 ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), 08434 ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 08435 cur->callid, 08436 cur->ocseq, cur->icseq, 08437 ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 08438 ast_test_flag(cur, SIP_CALL_ONHOLD) ? "Yes" : "No", 08439 ast_test_flag(cur, SIP_NEEDDESTROY) ? "(d)" : "", 08440 cur->lastmsg ); 08441 numchans++; 08442 } 08443 if (cur->subscribed != NONE && subscriptions) { 08444 ast_cli(fd, FORMAT3, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), 08445 ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, 08446 cur->callid, cur->exten, ast_extension_state2str(cur->laststate), 08447 subscription_type2str(cur->subscribed)); 08448 numchans++; 08449 } 08450 cur = cur->next; 08451 } 08452 ast_mutex_unlock(&iflock); 08453 if (!subscriptions) 08454 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 08455 else 08456 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 08457 return RESULT_SUCCESS; 08458 #undef FORMAT 08459 #undef FORMAT2 08460 #undef FORMAT3 08461 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
__sip_xmit: Transmit SIP message ---
Definition at line 1071 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().
01072 { 01073 int res; 01074 char iabuf[INET_ADDRSTRLEN]; 01075 01076 if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) 01077 res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->recv, sizeof(struct sockaddr_in)); 01078 else 01079 res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_in)); 01080 01081 if (res != len) { 01082 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)); 01083 } 01084 return res; 01085 }
static int __transmit_response | ( | struct sip_pvt * | p, | |
char * | msg, | |||
struct sip_request * | req, | |||
int | reliable | |||
) | [static] |
__transmit_response: Base transmit response function
Definition at line 4229 of file chan_sip.c.
References add_blank_header(), add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), get_header(), ast_channel::hangupcause, LOG_WARNING, sip_pvt::owner, respprep(), and send_response().
Referenced by transmit_response(), and transmit_response_reliable().
04230 { 04231 struct sip_request resp; 04232 int seqno = 0; 04233 04234 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 04235 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 04236 return -1; 04237 } 04238 respprep(&resp, p, msg, req); 04239 add_header_contentLength(&resp, 0); 04240 /* If we are cancelling an incoming invite for some reason, add information 04241 about the reason why we are doing this in clear text */ 04242 if (msg[0] != '1' && p->owner && p->owner->hangupcause) { 04243 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 04244 } 04245 add_blank_header(&resp); 04246 return send_response(p, &resp, reliable, seqno); 04247 }
static int _sip_show_peer | ( | int | type, | |
int | fd, | |||
struct mansession * | s, | |||
struct message * | m, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 8021 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, find_peer(), sip_peer::flags_page2, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, insecure2str(), sip_peer::language, sip_peer::lastmsg, sip_peer::lastmsgssent, sip_peer::mailbox, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, nat2str(), ast_variable::next, sip_auth::next, peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_auth::realm, RESULT_SHOWUSAGE, RESULT_SUCCESS, 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().
08022 { 08023 char status[30] = ""; 08024 char cbuf[256]; 08025 char iabuf[INET_ADDRSTRLEN]; 08026 struct sip_peer *peer; 08027 char codec_buf[512]; 08028 struct ast_codec_pref *pref; 08029 struct ast_variable *v; 08030 struct sip_auth *auth; 08031 int x = 0, codec = 0, load_realtime = 0; 08032 08033 if (argc < 4) 08034 return RESULT_SHOWUSAGE; 08035 08036 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 08037 peer = find_peer(argv[3], NULL, load_realtime); 08038 if (s) { /* Manager */ 08039 if (peer) 08040 ast_cli(s->fd, "Response: Success\r\n"); 08041 else { 08042 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); 08043 astman_send_error(s, m, cbuf); 08044 return 0; 08045 } 08046 } 08047 if (peer && type==0 ) { /* Normal listing */ 08048 ast_cli(fd,"\n\n"); 08049 ast_cli(fd, " * Name : %s\n", peer->name); 08050 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 08051 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 08052 auth = peer->auth; 08053 while(auth) { 08054 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 08055 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 08056 auth = auth->next; 08057 } 08058 ast_cli(fd, " Context : %s\n", peer->context); 08059 ast_cli(fd, " Subscr.Cont. : %s\n", ast_strlen_zero(peer->subscribecontext)?"<Not set>":peer->subscribecontext); 08060 ast_cli(fd, " Language : %s\n", peer->language); 08061 if (!ast_strlen_zero(peer->accountcode)) 08062 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 08063 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 08064 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 08065 if (!ast_strlen_zero(peer->fromuser)) 08066 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 08067 if (!ast_strlen_zero(peer->fromdomain)) 08068 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 08069 ast_cli(fd, " Callgroup : "); 08070 print_group(fd, peer->callgroup, 0); 08071 ast_cli(fd, " Pickupgroup : "); 08072 print_group(fd, peer->pickupgroup, 0); 08073 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 08074 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 08075 ast_cli(fd, " LastMsgsSent : %d\n", peer->lastmsgssent); 08076 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 08077 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)?"Yes":"No")); 08078 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 08079 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 08080 ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE))); 08081 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(peer, SIP_NAT))); 08082 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 08083 ast_cli(fd, " CanReinvite : %s\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Yes":"No")); 08084 ast_cli(fd, " PromiscRedir : %s\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Yes":"No")); 08085 ast_cli(fd, " User=Phone : %s\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Yes":"No")); 08086 ast_cli(fd, " Trust RPID : %s\n", (ast_test_flag(peer, SIP_TRUSTRPID) ? "Yes" : "No")); 08087 ast_cli(fd, " Send RPID : %s\n", (ast_test_flag(peer, SIP_SENDRPID) ? "Yes" : "No")); 08088 08089 /* - is enumerated */ 08090 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF))); 08091 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 08092 ast_cli(fd, " ToHost : %s\n", peer->tohost); 08093 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)); 08094 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 08095 ast_cli(fd, " Def. Username: %s\n", peer->username); 08096 ast_cli(fd, " SIP Options : "); 08097 if (peer->sipoptions) { 08098 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 08099 if (peer->sipoptions & sip_options[x].id) 08100 ast_cli(fd, "%s ", sip_options[x].text); 08101 } 08102 } else 08103 ast_cli(fd, "(none)"); 08104 08105 ast_cli(fd, "\n"); 08106 ast_cli(fd, " Codecs : "); 08107 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 08108 ast_cli(fd, "%s\n", codec_buf); 08109 ast_cli(fd, " Codec Order : ("); 08110 print_codec_to_cli(fd, &peer->prefs); 08111 08112 ast_cli(fd, ")\n"); 08113 08114 ast_cli(fd, " Status : "); 08115 peer_status(peer, status, sizeof(status)); 08116 ast_cli(fd, "%s\n",status); 08117 ast_cli(fd, " Useragent : %s\n", peer->useragent); 08118 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 08119 if (peer->chanvars) { 08120 ast_cli(fd, " Variables :\n"); 08121 for (v = peer->chanvars ; v ; v = v->next) 08122 ast_cli(fd, " %s = %s\n", v->name, v->value); 08123 } 08124 ast_cli(fd,"\n"); 08125 ASTOBJ_UNREF(peer,sip_destroy_peer); 08126 } else if (peer && type == 1) { /* manager listing */ 08127 ast_cli(fd, "Channeltype: SIP\r\n"); 08128 ast_cli(fd, "ObjectName: %s\r\n", peer->name); 08129 ast_cli(fd, "ChanObjectType: peer\r\n"); 08130 ast_cli(fd, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 08131 ast_cli(fd, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 08132 ast_cli(fd, "Context: %s\r\n", peer->context); 08133 ast_cli(fd, "Language: %s\r\n", peer->language); 08134 if (!ast_strlen_zero(peer->accountcode)) 08135 ast_cli(fd, "Accountcode: %s\r\n", peer->accountcode); 08136 ast_cli(fd, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 08137 ast_cli(fd, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 08138 if (!ast_strlen_zero(peer->fromuser)) 08139 ast_cli(fd, "SIP-FromUser: %s\r\n", peer->fromuser); 08140 if (!ast_strlen_zero(peer->fromdomain)) 08141 ast_cli(fd, "SIP-FromDomain: %s\r\n", peer->fromdomain); 08142 ast_cli(fd, "Callgroup: "); 08143 print_group(fd, peer->callgroup, 1); 08144 ast_cli(fd, "Pickupgroup: "); 08145 print_group(fd, peer->pickupgroup, 1); 08146 ast_cli(fd, "VoiceMailbox: %s\r\n", peer->mailbox); 08147 ast_cli(fd, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 08148 ast_cli(fd, "Call limit: %d\r\n", peer->call_limit); 08149 ast_cli(fd, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)?"Y":"N")); 08150 ast_cli(fd, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 08151 ast_cli(fd, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 08152 ast_cli(fd, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE))); 08153 ast_cli(fd, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(peer, SIP_NAT))); 08154 ast_cli(fd, "ACL: %s\r\n", (peer->ha?"Y":"N")); 08155 ast_cli(fd, "SIP-CanReinvite: %s\r\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Y":"N")); 08156 ast_cli(fd, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Y":"N")); 08157 ast_cli(fd, "SIP-UserPhone: %s\r\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Y":"N")); 08158 08159 /* - is enumerated */ 08160 ast_cli(fd, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF))); 08161 ast_cli(fd, "SIPLastMsg: %d\r\n", peer->lastmsg); 08162 ast_cli(fd, "ToHost: %s\r\n", peer->tohost); 08163 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)); 08164 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)); 08165 ast_cli(fd, "Default-Username: %s\r\n", peer->username); 08166 ast_cli(fd, "Codecs: "); 08167 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 08168 ast_cli(fd, "%s\r\n", codec_buf); 08169 ast_cli(fd, "CodecOrder: "); 08170 pref = &peer->prefs; 08171 for(x = 0; x < 32 ; x++) { 08172 codec = ast_codec_pref_index(pref,x); 08173 if (!codec) 08174 break; 08175 ast_cli(fd, "%s", ast_getformatname(codec)); 08176 if (x < 31 && ast_codec_pref_index(pref,x+1)) 08177 ast_cli(fd, ","); 08178 } 08179 08180 ast_cli(fd, "\r\n"); 08181 ast_cli(fd, "Status: "); 08182 peer_status(peer, status, sizeof(status)); 08183 ast_cli(fd, "%s\r\n", status); 08184 ast_cli(fd, "SIP-Useragent: %s\r\n", peer->useragent); 08185 ast_cli(fd, "Reg-Contact : %s\r\n", peer->fullcontact); 08186 if (peer->chanvars) { 08187 for (v = peer->chanvars ; v ; v = v->next) { 08188 ast_cli(fd, "ChanVariable:\n"); 08189 ast_cli(fd, " %s,%s\r\n", v->name, v->value); 08190 } 08191 } 08192 08193 ASTOBJ_UNREF(peer,sip_destroy_peer); 08194 08195 } else { 08196 ast_cli(fd,"Peer %s not found.\n", argv[3]); 08197 ast_cli(fd,"\n"); 08198 } 08199 08200 return RESULT_SUCCESS; 08201 }
static int _sip_show_peers | ( | int | fd, | |
int * | total, | |||
struct mansession * | s, | |||
struct message * | m, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
_sip_show_peers: Execute sip show peers command
Definition at line 7599 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, RESULT_SUCCESS, s, SIP_NAT, SIP_NAT_ROUTE, and SIP_PAGE2_DYNAMIC.
Referenced by manager_sip_show_peers(), and sip_show_peers().
07600 { 07601 regex_t regexbuf; 07602 int havepattern = 0; 07603 07604 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s\n" 07605 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s\n" 07606 07607 char name[256]; 07608 char iabuf[INET_ADDRSTRLEN]; 07609 int total_peers = 0; 07610 int peers_online = 0; 07611 int peers_offline = 0; 07612 char *id; 07613 char idtext[256] = ""; 07614 07615 if (s) { /* Manager - get ActionID */ 07616 id = astman_get_header(m,"ActionID"); 07617 if (!ast_strlen_zero(id)) 07618 snprintf(idtext,256,"ActionID: %s\r\n",id); 07619 } 07620 07621 switch (argc) { 07622 case 5: 07623 if (!strcasecmp(argv[3], "like")) { 07624 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 07625 return RESULT_SHOWUSAGE; 07626 havepattern = 1; 07627 } else 07628 return RESULT_SHOWUSAGE; 07629 case 3: 07630 break; 07631 default: 07632 return RESULT_SHOWUSAGE; 07633 } 07634 07635 if (!s) { /* Normal list */ 07636 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status"); 07637 } 07638 07639 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07640 char status[20] = ""; 07641 char srch[2000]; 07642 char pstatus; 07643 07644 ASTOBJ_RDLOCK(iterator); 07645 07646 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07647 ASTOBJ_UNLOCK(iterator); 07648 continue; 07649 } 07650 07651 if (!ast_strlen_zero(iterator->username) && !s) 07652 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 07653 else 07654 ast_copy_string(name, iterator->name, sizeof(name)); 07655 07656 pstatus = peer_status(iterator, status, sizeof(status)); 07657 if (pstatus) 07658 peers_online++; 07659 else { 07660 if (pstatus == 0) 07661 peers_offline++; 07662 else { /* Unmonitored */ 07663 /* Checking if port is 0 */ 07664 if ( ntohs(iterator->addr.sin_port) == 0 ) { 07665 peers_offline++; 07666 } else { 07667 peers_online++; 07668 } 07669 } 07670 } 07671 07672 snprintf(srch, sizeof(srch), FORMAT, name, 07673 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", 07674 ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 07675 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 07676 iterator->ha ? " A " : " ", /* permit/deny */ 07677 ntohs(iterator->addr.sin_port), status); 07678 07679 if (!s) {/* Normal CLI list */ 07680 ast_cli(fd, FORMAT, name, 07681 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", 07682 ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 07683 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 07684 iterator->ha ? " A " : " ", /* permit/deny */ 07685 07686 ntohs(iterator->addr.sin_port), status); 07687 } else { /* Manager format */ 07688 /* The names here need to be the same as other channels */ 07689 ast_cli(fd, 07690 "Event: PeerEntry\r\n%s" 07691 "Channeltype: SIP\r\n" 07692 "ObjectName: %s\r\n" 07693 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 07694 "IPaddress: %s\r\n" 07695 "IPport: %d\r\n" 07696 "Dynamic: %s\r\n" 07697 "Natsupport: %s\r\n" 07698 "ACL: %s\r\n" 07699 "Status: %s\r\n\r\n", 07700 idtext, 07701 iterator->name, 07702 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "-none-", 07703 ntohs(iterator->addr.sin_port), 07704 ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 07705 (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 07706 iterator->ha ? "yes" : "no", /* permit/deny */ 07707 status); 07708 } 07709 07710 ASTOBJ_UNLOCK(iterator); 07711 07712 total_peers++; 07713 } while(0) ); 07714 07715 if (!s) { 07716 ast_cli(fd,"%d sip peers [%d online , %d offline]\n",total_peers,peers_online,peers_offline); 07717 } 07718 07719 if (havepattern) 07720 regfree(®exbuf); 07721 07722 if (total) 07723 *total = total_peers; 07724 07725 07726 return RESULT_SUCCESS; 07727 #undef FORMAT 07728 #undef FORMAT2 07729 }
static int add_blank_header | ( | struct sip_request * | req | ) | [static] |
add_blank_header: Add blank header to SIP message
Definition at line 3818 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().
03819 { 03820 if (req->headers == SIP_MAX_HEADERS) { 03821 ast_log(LOG_WARNING, "Out of SIP header space\n"); 03822 return -1; 03823 } 03824 if (req->lines) { 03825 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 03826 return -1; 03827 } 03828 if (req->len >= sizeof(req->data) - 4) { 03829 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 03830 return -1; 03831 } 03832 req->header[req->headers] = req->data + req->len; 03833 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "\r\n"); 03834 req->len += strlen(req->header[req->headers]); 03835 req->headers++; 03836 return 0; 03837 }
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] |
Definition at line 4370 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().
04373 { 04374 int rtp_code; 04375 04376 if (debug) 04377 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 04378 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 04379 return; 04380 04381 ast_build_string(m_buf, m_size, " %d", rtp_code); 04382 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 04383 ast_rtp_lookup_mime_subtype(1, codec), 04384 sample_rate); 04385 if (codec == AST_FORMAT_G729A) 04386 /* Indicate that we don't support VAD (G.729 annex B) */ 04387 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 04388 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit | |||
) | [static] |
add_digit: add DTMF INFO tone to sip message ---
Definition at line 4339 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
04340 { 04341 char tmp[256]; 04342 04343 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=250\r\n", digit); 04344 add_header(req, "Content-Type", "application/dtmf-relay"); 04345 add_header_contentLength(req, strlen(tmp)); 04346 add_line(req, tmp); 04347 return 0; 04348 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
add_header: Add header to SIP message
Definition at line 3774 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.
03775 { 03776 int x = 0; 03777 03778 if (req->headers == SIP_MAX_HEADERS) { 03779 ast_log(LOG_WARNING, "Out of SIP header space\n"); 03780 return -1; 03781 } 03782 03783 if (req->lines) { 03784 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 03785 return -1; 03786 } 03787 03788 if (req->len >= sizeof(req->data) - 4) { 03789 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 03790 return -1; 03791 } 03792 03793 req->header[req->headers] = req->data + req->len; 03794 03795 if (compactheaders) { 03796 for (x = 0; x < (sizeof(aliases) / sizeof(aliases[0])); x++) 03797 if (!strcasecmp(aliases[x].fullname, var)) 03798 var = aliases[x].shortname; 03799 } 03800 03801 snprintf(req->header[req->headers], sizeof(req->data) - req->len - 4, "%s: %s\r\n", var, value); 03802 req->len += strlen(req->header[req->headers]); 03803 req->headers++; 03804 03805 return 0; 03806 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
add_header_contentLen: Add 'Content-Length' header to SIP message
Definition at line 3809 of file chan_sip.c.
References add_header().
Referenced by __transmit_response(), add_digit(), add_sdp(), add_text(), add_vidupdate(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_request(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), and transmit_state_notify().
03810 { 03811 char clen[10]; 03812 03813 snprintf(clen, sizeof(clen), "%d", len); 03814 return add_header(req, "Content-Length", clen); 03815 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
add_line: Add content (not header) to SIP message
Definition at line 3840 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.
03841 { 03842 if (req->lines == SIP_MAX_LINES) { 03843 ast_log(LOG_WARNING, "Out of SIP line space\n"); 03844 return -1; 03845 } 03846 if (!req->lines) { 03847 /* Add extra empty return */ 03848 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 03849 req->len += strlen(req->data + req->len); 03850 } 03851 if (req->len >= sizeof(req->data) - 4) { 03852 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 03853 return -1; 03854 } 03855 req->line[req->lines] = req->data + req->len; 03856 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 03857 req->len += strlen(req->line[req->lines]); 03858 req->lines++; 03859 return 0; 03860 }
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] |
Definition at line 4390 of file chan_sip.c.
References ast_build_string(), AST_RTP_DTMF, ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), ast_verbose(), and sip_pvt::rtp.
Referenced by add_sdp().
04393 { 04394 int rtp_code; 04395 04396 if (debug) 04397 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format)); 04398 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 04399 return; 04400 04401 ast_build_string(m_buf, m_size, " %d", rtp_code); 04402 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 04403 ast_rtp_lookup_mime_subtype(0, format), 04404 sample_rate); 04405 if (format == AST_RTP_DTMF) 04406 /* Indicate we support DTMF and FLASH... */ 04407 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 04408 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static] |
add_realm_authentication: Add realm authentication in list ---
Definition at line 12016 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().
12017 { 12018 char authcopy[256]; 12019 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 12020 char *stringp; 12021 struct sip_auth *auth; 12022 struct sip_auth *b = NULL, *a = authlist; 12023 12024 if (ast_strlen_zero(configuration)) 12025 return authlist; 12026 12027 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 12028 12029 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 12030 stringp = authcopy; 12031 12032 username = stringp; 12033 realm = strrchr(stringp, '@'); 12034 if (realm) { 12035 *realm = '\0'; 12036 realm++; 12037 } 12038 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 12039 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 12040 return authlist; 12041 } 12042 stringp = username; 12043 username = strsep(&stringp, ":"); 12044 if (username) { 12045 secret = strsep(&stringp, ":"); 12046 if (!secret) { 12047 stringp = username; 12048 md5secret = strsep(&stringp,"#"); 12049 } 12050 } 12051 auth = malloc(sizeof(struct sip_auth)); 12052 if (auth) { 12053 memset(auth, 0, sizeof(struct sip_auth)); 12054 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 12055 ast_copy_string(auth->username, username, sizeof(auth->username)); 12056 if (secret) 12057 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 12058 if (md5secret) 12059 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 12060 } else { 12061 ast_log(LOG_ERROR, "Allocation of auth structure failed, Out of memory\n"); 12062 return authlist; 12063 } 12064 12065 /* Add authentication to authl */ 12066 if (!authlist) { /* No existing list */ 12067 return auth; 12068 } 12069 while(a) { 12070 b = a; 12071 a = a->next; 12072 } 12073 b->next = auth; /* Add structure add end of list */ 12074 12075 if (option_verbose > 2) 12076 ast_verbose("Added authentication for realm %s\n", realm); 12077 12078 return authlist; 12079 12080 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
add_route: Add route header into request per learned route ---
Definition at line 3958 of file chan_sip.c.
References add_header(), sip_route::hop, n, and sip_route::next.
Referenced by reqprep().
03959 { 03960 char r[BUFSIZ*2], *p; 03961 int n, rem = sizeof(r); 03962 03963 if (!route) return; 03964 03965 p = r; 03966 while (route) { 03967 n = strlen(route->hop); 03968 if ((n+3)>rem) break; 03969 if (p != r) { 03970 *p++ = ','; 03971 --rem; 03972 } 03973 *p++ = '<'; 03974 ast_copy_string(p, route->hop, rem); p += n; 03975 *p++ = '>'; 03976 rem -= (n+2); 03977 route = route->next; 03978 } 03979 *p = '\0'; 03980 add_header(req, "Route", r); 03981 }
static int add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
add_sdp: Add Session Description Protocol message ---
Definition at line 4411 of file chan_sip.c.
References add_codec_to_sdp(), add_header(), add_header_contentLength(), add_line(), add_noncodec_to_sdp(), ast_build_string(), ast_codec_pref_index(), AST_FORMAT_MAX_AUDIO, AST_FORMAT_MAX_VIDEO, ast_inet_ntoa(), ast_log(), ast_rtp_get_us(), AST_RTP_MAX, ast_test_flag, ast_verbose(), capability, debug, sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_request::len, LOG_WARNING, sip_pvt::noncodeccapability, sip_pvt::ourip, sip_pvt::prefcodec, sip_pvt::prefs, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, s, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), SIP_NOVIDEO, t, VIDEO_CODEC_MASK, videosupport, sip_pvt::vredirip, and sip_pvt::vrtp.
04412 { 04413 int len = 0; 04414 int pref_codec; 04415 int alreadysent = 0; 04416 struct sockaddr_in sin; 04417 struct sockaddr_in vsin; 04418 char v[256]; 04419 char s[256]; 04420 char o[256]; 04421 char c[256]; 04422 char t[256]; 04423 char m_audio[256]; 04424 char m_video[256]; 04425 char a_audio[1024]; 04426 char a_video[1024]; 04427 char *m_audio_next = m_audio; 04428 char *m_video_next = m_video; 04429 size_t m_audio_left = sizeof(m_audio); 04430 size_t m_video_left = sizeof(m_video); 04431 char *a_audio_next = a_audio; 04432 char *a_video_next = a_video; 04433 size_t a_audio_left = sizeof(a_audio); 04434 size_t a_video_left = sizeof(a_video); 04435 char iabuf[INET_ADDRSTRLEN]; 04436 int x; 04437 int capability; 04438 struct sockaddr_in dest; 04439 struct sockaddr_in vdest = { 0, }; 04440 int debug; 04441 04442 debug = sip_debug_test_pvt(p); 04443 04444 len = 0; 04445 if (!p->rtp) { 04446 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 04447 return -1; 04448 } 04449 capability = p->jointcapability; 04450 04451 if (!p->sessionid) { 04452 p->sessionid = getpid(); 04453 p->sessionversion = p->sessionid; 04454 } else 04455 p->sessionversion++; 04456 ast_rtp_get_us(p->rtp, &sin); 04457 if (p->vrtp) 04458 ast_rtp_get_us(p->vrtp, &vsin); 04459 04460 if (p->redirip.sin_addr.s_addr) { 04461 dest.sin_port = p->redirip.sin_port; 04462 dest.sin_addr = p->redirip.sin_addr; 04463 if (p->redircodecs) 04464 capability = p->redircodecs; 04465 } else { 04466 dest.sin_addr = p->ourip; 04467 dest.sin_port = sin.sin_port; 04468 } 04469 04470 /* Determine video destination */ 04471 if (p->vrtp) { 04472 if (p->vredirip.sin_addr.s_addr) { 04473 vdest.sin_port = p->vredirip.sin_port; 04474 vdest.sin_addr = p->vredirip.sin_addr; 04475 } else { 04476 vdest.sin_addr = p->ourip; 04477 vdest.sin_port = vsin.sin_port; 04478 } 04479 } 04480 if (debug){ 04481 ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(sin.sin_port)); 04482 if (p->vrtp) 04483 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(vsin.sin_port)); 04484 } 04485 04486 /* We break with the "recommendation" and send our IP, in order that our 04487 peer doesn't have to ast_gethostbyname() us */ 04488 04489 snprintf(v, sizeof(v), "v=0\r\n"); 04490 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)); 04491 snprintf(s, sizeof(s), "s=session\r\n"); 04492 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr)); 04493 snprintf(t, sizeof(t), "t=0 0\r\n"); 04494 04495 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 04496 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 04497 04498 /* Prefer the codec we were requested to use, first, no matter what */ 04499 if (capability & p->prefcodec) { 04500 if (p->prefcodec <= AST_FORMAT_MAX_AUDIO) 04501 add_codec_to_sdp(p, p->prefcodec, 8000, 04502 &m_audio_next, &m_audio_left, 04503 &a_audio_next, &a_audio_left, 04504 debug); 04505 else 04506 add_codec_to_sdp(p, p->prefcodec, 90000, 04507 &m_video_next, &m_video_left, 04508 &a_video_next, &a_video_left, 04509 debug); 04510 alreadysent |= p->prefcodec; 04511 } 04512 04513 /* Start by sending our preferred codecs */ 04514 for (x = 0; x < 32; x++) { 04515 if (!(pref_codec = ast_codec_pref_index(&p->prefs, x))) 04516 break; 04517 04518 if (!(capability & pref_codec)) 04519 continue; 04520 04521 if (alreadysent & pref_codec) 04522 continue; 04523 04524 if (pref_codec <= AST_FORMAT_MAX_AUDIO) 04525 add_codec_to_sdp(p, pref_codec, 8000, 04526 &m_audio_next, &m_audio_left, 04527 &a_audio_next, &a_audio_left, 04528 debug); 04529 else 04530 add_codec_to_sdp(p, pref_codec, 90000, 04531 &m_video_next, &m_video_left, 04532 &a_video_next, &a_video_left, 04533 debug); 04534 alreadysent |= pref_codec; 04535 } 04536 04537 /* Now send any other common codecs, and non-codec formats: */ 04538 for (x = 1; x <= ((videosupport && p->vrtp) ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 04539 if (!(capability & x)) 04540 continue; 04541 04542 if (alreadysent & x) 04543 continue; 04544 04545 if (x <= AST_FORMAT_MAX_AUDIO) 04546 add_codec_to_sdp(p, x, 8000, 04547 &m_audio_next, &m_audio_left, 04548 &a_audio_next, &a_audio_left, 04549 debug); 04550 else 04551 add_codec_to_sdp(p, x, 90000, 04552 &m_video_next, &m_video_left, 04553 &a_video_next, &a_video_left, 04554 debug); 04555 } 04556 04557 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 04558 if (!(p->noncodeccapability & x)) 04559 continue; 04560 04561 add_noncodec_to_sdp(p, x, 8000, 04562 &m_audio_next, &m_audio_left, 04563 &a_audio_next, &a_audio_left, 04564 debug); 04565 } 04566 04567 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 04568 04569 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 04570 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 04571 04572 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 04573 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 04574 04575 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_audio) + strlen(a_audio); 04576 if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) /* only if video response is appropriate */ 04577 len += strlen(m_video) + strlen(a_video); 04578 04579 add_header(resp, "Content-Type", "application/sdp"); 04580 add_header_contentLength(resp, len); 04581 add_line(resp, v); 04582 add_line(resp, o); 04583 add_line(resp, s); 04584 add_line(resp, c); 04585 add_line(resp, t); 04586 add_line(resp, m_audio); 04587 add_line(resp, a_audio); 04588 if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) { /* only if video response is appropriate */ 04589 add_line(resp, m_video); 04590 add_line(resp, a_video); 04591 } 04592 04593 /* Update lastrtprx when we send our SDP */ 04594 time(&p->lastrtprx); 04595 time(&p->lastrtptx); 04596 04597 return 0; 04598 }
static int add_sip_domain | ( | const char * | domain, | |
const enum domain_mode | mode, | |||
const char * | context | |||
) | [static] |
add_sip_domain: Add SIP domain to list of domains we are responsible for
Definition at line 11949 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().
11950 { 11951 struct domain *d; 11952 11953 if (ast_strlen_zero(domain)) { 11954 ast_log(LOG_WARNING, "Zero length domain.\n"); 11955 return 1; 11956 } 11957 11958 d = calloc(1, sizeof(*d)); 11959 if (!d) { 11960 ast_log(LOG_ERROR, "Allocation of domain structure failed, Out of memory\n"); 11961 return 0; 11962 } 11963 11964 ast_copy_string(d->domain, domain, sizeof(d->domain)); 11965 11966 if (!ast_strlen_zero(context)) 11967 ast_copy_string(d->context, context, sizeof(d->context)); 11968 11969 d->mode = mode; 11970 11971 AST_LIST_LOCK(&domain_list); 11972 AST_LIST_INSERT_TAIL(&domain_list, d, list); 11973 AST_LIST_UNLOCK(&domain_list); 11974 11975 if (sipdebug) 11976 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 11977 11978 return 1; 11979 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
add_text: Add text body to SIP message ---
Definition at line 4328 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
04329 { 04330 /* XXX Convert \n's to \r\n's XXX */ 04331 add_header(req, "Content-Type", "text/plain"); 04332 add_header_contentLength(req, strlen(text)); 04333 add_line(req, text); 04334 return 0; 04335 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add_vidupdate: add XML encoded media control with update ---
Definition at line 4352 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
04353 { 04354 const char *xml_is_a_huge_waste_of_space = 04355 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 04356 " <media_control>\r\n" 04357 " <vc_primitive>\r\n" 04358 " <to_encoder>\r\n" 04359 " <picture_fast_update>\r\n" 04360 " </picture_fast_update>\r\n" 04361 " </to_encoder>\r\n" 04362 " </vc_primitive>\r\n" 04363 " </media_control>\r\n"; 04364 add_header(req, "Content-Type", "application/media_control+xml"); 04365 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 04366 add_line(req, xml_is_a_huge_waste_of_space); 04367 return 0; 04368 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
append_date: Append date to SIP message ---
Definition at line 4272 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().
04273 { 04274 char tmpdat[256]; 04275 struct tm tm; 04276 time_t t; 04277 04278 time(&t); 04279 gmtime_r(&t, &tm); 04280 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 04281 add_header(req, "Date", tmpdat); 04282 }
static int append_history | ( | struct sip_pvt * | p, | |
const char * | event, | |||
const char * | data | |||
) | [static] |
append_history: Append to SIP dialog history
Definition at line 1138 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().
01139 { 01140 struct sip_history *hist, *prev; 01141 char *c; 01142 01143 if (!recordhistory || !p) 01144 return 0; 01145 if(!(hist = malloc(sizeof(struct sip_history)))) { 01146 ast_log(LOG_WARNING, "Can't allocate memory for history"); 01147 return 0; 01148 } 01149 memset(hist, 0, sizeof(struct sip_history)); 01150 snprintf(hist->event, sizeof(hist->event), "%-15s %s", event, data); 01151 /* Trim up nicely */ 01152 c = hist->event; 01153 while(*c) { 01154 if ((*c == '\r') || (*c == '\n')) { 01155 *c = '\0'; 01156 break; 01157 } 01158 c++; 01159 } 01160 /* Enqueue into history */ 01161 prev = p->history; 01162 if (prev) { 01163 while(prev->next) 01164 prev = prev->next; 01165 prev->next = hist; 01166 } else { 01167 p->history = hist; 01168 } 01169 return 0; 01170 }
static AST_LIST_HEAD_STATIC | ( | domain_list | , | |
domain | ||||
) | [static] |
The SIP domain list
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 | ) | [static] |
ast_quiet_chan: Turn off generator data
Definition at line 10298 of file chan_sip.c.
References ast_channel::_state, ast_deactivate_generator(), AST_STATE_UP, and ast_channel::generatordata.
Referenced by attempt_transfer().
10299 { 10300 if (chan && chan->_state == AST_STATE_UP) { 10301 if (chan->generatordata) 10302 ast_deactivate_generator(chan); 10303 } 10304 }
static int ast_sip_ouraddrfor | ( | struct in_addr * | them, | |
struct in_addr * | us | |||
) | [static] |
ast_sip_ouraddrfor: NAT fix - decide which IP address to use for ASterisk server? ---
Definition at line 1103 of file chan_sip.c.
References ahp, ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), externexpire, externhost, externrefresh, hp, localaddr, LOG_DEBUG, and LOG_NOTICE.
Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
01104 { 01105 /* 01106 * Using the localaddr structure built up with localnet statements 01107 * apply it to their address to see if we need to substitute our 01108 * externip or can get away with our internal bindaddr 01109 */ 01110 struct sockaddr_in theirs; 01111 theirs.sin_addr = *them; 01112 if (localaddr && externip.sin_addr.s_addr && 01113 ast_apply_ha(localaddr, &theirs)) { 01114 char iabuf[INET_ADDRSTRLEN]; 01115 if (externexpire && (time(NULL) >= externexpire)) { 01116 struct ast_hostent ahp; 01117 struct hostent *hp; 01118 time(&externexpire); 01119 externexpire += externrefresh; 01120 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01121 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01122 } else 01123 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01124 } 01125 memcpy(us, &externip.sin_addr, sizeof(struct in_addr)); 01126 ast_inet_ntoa(iabuf, sizeof(iabuf), *(struct in_addr *)&them->s_addr); 01127 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", iabuf); 01128 } 01129 else if (bindaddr.sin_addr.s_addr) 01130 memcpy(us, &bindaddr.sin_addr, sizeof(struct in_addr)); 01131 else 01132 return ast_ouraddrfor(them, us); 01133 return 0; 01134 }
attempt_transfer: Attempt transfer of SIP call ---
Definition at line 10307 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.
10308 { 10309 int res = 0; 10310 struct ast_channel 10311 *chana = NULL, 10312 *chanb = NULL, 10313 *bridgea = NULL, 10314 *bridgeb = NULL, 10315 *peera = NULL, 10316 *peerb = NULL, 10317 *peerc = NULL, 10318 *peerd = NULL; 10319 10320 if (!p1->owner || !p2->owner) { 10321 ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n"); 10322 return -1; 10323 } 10324 chana = p1->owner; 10325 chanb = p2->owner; 10326 bridgea = ast_bridged_channel(chana); 10327 bridgeb = ast_bridged_channel(chanb); 10328 10329 if (bridgea) { 10330 peera = chana; 10331 peerb = chanb; 10332 peerc = bridgea; 10333 peerd = bridgeb; 10334 } else if (bridgeb) { 10335 peera = chanb; 10336 peerb = chana; 10337 peerc = bridgeb; 10338 peerd = bridgea; 10339 } 10340 10341 if (peera && peerb && peerc && (peerb != peerc)) { 10342 ast_quiet_chan(peera); 10343 ast_quiet_chan(peerb); 10344 ast_quiet_chan(peerc); 10345 ast_quiet_chan(peerd); 10346 10347 if (peera->cdr && peerb->cdr) { 10348 peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); 10349 } else if (peera->cdr) { 10350 peerb->cdr = peera->cdr; 10351 } 10352 peera->cdr = NULL; 10353 10354 if (peerb->cdr && peerc->cdr) { 10355 peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); 10356 } else if (peerc->cdr) { 10357 peerb->cdr = peerc->cdr; 10358 } 10359 peerc->cdr = NULL; 10360 10361 if (ast_channel_masquerade(peerb, peerc)) { 10362 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 10363 res = -1; 10364 } 10365 return res; 10366 } else { 10367 ast_log(LOG_NOTICE, "Transfer attempted with no appropriate bridged calls to transfer\n"); 10368 if (chana) 10369 ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV); 10370 if (chanb) 10371 ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV); 10372 return -1; 10373 } 10374 return 0; 10375 }
static int auto_congest | ( | void * | nothing | ) | [static] |
auto_congest: Scheduled congestion on a call ---
Definition at line 1999 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.
02000 { 02001 struct sip_pvt *p = nothing; 02002 ast_mutex_lock(&p->lock); 02003 p->initid = -1; 02004 if (p->owner) { 02005 if (!ast_mutex_trylock(&p->owner->lock)) { 02006 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 02007 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 02008 ast_mutex_unlock(&p->owner->lock); 02009 } 02010 } 02011 ast_mutex_unlock(&p->lock); 02012 return 0; 02013 }
static void build_callid | ( | char * | callid, | |
int | len, | |||
struct in_addr | ourip, | |||
char * | fromdomain | |||
) | [static] |
build_callid: Build SIP CALLID header ---
Definition at line 3054 of file chan_sip.c.
References ast_inet_ntoa(), ast_strlen_zero(), and thread_safe_rand().
Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
03055 { 03056 int res; 03057 int val; 03058 int x; 03059 char iabuf[INET_ADDRSTRLEN]; 03060 for (x=0; x<4; x++) { 03061 val = thread_safe_rand(); 03062 res = snprintf(callid, len, "%08x", val); 03063 len -= res; 03064 callid += res; 03065 } 03066 if (!ast_strlen_zero(fromdomain)) 03067 snprintf(callid, len, "@%s", fromdomain); 03068 else 03069 /* It's not important that we really use our right IP here... */ 03070 snprintf(callid, len, "@%s", ast_inet_ntoa(iabuf, sizeof(iabuf), ourip)); 03071 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
build_contact: Build contact header - the contact header we send out ---
Definition at line 4728 of file chan_sip.c.
References ast_inet_ntoa(), ast_strlen_zero(), sip_pvt::exten, sip_pvt::our_contact, sip_pvt::ourip, and ourport.
Referenced by check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().
04729 { 04730 char iabuf[INET_ADDRSTRLEN]; 04731 04732 /* Construct Contact: header */ 04733 if (ourport != 5060) /* Needs to be 5060, according to the RFC */ 04734 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); 04735 else 04736 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)); 04737 }
static struct sip_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
int | realtime | |||
) | [static] |
build_peer: Build peer from config file ---
Definition at line 12246 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.
12247 { 12248 struct sip_peer *peer = NULL; 12249 struct ast_ha *oldha = NULL; 12250 int obproxyfound=0; 12251 int found=0; 12252 int format=0; /* Ama flags */ 12253 time_t regseconds; 12254 char *varname = NULL, *varval = NULL; 12255 struct ast_variable *tmpvar = NULL; 12256 struct ast_flags peerflags = {(0)}; 12257 struct ast_flags mask = {(0)}; 12258 12259 12260 if (!realtime) 12261 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 12262 /* We also use a case-sensitive comparison (unlike find_peer) so 12263 that case changes made to the peer name will be properly handled 12264 during reload 12265 */ 12266 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 12267 12268 if (peer) { 12269 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12270 found++; 12271 } else { 12272 peer = malloc(sizeof(*peer)); 12273 if (peer) { 12274 memset(peer, 0, sizeof(*peer)); 12275 if (realtime) 12276 rpeerobjs++; 12277 else 12278 speerobjs++; 12279 ASTOBJ_INIT(peer); 12280 peer->expire = -1; 12281 peer->pokeexpire = -1; 12282 } else { 12283 ast_log(LOG_WARNING, "Can't allocate SIP peer memory\n"); 12284 } 12285 } 12286 /* Note that our peer HAS had its reference count incrased */ 12287 if (!peer) 12288 return NULL; 12289 12290 peer->lastmsgssent = -1; 12291 if (!found) { 12292 if (name) 12293 ast_copy_string(peer->name, name, sizeof(peer->name)); 12294 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 12295 peer->addr.sin_family = AF_INET; 12296 peer->defaddr.sin_family = AF_INET; 12297 } 12298 /* If we have channel variables, remove them (reload) */ 12299 if (peer->chanvars) { 12300 ast_variables_destroy(peer->chanvars); 12301 peer->chanvars = NULL; 12302 } 12303 strcpy(peer->context, default_context); 12304 strcpy(peer->subscribecontext, default_subscribecontext); 12305 strcpy(peer->vmexten, global_vmexten); 12306 strcpy(peer->language, default_language); 12307 strcpy(peer->musicclass, global_musicclass); 12308 ast_copy_flags(peer, &global_flags, SIP_USEREQPHONE); 12309 peer->secret[0] = '\0'; 12310 peer->md5secret[0] = '\0'; 12311 peer->cid_num[0] = '\0'; 12312 peer->cid_name[0] = '\0'; 12313 peer->fromdomain[0] = '\0'; 12314 peer->fromuser[0] = '\0'; 12315 peer->regexten[0] = '\0'; 12316 peer->mailbox[0] = '\0'; 12317 peer->callgroup = 0; 12318 peer->pickupgroup = 0; 12319 peer->rtpkeepalive = global_rtpkeepalive; 12320 peer->maxms = default_qualify; 12321 peer->prefs = prefs; 12322 oldha = peer->ha; 12323 peer->ha = NULL; 12324 peer->addr.sin_family = AF_INET; 12325 ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY); 12326 peer->capability = global_capability; 12327 peer->rtptimeout = global_rtptimeout; 12328 peer->rtpholdtimeout = global_rtpholdtimeout; 12329 while(v) { 12330 if (handle_common_options(&peerflags, &mask, v)) { 12331 v = v->next; 12332 continue; 12333 } 12334 12335 if (realtime && !strcasecmp(v->name, "regseconds")) { 12336 if (sscanf(v->value, "%ld", (time_t *)®seconds) != 1) 12337 regseconds = 0; 12338 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 12339 inet_aton(v->value, &(peer->addr.sin_addr)); 12340 } else if (realtime && !strcasecmp(v->name, "name")) 12341 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 12342 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 12343 ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact)); 12344 ast_set_flag((&peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT); 12345 } else if (!strcasecmp(v->name, "secret")) 12346 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 12347 else if (!strcasecmp(v->name, "md5secret")) 12348 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 12349 else if (!strcasecmp(v->name, "auth")) 12350 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 12351 else if (!strcasecmp(v->name, "callerid")) { 12352 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 12353 } else if (!strcasecmp(v->name, "context")) { 12354 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 12355 } else if (!strcasecmp(v->name, "subscribecontext")) { 12356 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 12357 } else if (!strcasecmp(v->name, "fromdomain")) 12358 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 12359 else if (!strcasecmp(v->name, "usereqphone")) 12360 ast_set2_flag(peer, ast_true(v->value), SIP_USEREQPHONE); 12361 else if (!strcasecmp(v->name, "fromuser")) 12362 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 12363 else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 12364 if (!strcasecmp(v->value, "dynamic")) { 12365 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 12366 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 12367 } else { 12368 /* They'll register with us */ 12369 ast_set_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC); 12370 if (!found) { 12371 /* Initialize stuff iff we're not found, otherwise 12372 we keep going with what we had */ 12373 memset(&peer->addr.sin_addr, 0, 4); 12374 if (peer->addr.sin_port) { 12375 /* If we've already got a port, make it the default rather than absolute */ 12376 peer->defaddr.sin_port = peer->addr.sin_port; 12377 peer->addr.sin_port = 0; 12378 } 12379 } 12380 } 12381 } else { 12382 /* Non-dynamic. Make sure we become that way if we're not */ 12383 if (peer->expire > -1) 12384 ast_sched_del(sched, peer->expire); 12385 peer->expire = -1; 12386 ast_clear_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC); 12387 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 12388 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 12389 ASTOBJ_UNREF(peer, sip_destroy_peer); 12390 return NULL; 12391 } 12392 } 12393 if (!strcasecmp(v->name, "outboundproxy")) 12394 obproxyfound=1; 12395 else { 12396 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 12397 if (!peer->addr.sin_port) 12398 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 12399 } 12400 } 12401 } else if (!strcasecmp(v->name, "defaultip")) { 12402 if (ast_get_ip(&peer->defaddr, v->value)) { 12403 ASTOBJ_UNREF(peer, sip_destroy_peer); 12404 return NULL; 12405 } 12406 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 12407 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 12408 } else if (!strcasecmp(v->name, "port")) { 12409 if (!realtime && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)) 12410 peer->defaddr.sin_port = htons(atoi(v->value)); 12411 else 12412 peer->addr.sin_port = htons(atoi(v->value)); 12413 } else if (!strcasecmp(v->name, "callingpres")) { 12414 peer->callingpres = ast_parse_caller_presentation(v->value); 12415 if (peer->callingpres == -1) 12416 peer->callingpres = atoi(v->value); 12417 } else if (!strcasecmp(v->name, "username")) { 12418 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 12419 } else if (!strcasecmp(v->name, "language")) { 12420 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 12421 } else if (!strcasecmp(v->name, "regexten")) { 12422 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 12423 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 12424 peer->call_limit = atoi(v->value); 12425 if (peer->call_limit < 0) 12426 peer->call_limit = 0; 12427 } else if (!strcasecmp(v->name, "amaflags")) { 12428 format = ast_cdr_amaflags2int(v->value); 12429 if (format < 0) { 12430 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 12431 } else { 12432 peer->amaflags = format; 12433 } 12434 } else if (!strcasecmp(v->name, "accountcode")) { 12435 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 12436 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 12437 ast_copy_string(peer->musicclass, v->value, sizeof(peer->musicclass)); 12438 } else if (!strcasecmp(v->name, "mailbox")) { 12439 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 12440 } else if (!strcasecmp(v->name, "vmexten")) { 12441 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 12442 } else if (!strcasecmp(v->name, "callgroup")) { 12443 peer->callgroup = ast_get_group(v->value); 12444 } else if (!strcasecmp(v->name, "pickupgroup")) { 12445 peer->pickupgroup = ast_get_group(v->value); 12446 } else if (!strcasecmp(v->name, "allow")) { 12447 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 12448 } else if (!strcasecmp(v->name, "disallow")) { 12449 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 12450 } else if (!strcasecmp(v->name, "rtptimeout")) { 12451 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 12452 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12453 peer->rtptimeout = global_rtptimeout; 12454 } 12455 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 12456 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 12457 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12458 peer->rtpholdtimeout = global_rtpholdtimeout; 12459 } 12460 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 12461 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 12462 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 12463 peer->rtpkeepalive = global_rtpkeepalive; 12464 } 12465 } else if (!strcasecmp(v->name, "setvar")) { 12466 /* Set peer channel variable */ 12467 varname = ast_strdupa(v->value); 12468 if (varname && (varval = strchr(varname,'='))) { 12469 *varval = '\0'; 12470 varval++; 12471 if ((tmpvar = ast_variable_new(varname, varval))) { 12472 tmpvar->next = peer->chanvars; 12473 peer->chanvars = tmpvar; 12474 } 12475 } 12476 } else if (!strcasecmp(v->name, "qualify")) { 12477 if (!strcasecmp(v->value, "no")) { 12478 peer->maxms = 0; 12479 } else if (!strcasecmp(v->value, "yes")) { 12480 peer->maxms = DEFAULT_MAXMS; 12481 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 12482 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); 12483 peer->maxms = 0; 12484 } 12485 } 12486 /* else if (strcasecmp(v->name,"type")) 12487 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 12488 */ 12489 v=v->next; 12490 } 12491 if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) && realtime) { 12492 time_t nowtime; 12493 12494 time(&nowtime); 12495 if ((nowtime - regseconds) > 0) { 12496 destroy_association(peer); 12497 memset(&peer->addr, 0, sizeof(peer->addr)); 12498 if (option_debug) 12499 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 12500 } 12501 } 12502 ast_copy_flags(peer, &peerflags, mask.flags); 12503 if (!found && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) && !ast_test_flag(peer, SIP_REALTIME)) 12504 reg_source_db(peer); 12505 ASTOBJ_UNMARK(peer); 12506 ast_free_ha(oldha); 12507 return peer; 12508 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
build_reply_digest: Build reply digest ---
Definition at line 9133 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_md5_hash(), ast_strlen_zero(), authl, sip_pvt::authname, sip_pvt::callid, sip_pvt::domain, find_realm_authentication(), LOG_DEBUG, sip_auth::md5secret, sip_registry::md5secret, sip_pvt::nonce, sip_pvt::noncecount, sip_pvt::opaque, sip_pvt::peermd5secret, sip_pvt::peersecret, sip_pvt::qop, sip_pvt::realm, sip_pvt::sa, sip_auth::secret, secret, sip_methods, sipdebug, text, thread_safe_rand(), sip_pvt::uri, sip_auth::username, sip_pvt::username, and username.
Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().
09134 { 09135 char a1[256]; 09136 char a2[256]; 09137 char a1_hash[256]; 09138 char a2_hash[256]; 09139 char resp[256]; 09140 char resp_hash[256]; 09141 char uri[256]; 09142 char cnonce[80]; 09143 char iabuf[INET_ADDRSTRLEN]; 09144 char *username; 09145 char *secret; 09146 char *md5secret; 09147 struct sip_auth *auth = (struct sip_auth *) NULL; /* Realm authentication */ 09148 09149 if (!ast_strlen_zero(p->domain)) 09150 ast_copy_string(uri, p->domain, sizeof(uri)); 09151 else if (!ast_strlen_zero(p->uri)) 09152 ast_copy_string(uri, p->uri, sizeof(uri)); 09153 else 09154 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); 09155 09156 snprintf(cnonce, sizeof(cnonce), "%08x", thread_safe_rand()); 09157 09158 /* Check if we have separate auth credentials */ 09159 if ((auth = find_realm_authentication(authl, p->realm))) { 09160 username = auth->username; 09161 secret = auth->secret; 09162 md5secret = auth->md5secret; 09163 if (sipdebug) 09164 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 09165 } else { 09166 /* No authentication, use peer or register= config */ 09167 username = p->authname; 09168 secret = p->peersecret; 09169 md5secret = p->peermd5secret; 09170 } 09171 if (ast_strlen_zero(username)) /* We have no authentication */ 09172 return -1; 09173 09174 09175 /* Calculate SIP digest response */ 09176 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 09177 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 09178 if (!ast_strlen_zero(md5secret)) 09179 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 09180 else 09181 ast_md5_hash(a1_hash,a1); 09182 ast_md5_hash(a2_hash,a2); 09183 09184 p->noncecount++; 09185 if (!ast_strlen_zero(p->qop)) 09186 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 09187 else 09188 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 09189 ast_md5_hash(resp_hash, resp); 09190 /* XXX We hard code our qop to "auth" for now. XXX */ 09191 if (!ast_strlen_zero(p->qop)) 09192 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); 09193 else 09194 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); 09195 09196 return 0; 09197 }
static void build_route | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | backwards | |||
) | [static] |
build_route: Build route list from Record-Route header ---
Definition at line 6086 of file chan_sip.c.
References __get_header(), ast_log(), ast_strlen_zero(), free_old_route(), get_header(), sip_route::hop, list_route(), LOG_DEBUG, malloc, sip_route::next, sip_pvt::route, sip_pvt::route_persistant, and sip_debug_test_pvt().
Referenced by handle_request_invite(), and handle_response_invite().
06087 { 06088 struct sip_route *thishop, *head, *tail; 06089 int start = 0; 06090 int len; 06091 char *rr, *contact, *c; 06092 06093 /* Once a persistant route is set, don't fool with it */ 06094 if (p->route && p->route_persistant) { 06095 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 06096 return; 06097 } 06098 06099 if (p->route) { 06100 free_old_route(p->route); 06101 p->route = NULL; 06102 } 06103 06104 p->route_persistant = backwards; 06105 06106 /* We build up head, then assign it to p->route when we're done */ 06107 head = NULL; tail = head; 06108 /* 1st we pass through all the hops in any Record-Route headers */ 06109 for (;;) { 06110 /* Each Record-Route header */ 06111 rr = __get_header(req, "Record-Route", &start); 06112 if (*rr == '\0') break; 06113 for (;;) { 06114 /* Each route entry */ 06115 /* Find < */ 06116 rr = strchr(rr, '<'); 06117 if (!rr) break; /* No more hops */ 06118 ++rr; 06119 len = strcspn(rr, ">") + 1; 06120 /* Make a struct route */ 06121 thishop = malloc(sizeof(*thishop) + len); 06122 if (thishop) { 06123 ast_copy_string(thishop->hop, rr, len); 06124 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 06125 /* Link in */ 06126 if (backwards) { 06127 /* Link in at head so they end up in reverse order */ 06128 thishop->next = head; 06129 head = thishop; 06130 /* If this was the first then it'll be the tail */ 06131 if (!tail) tail = thishop; 06132 } else { 06133 thishop->next = NULL; 06134 /* Link in at the end */ 06135 if (tail) 06136 tail->next = thishop; 06137 else 06138 head = thishop; 06139 tail = thishop; 06140 } 06141 } 06142 rr += len; 06143 } 06144 } 06145 06146 /* Only append the contact if we are dealing with a strict router */ 06147 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 06148 /* 2nd append the Contact: if there is one */ 06149 /* Can be multiple Contact headers, comma separated values - we just take the first */ 06150 contact = get_header(req, "Contact"); 06151 if (!ast_strlen_zero(contact)) { 06152 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 06153 /* Look for <: delimited address */ 06154 c = strchr(contact, '<'); 06155 if (c) { 06156 /* Take to > */ 06157 ++c; 06158 len = strcspn(c, ">") + 1; 06159 } else { 06160 /* No <> - just take the lot */ 06161 c = contact; 06162 len = strlen(contact) + 1; 06163 } 06164 thishop = malloc(sizeof(*thishop) + len); 06165 if (thishop) { 06166 ast_copy_string(thishop->hop, c, len); 06167 thishop->next = NULL; 06168 /* Goes at the end */ 06169 if (tail) 06170 tail->next = thishop; 06171 else 06172 head = thishop; 06173 } 06174 } 06175 } 06176 06177 /* Store as new route */ 06178 p->route = head; 06179 06180 /* For debugging dump what we ended up with */ 06181 if (sip_debug_test_pvt(p)) 06182 list_route(p->route); 06183 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
build_rpid: Build the Remote Party-ID & From using callingpres options ---
Definition at line 4740 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_strlen_zero(), sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, default_callerid, sip_pvt::fromdomain, sip_pvt::fromuser, LOG_WARNING, sip_pvt::ourip, sip_pvt::owner, sip_pvt::rpid, sip_pvt::rpid_from, strdup, and sip_pvt::tag.
Referenced by initreqprep().
04741 { 04742 int send_pres_tags = 1; 04743 const char *privacy=NULL; 04744 const char *screen=NULL; 04745 char buf[256]; 04746 const char *clid = default_callerid; 04747 const char *clin = NULL; 04748 char iabuf[INET_ADDRSTRLEN]; 04749 const char *fromdomain; 04750 04751 if (p->rpid || p->rpid_from) 04752 return; 04753 04754 if (p->owner && p->owner->cid.cid_num) 04755 clid = p->owner->cid.cid_num; 04756 if (p->owner && p->owner->cid.cid_name) 04757 clin = p->owner->cid.cid_name; 04758 if (ast_strlen_zero(clin)) 04759 clin = clid; 04760 04761 switch (p->callingpres) { 04762 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 04763 privacy = "off"; 04764 screen = "no"; 04765 break; 04766 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 04767 privacy = "off"; 04768 screen = "pass"; 04769 break; 04770 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 04771 privacy = "off"; 04772 screen = "fail"; 04773 break; 04774 case AST_PRES_ALLOWED_NETWORK_NUMBER: 04775 privacy = "off"; 04776 screen = "yes"; 04777 break; 04778 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 04779 privacy = "full"; 04780 screen = "no"; 04781 break; 04782 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 04783 privacy = "full"; 04784 screen = "pass"; 04785 break; 04786 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 04787 privacy = "full"; 04788 screen = "fail"; 04789 break; 04790 case AST_PRES_PROHIB_NETWORK_NUMBER: 04791 privacy = "full"; 04792 screen = "pass"; 04793 break; 04794 case AST_PRES_NUMBER_NOT_AVAILABLE: 04795 send_pres_tags = 0; 04796 break; 04797 default: 04798 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 04799 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 04800 privacy = "full"; 04801 else 04802 privacy = "off"; 04803 screen = "no"; 04804 break; 04805 } 04806 04807 fromdomain = ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain; 04808 04809 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 04810 if (send_pres_tags) 04811 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 04812 p->rpid = strdup(buf); 04813 04814 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>;tag=%s", clin, 04815 ast_strlen_zero(p->fromuser) ? clid : p->fromuser, 04816 fromdomain, p->tag); 04817 p->rpid_from = strdup(buf); 04818 }
static struct sip_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
int | realtime | |||
) | [static] |
build_user: Initiate a SIP user structure from sip.conf ---
Definition at line 12113 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.
12114 { 12115 struct sip_user *user; 12116 int format; 12117 struct ast_ha *oldha = NULL; 12118 char *varname = NULL, *varval = NULL; 12119 struct ast_variable *tmpvar = NULL; 12120 struct ast_flags userflags = {(0)}; 12121 struct ast_flags mask = {(0)}; 12122 12123 12124 user = (struct sip_user *)malloc(sizeof(struct sip_user)); 12125 if (!user) { 12126 return NULL; 12127 } 12128 memset(user, 0, sizeof(struct sip_user)); 12129 suserobjs++; 12130 ASTOBJ_INIT(user); 12131 ast_copy_string(user->name, name, sizeof(user->name)); 12132 oldha = user->ha; 12133 user->ha = NULL; 12134 ast_copy_flags(user, &global_flags, SIP_FLAGS_TO_COPY); 12135 user->capability = global_capability; 12136 user->prefs = prefs; 12137 /* set default context */ 12138 strcpy(user->context, default_context); 12139 strcpy(user->language, default_language); 12140 strcpy(user->musicclass, global_musicclass); 12141 while(v) { 12142 if (handle_common_options(&userflags, &mask, v)) { 12143 v = v->next; 12144 continue; 12145 } 12146 12147 if (!strcasecmp(v->name, "context")) { 12148 ast_copy_string(user->context, v->value, sizeof(user->context)); 12149 } else if (!strcasecmp(v->name, "subscribecontext")) { 12150 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 12151 } else if (!strcasecmp(v->name, "setvar")) { 12152 varname = ast_strdupa(v->value); 12153 if (varname && (varval = strchr(varname,'='))) { 12154 *varval = '\0'; 12155 varval++; 12156 if ((tmpvar = ast_variable_new(varname, varval))) { 12157 tmpvar->next = user->chanvars; 12158 user->chanvars = tmpvar; 12159 } 12160 } 12161 } else if (!strcasecmp(v->name, "permit") || 12162 !strcasecmp(v->name, "deny")) { 12163 user->ha = ast_append_ha(v->name, v->value, user->ha); 12164 } else if (!strcasecmp(v->name, "secret")) { 12165 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 12166 } else if (!strcasecmp(v->name, "md5secret")) { 12167 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 12168 } else if (!strcasecmp(v->name, "callerid")) { 12169 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 12170 } else if (!strcasecmp(v->name, "callgroup")) { 12171 user->callgroup = ast_get_group(v->value); 12172 } else if (!strcasecmp(v->name, "pickupgroup")) { 12173 user->pickupgroup = ast_get_group(v->value); 12174 } else if (!strcasecmp(v->name, "language")) { 12175 ast_copy_string(user->language, v->value, sizeof(user->language)); 12176 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 12177 ast_copy_string(user->musicclass, v->value, sizeof(user->musicclass)); 12178 } else if (!strcasecmp(v->name, "accountcode")) { 12179 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 12180 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 12181 user->call_limit = atoi(v->value); 12182 if (user->call_limit < 0) 12183 user->call_limit = 0; 12184 } else if (!strcasecmp(v->name, "amaflags")) { 12185 format = ast_cdr_amaflags2int(v->value); 12186 if (format < 0) { 12187 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 12188 } else { 12189 user->amaflags = format; 12190 } 12191 } else if (!strcasecmp(v->name, "allow")) { 12192 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 12193 } else if (!strcasecmp(v->name, "disallow")) { 12194 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 12195 } else if (!strcasecmp(v->name, "callingpres")) { 12196 user->callingpres = ast_parse_caller_presentation(v->value); 12197 if (user->callingpres == -1) 12198 user->callingpres = atoi(v->value); 12199 } 12200 /*else if (strcasecmp(v->name,"type")) 12201 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 12202 */ 12203 v = v->next; 12204 } 12205 ast_copy_flags(user, &userflags, mask.flags); 12206 ast_free_ha(oldha); 12207 return user; 12208 }
static void build_via | ( | struct sip_pvt * | p, | |
char * | buf, | |||
int | len | |||
) | [static] |
build_via: Build a Via header for a request ---
Definition at line 1090 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(), and transmit_register().
01091 { 01092 char iabuf[INET_ADDRSTRLEN]; 01093 01094 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01095 if (ast_test_flag(p, SIP_NAT) & SIP_NAT_RFC3581) 01096 snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); 01097 else /* Work around buggy UNIDEN UIP200 firmware */ 01098 snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); 01099 }
static int cb_extensionstate | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
cb_extensionstate: Callback for the devicestate notification (SUBSCRIBE) support subsystem ---
Definition at line 6429 of file chan_sip.c.
References append_history(), AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_verbose(), sip_pvt::autokillid, sip_pvt::laststate, NONE, option_debug, sip_cancel_destroy(), sip_scheddestroy(), sip_pvt::stateid, sip_pvt::subscribed, transmit_state_notify(), sip_pvt::username, VERBOSE_PREFIX_1, and VERBOSE_PREFIX_2.
Referenced by handle_request_subscribe().
06430 { 06431 struct sip_pvt *p = data; 06432 06433 switch(state) { 06434 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 06435 case AST_EXTENSION_REMOVED: /* Extension is gone */ 06436 if (p->autokillid > -1) 06437 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 06438 sip_scheddestroy(p, 15000); /* Delete subscription in 15 secs */ 06439 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); 06440 p->stateid = -1; 06441 p->subscribed = NONE; 06442 append_history(p, "Subscribestatus", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 06443 break; 06444 default: /* Tell user */ 06445 p->laststate = state; 06446 break; 06447 } 06448 transmit_state_notify(p, state, 1, 1); 06449 06450 if (option_debug > 1) 06451 ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username); 06452 return 0; 06453 }
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 | |||
) | [static] |
check_auth: Check user authorization from peer definition ---
Definition at line 6204 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().
06205 { 06206 int res = -1; 06207 char *response = "407 Proxy Authentication Required"; 06208 char *reqheader = "Proxy-Authorization"; 06209 char *respheader = "Proxy-Authenticate"; 06210 char *authtoken; 06211 #ifdef OSP_SUPPORT 06212 char *osptoken; 06213 #endif 06214 /* Always OK if no secret */ 06215 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret) 06216 #ifdef OSP_SUPPORT 06217 && !ast_test_flag(p, SIP_OSPAUTH) 06218 && global_allowguest != 2 06219 #endif 06220 ) 06221 return 0; 06222 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 06223 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 06224 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 06225 different circumstances! What a surprise. */ 06226 response = "401 Unauthorized"; 06227 reqheader = "Authorization"; 06228 respheader = "WWW-Authenticate"; 06229 } 06230 #ifdef OSP_SUPPORT 06231 else { 06232 ast_log (LOG_DEBUG, "Checking OSP Authentication!\n"); 06233 osptoken = get_header (req, "P-OSP-Auth-Token"); 06234 switch (ast_test_flag (p, SIP_OSPAUTH)) { 06235 case SIP_OSPAUTH_NO: 06236 break; 06237 case SIP_OSPAUTH_GATEWAY: 06238 if (ast_strlen_zero (osptoken)) { 06239 if (ast_strlen_zero (secret) && ast_strlen_zero (md5secret)) { 06240 return (0); 06241 } 06242 } 06243 else { 06244 return (check_osptoken (p, osptoken)); 06245 } 06246 break; 06247 case SIP_OSPAUTH_PROXY: 06248 if (ast_strlen_zero (osptoken)) { 06249 return (0); 06250 } 06251 else { 06252 return (check_osptoken (p, osptoken)); 06253 } 06254 break; 06255 case SIP_OSPAUTH_EXCLUSIVE: 06256 if (ast_strlen_zero (osptoken)) { 06257 return (-1); 06258 } 06259 else { 06260 return (check_osptoken (p, osptoken)); 06261 } 06262 break; 06263 default: 06264 return (-1); 06265 } 06266 } 06267 #endif 06268 authtoken = get_header(req, reqheader); 06269 if (ignore && !ast_strlen_zero(randdata) && ast_strlen_zero(authtoken)) { 06270 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 06271 information */ 06272 if (!ast_strlen_zero(randdata)) { 06273 if (!reliable) { 06274 /* Resend message if this was NOT a reliable delivery. Otherwise the 06275 retransmission should get it */ 06276 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06277 /* Schedule auto destroy in 15 seconds */ 06278 sip_scheddestroy(p, 15000); 06279 } 06280 res = 1; 06281 } 06282 } else if (ast_strlen_zero(randdata) || ast_strlen_zero(authtoken)) { 06283 snprintf(randdata, randlen, "%08x", thread_safe_rand()); 06284 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06285 /* Schedule auto destroy in 15 seconds */ 06286 sip_scheddestroy(p, 15000); 06287 res = 1; 06288 } else { 06289 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 06290 an example in the spec of just what it is you're doing a hash on. */ 06291 char a1[256]; 06292 char a2[256]; 06293 char a1_hash[256]; 06294 char a2_hash[256]; 06295 char resp[256]; 06296 char resp_hash[256]=""; 06297 char tmp[256]; 06298 char *c; 06299 char *z; 06300 char *ua_hash =""; 06301 char *resp_uri =""; 06302 char *nonce = ""; 06303 char *digestusername = ""; 06304 int wrongnonce = 0; 06305 char *usednonce = randdata; 06306 06307 /* Find their response among the mess that we'r sent for comparison */ 06308 ast_copy_string(tmp, authtoken, sizeof(tmp)); 06309 c = tmp; 06310 06311 while(c) { 06312 c = ast_skip_blanks(c); 06313 if (!*c) 06314 break; 06315 if (!strncasecmp(c, "response=", strlen("response="))) { 06316 c+= strlen("response="); 06317 if ((*c == '\"')) { 06318 ua_hash=++c; 06319 if ((c = strchr(c,'\"'))) 06320 *c = '\0'; 06321 06322 } else { 06323 ua_hash=c; 06324 if ((c = strchr(c,','))) 06325 *c = '\0'; 06326 } 06327 06328 } else if (!strncasecmp(c, "uri=", strlen("uri="))) { 06329 c+= strlen("uri="); 06330 if ((*c == '\"')) { 06331 resp_uri=++c; 06332 if ((c = strchr(c,'\"'))) 06333 *c = '\0'; 06334 } else { 06335 resp_uri=c; 06336 if ((c = strchr(c,','))) 06337 *c = '\0'; 06338 } 06339 06340 } else if (!strncasecmp(c, "username=", strlen("username="))) { 06341 c+= strlen("username="); 06342 if ((*c == '\"')) { 06343 digestusername=++c; 06344 if((c = strchr(c,'\"'))) 06345 *c = '\0'; 06346 } else { 06347 digestusername=c; 06348 if((c = strchr(c,','))) 06349 *c = '\0'; 06350 } 06351 } else if (!strncasecmp(c, "nonce=", strlen("nonce="))) { 06352 c+= strlen("nonce="); 06353 if ((*c == '\"')) { 06354 nonce=++c; 06355 if ((c = strchr(c,'\"'))) 06356 *c = '\0'; 06357 } else { 06358 nonce=c; 06359 if ((c = strchr(c,','))) 06360 *c = '\0'; 06361 } 06362 06363 } else 06364 if ((z = strchr(c,' ')) || (z = strchr(c,','))) c=z; 06365 if (c) 06366 c++; 06367 } 06368 /* Verify that digest username matches the username we auth as */ 06369 if (strcmp(username, digestusername)) { 06370 /* Oops, we're trying something here */ 06371 return -2; 06372 } 06373 06374 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 06375 if (strncasecmp(randdata, nonce, randlen)) { 06376 wrongnonce = 1; 06377 usednonce = nonce; 06378 } 06379 06380 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 06381 06382 if (!ast_strlen_zero(resp_uri)) 06383 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, resp_uri); 06384 else 06385 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, uri); 06386 06387 if (!ast_strlen_zero(md5secret)) 06388 snprintf(a1_hash, sizeof(a1_hash), "%s", md5secret); 06389 else 06390 ast_md5_hash(a1_hash, a1); 06391 06392 ast_md5_hash(a2_hash, a2); 06393 06394 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 06395 ast_md5_hash(resp_hash, resp); 06396 06397 if (wrongnonce) { 06398 06399 snprintf(randdata, randlen, "%08x", thread_safe_rand()); 06400 if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) { 06401 if (sipdebug) 06402 ast_log(LOG_NOTICE, "stale nonce received from '%s'\n", get_header(req, "To")); 06403 /* We got working auth token, based on stale nonce . */ 06404 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 1); 06405 } else { 06406 /* Everything was wrong, so give the device one more try with a new challenge */ 06407 if (sipdebug) 06408 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 06409 transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0); 06410 } 06411 06412 /* Schedule auto destroy in 15 seconds */ 06413 sip_scheddestroy(p, 15000); 06414 return 1; 06415 } 06416 /* resp_hash now has the expected response, compare the two */ 06417 if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) { 06418 /* Auth is OK */ 06419 res = 0; 06420 } 06421 } 06422 /* Failure */ 06423 return res; 06424 }
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
check_pendings: Check pending actions on SIP call ---
Definition at line 9571 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().
09572 { 09573 if (ast_test_flag(p, SIP_PENDINGBYE)) { 09574 /* if we can't BYE, then this is really a pending CANCEL */ 09575 if (!ast_test_flag(p, SIP_CAN_BYE)) 09576 transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0); 09577 /* Actually don't destroy us yet, wait for the 487 on our original 09578 INVITE, but do set an autodestruct just in case we never get it. */ 09579 else 09580 transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); 09581 ast_clear_flag(p, SIP_PENDINGBYE); 09582 sip_scheddestroy(p, 32000); 09583 } else if (ast_test_flag(p, SIP_NEEDREINVITE)) { 09584 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 09585 /* Didn't get to reinvite yet, so do it now */ 09586 transmit_reinvite_with_sdp(p); 09587 ast_clear_flag(p, SIP_NEEDREINVITE); 09588 } 09589 }
static int check_sip_domain | ( | const char * | domain, | |
char * | context, | |||
size_t | len | |||
) | [static] |
check_sip_domain: Check if domain part of uri is local to our server
Definition at line 11982 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().
11983 { 11984 struct domain *d; 11985 int result = 0; 11986 11987 AST_LIST_LOCK(&domain_list); 11988 AST_LIST_TRAVERSE(&domain_list, d, list) { 11989 if (strcasecmp(d->domain, domain)) 11990 continue; 11991 11992 if (len && !ast_strlen_zero(d->context)) 11993 ast_copy_string(context, d->context, len); 11994 11995 result = 1; 11996 break; 11997 } 11998 AST_LIST_UNLOCK(&domain_list); 11999 12000 return result; 12001 }
static int check_user | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | sipmethod, | |||
char * | uri, | |||
int | reliable, | |||
struct sockaddr_in * | sin, | |||
int | ignore | |||
) | [static] |
check_user: Find user ---
Definition at line 7355 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
07356 { 07357 return check_user_full(p, req, sipmethod, uri, reliable, sin, ignore, NULL, 0); 07358 }
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 | |||
) | [static] |
check_user_full: Check if matching user or peer is defined ---
Definition at line 7087 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().
07088 { 07089 struct sip_user *user = NULL; 07090 struct sip_peer *peer; 07091 char *of, from[256], *c; 07092 char *rpid,rpid_num[50]; 07093 char iabuf[INET_ADDRSTRLEN]; 07094 int res = 0; 07095 char *t; 07096 char calleridname[50]; 07097 int debug=sip_debug_test_addr(sin); 07098 struct ast_variable *tmpvar = NULL, *v = NULL; 07099 char *uri2 = ast_strdupa(uri); 07100 07101 /* Terminate URI */ 07102 t = uri2; 07103 while(*t && (*t > 32) && (*t != ';')) 07104 t++; 07105 *t = '\0'; 07106 of = get_header(req, "From"); 07107 if (pedanticsipchecking) 07108 ast_uri_decode(of); 07109 07110 ast_copy_string(from, of, sizeof(from)); 07111 07112 memset(calleridname,0,sizeof(calleridname)); 07113 get_calleridname(from, calleridname, sizeof(calleridname)); 07114 if (calleridname[0]) 07115 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 07116 07117 rpid = get_header(req, "Remote-Party-ID"); 07118 memset(rpid_num,0,sizeof(rpid_num)); 07119 if (!ast_strlen_zero(rpid)) 07120 p->callingpres = get_rpid_num(rpid,rpid_num, sizeof(rpid_num)); 07121 07122 of = get_in_brackets(from); 07123 if (ast_strlen_zero(p->exten)) { 07124 t = uri2; 07125 if (!strncmp(t, "sip:", 4)) 07126 t+= 4; 07127 ast_copy_string(p->exten, t, sizeof(p->exten)); 07128 t = strchr(p->exten, '@'); 07129 if (t) 07130 *t = '\0'; 07131 if (ast_strlen_zero(p->our_contact)) 07132 build_contact(p); 07133 } 07134 /* save the URI part of the From header */ 07135 ast_copy_string(p->from, of, sizeof(p->from)); 07136 if (strncmp(of, "sip:", 4)) { 07137 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07138 } else 07139 of += 4; 07140 /* Get just the username part */ 07141 if ((c = strchr(of, '@'))) { 07142 *c = '\0'; 07143 if ((c = strchr(of, ':'))) 07144 *c = '\0'; 07145 ast_copy_string(p->cid_num, of, sizeof(p->cid_num)); 07146 ast_shrink_phone_number(p->cid_num); 07147 } 07148 if (ast_strlen_zero(of)) 07149 return 0; 07150 07151 if (!mailbox) /* If it's a mailbox SUBSCRIBE, don't check users */ 07152 user = find_user(of, 1); 07153 07154 /* Find user based on user name in the from header */ 07155 if (user && ast_apply_ha(user->ha, sin)) { 07156 ast_copy_flags(p, user, SIP_FLAGS_TO_COPY); 07157 /* copy channel vars */ 07158 for (v = user->chanvars ; v ; v = v->next) { 07159 if ((tmpvar = ast_variable_new(v->name, v->value))) { 07160 tmpvar->next = p->chanvars; 07161 p->chanvars = tmpvar; 07162 } 07163 } 07164 p->prefs = user->prefs; 07165 /* replace callerid if rpid found, and not restricted */ 07166 if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) { 07167 if (*calleridname) 07168 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 07169 ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num)); 07170 ast_shrink_phone_number(p->cid_num); 07171 } 07172 07173 if (p->rtp) { 07174 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07175 ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07176 } 07177 if (p->vrtp) { 07178 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07179 ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07180 } 07181 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ignore))) { 07182 sip_cancel_destroy(p); 07183 ast_copy_flags(p, user, SIP_FLAGS_TO_COPY); 07184 /* Copy SIP extensions profile from INVITE */ 07185 if (p->sipoptions) 07186 user->sipoptions = p->sipoptions; 07187 07188 /* If we have a call limit, set flag */ 07189 if (user->call_limit) 07190 ast_set_flag(p, SIP_CALL_LIMIT); 07191 if (!ast_strlen_zero(user->context)) 07192 ast_copy_string(p->context, user->context, sizeof(p->context)); 07193 if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) { 07194 ast_copy_string(p->cid_num, user->cid_num, sizeof(p->cid_num)); 07195 ast_shrink_phone_number(p->cid_num); 07196 } 07197 if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) 07198 ast_copy_string(p->cid_name, user->cid_name, sizeof(p->cid_name)); 07199 ast_copy_string(p->peername, user->name, sizeof(p->peername)); 07200 ast_copy_string(p->username, user->name, sizeof(p->username)); 07201 ast_copy_string(p->peersecret, user->secret, sizeof(p->peersecret)); 07202 ast_copy_string(p->subscribecontext, user->subscribecontext, sizeof(p->subscribecontext)); 07203 ast_copy_string(p->peermd5secret, user->md5secret, sizeof(p->peermd5secret)); 07204 ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode)); 07205 ast_copy_string(p->language, user->language, sizeof(p->language)); 07206 ast_copy_string(p->musicclass, user->musicclass, sizeof(p->musicclass)); 07207 p->amaflags = user->amaflags; 07208 p->callgroup = user->callgroup; 07209 p->pickupgroup = user->pickupgroup; 07210 p->callingpres = user->callingpres; 07211 p->capability = user->capability; 07212 p->jointcapability = user->capability; 07213 if (p->peercapability) 07214 p->jointcapability &= p->peercapability; 07215 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO)) 07216 p->noncodeccapability |= AST_RTP_DTMF; 07217 else 07218 p->noncodeccapability &= ~AST_RTP_DTMF; 07219 } 07220 if (user && debug) 07221 ast_verbose("Found user '%s'\n", user->name); 07222 } else { 07223 if (user) { 07224 if (!mailbox && debug) 07225 ast_verbose("Found user '%s', but fails host access\n", user->name); 07226 ASTOBJ_UNREF(user,sip_destroy_user); 07227 } 07228 user = NULL; 07229 } 07230 07231 if (!user) { 07232 /* If we didn't find a user match, check for peers */ 07233 if (sipmethod == SIP_SUBSCRIBE) 07234 /* For subscribes, match on peer name only */ 07235 peer = find_peer(of, NULL, 1); 07236 else 07237 /* Look for peer based on the IP address we received data from */ 07238 /* If peer is registered from this IP address or have this as a default 07239 IP address, this call is from the peer 07240 */ 07241 peer = find_peer(NULL, &p->recv, 1); 07242 07243 if (peer) { 07244 if (debug) 07245 ast_verbose("Found peer '%s'\n", peer->name); 07246 /* Take the peer */ 07247 ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY); 07248 07249 /* Copy SIP extensions profile to peer */ 07250 if (p->sipoptions) 07251 peer->sipoptions = p->sipoptions; 07252 07253 /* replace callerid if rpid found, and not restricted */ 07254 if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) { 07255 if (*calleridname) 07256 ast_copy_string(p->cid_name, calleridname, sizeof(p->cid_name)); 07257 ast_copy_string(p->cid_num, rpid_num, sizeof(p->cid_num)); 07258 ast_shrink_phone_number(p->cid_num); 07259 } 07260 if (p->rtp) { 07261 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07262 ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07263 } 07264 if (p->vrtp) { 07265 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07266 ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 07267 } 07268 ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret)); 07269 p->peersecret[sizeof(p->peersecret)-1] = '\0'; 07270 ast_copy_string(p->subscribecontext, peer->subscribecontext, sizeof(p->subscribecontext)); 07271 ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret)); 07272 p->peermd5secret[sizeof(p->peermd5secret)-1] = '\0'; 07273 p->callingpres = peer->callingpres; 07274 if (peer->maxms && peer->lastms) 07275 p->timer_t1 = peer->lastms; 07276 if (ast_test_flag(peer, SIP_INSECURE_INVITE)) { 07277 /* Pretend there is no required authentication */ 07278 p->peersecret[0] = '\0'; 07279 p->peermd5secret[0] = '\0'; 07280 } 07281 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ignore))) { 07282 ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY); 07283 /* If we have a call limit, set flag */ 07284 if (peer->call_limit) 07285 ast_set_flag(p, SIP_CALL_LIMIT); 07286 ast_copy_string(p->peername, peer->name, sizeof(p->peername)); 07287 ast_copy_string(p->authname, peer->name, sizeof(p->authname)); 07288 /* copy channel vars */ 07289 for (v = peer->chanvars ; v ; v = v->next) { 07290 if ((tmpvar = ast_variable_new(v->name, v->value))) { 07291 tmpvar->next = p->chanvars; 07292 p->chanvars = tmpvar; 07293 } 07294 } 07295 if (mailbox) 07296 snprintf(mailbox, mailboxlen, ",%s,", peer->mailbox); 07297 if (!ast_strlen_zero(peer->username)) { 07298 ast_copy_string(p->username, peer->username, sizeof(p->username)); 07299 /* Use the default username for authentication on outbound calls */ 07300 ast_copy_string(p->authname, peer->username, sizeof(p->authname)); 07301 } 07302 if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) { 07303 ast_copy_string(p->cid_num, peer->cid_num, sizeof(p->cid_num)); 07304 ast_shrink_phone_number(p->cid_num); 07305 } 07306 if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 07307 ast_copy_string(p->cid_name, peer->cid_name, sizeof(p->cid_name)); 07308 ast_copy_string(p->fullcontact, peer->fullcontact, sizeof(p->fullcontact)); 07309 if (!ast_strlen_zero(peer->context)) 07310 ast_copy_string(p->context, peer->context, sizeof(p->context)); 07311 ast_copy_string(p->peersecret, peer->secret, sizeof(p->peersecret)); 07312 ast_copy_string(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret)); 07313 ast_copy_string(p->language, peer->language, sizeof(p->language)); 07314 ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode)); 07315 p->amaflags = peer->amaflags; 07316 p->callgroup = peer->callgroup; 07317 p->pickupgroup = peer->pickupgroup; 07318 p->capability = peer->capability; 07319 p->prefs = peer->prefs; 07320 p->jointcapability = peer->capability; 07321 if (p->peercapability) 07322 p->jointcapability &= p->peercapability; 07323 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO)) 07324 p->noncodeccapability |= AST_RTP_DTMF; 07325 else 07326 p->noncodeccapability &= ~AST_RTP_DTMF; 07327 } 07328 ASTOBJ_UNREF(peer,sip_destroy_peer); 07329 } else { 07330 if (debug) 07331 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)); 07332 07333 /* do we allow guests? */ 07334 if (!global_allowguest) { 07335 if (global_alwaysauthreject) 07336 res = -4; /* reject with fake authorization request */ 07337 else 07338 res = -1; /* we don't want any guests, authentication will fail */ 07339 #ifdef OSP_SUPPORT 07340 } else if (global_allowguest == 2) { 07341 ast_copy_flags(p, &global_flags, SIP_OSPAUTH); 07342 res = check_auth(p, req, p->randdata, sizeof(p->randdata), "", "", "", sipmethod, uri2, reliable, ignore); 07343 #endif 07344 } 07345 } 07346 07347 } 07348 07349 if (user) 07350 ASTOBJ_UNREF(user,sip_destroy_user); 07351 return res; 07352 }
static int check_via | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
check Via: header for hostname, port and rport request/answer
Definition at line 6963 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().
06964 { 06965 char via[256]; 06966 char iabuf[INET_ADDRSTRLEN]; 06967 char *c, *pt; 06968 struct hostent *hp; 06969 struct ast_hostent ahp; 06970 06971 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 06972 06973 /* Check for rport */ 06974 c = strstr(via, ";rport"); 06975 if (c && (c[6] != '=')) /* rport query, not answer */ 06976 ast_set_flag(p, SIP_NAT_ROUTE); 06977 06978 c = strchr(via, ';'); 06979 if (c) 06980 *c = '\0'; 06981 06982 c = strchr(via, ' '); 06983 if (c) { 06984 *c = '\0'; 06985 c = ast_skip_blanks(c+1); 06986 if (strcasecmp(via, "SIP/2.0/UDP")) { 06987 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 06988 return -1; 06989 } 06990 pt = strchr(c, ':'); 06991 if (pt) 06992 *pt++ = '\0'; /* remember port pointer */ 06993 hp = ast_gethostbyname(c, &ahp); 06994 if (!hp) { 06995 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 06996 return -1; 06997 } 06998 memset(&p->sa, 0, sizeof(p->sa)); 06999 p->sa.sin_family = AF_INET; 07000 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 07001 p->sa.sin_port = htons(pt ? atoi(pt) : DEFAULT_SIP_PORT); 07002 07003 if (sip_debug_test_pvt(p)) { 07004 c = (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? "NAT" : "non-NAT"; 07005 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), c); 07006 } 07007 } 07008 return 0; 07009 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
clear_realm_authentication: Clear realm authentication list (at reload) ---
Definition at line 12083 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by sip_destroy_peer(), sip_do_reload(), and unload_module().
12084 { 12085 struct sip_auth *a = authlist; 12086 struct sip_auth *b; 12087 12088 while (a) { 12089 b = a; 12090 a = a->next; 12091 free(b); 12092 } 12093 12094 return 1; 12095 }
static void clear_sip_domains | ( | void | ) | [static] |
clear_sip_domains: Clear our domain list (at reload)
Definition at line 12004 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().
12005 { 12006 struct domain *d; 12007 12008 AST_LIST_LOCK(&domain_list); 12009 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 12010 free(d); 12011 AST_LIST_UNLOCK(&domain_list); 12012 }
static char* complete_sip_debug_peer | ( | char * | line, | |
char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
complete_sip_debug_peer: Support routine for 'sip debug peer' CLI ---
Definition at line 8515 of file chan_sip.c.
References complete_sip_peer().
08516 { 08517 if (pos == 3) 08518 return complete_sip_peer(word, state, 0); 08519 08520 return NULL; 08521 }
static char* complete_sip_peer | ( | char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
complete_sip_peer: Do completion on peer name ---
Definition at line 8486 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().
08487 { 08488 char *result = NULL; 08489 int wordlen = strlen(word); 08490 int which = 0; 08491 08492 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 08493 /* locking of the object is not required because only the name and flags are being compared */ 08494 if (!strncasecmp(word, iterator->name, wordlen)) { 08495 if (flags2 && !ast_test_flag((&iterator->flags_page2), flags2)) 08496 continue; 08497 if (++which > state) { 08498 result = strdup(iterator->name); 08499 } 08500 } 08501 } while(0) ); 08502 return result; 08503 }
static char* complete_sip_prune_realtime_peer | ( | char * | line, | |
char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
complete_sip_prune_realtime_peer: Support routine for 'sip prune realtime peer' CLI ---
Definition at line 8586 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
08587 { 08588 if (pos == 4) 08589 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 08590 return NULL; 08591 }
static char* complete_sip_prune_realtime_user | ( | char * | line, | |
char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
complete_sip_prune_realtime_user: Support routine for 'sip prune realtime user' CLI ---
Definition at line 8594 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
08595 { 08596 if (pos == 4) 08597 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 08598 08599 return NULL; 08600 }
static char* complete_sip_show_peer | ( | char * | line, | |
char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
complete_sip_show_peer: Support routine for 'sip show peer' CLI ---
Definition at line 8506 of file chan_sip.c.
References complete_sip_peer().
08507 { 08508 if (pos == 3) 08509 return complete_sip_peer(word, state, 0); 08510 08511 return NULL; 08512 }
static char* complete_sip_show_user | ( | char * | line, | |
char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
complete_sip_show_user: Support routine for 'sip show user' CLI ---
Definition at line 8544 of file chan_sip.c.
References complete_sip_user().
08545 { 08546 if (pos == 3) 08547 return complete_sip_user(word, state, 0); 08548 08549 return NULL; 08550 }
static char* complete_sip_user | ( | char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
complete_sip_user: Do completion on user name ---
Definition at line 8524 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().
08525 { 08526 char *result = NULL; 08527 int wordlen = strlen(word); 08528 int which = 0; 08529 08530 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 08531 /* locking of the object is not required because only the name and flags are being compared */ 08532 if (!strncasecmp(word, iterator->name, wordlen)) { 08533 if (flags2 && !ast_test_flag(&(iterator->flags_page2), flags2)) 08534 continue; 08535 if (++which > state) { 08536 result = strdup(iterator->name); 08537 } 08538 } 08539 } while(0) ); 08540 return result; 08541 }
static char* complete_sipch | ( | char * | line, | |
char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
complete_sipch: Support routine for 'sip show channel' CLI ---
Definition at line 8464 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::callid, iflist, sip_pvt::next, and strdup.
08465 { 08466 int which=0; 08467 struct sip_pvt *cur; 08468 char *c = NULL; 08469 08470 ast_mutex_lock(&iflock); 08471 cur = iflist; 08472 while(cur) { 08473 if (!strncasecmp(word, cur->callid, strlen(word))) { 08474 if (++which > state) { 08475 c = strdup(cur->callid); 08476 break; 08477 } 08478 } 08479 cur = cur->next; 08480 } 08481 ast_mutex_unlock(&iflock); 08482 return c; 08483 }
static char* complete_sipnotify | ( | char * | line, | |
char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
complete_sipnotify: Support routine for 'sip notify' CLI ---
Definition at line 8553 of file chan_sip.c.
References ast_category_browse(), complete_sip_peer(), notify_types, and strdup.
08554 { 08555 char *c = NULL; 08556 08557 if (pos == 2) { 08558 int which = 0; 08559 char *cat; 08560 08561 /* do completion for notify type */ 08562 08563 if (!notify_types) 08564 return NULL; 08565 08566 cat = ast_category_browse(notify_types, NULL); 08567 while(cat) { 08568 if (!strncasecmp(word, cat, strlen(word))) { 08569 if (++which > state) { 08570 c = strdup(cat); 08571 break; 08572 } 08573 } 08574 cat = ast_category_browse(notify_types, cat); 08575 } 08576 return c; 08577 } 08578 08579 if (pos > 2) 08580 return complete_sip_peer(word, state, 0); 08581 08582 return NULL; 08583 }
static int copy_all_header | ( | struct sip_request * | req, | |
struct sip_request * | orig, | |||
char * | field | |||
) | [static] |
copy_all_header: Copy all headers from one request to another ---
Definition at line 3876 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
03877 { 03878 char *tmp; 03879 int start = 0; 03880 int copied = 0; 03881 for (;;) { 03882 tmp = __get_header(orig, field, &start); 03883 if (!ast_strlen_zero(tmp)) { 03884 /* Add what we're responding to */ 03885 add_header(req, field, tmp); 03886 copied++; 03887 } else 03888 break; 03889 } 03890 return copied ? 0 : -1; 03891 }
static int copy_header | ( | struct sip_request * | req, | |
struct sip_request * | orig, | |||
char * | field | |||
) | [static] |
copy_header: Copy one header field from one request to another
Definition at line 3863 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
03864 { 03865 char *tmp; 03866 tmp = get_header(orig, field); 03867 if (!ast_strlen_zero(tmp)) { 03868 /* Add what we're responding to */ 03869 return add_header(req, field, tmp); 03870 } 03871 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 03872 return -1; 03873 }
static void copy_request | ( | struct sip_request * | dst, | |
struct sip_request * | src | |||
) | [static] |
copy_request: copy SIP request (mostly used to save request for responses) ---
Definition at line 4601 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().
04602 { 04603 long offset; 04604 int x; 04605 offset = ((void *)dst) - ((void *)src); 04606 /* First copy stuff */ 04607 memcpy(dst, src, sizeof(*dst)); 04608 /* Now fix pointer arithmetic */ 04609 for (x=0; x < src->headers; x++) 04610 dst->header[x] += offset; 04611 for (x=0; x < src->lines; x++) 04612 dst->line[x] += offset; 04613 }
static int copy_via_headers | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
struct sip_request * | orig, | |||
char * | field | |||
) | [static] |
copy_via_headers: Copy SIP VIA Headers from the request to the response ---
Definition at line 3899 of file chan_sip.c.
References __get_header(), add_header(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_test_flag, LOG_NOTICE, sip_pvt::recv, SIP_NAT, and SIP_NAT_ALWAYS.
Referenced by respprep().
03900 { 03901 char tmp[256], *oh, *end; 03902 int start = 0; 03903 int copied = 0; 03904 char iabuf[INET_ADDRSTRLEN]; 03905 03906 for (;;) { 03907 oh = __get_header(orig, field, &start); 03908 if (!ast_strlen_zero(oh)) { 03909 if (!copied) { /* Only check for empty rport in topmost via header */ 03910 char *rport; 03911 char new[256]; 03912 03913 /* Find ;rport; (empty request) */ 03914 rport = strstr(oh, ";rport"); 03915 if (rport && *(rport+6) == '=') 03916 rport = NULL; /* We already have a parameter to rport */ 03917 03918 if (rport && (ast_test_flag(p, SIP_NAT) == SIP_NAT_ALWAYS)) { 03919 /* We need to add received port - rport */ 03920 ast_copy_string(tmp, oh, sizeof(tmp)); 03921 03922 rport = strstr(tmp, ";rport"); 03923 03924 if (rport) { 03925 end = strchr(rport + 1, ';'); 03926 if (end) 03927 memmove(rport, end, strlen(end) + 1); 03928 else 03929 *rport = '\0'; 03930 } 03931 03932 /* Add rport to first VIA header if requested */ 03933 /* Whoo hoo! Now we can indicate port address translation too! Just 03934 another RFC (RFC3581). I'll leave the original comments in for 03935 posterity. */ 03936 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)); 03937 } else { 03938 /* We should *always* add a received to the topmost via */ 03939 snprintf(new, sizeof(new), "%s;received=%s", oh, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 03940 } 03941 add_header(req, field, new); 03942 } else { 03943 /* Add the following via headers untouched */ 03944 add_header(req, field, oh); 03945 } 03946 copied++; 03947 } else 03948 break; 03949 } 03950 if (!copied) { 03951 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 03952 return -1; 03953 } 03954 return 0; 03955 }
static int create_addr | ( | struct sip_pvt * | dialog, | |
char * | opeer | |||
) | [static] |
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 1935 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.
01936 { 01937 struct hostent *hp; 01938 struct ast_hostent ahp; 01939 struct sip_peer *p; 01940 int found=0; 01941 char *port; 01942 int portno; 01943 char host[MAXHOSTNAMELEN], *hostn; 01944 char peer[256]; 01945 01946 ast_copy_string(peer, opeer, sizeof(peer)); 01947 port = strchr(peer, ':'); 01948 if (port) { 01949 *port = '\0'; 01950 port++; 01951 } 01952 dialog->sa.sin_family = AF_INET; 01953 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 01954 p = find_peer(peer, NULL, 1); 01955 01956 if (p) { 01957 found++; 01958 if (create_addr_from_peer(dialog, p)) 01959 ASTOBJ_UNREF(p, sip_destroy_peer); 01960 } 01961 if (!p) { 01962 if (found) 01963 return -1; 01964 01965 hostn = peer; 01966 if (port) 01967 portno = atoi(port); 01968 else 01969 portno = DEFAULT_SIP_PORT; 01970 if (srvlookup) { 01971 char service[MAXHOSTNAMELEN]; 01972 int tportno; 01973 int ret; 01974 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 01975 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 01976 if (ret > 0) { 01977 hostn = host; 01978 portno = tportno; 01979 } 01980 } 01981 hp = ast_gethostbyname(hostn, &ahp); 01982 if (hp) { 01983 ast_copy_string(dialog->tohost, peer, sizeof(dialog->tohost)); 01984 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 01985 dialog->sa.sin_port = htons(portno); 01986 memcpy(&dialog->recv, &dialog->sa, sizeof(dialog->recv)); 01987 return 0; 01988 } else { 01989 ast_log(LOG_WARNING, "No such host: %s\n", peer); 01990 return -1; 01991 } 01992 } else { 01993 ASTOBJ_UNREF(p, sip_destroy_peer); 01994 return 0; 01995 } 01996 }
create_addr_from_peer: create address structure from peer reference ---
Definition at line 1859 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().
01860 { 01861 char *callhost; 01862 01863 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 01864 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 01865 if (peer->addr.sin_addr.s_addr) { 01866 r->sa.sin_family = peer->addr.sin_family; 01867 r->sa.sin_addr = peer->addr.sin_addr; 01868 r->sa.sin_port = peer->addr.sin_port; 01869 } else { 01870 r->sa.sin_family = peer->defaddr.sin_family; 01871 r->sa.sin_addr = peer->defaddr.sin_addr; 01872 r->sa.sin_port = peer->defaddr.sin_port; 01873 } 01874 memcpy(&r->recv, &r->sa, sizeof(r->recv)); 01875 } else { 01876 return -1; 01877 } 01878 01879 ast_copy_flags(r, peer, SIP_FLAGS_TO_COPY); 01880 r->capability = peer->capability; 01881 r->prefs = peer->prefs; 01882 if (r->rtp) { 01883 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE)); 01884 ast_rtp_setnat(r->rtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE)); 01885 } 01886 if (r->vrtp) { 01887 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE)); 01888 ast_rtp_setnat(r->vrtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE)); 01889 } 01890 ast_copy_string(r->peername, peer->username, sizeof(r->peername)); 01891 ast_copy_string(r->authname, peer->username, sizeof(r->authname)); 01892 ast_copy_string(r->username, peer->username, sizeof(r->username)); 01893 ast_copy_string(r->peersecret, peer->secret, sizeof(r->peersecret)); 01894 ast_copy_string(r->peermd5secret, peer->md5secret, sizeof(r->peermd5secret)); 01895 ast_copy_string(r->tohost, peer->tohost, sizeof(r->tohost)); 01896 ast_copy_string(r->fullcontact, peer->fullcontact, sizeof(r->fullcontact)); 01897 if (!r->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 01898 if ((callhost = strchr(r->callid, '@'))) { 01899 strncpy(callhost + 1, peer->fromdomain, sizeof(r->callid) - (callhost - r->callid) - 2); 01900 } 01901 } 01902 if (ast_strlen_zero(r->tohost)) { 01903 if (peer->addr.sin_addr.s_addr) 01904 ast_inet_ntoa(r->tohost, sizeof(r->tohost), peer->addr.sin_addr); 01905 else 01906 ast_inet_ntoa(r->tohost, sizeof(r->tohost), peer->defaddr.sin_addr); 01907 } 01908 if (!ast_strlen_zero(peer->fromdomain)) 01909 ast_copy_string(r->fromdomain, peer->fromdomain, sizeof(r->fromdomain)); 01910 if (!ast_strlen_zero(peer->fromuser)) 01911 ast_copy_string(r->fromuser, peer->fromuser, sizeof(r->fromuser)); 01912 r->maxtime = peer->maxms; 01913 r->callgroup = peer->callgroup; 01914 r->pickupgroup = peer->pickupgroup; 01915 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 01916 if (peer->maxms && peer->lastms) 01917 r->timer_t1 = peer->lastms; 01918 if ((ast_test_flag(r, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(r, SIP_DTMF) == SIP_DTMF_AUTO)) 01919 r->noncodeccapability |= AST_RTP_DTMF; 01920 else 01921 r->noncodeccapability &= ~AST_RTP_DTMF; 01922 ast_copy_string(r->context, peer->context,sizeof(r->context)); 01923 r->rtptimeout = peer->rtptimeout; 01924 r->rtpholdtimeout = peer->rtpholdtimeout; 01925 r->rtpkeepalive = peer->rtpkeepalive; 01926 if (peer->call_limit) 01927 ast_set_flag(r, SIP_CALL_LIMIT); 01928 01929 return 0; 01930 }
char* description | ( | void | ) |
Provides a description of the module.
Definition at line 13530 of file chan_sip.c.
References desc.
13531 { 13532 return (char *) desc; 13533 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Definition at line 5723 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().
05724 { 05725 if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE)) { 05726 if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) { 05727 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", NULL); 05728 } else { 05729 ast_db_del("SIP/Registry", peer->name); 05730 } 05731 } 05732 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
determine_firstline_parts: parse first line of incoming SIP request
Definition at line 4636 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().
04637 { 04638 char *e, *cmd; 04639 int len; 04640 04641 cmd = ast_skip_blanks(req->header[0]); 04642 if (!*cmd) 04643 return -1; 04644 req->rlPart1 = cmd; 04645 e = ast_skip_nonblanks(cmd); 04646 /* Get the command */ 04647 if (*e) 04648 *e++ = '\0'; 04649 e = ast_skip_blanks(e); 04650 if ( !*e ) 04651 return -1; 04652 04653 if ( !strcasecmp(cmd, "SIP/2.0") ) { 04654 /* We have a response */ 04655 req->rlPart2 = e; 04656 len = strlen( req->rlPart2 ); 04657 if ( len < 2 ) { 04658 return -1; 04659 } 04660 ast_trim_blanks(e); 04661 } else { 04662 /* We have a request */ 04663 if ( *e == '<' ) { 04664 e++; 04665 if ( !*e ) { 04666 return -1; 04667 } 04668 } 04669 req->rlPart2 = e; /* URI */ 04670 if ( ( e= strrchr( req->rlPart2, 'S' ) ) == NULL ) { 04671 return -1; 04672 } 04673 /* XXX maybe trim_blanks() ? */ 04674 while( isspace( *(--e) ) ) {} 04675 if ( *e == '>' ) { 04676 *e = '\0'; 04677 } else { 04678 *(++e)= '\0'; 04679 } 04680 } 04681 return 1; 04682 }
static void* do_monitor | ( | void * | data | ) | [static] |
do_monitor: The SIP monitoring thread ---
Definition at line 11434 of file chan_sip.c.
References __sip_destroy(), ast_channel::_state, ast_io_add(), AST_IO_IN, ast_io_wait(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_rtp_sendcng(), ast_sched_runq(), ast_sched_wait(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, global_mwitime, iflist, 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_destroy_peer(), sip_do_reload(), SIP_NEEDDESTROY, sip_reloading, sip_send_mwi_to_peer(), sipsock, sipsock_read(), t, and VERBOSE_PREFIX_1.
11435 { 11436 int res; 11437 struct sip_pvt *sip; 11438 struct sip_peer *peer = NULL; 11439 time_t t; 11440 int fastrestart =0; 11441 int lastpeernum = -1; 11442 int curpeernum; 11443 int reloading; 11444 11445 /* Add an I/O event to our UDP socket */ 11446 if (sipsock > -1) 11447 ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 11448 11449 /* This thread monitors all the frame relay interfaces which are not yet in use 11450 (and thus do not have a separate thread) indefinitely */ 11451 /* From here on out, we die whenever asked */ 11452 for(;;) { 11453 /* Check for a reload request */ 11454 ast_mutex_lock(&sip_reload_lock); 11455 reloading = sip_reloading; 11456 sip_reloading = 0; 11457 ast_mutex_unlock(&sip_reload_lock); 11458 if (reloading) { 11459 if (option_verbose > 0) 11460 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 11461 sip_do_reload(); 11462 } 11463 /* Check for interfaces needing to be killed */ 11464 ast_mutex_lock(&iflock); 11465 restartsearch: 11466 time(&t); 11467 sip = iflist; 11468 /* don't scan the interface list if it hasn't been a reasonable period 11469 of time since the last time we did it (when MWI is being sent, we can 11470 get back to this point every millisecond or less) 11471 */ 11472 while(!fastrestart && sip) { 11473 ast_mutex_lock(&sip->lock); 11474 if (sip->rtp && sip->owner && (sip->owner->_state == AST_STATE_UP) && !sip->redirip.sin_addr.s_addr) { 11475 if (sip->lastrtptx && sip->rtpkeepalive && t > sip->lastrtptx + sip->rtpkeepalive) { 11476 /* Need to send an empty RTP packet */ 11477 time(&sip->lastrtptx); 11478 ast_rtp_sendcng(sip->rtp, 0); 11479 } 11480 if (sip->lastrtprx && (sip->rtptimeout || sip->rtpholdtimeout) && t > sip->lastrtprx + sip->rtptimeout) { 11481 /* Might be a timeout now -- see if we're on hold */ 11482 struct sockaddr_in sin; 11483 ast_rtp_get_peer(sip->rtp, &sin); 11484 if (sin.sin_addr.s_addr || 11485 (sip->rtpholdtimeout && 11486 (t > sip->lastrtprx + sip->rtpholdtimeout))) { 11487 /* Needs a hangup */ 11488 if (sip->rtptimeout) { 11489 while(sip->owner && ast_mutex_trylock(&sip->owner->lock)) { 11490 ast_mutex_unlock(&sip->lock); 11491 usleep(1); 11492 ast_mutex_lock(&sip->lock); 11493 } 11494 if (sip->owner) { 11495 ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", sip->owner->name, (long)(t - sip->lastrtprx)); 11496 /* Issue a softhangup */ 11497 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 11498 ast_mutex_unlock(&sip->owner->lock); 11499 /* forget the timeouts for this call, since a hangup 11500 has already been requested and we don't want to 11501 repeatedly request hangups 11502 */ 11503 sip->rtptimeout = 0; 11504 sip->rtpholdtimeout = 0; 11505 } 11506 } 11507 } 11508 } 11509 } 11510 if (ast_test_flag(sip, SIP_NEEDDESTROY) && !sip->packets && !sip->owner) { 11511 ast_mutex_unlock(&sip->lock); 11512 __sip_destroy(sip, 1); 11513 goto restartsearch; 11514 } 11515 ast_mutex_unlock(&sip->lock); 11516 sip = sip->next; 11517 } 11518 ast_mutex_unlock(&iflock); 11519 /* Don't let anybody kill us right away. Nobody should lock the interface list 11520 and wait for the monitor list, but the other way around is okay. */ 11521 ast_mutex_lock(&monlock); 11522 /* Lock the network interface */ 11523 ast_mutex_lock(&netlock); 11524 /* Okay, now that we know what to do, release the network lock */ 11525 ast_mutex_unlock(&netlock); 11526 /* And from now on, we're okay to be killed, so release the monitor lock as well */ 11527 ast_mutex_unlock(&monlock); 11528 pthread_testcancel(); 11529 /* Wait for sched or io */ 11530 res = ast_sched_wait(sched); 11531 if ((res < 0) || (res > 1000)) 11532 res = 1000; 11533 /* If we might need to send more mailboxes, don't wait long at all.*/ 11534 if (fastrestart) 11535 res = 1; 11536 res = ast_io_wait(io, res); 11537 if (res > 20) 11538 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 11539 ast_mutex_lock(&monlock); 11540 if (res >= 0) { 11541 res = ast_sched_runq(sched); 11542 if (res >= 20) 11543 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 11544 } 11545 11546 /* needs work to send mwi to realtime peers */ 11547 time(&t); 11548 fastrestart = 0; 11549 curpeernum = 0; 11550 peer = NULL; 11551 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 11552 if ((curpeernum > lastpeernum) && !ast_strlen_zero(iterator->mailbox) && ((t - iterator->lastmsgcheck) > global_mwitime)) { 11553 fastrestart = 1; 11554 lastpeernum = curpeernum; 11555 peer = ASTOBJ_REF(iterator); 11556 }; 11557 curpeernum++; 11558 } while (0) 11559 ); 11560 if (peer) { 11561 ASTOBJ_WRLOCK(peer); 11562 sip_send_mwi_to_peer(peer); 11563 ASTOBJ_UNLOCK(peer); 11564 ASTOBJ_UNREF(peer,sip_destroy_peer); 11565 } else { 11566 /* Reset where we come from */ 11567 lastpeernum = -1; 11568 } 11569 ast_mutex_unlock(&monlock); 11570 } 11571 /* Never reached */ 11572 return NULL; 11573 11574 }
static int do_proxy_auth | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
char * | header, | |||
char * | respheader, | |||
int | sipmethod, | |||
int | init | |||
) | [static] |
do_proxy_auth: Add authentication on outbound SIP packet ---
Definition at line 9026 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().
09027 { 09028 char digest[1024]; 09029 09030 if (!p->options) { 09031 p->options = calloc(1, sizeof(*p->options)); 09032 if (!p->options) { 09033 ast_log(LOG_ERROR, "Out of memory\n"); 09034 return -2; 09035 } 09036 } 09037 09038 p->authtries++; 09039 if (option_debug > 1) 09040 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 09041 memset(digest, 0, sizeof(digest)); 09042 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 09043 /* No way to authenticate */ 09044 return -1; 09045 } 09046 /* Now we have a reply digest */ 09047 p->options->auth = digest; 09048 p->options->authheader = respheader; 09049 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 09050 }
static int do_register_auth | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
char * | header, | |||
char * | respheader | |||
) | [static] |
do_register_auth: Authenticate for outbound registration ---
Definition at line 9002 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().
09003 { 09004 char digest[1024]; 09005 p->authtries++; 09006 memset(digest,0,sizeof(digest)); 09007 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 09008 /* There's nothing to use for authentication */ 09009 /* No digest challenge in request */ 09010 if (sip_debug_test_pvt(p) && p->registry) 09011 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 09012 /* No old challenge */ 09013 return -1; 09014 } 09015 if (recordhistory) { 09016 char tmp[80]; 09017 snprintf(tmp, sizeof(tmp), "Try: %d", p->authtries); 09018 append_history(p, "RegistryAuth", tmp); 09019 } 09020 if (sip_debug_test_pvt(p) && p->registry) 09021 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 09022 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 09023 }
static const char* domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Definition at line 7945 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
07946 { 07947 switch (mode) { 07948 case SIP_DOMAIN_AUTO: 07949 return "[Automatic]"; 07950 case SIP_DOMAIN_CONFIG: 07951 return "[Configured]"; 07952 } 07953 07954 return ""; 07955 }
static const char* dtmfmode2str | ( | int | mode | ) | [static] |
dtmfmode2str: Convert DTMF mode to printable string ---
Definition at line 7753 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().
07754 { 07755 switch (mode) { 07756 case SIP_DTMF_RFC2833: 07757 return "rfc2833"; 07758 case SIP_DTMF_INFO: 07759 return "info"; 07760 case SIP_DTMF_INBAND: 07761 return "inband"; 07762 case SIP_DTMF_AUTO: 07763 return "auto"; 07764 } 07765 return "<error>"; 07766 }
static int expire_register | ( | void * | data | ) | [static] |
expire_register: Expire registration of SIP peer ---
Definition at line 5735 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().
05736 { 05737 struct sip_peer *peer = data; 05738 05739 if (!peer) /* Hmmm. We have no peer. Weird. */ 05740 return 0; 05741 05742 memset(&peer->addr, 0, sizeof(peer->addr)); 05743 05744 destroy_association(peer); 05745 05746 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 05747 register_peer_exten(peer, 0); /* Remove regexten */ 05748 peer->expire = -1; 05749 ast_device_state_changed("SIP/%s", peer->name); 05750 05751 /* Do we need to release this peer from memory? 05752 Only for realtime peers and autocreated peers 05753 */ 05754 if (ast_test_flag(peer, SIP_SELFDESTRUCT) || ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTAUTOCLEAR)) { 05755 peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); /* Remove from peer list */ 05756 ASTOBJ_UNREF(peer, sip_destroy_peer); 05757 } 05758 05759 return 0; 05760 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
extract_uri: Check Contact: URI of SIP message ---
Definition at line 4714 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().
04715 { 04716 char stripped[256]; 04717 char *c, *n; 04718 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 04719 c = get_in_brackets(stripped); 04720 n = strchr(c, ';'); 04721 if (n) 04722 *n = '\0'; 04723 if (!ast_strlen_zero(c)) 04724 ast_copy_string(p->uri, c, sizeof(p->uri)); 04725 }
static char* find_alias | ( | const char * | name, | |
char * | _default | |||
) | [static] |
static struct sip_pvt* find_call | ( | struct sip_request * | req, | |
struct sockaddr_in * | sin, | |||
const int | intended_method | |||
) | [static] |
find_call: Connect incoming SIP message to current dialog or create new dialog structure
Definition at line 3172 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, sip_alloc(), sip_methods, SIP_PKT_WITH_TOTAG, SIP_REGISTER, SIP_RESPONSE, sip_pvt::tag, and sip_pvt::theirtag.
Referenced by sipsock_read().
03173 { 03174 struct sip_pvt *p; 03175 char *callid; 03176 char *tag = ""; 03177 char totag[128]; 03178 char fromtag[128]; 03179 03180 callid = get_header(req, "Call-ID"); 03181 03182 if (pedanticsipchecking) { 03183 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 03184 we need more to identify a branch - so we have to check branch, from 03185 and to tags to identify a call leg. 03186 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 03187 in sip.conf 03188 */ 03189 if (gettag(req, "To", totag, sizeof(totag))) 03190 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 03191 gettag(req, "From", fromtag, sizeof(fromtag)); 03192 03193 if (req->method == SIP_RESPONSE) 03194 tag = totag; 03195 else 03196 tag = fromtag; 03197 03198 03199 if (option_debug > 4 ) 03200 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); 03201 } 03202 03203 ast_mutex_lock(&iflock); 03204 p = iflist; 03205 while(p) { /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 03206 int found = 0; 03207 if (req->method == SIP_REGISTER) 03208 found = (!strcmp(p->callid, callid)); 03209 else 03210 found = (!strcmp(p->callid, callid) && 03211 (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ; 03212 03213 if (option_debug > 4) 03214 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); 03215 03216 /* If we get a new request within an existing to-tag - check the to tag as well */ 03217 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 03218 if (p->tag[0] == '\0' && totag[0]) { 03219 /* We have no to tag, but they have. Wrong dialog */ 03220 found = 0; 03221 } else if (totag[0]) { /* Both have tags, compare them */ 03222 if (strcmp(totag, p->tag)) { 03223 found = 0; /* This is not our packet */ 03224 } 03225 } 03226 if (!found && option_debug > 4) 03227 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); 03228 } 03229 03230 03231 if (found) { 03232 /* Found the call */ 03233 ast_mutex_lock(&p->lock); 03234 ast_mutex_unlock(&iflock); 03235 return p; 03236 } 03237 p = p->next; 03238 } 03239 ast_mutex_unlock(&iflock); 03240 p = sip_alloc(callid, sin, 1, intended_method); 03241 if (p) 03242 ast_mutex_lock(&p->lock); 03243 return p; 03244 }
static struct sip_peer* find_peer | ( | const char * | peer, | |
struct sockaddr_in * | sin, | |||
int | realtime | |||
) | [static] |
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 1766 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
01767 { 01768 struct sip_peer *p = NULL; 01769 01770 if (peer) 01771 p = ASTOBJ_CONTAINER_FIND(&peerl,peer); 01772 else 01773 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl,sin,name,sip_addr_hashfunc,1,sip_addrcmp); 01774 01775 if (!p && realtime) { 01776 p = realtime_peer(peer, sin); 01777 } 01778 01779 return p; 01780 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | realm | |||
) | [static] |
find_realm_authentication: Find authentication for a specific realm ---
Definition at line 12098 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
12099 { 12100 struct sip_auth *a = authlist; /* First entry in auth list */ 12101 12102 while (a) { 12103 if (!strcasecmp(a->realm, realm)){ 12104 break; 12105 } 12106 a = a->next; 12107 } 12108 12109 return a; 12110 }
static int find_sdp | ( | struct sip_request * | req | ) | [static] |
Determine whether a SIP message contains an SDP in its body.
req | the SIP request to process |
Definition at line 3444 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().
03445 { 03446 char *content_type; 03447 char *search; 03448 char *boundary; 03449 unsigned int x; 03450 03451 content_type = get_header(req, "Content-Type"); 03452 03453 /* if the body contains only SDP, this is easy */ 03454 if (!strcasecmp(content_type, "application/sdp")) { 03455 req->sdp_start = 0; 03456 req->sdp_end = req->lines; 03457 return 1; 03458 } 03459 03460 /* if it's not multipart/mixed, there cannot be an SDP */ 03461 if (strncasecmp(content_type, "multipart/mixed", 15)) 03462 return 0; 03463 03464 /* if there is no boundary marker, it's invalid */ 03465 if (!(search = strcasestr(content_type, ";boundary="))) 03466 return 0; 03467 03468 search += 10; 03469 03470 if (ast_strlen_zero(search)) 03471 return 0; 03472 03473 /* make a duplicate of the string, with two extra characters 03474 at the beginning */ 03475 boundary = ast_strdupa(search - 2); 03476 boundary[0] = boundary[1] = '-'; 03477 03478 /* search for the boundary marker, but stop when there are not enough 03479 lines left for it, the Content-Type header and at least one line of 03480 body */ 03481 for (x = 0; x < (req->lines - 2); x++) { 03482 if (!strncasecmp(req->line[x], boundary, strlen(boundary)) && 03483 !strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) { 03484 req->sdp_start = x + 2; 03485 /* search for the end of the body part */ 03486 for ( ; x < req->lines; x++) { 03487 if (!strncasecmp(req->line[x], boundary, strlen(boundary))) 03488 break; 03489 } 03490 req->sdp_end = x; 03491 return 1; 03492 } 03493 } 03494 03495 return 0; 03496 }
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
Definition at line 986 of file chan_sip.c.
References ast_strlen_zero(), sip_methods, and text.
Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read().
00987 { 00988 int i, res = 0; 00989 00990 if (ast_strlen_zero(msg)) 00991 return 0; 00992 00993 for (i = 1; (i < (sizeof(sip_methods) / sizeof(sip_methods[0]))) && !res; i++) { 00994 if (!strcasecmp(sip_methods[i].text, msg)) 00995 res = sip_methods[i].id; 00996 } 00997 return res; 00998 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static] |
find_subscription_type: Find subscription type in array
Definition at line 8389 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
08389 { 08390 int i; 08391 08392 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 08393 if (subscription_types[i].type == subtype) { 08394 return &subscription_types[i]; 08395 } 08396 } 08397 return &subscription_types[0]; 08398 }
static struct sip_user* find_user | ( | const char * | name, | |
int | realtime | |||
) | [static] |
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 1848 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
01849 { 01850 struct sip_user *u = NULL; 01851 u = ASTOBJ_CONTAINER_FIND(&userl,name); 01852 if (!u && realtime) { 01853 u = realtime_user(name); 01854 } 01855 return u; 01856 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
free_old_route: Remove route from route list ---
Definition at line 6062 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
06063 { 06064 struct sip_route *next; 06065 while (route) { 06066 next = route->next; 06067 free(route); 06068 route = next; 06069 } 06070 }
static char* func_check_sipdomain | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
function_check_sipdomain: Dial plan function to check if domain is local
Definition at line 9343 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.
09344 { 09345 if (ast_strlen_zero(data)) { 09346 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 09347 return buf; 09348 } 09349 if (check_sip_domain(data, NULL, 0)) 09350 ast_copy_string(buf, data, len); 09351 else 09352 buf[0] = '\0'; 09353 return buf; 09354 }
static char* func_header_read | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
func_header_read: Read SIP header (dialplan function)
Definition at line 9296 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.
09297 { 09298 struct sip_pvt *p; 09299 char *content; 09300 09301 if (!data) { 09302 ast_log(LOG_WARNING, "This function requires a header name.\n"); 09303 return NULL; 09304 } 09305 09306 ast_mutex_lock(&chan->lock); 09307 if (chan->type != channeltype) { 09308 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 09309 ast_mutex_unlock(&chan->lock); 09310 return NULL; 09311 } 09312 09313 p = chan->tech_pvt; 09314 09315 /* If there is no private structure, this channel is no longer alive */ 09316 if (!p) { 09317 ast_mutex_unlock(&chan->lock); 09318 return NULL; 09319 } 09320 09321 content = get_header(&p->initreq, data); 09322 09323 if (ast_strlen_zero(content)) { 09324 ast_mutex_unlock(&chan->lock); 09325 return NULL; 09326 } 09327 09328 ast_copy_string(buf, content, len); 09329 ast_mutex_unlock(&chan->lock); 09330 09331 return buf; 09332 }
static char* function_sipchaninfo_read | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
function_sipchaninfo_read: ${SIPCHANINFO()} Dialplan function - reads sip channel data
Definition at line 9470 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.
09471 { 09472 struct sip_pvt *p; 09473 char iabuf[INET_ADDRSTRLEN]; 09474 09475 *buf = 0; 09476 09477 if (!data) { 09478 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 09479 return NULL; 09480 } 09481 09482 ast_mutex_lock(&chan->lock); 09483 if (chan->type != channeltype) { 09484 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 09485 ast_mutex_unlock(&chan->lock); 09486 return NULL; 09487 } 09488 09489 /* ast_verbose("function_sipchaninfo_read: %s\n", data); */ 09490 p = chan->tech_pvt; 09491 09492 /* If there is no private structure, this channel is no longer alive */ 09493 if (!p) { 09494 ast_mutex_unlock(&chan->lock); 09495 return NULL; 09496 } 09497 09498 if (!strcasecmp(data, "peerip")) { 09499 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr) : "", len); 09500 } else if (!strcasecmp(data, "recvip")) { 09501 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr) : "", len); 09502 } else if (!strcasecmp(data, "from")) { 09503 ast_copy_string(buf, p->from, len); 09504 } else if (!strcasecmp(data, "uri")) { 09505 ast_copy_string(buf, p->uri, len); 09506 } else if (!strcasecmp(data, "useragent")) { 09507 ast_copy_string(buf, p->useragent, len); 09508 } else if (!strcasecmp(data, "peername")) { 09509 ast_copy_string(buf, p->peername, len); 09510 } else { 09511 ast_mutex_unlock(&chan->lock); 09512 return NULL; 09513 } 09514 ast_mutex_unlock(&chan->lock); 09515 09516 return buf; 09517 }
static char* function_sippeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
function_sippeer: ${SIPPEER()} Dialplan function - reads peer data
Definition at line 9369 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.
09370 { 09371 char *ret = NULL; 09372 struct sip_peer *peer; 09373 char *peername, *colname; 09374 char iabuf[INET_ADDRSTRLEN]; 09375 09376 if (!(peername = ast_strdupa(data))) { 09377 ast_log(LOG_ERROR, "Memory Error!\n"); 09378 return ret; 09379 } 09380 09381 if ((colname = strchr(peername, ':'))) { 09382 *colname = '\0'; 09383 colname++; 09384 } else { 09385 colname = "ip"; 09386 } 09387 if (!(peer = find_peer(peername, NULL, 1))) 09388 return ret; 09389 09390 if (!strcasecmp(colname, "ip")) { 09391 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len); 09392 } else if (!strcasecmp(colname, "status")) { 09393 peer_status(peer, buf, len); 09394 } else if (!strcasecmp(colname, "language")) { 09395 ast_copy_string(buf, peer->language, len); 09396 } else if (!strcasecmp(colname, "regexten")) { 09397 ast_copy_string(buf, peer->regexten, len); 09398 } else if (!strcasecmp(colname, "limit")) { 09399 snprintf(buf, len, "%d", peer->call_limit); 09400 } else if (!strcasecmp(colname, "curcalls")) { 09401 snprintf(buf, len, "%d", peer->inUse); 09402 } else if (!strcasecmp(colname, "accountcode")) { 09403 ast_copy_string(buf, peer->accountcode, len); 09404 } else if (!strcasecmp(colname, "useragent")) { 09405 ast_copy_string(buf, peer->useragent, len); 09406 } else if (!strcasecmp(colname, "mailbox")) { 09407 ast_copy_string(buf, peer->mailbox, len); 09408 } else if (!strcasecmp(colname, "context")) { 09409 ast_copy_string(buf, peer->context, len); 09410 } else if (!strcasecmp(colname, "expire")) { 09411 snprintf(buf, len, "%d", peer->expire); 09412 } else if (!strcasecmp(colname, "dynamic")) { 09413 ast_copy_string(buf, (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 09414 } else if (!strcasecmp(colname, "callerid_name")) { 09415 ast_copy_string(buf, peer->cid_name, len); 09416 } else if (!strcasecmp(colname, "callerid_num")) { 09417 ast_copy_string(buf, peer->cid_num, len); 09418 } else if (!strcasecmp(colname, "codecs")) { 09419 ast_getformatname_multiple(buf, len -1, peer->capability); 09420 } else if (!strncasecmp(colname, "codec[", 6)) { 09421 char *codecnum, *ptr; 09422 int index = 0, codec = 0; 09423 09424 codecnum = strchr(colname, '['); 09425 *codecnum = '\0'; 09426 codecnum++; 09427 if ((ptr = strchr(codecnum, ']'))) { 09428 *ptr = '\0'; 09429 } 09430 index = atoi(codecnum); 09431 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 09432 ast_copy_string(buf, ast_getformatname(codec), len); 09433 } 09434 } 09435 ret = buf; 09436 09437 ASTOBJ_UNREF(peer, sip_destroy_peer); 09438 09439 return ret; 09440 }
static int get_also_info | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
get_also_info: Call transfer support (old way, depreciated)--
Definition at line 6921 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().
06922 { 06923 char tmp[256], *c, *a; 06924 struct sip_request *req; 06925 06926 req = oreq; 06927 if (!req) 06928 req = &p->initreq; 06929 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 06930 06931 c = get_in_brackets(tmp); 06932 06933 06934 if (strncmp(c, "sip:", 4)) { 06935 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 06936 return -1; 06937 } 06938 c += 4; 06939 if ((a = strchr(c, '@'))) 06940 *a = '\0'; 06941 if ((a = strchr(c, ';'))) 06942 *a = '\0'; 06943 06944 if (sip_debug_test_pvt(p)) { 06945 ast_verbose("Looking for %s in %s\n", c, p->context); 06946 } 06947 if (ast_exists_extension(NULL, p->context, c, 1, NULL)) { 06948 /* This is an unsupervised transfer */ 06949 ast_log(LOG_DEBUG,"Assigning Extension %s to REFER-TO\n", c); 06950 ast_copy_string(p->refer_to, c, sizeof(p->refer_to)); 06951 ast_copy_string(p->referred_by, "", sizeof(p->referred_by)); 06952 ast_copy_string(p->refer_contact, "", sizeof(p->refer_contact)); 06953 p->refer_call = NULL; 06954 return 0; 06955 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 06956 return 1; 06957 } 06958 06959 return -1; 06960 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
get_body: get a specific line from the message body
Definition at line 2926 of file chan_sip.c.
References get_body_by_line(), sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
02927 { 02928 int x; 02929 int len = strlen(name); 02930 char *r; 02931 02932 for (x = 0; x < req->lines; x++) { 02933 r = get_body_by_line(req->line[x], name, len); 02934 if (r[0] != '\0') 02935 return r; 02936 } 02937 return ""; 02938 }
static char* get_body_by_line | ( | char * | line, | |
char * | name, | |||
int | nameLen | |||
) | [static] |
get_body_by_line: Reads one line of message body
Definition at line 2883 of file chan_sip.c.
Referenced by get_body(), get_sdp(), and get_sdp_iterate().
02884 { 02885 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') { 02886 return ast_skip_blanks(line + nameLen + 1); 02887 } 02888 return ""; 02889 }
static char* get_calleridname | ( | char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
get_calleridname: Get caller id name from SIP headers ---
Definition at line 7012 of file chan_sip.c.
Referenced by check_user_full().
07013 { 07014 char *end = strchr(input,'<'); 07015 char *tmp = strchr(input,'\"'); 07016 int bytes = 0; 07017 int maxbytes = outputsize - 1; 07018 07019 if (!end || (end == input)) return NULL; 07020 /* move away from "<" */ 07021 end--; 07022 /* we found "name" */ 07023 if (tmp && tmp < end) { 07024 end = strchr(tmp+1, '\"'); 07025 if (!end) return NULL; 07026 bytes = (int) (end - tmp); 07027 /* protect the output buffer */ 07028 if (bytes > maxbytes) 07029 bytes = maxbytes; 07030 ast_copy_string(output, tmp + 1, bytes); 07031 } else { 07032 /* we didn't find "name" */ 07033 /* clear the empty characters in the begining*/ 07034 input = ast_skip_blanks(input); 07035 /* clear the empty characters in the end */ 07036 while(*end && (*end < 33) && end > input) 07037 end--; 07038 if (end >= input) { 07039 bytes = (int) (end - input) + 2; 07040 /* protect the output buffer */ 07041 if (bytes > maxbytes) { 07042 bytes = maxbytes; 07043 } 07044 ast_copy_string(output, input, bytes); 07045 } 07046 else 07047 return NULL; 07048 } 07049 return output; 07050 }
static int get_destination | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
get_destination: Find out who the call is for --
Definition at line 6646 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().
06647 { 06648 char tmp[256] = "", *uri, *a, *user, *domain, *opts; 06649 char tmpf[256], *from; 06650 struct sip_request *req; 06651 char *colon; 06652 06653 req = oreq; 06654 if (!req) 06655 req = &p->initreq; 06656 if (req->rlPart2) 06657 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 06658 uri = get_in_brackets(tmp); 06659 06660 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 06661 06662 from = get_in_brackets(tmpf); 06663 06664 if (strncmp(uri, "sip:", 4)) { 06665 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 06666 return -1; 06667 } 06668 uri += 4; 06669 if (!ast_strlen_zero(from)) { 06670 if (strncmp(from, "sip:", 4)) { 06671 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 06672 return -1; 06673 } 06674 from += 4; 06675 } else 06676 from = NULL; 06677 06678 if (pedanticsipchecking) { 06679 ast_uri_decode(uri); 06680 ast_uri_decode(from); 06681 } 06682 06683 /* Get the target domain first and user */ 06684 if ((domain = strchr(uri, '@'))) { 06685 *domain++ = '\0'; 06686 user = uri; 06687 } else { 06688 /* No user portion present */ 06689 domain = uri; 06690 user = "s"; 06691 } 06692 06693 /* Strip port from domain if present */ 06694 if ((colon = strchr(domain, ':'))) { 06695 *colon = '\0'; 06696 } 06697 06698 /* Strip any params or options from user */ 06699 if ((opts = strchr(user, ';'))) { 06700 *opts = '\0'; 06701 } 06702 06703 ast_copy_string(p->domain, domain, sizeof(p->domain)); 06704 06705 if (!AST_LIST_EMPTY(&domain_list)) { 06706 char domain_context[AST_MAX_EXTENSION]; 06707 06708 domain_context[0] = '\0'; 06709 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 06710 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 06711 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 06712 return -2; 06713 } 06714 } 06715 /* If we have a context defined, overwrite the original context */ 06716 if (!ast_strlen_zero(domain_context)) 06717 ast_copy_string(p->context, domain_context, sizeof(p->context)); 06718 } 06719 06720 if (from) { 06721 if ((a = strchr(from, ';'))) 06722 *a = '\0'; 06723 if ((a = strchr(from, '@'))) { 06724 *a = '\0'; 06725 ast_copy_string(p->fromdomain, a + 1, sizeof(p->fromdomain)); 06726 } else 06727 ast_copy_string(p->fromdomain, from, sizeof(p->fromdomain)); 06728 } 06729 if (sip_debug_test_pvt(p)) 06730 ast_verbose("Looking for %s in %s (domain %s)\n", user, p->context, p->domain); 06731 06732 /* Return 0 if we have a matching extension */ 06733 if (ast_exists_extension(NULL, p->context, user, 1, from) || 06734 !strcmp(uri, ast_pickup_ext())) { 06735 if (!oreq) 06736 ast_copy_string(p->exten, user, sizeof(p->exten)); 06737 return 0; 06738 } 06739 06740 /* Return 1 for overlap dialling support */ 06741 if (ast_canmatch_extension(NULL, p->context, user, 1, from) || 06742 !strncmp(user, ast_pickup_ext(),strlen(user))) { 06743 return 1; 06744 } 06745 06746 return -1; 06747 }
static char * get_header | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
get_header: Get header from SIP request ---
Definition at line 2985 of file chan_sip.c.
References __get_header().
02986 { 02987 int start = 0; 02988 return __get_header(req, name, &start); 02989 }
static char* get_in_brackets | ( | char * | tmp | ) | [static] |
get_in_brackets: Pick out text in brackets from character string ---
Definition at line 1548 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().
01549 { 01550 char *parse; 01551 char *first_quote; 01552 char *first_bracket; 01553 char *second_bracket; 01554 char last_char; 01555 01556 parse = tmp; 01557 while (1) { 01558 first_quote = strchr(parse, '"'); 01559 first_bracket = strchr(parse, '<'); 01560 if (first_quote && first_bracket && (first_quote < first_bracket)) { 01561 last_char = '\0'; 01562 for (parse = first_quote + 1; *parse; parse++) { 01563 if ((*parse == '"') && (last_char != '\\')) 01564 break; 01565 last_char = *parse; 01566 } 01567 if (!*parse) { 01568 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 01569 return tmp; 01570 } 01571 parse++; 01572 continue; 01573 } 01574 if (first_bracket) { 01575 second_bracket = strchr(first_bracket + 1, '>'); 01576 if (second_bracket) { 01577 *second_bracket = '\0'; 01578 return first_bracket + 1; 01579 } else { 01580 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 01581 return tmp; 01582 } 01583 } 01584 return tmp; 01585 } 01586 }
static int get_msg_text | ( | char * | buf, | |
int | len, | |||
struct sip_request * | req | |||
) | [static] |
get_msg_text: Get text out of a SIP MESSAGE packet ---
Definition at line 7361 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by receive_message().
07362 { 07363 int x; 07364 int y; 07365 07366 buf[0] = '\0'; 07367 y = len - strlen(buf) - 5; 07368 if (y < 0) 07369 y = 0; 07370 for (x=0;x<req->lines;x++) { 07371 strncat(buf, req->line[x], y); /* safe */ 07372 y -= strlen(req->line[x]) + 1; 07373 if (y < 0) 07374 y = 0; 07375 if (y != 0) 07376 strcat(buf, "\n"); /* safe */ 07377 } 07378 return 0; 07379 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
get_rdnis: get referring dnis ---
Definition at line 6618 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().
06619 { 06620 char tmp[256], *c, *a; 06621 struct sip_request *req; 06622 06623 req = oreq; 06624 if (!req) 06625 req = &p->initreq; 06626 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 06627 if (ast_strlen_zero(tmp)) 06628 return 0; 06629 c = get_in_brackets(tmp); 06630 if (strncmp(c, "sip:", 4)) { 06631 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 06632 return -1; 06633 } 06634 c += 4; 06635 if ((a = strchr(c, '@')) || (a = strchr(c, ';'))) { 06636 *a = '\0'; 06637 } 06638 if (sip_debug_test_pvt(p)) 06639 ast_verbose("RDNIS is %s\n", c); 06640 ast_copy_string(p->rdnis, c, sizeof(p->rdnis)); 06641 06642 return 0; 06643 }
static int get_refer_info | ( | struct sip_pvt * | sip_pvt, | |
struct sip_request * | outgoing_req | |||
) | [static] |
get_refer_info: Call transfer support (the REFER method) ---
Definition at line 6779 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().
06780 { 06781 06782 char *p_refer_to = NULL, *p_referred_by = NULL, *h_refer_to = NULL, *h_referred_by = NULL, *h_contact = NULL; 06783 char *replace_callid = "", *refer_to = NULL, *referred_by = NULL, *ptr = NULL; 06784 struct sip_request *req = NULL; 06785 struct sip_pvt *sip_pvt_ptr = NULL; 06786 struct ast_channel *chan = NULL, *peer = NULL; 06787 const char *transfercontext; 06788 06789 req = outgoing_req; 06790 06791 if (!req) { 06792 req = &sip_pvt->initreq; 06793 } 06794 06795 if (!( (p_refer_to = get_header(req, "Refer-To")) && (h_refer_to = ast_strdupa(p_refer_to)) )) { 06796 ast_log(LOG_WARNING, "No Refer-To Header That's illegal\n"); 06797 return -1; 06798 } 06799 06800 refer_to = get_in_brackets(h_refer_to); 06801 06802 if (!( (p_referred_by = get_header(req, "Referred-By")) && (h_referred_by = ast_strdupa(p_referred_by)) )) { 06803 ast_log(LOG_WARNING, "No Referrred-By Header That's not illegal\n"); 06804 return -1; 06805 } else { 06806 if (pedanticsipchecking) { 06807 ast_uri_decode(h_referred_by); 06808 } 06809 referred_by = get_in_brackets(h_referred_by); 06810 } 06811 h_contact = get_header(req, "Contact"); 06812 06813 if (strncmp(refer_to, "sip:", 4)) { 06814 ast_log(LOG_WARNING, "Refer-to: Huh? Not a SIP header (%s)?\n", refer_to); 06815 return -1; 06816 } 06817 06818 if (strncmp(referred_by, "sip:", 4)) { 06819 ast_log(LOG_WARNING, "Referred-by: Huh? Not a SIP header (%s) Ignoring?\n", referred_by); 06820 referred_by = NULL; 06821 } 06822 06823 if (refer_to) 06824 refer_to += 4; 06825 06826 if (referred_by) 06827 referred_by += 4; 06828 06829 if ((ptr = strchr(refer_to, '?'))) { 06830 /* Search for arguments */ 06831 *ptr = '\0'; 06832 ptr++; 06833 if (!strncasecmp(ptr, "REPLACES=", 9)) { 06834 char *p; 06835 replace_callid = ast_strdupa(ptr + 9); 06836 /* someday soon to support invite/replaces properly! 06837 replaces_header = ast_strdupa(replace_callid); 06838 -anthm 06839 */ 06840 ast_uri_decode(replace_callid); 06841 if ((ptr = strchr(replace_callid, '%'))) 06842 *ptr = '\0'; 06843 if ((ptr = strchr(replace_callid, ';'))) 06844 *ptr = '\0'; 06845 /* Skip leading whitespace XXX memmove behaviour with overlaps ? */ 06846 p = ast_skip_blanks(replace_callid); 06847 if (p != replace_callid) 06848 memmove(replace_callid, p, strlen(p)); 06849 } 06850 } 06851 06852 if ((ptr = strchr(refer_to, '@'))) /* Skip domain (should be saved in SIPDOMAIN) */ 06853 *ptr = '\0'; 06854 if ((ptr = strchr(refer_to, ';'))) 06855 *ptr = '\0'; 06856 06857 if (referred_by) { 06858 if ((ptr = strchr(referred_by, '@'))) 06859 *ptr = '\0'; 06860 if ((ptr = strchr(referred_by, ';'))) 06861 *ptr = '\0'; 06862 } 06863 06864 transfercontext = pbx_builtin_getvar_helper(sip_pvt->owner, "TRANSFER_CONTEXT"); 06865 if (ast_strlen_zero(transfercontext)) 06866 transfercontext = sip_pvt->context; 06867 06868 if (sip_debug_test_pvt(sip_pvt)) { 06869 ast_verbose("Transfer to %s in %s\n", refer_to, transfercontext); 06870 if (referred_by) 06871 ast_verbose("Transfer from %s in %s\n", referred_by, sip_pvt->context); 06872 } 06873 if (!ast_strlen_zero(replace_callid)) { 06874 /* This is a supervised transfer */ 06875 ast_log(LOG_DEBUG,"Assigning Replace-Call-ID Info %s to REPLACE_CALL_ID\n",replace_callid); 06876 06877 ast_copy_string(sip_pvt->refer_to, "", sizeof(sip_pvt->refer_to)); 06878 ast_copy_string(sip_pvt->referred_by, "", sizeof(sip_pvt->referred_by)); 06879 ast_copy_string(sip_pvt->refer_contact, "", sizeof(sip_pvt->refer_contact)); 06880 sip_pvt->refer_call = NULL; 06881 if ((sip_pvt_ptr = get_sip_pvt_byid_locked(replace_callid))) { 06882 sip_pvt->refer_call = sip_pvt_ptr; 06883 if (sip_pvt->refer_call == sip_pvt) { 06884 ast_log(LOG_NOTICE, "Supervised transfer attempted to transfer into same call id (%s == %s)!\n", replace_callid, sip_pvt->callid); 06885 sip_pvt->refer_call = NULL; 06886 } else 06887 return 0; 06888 } else { 06889 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); 06890 /* XXX The refer_to could contain a call on an entirely different machine, requiring an 06891 INVITE with a replaces header -anthm XXX */ 06892 /* The only way to find out is to use the dialplan - oej */ 06893 } 06894 } else if (ast_exists_extension(NULL, transfercontext, refer_to, 1, NULL) || !strcmp(refer_to, ast_parking_ext())) { 06895 /* This is an unsupervised transfer (blind transfer) */ 06896 06897 ast_log(LOG_DEBUG,"Unsupervised transfer to (Refer-To): %s\n", refer_to); 06898 if (referred_by) 06899 ast_log(LOG_DEBUG,"Transferred by (Referred-by: ) %s \n", referred_by); 06900 ast_log(LOG_DEBUG,"Transfer Contact Info %s (REFER_CONTACT)\n", h_contact); 06901 ast_copy_string(sip_pvt->refer_to, refer_to, sizeof(sip_pvt->refer_to)); 06902 if (referred_by) 06903 ast_copy_string(sip_pvt->referred_by, referred_by, sizeof(sip_pvt->referred_by)); 06904 if (h_contact) { 06905 ast_copy_string(sip_pvt->refer_contact, h_contact, sizeof(sip_pvt->refer_contact)); 06906 } 06907 sip_pvt->refer_call = NULL; 06908 if ((chan = sip_pvt->owner) && (peer = ast_bridged_channel(sip_pvt->owner))) { 06909 pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name); 06910 pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", chan->name); 06911 } 06912 return 0; 06913 } else if (ast_canmatch_extension(NULL, transfercontext, refer_to, 1, NULL)) { 06914 return 1; 06915 } 06916 06917 return -1; 06918 }
static int get_rpid_num | ( | char * | input, | |
char * | output, | |||
int | maxlen | |||
) | [static] |
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 7056 of file chan_sip.c.
References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
07057 { 07058 char *start; 07059 char *end; 07060 07061 start = strchr(input,':'); 07062 if (!start) { 07063 output[0] = '\0'; 07064 return 0; 07065 } 07066 start++; 07067 07068 /* we found "number" */ 07069 ast_copy_string(output,start,maxlen); 07070 output[maxlen-1] = '\0'; 07071 07072 end = strchr(output,'@'); 07073 if (end) 07074 *end = '\0'; 07075 else 07076 output[0] = '\0'; 07077 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 07078 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 07079 07080 return 0; 07081 }
static char* get_sdp | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
get_sdp: get a specific line from the SDP
Definition at line 2892 of file chan_sip.c.
References get_body_by_line(), sip_request::line, and sip_request::sdp_start.
02893 { 02894 int x; 02895 int len = strlen(name); 02896 char *r; 02897 02898 for (x = req->sdp_start; x < req->sdp_end; x++) { 02899 r = get_body_by_line(req->line[x], name, len); 02900 if (r[0] != '\0') 02901 return r; 02902 } 02903 return ""; 02904 }
static char* get_sdp_iterate | ( | int * | iterator, | |
struct sip_request * | req, | |||
char * | name | |||
) | [static] |
Definition at line 2911 of file chan_sip.c.
References get_body_by_line(), and sip_request::line.
02913 { 02914 int len = strlen(name); 02915 char *r; 02916 02917 while (*iterator < req->sdp_end) { 02918 r = get_body_by_line(req->line[(*iterator)++], name, len); 02919 if (r[0] != '\0') 02920 return r; 02921 } 02922 return ""; 02923 }
static struct sip_pvt* get_sip_pvt_byid_locked | ( | char * | callid | ) | [static] |
get_sip_pvt_byid_locked: Lock interface lock and find matching pvt lock ---
Definition at line 6750 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().
06751 { 06752 struct sip_pvt *sip_pvt_ptr = NULL; 06753 06754 /* Search interfaces and find the match */ 06755 ast_mutex_lock(&iflock); 06756 sip_pvt_ptr = iflist; 06757 while(sip_pvt_ptr) { 06758 if (!strcmp(sip_pvt_ptr->callid, callid)) { 06759 /* Go ahead and lock it (and its owner) before returning */ 06760 ast_mutex_lock(&sip_pvt_ptr->lock); 06761 if (sip_pvt_ptr->owner) { 06762 while(ast_mutex_trylock(&sip_pvt_ptr->owner->lock)) { 06763 ast_mutex_unlock(&sip_pvt_ptr->lock); 06764 usleep(1); 06765 ast_mutex_lock(&sip_pvt_ptr->lock); 06766 if (!sip_pvt_ptr->owner) 06767 break; 06768 } 06769 } 06770 break; 06771 } 06772 sip_pvt_ptr = sip_pvt_ptr->next; 06773 } 06774 ast_mutex_unlock(&iflock); 06775 return sip_pvt_ptr; 06776 }
static char * gettag | ( | struct sip_request * | req, | |
char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
gettag: Get tag from packet
Definition at line 10378 of file chan_sip.c.
References get_header(), and strcasestr().
Referenced by find_call(), handle_request(), and handle_response().
10379 { 10380 10381 char *thetag, *sep; 10382 10383 10384 if (!tagbuf) 10385 return NULL; 10386 tagbuf[0] = '\0'; /* reset the buffer */ 10387 thetag = get_header(req, header); 10388 thetag = strcasestr(thetag, ";tag="); 10389 if (thetag) { 10390 thetag += 5; 10391 ast_copy_string(tagbuf, thetag, tagbufsize); 10392 sep = strchr(tagbuf, ';'); 10393 if (sep) 10394 *sep = '\0'; 10395 } 10396 return thetag; 10397 }
static int handle_common_options | ( | struct ast_flags * | flags, | |
struct ast_flags * | mask, | |||
struct ast_variable * | v | |||
) | [static] |
handle_common_options: Handle flag-type options common to users and peers ---
Definition at line 11840 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().
11841 { 11842 int res = 0; 11843 11844 if (!strcasecmp(v->name, "trustrpid")) { 11845 ast_set_flag(mask, SIP_TRUSTRPID); 11846 ast_set2_flag(flags, ast_true(v->value), SIP_TRUSTRPID); 11847 res = 1; 11848 } else if (!strcasecmp(v->name, "sendrpid")) { 11849 ast_set_flag(mask, SIP_SENDRPID); 11850 ast_set2_flag(flags, ast_true(v->value), SIP_SENDRPID); 11851 res = 1; 11852 } else if (!strcasecmp(v->name, "useclientcode")) { 11853 ast_set_flag(mask, SIP_USECLIENTCODE); 11854 ast_set2_flag(flags, ast_true(v->value), SIP_USECLIENTCODE); 11855 res = 1; 11856 } else if (!strcasecmp(v->name, "dtmfmode")) { 11857 ast_set_flag(mask, SIP_DTMF); 11858 ast_clear_flag(flags, SIP_DTMF); 11859 if (!strcasecmp(v->value, "inband")) 11860 ast_set_flag(flags, SIP_DTMF_INBAND); 11861 else if (!strcasecmp(v->value, "rfc2833")) 11862 ast_set_flag(flags, SIP_DTMF_RFC2833); 11863 else if (!strcasecmp(v->value, "info")) 11864 ast_set_flag(flags, SIP_DTMF_INFO); 11865 else if (!strcasecmp(v->value, "auto")) 11866 ast_set_flag(flags, SIP_DTMF_AUTO); 11867 else { 11868 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 11869 ast_set_flag(flags, SIP_DTMF_RFC2833); 11870 } 11871 } else if (!strcasecmp(v->name, "nat")) { 11872 ast_set_flag(mask, SIP_NAT); 11873 ast_clear_flag(flags, SIP_NAT); 11874 if (!strcasecmp(v->value, "never")) 11875 ast_set_flag(flags, SIP_NAT_NEVER); 11876 else if (!strcasecmp(v->value, "route")) 11877 ast_set_flag(flags, SIP_NAT_ROUTE); 11878 else if (ast_true(v->value)) 11879 ast_set_flag(flags, SIP_NAT_ALWAYS); 11880 else 11881 ast_set_flag(flags, SIP_NAT_RFC3581); 11882 } else if (!strcasecmp(v->name, "canreinvite")) { 11883 ast_set_flag(mask, SIP_REINVITE); 11884 ast_clear_flag(flags, SIP_REINVITE); 11885 if (!strcasecmp(v->value, "update")) 11886 ast_set_flag(flags, SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 11887 else 11888 ast_set2_flag(flags, ast_true(v->value), SIP_CAN_REINVITE); 11889 } else if (!strcasecmp(v->name, "insecure")) { 11890 ast_set_flag(mask, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11891 ast_clear_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11892 if (!strcasecmp(v->value, "very")) 11893 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 11894 else if (ast_true(v->value)) 11895 ast_set_flag(flags, SIP_INSECURE_PORT); 11896 else if (!ast_false(v->value)) { 11897 char buf[64]; 11898 char *word, *next; 11899 11900 ast_copy_string(buf, v->value, sizeof(buf)); 11901 next = buf; 11902 while ((word = strsep(&next, ","))) { 11903 if (!strcasecmp(word, "port")) 11904 ast_set_flag(flags, SIP_INSECURE_PORT); 11905 else if (!strcasecmp(word, "invite")) 11906 ast_set_flag(flags, SIP_INSECURE_INVITE); 11907 else 11908 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", v->value, v->lineno); 11909 } 11910 } 11911 } else if (!strcasecmp(v->name, "progressinband")) { 11912 ast_set_flag(mask, SIP_PROG_INBAND); 11913 ast_clear_flag(flags, SIP_PROG_INBAND); 11914 if (ast_true(v->value)) 11915 ast_set_flag(flags, SIP_PROG_INBAND_YES); 11916 else if (strcasecmp(v->value, "never")) 11917 ast_set_flag(flags, SIP_PROG_INBAND_NO); 11918 } else if (!strcasecmp(v->name, "allowguest")) { 11919 #ifdef OSP_SUPPORT 11920 if (!strcasecmp(v->value, "osp")) 11921 global_allowguest = 2; 11922 else 11923 #endif 11924 if (ast_true(v->value)) 11925 global_allowguest = 1; 11926 else 11927 global_allowguest = 0; 11928 #ifdef OSP_SUPPORT 11929 } else if (!strcasecmp(v->name, "ospauth")) { 11930 ast_set_flag(mask, SIP_OSPAUTH); 11931 ast_clear_flag(flags, SIP_OSPAUTH); 11932 if (!strcasecmp(v->value, "proxy")) 11933 ast_set_flag(flags, SIP_OSPAUTH_PROXY); 11934 else if (!strcasecmp(v->value, "gateway")) 11935 ast_set_flag(flags, SIP_OSPAUTH_GATEWAY); 11936 else if(!strcasecmp (v->value, "exclusive")) 11937 ast_set_flag(flags, SIP_OSPAUTH_EXCLUSIVE); 11938 #endif 11939 } else if (!strcasecmp(v->name, "promiscredir")) { 11940 ast_set_flag(mask, SIP_PROMISCREDIR); 11941 ast_set2_flag(flags, ast_true(v->value), SIP_PROMISCREDIR); 11942 res = 1; 11943 } 11944 11945 return res; 11946 }
static int handle_request | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
struct sockaddr_in * | sin, | |||
int * | recount, | |||
int * | nounlock | |||
) | [static] |
handle_request: Handle SIP requests (methods) ---
Definition at line 11095 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.
11096 { 11097 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 11098 relatively static */ 11099 struct sip_request resp; 11100 char *cmd; 11101 char *cseq; 11102 char *useragent; 11103 int seqno; 11104 int len; 11105 int ignore=0; 11106 int respid; 11107 int res = 0; 11108 char iabuf[INET_ADDRSTRLEN]; 11109 int debug = sip_debug_test_pvt(p); 11110 char *e; 11111 int error = 0; 11112 11113 /* Clear out potential response */ 11114 memset(&resp, 0, sizeof(resp)); 11115 11116 /* Get Method and Cseq */ 11117 cseq = get_header(req, "Cseq"); 11118 cmd = req->header[0]; 11119 11120 /* Must have Cseq */ 11121 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 11122 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 11123 error = 1; 11124 } 11125 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 11126 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 11127 error = 1; 11128 } 11129 if (error) { 11130 if (!p->initreq.header) /* New call */ 11131 ast_set_flag(p, SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 11132 return -1; 11133 } 11134 /* Get the command XXX */ 11135 11136 cmd = req->rlPart1; 11137 e = req->rlPart2; 11138 11139 /* Save useragent of the client */ 11140 useragent = get_header(req, "User-Agent"); 11141 if (!ast_strlen_zero(useragent)) 11142 ast_copy_string(p->useragent, useragent, sizeof(p->useragent)); 11143 11144 /* Find out SIP method for incoming request */ 11145 if (req->method == SIP_RESPONSE) { /* Response to our request */ 11146 /* Response to our request -- Do some sanity checks */ 11147 if (!p->initreq.headers) { 11148 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 11149 ast_set_flag(p, SIP_NEEDDESTROY); 11150 return 0; 11151 } else if (p->ocseq && (p->ocseq < seqno)) { 11152 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 11153 return -1; 11154 } else if (p->ocseq && (p->ocseq != seqno)) { 11155 /* ignore means "don't do anything with it" but still have to 11156 respond appropriately */ 11157 ignore=1; 11158 } 11159 11160 e = ast_skip_blanks(e); 11161 if (sscanf(e, "%d %n", &respid, &len) != 1) { 11162 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 11163 } else { 11164 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 11165 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 11166 extract_uri(p, req); 11167 handle_response(p, respid, e + len, req, ignore, seqno); 11168 } 11169 return 0; 11170 } 11171 11172 /* New SIP request coming in 11173 (could be new request in existing SIP dialog as well...) 11174 */ 11175 11176 p->method = req->method; /* Find out which SIP method they are using */ 11177 if (option_debug > 2) 11178 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 11179 11180 if (p->icseq && (p->icseq > seqno)) { 11181 if (option_debug) 11182 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 11183 if (req->method != SIP_ACK) 11184 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 11185 return -1; 11186 } else if (p->icseq && (p->icseq == seqno) && req->method != SIP_ACK &&(p->method != SIP_CANCEL|| ast_test_flag(p, SIP_ALREADYGONE))) { 11187 /* ignore means "don't do anything with it" but still have to 11188 respond appropriately. We do this if we receive a repeat of 11189 the last sequence number */ 11190 ignore=2; 11191 if (option_debug > 2) 11192 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 11193 } 11194 11195 if (seqno >= p->icseq) 11196 /* Next should follow monotonically (but not necessarily 11197 incrementally -- thanks again to the genius authors of SIP -- 11198 increasing */ 11199 p->icseq = seqno; 11200 11201 /* Find their tag if we haven't got it */ 11202 if (ast_strlen_zero(p->theirtag)) { 11203 gettag(req, "From", p->theirtag, sizeof(p->theirtag)); 11204 } 11205 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 11206 11207 if (pedanticsipchecking) { 11208 /* If this is a request packet without a from tag, it's not 11209 correct according to RFC 3261 */ 11210 /* Check if this a new request in a new dialog with a totag already attached to it, 11211 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 11212 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 11213 /* If this is a first request and it got a to-tag, it is not for us */ 11214 if (!ignore && req->method == SIP_INVITE) { 11215 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req, 1); 11216 /* Will cease to exist after ACK */ 11217 } else if (req->method != SIP_ACK) { 11218 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 11219 ast_set_flag(p, SIP_NEEDDESTROY); 11220 } 11221 return res; 11222 } 11223 } 11224 11225 /* Handle various incoming SIP methods in requests */ 11226 switch (p->method) { 11227 case SIP_OPTIONS: 11228 res = handle_request_options(p, req, debug); 11229 break; 11230 case SIP_INVITE: 11231 res = handle_request_invite(p, req, debug, ignore, seqno, sin, recount, e); 11232 break; 11233 case SIP_REFER: 11234 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 11235 break; 11236 case SIP_CANCEL: 11237 res = handle_request_cancel(p, req, debug, ignore); 11238 break; 11239 case SIP_BYE: 11240 res = handle_request_bye(p, req, debug, ignore); 11241 break; 11242 case SIP_MESSAGE: 11243 res = handle_request_message(p, req, debug, ignore); 11244 break; 11245 case SIP_SUBSCRIBE: 11246 res = handle_request_subscribe(p, req, debug, ignore, sin, seqno, e); 11247 break; 11248 case SIP_REGISTER: 11249 res = handle_request_register(p, req, debug, ignore, sin, e); 11250 break; 11251 case SIP_INFO: 11252 if (!ignore) { 11253 if (debug) 11254 ast_verbose("Receiving INFO!\n"); 11255 handle_request_info(p, req); 11256 } else { /* if ignoring, transmit response */ 11257 transmit_response(p, "200 OK", req); 11258 } 11259 break; 11260 case SIP_NOTIFY: 11261 /* XXX we get NOTIFY's from some servers. WHY?? Maybe we should 11262 look into this someday XXX */ 11263 transmit_response(p, "200 OK", req); 11264 if (!p->lastinvite) 11265 ast_set_flag(p, SIP_NEEDDESTROY); 11266 break; 11267 case SIP_ACK: 11268 /* Make sure we don't ignore this */ 11269 if (seqno == p->pendinginvite) { 11270 p->pendinginvite = 0; 11271 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 11272 if (find_sdp(req)) { 11273 if (process_sdp(p, req)) 11274 return -1; 11275 } 11276 check_pendings(p); 11277 } 11278 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 11279 ast_set_flag(p, SIP_NEEDDESTROY); 11280 break; 11281 default: 11282 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 11283 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 11284 cmd, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); 11285 /* If this is some new method, and we don't have a call, destroy it now */ 11286 if (!p->initreq.headers) 11287 ast_set_flag(p, SIP_NEEDDESTROY); 11288 break; 11289 } 11290 return res; 11291 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug, | |||
int | ignore | |||
) | [static] |
handle_request_bye: Handle incoming BYE request ---
Definition at line 10786 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().
10787 { 10788 struct ast_channel *c=NULL; 10789 int res; 10790 struct ast_channel *bridged_to; 10791 char iabuf[INET_ADDRSTRLEN]; 10792 10793 if (p->pendinginvite && !ast_test_flag(p, SIP_OUTGOING) && !ignore) 10794 transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1); 10795 10796 copy_request(&p->initreq, req); 10797 check_via(p, req); 10798 ast_set_flag(p, SIP_ALREADYGONE); 10799 if (p->rtp) { 10800 /* Immediately stop RTP */ 10801 ast_rtp_stop(p->rtp); 10802 } 10803 if (p->vrtp) { 10804 /* Immediately stop VRTP */ 10805 ast_rtp_stop(p->vrtp); 10806 } 10807 if (!ast_strlen_zero(get_header(req, "Also"))) { 10808 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 10809 ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 10810 if (ast_strlen_zero(p->context)) 10811 strcpy(p->context, default_context); 10812 res = get_also_info(p, req); 10813 if (!res) { 10814 c = p->owner; 10815 if (c) { 10816 bridged_to = ast_bridged_channel(c); 10817 if (bridged_to) { 10818 /* Don't actually hangup here... */ 10819 ast_moh_stop(bridged_to); 10820 ast_async_goto(bridged_to, p->context, p->refer_to,1); 10821 } else 10822 ast_queue_hangup(p->owner); 10823 } 10824 } else { 10825 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); 10826 if (p->owner) 10827 ast_queue_hangup(p->owner); 10828 } 10829 } else if (p->owner) { 10830 ast_queue_hangup(p->owner); 10831 if (option_debug > 2) 10832 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n."); 10833 } else { 10834 ast_set_flag(p, SIP_NEEDDESTROY); 10835 if (option_debug > 2) 10836 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n."); 10837 } 10838 transmit_response(p, "200 OK", req); 10839 10840 return 1; 10841 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug, | |||
int | ignore | |||
) | [static] |
handle_request_cancel: Handle incoming CANCEL request ---
Definition at line 10757 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().
10758 { 10759 10760 check_via(p, req); 10761 ast_set_flag(p, SIP_ALREADYGONE); 10762 if (p->rtp) { 10763 /* Immediately stop RTP */ 10764 ast_rtp_stop(p->rtp); 10765 } 10766 if (p->vrtp) { 10767 /* Immediately stop VRTP */ 10768 ast_rtp_stop(p->vrtp); 10769 } 10770 if (p->owner) 10771 ast_queue_hangup(p->owner); 10772 else 10773 ast_set_flag(p, SIP_NEEDDESTROY); 10774 if (p->initreq.len > 0) { 10775 if (!ignore) 10776 transmit_response_reliable(p, "487 Request Terminated", &p->initreq, 1); 10777 transmit_response(p, "200 OK", req); 10778 return 1; 10779 } else { 10780 transmit_response(p, "481 Call Leg Does Not Exist", req); 10781 return 0; 10782 } 10783 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
handle_request_info: Receive SIP INFO Message ---
Definition at line 8742 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().
08743 { 08744 char buf[1024]; 08745 unsigned int event; 08746 char *c; 08747 08748 /* Need to check the media/type */ 08749 if (!strcasecmp(get_header(req, "Content-Type"), "application/dtmf-relay") || 08750 !strcasecmp(get_header(req, "Content-Type"), "application/vnd.nortelnetworks.digits")) { 08751 08752 /* Try getting the "signal=" part */ 08753 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 08754 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 08755 transmit_response(p, "200 OK", req); /* Should return error */ 08756 return; 08757 } else { 08758 ast_copy_string(buf, c, sizeof(buf)); 08759 } 08760 08761 if (!p->owner) { /* not a PBX call */ 08762 transmit_response(p, "481 Call leg/transaction does not exist", req); 08763 ast_set_flag(p, SIP_NEEDDESTROY); 08764 return; 08765 } 08766 08767 if (ast_strlen_zero(buf)) { 08768 transmit_response(p, "200 OK", req); 08769 return; 08770 } 08771 08772 if (buf[0] == '*') 08773 event = 10; 08774 else if (buf[0] == '#') 08775 event = 11; 08776 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 08777 event = 12 + buf[0] - 'A'; 08778 else 08779 event = atoi(buf); 08780 if (event == 16) { 08781 /* send a FLASH event */ 08782 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 08783 ast_queue_frame(p->owner, &f); 08784 if (sipdebug) 08785 ast_verbose("* DTMF-relay event received: FLASH\n"); 08786 } else { 08787 /* send a DTMF event */ 08788 struct ast_frame f = { AST_FRAME_DTMF, }; 08789 if (event < 10) { 08790 f.subclass = '0' + event; 08791 } else if (event < 11) { 08792 f.subclass = '*'; 08793 } else if (event < 12) { 08794 f.subclass = '#'; 08795 } else if (event < 16) { 08796 f.subclass = 'A' + (event - 12); 08797 } 08798 ast_queue_frame(p->owner, &f); 08799 if (sipdebug) 08800 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 08801 } 08802 transmit_response(p, "200 OK", req); 08803 return; 08804 } else if (!strcasecmp(get_header(req, "Content-Type"), "application/media_control+xml")) { 08805 /* Eh, we'll just assume it's a fast picture update for now */ 08806 if (p->owner) 08807 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 08808 transmit_response(p, "200 OK", req); 08809 return; 08810 } else if ((c = get_header(req, "X-ClientCode"))) { 08811 /* Client code (from SNOM phone) */ 08812 if (ast_test_flag(p, SIP_USECLIENTCODE)) { 08813 if (p->owner && p->owner->cdr) 08814 ast_cdr_setuserfield(p->owner, c); 08815 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 08816 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 08817 transmit_response(p, "200 OK", req); 08818 } else { 08819 transmit_response(p, "403 Unauthorized", req); 08820 } 08821 return; 08822 } 08823 /* Other type of INFO message, not really understood by Asterisk */ 08824 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 08825 08826 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 08827 transmit_response(p, "415 Unsupported media type", req); 08828 return; 08829 }
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 | |||
) | [static] |
handle_request_invite: Handle incoming INVITE request
Definition at line 10424 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().
10425 { 10426 int res = 1; 10427 struct ast_channel *c=NULL; 10428 int gotdest; 10429 struct ast_frame af = { AST_FRAME_NULL, }; 10430 char *supported; 10431 char *required; 10432 unsigned int required_profile = 0; 10433 10434 /* Find out what they support */ 10435 if (!p->sipoptions) { 10436 supported = get_header(req, "Supported"); 10437 if (supported) 10438 parse_sip_options(p, supported); 10439 } 10440 required = get_header(req, "Require"); 10441 if (!ast_strlen_zero(required)) { 10442 required_profile = parse_sip_options(NULL, required); 10443 if (required_profile) { /* They require something */ 10444 /* At this point we support no extensions, so fail */ 10445 transmit_response_with_unsupported(p, "420 Bad extension", req, required); 10446 if (!p->lastinvite) 10447 ast_set_flag(p, SIP_NEEDDESTROY); 10448 return -1; 10449 10450 } 10451 } 10452 10453 /* Check if this is a loop */ 10454 /* This happens since we do not properly support SIP domain 10455 handling yet... -oej */ 10456 if (ast_test_flag(p, SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 10457 /* This is a call to ourself. Send ourselves an error code and stop 10458 processing immediately, as SIP really has no good mechanism for 10459 being able to call yourself */ 10460 transmit_response(p, "482 Loop Detected", req); 10461 /* We do NOT destroy p here, so that our response will be accepted */ 10462 return 0; 10463 } 10464 if (!ignore) { 10465 /* Use this as the basis */ 10466 if (debug) 10467 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 10468 sip_cancel_destroy(p); 10469 /* This call is no longer outgoing if it ever was */ 10470 ast_clear_flag(p, SIP_OUTGOING); 10471 /* This also counts as a pending invite */ 10472 p->pendinginvite = seqno; 10473 copy_request(&p->initreq, req); 10474 check_via(p, req); 10475 if (p->owner) { 10476 /* Handle SDP here if we already have an owner */ 10477 if (find_sdp(req)) { 10478 if (process_sdp(p, req)) { 10479 transmit_response(p, "488 Not acceptable here", req); 10480 if (!p->lastinvite) 10481 ast_set_flag(p, SIP_NEEDDESTROY); 10482 return -1; 10483 } 10484 } else { 10485 p->jointcapability = p->capability; 10486 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 10487 } 10488 } 10489 } else if (debug) 10490 ast_verbose("Ignoring this INVITE request\n"); 10491 if (!p->lastinvite && !ignore && !p->owner) { 10492 /* Handle authentication if this is our first invite */ 10493 res = check_user(p, req, SIP_INVITE, e, 1, sin, ignore); 10494 /* if an authentication challenge was sent, we are done here */ 10495 if (res > 0) 10496 return 0; 10497 if (res < 0) { 10498 if (res == -4) { 10499 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 10500 transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1); 10501 } else { 10502 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 10503 if (ignore) 10504 transmit_response(p, "403 Forbidden", req); 10505 else 10506 transmit_response_reliable(p, "403 Forbidden", req, 1); 10507 } 10508 ast_set_flag(p, SIP_NEEDDESTROY); 10509 p->theirtag[0] = '\0'; /* Forget their to-tag, we'll get a new one */ 10510 return 0; 10511 } 10512 /* Process the SDP portion */ 10513 if (find_sdp(req)) { 10514 if (process_sdp(p, req)) { 10515 transmit_response(p, "488 Not acceptable here", req); 10516 ast_set_flag(p, SIP_NEEDDESTROY); 10517 return -1; 10518 } 10519 } else { 10520 p->jointcapability = p->capability; 10521 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 10522 } 10523 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 10524 if (p->owner) 10525 ast_queue_frame(p->owner, &af); 10526 /* Initialize the context if it hasn't been already */ 10527 if (ast_strlen_zero(p->context)) 10528 strcpy(p->context, default_context); 10529 /* Check number of concurrent calls -vs- incoming limit HERE */ 10530 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 10531 res = update_call_counter(p, INC_CALL_LIMIT); 10532 if (res) { 10533 if (res < 0) { 10534 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 10535 if (ignore) 10536 transmit_response(p, "480 Temporarily Unavailable (Call limit)", req); 10537 else 10538 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req, 1); 10539 ast_set_flag(p, SIP_NEEDDESTROY); 10540 } 10541 return 0; 10542 } 10543 /* Get destination right away */ 10544 gotdest = get_destination(p, NULL); 10545 10546 get_rdnis(p, NULL); 10547 extract_uri(p, req); 10548 build_contact(p); 10549 10550 if (gotdest) { 10551 if (gotdest < 0) { 10552 if (ignore) 10553 transmit_response(p, "404 Not Found", req); 10554 else 10555 transmit_response_reliable(p, "404 Not Found", req, 1); 10556 update_call_counter(p, DEC_CALL_LIMIT); 10557 } else { 10558 if (ignore) 10559 transmit_response(p, "484 Address Incomplete", req); 10560 else 10561 transmit_response_reliable(p, "484 Address Incomplete", req, 1); 10562 update_call_counter(p, DEC_CALL_LIMIT); 10563 } 10564 ast_set_flag(p, SIP_NEEDDESTROY); 10565 } else { 10566 /* If no extension was specified, use the s one */ 10567 if (ast_strlen_zero(p->exten)) 10568 ast_copy_string(p->exten, "s", sizeof(p->exten)); 10569 /* Initialize tag */ 10570 make_our_tag(p->tag, sizeof(p->tag)); 10571 /* First invitation */ 10572 c = sip_new(p, AST_STATE_DOWN, ast_strlen_zero(p->username) ? NULL : p->username ); 10573 *recount = 1; 10574 /* Save Record-Route for any later requests we make on this dialogue */ 10575 build_route(p, req, 0); 10576 if (c) { 10577 /* Pre-lock the call */ 10578 ast_mutex_lock(&c->lock); 10579 } 10580 } 10581 10582 } else { 10583 if (option_debug > 1 && sipdebug) 10584 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 10585 c = p->owner; 10586 } 10587 if (!ignore && p) 10588 p->lastinvite = seqno; 10589 if (c) { 10590 #ifdef OSP_SUPPORT 10591 ast_channel_setwhentohangup (c, p->osptimelimit); 10592 #endif 10593 switch(c->_state) { 10594 case AST_STATE_DOWN: 10595 transmit_response(p, "100 Trying", req); 10596 ast_setstate(c, AST_STATE_RING); 10597 if (strcmp(p->exten, ast_pickup_ext())) { 10598 enum ast_pbx_result res; 10599 10600 res = ast_pbx_start(c); 10601 10602 switch (res) { 10603 case AST_PBX_FAILED: 10604 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 10605 if (ignore) 10606 transmit_response(p, "503 Unavailable", req); 10607 else 10608 transmit_response_reliable(p, "503 Unavailable", req, 1); 10609 break; 10610 case AST_PBX_CALL_LIMIT: 10611 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 10612 if (ignore) 10613 transmit_response(p, "480 Temporarily Unavailable", req); 10614 else 10615 transmit_response_reliable(p, "480 Temporarily Unavailable", req, 1); 10616 break; 10617 case AST_PBX_SUCCESS: 10618 /* nothing to do */ 10619 break; 10620 } 10621 10622 if (res) { 10623 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 10624 /* Unlock locks so ast_hangup can do its magic */ 10625 ast_mutex_unlock(&c->lock); 10626 ast_mutex_unlock(&p->lock); 10627 ast_hangup(c); 10628 ast_mutex_lock(&p->lock); 10629 c = NULL; 10630 } 10631 } else { 10632 ast_mutex_unlock(&c->lock); 10633 if (ast_pickup_call(c)) { 10634 ast_log(LOG_NOTICE, "Nothing to pick up\n"); 10635 if (ignore) 10636 transmit_response(p, "503 Unavailable", req); 10637 else 10638 transmit_response_reliable(p, "503 Unavailable", req, 1); 10639 ast_set_flag(p, SIP_ALREADYGONE); 10640 /* Unlock locks so ast_hangup can do its magic */ 10641 ast_mutex_unlock(&p->lock); 10642 ast_hangup(c); 10643 ast_mutex_lock(&p->lock); 10644 c = NULL; 10645 } else { 10646 ast_mutex_unlock(&p->lock); 10647 ast_setstate(c, AST_STATE_DOWN); 10648 ast_hangup(c); 10649 ast_mutex_lock(&p->lock); 10650 c = NULL; 10651 } 10652 } 10653 break; 10654 case AST_STATE_RING: 10655 transmit_response(p, "100 Trying", req); 10656 break; 10657 case AST_STATE_RINGING: 10658 transmit_response(p, "180 Ringing", req); 10659 break; 10660 case AST_STATE_UP: 10661 transmit_response_with_sdp(p, "200 OK", req, 1); 10662 break; 10663 default: 10664 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 10665 transmit_response(p, "100 Trying", req); 10666 } 10667 } else { 10668 if (p && !ast_test_flag(p, SIP_NEEDDESTROY) && !ignore) { 10669 if (!p->jointcapability) { 10670 if (ignore) 10671 transmit_response(p, "488 Not Acceptable Here (codec error)", req); 10672 else 10673 transmit_response_reliable(p, "488 Not Acceptable Here (codec error)", req, 1); 10674 ast_set_flag(p, SIP_NEEDDESTROY); 10675 } else { 10676 ast_log(LOG_NOTICE, "Unable to create/find channel\n"); 10677 if (ignore) 10678 transmit_response(p, "503 Unavailable", req); 10679 else 10680 transmit_response_reliable(p, "503 Unavailable", req, 1); 10681 ast_set_flag(p, SIP_NEEDDESTROY); 10682 } 10683 } 10684 } 10685 return res; 10686 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug, | |||
int | ignore | |||
) | [static] |
handle_request_message: Handle incoming MESSAGE request ---
Definition at line 10844 of file chan_sip.c.
References ast_verbose(), receive_message(), and transmit_response().
Referenced by handle_request().
10845 { 10846 if (!ignore) { 10847 if (debug) 10848 ast_verbose("Receiving message!\n"); 10849 receive_message(p, req); 10850 } else { 10851 transmit_response(p, "202 Accepted", req); 10852 } 10853 return 1; 10854 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug | |||
) | [static] |
handle_request_options: Handle incoming OPTIONS request
Definition at line 10400 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().
10401 { 10402 int res; 10403 10404 res = get_destination(p, req); 10405 build_contact(p); 10406 /* XXX Should we authenticate OPTIONS? XXX */ 10407 if (ast_strlen_zero(p->context)) 10408 strcpy(p->context, default_context); 10409 if (res < 0) 10410 transmit_response_with_allow(p, "404 Not Found", req, 0); 10411 else if (res > 0) 10412 transmit_response_with_allow(p, "484 Address Incomplete", req, 0); 10413 else 10414 transmit_response_with_allow(p, "200 OK", req, 0); 10415 /* Destroy if this OPTIONS was the opening request, but not if 10416 it's in the middle of a normal call flow. */ 10417 if (!p->lastinvite) 10418 ast_set_flag(p, SIP_NEEDDESTROY); 10419 10420 return res; 10421 }
static int handle_request_refer | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug, | |||
int | ignore, | |||
int | seqno, | |||
int * | nounlock | |||
) | [static] |
handle_request_refer: Handle incoming REFER request ---
Definition at line 10689 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().
10690 { 10691 struct ast_channel *c=NULL; 10692 int res; 10693 struct ast_channel *transfer_to; 10694 10695 if (option_debug > 2) 10696 ast_log(LOG_DEBUG, "SIP call transfer received for call %s (REFER)!\n", p->callid); 10697 if (ast_strlen_zero(p->context)) 10698 strcpy(p->context, default_context); 10699 res = get_refer_info(p, req); 10700 if (res < 0) 10701 transmit_response(p, "603 Declined", req); 10702 else if (res > 0) 10703 transmit_response(p, "484 Address Incomplete", req); 10704 else { 10705 int nobye = 0; 10706 if (!ignore) { 10707 if (p->refer_call) { 10708 ast_log(LOG_DEBUG,"202 Accepted (supervised)\n"); 10709 attempt_transfer(p, p->refer_call); 10710 if (p->refer_call->owner) 10711 ast_mutex_unlock(&p->refer_call->owner->lock); 10712 ast_mutex_unlock(&p->refer_call->lock); 10713 p->refer_call = NULL; 10714 ast_set_flag(p, SIP_GOTREFER); 10715 } else { 10716 ast_log(LOG_DEBUG,"202 Accepted (blind)\n"); 10717 c = p->owner; 10718 if (c) { 10719 transfer_to = ast_bridged_channel(c); 10720 if (transfer_to) { 10721 ast_log(LOG_DEBUG, "Got SIP blind transfer, applying to '%s'\n", transfer_to->name); 10722 ast_moh_stop(transfer_to); 10723 if (!strcmp(p->refer_to, ast_parking_ext())) { 10724 /* Must release c's lock now, because it will not longer 10725 be accessible after the transfer! */ 10726 *nounlock = 1; 10727 ast_mutex_unlock(&c->lock); 10728 sip_park(transfer_to, c, req); 10729 nobye = 1; 10730 } else { 10731 /* Must release c's lock now, because it will not longer 10732 be accessible after the transfer! */ 10733 *nounlock = 1; 10734 ast_mutex_unlock(&c->lock); 10735 ast_async_goto(transfer_to,p->context, p->refer_to,1); 10736 } 10737 } else { 10738 ast_log(LOG_DEBUG, "Got SIP blind transfer but nothing to transfer to.\n"); 10739 ast_queue_hangup(p->owner); 10740 } 10741 } 10742 ast_set_flag(p, SIP_GOTREFER); 10743 } 10744 transmit_response(p, "202 Accepted", req); 10745 transmit_notify_with_sipfrag(p, seqno); 10746 /* Always increment on a BYE */ 10747 if (!nobye) { 10748 transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); 10749 ast_set_flag(p, SIP_ALREADYGONE); 10750 } 10751 } 10752 } 10753 return res; 10754 }
static int handle_request_register | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug, | |||
int | ignore, | |||
struct sockaddr_in * | sin, | |||
char * | e | |||
) | [static] |
handle_request_register: Handle incoming REGISTER request ---
Definition at line 11073 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().
11074 { 11075 int res = 0; 11076 char iabuf[INET_ADDRSTRLEN]; 11077 11078 /* Use this as the basis */ 11079 if (debug) 11080 ast_verbose("Using latest REGISTER request as basis request\n"); 11081 copy_request(&p->initreq, req); 11082 check_via(p, req); 11083 if ((res = register_verify(p, sin, req, e, ignore)) < 0) 11084 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")); 11085 if (res < 1) { 11086 /* Destroy the session, but keep us around for just a bit in case they don't 11087 get our 200 OK */ 11088 sip_scheddestroy(p, 15*1000); 11089 } 11090 return res; 11091 }
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 | |||
) | [static] |
handle_request_subscribe: Handle incoming SUBSCRIBE request ---
Definition at line 10856 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().
10857 { 10858 int gotdest; 10859 int res = 0; 10860 int firststate = AST_EXTENSION_REMOVED; 10861 10862 if (p->initreq.headers) { 10863 /* We already have a dialog */ 10864 if (p->initreq.method != SIP_SUBSCRIBE) { 10865 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 10866 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 10867 transmit_response(p, "403 Forbidden (within dialog)", req); 10868 /* Do not destroy session, since we will break the call if we do */ 10869 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); 10870 return 0; 10871 } else { 10872 if (debug) 10873 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 10874 } 10875 } 10876 if (!ignore && !p->initreq.headers) { 10877 /* Use this as the basis */ 10878 if (debug) 10879 ast_verbose("Using latest SUBSCRIBE request as basis request\n"); 10880 /* This call is no longer outgoing if it ever was */ 10881 ast_clear_flag(p, SIP_OUTGOING); 10882 copy_request(&p->initreq, req); 10883 check_via(p, req); 10884 } else if (debug && ignore) 10885 ast_verbose("Ignoring this SUBSCRIBE request\n"); 10886 10887 if (!p->lastinvite) { 10888 char mailboxbuf[256]=""; 10889 int found = 0; 10890 char *mailbox = NULL; 10891 int mailboxsize = 0; 10892 char *eventparam; 10893 10894 char *event = get_header(req, "Event"); /* Get Event package name */ 10895 char *accept = get_header(req, "Accept"); 10896 10897 /* Find parameters to Event: header value and remove them for now */ 10898 eventparam = strchr(event, ';'); 10899 if (eventparam) { 10900 *eventparam = '\0'; 10901 eventparam++; 10902 } 10903 10904 if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) { 10905 mailbox = mailboxbuf; 10906 mailboxsize = sizeof(mailboxbuf); 10907 } 10908 /* Handle authentication if this is our first subscribe */ 10909 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, ignore, mailbox, mailboxsize); 10910 /* if an authentication challenge was sent, we are done here */ 10911 if (res > 0) 10912 return 0; 10913 if (res < 0) { 10914 if (res == -4) { 10915 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 10916 transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1); 10917 } else { 10918 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 10919 if (ignore) 10920 transmit_response(p, "403 Forbidden", req); 10921 else 10922 transmit_response_reliable(p, "403 Forbidden", req, 1); 10923 } 10924 ast_set_flag(p, SIP_NEEDDESTROY); 10925 return 0; 10926 } 10927 gotdest = get_destination(p, NULL); 10928 /* Initialize the context if it hasn't been already; 10929 note this is done _after_ handling any domain lookups, 10930 because the context specified there is for calls, not 10931 subscriptions 10932 */ 10933 if (!ast_strlen_zero(p->subscribecontext)) 10934 ast_copy_string(p->context, p->subscribecontext, sizeof(p->context)); 10935 else if (ast_strlen_zero(p->context)) 10936 strcpy(p->context, default_context); 10937 /* Get destination right away */ 10938 build_contact(p); 10939 if (gotdest) { 10940 if (gotdest < 0) 10941 transmit_response(p, "404 Not Found", req); 10942 else 10943 transmit_response(p, "484 Address Incomplete", req); /* Overlap dialing on SUBSCRIBE?? */ 10944 ast_set_flag(p, SIP_NEEDDESTROY); 10945 } else { 10946 10947 /* Initialize tag for new subscriptions */ 10948 if (ast_strlen_zero(p->tag)) 10949 make_our_tag(p->tag, sizeof(p->tag)); 10950 10951 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 10952 10953 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 10954 if (strstr(accept, "application/pidf+xml")) { 10955 p->subscribed = PIDF_XML; /* RFC 3863 format */ 10956 } else if (strstr(accept, "application/dialog-info+xml")) { 10957 p->subscribed = DIALOG_INFO_XML; 10958 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 10959 } else if (strstr(accept, "application/cpim-pidf+xml")) { 10960 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 10961 } else if (strstr(accept, "application/xpidf+xml")) { 10962 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 10963 } else if (strstr(p->useragent, "Polycom")) { 10964 p->subscribed = XPIDF_XML; /* Polycoms subscribe for "event: dialog" but don't include an "accept:" header */ 10965 } else { 10966 /* Can't find a format for events that we know about */ 10967 transmit_response(p, "489 Bad Event", req); 10968 ast_set_flag(p, SIP_NEEDDESTROY); 10969 return 0; 10970 } 10971 } else if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) { 10972 /* Looks like they actually want a mailbox status */ 10973 10974 /* At this point, we should check if they subscribe to a mailbox that 10975 has the same extension as the peer or the mailbox id. If we configure 10976 the context to be the same as a SIP domain, we could check mailbox 10977 context as well. To be able to securely accept subscribes on mailbox 10978 IDs, not extensions, we need to check the digest auth user to make 10979 sure that the user has access to the mailbox. 10980 10981 Since we do not act on this subscribe anyway, we might as well 10982 accept any authenticated peer with a mailbox definition in their 10983 config section. 10984 10985 */ 10986 if (!ast_strlen_zero(mailbox)) { 10987 found++; 10988 } 10989 10990 if (found){ 10991 transmit_response(p, "200 OK", req); 10992 ast_set_flag(p, SIP_NEEDDESTROY); 10993 } else { 10994 transmit_response(p, "404 Not found", req); 10995 ast_set_flag(p, SIP_NEEDDESTROY); 10996 } 10997 return 0; 10998 } else { /* At this point, Asterisk does not understand the specified event */ 10999 transmit_response(p, "489 Bad Event", req); 11000 if (option_debug > 1) 11001 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 11002 ast_set_flag(p, SIP_NEEDDESTROY); 11003 return 0; 11004 } 11005 if (p->subscribed != NONE) 11006 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 11007 } 11008 } 11009 11010 if (!ignore && p) 11011 p->lastinvite = seqno; 11012 if (p && !ast_test_flag(p, SIP_NEEDDESTROY)) { 11013 p->expiry = atoi(get_header(req, "Expires")); 11014 11015 /* The next 4 lines can be removed if the SNOM Expires bug is fixed */ 11016 if (p->subscribed == DIALOG_INFO_XML) { 11017 if (p->expiry > max_expiry) 11018 p->expiry = max_expiry; 11019 } 11020 if (sipdebug || option_debug > 1) 11021 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 11022 if (p->autokillid > -1) 11023 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 11024 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 11025 11026 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 11027 char iabuf[INET_ADDRSTRLEN]; 11028 11029 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)); 11030 transmit_response(p, "404 Not found", req); 11031 ast_set_flag(p, SIP_NEEDDESTROY); 11032 return 0; 11033 } else { 11034 struct sip_pvt *p_old; 11035 11036 transmit_response(p, "200 OK", req); 11037 transmit_state_notify(p, firststate, 1, 1); /* Send first notification */ 11038 append_history(p, "Subscribestatus", ast_extension_state2str(firststate)); 11039 11040 /* remove any old subscription from this peer for the same exten/context, 11041 as the peer has obviously forgotten about it and it's wasteful to wait 11042 for it to expire and send NOTIFY messages to the peer only to have them 11043 ignored (or generate errors) 11044 */ 11045 ast_mutex_lock(&iflock); 11046 for (p_old = iflist; p_old; p_old = p_old->next) { 11047 if (p_old == p) 11048 continue; 11049 if (p_old->initreq.method != SIP_SUBSCRIBE) 11050 continue; 11051 if (p_old->subscribed == NONE) 11052 continue; 11053 ast_mutex_lock(&p_old->lock); 11054 if (!strcmp(p_old->username, p->username)) { 11055 if (!strcmp(p_old->exten, p->exten) && 11056 !strcmp(p_old->context, p->context)) { 11057 ast_set_flag(p_old, SIP_NEEDDESTROY); 11058 ast_mutex_unlock(&p_old->lock); 11059 break; 11060 } 11061 } 11062 ast_mutex_unlock(&p_old->lock); 11063 } 11064 ast_mutex_unlock(&iflock); 11065 } 11066 if (!p->expiry) 11067 ast_set_flag(p, SIP_NEEDDESTROY); 11068 } 11069 return 1; 11070 }
static void handle_response | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | ignore, | |||
int | seqno | |||
) | [static] |
handle_response: Handle SIP response in dialogue ---
Definition at line 9922 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.
09923 { 09924 char *msg, *c; 09925 struct ast_channel *owner; 09926 char iabuf[INET_ADDRSTRLEN]; 09927 int sipmethod; 09928 int res = 1; 09929 09930 c = get_header(req, "Cseq"); 09931 msg = strchr(c, ' '); 09932 if (!msg) 09933 msg = ""; 09934 else 09935 msg++; 09936 sipmethod = find_sip_method(msg); 09937 09938 owner = p->owner; 09939 if (owner) 09940 owner->hangupcause = hangup_sip2cause(resp); 09941 09942 /* Acknowledge whatever it is destined for */ 09943 if ((resp >= 100) && (resp <= 199)) 09944 __sip_semi_ack(p, seqno, 0, sipmethod); 09945 else 09946 __sip_ack(p, seqno, 0, sipmethod); 09947 09948 /* Get their tag if we haven't already */ 09949 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 09950 gettag(req, "To", p->theirtag, sizeof(p->theirtag)); 09951 } 09952 if (p->peerpoke) { 09953 /* We don't really care what the response is, just that it replied back. 09954 Well, as long as it's not a 100 response... since we might 09955 need to hang around for something more "definitive" */ 09956 09957 res = handle_response_peerpoke(p, resp, rest, req, ignore, seqno, sipmethod); 09958 } else if (ast_test_flag(p, SIP_OUTGOING)) { 09959 /* Acknowledge sequence number */ 09960 if (p->initid > -1) { 09961 /* Don't auto congest anymore since we've gotten something useful back */ 09962 ast_sched_del(sched, p->initid); 09963 p->initid = -1; 09964 } 09965 switch(resp) { 09966 case 100: /* 100 Trying */ 09967 if (sipmethod == SIP_INVITE) 09968 handle_response_invite(p, resp, rest, req, ignore, seqno); 09969 break; 09970 case 183: /* 183 Session Progress */ 09971 if (sipmethod == SIP_INVITE) 09972 handle_response_invite(p, resp, rest, req, ignore, seqno); 09973 break; 09974 case 180: /* 180 Ringing */ 09975 if (sipmethod == SIP_INVITE) 09976 handle_response_invite(p, resp, rest, req, ignore, seqno); 09977 break; 09978 case 200: /* 200 OK */ 09979 p->authtries = 0; /* Reset authentication counter */ 09980 if (sipmethod == SIP_MESSAGE) { 09981 /* We successfully transmitted a message */ 09982 ast_set_flag(p, SIP_NEEDDESTROY); 09983 } else if (sipmethod == SIP_NOTIFY) { 09984 /* They got the notify, this is the end */ 09985 if (p->owner) { 09986 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 09987 ast_queue_hangup(p->owner); 09988 } else { 09989 if (p->subscribed == NONE) { 09990 ast_set_flag(p, SIP_NEEDDESTROY); 09991 } 09992 } 09993 } else if (sipmethod == SIP_INVITE) { 09994 handle_response_invite(p, resp, rest, req, ignore, seqno); 09995 } else if (sipmethod == SIP_REGISTER) { 09996 res = handle_response_register(p, resp, rest, req, ignore, seqno); 09997 } else if (sipmethod == SIP_BYE) { 09998 /* Ok, we're ready to go */ 09999 ast_set_flag(p, SIP_NEEDDESTROY); 10000 } 10001 break; 10002 case 401: /* Not www-authorized on SIP method */ 10003 if (sipmethod == SIP_INVITE) { 10004 handle_response_invite(p, resp, rest, req, ignore, seqno); 10005 } else if (p->registry && sipmethod == SIP_REGISTER) { 10006 res = handle_response_register(p, resp, rest, req, ignore, seqno); 10007 } else { 10008 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 10009 ast_set_flag(p, SIP_NEEDDESTROY); 10010 } 10011 break; 10012 case 403: /* Forbidden - we failed authentication */ 10013 if (sipmethod == SIP_INVITE) { 10014 handle_response_invite(p, resp, rest, req, ignore, seqno); 10015 } else if (p->registry && sipmethod == SIP_REGISTER) { 10016 res = handle_response_register(p, resp, rest, req, ignore, seqno); 10017 } else { 10018 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for %s\n", msg); 10019 } 10020 break; 10021 case 404: /* Not found */ 10022 if (p->registry && sipmethod == SIP_REGISTER) { 10023 res = handle_response_register(p, resp, rest, req, ignore, seqno); 10024 } else if (sipmethod == SIP_INVITE) { 10025 handle_response_invite(p, resp, rest, req, ignore, seqno); 10026 } else if (owner) 10027 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 10028 break; 10029 case 407: /* Proxy auth required */ 10030 if (sipmethod == SIP_INVITE) { 10031 handle_response_invite(p, resp, rest, req, ignore, seqno); 10032 } else if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) { 10033 if (ast_strlen_zero(p->authname)) 10034 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 10035 msg, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); 10036 ast_set_flag(p, SIP_NEEDDESTROY); 10037 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 10038 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 10039 ast_set_flag(p, SIP_NEEDDESTROY); 10040 } 10041 } else if (p->registry && sipmethod == SIP_REGISTER) { 10042 res = handle_response_register(p, resp, rest, req, ignore, seqno); 10043 } else /* We can't handle this, giving up in a bad way */ 10044 ast_set_flag(p, SIP_NEEDDESTROY); 10045 10046 break; 10047 case 491: /* Pending */ 10048 if (sipmethod == SIP_INVITE) { 10049 handle_response_invite(p, resp, rest, req, ignore, seqno); 10050 } 10051 case 501: /* Not Implemented */ 10052 if (sipmethod == SIP_INVITE) { 10053 handle_response_invite(p, resp, rest, req, ignore, seqno); 10054 } else 10055 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), msg); 10056 break; 10057 default: 10058 if ((resp >= 300) && (resp < 700)) { 10059 if ((option_verbose > 2) && (resp != 487)) 10060 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)); 10061 ast_set_flag(p, SIP_ALREADYGONE); 10062 if (p->rtp) { 10063 /* Immediately stop RTP */ 10064 ast_rtp_stop(p->rtp); 10065 } 10066 if (p->vrtp) { 10067 /* Immediately stop VRTP */ 10068 ast_rtp_stop(p->vrtp); 10069 } 10070 /* XXX Locking issues?? XXX */ 10071 switch(resp) { 10072 case 300: /* Multiple Choices */ 10073 case 301: /* Moved permenantly */ 10074 case 302: /* Moved temporarily */ 10075 case 305: /* Use Proxy */ 10076 parse_moved_contact(p, req); 10077 /* Fall through */ 10078 case 486: /* Busy here */ 10079 case 600: /* Busy everywhere */ 10080 case 603: /* Decline */ 10081 if (p->owner) 10082 ast_queue_control(p->owner, AST_CONTROL_BUSY); 10083 break; 10084 case 487: 10085 /* channel now destroyed - dec the inUse counter */ 10086 if (owner) 10087 ast_queue_hangup(p->owner); 10088 update_call_counter(p, DEC_CALL_LIMIT); 10089 break; 10090 case 482: /* SIP is incapable of performing a hairpin call, which 10091 is yet another failure of not having a layer 2 (again, YAY 10092 IETF for thinking ahead). So we treat this as a call 10093 forward and hope we end up at the right place... */ 10094 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 10095 if (p->owner) 10096 snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "Local/%s@%s", p->username, p->context); 10097 /* Fall through */ 10098 case 488: /* Not acceptable here - codec error */ 10099 case 480: /* Temporarily Unavailable */ 10100 case 404: /* Not Found */ 10101 case 410: /* Gone */ 10102 case 400: /* Bad Request */ 10103 case 500: /* Server error */ 10104 case 503: /* Service Unavailable */ 10105 if (owner) 10106 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 10107 break; 10108 default: 10109 /* Send hangup */ 10110 if (owner) 10111 ast_queue_hangup(p->owner); 10112 break; 10113 } 10114 /* ACK on invite */ 10115 if (sipmethod == SIP_INVITE) 10116 transmit_request(p, SIP_ACK, seqno, 0, 0); 10117 ast_set_flag(p, SIP_ALREADYGONE); 10118 if (!p->owner) 10119 ast_set_flag(p, SIP_NEEDDESTROY); 10120 } else if ((resp >= 100) && (resp < 200)) { 10121 if (sipmethod == SIP_INVITE) { 10122 if (!ignore) 10123 sip_cancel_destroy(p); 10124 if (find_sdp(req)) 10125 process_sdp(p, req); 10126 if (p->owner) { 10127 /* Queue a progress frame */ 10128 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 10129 } 10130 } 10131 } else 10132 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)); 10133 } 10134 } else { 10135 /* Responses to OUTGOING SIP requests on INCOMING calls 10136 get handled here. As well as out-of-call message responses */ 10137 if (req->debug) 10138 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 10139 if (resp == 200) { 10140 /* Tags in early session is replaced by the tag in 200 OK, which is 10141 the final reply to our INVITE */ 10142 gettag(req, "To", p->theirtag, sizeof(p->theirtag)); 10143 } 10144 10145 switch(resp) { 10146 case 200: 10147 if (sipmethod == SIP_INVITE) { 10148 handle_response_invite(p, resp, rest, req, ignore, seqno); 10149 } else if (sipmethod == SIP_CANCEL) { 10150 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 10151 } else if (sipmethod == SIP_MESSAGE) 10152 /* We successfully transmitted a message */ 10153 ast_set_flag(p, SIP_NEEDDESTROY); 10154 else if (sipmethod == SIP_BYE) 10155 /* Ok, we're ready to go */ 10156 ast_set_flag(p, SIP_NEEDDESTROY); 10157 break; 10158 case 401: /* www-auth */ 10159 case 407: 10160 if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) { 10161 char *auth, *auth2; 10162 10163 if (resp == 407) { 10164 auth = "Proxy-Authenticate"; 10165 auth2 = "Proxy-Authorization"; 10166 } else { 10167 auth = "WWW-Authenticate"; 10168 auth2 = "Authorization"; 10169 } 10170 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 10171 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 10172 ast_set_flag(p, SIP_NEEDDESTROY); 10173 } 10174 } else if (sipmethod == SIP_INVITE) { 10175 handle_response_invite(p, resp, rest, req, ignore, seqno); 10176 } 10177 break; 10178 case 481: /* Call leg does not exist */ 10179 if (sipmethod == SIP_INVITE) { 10180 /* Re-invite failed */ 10181 handle_response_invite(p, resp, rest, req, ignore, seqno); 10182 } 10183 break; 10184 default: /* Errors without handlers */ 10185 if ((resp >= 100) && (resp < 200)) { 10186 if (sipmethod == SIP_INVITE && !ignore) /* re-invite */ 10187 sip_cancel_destroy(p); 10188 10189 } 10190 if ((resp >= 300) && (resp < 700)) { 10191 if ((option_verbose > 2) && (resp != 487)) 10192 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)); 10193 switch(resp) { 10194 case 488: /* Not acceptable here - codec error */ 10195 case 603: /* Decline */ 10196 case 500: /* Server error */ 10197 case 503: /* Service Unavailable */ 10198 10199 if (sipmethod == SIP_INVITE && !ignore) { /* re-invite failed */ 10200 sip_cancel_destroy(p); 10201 } 10202 break; 10203 } 10204 } 10205 break; 10206 } 10207 } 10208 }
static void handle_response_invite | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | ignore, | |||
int | seqno | |||
) | [static] |
handle_response_invite: Handle SIP response in dialogue ---
Definition at line 9592 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().
09593 { 09594 int outgoing = ast_test_flag(p, SIP_OUTGOING); 09595 09596 if (option_debug > 3) { 09597 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 09598 if (reinvite) 09599 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 09600 else 09601 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 09602 } 09603 09604 if (ast_test_flag(p, SIP_ALREADYGONE)) { /* This call is already gone */ 09605 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 09606 return; 09607 } 09608 09609 /* RFC3261 says we must treat every 1xx response (but not 100) 09610 that we don't recognize as if it was 183. 09611 */ 09612 if ((resp > 100) && 09613 (resp < 200) && 09614 (resp != 180) && 09615 (resp != 183)) 09616 resp = 183; 09617 09618 switch (resp) { 09619 case 100: /* Trying */ 09620 if (!ignore) 09621 sip_cancel_destroy(p); 09622 check_pendings(p); 09623 break; 09624 case 180: /* 180 Ringing */ 09625 if (!ignore) 09626 sip_cancel_destroy(p); 09627 if (!ignore && p->owner) { 09628 ast_queue_control(p->owner, AST_CONTROL_RINGING); 09629 if (p->owner->_state != AST_STATE_UP) 09630 ast_setstate(p->owner, AST_STATE_RINGING); 09631 } 09632 if (find_sdp(req)) { 09633 process_sdp(p, req); 09634 if (!ignore && p->owner) { 09635 /* Queue a progress frame only if we have SDP in 180 */ 09636 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 09637 } 09638 } 09639 ast_set_flag(p, SIP_CAN_BYE); 09640 check_pendings(p); 09641 break; 09642 case 183: /* Session progress */ 09643 if (!ignore) 09644 sip_cancel_destroy(p); 09645 /* Ignore 183 Session progress without SDP */ 09646 if (find_sdp(req)) { 09647 process_sdp(p, req); 09648 if (!ignore && p->owner) { 09649 /* Queue a progress frame */ 09650 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 09651 } 09652 } 09653 ast_set_flag(p, SIP_CAN_BYE); 09654 check_pendings(p); 09655 break; 09656 case 200: /* 200 OK on invite - someone's answering our call */ 09657 if (!ignore) 09658 sip_cancel_destroy(p); 09659 p->authtries = 0; 09660 if (find_sdp(req)) { 09661 process_sdp(p, req); 09662 } 09663 09664 /* Parse contact header for continued conversation */ 09665 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 09666 /* This is important when we have a SIP proxy between us and the phone */ 09667 if (outgoing) { 09668 parse_ok_contact(p, req); 09669 09670 /* Save Record-Route for any later requests we make on this dialogue */ 09671 build_route(p, req, 1); 09672 } 09673 09674 if (!ignore && p->owner) { 09675 if (p->owner->_state != AST_STATE_UP) { 09676 #ifdef OSP_SUPPORT 09677 time(&p->ospstart); 09678 #endif 09679 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 09680 } else { /* RE-invite */ 09681 struct ast_frame af = { AST_FRAME_NULL, }; 09682 ast_queue_frame(p->owner, &af); 09683 } 09684 } else { 09685 /* It's possible we're getting an ACK after we've tried to disconnect 09686 by sending CANCEL */ 09687 /* THIS NEEDS TO BE CHECKED: OEJ */ 09688 if (!ignore) 09689 ast_set_flag(p, SIP_PENDINGBYE); 09690 } 09691 /* If I understand this right, the branch is different for a non-200 ACK only */ 09692 transmit_request(p, SIP_ACK, seqno, 0, 1); 09693 ast_set_flag(p, SIP_CAN_BYE); 09694 check_pendings(p); 09695 break; 09696 case 407: /* Proxy authentication */ 09697 case 401: /* Www auth */ 09698 /* First we ACK */ 09699 transmit_request(p, SIP_ACK, seqno, 0, 0); 09700 if (p->options) 09701 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 09702 09703 /* Then we AUTH */ 09704 p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */ 09705 if (!ignore) { 09706 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 09707 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 09708 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 09709 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 09710 ast_set_flag(p, SIP_NEEDDESTROY); 09711 ast_set_flag(p, SIP_ALREADYGONE); 09712 if (p->owner) 09713 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09714 } 09715 } 09716 break; 09717 case 403: /* Forbidden */ 09718 /* First we ACK */ 09719 transmit_request(p, SIP_ACK, seqno, 0, 0); 09720 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for INVITE to '%s'\n", get_header(&p->initreq, "From")); 09721 if (!ignore && p->owner) 09722 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09723 ast_set_flag(p, SIP_NEEDDESTROY); 09724 ast_set_flag(p, SIP_ALREADYGONE); 09725 break; 09726 case 404: /* Not found */ 09727 transmit_request(p, SIP_ACK, seqno, 0, 0); 09728 if (p->owner && !ignore) 09729 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09730 ast_set_flag(p, SIP_ALREADYGONE); 09731 break; 09732 case 481: /* Call leg does not exist */ 09733 /* Could be REFER or INVITE */ 09734 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 09735 transmit_request(p, SIP_ACK, seqno, 0, 0); 09736 break; 09737 case 491: /* Pending */ 09738 /* we have to wait a while, then retransmit */ 09739 /* Transmission is rescheduled, so everything should be taken care of. 09740 We should support the retry-after at some point */ 09741 break; 09742 case 501: /* Not implemented */ 09743 if (p->owner) 09744 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 09745 break; 09746 } 09747 }
static int handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | ignore, | |||
int | seqno, | |||
int | sipmethod | |||
) | [static] |
handle_response_peerpoke: Handle qualification responses (OPTIONS)
Definition at line 9866 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().
09867 { 09868 struct sip_peer *peer; 09869 int pingtime; 09870 struct timeval tv; 09871 09872 if (resp != 100) { 09873 int statechanged = 0; 09874 int newstate = 0; 09875 peer = p->peerpoke; 09876 gettimeofday(&tv, NULL); 09877 pingtime = ast_tvdiff_ms(tv, peer->ps); 09878 if (pingtime < 1) 09879 pingtime = 1; 09880 if ((peer->lastms < 0) || (peer->lastms > peer->maxms)) { 09881 if (pingtime <= peer->maxms) { 09882 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! (%dms / %dms)\n", peer->name, pingtime, peer->maxms); 09883 statechanged = 1; 09884 newstate = 1; 09885 } 09886 } else if ((peer->lastms > 0) && (peer->lastms <= peer->maxms)) { 09887 if (pingtime > peer->maxms) { 09888 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED! (%dms / %dms)\n", peer->name, pingtime, peer->maxms); 09889 statechanged = 1; 09890 newstate = 2; 09891 } 09892 } 09893 if (!peer->lastms) 09894 statechanged = 1; 09895 peer->lastms = pingtime; 09896 peer->call = NULL; 09897 if (statechanged) { 09898 ast_device_state_changed("SIP/%s", peer->name); 09899 if (newstate == 2) { 09900 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, pingtime); 09901 } else { 09902 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, pingtime); 09903 } 09904 } 09905 09906 if (peer->pokeexpire > -1) 09907 ast_sched_del(sched, peer->pokeexpire); 09908 if (sipmethod == SIP_INVITE) /* Does this really happen? */ 09909 transmit_request(p, SIP_ACK, seqno, 0, 0); 09910 ast_set_flag(p, SIP_NEEDDESTROY); 09911 09912 /* Try again eventually */ 09913 if ((peer->lastms < 0) || (peer->lastms > peer->maxms)) 09914 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 09915 else 09916 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_OK, sip_poke_peer_s, peer); 09917 } 09918 return 1; 09919 }
static int handle_response_register | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | ignore, | |||
int | seqno | |||
) | [static] |
handle_response_register: Handle responses on REGISTER to services ---
Definition at line 9750 of file chan_sip.c.
References __get_header(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_strlen_zero(), ASTOBJ_UNREF, sip_pvt::authtries, sip_registry::call, sip_registry::contact, default_expiry, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, EXPIRY_GUARD_LIMIT, EXPIRY_GUARD_MIN, EXPIRY_GUARD_PCT, EXPIRY_GUARD_SECS, get_header(), global_regattempts_max, sip_registry::hostname, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), MAX, MAX_AUTHTRIES, sip_pvt::our_contact, sip_registry::refresh, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, strcasestr(), sip_registry::timeout, and sip_registry::username.
Referenced by handle_response().
09751 { 09752 int expires, expires_ms; 09753 struct sip_registry *r; 09754 r=p->registry; 09755 09756 switch (resp) { 09757 case 401: /* Unauthorized */ 09758 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 09759 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 09760 ast_set_flag(p, SIP_NEEDDESTROY); 09761 } 09762 break; 09763 case 403: /* Forbidden */ 09764 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 09765 if (global_regattempts_max) 09766 p->registry->regattempts = global_regattempts_max+1; 09767 ast_sched_del(sched, r->timeout); 09768 ast_set_flag(p, SIP_NEEDDESTROY); 09769 break; 09770 case 404: /* Not found */ 09771 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 09772 if (global_regattempts_max) 09773 p->registry->regattempts = global_regattempts_max+1; 09774 ast_set_flag(p, SIP_NEEDDESTROY); 09775 r->call = NULL; 09776 ast_sched_del(sched, r->timeout); 09777 break; 09778 case 407: /* Proxy auth */ 09779 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 09780 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 09781 ast_set_flag(p, SIP_NEEDDESTROY); 09782 } 09783 break; 09784 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 09785 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 09786 if (global_regattempts_max) 09787 p->registry->regattempts = global_regattempts_max+1; 09788 ast_set_flag(p, SIP_NEEDDESTROY); 09789 r->call = NULL; 09790 ast_sched_del(sched, r->timeout); 09791 break; 09792 case 200: /* 200 OK */ 09793 if (!r) { 09794 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 09795 ast_set_flag(p, SIP_NEEDDESTROY); 09796 return 0; 09797 } 09798 09799 r->regstate=REG_STATE_REGISTERED; 09800 manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 09801 r->regattempts = 0; 09802 ast_log(LOG_DEBUG, "Registration successful\n"); 09803 if (r->timeout > -1) { 09804 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 09805 ast_sched_del(sched, r->timeout); 09806 } 09807 r->timeout=-1; 09808 r->call = NULL; 09809 p->registry = NULL; 09810 /* Let this one hang around until we have all the responses */ 09811 sip_scheddestroy(p, 32000); 09812 /* ast_set_flag(p, SIP_NEEDDESTROY); */ 09813 09814 /* set us up for re-registering */ 09815 /* figure out how long we got registered for */ 09816 if (r->expire > -1) 09817 ast_sched_del(sched, r->expire); 09818 /* according to section 6.13 of RFC, contact headers override 09819 expires headers, so check those first */ 09820 expires = 0; 09821 if (!ast_strlen_zero(get_header(req, "Contact"))) { 09822 char *contact = NULL; 09823 char *tmptmp = NULL; 09824 int start = 0; 09825 for(;;) { 09826 contact = __get_header(req, "Contact", &start); 09827 /* this loop ensures we get a contact header about our register request */ 09828 if(!ast_strlen_zero(contact)) { 09829 if( (tmptmp=strstr(contact, p->our_contact))) { 09830 contact=tmptmp; 09831 break; 09832 } 09833 } else 09834 break; 09835 } 09836 tmptmp = strcasestr(contact, "expires="); 09837 if (tmptmp) { 09838 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 09839 expires = 0; 09840 } 09841 09842 } 09843 if (!expires) 09844 expires=atoi(get_header(req, "expires")); 09845 if (!expires) 09846 expires=default_expiry; 09847 09848 expires_ms = expires * 1000; 09849 if (expires <= EXPIRY_GUARD_LIMIT) 09850 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 09851 else 09852 expires_ms -= EXPIRY_GUARD_SECS * 1000; 09853 if (sipdebug) 09854 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 09855 09856 r->refresh= (int) expires_ms / 1000; 09857 09858 /* Schedule re-registration before we expire */ 09859 r->expire=ast_sched_add(sched, expires_ms, sip_reregister, r); 09860 ASTOBJ_UNREF(r, sip_registry_destroy); 09861 } 09862 return 1; 09863 }
static char* hangup_cause2sip | ( | int | cause | ) | [static] |
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 2364 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().
02365 { 02366 switch(cause) 02367 { 02368 case AST_CAUSE_UNALLOCATED: /* 1 */ 02369 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 02370 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 02371 return "404 Not Found"; 02372 case AST_CAUSE_CONGESTION: /* 34 */ 02373 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 02374 return "503 Service Unavailable"; 02375 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 02376 return "408 Request Timeout"; 02377 case AST_CAUSE_NO_ANSWER: /* 19 */ 02378 return "480 Temporarily unavailable"; 02379 case AST_CAUSE_CALL_REJECTED: /* 21 */ 02380 return "403 Forbidden"; 02381 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 02382 return "410 Gone"; 02383 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 02384 return "480 Temporarily unavailable"; 02385 case AST_CAUSE_INVALID_NUMBER_FORMAT: 02386 return "484 Address incomplete"; 02387 case AST_CAUSE_USER_BUSY: 02388 return "486 Busy here"; 02389 case AST_CAUSE_FAILURE: 02390 return "500 Server internal failure"; 02391 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 02392 return "501 Not Implemented"; 02393 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 02394 return "503 Service Unavailable"; 02395 /* Used in chan_iax2 */ 02396 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 02397 return "502 Bad Gateway"; 02398 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 02399 return "488 Not Acceptable Here"; 02400 02401 case AST_CAUSE_NOTDEFINED: 02402 default: 02403 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 02404 return NULL; 02405 } 02406 02407 /* Never reached */ 02408 return 0; 02409 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
hangup_sip2cause: Convert SIP hangup causes to Asterisk hangup causes ---
Definition at line 2295 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().
02296 { 02297 /* Possible values taken from causes.h */ 02298 02299 switch(cause) { 02300 case 603: /* Declined */ 02301 case 403: /* Not found */ 02302 case 487: /* Call cancelled */ 02303 return AST_CAUSE_CALL_REJECTED; 02304 case 404: /* Not found */ 02305 return AST_CAUSE_UNALLOCATED; 02306 case 408: /* No reaction */ 02307 return AST_CAUSE_NO_USER_RESPONSE; 02308 case 480: /* No answer */ 02309 return AST_CAUSE_FAILURE; 02310 case 483: /* Too many hops */ 02311 return AST_CAUSE_NO_ANSWER; 02312 case 486: /* Busy everywhere */ 02313 return AST_CAUSE_BUSY; 02314 case 488: /* No codecs approved */ 02315 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 02316 case 500: /* Server internal failure */ 02317 return AST_CAUSE_FAILURE; 02318 case 501: /* Call rejected */ 02319 return AST_CAUSE_FACILITY_REJECTED; 02320 case 502: 02321 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 02322 case 503: /* Service unavailable */ 02323 return AST_CAUSE_CONGESTION; 02324 default: 02325 return AST_CAUSE_NORMAL; 02326 } 02327 /* Never reached */ 02328 return 0; 02329 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
char * | recip | |||
) | [static] |
init_req: Initialize SIP request ---
Definition at line 4063 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.
04064 { 04065 /* Initialize a response */ 04066 if (req->headers || req->len) { 04067 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 04068 return -1; 04069 } 04070 req->header[req->headers] = req->data + req->len; 04071 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 04072 req->len += strlen(req->header[req->headers]); 04073 req->headers++; 04074 req->method = sipmethod; 04075 return 0; 04076 }
static int init_resp | ( | struct sip_request * | req, | |
char * | resp, | |||
struct sip_request * | orig | |||
) | [static] |
init_resp: Initialize SIP response, based on SIP request ---
Definition at line 4047 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.
04048 { 04049 /* Initialize a response */ 04050 if (req->headers || req->len) { 04051 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 04052 return -1; 04053 } 04054 req->method = SIP_RESPONSE; 04055 req->header[req->headers] = req->data + req->len; 04056 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "SIP/2.0 %s\r\n", resp); 04057 req->len += strlen(req->header[req->headers]); 04058 req->headers++; 04059 return 0; 04060 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
initreqprep: Initiate new SIP request to peer/user ---
Definition at line 4821 of file chan_sip.c.
References add_header(), ast_build_string(), AST_DIGIT_ANYNUM, ast_inet_ntoa(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), build_rpid(), CALLERID_UNKNOWN, sip_pvt::callid, sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, default_callerid, DEFAULT_MAX_FORWARDS, default_useragent, sip_pvt::exten, sip_pvt::fromdomain, sip_pvt::fromname, sip_pvt::fromuser, sip_pvt::fullcontact, init_req(), sip_pvt::lastmsg, n, sip_pvt::ocseq, sip_pvt::options, sip_pvt::our_contact, sip_pvt::ourip, ourport, sip_pvt::owner, pedanticsipchecking, sip_pvt::rpid, sip_pvt::sa, SIP_INVITE, sip_methods, SIP_NOTIFY, SIP_SENDRPID, SIP_USEREQPHONE, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, sip_pvt::tohost, sip_pvt::uri, sip_invite_param::uri_options, sip_pvt::username, sip_pvt::via, and sip_invite_param::vxml_url.
Referenced by sip_notify(), transmit_invite(), and transmit_notify_with_mwi().
04822 { 04823 char invite_buf[256] = ""; 04824 char *invite = invite_buf; 04825 size_t invite_max = sizeof(invite_buf); 04826 char from[256]; 04827 char to[256]; 04828 char tmp[BUFSIZ/2]; 04829 char tmp2[BUFSIZ/2]; 04830 char iabuf[INET_ADDRSTRLEN]; 04831 char *l = NULL, *n = NULL; 04832 int x; 04833 char urioptions[256]=""; 04834 04835 if (ast_test_flag(p, SIP_USEREQPHONE)) { 04836 char onlydigits = 1; 04837 x=0; 04838 04839 /* Test p->username against allowed characters in AST_DIGIT_ANY 04840 If it matches the allowed characters list, then sipuser = ";user=phone" 04841 If not, then sipuser = "" 04842 */ 04843 /* + is allowed in first position in a tel: uri */ 04844 if (p->username && p->username[0] == '+') 04845 x=1; 04846 04847 for (; x < strlen(p->username); x++) { 04848 if (!strchr(AST_DIGIT_ANYNUM, p->username[x])) { 04849 onlydigits = 0; 04850 break; 04851 } 04852 } 04853 04854 /* If we have only digits, add ;user=phone to the uri */ 04855 if (onlydigits) 04856 strcpy(urioptions, ";user=phone"); 04857 } 04858 04859 04860 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 04861 04862 if (p->owner) { 04863 l = p->owner->cid.cid_num; 04864 n = p->owner->cid.cid_name; 04865 } 04866 /* if we are not sending RPID and user wants his callerid restricted */ 04867 if (!ast_test_flag(p, SIP_SENDRPID) && ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 04868 l = CALLERID_UNKNOWN; 04869 n = l; 04870 } 04871 if (ast_strlen_zero(l)) 04872 l = default_callerid; 04873 if (ast_strlen_zero(n)) 04874 n = l; 04875 /* Allow user to be overridden */ 04876 if (!ast_strlen_zero(p->fromuser)) 04877 l = p->fromuser; 04878 else /* Save for any further attempts */ 04879 ast_copy_string(p->fromuser, l, sizeof(p->fromuser)); 04880 04881 /* Allow user to be overridden */ 04882 if (!ast_strlen_zero(p->fromname)) 04883 n = p->fromname; 04884 else /* Save for any further attempts */ 04885 ast_copy_string(p->fromname, n, sizeof(p->fromname)); 04886 04887 if (pedanticsipchecking) { 04888 ast_uri_encode(n, tmp, sizeof(tmp), 0); 04889 n = tmp; 04890 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 04891 l = tmp2; 04892 } 04893 04894 if ((ourport != 5060) && ast_strlen_zero(p->fromdomain)) /* Needs to be 5060 */ 04895 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); 04896 else 04897 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); 04898 04899 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 04900 if (!ast_strlen_zero(p->fullcontact)) { 04901 /* If we have full contact, trust it */ 04902 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 04903 } else { 04904 /* Otherwise, use the username while waiting for registration */ 04905 ast_build_string(&invite, &invite_max, "sip:"); 04906 if (!ast_strlen_zero(p->username)) { 04907 n = p->username; 04908 if (pedanticsipchecking) { 04909 ast_uri_encode(n, tmp, sizeof(tmp), 0); 04910 n = tmp; 04911 } 04912 ast_build_string(&invite, &invite_max, "%s@", n); 04913 } 04914 ast_build_string(&invite, &invite_max, "%s", p->tohost); 04915 if (ntohs(p->sa.sin_port) != 5060) /* Needs to be 5060 */ 04916 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 04917 ast_build_string(&invite, &invite_max, "%s", urioptions); 04918 } 04919 04920 /* If custom URI options have been provided, append them */ 04921 if (p->options && p->options->uri_options) 04922 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 04923 04924 ast_copy_string(p->uri, invite_buf, sizeof(p->uri)); 04925 04926 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 04927 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 04928 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag); 04929 } else if (p->options && p->options->vxml_url) { 04930 /* If there is a VXML URL append it to the SIP URL */ 04931 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 04932 } else { 04933 snprintf(to, sizeof(to), "<%s>", p->uri); 04934 } 04935 04936 memset(req, 0, sizeof(struct sip_request)); 04937 init_req(req, sipmethod, p->uri); 04938 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 04939 04940 add_header(req, "Via", p->via); 04941 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 04942 * OTOH, then we won't have anything in p->route anyway */ 04943 /* Build Remote Party-ID and From */ 04944 if (ast_test_flag(p, SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 04945 build_rpid(p); 04946 add_header(req, "From", p->rpid_from); 04947 } else { 04948 add_header(req, "From", from); 04949 } 04950 add_header(req, "To", to); 04951 ast_copy_string(p->exten, l, sizeof(p->exten)); 04952 build_contact(p); 04953 add_header(req, "Contact", p->our_contact); 04954 add_header(req, "Call-ID", p->callid); 04955 add_header(req, "CSeq", tmp); 04956 add_header(req, "User-Agent", default_useragent); 04957 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 04958 if (p->rpid) 04959 add_header(req, "Remote-Party-ID", p->rpid); 04960 }
static const char* insecure2str | ( | int | port, | |
int | invite | |||
) | [static] |
insecure2str: Convert Insecure setting to printable string ---
Definition at line 7769 of file chan_sip.c.
Referenced by _sip_show_peer().
07770 { 07771 if (port && invite) 07772 return "port,invite"; 07773 else if (port) 07774 return "port"; 07775 else if (invite) 07776 return "invite"; 07777 else 07778 return "no"; 07779 }
char* key | ( | void | ) |
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 13525 of file chan_sip.c.
References ASTERISK_GPL_KEY.
13526 { 13527 return ASTERISK_GPL_KEY; 13528 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
list_route: List all routes - mostly for debugging ---
Definition at line 6073 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
06074 { 06075 if (!route) { 06076 ast_verbose("list_route: no route\n"); 06077 return; 06078 } 06079 while (route) { 06080 ast_verbose("list_route: hop: <%s>\n", route->hop); 06081 route = route->next; 06082 } 06083 }
int load_module | ( | void | ) |
Initialize the module.
Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 13373 of file chan_sip.c.
References ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register(), ast_log(), ast_manager_register2(), ast_register_application(), ast_rtp_proto_register(), ASTOBJ_CONTAINER_INIT, channeltype, checksipdomain_function, EVENT_FLAG_SYSTEM, io, io_context_create(), LOG_ERROR, LOG_WARNING, manager_sip_show_peer(), manager_sip_show_peers(), mandescr_show_peer, my_clis, peerl, regl, reload_config(), restart_monitor(), sched_context_create(), sip_addheader(), sip_dtmfmode(), sip_getheader(), sip_header_function, sip_poke_all_peers(), sip_rtp, sip_send_all_registers(), sip_tech, sipchaninfo_function, sippeer_function, and userl.
13374 { 13375 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 13376 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 13377 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 13378 13379 sched = sched_context_create(); 13380 if (!sched) { 13381 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 13382 } 13383 13384 io = io_context_create(); 13385 if (!io) { 13386 ast_log(LOG_WARNING, "Unable to create I/O context\n"); 13387 } 13388 13389 reload_config(); /* Load the configuration from sip.conf */ 13390 13391 /* Make sure we can register our sip channel type */ 13392 if (ast_channel_register(&sip_tech)) { 13393 ast_log(LOG_ERROR, "Unable to register channel type %s\n", channeltype); 13394 return -1; 13395 } 13396 13397 /* Register all CLI functions for SIP */ 13398 ast_cli_register_multiple(my_clis, sizeof(my_clis)/ sizeof(my_clis[0])); 13399 13400 /* Tell the RTP subdriver that we're here */ 13401 ast_rtp_proto_register(&sip_rtp); 13402 13403 /* Register dialplan applications */ 13404 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 13405 13406 /* These will be removed soon */ 13407 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 13408 ast_register_application(app_sipgetheader, sip_getheader, synopsis_sipgetheader, descrip_sipgetheader); 13409 13410 /* Register dialplan functions */ 13411 ast_custom_function_register(&sip_header_function); 13412 ast_custom_function_register(&sippeer_function); 13413 ast_custom_function_register(&sipchaninfo_function); 13414 ast_custom_function_register(&checksipdomain_function); 13415 13416 /* Register manager commands */ 13417 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 13418 "List SIP peers (text format)", mandescr_show_peers); 13419 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 13420 "Show SIP peer (text format)", mandescr_show_peer); 13421 13422 sip_poke_all_peers(); 13423 sip_send_all_registers(); 13424 13425 /* And start the monitor for the first time */ 13426 restart_monitor(); 13427 13428 return 0; 13429 }
static int lws2sws | ( | char * | msgbuf, | |
int | len | |||
) | [static] |
lws2sws: Parse multiline SIP headers into one header
Definition at line 3321 of file chan_sip.c.
References t.
Referenced by sipsock_read().
03322 { 03323 int h = 0, t = 0; 03324 int lws = 0; 03325 03326 for (; h < len;) { 03327 /* Eliminate all CRs */ 03328 if (msgbuf[h] == '\r') { 03329 h++; 03330 continue; 03331 } 03332 /* Check for end-of-line */ 03333 if (msgbuf[h] == '\n') { 03334 /* Check for end-of-message */ 03335 if (h + 1 == len) 03336 break; 03337 /* Check for a continuation line */ 03338 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 03339 /* Merge continuation line */ 03340 h++; 03341 continue; 03342 } 03343 /* Propagate LF and start new line */ 03344 msgbuf[t++] = msgbuf[h++]; 03345 lws = 0; 03346 continue; 03347 } 03348 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 03349 if (lws) { 03350 h++; 03351 continue; 03352 } 03353 msgbuf[t++] = msgbuf[h++]; 03354 lws = 1; 03355 continue; 03356 } 03357 msgbuf[t++] = msgbuf[h++]; 03358 if (lws) 03359 lws = 0; 03360 } 03361 msgbuf[t] = '\0'; 03362 return t; 03363 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Definition at line 3073 of file chan_sip.c.
References thread_safe_rand().
Referenced by handle_request_invite(), handle_request_subscribe(), sip_alloc(), and transmit_register().
03074 { 03075 snprintf(tagbuf, len, "as%08x", thread_safe_rand()); 03076 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
struct message * | m | |||
) | [static] |
manager_sip_show_peer: Show SIP peers in the manager API ---
Definition at line 7989 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().
07990 { 07991 char *id = astman_get_header(m,"ActionID"); 07992 char *a[4]; 07993 char *peer; 07994 int ret; 07995 07996 peer = astman_get_header(m,"Peer"); 07997 if (ast_strlen_zero(peer)) { 07998 astman_send_error(s, m, "Peer: <name> missing.\n"); 07999 return 0; 08000 } 08001 a[0] = "sip"; 08002 a[1] = "show"; 08003 a[2] = "peer"; 08004 a[3] = peer; 08005 08006 if (!ast_strlen_zero(id)) 08007 ast_cli(s->fd, "ActionID: %s\r\n",id); 08008 ret = _sip_show_peer(1, s->fd, s, m, 4, a ); 08009 ast_cli( s->fd, "\r\n\r\n" ); 08010 return ret; 08011 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
struct message * | m | |||
) | [static] |
manager_sip_show_peers: Show SIP peers in the manager API ---
Definition at line 7570 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().
07571 { 07572 char *id = astman_get_header(m,"ActionID"); 07573 char *a[] = { "sip", "show", "peers" }; 07574 char idtext[256] = ""; 07575 int total = 0; 07576 07577 if (!ast_strlen_zero(id)) 07578 snprintf(idtext,256,"ActionID: %s\r\n",id); 07579 07580 astman_send_ack(s, m, "Peer status list will follow"); 07581 /* List the peers in separate manager events */ 07582 _sip_show_peers(s->fd, &total, s, m, 3, a); 07583 /* Send final confirmation */ 07584 ast_cli(s->fd, 07585 "Event: PeerlistComplete\r\n" 07586 "ListItems: %d\r\n" 07587 "%s" 07588 "\r\n", total, idtext); 07589 return 0; 07590 }
static char* nat2str | ( | int | nat | ) | [static] |
nat2str: Convert NAT setting to text string
Definition at line 7472 of file chan_sip.c.
References SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, and SIP_NAT_ROUTE.
Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_users().
07473 { 07474 switch(nat) { 07475 case SIP_NAT_NEVER: 07476 return "No"; 07477 case SIP_NAT_ROUTE: 07478 return "Route"; 07479 case SIP_NAT_ALWAYS: 07480 return "Always"; 07481 case SIP_NAT_RFC3581: 07482 return "RFC3581"; 07483 default: 07484 return "Unknown"; 07485 } 07486 }
static void parse_copy | ( | struct sip_request * | dst, | |
struct sip_request * | src | |||
) | [static] |
parse_copy: Copy SIP request, parse it
Definition at line 1472 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
01473 { 01474 memset(dst, 0, sizeof(*dst)); 01475 memcpy(dst->data, src->data, sizeof(dst->data)); 01476 dst->len = src->len; 01477 parse_request(dst); 01478 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
parse_moved_contact: Parse 302 Moved temporalily response
Definition at line 9537 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().
09538 { 09539 char tmp[256]; 09540 char *s, *e; 09541 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 09542 s = get_in_brackets(tmp); 09543 e = strchr(s, ';'); 09544 if (e) 09545 *e = '\0'; 09546 if (ast_test_flag(p, SIP_PROMISCREDIR)) { 09547 if (!strncasecmp(s, "sip:", 4)) 09548 s += 4; 09549 e = strchr(s, '/'); 09550 if (e) 09551 *e = '\0'; 09552 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 09553 if (p->owner) 09554 snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "SIP/%s", s); 09555 } else { 09556 e = strchr(tmp, '@'); 09557 if (e) 09558 *e = '\0'; 09559 e = strchr(tmp, '/'); 09560 if (e) 09561 *e = '\0'; 09562 if (!strncasecmp(s, "sip:", 4)) 09563 s += 4; 09564 ast_log(LOG_DEBUG, "Found 302 Redirect to extension '%s'\n", s); 09565 if (p->owner) 09566 ast_copy_string(p->owner->call_forward, s, sizeof(p->owner->call_forward)); 09567 } 09568 }
static int parse_ok_contact | ( | struct sip_pvt * | pvt, | |
struct sip_request * | req | |||
) | [static] |
parse_ok_contact: Parse contact header for 200 OK on INVITE ---
Definition at line 5834 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, n, sip_pvt::okcontacturi, sip_pvt::recv, sip_pvt::sa, SIP_LEN_CONTACT, SIP_NAT, and SIP_NAT_ROUTE.
Referenced by handle_response_invite().
05835 { 05836 char contact[SIP_LEN_CONTACT]; 05837 char *c, *n, *pt; 05838 int port; 05839 struct hostent *hp; 05840 struct ast_hostent ahp; 05841 struct sockaddr_in oldsin; 05842 05843 /* Look for brackets */ 05844 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 05845 c = get_in_brackets(contact); 05846 05847 /* Save full contact to call pvt for later bye or re-invite */ 05848 ast_copy_string(pvt->fullcontact, c, sizeof(pvt->fullcontact)); 05849 05850 /* Save URI for later ACKs, BYE or RE-invites */ 05851 ast_copy_string(pvt->okcontacturi, c, sizeof(pvt->okcontacturi)); 05852 05853 /* Make sure it's a SIP URL */ 05854 if (strncasecmp(c, "sip:", 4)) { 05855 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c); 05856 } else 05857 c += 4; 05858 05859 /* Ditch arguments */ 05860 n = strchr(c, ';'); 05861 if (n) 05862 *n = '\0'; 05863 05864 /* Grab host */ 05865 n = strchr(c, '@'); 05866 if (!n) { 05867 n = c; 05868 c = NULL; 05869 } else { 05870 *n = '\0'; 05871 n++; 05872 } 05873 pt = strchr(n, ':'); 05874 if (pt) { 05875 *pt = '\0'; 05876 pt++; 05877 port = atoi(pt); 05878 } else 05879 port = DEFAULT_SIP_PORT; 05880 05881 memcpy(&oldsin, &pvt->sa, sizeof(oldsin)); 05882 05883 if (!(ast_test_flag(pvt, SIP_NAT) & SIP_NAT_ROUTE)) { 05884 /* XXX This could block for a long time XXX */ 05885 /* We should only do this if it's a name, not an IP */ 05886 hp = ast_gethostbyname(n, &ahp); 05887 if (!hp) { 05888 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 05889 return -1; 05890 } 05891 pvt->sa.sin_family = AF_INET; 05892 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 05893 pvt->sa.sin_port = htons(port); 05894 } else { 05895 /* Don't trust the contact field. Just use what they came to us 05896 with. */ 05897 memcpy(&pvt->sa, &pvt->recv, sizeof(pvt->sa)); 05898 } 05899 return 0; 05900 }
static enum parse_register_result parse_register_contact | ( | struct sip_pvt * | pvt, | |
struct sip_peer * | p, | |||
struct sip_request * | req | |||
) | [static] |
parse_register_contact: Parse contact header and save registration ---
Definition at line 5910 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, n, option_verbose, sip_pvt::our_contact, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), SIP_NAT, SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), SIP_REALTIME, sip_pvt::sipoptions, sip_peer::sipoptions, strcasestr(), sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.
Referenced by register_verify().
05911 { 05912 char contact[BUFSIZ]; 05913 char data[BUFSIZ]; 05914 char iabuf[INET_ADDRSTRLEN]; 05915 char *expires = get_header(req, "Expires"); 05916 int expiry = atoi(expires); 05917 char *c, *n, *pt; 05918 int port; 05919 char *useragent; 05920 struct hostent *hp; 05921 struct ast_hostent ahp; 05922 struct sockaddr_in oldsin; 05923 05924 if (ast_strlen_zero(expires)) { /* No expires header */ 05925 expires = strcasestr(get_header(req, "Contact"), ";expires="); 05926 if (expires) { 05927 char *ptr; 05928 if ((ptr = strchr(expires, ';'))) 05929 *ptr = '\0'; 05930 if (sscanf(expires + 9, "%d", &expiry) != 1) 05931 expiry = default_expiry; 05932 } else { 05933 /* Nothing has been specified */ 05934 expiry = default_expiry; 05935 } 05936 } 05937 /* Look for brackets */ 05938 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 05939 if (strchr(contact, '<') == NULL) { /* No <, check for ; and strip it */ 05940 char *ptr = strchr(contact, ';'); /* This is Header options, not URI options */ 05941 if (ptr) 05942 *ptr = '\0'; 05943 } 05944 c = get_in_brackets(contact); 05945 05946 /* if they did not specify Contact: or Expires:, they are querying 05947 what we currently have stored as their contact address, so return 05948 it 05949 */ 05950 if (ast_strlen_zero(c) && ast_strlen_zero(expires)) { 05951 /* If we have an active registration, tell them when the registration is going to expire */ 05952 if ((p->expire > -1) && !ast_strlen_zero(p->fullcontact)) { 05953 pvt->expiry = ast_sched_when(sched, p->expire); 05954 } 05955 return PARSE_REGISTER_QUERY; 05956 } else if (!strcasecmp(c, "*") || !expiry) { /* Unregister this peer */ 05957 /* This means remove all registrations and return OK */ 05958 memset(&p->addr, 0, sizeof(p->addr)); 05959 if (p->expire > -1) 05960 ast_sched_del(sched, p->expire); 05961 p->expire = -1; 05962 05963 destroy_association(p); 05964 05965 register_peer_exten(p, 0); 05966 p->fullcontact[0] = '\0'; 05967 p->useragent[0] = '\0'; 05968 p->sipoptions = 0; 05969 p->lastms = 0; 05970 05971 if (option_verbose > 2) 05972 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", p->name); 05973 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", p->name); 05974 return PARSE_REGISTER_UPDATE; 05975 } 05976 ast_copy_string(p->fullcontact, c, sizeof(p->fullcontact)); 05977 /* For the 200 OK, we should use the received contact */ 05978 snprintf(pvt->our_contact, sizeof(pvt->our_contact) - 1, "<%s>", c); 05979 /* Make sure it's a SIP URL */ 05980 if (strncasecmp(c, "sip:", 4)) { 05981 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c); 05982 } else 05983 c += 4; 05984 /* Ditch q */ 05985 n = strchr(c, ';'); 05986 if (n) { 05987 *n = '\0'; 05988 } 05989 /* Grab host */ 05990 n = strchr(c, '@'); 05991 if (!n) { 05992 n = c; 05993 c = NULL; 05994 } else { 05995 *n = '\0'; 05996 n++; 05997 } 05998 pt = strchr(n, ':'); 05999 if (pt) { 06000 *pt = '\0'; 06001 pt++; 06002 port = atoi(pt); 06003 } else 06004 port = DEFAULT_SIP_PORT; 06005 memcpy(&oldsin, &p->addr, sizeof(oldsin)); 06006 if (!(ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)) { 06007 /* XXX This could block for a long time XXX */ 06008 hp = ast_gethostbyname(n, &ahp); 06009 if (!hp) { 06010 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 06011 return PARSE_REGISTER_FAILED; 06012 } 06013 p->addr.sin_family = AF_INET; 06014 memcpy(&p->addr.sin_addr, hp->h_addr, sizeof(p->addr.sin_addr)); 06015 p->addr.sin_port = htons(port); 06016 } else { 06017 /* Don't trust the contact field. Just use what they came to us 06018 with */ 06019 memcpy(&p->addr, &pvt->recv, sizeof(p->addr)); 06020 } 06021 06022 if (c) /* Overwrite the default username from config at registration */ 06023 ast_copy_string(p->username, c, sizeof(p->username)); 06024 else 06025 p->username[0] = '\0'; 06026 06027 if (p->expire > -1) 06028 ast_sched_del(sched, p->expire); 06029 if ((expiry < 1) || (expiry > max_expiry)) 06030 expiry = max_expiry; 06031 if (!ast_test_flag(p, SIP_REALTIME)) 06032 p->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, p); 06033 else 06034 p->expire = -1; 06035 pvt->expiry = expiry; 06036 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); 06037 if (!ast_test_flag((&p->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 06038 ast_db_put("SIP/Registry", p->name, data); 06039 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", p->name); 06040 if (inaddrcmp(&p->addr, &oldsin)) { 06041 sip_poke_peer(p); 06042 if (option_verbose > 2) 06043 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); 06044 register_peer_exten(p, 1); 06045 } 06046 06047 /* Save SIP options profile */ 06048 p->sipoptions = pvt->sipoptions; 06049 06050 /* Save User agent */ 06051 useragent = get_header(req, "User-Agent"); 06052 if (useragent && strcasecmp(useragent, p->useragent)) { 06053 ast_copy_string(p->useragent, useragent, sizeof(p->useragent)); 06054 if (option_verbose > 3) { 06055 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n",p->useragent,p->name); 06056 } 06057 } 06058 return PARSE_REGISTER_UPDATE; 06059 }
static void parse_request | ( | struct sip_request * | req | ) | [static] |
parse_request: Parse a SIP message ----
Definition at line 3366 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, and SIP_MAX_LINES.
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().
03367 { 03368 /* Divide fields by NULL's */ 03369 char *c; 03370 int f = 0; 03371 03372 c = req->data; 03373 03374 /* First header starts immediately */ 03375 req->header[f] = c; 03376 while(*c) { 03377 if (*c == '\n') { 03378 /* We've got a new header */ 03379 *c = 0; 03380 03381 if (sipdebug && option_debug > 3) 03382 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 03383 if (ast_strlen_zero(req->header[f])) { 03384 /* Line by itself means we're now in content */ 03385 c++; 03386 break; 03387 } 03388 if (f >= SIP_MAX_HEADERS - 1) { 03389 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 03390 } else 03391 f++; 03392 req->header[f] = c + 1; 03393 } else if (*c == '\r') { 03394 /* Ignore but eliminate \r's */ 03395 *c = 0; 03396 } 03397 c++; 03398 } 03399 /* Check for last header */ 03400 if (!ast_strlen_zero(req->header[f])) { 03401 if (sipdebug && option_debug > 3) 03402 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 03403 f++; 03404 } 03405 req->headers = f; 03406 /* Now we process any mime content */ 03407 f = 0; 03408 req->line[f] = c; 03409 while(*c) { 03410 if (*c == '\n') { 03411 /* We've got a new line */ 03412 *c = 0; 03413 if (sipdebug && option_debug > 3) 03414 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 03415 if (f >= SIP_MAX_LINES - 1) { 03416 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 03417 } else 03418 f++; 03419 req->line[f] = c + 1; 03420 } else if (*c == '\r') { 03421 /* Ignore and eliminate \r's */ 03422 *c = 0; 03423 } 03424 c++; 03425 } 03426 /* Check for last line */ 03427 if (!ast_strlen_zero(req->line[f])) 03428 f++; 03429 req->lines = f; 03430 if (*c) 03431 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 03432 /* Split up the first line parts */ 03433 determine_firstline_parts(req); 03434 }
unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
char * | supported | |||
) |
parse_sip_options: Parse supported header in incoming packet
Definition at line 1001 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), sip_pvt::callid, LOG_DEBUG, option_debug, sip_options, sip_pvt::sipoptions, and text.
Referenced by handle_request_invite().
01002 { 01003 char *next = NULL; 01004 char *sep = NULL; 01005 char *temp = ast_strdupa(supported); 01006 int i; 01007 unsigned int profile = 0; 01008 01009 if (ast_strlen_zero(supported) ) 01010 return 0; 01011 01012 if (option_debug > 2 && sipdebug) 01013 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01014 01015 next = temp; 01016 while (next) { 01017 char res=0; 01018 if ( (sep = strchr(next, ',')) != NULL) { 01019 *sep = '\0'; 01020 sep++; 01021 } 01022 while (*next == ' ') /* Skip spaces */ 01023 next++; 01024 if (option_debug > 2 && sipdebug) 01025 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01026 for (i=0; (i < (sizeof(sip_options) / sizeof(sip_options[0]))) && !res; i++) { 01027 if (!strcasecmp(next, sip_options[i].text)) { 01028 profile |= sip_options[i].id; 01029 res = 1; 01030 if (option_debug > 2 && sipdebug) 01031 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01032 } 01033 } 01034 if (!res) 01035 if (option_debug > 2 && sipdebug) 01036 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01037 next = sep; 01038 } 01039 if (pvt) { 01040 pvt->sipoptions = profile; 01041 if (option_debug) 01042 ast_log(LOG_DEBUG, "* SIP extension value: %d for call %s\n", profile, pvt->callid); 01043 } 01044 return profile; 01045 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 7490 of file chan_sip.c.
References sip_peer::lastms, and sip_peer::maxms.
07491 { 07492 int res = 0; 07493 if (peer->maxms) { 07494 if (peer->lastms < 0) { 07495 ast_copy_string(status, "UNREACHABLE", statuslen); 07496 } else if (peer->lastms > peer->maxms) { 07497 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 07498 res = 1; 07499 } else if (peer->lastms) { 07500 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 07501 res = 1; 07502 } else { 07503 ast_copy_string(status, "UNKNOWN", statuslen); 07504 } 07505 } else { 07506 ast_copy_string(status, "Unmonitored", statuslen); 07507 /* Checking if port is 0 */ 07508 res = -1; 07509 } 07510 return res; 07511 }
static void print_codec_to_cli | ( | int | fd, | |
struct ast_codec_pref * | pref | |||
) | [static] |
print_codec_to_cli: Print codec list from preference to CLI/manager
Definition at line 7929 of file chan_sip.c.
References ast_cli(), ast_codec_pref_index(), and ast_getformatname().
Referenced by _sip_show_peer(), and sip_show_settings().
07930 { 07931 int x, codec; 07932 07933 for(x = 0; x < 32 ; x++) { 07934 codec = ast_codec_pref_index(pref, x); 07935 if (!codec) 07936 break; 07937 ast_cli(fd, "%s", ast_getformatname(codec)); 07938 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 07939 ast_cli(fd, ","); 07940 } 07941 if (!x) 07942 ast_cli(fd, "none"); 07943 }
static void print_group | ( | int | fd, | |
unsigned int | group, | |||
int | crlf | |||
) | [static] |
print_group: Print call group and pickup group ---
Definition at line 7746 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
07747 { 07748 char buf[256]; 07749 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 07750 }
static int process_sdp | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
process_sdp: Process SIP SDP and activate RTP channels---
Definition at line 3499 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.
03500 { 03501 char *m; 03502 char *c; 03503 char *a; 03504 char host[258]; 03505 char iabuf[INET_ADDRSTRLEN]; 03506 int len = -1; 03507 int portno = -1; 03508 int vportno = -1; 03509 int peercapability, peernoncodeccapability; 03510 int vpeercapability=0, vpeernoncodeccapability=0; 03511 struct sockaddr_in sin; 03512 char *codecs; 03513 struct hostent *hp; 03514 struct ast_hostent ahp; 03515 int codec; 03516 int destiterator = 0; 03517 int iterator; 03518 int sendonly = 0; 03519 int x,y; 03520 int debug=sip_debug_test_pvt(p); 03521 struct ast_channel *bridgepeer = NULL; 03522 03523 if (!p->rtp) { 03524 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 03525 return -1; 03526 } 03527 03528 /* Update our last rtprx when we receive an SDP, too */ 03529 time(&p->lastrtprx); 03530 time(&p->lastrtptx); 03531 03532 m = get_sdp(req, "m"); 03533 sdpLineNum_iterator_init(&destiterator, req); 03534 c = get_sdp_iterate(&destiterator, req, "c"); 03535 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 03536 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 03537 return -1; 03538 } 03539 if (sscanf(c, "IN IP4 %256s", host) != 1) { 03540 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 03541 return -1; 03542 } 03543 /* XXX This could block for a long time, and block the main thread! XXX */ 03544 hp = ast_gethostbyname(host, &ahp); 03545 if (!hp) { 03546 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 03547 return -1; 03548 } 03549 sdpLineNum_iterator_init(&iterator, req); 03550 ast_set_flag(p, SIP_NOVIDEO); 03551 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 03552 int found = 0; 03553 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &y, &len) == 2) || 03554 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) { 03555 found = 1; 03556 portno = x; 03557 /* Scan through the RTP payload types specified in a "m=" line: */ 03558 ast_rtp_pt_clear(p->rtp); 03559 codecs = m + len; 03560 while(!ast_strlen_zero(codecs)) { 03561 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 03562 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 03563 return -1; 03564 } 03565 if (debug) 03566 ast_verbose("Found RTP audio format %d\n", codec); 03567 ast_rtp_set_m_type(p->rtp, codec); 03568 codecs = ast_skip_blanks(codecs + len); 03569 } 03570 } 03571 if (p->vrtp) 03572 ast_rtp_pt_clear(p->vrtp); /* Must be cleared in case no m=video line exists */ 03573 03574 if (p->vrtp && (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { 03575 found = 1; 03576 ast_clear_flag(p, SIP_NOVIDEO); 03577 vportno = x; 03578 /* Scan through the RTP payload types specified in a "m=" line: */ 03579 codecs = m + len; 03580 while(!ast_strlen_zero(codecs)) { 03581 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 03582 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 03583 return -1; 03584 } 03585 if (debug) 03586 ast_verbose("Found RTP video format %d\n", codec); 03587 ast_rtp_set_m_type(p->vrtp, codec); 03588 codecs = ast_skip_blanks(codecs + len); 03589 } 03590 } 03591 if (!found ) 03592 ast_log(LOG_WARNING, "Unknown SDP media type in offer: %s\n", m); 03593 } 03594 if (portno == -1 && vportno == -1) { 03595 /* No acceptable offer found in SDP */ 03596 return -2; 03597 } 03598 /* Check for Media-description-level-address for audio */ 03599 c = get_sdp_iterate(&destiterator, req, "c"); 03600 if (!ast_strlen_zero(c)) { 03601 if (sscanf(c, "IN IP4 %256s", host) != 1) { 03602 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 03603 } else { 03604 /* XXX This could block for a long time, and block the main thread! XXX */ 03605 hp = ast_gethostbyname(host, &ahp); 03606 if (!hp) { 03607 ast_log(LOG_WARNING, "Unable to lookup host in secondary c= line, '%s'\n", c); 03608 } 03609 } 03610 } 03611 /* RTP addresses and ports for audio and video */ 03612 sin.sin_family = AF_INET; 03613 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 03614 03615 /* Setup audio port number */ 03616 sin.sin_port = htons(portno); 03617 if (p->rtp && sin.sin_port) { 03618 ast_rtp_set_peer(p->rtp, &sin); 03619 if (debug) { 03620 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 03621 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)); 03622 } 03623 } 03624 /* Check for Media-description-level-address for video */ 03625 c = get_sdp_iterate(&destiterator, req, "c"); 03626 if (!ast_strlen_zero(c)) { 03627 if (sscanf(c, "IN IP4 %256s", host) != 1) { 03628 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 03629 } else { 03630 /* XXX This could block for a long time, and block the main thread! XXX */ 03631 hp = ast_gethostbyname(host, &ahp); 03632 if (!hp) { 03633 ast_log(LOG_WARNING, "Unable to lookup host in secondary c= line, '%s'\n", c); 03634 } 03635 } 03636 } 03637 /* Setup video port number */ 03638 sin.sin_port = htons(vportno); 03639 if (p->vrtp && sin.sin_port) { 03640 ast_rtp_set_peer(p->vrtp, &sin); 03641 if (debug) { 03642 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 03643 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)); 03644 } 03645 } 03646 03647 /* Next, scan through each "a=rtpmap:" line, noting each 03648 * specified RTP payload type (with corresponding MIME subtype): 03649 */ 03650 sdpLineNum_iterator_init(&iterator, req); 03651 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 03652 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 03653 if (!strcasecmp(a, "sendonly") || !strcasecmp(a, "inactive")) { 03654 sendonly = 1; 03655 continue; 03656 } 03657 if (!strcasecmp(a, "sendrecv")) { 03658 sendonly = 0; 03659 } 03660 if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue; 03661 if (debug) 03662 ast_verbose("Found description format %s\n", mimeSubtype); 03663 /* Note: should really look at the 'freq' and '#chans' params too */ 03664 ast_rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype); 03665 if (p->vrtp) 03666 ast_rtp_set_rtpmap_type(p->vrtp, codec, "video", mimeSubtype); 03667 } 03668 03669 /* Now gather all of the codecs that were asked for: */ 03670 ast_rtp_get_current_formats(p->rtp, 03671 &peercapability, &peernoncodeccapability); 03672 if (p->vrtp) 03673 ast_rtp_get_current_formats(p->vrtp, 03674 &vpeercapability, &vpeernoncodeccapability); 03675 p->jointcapability = p->capability & (peercapability | vpeercapability); 03676 p->peercapability = (peercapability | vpeercapability); 03677 p->noncodeccapability = noncodeccapability & peernoncodeccapability; 03678 03679 if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO) { 03680 ast_clear_flag(p, SIP_DTMF); 03681 if (p->noncodeccapability & AST_RTP_DTMF) { 03682 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 03683 ast_set_flag(p, SIP_DTMF_RFC2833); 03684 } else { 03685 ast_set_flag(p, SIP_DTMF_INBAND); 03686 } 03687 } 03688 03689 if (debug) { 03690 /* shame on whoever coded this.... */ 03691 const unsigned slen=512; 03692 char s1[slen], s2[slen], s3[slen], s4[slen]; 03693 03694 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 03695 ast_getformatname_multiple(s1, slen, p->capability), 03696 ast_getformatname_multiple(s2, slen, peercapability), 03697 ast_getformatname_multiple(s3, slen, vpeercapability), 03698 ast_getformatname_multiple(s4, slen, p->jointcapability)); 03699 03700 ast_verbose("Non-codec capabilities: us - %s, peer - %s, combined - %s\n", 03701 ast_rtp_lookup_mime_multiple(s1, slen, noncodeccapability, 0), 03702 ast_rtp_lookup_mime_multiple(s2, slen, peernoncodeccapability, 0), 03703 ast_rtp_lookup_mime_multiple(s3, slen, p->noncodeccapability, 0)); 03704 } 03705 if (!p->jointcapability) { 03706 ast_log(LOG_NOTICE, "No compatible codecs!\n"); 03707 return -1; 03708 } 03709 03710 if (!p->owner) /* There's no open channel owning us */ 03711 return 0; 03712 03713 if (!(p->owner->nativeformats & p->jointcapability)) { 03714 const unsigned slen=512; 03715 char s1[slen], s2[slen]; 03716 ast_log(LOG_DEBUG, "Oooh, we need to change our formats since our peer supports only %s and not %s\n", 03717 ast_getformatname_multiple(s1, slen, p->jointcapability), 03718 ast_getformatname_multiple(s2, slen, p->owner->nativeformats)); 03719 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1); 03720 ast_set_read_format(p->owner, p->owner->readformat); 03721 ast_set_write_format(p->owner, p->owner->writeformat); 03722 } 03723 if ((bridgepeer=ast_bridged_channel(p->owner))) { 03724 /* We have a bridge */ 03725 /* Turn on/off music on hold if we are holding/unholding */ 03726 struct ast_frame af = { AST_FRAME_NULL, }; 03727 if (sin.sin_addr.s_addr && !sendonly) { 03728 ast_moh_stop(bridgepeer); 03729 03730 /* Activate a re-invite */ 03731 ast_queue_frame(p->owner, &af); 03732 } else { 03733 /* No address for RTP, we're on hold */ 03734 03735 ast_moh_start(bridgepeer, NULL); 03736 if (sendonly) 03737 ast_rtp_stop(p->rtp); 03738 /* Activate a re-invite */ 03739 ast_queue_frame(p->owner, &af); 03740 } 03741 } 03742 03743 /* Manager Hold and Unhold events must be generated, if necessary */ 03744 if (sin.sin_addr.s_addr && !sendonly) { 03745 append_history(p, "Unhold", req->data); 03746 03747 if (callevents && ast_test_flag(p, SIP_CALL_ONHOLD)) { 03748 manager_event(EVENT_FLAG_CALL, "Unhold", 03749 "Channel: %s\r\n" 03750 "Uniqueid: %s\r\n", 03751 p->owner->name, 03752 p->owner->uniqueid); 03753 03754 } 03755 ast_clear_flag(p, SIP_CALL_ONHOLD); 03756 } else { 03757 /* No address for RTP, we're on hold */ 03758 append_history(p, "Hold", req->data); 03759 03760 if (callevents && !ast_test_flag(p, SIP_CALL_ONHOLD)) { 03761 manager_event(EVENT_FLAG_CALL, "Hold", 03762 "Channel: %s\r\n" 03763 "Uniqueid: %s\r\n", 03764 p->owner->name, 03765 p->owner->uniqueid); 03766 } 03767 ast_set_flag(p, SIP_CALL_ONHOLD); 03768 } 03769 03770 return 0; 03771 }
static struct sip_peer* realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
Definition at line 1686 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.
01687 { 01688 struct sip_peer *peer=NULL; 01689 struct ast_variable *var; 01690 struct ast_variable *tmp; 01691 char *newpeername = (char *) peername; 01692 char iabuf[80]; 01693 01694 /* First check on peer name */ 01695 if (newpeername) 01696 var = ast_load_realtime("sippeers", "name", peername, NULL); 01697 else if (sin) { /* Then check on IP address */ 01698 ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr); 01699 var = ast_load_realtime("sippeers", "host", iabuf, NULL); /* First check for fixed IP hosts */ 01700 if (!var) 01701 var = ast_load_realtime("sippeers", "ipaddr", iabuf, NULL); /* Then check for registred hosts */ 01702 01703 } else 01704 return NULL; 01705 01706 if (!var) 01707 return NULL; 01708 01709 tmp = var; 01710 /* If this is type=user, then skip this object. */ 01711 while(tmp) { 01712 if (!strcasecmp(tmp->name, "type") && 01713 !strcasecmp(tmp->value, "user")) { 01714 ast_variables_destroy(var); 01715 return NULL; 01716 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 01717 newpeername = tmp->value; 01718 } 01719 tmp = tmp->next; 01720 } 01721 01722 if (!newpeername) { /* Did not find peer in realtime */ 01723 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 01724 ast_variables_destroy(var); 01725 return (struct sip_peer *) NULL; 01726 } 01727 01728 /* Peer found in realtime, now build it in memory */ 01729 peer = build_peer(newpeername, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)); 01730 if (!peer) { 01731 ast_variables_destroy(var); 01732 return (struct sip_peer *) NULL; 01733 } 01734 01735 if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 01736 /* Cache peer */ 01737 ast_copy_flags((&peer->flags_page2),(&global_flags_page2), SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 01738 if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTAUTOCLEAR)) { 01739 if (peer->expire > -1) { 01740 ast_sched_del(sched, peer->expire); 01741 } 01742 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, (void *)peer); 01743 } 01744 ASTOBJ_CONTAINER_LINK(&peerl,peer); 01745 } else { 01746 ast_set_flag(peer, SIP_REALTIME); 01747 } 01748 ast_variables_destroy(var); 01749 01750 return peer; 01751 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
const char * | username, | |||
const char * | fullcontact, | |||
int | expirey | |||
) | [static] |
realtime_update_peer: Update peer object in realtime storage ---
Definition at line 1608 of file chan_sip.c.
References ast_inet_ntoa(), ast_update_realtime(), and ipaddr.
01609 { 01610 char port[10]; 01611 char ipaddr[20]; 01612 char regseconds[20]; 01613 time_t nowtime; 01614 01615 time(&nowtime); 01616 nowtime += expirey; 01617 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 01618 ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr); 01619 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 01620 01621 if (fullcontact) 01622 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, "fullcontact", fullcontact, NULL); 01623 else 01624 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, NULL); 01625 }
static struct sip_user* realtime_user | ( | const char * | username | ) | [static] |
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 1800 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.
01801 { 01802 struct ast_variable *var; 01803 struct ast_variable *tmp; 01804 struct sip_user *user = NULL; 01805 01806 var = ast_load_realtime("sipusers", "name", username, NULL); 01807 01808 if (!var) 01809 return NULL; 01810 01811 tmp = var; 01812 while (tmp) { 01813 if (!strcasecmp(tmp->name, "type") && 01814 !strcasecmp(tmp->value, "peer")) { 01815 ast_variables_destroy(var); 01816 return NULL; 01817 } 01818 tmp = tmp->next; 01819 } 01820 01821 01822 01823 user = build_user(username, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)); 01824 01825 if (!user) { /* No user found */ 01826 ast_variables_destroy(var); 01827 return NULL; 01828 } 01829 01830 if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 01831 ast_set_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS); 01832 suserobjs++; 01833 ASTOBJ_CONTAINER_LINK(&userl,user); 01834 } else { 01835 /* Move counter from s to r... */ 01836 suserobjs--; 01837 ruserobjs++; 01838 ast_set_flag(user, SIP_REALTIME); 01839 } 01840 ast_variables_destroy(var); 01841 return user; 01842 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
receive_message: Receive SIP MESSAGE method messages ---
Definition at line 7385 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().
07386 { 07387 char buf[1024]; 07388 struct ast_frame f; 07389 char *content_type; 07390 07391 content_type = get_header(req, "Content-Type"); 07392 if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */ 07393 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 07394 ast_set_flag(p, SIP_NEEDDESTROY); 07395 return; 07396 } 07397 07398 if (get_msg_text(buf, sizeof(buf), req)) { 07399 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 07400 transmit_response(p, "202 Accepted", req); 07401 ast_set_flag(p, SIP_NEEDDESTROY); 07402 return; 07403 } 07404 07405 if (p->owner) { 07406 if (sip_debug_test_pvt(p)) 07407 ast_verbose("Message received: '%s'\n", buf); 07408 memset(&f, 0, sizeof(f)); 07409 f.frametype = AST_FRAME_TEXT; 07410 f.subclass = 0; 07411 f.offset = 0; 07412 f.data = buf; 07413 f.datalen = strlen(buf); 07414 ast_queue_frame(p->owner, &f); 07415 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 07416 } else { /* Message outside of a call, we do not support that */ 07417 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); 07418 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 07419 } 07420 ast_set_flag(p, SIP_NEEDDESTROY); 07421 return; 07422 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
reg_source_db: Get registration details from Asterisk DB ---
Definition at line 5773 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.
05774 { 05775 char data[256]; 05776 char iabuf[INET_ADDRSTRLEN]; 05777 struct in_addr in; 05778 int expiry; 05779 int port; 05780 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 05781 05782 if (ast_test_flag(&(peer->flags_page2), SIP_PAGE2_RT_FROMCONTACT)) 05783 return; 05784 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 05785 return; 05786 05787 scan = data; 05788 addr = strsep(&scan, ":"); 05789 port_str = strsep(&scan, ":"); 05790 expiry_str = strsep(&scan, ":"); 05791 username = strsep(&scan, ":"); 05792 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 05793 05794 if (!inet_aton(addr, &in)) 05795 return; 05796 05797 if (port_str) 05798 port = atoi(port_str); 05799 else 05800 return; 05801 05802 if (expiry_str) 05803 expiry = atoi(expiry_str); 05804 else 05805 return; 05806 05807 if (username) 05808 ast_copy_string(peer->username, username, sizeof(peer->username)); 05809 if (contact) 05810 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 05811 05812 if (option_verbose > 2) 05813 ast_verbose(VERBOSE_PREFIX_3 "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 05814 peer->name, peer->username, ast_inet_ntoa(iabuf, sizeof(iabuf), in), port, expiry); 05815 05816 memset(&peer->addr, 0, sizeof(peer->addr)); 05817 peer->addr.sin_family = AF_INET; 05818 peer->addr.sin_addr = in; 05819 peer->addr.sin_port = htons(port); 05820 if (sipsock < 0) { 05821 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 05822 if (peer->pokeexpire > -1) 05823 ast_sched_del(sched, peer->pokeexpire); 05824 peer->pokeexpire = ast_sched_add(sched, thread_safe_rand() % 5000 + 1, sip_poke_peer_s, peer); 05825 } else 05826 sip_poke_peer(peer); 05827 if (peer->expire > -1) 05828 ast_sched_del(sched, peer->expire); 05829 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 05830 register_peer_exten(peer, 1); 05831 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
register_peer_exten: Automatically add peer extension to dial plan ---
Definition at line 1628 of file chan_sip.c.
References ast_add_extension(), ast_context_remove_extension(), ast_strlen_zero(), FREE, sip_peer::regexten, strdup, and strsep().
01629 { 01630 char multi[256]; 01631 char *stringp, *ext; 01632 if (!ast_strlen_zero(regcontext)) { 01633 ast_copy_string(multi, ast_strlen_zero(peer->regexten) ? peer->name : peer->regexten, sizeof(multi)); 01634 stringp = multi; 01635 while((ext = strsep(&stringp, "&"))) { 01636 if (onoff) 01637 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), FREE, channeltype); 01638 else 01639 ast_context_remove_extension(regcontext, ext, 1, NULL); 01640 } 01641 } 01642 }
static int register_verify | ( | struct sip_pvt * | p, | |
struct sockaddr_in * | sin, | |||
struct sip_request * | req, | |||
char * | uri, | |||
int | ignore | |||
) | [static] |
register_verify: Verify registration of user
Definition at line 6465 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().
06466 { 06467 int res = -3; 06468 struct sip_peer *peer; 06469 char tmp[256]; 06470 char iabuf[INET_ADDRSTRLEN]; 06471 char *name, *c; 06472 char *t; 06473 char *domain; 06474 06475 /* Terminate URI */ 06476 t = uri; 06477 while(*t && (*t > 32) && (*t != ';')) 06478 t++; 06479 *t = '\0'; 06480 06481 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 06482 if (pedanticsipchecking) 06483 ast_uri_decode(tmp); 06484 06485 c = get_in_brackets(tmp); 06486 /* Ditch ;user=phone */ 06487 name = strchr(c, ';'); 06488 if (name) 06489 *name = '\0'; 06490 06491 if (!strncmp(c, "sip:", 4)) { 06492 name = c + 4; 06493 } else { 06494 name = c; 06495 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)); 06496 } 06497 06498 /* Strip off the domain name */ 06499 if ((c = strchr(name, '@'))) { 06500 *c++ = '\0'; 06501 domain = c; 06502 if ((c = strchr(domain, ':'))) /* Remove :port */ 06503 *c = '\0'; 06504 if (!AST_LIST_EMPTY(&domain_list)) { 06505 if (!check_sip_domain(domain, NULL, 0)) { 06506 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 06507 return -3; 06508 } 06509 } 06510 } 06511 06512 ast_copy_string(p->exten, name, sizeof(p->exten)); 06513 build_contact(p); 06514 peer = find_peer(name, NULL, 1); 06515 if (!(peer && ast_apply_ha(peer->ha, sin))) { 06516 if (peer) 06517 ASTOBJ_UNREF(peer,sip_destroy_peer); 06518 } 06519 if (peer) { 06520 if (!ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)) { 06521 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 06522 } else { 06523 ast_copy_flags(p, peer, SIP_NAT); 06524 transmit_response(p, "100 Trying", req); 06525 if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, 0, ignore))) { 06526 sip_cancel_destroy(p); 06527 switch (parse_register_contact(p, peer, req)) { 06528 case PARSE_REGISTER_FAILED: 06529 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 06530 transmit_response_with_date(p, "400 Bad Request", req); 06531 peer->lastmsgssent = -1; 06532 res = 0; 06533 break; 06534 case PARSE_REGISTER_QUERY: 06535 transmit_response_with_date(p, "200 OK", req); 06536 peer->lastmsgssent = -1; 06537 res = 0; 06538 break; 06539 case PARSE_REGISTER_UPDATE: 06540 update_peer(peer, p->expiry); 06541 /* Say OK and ask subsystem to retransmit msg counter */ 06542 transmit_response_with_date(p, "200 OK", req); 06543 peer->lastmsgssent = -1; 06544 res = 0; 06545 break; 06546 } 06547 } 06548 } 06549 } 06550 if (!peer && autocreatepeer) { 06551 /* Create peer if we have autocreate mode enabled */ 06552 peer = temp_peer(name); 06553 if (peer) { 06554 ASTOBJ_CONTAINER_LINK(&peerl, peer); 06555 sip_cancel_destroy(p); 06556 switch (parse_register_contact(p, peer, req)) { 06557 case PARSE_REGISTER_FAILED: 06558 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 06559 transmit_response_with_date(p, "400 Bad Request", req); 06560 peer->lastmsgssent = -1; 06561 res = 0; 06562 break; 06563 case PARSE_REGISTER_QUERY: 06564 transmit_response_with_date(p, "200 OK", req); 06565 peer->lastmsgssent = -1; 06566 res = 0; 06567 break; 06568 case PARSE_REGISTER_UPDATE: 06569 /* Say OK and ask subsystem to retransmit msg counter */ 06570 transmit_response_with_date(p, "200 OK", req); 06571 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 06572 peer->lastmsgssent = -1; 06573 res = 0; 06574 break; 06575 } 06576 } 06577 } 06578 if (!res) { 06579 ast_device_state_changed("SIP/%s", peer->name); 06580 } 06581 if (res < 0) { 06582 switch (res) { 06583 case -1: 06584 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 06585 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 06586 break; 06587 case -2: 06588 /* Username and digest username does not match. 06589 Asterisk uses the From: username for authentication. We need the 06590 users to use the same authentication user name until we support 06591 proper authentication by digest auth name */ 06592 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 06593 break; 06594 case -3: 06595 if (global_alwaysauthreject) { 06596 transmit_fake_auth_response(p, &p->initreq, p->randdata, sizeof(p->randdata), 1); 06597 } else { 06598 /* URI not found */ 06599 transmit_response(p, "404 Not found", &p->initreq); 06600 } 06601 /* Set res back to -2 because we don't want to return an invalid domain message. That check already happened up above. */ 06602 res = -2; 06603 break; 06604 } 06605 if (option_debug > 1) { 06606 ast_log(LOG_DEBUG, "SIP REGISTER attempt failed for %s : %s\n", 06607 peer->name, 06608 (res == -1) ? "Bad password" : ((res == -2 ) ? "Bad digest user" : "Peer not found")); 06609 } 06610 } 06611 if (peer) 06612 ASTOBJ_UNREF(peer,sip_destroy_peer); 06613 06614 return res; 06615 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 5313 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.
05314 { 05315 switch(regstate) { 05316 case REG_STATE_FAILED: 05317 return "Failed"; 05318 case REG_STATE_UNREGISTERED: 05319 return "Unregistered"; 05320 case REG_STATE_REGSENT: 05321 return "Request Sent"; 05322 case REG_STATE_AUTHSENT: 05323 return "Auth. Sent"; 05324 case REG_STATE_REGISTERED: 05325 return "Registered"; 05326 case REG_STATE_REJECTED: 05327 return "Rejected"; 05328 case REG_STATE_TIMEOUT: 05329 return "Timeout"; 05330 case REG_STATE_NOAUTH: 05331 return "No Authentication"; 05332 default: 05333 return "Unknown"; 05334 } 05335 }
int reload | ( | void | ) |
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 13337 of file chan_sip.c.
References sip_reload().
13338 { 13339 return sip_reload(0, 0, NULL); 13340 }
static int reload_config | ( | void | ) | [static] |
reload_config: Re-read SIP.conf config file ---
Definition at line 12516 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_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.
12517 { 12518 struct ast_config *cfg; 12519 struct ast_variable *v; 12520 struct sip_peer *peer; 12521 struct sip_user *user; 12522 struct ast_hostent ahp; 12523 char *cat; 12524 char *utype; 12525 struct hostent *hp; 12526 int format; 12527 char iabuf[INET_ADDRSTRLEN]; 12528 struct ast_flags dummy; 12529 int auto_sip_domains = 0; 12530 struct sockaddr_in old_bindaddr = bindaddr; 12531 12532 cfg = ast_config_load(config); 12533 12534 /* We *must* have a config file otherwise stop immediately */ 12535 if (!cfg) { 12536 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 12537 return -1; 12538 } 12539 12540 /* Reset IP addresses */ 12541 memset(&bindaddr, 0, sizeof(bindaddr)); 12542 memset(&localaddr, 0, sizeof(localaddr)); 12543 memset(&externip, 0, sizeof(externip)); 12544 memset(&prefs, 0 , sizeof(prefs)); 12545 sipdebug &= ~SIP_DEBUG_CONFIG; 12546 12547 /* Initialize some reasonable defaults at SIP reload */ 12548 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 12549 default_subscribecontext[0] = '\0'; 12550 default_language[0] = '\0'; 12551 default_fromdomain[0] = '\0'; 12552 default_qualify = 0; 12553 allow_external_domains = 1; /* Allow external invites */ 12554 externhost[0] = '\0'; 12555 externexpire = 0; 12556 externrefresh = 10; 12557 ast_copy_string(default_useragent, DEFAULT_USERAGENT, sizeof(default_useragent)); 12558 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 12559 global_notifyringing = 1; 12560 global_alwaysauthreject = 0; 12561 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 12562 ast_copy_string(global_musicclass, "default", sizeof(global_musicclass)); 12563 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 12564 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 12565 outboundproxyip.sin_port = htons(DEFAULT_SIP_PORT); 12566 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 12567 videosupport = 0; 12568 compactheaders = 0; 12569 dumphistory = 0; 12570 recordhistory = 0; 12571 relaxdtmf = 0; 12572 callevents = 0; 12573 ourport = DEFAULT_SIP_PORT; 12574 global_rtptimeout = 0; 12575 global_rtpholdtimeout = 0; 12576 global_rtpkeepalive = 0; 12577 global_rtautoclear = 120; 12578 pedanticsipchecking = 0; 12579 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 12580 global_regattempts_max = 0; 12581 ast_clear_flag(&global_flags, AST_FLAGS_ALL); 12582 ast_clear_flag(&global_flags_page2, AST_FLAGS_ALL); 12583 ast_set_flag(&global_flags, SIP_DTMF_RFC2833); 12584 ast_set_flag(&global_flags, SIP_NAT_RFC3581); 12585 ast_set_flag(&global_flags, SIP_CAN_REINVITE); 12586 ast_set_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE); 12587 global_mwitime = DEFAULT_MWITIME; 12588 strcpy(global_vmexten, DEFAULT_VMEXTEN); 12589 srvlookup = 0; 12590 autocreatepeer = 0; 12591 regcontext[0] = '\0'; 12592 tos = 0; 12593 expiry = DEFAULT_EXPIRY; 12594 global_allowguest = 1; 12595 12596 /* Read the [general] config section of sip.conf (or from realtime config) */ 12597 v = ast_variable_browse(cfg, "general"); 12598 while(v) { 12599 if (handle_common_options(&global_flags, &dummy, v)) { 12600 v = v->next; 12601 continue; 12602 } 12603 12604 /* Create the interface list */ 12605 if (!strcasecmp(v->name, "context")) { 12606 ast_copy_string(default_context, v->value, sizeof(default_context)); 12607 } else if (!strcasecmp(v->name, "realm")) { 12608 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 12609 } else if (!strcasecmp(v->name, "useragent")) { 12610 ast_copy_string(default_useragent, v->value, sizeof(default_useragent)); 12611 ast_log(LOG_DEBUG, "Setting User Agent Name to %s\n", 12612 default_useragent); 12613 } else if (!strcasecmp(v->name, "rtcachefriends")) { 12614 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 12615 } else if (!strcasecmp(v->name, "rtupdate")) { 12616 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTUPDATE); 12617 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 12618 ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 12619 } else if (!strcasecmp(v->name, "rtautoclear")) { 12620 int i = atoi(v->value); 12621 if (i > 0) 12622 global_rtautoclear = i; 12623 else 12624 i = 0; 12625 ast_set2_flag((&global_flags_page2), i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 12626 } else if (!strcasecmp(v->name, "usereqphone")) { 12627 ast_set2_flag((&global_flags), ast_true(v->value), SIP_USEREQPHONE); 12628 } else if (!strcasecmp(v->name, "relaxdtmf")) { 12629 relaxdtmf = ast_true(v->value); 12630 } else if (!strcasecmp(v->name, "checkmwi")) { 12631 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 12632 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 12633 global_mwitime = DEFAULT_MWITIME; 12634 } 12635 } else if (!strcasecmp(v->name, "vmexten")) { 12636 ast_copy_string(global_vmexten, v->value, sizeof(global_vmexten)); 12637 } else if (!strcasecmp(v->name, "rtptimeout")) { 12638 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 12639 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12640 global_rtptimeout = 0; 12641 } 12642 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 12643 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 12644 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 12645 global_rtpholdtimeout = 0; 12646 } 12647 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 12648 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 12649 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 12650 global_rtpkeepalive = 0; 12651 } 12652 } else if (!strcasecmp(v->name, "videosupport")) { 12653 videosupport = ast_true(v->value); 12654 } else if (!strcasecmp(v->name, "compactheaders")) { 12655 compactheaders = ast_true(v->value); 12656 } else if (!strcasecmp(v->name, "notifymimetype")) { 12657 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 12658 } else if (!strcasecmp(v->name, "notifyringing")) { 12659 global_notifyringing = ast_true(v->value); 12660 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 12661 global_alwaysauthreject = ast_true(v->value); 12662 } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 12663 ast_copy_string(global_musicclass, v->value, sizeof(global_musicclass)); 12664 } else if (!strcasecmp(v->name, "language")) { 12665 ast_copy_string(default_language, v->value, sizeof(default_language)); 12666 } else if (!strcasecmp(v->name, "regcontext")) { 12667 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 12668 /* Create context if it doesn't exist already */ 12669 if (!ast_context_find(regcontext)) 12670 ast_context_create(NULL, regcontext, channeltype); 12671 } else if (!strcasecmp(v->name, "callerid")) { 12672 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 12673 } else if (!strcasecmp(v->name, "fromdomain")) { 12674 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 12675 } else if (!strcasecmp(v->name, "outboundproxy")) { 12676 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 12677 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 12678 } else if (!strcasecmp(v->name, "outboundproxyport")) { 12679 /* Port needs to be after IP */ 12680 sscanf(v->value, "%d", &format); 12681 outboundproxyip.sin_port = htons(format); 12682 } else if (!strcasecmp(v->name, "autocreatepeer")) { 12683 autocreatepeer = ast_true(v->value); 12684 } else if (!strcasecmp(v->name, "srvlookup")) { 12685 srvlookup = ast_true(v->value); 12686 } else if (!strcasecmp(v->name, "pedantic")) { 12687 pedanticsipchecking = ast_true(v->value); 12688 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 12689 max_expiry = atoi(v->value); 12690 if (max_expiry < 1) 12691 max_expiry = DEFAULT_MAX_EXPIRY; 12692 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 12693 default_expiry = atoi(v->value); 12694 if (default_expiry < 1) 12695 default_expiry = DEFAULT_DEFAULT_EXPIRY; 12696 } else if (!strcasecmp(v->name, "sipdebug")) { 12697 if (ast_true(v->value)) 12698 sipdebug |= SIP_DEBUG_CONFIG; 12699 } else if (!strcasecmp(v->name, "dumphistory")) { 12700 dumphistory = ast_true(v->value); 12701 } else if (!strcasecmp(v->name, "recordhistory")) { 12702 recordhistory = ast_true(v->value); 12703 } else if (!strcasecmp(v->name, "registertimeout")) { 12704 global_reg_timeout = atoi(v->value); 12705 if (global_reg_timeout < 1) 12706 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 12707 } else if (!strcasecmp(v->name, "registerattempts")) { 12708 global_regattempts_max = atoi(v->value); 12709 } else if (!strcasecmp(v->name, "bindaddr")) { 12710 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 12711 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 12712 } else { 12713 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 12714 } 12715 } else if (!strcasecmp(v->name, "localnet")) { 12716 struct ast_ha *na; 12717 if (!(na = ast_append_ha("d", v->value, localaddr))) 12718 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 12719 else 12720 localaddr = na; 12721 } else if (!strcasecmp(v->name, "localmask")) { 12722 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 12723 } else if (!strcasecmp(v->name, "externip")) { 12724 if (!(hp = ast_gethostbyname(v->value, &ahp))) 12725 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 12726 else 12727 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 12728 externexpire = 0; 12729 } else if (!strcasecmp(v->name, "externhost")) { 12730 ast_copy_string(externhost, v->value, sizeof(externhost)); 12731 if (!(hp = ast_gethostbyname(externhost, &ahp))) 12732 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 12733 else 12734 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 12735 time(&externexpire); 12736 } else if (!strcasecmp(v->name, "externrefresh")) { 12737 if (sscanf(v->value, "%d", &externrefresh) != 1) { 12738 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 12739 externrefresh = 10; 12740 } 12741 } else if (!strcasecmp(v->name, "allow")) { 12742 ast_parse_allow_disallow(&prefs, &global_capability, v->value, 1); 12743 } else if (!strcasecmp(v->name, "disallow")) { 12744 ast_parse_allow_disallow(&prefs, &global_capability, v->value, 0); 12745 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 12746 allow_external_domains = ast_true(v->value); 12747 } else if (!strcasecmp(v->name, "autodomain")) { 12748 auto_sip_domains = ast_true(v->value); 12749 } else if (!strcasecmp(v->name, "domain")) { 12750 char *domain = ast_strdupa(v->value); 12751 char *context = strchr(domain, ','); 12752 12753 if (context) 12754 *context++ = '\0'; 12755 12756 if (option_debug && ast_strlen_zero(context)) 12757 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 12758 if (ast_strlen_zero(domain)) 12759 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 12760 else 12761 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 12762 } else if (!strcasecmp(v->name, "register")) { 12763 sip_register(v->value, v->lineno); 12764 } else if (!strcasecmp(v->name, "tos")) { 12765 if (ast_str2tos(v->value, &tos)) 12766 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 12767 } else if (!strcasecmp(v->name, "bindport")) { 12768 if (sscanf(v->value, "%d", &ourport) == 1) { 12769 bindaddr.sin_port = htons(ourport); 12770 } else { 12771 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 12772 } 12773 } else if (!strcasecmp(v->name, "qualify")) { 12774 if (!strcasecmp(v->value, "no")) { 12775 default_qualify = 0; 12776 } else if (!strcasecmp(v->value, "yes")) { 12777 default_qualify = DEFAULT_MAXMS; 12778 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 12779 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 12780 default_qualify = 0; 12781 } 12782 } else if (!strcasecmp(v->name, "callevents")) { 12783 callevents = ast_true(v->value); 12784 } 12785 /* else if (strcasecmp(v->name,"type")) 12786 * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 12787 */ 12788 v = v->next; 12789 } 12790 12791 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 12792 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 12793 allow_external_domains = 1; 12794 } 12795 12796 /* Build list of authentication to various SIP realms, i.e. service providers */ 12797 v = ast_variable_browse(cfg, "authentication"); 12798 while(v) { 12799 /* Format for authentication is auth = username:password@realm */ 12800 if (!strcasecmp(v->name, "auth")) { 12801 authl = add_realm_authentication(authl, v->value, v->lineno); 12802 } 12803 v = v->next; 12804 } 12805 12806 /* Load peers, users and friends */ 12807 cat = ast_category_browse(cfg, NULL); 12808 while(cat) { 12809 if (strcasecmp(cat, "general") && strcasecmp(cat, "authentication")) { 12810 utype = ast_variable_retrieve(cfg, cat, "type"); 12811 if (utype) { 12812 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 12813 user = build_user(cat, ast_variable_browse(cfg, cat), 0); 12814 if (user) { 12815 ASTOBJ_CONTAINER_LINK(&userl,user); 12816 ASTOBJ_UNREF(user, sip_destroy_user); 12817 } 12818 } 12819 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 12820 peer = build_peer(cat, ast_variable_browse(cfg, cat), 0); 12821 if (peer) { 12822 ASTOBJ_CONTAINER_LINK(&peerl,peer); 12823 ASTOBJ_UNREF(peer, sip_destroy_peer); 12824 } 12825 } else if (strcasecmp(utype, "user")) { 12826 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 12827 } 12828 } else 12829 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 12830 } 12831 cat = ast_category_browse(cfg, cat); 12832 } 12833 if (ast_find_ourip(&__ourip, bindaddr)) { 12834 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 12835 return 0; 12836 } 12837 if (!ntohs(bindaddr.sin_port)) 12838 bindaddr.sin_port = ntohs(DEFAULT_SIP_PORT); 12839 bindaddr.sin_family = AF_INET; 12840 ast_mutex_lock(&netlock); 12841 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 12842 close(sipsock); 12843 sipsock = -1; 12844 } 12845 if (sipsock < 0) { 12846 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 12847 if (sipsock < 0) { 12848 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 12849 } else { 12850 /* Allow SIP clients on the same host to access us: */ 12851 const int reuseFlag = 1; 12852 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 12853 (const char*)&reuseFlag, 12854 sizeof reuseFlag); 12855 12856 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 12857 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 12858 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port), 12859 strerror(errno)); 12860 close(sipsock); 12861 sipsock = -1; 12862 } else { 12863 if (option_verbose > 1) { 12864 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 12865 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 12866 ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos); 12867 } 12868 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) 12869 ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos); 12870 } 12871 } 12872 } 12873 ast_mutex_unlock(&netlock); 12874 12875 /* Add default domains - host name, IP address and IP:port */ 12876 /* Only do this if user added any sip domain with "localdomains" */ 12877 /* In order to *not* break backwards compatibility */ 12878 /* Some phones address us at IP only, some with additional port number */ 12879 if (auto_sip_domains) { 12880 char temp[MAXHOSTNAMELEN]; 12881 12882 /* First our default IP address */ 12883 if (bindaddr.sin_addr.s_addr) { 12884 ast_inet_ntoa(temp, sizeof(temp), bindaddr.sin_addr); 12885 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12886 } else { 12887 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 12888 } 12889 12890 /* Our extern IP address, if configured */ 12891 if (externip.sin_addr.s_addr) { 12892 ast_inet_ntoa(temp, sizeof(temp), externip.sin_addr); 12893 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12894 } 12895 12896 /* Extern host name (NAT traversal support) */ 12897 if (!ast_strlen_zero(externhost)) 12898 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 12899 12900 /* Our host name */ 12901 if (!gethostname(temp, sizeof(temp))) 12902 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 12903 } 12904 12905 /* Release configuration from memory */ 12906 ast_config_destroy(cfg); 12907 12908 /* Load the list of manual NOTIFY types to support */ 12909 if (notify_types) 12910 ast_config_destroy(notify_types); 12911 notify_types = ast_config_load(notify_config); 12912 12913 return 0; 12914 }
static int reply_digest | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
char * | header, | |||
int | sipmethod, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
reply_digest: reply to authentication for outbound registrations ---
Definition at line 9056 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), build_reply_digest(), sip_registry::domain, sip_pvt::domain, get_header(), key(), keys, LOG_WARNING, sip_registry::nonce, sip_pvt::nonce, sip_registry::noncecount, sip_pvt::noncecount, sip_registry::opaque, sip_pvt::opaque, sip_registry::qop, sip_pvt::qop, sip_registry::realm, sip_pvt::realm, sip_pvt::registry, and strsep().
Referenced by do_proxy_auth(), and do_register_auth().
09058 { 09059 char tmp[512]; 09060 char *c; 09061 char oldnonce[256]; 09062 09063 /* table of recognised keywords, and places where they should be copied */ 09064 const struct x { 09065 const char *key; 09066 char *dst; 09067 int dstlen; 09068 } *i, keys[] = { 09069 { "realm=", p->realm, sizeof(p->realm) }, 09070 { "nonce=", p->nonce, sizeof(p->nonce) }, 09071 { "opaque=", p->opaque, sizeof(p->opaque) }, 09072 { "qop=", p->qop, sizeof(p->qop) }, 09073 { "domain=", p->domain, sizeof(p->domain) }, 09074 { NULL, NULL, 0 }, 09075 }; 09076 09077 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 09078 if (ast_strlen_zero(tmp)) 09079 return -1; 09080 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 09081 ast_log(LOG_WARNING, "missing Digest.\n"); 09082 return -1; 09083 } 09084 c = tmp + strlen("Digest "); 09085 for (i = keys; i->key != NULL; i++) 09086 i->dst[0] = '\0'; /* init all to empty strings */ 09087 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 09088 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 09089 for (i = keys; i->key != NULL; i++) { 09090 char *src, *separator; 09091 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 09092 continue; 09093 /* Found. Skip keyword, take text in quotes or up to the separator. */ 09094 c += strlen(i->key); 09095 if (*c == '\"') { 09096 src = ++c; 09097 separator = "\""; 09098 } else { 09099 src = c; 09100 separator = ","; 09101 } 09102 strsep(&c, separator); /* clear separator and move ptr */ 09103 ast_copy_string(i->dst, src, i->dstlen); 09104 break; 09105 } 09106 if (i->key == NULL) /* not found, try ',' */ 09107 strsep(&c, ","); 09108 } 09109 /* Reset nonce count */ 09110 if (strcmp(p->nonce, oldnonce)) 09111 p->noncecount = 0; 09112 09113 /* Save auth data for following registrations */ 09114 if (p->registry) { 09115 struct sip_registry *r = p->registry; 09116 09117 if (strcmp(r->nonce, p->nonce)) { 09118 ast_copy_string(r->realm, p->realm, sizeof(r->realm)); 09119 ast_copy_string(r->nonce, p->nonce, sizeof(r->nonce)); 09120 ast_copy_string(r->domain, p->domain, sizeof(r->domain)); 09121 ast_copy_string(r->opaque, p->opaque, sizeof(r->opaque)); 09122 ast_copy_string(r->qop, p->qop, sizeof(r->qop)); 09123 r->noncecount = 0; 09124 } 09125 } 09126 return build_reply_digest(p, sipmethod, digest, digest_len); 09127 }
static int reqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod, | |||
int | seqno, | |||
int | newbranch | |||
) | [static] |
reqprep: Initialize a SIP request response packet ---
Definition at line 4128 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.
04129 { 04130 struct sip_request *orig = &p->initreq; 04131 char stripped[80]; 04132 char tmp[80]; 04133 char newto[256]; 04134 char *c, *n; 04135 char *ot, *of; 04136 int is_strict = 0; /* Strict routing flag */ 04137 04138 memset(req, 0, sizeof(struct sip_request)); 04139 04140 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 04141 04142 if (!seqno) { 04143 p->ocseq++; 04144 seqno = p->ocseq; 04145 } 04146 04147 if (newbranch) { 04148 p->branch ^= thread_safe_rand(); 04149 build_via(p, p->via, sizeof(p->via)); 04150 } 04151 04152 /* Check for strict or loose router */ 04153 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) 04154 is_strict = 1; 04155 04156 if (sipmethod == SIP_CANCEL) { 04157 c = p->initreq.rlPart2; /* Use original URI */ 04158 } else if (sipmethod == SIP_ACK) { 04159 /* Use URI from Contact: in 200 OK (if INVITE) 04160 (we only have the contacturi on INVITEs) */ 04161 if (!ast_strlen_zero(p->okcontacturi)) 04162 c = is_strict ? p->route->hop : p->okcontacturi; 04163 else 04164 c = p->initreq.rlPart2; 04165 } else if (!ast_strlen_zero(p->okcontacturi)) { 04166 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 04167 } else if (!ast_strlen_zero(p->uri)) { 04168 c = p->uri; 04169 } else { 04170 /* We have no URI, use To: or From: header as URI (depending on direction) */ 04171 c = get_header(orig, (ast_test_flag(p, SIP_OUTGOING)) ? "To" : "From"); 04172 ast_copy_string(stripped, c, sizeof(stripped)); 04173 c = get_in_brackets(stripped); 04174 n = strchr(c, ';'); 04175 if (n) 04176 *n = '\0'; 04177 } 04178 init_req(req, sipmethod, c); 04179 04180 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 04181 04182 add_header(req, "Via", p->via); 04183 if (p->route) { 04184 set_destination(p, p->route->hop); 04185 if (is_strict) 04186 add_route(req, p->route->next); 04187 else 04188 add_route(req, p->route); 04189 } 04190 04191 ot = get_header(orig, "To"); 04192 of = get_header(orig, "From"); 04193 04194 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 04195 as our original request, including tag (or presumably lack thereof) */ 04196 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 04197 /* Add the proper tag if we don't have it already. If they have specified 04198 their tag, use it. Otherwise, use our own tag */ 04199 if (ast_test_flag(p, SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 04200 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 04201 else if (!ast_test_flag(p, SIP_OUTGOING)) 04202 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 04203 else 04204 snprintf(newto, sizeof(newto), "%s", ot); 04205 ot = newto; 04206 } 04207 04208 if (ast_test_flag(p, SIP_OUTGOING)) { 04209 add_header(req, "From", of); 04210 add_header(req, "To", ot); 04211 } else { 04212 add_header(req, "From", ot); 04213 add_header(req, "To", of); 04214 } 04215 add_header(req, "Contact", p->our_contact); 04216 copy_header(req, orig, "Call-ID"); 04217 add_header(req, "CSeq", tmp); 04218 04219 add_header(req, "User-Agent", default_useragent); 04220 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 04221 04222 if (p->rpid) 04223 add_header(req, "Remote-Party-ID", p->rpid); 04224 04225 return 0; 04226 }
static int respprep | ( | struct sip_request * | resp, | |
struct sip_pvt * | p, | |||
char * | msg, | |||
struct sip_request * | req | |||
) | [static] |
respprep: Prepare SIP response packet ---
Definition at line 4080 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.
04081 { 04082 char newto[256], *ot; 04083 04084 memset(resp, 0, sizeof(*resp)); 04085 init_resp(resp, msg, req); 04086 copy_via_headers(p, resp, req, "Via"); 04087 if (msg[0] == '2') 04088 copy_all_header(resp, req, "Record-Route"); 04089 copy_header(resp, req, "From"); 04090 ot = get_header(req, "To"); 04091 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 04092 /* Add the proper tag if we don't have it already. If they have specified 04093 their tag, use it. Otherwise, use our own tag */ 04094 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(p, SIP_OUTGOING)) 04095 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 04096 else if (p->tag && !ast_test_flag(p, SIP_OUTGOING)) 04097 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 04098 else { 04099 ast_copy_string(newto, ot, sizeof(newto)); 04100 newto[sizeof(newto) - 1] = '\0'; 04101 } 04102 ot = newto; 04103 } 04104 add_header(resp, "To", ot); 04105 copy_header(resp, req, "Call-ID"); 04106 copy_header(resp, req, "CSeq"); 04107 add_header(resp, "User-Agent", default_useragent); 04108 add_header(resp, "Allow", ALLOWED_METHODS); 04109 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 04110 /* For registration responses, we also need expiry and 04111 contact info */ 04112 char tmp[256]; 04113 04114 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 04115 add_header(resp, "Expires", tmp); 04116 if (p->expiry) { /* Only add contact if we have an expiry time */ 04117 char contact[SIP_LEN_CONTACT]; 04118 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 04119 add_header(resp, "Contact", contact); /* Not when we unregister */ 04120 } 04121 } else if (p->our_contact[0]) { 04122 add_header(resp, "Contact", p->our_contact); 04123 } 04124 return 0; 04125 }
static int restart_monitor | ( | void | ) | [static] |
restart_monitor: Start the channel monitor thread ---
Definition at line 11577 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.
11578 { 11579 /* If we're supposed to be stopped -- stay stopped */ 11580 if (monitor_thread == AST_PTHREADT_STOP) 11581 return 0; 11582 if (ast_mutex_lock(&monlock)) { 11583 ast_log(LOG_WARNING, "Unable to lock monitor\n"); 11584 return -1; 11585 } 11586 if (monitor_thread == pthread_self()) { 11587 ast_mutex_unlock(&monlock); 11588 ast_log(LOG_WARNING, "Cannot kill myself\n"); 11589 return -1; 11590 } 11591 if (monitor_thread != AST_PTHREADT_NULL) { 11592 /* Wake up the thread */ 11593 pthread_kill(monitor_thread, SIGURG); 11594 } else { 11595 /* Start a new monitor */ 11596 if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) { 11597 ast_mutex_unlock(&monlock); 11598 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 11599 return -1; 11600 } 11601 } 11602 ast_mutex_unlock(&monlock); 11603 return 0; 11604 }
static int retrans_pkt | ( | void * | data | ) | [static] |
retrans_pkt: Retransmit SIP message if no answer ---
Definition at line 1173 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.
01174 { 01175 struct sip_pkt *pkt=data, *prev, *cur = NULL; 01176 char iabuf[INET_ADDRSTRLEN]; 01177 int reschedule = DEFAULT_RETRANS; 01178 01179 /* Lock channel */ 01180 ast_mutex_lock(&pkt->owner->lock); 01181 01182 if (pkt->retrans < MAX_RETRANS) { 01183 char buf[80]; 01184 01185 pkt->retrans++; 01186 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01187 if (sipdebug && option_debug > 3) 01188 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); 01189 } else { 01190 int siptimer_a; 01191 01192 if (sipdebug && option_debug > 3) 01193 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01194 if (!pkt->timer_a) 01195 pkt->timer_a = 2 ; 01196 else 01197 pkt->timer_a = 2 * pkt->timer_a; 01198 01199 /* For non-invites, a maximum of 4 secs */ 01200 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01201 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01202 siptimer_a = 4000; 01203 01204 /* Reschedule re-transmit */ 01205 reschedule = siptimer_a; 01206 if (option_debug > 3) 01207 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); 01208 } 01209 01210 if (pkt->owner && sip_debug_test_pvt(pkt->owner)) { 01211 if (ast_test_flag(pkt->owner, SIP_NAT) & SIP_NAT_ROUTE) 01212 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); 01213 else 01214 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); 01215 } 01216 snprintf(buf, sizeof(buf), "ReTx %d", reschedule); 01217 01218 append_history(pkt->owner, buf, pkt->data); 01219 __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01220 ast_mutex_unlock(&pkt->owner->lock); 01221 return reschedule; 01222 } 01223 /* Too many retries */ 01224 if (pkt->owner && pkt->method != SIP_OPTIONS) { 01225 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01226 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"); 01227 } else { 01228 if (pkt->method == SIP_OPTIONS && sipdebug) 01229 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid); 01230 } 01231 append_history(pkt->owner, "MaxRetries", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01232 01233 pkt->retransid = -1; 01234 01235 if (ast_test_flag(pkt, FLAG_FATAL)) { 01236 while(pkt->owner->owner && ast_mutex_trylock(&pkt->owner->owner->lock)) { 01237 ast_mutex_unlock(&pkt->owner->lock); 01238 usleep(1); 01239 ast_mutex_lock(&pkt->owner->lock); 01240 } 01241 if (pkt->owner->owner) { 01242 ast_set_flag(pkt->owner, SIP_ALREADYGONE); 01243 ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid); 01244 ast_queue_hangup(pkt->owner->owner); 01245 ast_mutex_unlock(&pkt->owner->owner->lock); 01246 } else { 01247 /* If no channel owner, destroy now */ 01248 ast_set_flag(pkt->owner, SIP_NEEDDESTROY); 01249 } 01250 } 01251 /* In any case, go ahead and remove the packet */ 01252 prev = NULL; 01253 cur = pkt->owner->packets; 01254 while(cur) { 01255 if (cur == pkt) 01256 break; 01257 prev = cur; 01258 cur = cur->next; 01259 } 01260 if (cur) { 01261 if (prev) 01262 prev->next = cur->next; 01263 else 01264 pkt->owner->packets = cur->next; 01265 ast_mutex_unlock(&pkt->owner->lock); 01266 free(cur); 01267 pkt = NULL; 01268 } else 01269 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 01270 if (pkt) 01271 ast_mutex_unlock(&pkt->owner->lock); 01272 return 0; 01273 }
static void sdpLineNum_iterator_init | ( | int * | iterator, | |
struct sip_request * | req | |||
) | [static] |
Definition at line 2906 of file chan_sip.c.
References sip_request::sdp_start.
02907 { 02908 *iterator = req->sdp_start; 02909 }
static int send_request | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | reliable, | |||
int | seqno | |||
) | [static] |
send_request: Send SIP Request to the other part of the dialogue ---
Definition at line 1515 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.
01516 { 01517 int res; 01518 char iabuf[INET_ADDRSTRLEN]; 01519 struct sip_request tmp; 01520 char tmpmsg[80]; 01521 01522 if (sip_debug_test_pvt(p)) { 01523 if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) 01524 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); 01525 else 01526 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); 01527 } 01528 if (reliable) { 01529 if (recordhistory) { 01530 parse_copy(&tmp, req); 01531 snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq")); 01532 append_history(p, "TxReqRel", tmpmsg); 01533 } 01534 res = __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable > 1), req->method); 01535 } else { 01536 if (recordhistory) { 01537 parse_copy(&tmp, req); 01538 snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq")); 01539 append_history(p, "TxReq", tmpmsg); 01540 } 01541 res = __sip_xmit(p, req->data, req->len); 01542 } 01543 return res; 01544 }
static int send_response | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | reliable, | |||
int | seqno | |||
) | [static] |
send_response: Transmit response on SIP request---
Definition at line 1481 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.
01482 { 01483 int res; 01484 char iabuf[INET_ADDRSTRLEN]; 01485 struct sip_request tmp; 01486 char tmpmsg[80]; 01487 01488 if (sip_debug_test_pvt(p)) { 01489 if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) 01490 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); 01491 else 01492 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); 01493 } 01494 if (reliable) { 01495 if (recordhistory) { 01496 parse_copy(&tmp, req); 01497 snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq")); 01498 append_history(p, "TxRespRel", tmpmsg); 01499 } 01500 res = __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable > 1), req->method); 01501 } else { 01502 if (recordhistory) { 01503 parse_copy(&tmp, req); 01504 snprintf(tmpmsg, sizeof(tmpmsg), "%s / %s", tmp.data, get_header(&tmp, "CSeq")); 01505 append_history(p, "TxResp", tmpmsg); 01506 } 01507 res = __sip_xmit(p, req->data, req->len); 01508 } 01509 if (res > 0) 01510 return 0; 01511 return res; 01512 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
set_destination: Set destination from SIP URI ---
Definition at line 3984 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().
03985 { 03986 char *h, *maddr, hostname[256]; 03987 char iabuf[INET_ADDRSTRLEN]; 03988 int port, hn; 03989 struct hostent *hp; 03990 struct ast_hostent ahp; 03991 int debug=sip_debug_test_pvt(p); 03992 03993 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 03994 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 03995 03996 if (debug) 03997 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 03998 03999 /* Find and parse hostname */ 04000 h = strchr(uri, '@'); 04001 if (h) 04002 ++h; 04003 else { 04004 h = uri; 04005 if (strncmp(h, "sip:", 4) == 0) 04006 h += 4; 04007 else if (strncmp(h, "sips:", 5) == 0) 04008 h += 5; 04009 } 04010 hn = strcspn(h, ":;>") + 1; 04011 if (hn > sizeof(hostname)) 04012 hn = sizeof(hostname); 04013 ast_copy_string(hostname, h, hn); 04014 h += hn - 1; 04015 04016 /* Is "port" present? if not default to DEFAULT_SIP_PORT */ 04017 if (*h == ':') { 04018 /* Parse port */ 04019 ++h; 04020 port = strtol(h, &h, 10); 04021 } 04022 else 04023 port = DEFAULT_SIP_PORT; 04024 04025 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 04026 maddr = strstr(h, "maddr="); 04027 if (maddr) { 04028 maddr += 6; 04029 hn = strspn(maddr, "0123456789.") + 1; 04030 if (hn > sizeof(hostname)) hn = sizeof(hostname); 04031 ast_copy_string(hostname, maddr, hn); 04032 } 04033 04034 hp = ast_gethostbyname(hostname, &ahp); 04035 if (hp == NULL) { 04036 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 04037 return; 04038 } 04039 p->sa.sin_family = AF_INET; 04040 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 04041 p->sa.sin_port = htons(port); 04042 if (debug) 04043 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), port); 04044 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
sip_addheader: Add a SIP header ---
Definition at line 13075 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().
13076 { 13077 int no = 0; 13078 int ok = 0; 13079 char varbuf[128]; 13080 13081 if (ast_strlen_zero((char *)data)) { 13082 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 13083 return 0; 13084 } 13085 ast_mutex_lock(&chan->lock); 13086 13087 /* Check for headers */ 13088 while (!ok && no <= 50) { 13089 no++; 13090 snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%02d", no); 13091 if (ast_strlen_zero(pbx_builtin_getvar_helper(chan, varbuf + 1))) 13092 ok = 1; 13093 } 13094 if (ok) { 13095 pbx_builtin_setvar_helper (chan, varbuf, (char *)data); 13096 if (sipdebug) 13097 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", (char *) data, varbuf); 13098 } else { 13099 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 13100 } 13101 ast_mutex_unlock(&chan->lock); 13102 return 0; 13103 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
sip_addrcmp: Support routine for find_peer ---
Definition at line 1754 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
01755 { 01756 /* We know name is the first field, so we can cast */ 01757 struct sip_peer *p = (struct sip_peer *)name; 01758 return !(!inaddrcmp(&p->addr, sin) || 01759 (ast_test_flag(p, SIP_INSECURE_PORT) && 01760 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 01761 }
static struct sip_pvt* sip_alloc | ( | char * | callid, | |
struct sockaddr_in * | sin, | |||
int | useglobal_nat, | |||
const int | intended_method | |||
) | [static] |
sip_alloc: Allocate SIP_PVT structure and set defaults ---
Definition at line 3079 of file chan_sip.c.
References 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, free, global_flags, iflist, io, LOG_DEBUG, LOG_WARNING, make_our_tag(), NONE, option_debug, prefs, sched, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_OPTIONS, SIP_REGISTER, text, and thread_safe_rand().
Referenced by find_call(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
03080 { 03081 struct sip_pvt *p; 03082 03083 if (!(p = calloc(1, sizeof(*p)))) 03084 return NULL; 03085 03086 ast_mutex_init(&p->lock); 03087 03088 p->method = intended_method; 03089 p->initid = -1; 03090 p->autokillid = -1; 03091 p->subscribed = NONE; 03092 p->stateid = -1; 03093 p->prefs = prefs; 03094 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 03095 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 03096 #ifdef OSP_SUPPORT 03097 p->osphandle = -1; 03098 p->osptimelimit = 0; 03099 #endif 03100 if (sin) { 03101 memcpy(&p->sa, sin, sizeof(p->sa)); 03102 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 03103 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 03104 } else { 03105 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 03106 } 03107 03108 p->branch = thread_safe_rand(); 03109 make_our_tag(p->tag, sizeof(p->tag)); 03110 /* Start with 101 instead of 1 */ 03111 p->ocseq = 101; 03112 03113 if (sip_methods[intended_method].need_rtp) { 03114 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 03115 if (videosupport) 03116 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 03117 if (!p->rtp || (videosupport && !p->vrtp)) { 03118 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", videosupport ? "and video" : "", strerror(errno)); 03119 ast_mutex_destroy(&p->lock); 03120 if (p->chanvars) { 03121 ast_variables_destroy(p->chanvars); 03122 p->chanvars = NULL; 03123 } 03124 free(p); 03125 return NULL; 03126 } 03127 ast_rtp_settos(p->rtp, tos); 03128 if (p->vrtp) 03129 ast_rtp_settos(p->vrtp, tos); 03130 p->rtptimeout = global_rtptimeout; 03131 p->rtpholdtimeout = global_rtpholdtimeout; 03132 p->rtpkeepalive = global_rtpkeepalive; 03133 } 03134 03135 if (useglobal_nat && sin) { 03136 /* Setup NAT structure according to global settings if we have an address */ 03137 ast_copy_flags(p, &global_flags, SIP_NAT); 03138 memcpy(&p->recv, sin, sizeof(p->recv)); 03139 if (p->rtp) 03140 ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 03141 if (p->vrtp) 03142 ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); 03143 } 03144 03145 if (p->method != SIP_REGISTER) 03146 ast_copy_string(p->fromdomain, default_fromdomain, sizeof(p->fromdomain)); 03147 build_via(p, p->via, sizeof(p->via)); 03148 if (!callid) 03149 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 03150 else 03151 ast_copy_string(p->callid, callid, sizeof(p->callid)); 03152 ast_copy_flags(p, &global_flags, SIP_FLAGS_TO_COPY); 03153 /* Assign default music on hold class */ 03154 strcpy(p->musicclass, global_musicclass); 03155 p->capability = global_capability; 03156 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO)) 03157 p->noncodeccapability |= AST_RTP_DTMF; 03158 strcpy(p->context, default_context); 03159 03160 /* Add to active dialog list */ 03161 ast_mutex_lock(&iflock); 03162 p->next = iflist; 03163 iflist = p; 03164 ast_mutex_unlock(&iflock); 03165 if (option_debug) 03166 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"); 03167 return p; 03168 }
static int sip_answer | ( | struct ast_channel * | ast | ) | [static] |
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface
Definition at line 2541 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().
02542 { 02543 int res = 0; 02544 struct sip_pvt *p = ast->tech_pvt; 02545 02546 ast_mutex_lock(&p->lock); 02547 if (ast->_state != AST_STATE_UP) { 02548 #ifdef OSP_SUPPORT 02549 time(&p->ospstart); 02550 #endif 02551 try_suggested_sip_codec(p); 02552 02553 ast_setstate(ast, AST_STATE_UP); 02554 if (option_debug) 02555 ast_log(LOG_DEBUG, "sip_answer(%s)\n", ast->name); 02556 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, 1); 02557 } 02558 ast_mutex_unlock(&p->lock); 02559 return res; 02560 }
static int sip_call | ( | struct ast_channel * | ast, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
sip_call: Initiate SIP call from PBX used from the dial() application
Definition at line 2020 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.
02021 { 02022 int res; 02023 struct sip_pvt *p; 02024 #ifdef OSP_SUPPORT 02025 char *osphandle = NULL; 02026 #endif 02027 struct varshead *headp; 02028 struct ast_var_t *current; 02029 02030 02031 02032 p = ast->tech_pvt; 02033 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 02034 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 02035 return -1; 02036 } 02037 02038 02039 /* Check whether there is vxml_url, distinctive ring variables */ 02040 02041 headp=&ast->varshead; 02042 AST_LIST_TRAVERSE(headp,current,entries) { 02043 /* Check whether there is a VXML_URL variable */ 02044 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 02045 p->options->vxml_url = ast_var_value(current); 02046 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 02047 p->options->uri_options = ast_var_value(current); 02048 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 02049 /* Check whether there is a ALERT_INFO variable */ 02050 p->options->distinctive_ring = ast_var_value(current); 02051 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 02052 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 02053 p->options->addsipheaders = 1; 02054 } 02055 02056 02057 #ifdef OSP_SUPPORT 02058 else if (!p->options->osptoken && !strcasecmp(ast_var_name(current), "OSPTOKEN")) { 02059 p->options->osptoken = ast_var_value(current); 02060 } else if (!osphandle && !strcasecmp(ast_var_name(current), "OSPHANDLE")) { 02061 osphandle = ast_var_value(current); 02062 } 02063 #endif 02064 } 02065 02066 res = 0; 02067 ast_set_flag(p, SIP_OUTGOING); 02068 #ifdef OSP_SUPPORT 02069 if (!p->options->osptoken || !osphandle || (sscanf(osphandle, "%d", &p->osphandle) != 1)) { 02070 /* Force Disable OSP support */ 02071 ast_log(LOG_DEBUG, "Disabling OSP support for this call. osptoken = %s, osphandle = %s\n", p->options->osptoken, osphandle); 02072 p->options->osptoken = NULL; 02073 osphandle = NULL; 02074 p->osphandle = -1; 02075 } 02076 #endif 02077 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 02078 res = update_call_counter(p, INC_CALL_LIMIT); 02079 if ( res != -1 ) { 02080 p->callingpres = ast->cid.cid_pres; 02081 p->jointcapability = p->capability; 02082 transmit_invite(p, SIP_INVITE, 1, 2); 02083 if (p->maxtime) { 02084 /* Initialize auto-congest time */ 02085 p->initid = ast_sched_add(sched, p->maxtime * 4, auto_congest, p); 02086 } 02087 } 02088 return res; 02089 }
static int sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
sip_cancel_destroy: Cancel destruction of SIP call ---
Definition at line 1361 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().
01362 { 01363 if (p->autokillid > -1) 01364 ast_sched_del(sched, p->autokillid); 01365 append_history(p, "CancelDestroy", ""); 01366 p->autokillid = -1; 01367 return 0; 01368 }
static int sip_debug_test_addr | ( | struct sockaddr_in * | addr | ) | [inline, static] |
sip_debug_test_addr: See if we pass debug IP filter
Definition at line 1048 of file chan_sip.c.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01049 { 01050 if (sipdebug == 0) 01051 return 0; 01052 if (debugaddr.sin_addr.s_addr) { 01053 if (((ntohs(debugaddr.sin_port) != 0) 01054 && (debugaddr.sin_port != addr->sin_port)) 01055 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01056 return 0; 01057 } 01058 return 1; 01059 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
sip_debug_test_pvt: Test PVT for debugging output
Definition at line 1062 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(), build_route(), check_via(), do_register_auth(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), handle_request(), process_sdp(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendtext(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_sip_request().
01063 { 01064 if (sipdebug == 0) 01065 return 0; 01066 return sip_debug_test_addr(((ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? &p->recv : &p->sa)); 01067 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
sip_destroy: Destroy SIP call structure ---
Definition at line 2284 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().
02285 { 02286 ast_mutex_lock(&iflock); 02287 __sip_destroy(p, 1); 02288 ast_mutex_unlock(&iflock); 02289 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
sip_destroy_peer: Destroy peer object from memory
Definition at line 1645 of file chan_sip.c.
References ast_dnsmgr_release(), ast_free_ha(), ast_sched_del(), ast_test_flag, ast_variables_destroy(), sip_peer::auth, sip_peer::call, sip_peer::chanvars, clear_realm_authentication(), sip_peer::dnsmgr, sip_peer::expire, free, sip_peer::ha, sip_peer::pokeexpire, register_peer_exten(), sched, sip_destroy(), SIP_REALTIME, and SIP_SELFDESTRUCT.
Referenced by _sip_show_peer(), build_peer(), check_user_full(), create_addr(), do_monitor(), expire_register(), function_sippeer(), register_verify(), reload_config(), sip_devicestate(), sip_do_debug_peer(), sip_prune_realtime(), unload_module(), and update_call_counter().
01646 { 01647 /* Delete it, it needs to disappear */ 01648 if (peer->call) 01649 sip_destroy(peer->call); 01650 if (peer->chanvars) { 01651 ast_variables_destroy(peer->chanvars); 01652 peer->chanvars = NULL; 01653 } 01654 if (peer->expire > -1) 01655 ast_sched_del(sched, peer->expire); 01656 if (peer->pokeexpire > -1) 01657 ast_sched_del(sched, peer->pokeexpire); 01658 register_peer_exten(peer, 0); 01659 ast_free_ha(peer->ha); 01660 if (ast_test_flag(peer, SIP_SELFDESTRUCT)) 01661 apeerobjs--; 01662 else if (ast_test_flag(peer, SIP_REALTIME)) 01663 rpeerobjs--; 01664 else 01665 speerobjs--; 01666 clear_realm_authentication(peer->auth); 01667 peer->auth = (struct sip_auth *) NULL; 01668 if (peer->dnsmgr) 01669 ast_dnsmgr_release(peer->dnsmgr); 01670 free(peer); 01671 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
sip_destroy_user: Remove user object from in-memory storage ---
Definition at line 1783 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().
01784 { 01785 ast_free_ha(user->ha); 01786 if (user->chanvars) { 01787 ast_variables_destroy(user->chanvars); 01788 user->chanvars = NULL; 01789 } 01790 if (ast_test_flag(user, SIP_REALTIME)) 01791 ruserobjs--; 01792 else 01793 suserobjs--; 01794 free(user); 01795 }
static int sip_devicestate | ( | void * | data | ) | [static] |
sip_devicestate: Part of PBX channel interface ---
Definition at line 11703 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().
11704 { 11705 char *host; 11706 char *tmp; 11707 11708 struct hostent *hp; 11709 struct ast_hostent ahp; 11710 struct sip_peer *p; 11711 11712 int res = AST_DEVICE_INVALID; 11713 11714 host = ast_strdupa(data); 11715 if ((tmp = strchr(host, '@'))) 11716 host = tmp + 1; 11717 11718 if (option_debug > 2) 11719 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 11720 11721 if ((p = find_peer(host, NULL, 1))) { 11722 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 11723 /* we have an address for the peer */ 11724 /* if qualify is turned on, check the status */ 11725 if (p->maxms && (p->lastms > p->maxms)) { 11726 res = AST_DEVICE_UNAVAILABLE; 11727 } else { 11728 /* qualify is not on, or the peer is responding properly */ 11729 /* check call limit */ 11730 if (p->call_limit && (p->inUse == p->call_limit)) 11731 res = AST_DEVICE_BUSY; 11732 else if (p->call_limit && p->inUse) 11733 res = AST_DEVICE_INUSE; 11734 else if (p->call_limit) 11735 res = AST_DEVICE_NOT_INUSE; 11736 else 11737 res = AST_DEVICE_UNKNOWN; 11738 } 11739 } else { 11740 /* there is no address, it's unavailable */ 11741 res = AST_DEVICE_UNAVAILABLE; 11742 } 11743 ASTOBJ_UNREF(p,sip_destroy_peer); 11744 } else { 11745 hp = ast_gethostbyname(host, &ahp); 11746 if (hp) 11747 res = AST_DEVICE_UNKNOWN; 11748 } 11749 11750 return res; 11751 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_do_debug: Turn on SIP debugging (CLI command)
Definition at line 8888 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.
08889 { 08890 int oldsipdebug = sipdebug & SIP_DEBUG_CONSOLE; 08891 if (argc != 2) { 08892 if (argc != 4) 08893 return RESULT_SHOWUSAGE; 08894 else if (strncmp(argv[2], "ip\0", 3) == 0) 08895 return sip_do_debug_ip(fd, argc, argv); 08896 else if (strncmp(argv[2], "peer\0", 5) == 0) 08897 return sip_do_debug_peer(fd, argc, argv); 08898 else return RESULT_SHOWUSAGE; 08899 } 08900 sipdebug |= SIP_DEBUG_CONSOLE; 08901 memset(&debugaddr, 0, sizeof(debugaddr)); 08902 if (oldsipdebug) 08903 ast_cli(fd, "SIP Debugging re-enabled\n"); 08904 else 08905 ast_cli(fd, "SIP Debugging enabled\n"); 08906 return RESULT_SUCCESS; 08907 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_do_debug: Enable SIP Debugging in CLI ---
Definition at line 8832 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().
08833 { 08834 struct hostent *hp; 08835 struct ast_hostent ahp; 08836 char iabuf[INET_ADDRSTRLEN]; 08837 int port = 0; 08838 char *p, *arg; 08839 08840 if (argc != 4) 08841 return RESULT_SHOWUSAGE; 08842 arg = argv[3]; 08843 p = strstr(arg, ":"); 08844 if (p) { 08845 *p = '\0'; 08846 p++; 08847 port = atoi(p); 08848 } 08849 hp = ast_gethostbyname(arg, &ahp); 08850 if (hp == NULL) { 08851 return RESULT_SHOWUSAGE; 08852 } 08853 debugaddr.sin_family = AF_INET; 08854 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 08855 debugaddr.sin_port = htons(port); 08856 if (port == 0) 08857 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr)); 08858 else 08859 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), port); 08860 sipdebug |= SIP_DEBUG_CONSOLE; 08861 return RESULT_SUCCESS; 08862 }
static int sip_do_debug_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_do_debug_peer: Turn on SIP debugging with peer mask
Definition at line 8865 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().
08866 { 08867 struct sip_peer *peer; 08868 char iabuf[INET_ADDRSTRLEN]; 08869 if (argc != 4) 08870 return RESULT_SHOWUSAGE; 08871 peer = find_peer(argv[3], NULL, 1); 08872 if (peer) { 08873 if (peer->addr.sin_addr.s_addr) { 08874 debugaddr.sin_family = AF_INET; 08875 memcpy(&debugaddr.sin_addr, &peer->addr.sin_addr, sizeof(debugaddr.sin_addr)); 08876 debugaddr.sin_port = peer->addr.sin_port; 08877 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 08878 sipdebug |= SIP_DEBUG_CONSOLE; 08879 } else 08880 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[3]); 08881 ASTOBJ_UNREF(peer,sip_destroy_peer); 08882 } else 08883 ast_cli(fd, "No such peer '%s'\n", argv[3]); 08884 return RESULT_SUCCESS; 08885 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_do_history: Enable SIP History logging (CLI) ---
Definition at line 8967 of file chan_sip.c.
References ast_cli(), recordhistory, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
08968 { 08969 if (argc != 2) { 08970 return RESULT_SHOWUSAGE; 08971 } 08972 recordhistory = 1; 08973 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 08974 return RESULT_SUCCESS; 08975 }
static int sip_do_reload | ( | void | ) | [static] |
sip_do_reload: Reload module
Definition at line 13289 of file chan_sip.c.
References ast_log(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, authl, clear_realm_authentication(), clear_sip_domains(), LOG_DEBUG, option_debug, regl, and sip_destroy().
Referenced by do_monitor().
13290 { 13291 clear_realm_authentication(authl); 13292 clear_sip_domains(); 13293 authl = NULL; 13294 13295 /* First, destroy all outstanding registry calls */ 13296 /* This is needed, since otherwise active registry entries will not be destroyed */ 13297 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 13298 ASTOBJ_RDLOCK(iterator); 13299 if (iterator->call) { 13300 if (option_debug > 2) 13301 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 13302 /* This will also remove references to the registry */ 13303 sip_destroy(iterator->call); 13304 } 13305 ASTOBJ_UNLOCK(iterator); 13306 } while(0)); 13307 13308 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 13309 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 13310 ASTOBJ_CONTAINER_MARKALL(&peerl); 13311 reload_config(); 13312 /* Prune peers who still are supposed to be deleted */ 13313 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 13314 13315 sip_poke_all_peers(); 13316 sip_send_all_registers(); 13317 13318 return 0; 13319 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
sip_dtmfmode: change the DTMFmode for a SIP call (application) ---
Definition at line 13025 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().
13026 { 13027 struct sip_pvt *p; 13028 char *mode; 13029 if (data) 13030 mode = (char *)data; 13031 else { 13032 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 13033 return 0; 13034 } 13035 ast_mutex_lock(&chan->lock); 13036 if (chan->type != channeltype) { 13037 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 13038 ast_mutex_unlock(&chan->lock); 13039 return 0; 13040 } 13041 p = chan->tech_pvt; 13042 if (!p) { 13043 ast_mutex_unlock(&chan->lock); 13044 return 0; 13045 } 13046 ast_mutex_lock(&p->lock); 13047 if (!strcasecmp(mode,"info")) { 13048 ast_clear_flag(p, SIP_DTMF); 13049 ast_set_flag(p, SIP_DTMF_INFO); 13050 } else if (!strcasecmp(mode,"rfc2833")) { 13051 ast_clear_flag(p, SIP_DTMF); 13052 ast_set_flag(p, SIP_DTMF_RFC2833); 13053 } else if (!strcasecmp(mode,"inband")) { 13054 ast_clear_flag(p, SIP_DTMF); 13055 ast_set_flag(p, SIP_DTMF_INBAND); 13056 } else 13057 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 13058 if (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) { 13059 if (!p->vad) { 13060 p->vad = ast_dsp_new(); 13061 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 13062 } 13063 } else { 13064 if (p->vad) { 13065 ast_dsp_free(p->vad); 13066 p->vad = NULL; 13067 } 13068 } 13069 ast_mutex_unlock(&p->lock); 13070 ast_mutex_unlock(&chan->lock); 13071 return 0; 13072 }
void sip_dump_history | ( | struct sip_pvt * | dialog | ) | [static] |
dump_history: Dump SIP history to debug log file at end of lifespan for SIP dialog
Definition at line 8713 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().
08714 { 08715 int x; 08716 struct sip_history *hist; 08717 08718 if (!dialog) 08719 return; 08720 08721 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 08722 if (dialog->subscribed) 08723 ast_log(LOG_DEBUG, " * Subscription\n"); 08724 else 08725 ast_log(LOG_DEBUG, " * SIP Call\n"); 08726 x = 0; 08727 hist = dialog->history; 08728 while(hist) { 08729 x++; 08730 ast_log(LOG_DEBUG, " %d. %s\n", x, hist->event); 08731 hist = hist->next; 08732 } 08733 if (!x) 08734 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 08735 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 08736 08737 }
static int sip_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links ----
Definition at line 2616 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.
02617 { 02618 struct sip_pvt *p = newchan->tech_pvt; 02619 ast_mutex_lock(&p->lock); 02620 if (p->owner != oldchan) { 02621 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 02622 ast_mutex_unlock(&p->lock); 02623 return -1; 02624 } 02625 p->owner = newchan; 02626 ast_mutex_unlock(&p->lock); 02627 return 0; 02628 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
sip_get_codec: Return SIP UA's codec (part of the RTP interface) ---
Definition at line 13240 of file chan_sip.c.
References sip_pvt::peercapability, and ast_channel::tech_pvt.
13241 { 13242 struct sip_pvt *p = chan->tech_pvt; 13243 return p->peercapability; 13244 }
static struct ast_rtp* sip_get_rtp_peer | ( | struct ast_channel * | chan | ) | [static] |
sip_get_rtp_peer: Returns null if we can't reinvite (part of RTP interface)
Definition at line 12917 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.
12918 { 12919 struct sip_pvt *p; 12920 struct ast_rtp *rtp = NULL; 12921 p = chan->tech_pvt; 12922 if (!p) 12923 return NULL; 12924 ast_mutex_lock(&p->lock); 12925 if (p->rtp && ast_test_flag(p, SIP_CAN_REINVITE)) 12926 rtp = p->rtp; 12927 ast_mutex_unlock(&p->lock); 12928 return rtp; 12929 }
static struct ast_rtp* sip_get_vrtp_peer | ( | struct ast_channel * | chan | ) | [static] |
sip_get_vrtp_peer: Returns null if we can't reinvite video (part of RTP interface)
Definition at line 12932 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.
12933 { 12934 struct sip_pvt *p; 12935 struct ast_rtp *rtp = NULL; 12936 p = chan->tech_pvt; 12937 if (!p) 12938 return NULL; 12939 12940 ast_mutex_lock(&p->lock); 12941 if (p->vrtp && ast_test_flag(p, SIP_CAN_REINVITE)) 12942 rtp = p->vrtp; 12943 ast_mutex_unlock(&p->lock); 12944 return rtp; 12945 }
static int sip_getheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
sip_getheader: Get a SIP header (dialplan app) ---
Definition at line 13106 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().
13107 { 13108 char *argv, *varname = NULL, *header = NULL, *content, *options = NULL; 13109 static int dep_warning = 0; 13110 struct sip_pvt *p; 13111 int priority_jump = 0; 13112 13113 if (!dep_warning) { 13114 ast_log(LOG_WARNING, "SIPGetHeader is deprecated, use the SIP_HEADER function instead.\n"); 13115 dep_warning = 1; 13116 } 13117 13118 argv = ast_strdupa(data); 13119 if (!argv) { 13120 ast_log(LOG_DEBUG, "Memory allocation failed\n"); 13121 return 0; 13122 } 13123 13124 if (strchr (argv, '=') ) { /* Pick out argument */ 13125 varname = strsep (&argv, "="); 13126 if (strchr(argv, '|')) { 13127 header = strsep (&argv, "|"); 13128 options = strsep (&argv, "\0"); 13129 } else { 13130 header = strsep (&argv, "\0"); 13131 } 13132 13133 } 13134 13135 if (!varname || !header) { 13136 ast_log(LOG_DEBUG, "SIPGetHeader: Ignoring command, Syntax error in argument\n"); 13137 return 0; 13138 } 13139 13140 if (options) { 13141 if (strchr(options, 'j')) 13142 priority_jump = 1; 13143 } 13144 13145 ast_mutex_lock(&chan->lock); 13146 if (chan->type != channeltype) { 13147 ast_log(LOG_WARNING, "Call this application only on incoming SIP calls\n"); 13148 ast_mutex_unlock(&chan->lock); 13149 return 0; 13150 } 13151 13152 p = chan->tech_pvt; 13153 content = get_header(&p->initreq, header); /* Get the header */ 13154 if (!ast_strlen_zero(content)) { 13155 pbx_builtin_setvar_helper(chan, varname, content); 13156 if (option_verbose > 2) 13157 ast_verbose(VERBOSE_PREFIX_3 "SIPGetHeader: set variable %s to %s\n", varname, content); 13158 pbx_builtin_setvar_helper(chan, "SIPGETSTATUS", "FOUND"); 13159 } else { 13160 ast_log(LOG_WARNING,"SIP Header %s not found for channel variable %s\n", header, varname); 13161 if (priority_jump || option_priority_jumping) { 13162 /* Goto priority n+101 if it exists, where n is the current priority number */ 13163 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101); 13164 } 13165 pbx_builtin_setvar_helper(chan, "SIPGETSTATUS", "NOTFOUND"); 13166 } 13167 13168 ast_mutex_unlock(&chan->lock); 13169 return 0; 13170 }
static int sip_hangup | ( | struct ast_channel * | ast | ) | [static] |
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup
Definition at line 2414 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.
02415 { 02416 struct sip_pvt *p = ast->tech_pvt; 02417 int needcancel = 0; 02418 int needdestroy = 0; 02419 02420 if (!p) { 02421 ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n"); 02422 return 0; 02423 } 02424 if (option_debug) 02425 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 02426 02427 ast_mutex_lock(&p->lock); 02428 #ifdef OSP_SUPPORT 02429 if ((p->osphandle > -1) && (ast->_state == AST_STATE_UP)) { 02430 ast_osp_terminate(p->osphandle, AST_CAUSE_NORMAL, p->ospstart, time(NULL) - p->ospstart); 02431 } 02432 #endif 02433 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter\n", p->username); 02434 update_call_counter(p, DEC_CALL_LIMIT); 02435 /* Determine how to disconnect */ 02436 if (p->owner != ast) { 02437 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 02438 ast_mutex_unlock(&p->lock); 02439 return 0; 02440 } 02441 /* If the call is not UP, we need to send CANCEL instead of BYE */ 02442 if (ast->_state != AST_STATE_UP) 02443 needcancel = 1; 02444 02445 /* Disconnect */ 02446 if (p->vad) { 02447 ast_dsp_free(p->vad); 02448 } 02449 p->owner = NULL; 02450 ast->tech_pvt = NULL; 02451 02452 ast_mutex_lock(&usecnt_lock); 02453 usecnt--; 02454 ast_mutex_unlock(&usecnt_lock); 02455 ast_update_use_count(); 02456 02457 /* Do not destroy this pvt until we have timeout or 02458 get an answer to the BYE or INVITE/CANCEL 02459 If we get no answer during retransmit period, drop the call anyway. 02460 (Sorry, mother-in-law, you can't deny a hangup by sending 02461 603 declined to BYE...) 02462 */ 02463 if (ast_test_flag(p, SIP_ALREADYGONE)) 02464 needdestroy = 1; /* Set destroy flag at end of this function */ 02465 else 02466 sip_scheddestroy(p, 32000); 02467 02468 /* Start the process if it's not already started */ 02469 if (!ast_test_flag(p, SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 02470 if (needcancel) { /* Outgoing call, not up */ 02471 if (ast_test_flag(p, SIP_OUTGOING)) { 02472 /* stop retransmitting an INVITE that has not received a response */ 02473 __sip_pretend_ack(p); 02474 02475 /* are we allowed to send CANCEL yet? if not, mark 02476 it pending */ 02477 if (!ast_test_flag(p, SIP_CAN_BYE)) { 02478 ast_set_flag(p, SIP_PENDINGBYE); 02479 /* Do we need a timer here if we don't hear from them at all? */ 02480 } else { 02481 /* Send a new request: CANCEL */ 02482 transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0); 02483 /* Actually don't destroy us yet, wait for the 487 on our original 02484 INVITE, but do set an autodestruct just in case we never get it. */ 02485 } 02486 if ( p->initid != -1 ) { 02487 /* channel still up - reverse dec of inUse counter 02488 only if the channel is not auto-congested */ 02489 update_call_counter(p, INC_CALL_LIMIT); 02490 } 02491 } else { /* Incoming call, not up */ 02492 char *res; 02493 if (ast->hangupcause && ((res = hangup_cause2sip(ast->hangupcause)))) { 02494 transmit_response_reliable(p, res, &p->initreq, 1); 02495 } else 02496 transmit_response_reliable(p, "603 Declined", &p->initreq, 1); 02497 } 02498 } else { /* Call is in UP state, send BYE */ 02499 if (!p->pendinginvite) { 02500 /* Send a hangup */ 02501 transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); 02502 } else { 02503 /* Note we will need a BYE when this all settles out 02504 but we can't send one while we have "INVITE" outstanding. */ 02505 ast_set_flag(p, SIP_PENDINGBYE); 02506 ast_clear_flag(p, SIP_NEEDREINVITE); 02507 } 02508 } 02509 } 02510 if (needdestroy) 02511 ast_set_flag(p, SIP_NEEDDESTROY); 02512 ast_mutex_unlock(&p->lock); 02513 return 0; 02514 }
static int sip_indicate | ( | struct ast_channel * | ast, | |
int | condition | |||
) | [static] |
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 2673 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.
02674 { 02675 struct sip_pvt *p = ast->tech_pvt; 02676 int res = 0; 02677 02678 ast_mutex_lock(&p->lock); 02679 switch(condition) { 02680 case AST_CONTROL_RINGING: 02681 if (ast->_state == AST_STATE_RING) { 02682 if (!ast_test_flag(p, SIP_PROGRESS_SENT) || 02683 (ast_test_flag(p, SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 02684 /* Send 180 ringing if out-of-band seems reasonable */ 02685 transmit_response(p, "180 Ringing", &p->initreq); 02686 ast_set_flag(p, SIP_RINGING); 02687 if (ast_test_flag(p, SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 02688 break; 02689 } else { 02690 /* Well, if it's not reasonable, just send in-band */ 02691 } 02692 } 02693 res = -1; 02694 break; 02695 case AST_CONTROL_BUSY: 02696 if (ast->_state != AST_STATE_UP) { 02697 transmit_response(p, "486 Busy Here", &p->initreq); 02698 ast_set_flag(p, SIP_ALREADYGONE); 02699 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 02700 break; 02701 } 02702 res = -1; 02703 break; 02704 case AST_CONTROL_CONGESTION: 02705 if (ast->_state != AST_STATE_UP) { 02706 transmit_response(p, "503 Service Unavailable", &p->initreq); 02707 ast_set_flag(p, SIP_ALREADYGONE); 02708 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 02709 break; 02710 } 02711 res = -1; 02712 break; 02713 case AST_CONTROL_PROCEEDING: 02714 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02715 transmit_response(p, "100 Trying", &p->initreq); 02716 break; 02717 } 02718 res = -1; 02719 break; 02720 case AST_CONTROL_PROGRESS: 02721 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02722 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); 02723 ast_set_flag(p, SIP_PROGRESS_SENT); 02724 break; 02725 } 02726 res = -1; 02727 break; 02728 case AST_CONTROL_HOLD: /* The other part of the bridge are put on hold */ 02729 if (sipdebug) 02730 ast_log(LOG_DEBUG, "Bridged channel now on hold%s\n", p->callid); 02731 res = -1; 02732 break; 02733 case AST_CONTROL_UNHOLD: /* The other part of the bridge are back from hold */ 02734 if (sipdebug) 02735 ast_log(LOG_DEBUG, "Bridged channel is back from hold, let's talk! : %s\n", p->callid); 02736 res = -1; 02737 break; 02738 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 02739 if (p->vrtp && !ast_test_flag(p, SIP_NOVIDEO)) { 02740 transmit_info_with_vidupdate(p); 02741 res = 0; 02742 } else 02743 res = -1; 02744 break; 02745 case -1: 02746 res = -1; 02747 break; 02748 default: 02749 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 02750 res = -1; 02751 break; 02752 } 02753 ast_mutex_unlock(&p->lock); 02754 return res; 02755 }
static struct ast_channel* sip_new | ( | struct sip_pvt * | i, | |
int | state, | |||
char * | title | |||
) | [static] |
sip_new: Initiate a call in the SIP channel
Definition at line 2761 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().
02762 { 02763 struct ast_channel *tmp; 02764 struct ast_variable *v = NULL; 02765 int fmt; 02766 #ifdef OSP_SUPPORT 02767 char iabuf[INET_ADDRSTRLEN]; 02768 char peer[MAXHOSTNAMELEN]; 02769 #endif 02770 02771 ast_mutex_unlock(&i->lock); 02772 /* Don't hold a sip pvt lock while we allocate a channel */ 02773 tmp = ast_channel_alloc(1); 02774 ast_mutex_lock(&i->lock); 02775 if (!tmp) { 02776 ast_log(LOG_WARNING, "Unable to allocate SIP channel structure\n"); 02777 return NULL; 02778 } 02779 tmp->tech = &sip_tech; 02780 /* Select our native format based on codec preference until we receive 02781 something from another device to the contrary. */ 02782 if (i->jointcapability) 02783 tmp->nativeformats = ast_codec_choose(&i->prefs, i->jointcapability, 1); 02784 else if (i->capability) 02785 tmp->nativeformats = ast_codec_choose(&i->prefs, i->capability, 1); 02786 else 02787 tmp->nativeformats = ast_codec_choose(&i->prefs, global_capability, 1); 02788 fmt = ast_best_codec(tmp->nativeformats); 02789 02790 if (title) 02791 snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", title, (int)(long) i); 02792 else if (strchr(i->fromdomain,':')) 02793 snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", strchr(i->fromdomain,':') + 1, (int)(long) i); 02794 else 02795 snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", i->fromdomain, (int)(long) i); 02796 02797 tmp->type = channeltype; 02798 if (ast_test_flag(i, SIP_DTMF) == SIP_DTMF_INBAND) { 02799 i->vad = ast_dsp_new(); 02800 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 02801 if (relaxdtmf) 02802 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 02803 } 02804 if (i->rtp) { 02805 tmp->fds[0] = ast_rtp_fd(i->rtp); 02806 tmp->fds[1] = ast_rtcp_fd(i->rtp); 02807 } 02808 if (i->vrtp) { 02809 tmp->fds[2] = ast_rtp_fd(i->vrtp); 02810 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 02811 } 02812 if (state == AST_STATE_RING) 02813 tmp->rings = 1; 02814 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 02815 tmp->writeformat = fmt; 02816 tmp->rawwriteformat = fmt; 02817 tmp->readformat = fmt; 02818 tmp->rawreadformat = fmt; 02819 tmp->tech_pvt = i; 02820 02821 tmp->callgroup = i->callgroup; 02822 tmp->pickupgroup = i->pickupgroup; 02823 tmp->cid.cid_pres = i->callingpres; 02824 if (!ast_strlen_zero(i->accountcode)) 02825 ast_copy_string(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode)); 02826 if (i->amaflags) 02827 tmp->amaflags = i->amaflags; 02828 if (!ast_strlen_zero(i->language)) 02829 ast_copy_string(tmp->language, i->language, sizeof(tmp->language)); 02830 if (!ast_strlen_zero(i->musicclass)) 02831 ast_copy_string(tmp->musicclass, i->musicclass, sizeof(tmp->musicclass)); 02832 i->owner = tmp; 02833 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 02834 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 02835 02836 if (!ast_strlen_zero(i->cid_num)) 02837 tmp->cid.cid_num = strdup(i->cid_num); 02838 if (!ast_strlen_zero(i->cid_name)) 02839 tmp->cid.cid_name = strdup(i->cid_name); 02840 if (!ast_strlen_zero(i->rdnis)) 02841 tmp->cid.cid_rdnis = strdup(i->rdnis); 02842 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 02843 tmp->cid.cid_dnid = strdup(i->exten); 02844 02845 tmp->priority = 1; 02846 if (!ast_strlen_zero(i->uri)) { 02847 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 02848 } 02849 if (!ast_strlen_zero(i->domain)) { 02850 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 02851 } 02852 if (!ast_strlen_zero(i->useragent)) { 02853 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 02854 } 02855 if (!ast_strlen_zero(i->callid)) { 02856 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 02857 } 02858 #ifdef OSP_SUPPORT 02859 snprintf(peer, sizeof(peer), "[%s]:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), i->sa.sin_addr), ntohs(i->sa.sin_port)); 02860 pbx_builtin_setvar_helper(tmp, "OSPPEER", peer); 02861 #endif 02862 ast_setstate(tmp, state); 02863 if (state != AST_STATE_DOWN) { 02864 if (ast_pbx_start(tmp)) { 02865 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 02866 ast_hangup(tmp); 02867 tmp = NULL; 02868 } 02869 } 02870 /* Set channel variables for this call from configuration */ 02871 for (v = i->chanvars ; v ; v = v->next) 02872 pbx_builtin_setvar_helper(tmp,v->name,v->value); 02873 02874 ast_mutex_lock(&usecnt_lock); 02875 usecnt++; 02876 ast_mutex_unlock(&usecnt_lock); 02877 ast_update_use_count(); 02878 02879 return tmp; 02880 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_no_debug: Disable SIP Debugging in CLI ---
Definition at line 8989 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_DEBUG_CONSOLE, and sipdebug.
08991 { 08992 if (argc != 3) 08993 return RESULT_SHOWUSAGE; 08994 sipdebug &= ~SIP_DEBUG_CONSOLE; 08995 ast_cli(fd, "SIP Debugging Disabled\n"); 08996 return RESULT_SUCCESS; 08997 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_no_history: Disable SIP History logging (CLI) ---
Definition at line 8978 of file chan_sip.c.
References ast_cli(), recordhistory, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
08979 { 08980 if (argc != 3) { 08981 return RESULT_SHOWUSAGE; 08982 } 08983 recordhistory = 0; 08984 ast_cli(fd, "SIP History Recording Disabled\n"); 08985 return RESULT_SUCCESS; 08986 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_notify: Send SIP notify to peer
Definition at line 8910 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, RESULT_SUCCESS, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), var, and sip_pvt::via.
08911 { 08912 struct ast_variable *varlist; 08913 int i; 08914 08915 if (argc < 4) 08916 return RESULT_SHOWUSAGE; 08917 08918 if (!notify_types) { 08919 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 08920 return RESULT_FAILURE; 08921 } 08922 08923 varlist = ast_variable_browse(notify_types, argv[2]); 08924 08925 if (!varlist) { 08926 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 08927 return RESULT_FAILURE; 08928 } 08929 08930 for (i = 3; i < argc; i++) { 08931 struct sip_pvt *p; 08932 struct sip_request req; 08933 struct ast_variable *var; 08934 08935 p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY); 08936 if (!p) { 08937 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify\n"); 08938 return RESULT_FAILURE; 08939 } 08940 08941 if (create_addr(p, argv[i])) { 08942 /* Maybe they're not registered, etc. */ 08943 sip_destroy(p); 08944 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 08945 continue; 08946 } 08947 08948 initreqprep(&req, p, SIP_NOTIFY); 08949 08950 for (var = varlist; var; var = var->next) 08951 add_header(&req, var->name, var->value); 08952 08953 add_blank_header(&req); 08954 /* Recalculate our side, and recalculate Call ID */ 08955 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 08956 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 08957 build_via(p, p->via, sizeof(p->via)); 08958 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 08959 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 08960 transmit_sip_request(p, &req); 08961 sip_scheddestroy(p, 15000); 08962 } 08963 08964 return RESULT_SUCCESS; 08965 }
static int sip_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2, | |||
struct sip_request * | req | |||
) | [static] |
sip_park: Park a call ---
Definition at line 10240 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().
10241 { 10242 struct sip_dual *d; 10243 struct ast_channel *chan1m, *chan2m; 10244 pthread_t th; 10245 chan1m = ast_channel_alloc(0); 10246 chan2m = ast_channel_alloc(0); 10247 if ((!chan2m) || (!chan1m)) { 10248 if (chan1m) 10249 ast_hangup(chan1m); 10250 if (chan2m) 10251 ast_hangup(chan2m); 10252 return -1; 10253 } 10254 snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name); 10255 /* Make formats okay */ 10256 chan1m->readformat = chan1->readformat; 10257 chan1m->writeformat = chan1->writeformat; 10258 ast_channel_masquerade(chan1m, chan1); 10259 /* Setup the extensions and such */ 10260 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 10261 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 10262 chan1m->priority = chan1->priority; 10263 10264 /* We make a clone of the peer channel too, so we can play 10265 back the announcement */ 10266 snprintf(chan2m->name, sizeof (chan2m->name), "SIPPeer/%s",chan2->name); 10267 /* Make formats okay */ 10268 chan2m->readformat = chan2->readformat; 10269 chan2m->writeformat = chan2->writeformat; 10270 ast_channel_masquerade(chan2m, chan2); 10271 /* Setup the extensions and such */ 10272 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 10273 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 10274 chan2m->priority = chan2->priority; 10275 ast_mutex_lock(&chan2m->lock); 10276 if (ast_do_masquerade(chan2m)) { 10277 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 10278 ast_mutex_unlock(&chan2m->lock); 10279 ast_hangup(chan2m); 10280 return -1; 10281 } 10282 ast_mutex_unlock(&chan2m->lock); 10283 d = malloc(sizeof(struct sip_dual)); 10284 if (d) { 10285 memset(d, 0, sizeof(*d)); 10286 /* Save original request for followup */ 10287 copy_request(&d->req, req); 10288 d->chan1 = chan1m; 10289 d->chan2 = chan2m; 10290 if (!ast_pthread_create(&th, NULL, sip_park_thread, d)) 10291 return 0; 10292 free(d); 10293 } 10294 return -1; 10295 }
static void* sip_park_thread | ( | void * | stuff | ) | [static] |
sip_park_thread: Park SIP call support function
Definition at line 10217 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().
10218 { 10219 struct ast_channel *chan1, *chan2; 10220 struct sip_dual *d; 10221 struct sip_request req; 10222 int ext; 10223 int res; 10224 d = stuff; 10225 chan1 = d->chan1; 10226 chan2 = d->chan2; 10227 copy_request(&req, &d->req); 10228 free(d); 10229 ast_mutex_lock(&chan1->lock); 10230 ast_do_masquerade(chan1); 10231 ast_mutex_unlock(&chan1->lock); 10232 res = ast_park_call(chan1, chan2, 0, &ext); 10233 /* Then hangup */ 10234 ast_hangup(chan2); 10235 ast_log(LOG_DEBUG, "Parked on extension '%d'\n", ext); 10236 return NULL; 10237 }
static void sip_poke_all_peers | ( | void | ) | [static] |
sip_poke_all_peers: Send a poke to all known peers
Definition at line 13256 of file chan_sip.c.
References ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, peerl, and sip_poke_peer().
Referenced by load_module().
13257 { 13258 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 13259 ASTOBJ_WRLOCK(iterator); 13260 sip_poke_peer(iterator); 13261 ASTOBJ_UNLOCK(iterator); 13262 } while (0) 13263 ); 13264 }
static int sip_poke_noanswer | ( | void * | data | ) | [static] |
sip_poke_noanswer: No answer to Qualify poke ---
Definition at line 11607 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().
11608 { 11609 struct sip_peer *peer = data; 11610 11611 peer->pokeexpire = -1; 11612 if (peer->lastms > -1) { 11613 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 11614 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 11615 } 11616 if (peer->call) 11617 sip_destroy(peer->call); 11618 peer->call = NULL; 11619 peer->lastms = -1; 11620 ast_device_state_changed("SIP/%s", peer->name); 11621 /* Try again quickly */ 11622 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 11623 return 0; 11624 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
sip_poke_peer: Check availability of peer, also keep NAT open ---
Definition at line 11629 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().
11630 { 11631 struct sip_pvt *p; 11632 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 11633 /* IF we have no IP, or this isn't to be monitored, return 11634 imeediately after clearing things out */ 11635 if (peer->pokeexpire > -1) 11636 ast_sched_del(sched, peer->pokeexpire); 11637 peer->lastms = 0; 11638 peer->pokeexpire = -1; 11639 peer->call = NULL; 11640 return 0; 11641 } 11642 if (peer->call > 0) { 11643 if (sipdebug) 11644 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 11645 sip_destroy(peer->call); 11646 } 11647 p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS); 11648 if (!peer->call) { 11649 ast_log(LOG_WARNING, "Unable to allocate dialog for poking peer '%s'\n", peer->name); 11650 return -1; 11651 } 11652 memcpy(&p->sa, &peer->addr, sizeof(p->sa)); 11653 memcpy(&p->recv, &peer->addr, sizeof(p->sa)); 11654 ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY); 11655 11656 /* Send OPTIONs to peer's fullcontact */ 11657 if (!ast_strlen_zero(peer->fullcontact)) { 11658 ast_copy_string (p->fullcontact, peer->fullcontact, sizeof(p->fullcontact)); 11659 } 11660 11661 if (!ast_strlen_zero(peer->tohost)) 11662 ast_copy_string(p->tohost, peer->tohost, sizeof(p->tohost)); 11663 else 11664 ast_inet_ntoa(p->tohost, sizeof(p->tohost), peer->addr.sin_addr); 11665 11666 /* Recalculate our side, and recalculate Call ID */ 11667 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11668 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11669 build_via(p, p->via, sizeof(p->via)); 11670 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11671 11672 if (peer->pokeexpire > -1) 11673 ast_sched_del(sched, peer->pokeexpire); 11674 p->peerpoke = peer; 11675 ast_set_flag(p, SIP_OUTGOING); 11676 #ifdef VOCAL_DATA_HACK 11677 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 11678 transmit_invite(p, SIP_INVITE, 0, 2); 11679 #else 11680 transmit_invite(p, SIP_OPTIONS, 0, 2); 11681 #endif 11682 gettimeofday(&peer->ps, NULL); 11683 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer); 11684 11685 return 0; 11686 }
static int sip_poke_peer_s | ( | void * | data | ) | [static] |
Definition at line 5764 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().
05765 { 05766 struct sip_peer *peer = data; 05767 peer->pokeexpire = -1; 05768 sip_poke_peer(peer); 05769 return 0; 05770 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_prune_realtime: Remove temporary realtime objects from memory (CLI) ---
Definition at line 7782 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, name, peerl, RESULT_SHOWUSAGE, sip_destroy_peer(), SIP_PAGE2_RTCACHEFRIENDS, and user.
07783 { 07784 struct sip_peer *peer; 07785 struct sip_user *user; 07786 int pruneuser = 0; 07787 int prunepeer = 0; 07788 int multi = 0; 07789 char *name = NULL; 07790 regex_t regexbuf; 07791 07792 switch (argc) { 07793 case 4: 07794 if (!strcasecmp(argv[3], "user")) 07795 return RESULT_SHOWUSAGE; 07796 if (!strcasecmp(argv[3], "peer")) 07797 return RESULT_SHOWUSAGE; 07798 if (!strcasecmp(argv[3], "like")) 07799 return RESULT_SHOWUSAGE; 07800 if (!strcasecmp(argv[3], "all")) { 07801 multi = 1; 07802 pruneuser = prunepeer = 1; 07803 } else { 07804 pruneuser = prunepeer = 1; 07805 name = argv[3]; 07806 } 07807 break; 07808 case 5: 07809 if (!strcasecmp(argv[4], "like")) 07810 return RESULT_SHOWUSAGE; 07811 if (!strcasecmp(argv[3], "all")) 07812 return RESULT_SHOWUSAGE; 07813 if (!strcasecmp(argv[3], "like")) { 07814 multi = 1; 07815 name = argv[4]; 07816 pruneuser = prunepeer = 1; 07817 } else if (!strcasecmp(argv[3], "user")) { 07818 pruneuser = 1; 07819 if (!strcasecmp(argv[4], "all")) 07820 multi = 1; 07821 else 07822 name = argv[4]; 07823 } else if (!strcasecmp(argv[3], "peer")) { 07824 prunepeer = 1; 07825 if (!strcasecmp(argv[4], "all")) 07826 multi = 1; 07827 else 07828 name = argv[4]; 07829 } else 07830 return RESULT_SHOWUSAGE; 07831 break; 07832 case 6: 07833 if (strcasecmp(argv[4], "like")) 07834 return RESULT_SHOWUSAGE; 07835 if (!strcasecmp(argv[3], "user")) { 07836 pruneuser = 1; 07837 name = argv[5]; 07838 } else if (!strcasecmp(argv[3], "peer")) { 07839 prunepeer = 1; 07840 name = argv[5]; 07841 } else 07842 return RESULT_SHOWUSAGE; 07843 break; 07844 default: 07845 return RESULT_SHOWUSAGE; 07846 } 07847 07848 if (multi && name) { 07849 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 07850 return RESULT_SHOWUSAGE; 07851 } 07852 07853 if (multi) { 07854 if (prunepeer) { 07855 int pruned = 0; 07856 07857 ASTOBJ_CONTAINER_WRLOCK(&peerl); 07858 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07859 ASTOBJ_RDLOCK(iterator); 07860 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07861 ASTOBJ_UNLOCK(iterator); 07862 continue; 07863 }; 07864 if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07865 ASTOBJ_MARK(iterator); 07866 pruned++; 07867 } 07868 ASTOBJ_UNLOCK(iterator); 07869 } while (0) ); 07870 if (pruned) { 07871 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 07872 ast_cli(fd, "%d peers pruned.\n", pruned); 07873 } else 07874 ast_cli(fd, "No peers found to prune.\n"); 07875 ASTOBJ_CONTAINER_UNLOCK(&peerl); 07876 } 07877 if (pruneuser) { 07878 int pruned = 0; 07879 07880 ASTOBJ_CONTAINER_WRLOCK(&userl); 07881 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07882 ASTOBJ_RDLOCK(iterator); 07883 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07884 ASTOBJ_UNLOCK(iterator); 07885 continue; 07886 }; 07887 if (ast_test_flag((&iterator->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07888 ASTOBJ_MARK(iterator); 07889 pruned++; 07890 } 07891 ASTOBJ_UNLOCK(iterator); 07892 } while (0) ); 07893 if (pruned) { 07894 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 07895 ast_cli(fd, "%d users pruned.\n", pruned); 07896 } else 07897 ast_cli(fd, "No users found to prune.\n"); 07898 ASTOBJ_CONTAINER_UNLOCK(&userl); 07899 } 07900 } else { 07901 if (prunepeer) { 07902 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 07903 if (!ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07904 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 07905 ASTOBJ_CONTAINER_LINK(&peerl, peer); 07906 } else 07907 ast_cli(fd, "Peer '%s' pruned.\n", name); 07908 ASTOBJ_UNREF(peer, sip_destroy_peer); 07909 } else 07910 ast_cli(fd, "Peer '%s' not found.\n", name); 07911 } 07912 if (pruneuser) { 07913 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 07914 if (!ast_test_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { 07915 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 07916 ASTOBJ_CONTAINER_LINK(&userl, user); 07917 } else 07918 ast_cli(fd, "User '%s' pruned.\n", name); 07919 ASTOBJ_UNREF(user, sip_destroy_user); 07920 } else 07921 ast_cli(fd, "User '%s' not found.\n", name); 07922 } 07923 } 07924 07925 return RESULT_SUCCESS; 07926 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
sip_read: Read SIP RTP from channel
Definition at line 3042 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.
03043 { 03044 struct ast_frame *fr; 03045 struct sip_pvt *p = ast->tech_pvt; 03046 ast_mutex_lock(&p->lock); 03047 fr = sip_rtp_read(ast, p); 03048 time(&p->lastrtprx); 03049 ast_mutex_unlock(&p->lock); 03050 return fr; 03051 }
static int sip_reg_timeout | ( | void * | data | ) | [static] |
sip_reg_timeout: Registration timeout, register again
Definition at line 5375 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().
05376 { 05377 05378 /* if we are here, our registration timed out, so we'll just do it over */ 05379 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 05380 struct sip_pvt *p; 05381 int res; 05382 05383 /* if we couldn't get a reference to the registry object, punt */ 05384 if (!r) 05385 return 0; 05386 05387 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 05388 if (r->call) { 05389 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 05390 in the single SIP manager thread. */ 05391 p = r->call; 05392 if (p->registry) 05393 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 05394 r->call = NULL; 05395 ast_set_flag(p, SIP_NEEDDESTROY); 05396 /* Pretend to ACK anything just in case */ 05397 __sip_pretend_ack(p); 05398 } 05399 /* If we have a limit, stop registration and give up */ 05400 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 05401 /* Ok, enough is enough. Don't try any more */ 05402 /* We could add an external notification here... 05403 steal it from app_voicemail :-) */ 05404 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 05405 r->regstate=REG_STATE_FAILED; 05406 } else { 05407 r->regstate=REG_STATE_UNREGISTERED; 05408 r->timeout = -1; 05409 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 05410 } 05411 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)); 05412 ASTOBJ_UNREF(r,sip_registry_destroy); 05413 return 0; 05414 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
sip_register: Parse register=> line in sip.conf and add to registry
Definition at line 3247 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(), sip_registry::expire, sip_registry::hostname, hostname, LOG_ERROR, LOG_WARNING, malloc, sip_registry::ocseq, sip_registry::portno, sip_registry::refresh, regl, sip_registry::secret, secret, sip_registry_destroy(), strsep(), sip_registry::timeout, sip_registry::username, and username.
Referenced by reload_config().
03248 { 03249 struct sip_registry *reg; 03250 char copy[256]; 03251 char *username=NULL, *hostname=NULL, *secret=NULL, *authuser=NULL; 03252 char *porta=NULL; 03253 char *contact=NULL; 03254 char *stringp=NULL; 03255 03256 if (!value) 03257 return -1; 03258 ast_copy_string(copy, value, sizeof(copy)); 03259 stringp=copy; 03260 username = stringp; 03261 hostname = strrchr(stringp, '@'); 03262 if (hostname) { 03263 *hostname = '\0'; 03264 hostname++; 03265 } 03266 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 03267 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 03268 return -1; 03269 } 03270 stringp=username; 03271 username = strsep(&stringp, ":"); 03272 if (username) { 03273 secret = strsep(&stringp, ":"); 03274 if (secret) 03275 authuser = strsep(&stringp, ":"); 03276 } 03277 stringp = hostname; 03278 hostname = strsep(&stringp, "/"); 03279 if (hostname) 03280 contact = strsep(&stringp, "/"); 03281 if (ast_strlen_zero(contact)) 03282 contact = "s"; 03283 stringp=hostname; 03284 hostname = strsep(&stringp, ":"); 03285 porta = strsep(&stringp, ":"); 03286 03287 if (porta && !atoi(porta)) { 03288 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 03289 return -1; 03290 } 03291 reg = malloc(sizeof(struct sip_registry)); 03292 if (!reg) { 03293 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 03294 return -1; 03295 } 03296 memset(reg, 0, sizeof(struct sip_registry)); 03297 regobjs++; 03298 ASTOBJ_INIT(reg); 03299 ast_copy_string(reg->contact, contact, sizeof(reg->contact)); 03300 if (username) 03301 ast_copy_string(reg->username, username, sizeof(reg->username)); 03302 if (hostname) 03303 ast_copy_string(reg->hostname, hostname, sizeof(reg->hostname)); 03304 if (authuser) 03305 ast_copy_string(reg->authuser, authuser, sizeof(reg->authuser)); 03306 if (secret) 03307 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 03308 reg->expire = -1; 03309 reg->timeout = -1; 03310 reg->refresh = default_expiry; 03311 reg->portno = porta ? atoi(porta) : 0; 03312 reg->callid_valid = 0; 03313 reg->ocseq = 101; 03314 ASTOBJ_CONTAINER_LINK(®l, reg); 03315 ASTOBJ_UNREF(reg,sip_registry_destroy); 03316 return 0; 03317 }
static void sip_registry_destroy | ( | struct sip_registry * | reg | ) | [static] |
sip_registry_destroy: Destroy registry object ---
Definition at line 2093 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(), handle_response_register(), sip_reg_timeout(), sip_register(), sip_reregister(), and unload_module().
02094 { 02095 /* Really delete */ 02096 if (reg->call) { 02097 /* Clear registry before destroying to ensure 02098 we don't get reentered trying to grab the registry lock */ 02099 reg->call->registry = NULL; 02100 sip_destroy(reg->call); 02101 } 02102 if (reg->expire > -1) 02103 ast_sched_del(sched, reg->expire); 02104 if (reg->timeout > -1) 02105 ast_sched_del(sched, reg->timeout); 02106 regobjs--; 02107 free(reg); 02108 02109 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_reload: Force reload of module from cli ---
Definition at line 13322 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), restart_monitor(), and sip_reloading.
Referenced by reload().
13323 { 13324 13325 ast_mutex_lock(&sip_reload_lock); 13326 if (sip_reloading) { 13327 ast_verbose("Previous SIP reload not yet done\n"); 13328 } else 13329 sip_reloading = 1; 13330 ast_mutex_unlock(&sip_reload_lock); 13331 restart_monitor(); 13332 13333 return 0; 13334 }
static struct ast_channel * sip_request_call | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
sip_request: PBX interface function -build SIP pvt structure ---
Definition at line 11755 of file chan_sip.c.
References __ourip, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, AST_FORMAT_MAX_AUDIO, ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_strlen_zero(), ast_update_use_count(), build_callid(), build_via(), 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.
11756 { 11757 int oldformat; 11758 struct sip_pvt *p; 11759 struct ast_channel *tmpc = NULL; 11760 char *ext, *host; 11761 char tmp[256]; 11762 char *dest = data; 11763 11764 oldformat = format; 11765 format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1); 11766 if (!format) { 11767 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)); 11768 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 11769 return NULL; 11770 } 11771 p = sip_alloc(NULL, NULL, 0, SIP_INVITE); 11772 if (!p) { 11773 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory)\n", (char *)data); 11774 *cause = AST_CAUSE_SWITCH_CONGESTION; 11775 return NULL; 11776 } 11777 11778 p->options = calloc(1, sizeof(*p->options)); 11779 if (!p->options) { 11780 sip_destroy(p); 11781 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 11782 *cause = AST_CAUSE_SWITCH_CONGESTION; 11783 return NULL; 11784 } 11785 11786 ast_copy_string(tmp, dest, sizeof(tmp)); 11787 host = strchr(tmp, '@'); 11788 if (host) { 11789 *host = '\0'; 11790 host++; 11791 ext = tmp; 11792 } else { 11793 ext = strchr(tmp, '/'); 11794 if (ext) { 11795 *ext++ = '\0'; 11796 host = tmp; 11797 } 11798 else { 11799 host = tmp; 11800 ext = NULL; 11801 } 11802 } 11803 11804 if (create_addr(p, host)) { 11805 *cause = AST_CAUSE_UNREGISTERED; 11806 sip_destroy(p); 11807 return NULL; 11808 } 11809 if (ast_strlen_zero(p->peername) && ext) 11810 ast_copy_string(p->peername, ext, sizeof(p->peername)); 11811 /* Recalculate our side, and recalculate Call ID */ 11812 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11813 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11814 build_via(p, p->via, sizeof(p->via)); 11815 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11816 11817 /* We have an extension to call, don't use the full contact here */ 11818 /* This to enable dialling registered peers with extension dialling, 11819 like SIP/peername/extension 11820 SIP/peername will still use the full contact */ 11821 if (ext) { 11822 ast_copy_string(p->username, ext, sizeof(p->username)); 11823 p->fullcontact[0] = 0; 11824 } 11825 #if 0 11826 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 11827 #endif 11828 p->prefcodec = format; 11829 ast_mutex_lock(&p->lock); 11830 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 11831 ast_mutex_unlock(&p->lock); 11832 if (!tmpc) 11833 sip_destroy(p); 11834 ast_update_use_count(); 11835 restart_monitor(); 11836 return tmpc; 11837 }
static int sip_reregister | ( | void * | data | ) | [static] |
sip_reregister: Update registration with SIP Proxy---
Definition at line 5340 of file chan_sip.c.
References __sip_do_register(), append_history(), ast_log(), ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, sip_registry::expire, sip_registry::hostname, LOG_NOTICE, recordhistory, sip_registry_destroy(), sipdebug, and sip_registry::username.
Referenced by handle_response_register(), and sip_send_all_registers().
05341 { 05342 /* if we are here, we know that we need to reregister. */ 05343 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 05344 05345 /* if we couldn't get a reference to the registry object, punt */ 05346 if (!r) 05347 return 0; 05348 05349 if (r->call && recordhistory) { 05350 char tmp[80]; 05351 snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname); 05352 append_history(r->call, "RegistryRenew", tmp); 05353 } 05354 /* Since registry's are only added/removed by the the monitor thread, this 05355 may be overkill to reference/dereference at all here */ 05356 if (sipdebug) 05357 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 05358 05359 r->expire = -1; 05360 __sip_do_register(r); 05361 ASTOBJ_UNREF(r, sip_registry_destroy); 05362 return 0; 05363 }
static struct ast_frame* sip_rtp_read | ( | struct ast_channel * | ast, | |
struct sip_pvt * | p | |||
) | [static] |
sip_rtp_read: Read RTP from network ---
Definition at line 2992 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().
02993 { 02994 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 02995 struct ast_frame *f; 02996 static struct ast_frame null_frame = { AST_FRAME_NULL, }; 02997 02998 if (!p->rtp) { 02999 /* We have no RTP allocated for this channel */ 03000 return &null_frame; 03001 } 03002 03003 switch(ast->fdno) { 03004 case 0: 03005 f = ast_rtp_read(p->rtp); /* RTP Audio */ 03006 break; 03007 case 1: 03008 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 03009 break; 03010 case 2: 03011 f = ast_rtp_read(p->vrtp); /* RTP Video */ 03012 break; 03013 case 3: 03014 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 03015 break; 03016 default: 03017 f = &null_frame; 03018 } 03019 /* Don't forward RFC2833 if we're not supposed to */ 03020 if (f && (f->frametype == AST_FRAME_DTMF) && (ast_test_flag(p, SIP_DTMF) != SIP_DTMF_RFC2833)) 03021 return &null_frame; 03022 if (p->owner) { 03023 /* We already hold the channel lock */ 03024 if (f->frametype == AST_FRAME_VOICE) { 03025 if (f->subclass != p->owner->nativeformats) { 03026 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 03027 p->owner->nativeformats = f->subclass; 03028 ast_set_read_format(p->owner, p->owner->readformat); 03029 ast_set_write_format(p->owner, p->owner->writeformat); 03030 } 03031 if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 03032 f = ast_dsp_process(p->owner, p->vad, f); 03033 if (f && (f->frametype == AST_FRAME_DTMF)) 03034 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 03035 } 03036 } 03037 } 03038 return f; 03039 }
static int sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
sip_scheddestroy: Schedule destruction of SIP call ---
Definition at line 1344 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().
01345 { 01346 char tmp[80]; 01347 if (sip_debug_test_pvt(p)) 01348 ast_verbose("Scheduling destruction of call '%s' in %d ms\n", p->callid, ms); 01349 if (recordhistory) { 01350 snprintf(tmp, sizeof(tmp), "%d ms", ms); 01351 append_history(p, "SchedDestroy", tmp); 01352 } 01353 01354 if (p->autokillid > -1) 01355 ast_sched_del(sched, p->autokillid); 01356 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 01357 return 0; 01358 }
static void sip_send_all_registers | ( | void | ) | [static] |
sip_send_all_registers: Send all known registrations
Definition at line 13267 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().
13268 { 13269 int ms; 13270 int regspacing; 13271 if (!regobjs) 13272 return; 13273 regspacing = default_expiry * 1000/regobjs; 13274 if (regspacing > 100) 13275 regspacing = 100; 13276 ms = regspacing; 13277 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 13278 ASTOBJ_WRLOCK(iterator); 13279 if (iterator->expire > -1) 13280 ast_sched_del(sched, iterator->expire); 13281 ms += regspacing; 13282 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 13283 ASTOBJ_UNLOCK(iterator); 13284 } while (0) 13285 ); 13286 }
static int sip_send_mwi_to_peer | ( | struct sip_peer * | peer | ) | [static] |
sip_send_mwi_to_peer: Send message waiting indication ---
Definition at line 11394 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.
Referenced by do_monitor().
11395 { 11396 /* Called with peerl lock, but releases it */ 11397 struct sip_pvt *p; 11398 int newmsgs, oldmsgs; 11399 11400 /* Check for messages */ 11401 ast_app_messagecount(peer->mailbox, &newmsgs, &oldmsgs); 11402 11403 time(&peer->lastmsgcheck); 11404 11405 /* Return now if it's the same thing we told them last time */ 11406 if (((newmsgs << 8) | (oldmsgs)) == peer->lastmsgssent) { 11407 return 0; 11408 } 11409 11410 p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY); 11411 if (!p) { 11412 ast_log(LOG_WARNING, "Unable to build sip pvt data for MWI\n"); 11413 return -1; 11414 } 11415 peer->lastmsgssent = ((newmsgs << 8) | (oldmsgs)); 11416 if (create_addr_from_peer(p, peer)) { 11417 /* Maybe they're not registered, etc. */ 11418 sip_destroy(p); 11419 return 0; 11420 } 11421 /* Recalculate our side, and recalculate Call ID */ 11422 if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) 11423 memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); 11424 build_via(p, p->via, sizeof(p->via)); 11425 build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); 11426 /* Send MWI */ 11427 ast_set_flag(p, SIP_OUTGOING); 11428 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 11429 sip_scheddestroy(p, 15000); 11430 return 0; 11431 }
static int sip_senddigit | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
sip_senddigit: Send DTMF character on SIP channel
Definition at line 2632 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().
02633 { 02634 struct sip_pvt *p = ast->tech_pvt; 02635 int res = 0; 02636 ast_mutex_lock(&p->lock); 02637 switch (ast_test_flag(p, SIP_DTMF)) { 02638 case SIP_DTMF_INFO: 02639 transmit_info_with_digit(p, digit); 02640 break; 02641 case SIP_DTMF_RFC2833: 02642 if (p->rtp) 02643 ast_rtp_senddigit(p->rtp, digit); 02644 break; 02645 case SIP_DTMF_INBAND: 02646 res = -1; 02647 break; 02648 } 02649 ast_mutex_unlock(&p->lock); 02650 return res; 02651 }
static int sip_sendtext | ( | struct ast_channel * | ast, | |
const char * | text | |||
) | [static] |
sip_sendtext: Send SIP MESSAGE text within a call ---
Definition at line 1590 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().
01591 { 01592 struct sip_pvt *p = ast->tech_pvt; 01593 int debug=sip_debug_test_pvt(p); 01594 01595 if (debug) 01596 ast_verbose("Sending text %s on %s\n", text, ast->name); 01597 if (!p) 01598 return -1; 01599 if (ast_strlen_zero(text)) 01600 return 0; 01601 if (debug) 01602 ast_verbose("Really sending text %s on %s\n", text, ast->name); 01603 transmit_message_with_text(p, text); 01604 return 0; 01605 }
static int sip_set_rtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp * | rtp, | |||
struct ast_rtp * | vrtp, | |||
int | codecs, | |||
int | nat_active | |||
) | [static] |
sip_set_rtp_peer: Set the RTP peer for this call ---
Definition at line 12948 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.
12949 { 12950 struct sip_pvt *p; 12951 int changed = 0; 12952 12953 p = chan->tech_pvt; 12954 if (!p) 12955 return -1; 12956 ast_mutex_lock(&p->lock); 12957 if (rtp) { 12958 changed |= ast_rtp_get_peer(rtp, &p->redirip); 12959 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 12960 memset(&p->redirip, 0, sizeof(p->redirip)); 12961 changed = 1; 12962 } 12963 if (vrtp) { 12964 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 12965 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 12966 memset(&p->vredirip, 0, sizeof(p->vredirip)); 12967 changed = 1; 12968 } 12969 if (codecs && (p->redircodecs != codecs)) { 12970 p->redircodecs = codecs; 12971 changed = 1; 12972 } 12973 if (changed && !ast_test_flag(p, SIP_GOTREFER)) { 12974 if (!p->pendinginvite) { 12975 if (option_debug > 2) { 12976 char iabuf[INET_ADDRSTRLEN]; 12977 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)); 12978 } 12979 transmit_reinvite_with_sdp(p); 12980 } else if (!ast_test_flag(p, SIP_PENDINGBYE)) { 12981 if (option_debug > 2) { 12982 char iabuf[INET_ADDRSTRLEN]; 12983 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)); 12984 } 12985 ast_set_flag(p, SIP_NEEDREINVITE); 12986 } 12987 } 12988 /* Reset lastrtprx timer */ 12989 time(&p->lastrtprx); 12990 time(&p->lastrtptx); 12991 ast_mutex_unlock(&p->lock); 12992 return 0; 12993 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_show_channel: Show details of one call ---
Definition at line 8603 of file chan_sip.c.
References ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::capability, sip_pvt::cid_num, dtmfmode2str(), sip_route::hop, iflist, sip_pvt::jointcapability, sip_pvt::lastmsg, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::peername, sip_pvt::recv, sip_pvt::redirip, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, SIP_NEEDDESTROY, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, sip_pvt::theirtag, sip_pvt::uri, sip_pvt::useragent, and sip_pvt::username.
08604 { 08605 struct sip_pvt *cur; 08606 char iabuf[INET_ADDRSTRLEN]; 08607 size_t len; 08608 int found = 0; 08609 08610 if (argc != 4) 08611 return RESULT_SHOWUSAGE; 08612 len = strlen(argv[3]); 08613 ast_mutex_lock(&iflock); 08614 cur = iflist; 08615 while(cur) { 08616 if (!strncasecmp(cur->callid, argv[3],len)) { 08617 ast_cli(fd,"\n"); 08618 if (cur->subscribed != NONE) 08619 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 08620 else 08621 ast_cli(fd, " * SIP Call\n"); 08622 ast_cli(fd, " Direction: %s\n", ast_test_flag(cur, SIP_OUTGOING)?"Outgoing":"Incoming"); 08623 ast_cli(fd, " Call-ID: %s\n", cur->callid); 08624 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 08625 ast_cli(fd, " Non-Codec Capability: %d\n", cur->noncodeccapability); 08626 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 08627 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 08628 ast_cli(fd, " Format %s\n", ast_getformatname(cur->owner ? cur->owner->nativeformats : 0) ); 08629 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 08630 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 08631 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(cur, SIP_NAT))); 08632 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)" ); 08633 ast_cli(fd, " Our Tag: %s\n", cur->tag); 08634 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 08635 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 08636 if (!ast_strlen_zero(cur->username)) 08637 ast_cli(fd, " Username: %s\n", cur->username); 08638 if (!ast_strlen_zero(cur->peername)) 08639 ast_cli(fd, " Peername: %s\n", cur->peername); 08640 if (!ast_strlen_zero(cur->uri)) 08641 ast_cli(fd, " Original uri: %s\n", cur->uri); 08642 if (!ast_strlen_zero(cur->cid_num)) 08643 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 08644 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(cur, SIP_NEEDDESTROY)); 08645 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 08646 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(cur, SIP_PROMISCREDIR) ? "Yes" : "No"); 08647 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 08648 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(cur, SIP_DTMF))); 08649 ast_cli(fd, " SIP Options: "); 08650 if (cur->sipoptions) { 08651 int x; 08652 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 08653 if (cur->sipoptions & sip_options[x].id) 08654 ast_cli(fd, "%s ", sip_options[x].text); 08655 } 08656 } else 08657 ast_cli(fd, "(none)\n"); 08658 ast_cli(fd, "\n\n"); 08659 found++; 08660 } 08661 cur = cur->next; 08662 } 08663 ast_mutex_unlock(&iflock); 08664 if (!found) 08665 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 08666 return RESULT_SUCCESS; 08667 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_show_channels: Show active SIP channels ---
Definition at line 8404 of file chan_sip.c.
References __sip_show_channels().
08405 { 08406 return __sip_show_channels(fd, argc, argv, 0); 08407 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 7959 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.
07960 { 07961 struct domain *d; 07962 07963 if (AST_LIST_EMPTY(&domain_list)) { 07964 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 07965 return RESULT_SUCCESS; 07966 } else { 07967 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 07968 AST_LIST_LOCK(&domain_list); 07969 AST_LIST_TRAVERSE(&domain_list, d, list) 07970 ast_cli(fd, FORMAT, d->domain, ast_strlen_zero(d->context) ? "(default)": d->context, 07971 domain_mode_to_text(d->mode)); 07972 AST_LIST_UNLOCK(&domain_list); 07973 ast_cli(fd, "\n"); 07974 return RESULT_SUCCESS; 07975 } 07976 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_show_history: Show history details of one call ---
Definition at line 8670 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.
08671 { 08672 struct sip_pvt *cur; 08673 struct sip_history *hist; 08674 size_t len; 08675 int x; 08676 int found = 0; 08677 08678 if (argc != 4) 08679 return RESULT_SHOWUSAGE; 08680 if (!recordhistory) 08681 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 08682 len = strlen(argv[3]); 08683 ast_mutex_lock(&iflock); 08684 cur = iflist; 08685 while(cur) { 08686 if (!strncasecmp(cur->callid, argv[3], len)) { 08687 ast_cli(fd,"\n"); 08688 if (cur->subscribed != NONE) 08689 ast_cli(fd, " * Subscription\n"); 08690 else 08691 ast_cli(fd, " * SIP Call\n"); 08692 x = 0; 08693 hist = cur->history; 08694 while(hist) { 08695 x++; 08696 ast_cli(fd, "%d. %s\n", x, hist->event); 08697 hist = hist->next; 08698 } 08699 if (!x) 08700 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 08701 found++; 08702 } 08703 cur = cur->next; 08704 } 08705 ast_mutex_unlock(&iflock); 08706 if (!found) 08707 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 08708 return RESULT_SUCCESS; 08709 }
static int sip_show_inuse | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_show_inuse: CLI Command to show calls within limits set by call_limit ---
Definition at line 7426 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, FORMAT2, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
07426 { 07427 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 07428 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 07429 char ilimits[40]; 07430 char iused[40]; 07431 int showall = 0; 07432 07433 if (argc < 3) 07434 return RESULT_SHOWUSAGE; 07435 07436 if (argc == 4 && !strcmp(argv[3],"all")) 07437 showall = 1; 07438 07439 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 07440 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07441 ASTOBJ_RDLOCK(iterator); 07442 if (iterator->call_limit) 07443 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 07444 else 07445 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 07446 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 07447 if (showall || iterator->call_limit) 07448 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 07449 ASTOBJ_UNLOCK(iterator); 07450 } while (0) ); 07451 07452 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 07453 07454 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 07455 ASTOBJ_RDLOCK(iterator); 07456 if (iterator->call_limit) 07457 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 07458 else 07459 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 07460 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 07461 if (showall || iterator->call_limit) 07462 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 07463 ASTOBJ_UNLOCK(iterator); 07464 } while (0) ); 07465 07466 return RESULT_SUCCESS; 07467 #undef FORMAT 07468 #undef FORMAT2 07469 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_show_objects: List all allocated SIP Objects ---
Definition at line 7732 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.
07733 { 07734 char tmp[256]; 07735 if (argc != 3) 07736 return RESULT_SHOWUSAGE; 07737 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 07738 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 07739 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 07740 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 07741 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 07742 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 07743 return RESULT_SUCCESS; 07744 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_show_peer: Show one peer in detail ---
Definition at line 8016 of file chan_sip.c.
References _sip_show_peer().
08017 { 08018 return _sip_show_peer(0, fd, NULL, NULL, argc, argv); 08019 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_show_peers: CLI Show Peers command
Definition at line 7593 of file chan_sip.c.
References _sip_show_peers().
07594 { 07595 return _sip_show_peers(fd, NULL, NULL, NULL, argc, argv); 07596 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_show_registry: Show SIP Registry (registrations with other SIP proxies ---
Definition at line 8268 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, DEFAULT_SIP_PORT, FORMAT, FORMAT2, host, regl, regstate2str(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
08269 { 08270 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s\n" 08271 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s\n" 08272 char host[80]; 08273 08274 if (argc != 3) 08275 return RESULT_SHOWUSAGE; 08276 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State"); 08277 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 08278 ASTOBJ_RDLOCK(iterator); 08279 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : DEFAULT_SIP_PORT); 08280 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate)); 08281 ASTOBJ_UNLOCK(iterator); 08282 } while(0)); 08283 return RESULT_SUCCESS; 08284 #undef FORMAT 08285 #undef FORMAT2 08286 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_show_settings: List global settings for the SIP channel ---
Definition at line 8289 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.
08290 { 08291 char tmp[BUFSIZ]; 08292 int realtimepeers = 0; 08293 int realtimeusers = 0; 08294 08295 realtimepeers = ast_check_realtime("sippeers"); 08296 realtimeusers = ast_check_realtime("sipusers"); 08297 08298 if (argc != 3) 08299 return RESULT_SHOWUSAGE; 08300 ast_cli(fd, "\n\nGlobal Settings:\n"); 08301 ast_cli(fd, "----------------\n"); 08302 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 08303 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(tmp, sizeof(tmp), bindaddr.sin_addr)); 08304 ast_cli(fd, " Videosupport: %s\n", videosupport ? "Yes" : "No"); 08305 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 08306 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 08307 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags, SIP_PROMISCREDIR) ? "Yes" : "No"); 08308 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 08309 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 08310 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags, SIP_USEREQPHONE) ? "Yes" : "No"); 08311 ast_cli(fd, " Our auth realm %s\n", global_realm); 08312 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 08313 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 08314 ast_cli(fd, " User Agent: %s\n", default_useragent); 08315 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 08316 ast_cli(fd, " Reg. context: %s\n", ast_strlen_zero(regcontext) ? "(not set)" : regcontext); 08317 ast_cli(fd, " Caller ID: %s\n", default_callerid); 08318 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 08319 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 08320 ast_cli(fd, " Call Events: %s\n", callevents ? "On" : "Off"); 08321 ast_cli(fd, " IP ToS: 0x%x\n", tos); 08322 #ifdef OSP_SUPPORT 08323 ast_cli(fd, " OSP Support: Yes\n"); 08324 #else 08325 ast_cli(fd, " OSP Support: No\n"); 08326 #endif 08327 if (!realtimepeers && !realtimeusers) 08328 ast_cli(fd, " SIP realtime: Disabled\n" ); 08329 else 08330 ast_cli(fd, " SIP realtime: Enabled\n" ); 08331 08332 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 08333 ast_cli(fd, "---------------------------\n"); 08334 ast_cli(fd, " Codecs: "); 08335 print_codec_to_cli(fd, &prefs); 08336 ast_cli(fd, "\n"); 08337 ast_cli(fd, " Relax DTMF: %s\n", relaxdtmf ? "Yes" : "No"); 08338 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 08339 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 08340 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 08341 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 08342 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 08343 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 08344 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 08345 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 08346 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 08347 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 08348 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 08349 ast_cli(fd, "\nDefault Settings:\n"); 08350 ast_cli(fd, "-----------------\n"); 08351 ast_cli(fd, " Context: %s\n", default_context); 08352 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags, SIP_NAT))); 08353 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags, SIP_DTMF))); 08354 ast_cli(fd, " Qualify: %d\n", default_qualify); 08355 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags, SIP_USECLIENTCODE) ? "Yes" : "No"); 08356 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" ); 08357 ast_cli(fd, " Language: %s\n", ast_strlen_zero(default_language) ? "(Defaults to English)" : default_language); 08358 ast_cli(fd, " Musicclass: %s\n", global_musicclass); 08359 ast_cli(fd, " Voice Mail Extension: %s\n", global_vmexten); 08360 08361 08362 if (realtimepeers || realtimeusers) { 08363 ast_cli(fd, "\nRealtime SIP Settings:\n"); 08364 ast_cli(fd, "----------------------\n"); 08365 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 08366 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 08367 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 08368 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 08369 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 08370 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 08371 } 08372 ast_cli(fd, "\n----\n"); 08373 return RESULT_SUCCESS; 08374 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_show_subscriptions: Show active SIP subscriptions ---
Definition at line 8410 of file chan_sip.c.
References __sip_show_channels().
08411 { 08412 return __sip_show_channels(fd, argc, argv, 1); 08413 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_show_user: Show one user in detail ---
Definition at line 8204 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, RESULT_SUCCESS, sip_destroy_user(), user, and ast_variable::value.
08205 { 08206 char cbuf[256]; 08207 struct sip_user *user; 08208 struct ast_codec_pref *pref; 08209 struct ast_variable *v; 08210 int x = 0, codec = 0, load_realtime = 0; 08211 08212 if (argc < 4) 08213 return RESULT_SHOWUSAGE; 08214 08215 /* Load from realtime storage? */ 08216 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 08217 08218 user = find_user(argv[3], load_realtime); 08219 if (user) { 08220 ast_cli(fd,"\n\n"); 08221 ast_cli(fd, " * Name : %s\n", user->name); 08222 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 08223 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 08224 ast_cli(fd, " Context : %s\n", user->context); 08225 ast_cli(fd, " Language : %s\n", user->language); 08226 if (!ast_strlen_zero(user->accountcode)) 08227 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 08228 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 08229 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 08230 ast_cli(fd, " Call limit : %d\n", user->call_limit); 08231 ast_cli(fd, " Callgroup : "); 08232 print_group(fd, user->callgroup, 0); 08233 ast_cli(fd, " Pickupgroup : "); 08234 print_group(fd, user->pickupgroup, 0); 08235 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 08236 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 08237 ast_cli(fd, " Codec Order : ("); 08238 pref = &user->prefs; 08239 for(x = 0; x < 32 ; x++) { 08240 codec = ast_codec_pref_index(pref,x); 08241 if (!codec) 08242 break; 08243 ast_cli(fd, "%s", ast_getformatname(codec)); 08244 if (x < 31 && ast_codec_pref_index(pref,x+1)) 08245 ast_cli(fd, "|"); 08246 } 08247 08248 if (!x) 08249 ast_cli(fd, "none"); 08250 ast_cli(fd, ")\n"); 08251 08252 if (user->chanvars) { 08253 ast_cli(fd, " Variables :\n"); 08254 for (v = user->chanvars ; v ; v = v->next) 08255 ast_cli(fd, " %s = %s\n", v->name, v->value); 08256 } 08257 ast_cli(fd,"\n"); 08258 ASTOBJ_UNREF(user,sip_destroy_user); 08259 } else { 08260 ast_cli(fd,"User %s not found.\n", argv[3]); 08261 ast_cli(fd,"\n"); 08262 } 08263 08264 return RESULT_SUCCESS; 08265 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_show_users: CLI Command 'SIP Show Users' ---
Definition at line 7514 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, nat2str(), RESULT_SHOWUSAGE, SIP_NAT, and userl.
07515 { 07516 regex_t regexbuf; 07517 int havepattern = 0; 07518 07519 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 07520 07521 switch (argc) { 07522 case 5: 07523 if (!strcasecmp(argv[3], "like")) { 07524 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 07525 return RESULT_SHOWUSAGE; 07526 havepattern = 1; 07527 } else 07528 return RESULT_SHOWUSAGE; 07529 case 3: 07530 break; 07531 default: 07532 return RESULT_SHOWUSAGE; 07533 } 07534 07535 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 07536 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 07537 ASTOBJ_RDLOCK(iterator); 07538 07539 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 07540 ASTOBJ_UNLOCK(iterator); 07541 continue; 07542 } 07543 07544 ast_cli(fd, FORMAT, iterator->name, 07545 iterator->secret, 07546 iterator->accountcode, 07547 iterator->context, 07548 iterator->ha ? "Yes" : "No", 07549 nat2str(ast_test_flag(iterator, SIP_NAT))); 07550 ASTOBJ_UNLOCK(iterator); 07551 } while (0) 07552 ); 07553 07554 if (havepattern) 07555 regfree(®exbuf); 07556 07557 return RESULT_SUCCESS; 07558 #undef FORMAT 07559 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
sip_sipredirect: Transfer call before connect with a 302 redirect ---
Definition at line 13176 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().
13177 { 13178 char *cdest; 13179 char *extension, *host, *port; 13180 char tmp[80]; 13181 13182 cdest = ast_strdupa(dest); 13183 if (!cdest) { 13184 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 13185 return 0; 13186 } 13187 extension = strsep(&cdest, "@"); 13188 host = strsep(&cdest, ":"); 13189 port = strsep(&cdest, ":"); 13190 if (!extension) { 13191 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 13192 return 0; 13193 } 13194 13195 /* we'll issue the redirect message here */ 13196 if (!host) { 13197 char *localtmp; 13198 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 13199 if (!strlen(tmp)) { 13200 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 13201 return 0; 13202 } 13203 if ((localtmp = strstr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 13204 char lhost[80], lport[80]; 13205 memset(lhost, 0, sizeof(lhost)); 13206 memset(lport, 0, sizeof(lport)); 13207 localtmp++; 13208 /* This is okey because lhost and lport are as big as tmp */ 13209 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 13210 if (!strlen(lhost)) { 13211 ast_log(LOG_ERROR, "Can't find the host address\n"); 13212 return 0; 13213 } 13214 host = ast_strdupa(lhost); 13215 if (!host) { 13216 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 13217 return 0; 13218 } 13219 if (!ast_strlen_zero(lport)) { 13220 port = ast_strdupa(lport); 13221 if (!port) { 13222 ast_log(LOG_ERROR, "Problem allocating the memory\n"); 13223 return 0; 13224 } 13225 } 13226 } 13227 } 13228 13229 snprintf(p->our_contact, sizeof(p->our_contact), "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 13230 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq, 1); 13231 13232 /* this is all that we want to send to that SIP device */ 13233 ast_set_flag(p, SIP_ALREADYGONE); 13234 13235 /* hangup here */ 13236 return -1; 13237 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
sip_transfer: Transfer SIP call
Definition at line 2656 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().
02657 { 02658 struct sip_pvt *p = ast->tech_pvt; 02659 int res; 02660 02661 ast_mutex_lock(&p->lock); 02662 if (ast->_state == AST_STATE_RING) 02663 res = sip_sipredirect(p, dest); 02664 else 02665 res = transmit_refer(p, dest); 02666 ast_mutex_unlock(&p->lock); 02667 return res; 02668 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
sip_write: Send frame to media channel (rtp) ---
Definition at line 2563 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.
02564 { 02565 struct sip_pvt *p = ast->tech_pvt; 02566 int res = 0; 02567 switch (frame->frametype) { 02568 case AST_FRAME_VOICE: 02569 if (!(frame->subclass & ast->nativeformats)) { 02570 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", 02571 frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat); 02572 return 0; 02573 } 02574 if (p) { 02575 ast_mutex_lock(&p->lock); 02576 if (p->rtp) { 02577 /* If channel is not up, activate early media session */ 02578 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02579 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); 02580 ast_set_flag(p, SIP_PROGRESS_SENT); 02581 } 02582 time(&p->lastrtptx); 02583 res = ast_rtp_write(p->rtp, frame); 02584 } 02585 ast_mutex_unlock(&p->lock); 02586 } 02587 break; 02588 case AST_FRAME_VIDEO: 02589 if (p) { 02590 ast_mutex_lock(&p->lock); 02591 if (p->vrtp) { 02592 /* Activate video early media */ 02593 if ((ast->_state != AST_STATE_UP) && !ast_test_flag(p, SIP_PROGRESS_SENT) && !ast_test_flag(p, SIP_OUTGOING)) { 02594 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, 0); 02595 ast_set_flag(p, SIP_PROGRESS_SENT); 02596 } 02597 time(&p->lastrtptx); 02598 res = ast_rtp_write(p->vrtp, frame); 02599 } 02600 ast_mutex_unlock(&p->lock); 02601 } 02602 break; 02603 case AST_FRAME_IMAGE: 02604 return 0; 02605 break; 02606 default: 02607 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 02608 return 0; 02609 } 02610 02611 return res; 02612 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
sipsock_read: Read data from SIP socket ---
Definition at line 11295 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().
11296 { 11297 struct sip_request req; 11298 struct sockaddr_in sin = { 0, }; 11299 struct sip_pvt *p; 11300 int res; 11301 socklen_t len; 11302 int nounlock; 11303 int recount = 0; 11304 char iabuf[INET_ADDRSTRLEN]; 11305 unsigned int lockretry = 100; 11306 11307 len = sizeof(sin); 11308 memset(&req, 0, sizeof(req)); 11309 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 11310 if (res < 0) { 11311 #if !defined(__FreeBSD__) 11312 if (errno == EAGAIN) 11313 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 11314 else 11315 #endif 11316 if (errno != ECONNREFUSED) 11317 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 11318 return 1; 11319 } 11320 if (res == sizeof(req.data)) { 11321 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 11322 req.data[sizeof(req.data) - 1] = '\0'; 11323 } else 11324 req.data[res] = '\0'; 11325 req.len = res; 11326 if(sip_debug_test_addr(&sin)) 11327 ast_set_flag(&req, SIP_PKT_DEBUG); 11328 if (pedanticsipchecking) 11329 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 11330 if (ast_test_flag(&req, SIP_PKT_DEBUG)) { 11331 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); 11332 } 11333 parse_request(&req); 11334 req.method = find_sip_method(req.rlPart1); 11335 if (ast_test_flag(&req, SIP_PKT_DEBUG)) { 11336 ast_verbose("--- (%d headers %d lines)", req.headers, req.lines); 11337 if (req.headers + req.lines == 0) 11338 ast_verbose(" Nat keepalive "); 11339 ast_verbose("---\n"); 11340 } 11341 11342 if (req.headers < 2) { 11343 /* Must have at least two headers */ 11344 return 1; 11345 } 11346 11347 11348 /* Process request, with netlock held */ 11349 retrylock: 11350 ast_mutex_lock(&netlock); 11351 p = find_call(&req, &sin, req.method); 11352 if (p) { 11353 /* Go ahead and lock the owner if it has one -- we may need it */ 11354 if (p->owner && ast_mutex_trylock(&p->owner->lock)) { 11355 ast_log(LOG_DEBUG, "Failed to grab lock, trying again...\n"); 11356 ast_mutex_unlock(&p->lock); 11357 ast_mutex_unlock(&netlock); 11358 /* Sleep for a very short amount of time */ 11359 usleep(1); 11360 if (--lockretry) 11361 goto retrylock; 11362 } 11363 if (!lockretry) { 11364 ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", p->owner->name); 11365 ast_log(LOG_ERROR, "SIP MESSAGE JUST IGNORED: %s \n", req.data); 11366 ast_log(LOG_ERROR, "BAD! BAD! BAD!\n"); 11367 return 1; 11368 } 11369 memcpy(&p->recv, &sin, sizeof(p->recv)); 11370 if (recordhistory) { 11371 char tmp[80]; 11372 /* This is a response, note what it was for */ 11373 snprintf(tmp, sizeof(tmp), "%s / %s /%s", req.data, get_header(&req, "CSeq"), req.rlPart2); 11374 append_history(p, "Rx", tmp); 11375 } 11376 nounlock = 0; 11377 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 11378 /* Request failed */ 11379 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 11380 } 11381 11382 if (p->owner && !nounlock) 11383 ast_mutex_unlock(&p->owner->lock); 11384 ast_mutex_unlock(&p->lock); 11385 } 11386 ast_mutex_unlock(&netlock); 11387 if (recount) 11388 ast_update_use_count(); 11389 11390 return 1; 11391 }
static const char* subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
subscription_type2str: Show subscription type in string format
Definition at line 8377 of file chan_sip.c.
References subscription_types, and type.
Referenced by __sip_show_channels(), and sip_show_channel().
08377 { 08378 int i; 08379 08380 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 08381 if (subscription_types[i].type == subtype) { 08382 return subscription_types[i].text; 08383 } 08384 } 08385 return subscription_types[0].text; 08386 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
temp_peer: Create temporary peer (used in autocreatepeer mode) ---
Definition at line 12211 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().
12212 { 12213 struct sip_peer *peer; 12214 12215 peer = malloc(sizeof(*peer)); 12216 if (!peer) 12217 return NULL; 12218 12219 memset(peer, 0, sizeof(*peer)); 12220 apeerobjs++; 12221 ASTOBJ_INIT(peer); 12222 12223 peer->expire = -1; 12224 peer->pokeexpire = -1; 12225 ast_copy_string(peer->name, name, sizeof(peer->name)); 12226 ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY); 12227 strcpy(peer->context, default_context); 12228 strcpy(peer->subscribecontext, default_subscribecontext); 12229 strcpy(peer->language, default_language); 12230 strcpy(peer->musicclass, global_musicclass); 12231 peer->addr.sin_port = htons(DEFAULT_SIP_PORT); 12232 peer->addr.sin_family = AF_INET; 12233 peer->capability = global_capability; 12234 peer->rtptimeout = global_rtptimeout; 12235 peer->rtpholdtimeout = global_rtpholdtimeout; 12236 peer->rtpkeepalive = global_rtpkeepalive; 12237 ast_set_flag(peer, SIP_SELFDESTRUCT); 12238 ast_set_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC); 12239 peer->prefs = prefs; 12240 reg_source_db(peer); 12241 12242 return peer; 12243 }
static force_inline int thread_safe_rand | ( | void | ) | [static] |
Thread-safe random number generator.
Definition at line 972 of file chan_sip.c.
References ast_mutex_lock(), and ast_mutex_unlock().
Referenced by build_callid(), build_reply_digest(), check_auth(), make_our_tag(), reg_source_db(), reqprep(), sip_alloc(), transmit_fake_auth_response(), transmit_invite(), and transmit_register().
00973 { 00974 int val; 00975 00976 ast_mutex_lock(&rand_lock); 00977 val = rand(); 00978 ast_mutex_unlock(&rand_lock); 00979 00980 return val; 00981 }
static void transmit_fake_auth_response | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
char * | randdata, | |||
int | randlen, | |||
int | reliable | |||
) | [static] |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
Definition at line 6458 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().
06459 { 06460 snprintf(randdata, randlen, "%08x", thread_safe_rand()); 06461 transmit_response_with_auth(p, "401 Unauthorized", req, randdata, reliable, "WWW-Authenticate", 0); 06462 }
static int transmit_info_with_digit | ( | struct sip_pvt * | p, | |
char | digit | |||
) | [static] |
transmit_info_with_digit: Send SIP INFO dtmf message, see Cisco documentation on cisco.co m ---
Definition at line 5663 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_INFO.
Referenced by sip_senddigit().
05664 { 05665 struct sip_request req; 05666 reqprep(&req, p, SIP_INFO, 0, 1); 05667 add_digit(&req, digit); 05668 return send_request(p, &req, 1, p->ocseq); 05669 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
transmit_info_with_vidupdate: Send SIP INFO with video update request ---
Definition at line 5672 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_INFO.
Referenced by sip_indicate().
05673 { 05674 struct sip_request req; 05675 reqprep(&req, p, SIP_INFO, 0, 1); 05676 add_vidupdate(&req); 05677 return send_request(p, &req, 1, p->ocseq); 05678 }
static int transmit_invite | ( | struct sip_pvt * | p, | |
int | sipmethod, | |||
int | sendsdp, | |||
int | init | |||
) | [static] |
transmit_invite: Build REFER/INVITE/OPTIONS message and transmit it ---
Definition at line 4963 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().
04964 { 04965 struct sip_request req; 04966 04967 req.method = sipmethod; 04968 if (init) { 04969 /* Bump branch even on initial requests */ 04970 p->branch ^= thread_safe_rand(); 04971 build_via(p, p->via, sizeof(p->via)); 04972 if (init > 1) 04973 initreqprep(&req, p, sipmethod); 04974 else 04975 reqprep(&req, p, sipmethod, 0, 1); 04976 } else 04977 reqprep(&req, p, sipmethod, 0, 1); 04978 04979 if (p->options && p->options->auth) 04980 add_header(&req, p->options->authheader, p->options->auth); 04981 append_date(&req); 04982 if (sipmethod == SIP_REFER) { /* Call transfer */ 04983 if (!ast_strlen_zero(p->refer_to)) 04984 add_header(&req, "Refer-To", p->refer_to); 04985 if (!ast_strlen_zero(p->referred_by)) 04986 add_header(&req, "Referred-By", p->referred_by); 04987 } 04988 #ifdef OSP_SUPPORT 04989 if ((req.method != SIP_OPTIONS) && p->options && !ast_strlen_zero(p->options->osptoken)) { 04990 ast_log(LOG_DEBUG,"Adding OSP Token: %s\n", p->options->osptoken); 04991 add_header(&req, "P-OSP-Auth-Token", p->options->osptoken); 04992 } 04993 #endif 04994 if (p->options && !ast_strlen_zero(p->options->distinctive_ring)) 04995 { 04996 add_header(&req, "Alert-Info", p->options->distinctive_ring); 04997 } 04998 add_header(&req, "Allow", ALLOWED_METHODS); 04999 if (p->options && p->options->addsipheaders ) { 05000 struct ast_channel *ast; 05001 char *header = (char *) NULL; 05002 char *content = (char *) NULL; 05003 char *end = (char *) NULL; 05004 struct varshead *headp = (struct varshead *) NULL; 05005 struct ast_var_t *current; 05006 05007 ast = p->owner; /* The owner channel */ 05008 if (ast) { 05009 char *headdup; 05010 headp = &ast->varshead; 05011 if (!headp) 05012 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 05013 else { 05014 AST_LIST_TRAVERSE(headp, current, entries) { 05015 /* SIPADDHEADER: Add SIP header to outgoing call */ 05016 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 05017 header = ast_var_value(current); 05018 headdup = ast_strdupa(header); 05019 /* Strip of the starting " (if it's there) */ 05020 if (*headdup == '"') 05021 headdup++; 05022 if ((content = strchr(headdup, ':'))) { 05023 *content = '\0'; 05024 content++; /* Move pointer ahead */ 05025 /* Skip white space */ 05026 while (*content == ' ') 05027 content++; 05028 /* Strip the ending " (if it's there) */ 05029 end = content + strlen(content) -1; 05030 if (*end == '"') 05031 *end = '\0'; 05032 05033 add_header(&req, headdup, content); 05034 if (sipdebug) 05035 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 05036 } 05037 } 05038 } 05039 } 05040 } 05041 } 05042 if (sdp && p->rtp) { 05043 ast_rtp_offered_from_local(p->rtp, 1); 05044 add_sdp(&req, p); 05045 } else { 05046 add_header_contentLength(&req, 0); 05047 add_blank_header(&req); 05048 } 05049 05050 if (!p->initreq.headers) { 05051 /* Use this as the basis */ 05052 copy_request(&p->initreq, &req); 05053 parse_request(&p->initreq); 05054 if (sip_debug_test_pvt(p)) 05055 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05056 } 05057 p->lastinvite = p->ocseq; 05058 return send_request(p, &req, init ? 2 : 1, p->ocseq); 05059 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
transmit_message_with_text: Transmit text with SIP MESSAGE method ---
Definition at line 5609 of file chan_sip.c.
References add_text(), sip_pvt::ocseq, reqprep(), send_request(), and SIP_MESSAGE.
Referenced by sip_sendtext().
05610 { 05611 struct sip_request req; 05612 reqprep(&req, p, SIP_MESSAGE, 0, 1); 05613 add_text(&req, text); 05614 return send_request(p, &req, 1, p->ocseq); 05615 }
static int transmit_notify_with_mwi | ( | struct sip_pvt * | p, | |
int | newmsgs, | |||
int | oldmsgs, | |||
char * | vmexten | |||
) | [static] |
transmit_notify_with_mwi: Notify user of messages waiting in voicemail ---
Definition at line 5234 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().
05235 { 05236 struct sip_request req; 05237 char tmp[500]; 05238 char *t = tmp; 05239 size_t maxbytes = sizeof(tmp); 05240 char iabuf[INET_ADDRSTRLEN]; 05241 05242 initreqprep(&req, p, SIP_NOTIFY); 05243 add_header(&req, "Event", "message-summary"); 05244 add_header(&req, "Content-Type", default_notifymime); 05245 05246 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 05247 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); 05248 ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d (0/0)\r\n", newmsgs, oldmsgs); 05249 05250 if (t > tmp + sizeof(tmp)) 05251 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 05252 05253 add_header_contentLength(&req, strlen(tmp)); 05254 add_line(&req, tmp); 05255 05256 if (!p->initreq.headers) { /* Use this as the basis */ 05257 copy_request(&p->initreq, &req); 05258 parse_request(&p->initreq); 05259 if (sip_debug_test_pvt(p)) 05260 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05261 determine_firstline_parts(&p->initreq); 05262 } 05263 05264 return send_request(p, &req, 1, p->ocseq); 05265 }
static int transmit_notify_with_sipfrag | ( | struct sip_pvt * | p, | |
int | cseq | |||
) | [static] |
transmit_notify_with_sipfrag: Notify a transferring party of the status of trasnfer ---
Definition at line 5287 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().
05288 { 05289 struct sip_request req; 05290 char tmp[20]; 05291 reqprep(&req, p, SIP_NOTIFY, 0, 1); 05292 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 05293 add_header(&req, "Event", tmp); 05294 add_header(&req, "Subscription-state", "terminated;reason=noresource"); 05295 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 05296 05297 strcpy(tmp, "SIP/2.0 200 OK"); 05298 add_header_contentLength(&req, strlen(tmp)); 05299 add_line(&req, tmp); 05300 05301 if (!p->initreq.headers) { 05302 /* Use this as the basis */ 05303 copy_request(&p->initreq, &req); 05304 parse_request(&p->initreq); 05305 if (sip_debug_test_pvt(p)) 05306 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05307 determine_firstline_parts(&p->initreq); 05308 } 05309 05310 return send_request(p, &req, 1, p->ocseq); 05311 }
static int transmit_refer | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
transmit_refer: Transmit SIP REFER message ---
Definition at line 5618 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().
05619 { 05620 struct sip_request req; 05621 char from[256]; 05622 char *of, *c; 05623 char referto[256]; 05624 05625 if (ast_test_flag(p, SIP_OUTGOING)) 05626 of = get_header(&p->initreq, "To"); 05627 else 05628 of = get_header(&p->initreq, "From"); 05629 ast_copy_string(from, of, sizeof(from)); 05630 of = get_in_brackets(from); 05631 ast_copy_string(p->from,of,sizeof(p->from)); 05632 if (strncmp(of, "sip:", 4)) { 05633 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 05634 } else 05635 of += 4; 05636 /* Get just the username part */ 05637 if ((c = strchr(dest, '@'))) { 05638 c = NULL; 05639 } else if ((c = strchr(of, '@'))) { 05640 *c = '\0'; 05641 c++; 05642 } 05643 if (c) { 05644 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 05645 } else { 05646 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 05647 } 05648 05649 /* save in case we get 407 challenge */ 05650 ast_copy_string(p->refer_to, referto, sizeof(p->refer_to)); 05651 ast_copy_string(p->referred_by, p->our_contact, sizeof(p->referred_by)); 05652 05653 reqprep(&req, p, SIP_REFER, 0, 1); 05654 add_header(&req, "Refer-To", referto); 05655 if (!ast_strlen_zero(p->our_contact)) 05656 add_header(&req, "Referred-By", p->our_contact); 05657 add_blank_header(&req); 05658 return send_request(p, &req, 1, p->ocseq); 05659 }
static int transmit_register | ( | struct sip_registry * | r, | |
int | sipmethod, | |||
char * | auth, | |||
char * | authheader | |||
) | [static] |
transmit_register: Transmit register to SIP proxy or UA ---
Definition at line 5417 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().
05418 { 05419 struct sip_request req; 05420 char from[256]; 05421 char to[256]; 05422 char tmp[80]; 05423 char via[80]; 05424 char addr[80]; 05425 struct sip_pvt *p; 05426 05427 /* exit if we are already in process with this registrar ?*/ 05428 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 05429 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 05430 return 0; 05431 } 05432 05433 if (r->call) { /* We have a registration */ 05434 if (!auth) { 05435 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 05436 return 0; 05437 } else { 05438 p = r->call; 05439 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 05440 p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */ 05441 } 05442 } else { 05443 /* Build callid for registration if we haven't registered before */ 05444 if (!r->callid_valid) { 05445 build_callid(r->callid, sizeof(r->callid), __ourip, default_fromdomain); 05446 r->callid_valid = 1; 05447 } 05448 /* Allocate SIP packet for registration */ 05449 p=sip_alloc( r->callid, NULL, 0, SIP_REGISTER); 05450 if (!p) { 05451 ast_log(LOG_WARNING, "Unable to allocate registration call\n"); 05452 return 0; 05453 } 05454 if (recordhistory) { 05455 char tmp[80]; 05456 snprintf(tmp, sizeof(tmp), "Account: %s@%s", r->username, r->hostname); 05457 append_history(p, "RegistryInit", tmp); 05458 } 05459 /* Find address to hostname */ 05460 if (create_addr(p, r->hostname)) { 05461 /* we have what we hope is a temporary network error, 05462 * probably DNS. We need to reschedule a registration try */ 05463 sip_destroy(p); 05464 if (r->timeout > -1) { 05465 ast_sched_del(sched, r->timeout); 05466 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 05467 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 05468 } else { 05469 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 05470 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); 05471 } 05472 r->regattempts++; 05473 return 0; 05474 } 05475 /* Copy back Call-ID in case create_addr changed it */ 05476 ast_copy_string(r->callid, p->callid, sizeof(r->callid)); 05477 if (r->portno) 05478 p->sa.sin_port = htons(r->portno); 05479 else /* Set registry port to the port set from the peer definition/srv or default */ 05480 r->portno = ntohs(p->sa.sin_port); 05481 ast_set_flag(p, SIP_OUTGOING); /* Registration is outgoing call */ 05482 r->call=p; /* Save pointer to SIP packet */ 05483 p->registry=ASTOBJ_REF(r); /* Add pointer to registry in packet */ 05484 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 05485 ast_copy_string(p->peersecret, r->secret, sizeof(p->peersecret)); 05486 if (!ast_strlen_zero(r->md5secret)) 05487 ast_copy_string(p->peermd5secret, r->md5secret, sizeof(p->peermd5secret)); 05488 /* User name in this realm 05489 - if authuser is set, use that, otherwise use username */ 05490 if (!ast_strlen_zero(r->authuser)) { 05491 ast_copy_string(p->peername, r->authuser, sizeof(p->peername)); 05492 ast_copy_string(p->authname, r->authuser, sizeof(p->authname)); 05493 } else { 05494 if (!ast_strlen_zero(r->username)) { 05495 ast_copy_string(p->peername, r->username, sizeof(p->peername)); 05496 ast_copy_string(p->authname, r->username, sizeof(p->authname)); 05497 ast_copy_string(p->fromuser, r->username, sizeof(p->fromuser)); 05498 } 05499 } 05500 if (!ast_strlen_zero(r->username)) 05501 ast_copy_string(p->username, r->username, sizeof(p->username)); 05502 /* Save extension in packet */ 05503 ast_copy_string(p->exten, r->contact, sizeof(p->exten)); 05504 05505 /* 05506 check which address we should use in our contact header 05507 based on whether the remote host is on the external or 05508 internal network so we can register through nat 05509 */ 05510 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 05511 memcpy(&p->ourip, &bindaddr.sin_addr, sizeof(p->ourip)); 05512 build_contact(p); 05513 } 05514 05515 /* set up a timeout */ 05516 if (auth == NULL) { 05517 if (r->timeout > -1) { 05518 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 05519 ast_sched_del(sched, r->timeout); 05520 } 05521 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 05522 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 05523 } 05524 05525 if (strchr(r->username, '@')) { 05526 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 05527 if (!ast_strlen_zero(p->theirtag)) 05528 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 05529 else 05530 snprintf(to, sizeof(to), "<sip:%s>", r->username); 05531 } else { 05532 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 05533 if (!ast_strlen_zero(p->theirtag)) 05534 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 05535 else 05536 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 05537 } 05538 05539 /* Fromdomain is what we are registering to, regardless of actual 05540 host name from SRV */ 05541 if (!ast_strlen_zero(p->fromdomain)) 05542 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 05543 else 05544 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 05545 ast_copy_string(p->uri, addr, sizeof(p->uri)); 05546 05547 p->branch ^= thread_safe_rand(); 05548 05549 memset(&req, 0, sizeof(req)); 05550 init_req(&req, sipmethod, addr); 05551 05552 /* Add to CSEQ */ 05553 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 05554 p->ocseq = r->ocseq; 05555 05556 build_via(p, via, sizeof(via)); 05557 add_header(&req, "Via", via); 05558 add_header(&req, "From", from); 05559 add_header(&req, "To", to); 05560 add_header(&req, "Call-ID", p->callid); 05561 add_header(&req, "CSeq", tmp); 05562 add_header(&req, "User-Agent", default_useragent); 05563 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 05564 05565 05566 if (auth) /* Add auth header */ 05567 add_header(&req, authheader, auth); 05568 else if (!ast_strlen_zero(r->nonce)) { 05569 char digest[1024]; 05570 05571 /* We have auth data to reuse, build a digest header! */ 05572 if (sipdebug) 05573 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 05574 ast_copy_string(p->realm, r->realm, sizeof(p->realm)); 05575 ast_copy_string(p->nonce, r->nonce, sizeof(p->nonce)); 05576 ast_copy_string(p->domain, r->domain, sizeof(p->domain)); 05577 ast_copy_string(p->opaque, r->opaque, sizeof(p->opaque)); 05578 ast_copy_string(p->qop, r->qop, sizeof(p->qop)); 05579 p->noncecount = r->noncecount++; 05580 05581 memset(digest,0,sizeof(digest)); 05582 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 05583 add_header(&req, "Authorization", digest); 05584 else 05585 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 05586 05587 } 05588 05589 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 05590 add_header(&req, "Expires", tmp); 05591 add_header(&req, "Contact", p->our_contact); 05592 add_header(&req, "Event", "registration"); 05593 add_header_contentLength(&req, 0); 05594 add_blank_header(&req); 05595 copy_request(&p->initreq, &req); 05596 parse_request(&p->initreq); 05597 if (sip_debug_test_pvt(p)) { 05598 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05599 } 05600 determine_firstline_parts(&p->initreq); 05601 r->regstate=auth?REG_STATE_AUTHSENT:REG_STATE_REGSENT; 05602 r->regattempts++; /* Another attempt */ 05603 if (option_debug > 3) 05604 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 05605 return send_request(p, &req, 2, p->ocseq); 05606 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
transmit_reinvite_with_sdp: Transmit reinvite with SDP :-) ---
Definition at line 4690 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().
04691 { 04692 struct sip_request req; 04693 if (ast_test_flag(p, SIP_REINVITE_UPDATE)) 04694 reqprep(&req, p, SIP_UPDATE, 0, 1); 04695 else 04696 reqprep(&req, p, SIP_INVITE, 0, 1); 04697 04698 add_header(&req, "Allow", ALLOWED_METHODS); 04699 if (sipdebug) 04700 add_header(&req, "X-asterisk-info", "SIP re-invite (RTP bridge)"); 04701 ast_rtp_offered_from_local(p->rtp, 1); 04702 add_sdp(&req, p); 04703 /* Use this as the basis */ 04704 copy_request(&p->initreq, &req); 04705 parse_request(&p->initreq); 04706 if (sip_debug_test_pvt(p)) 04707 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 04708 p->lastinvite = p->ocseq; 04709 ast_set_flag(p, SIP_OUTGOING); 04710 return send_request(p, &req, 1, p->ocseq); 04711 }
static int transmit_request | ( | struct sip_pvt * | p, | |
int | sipmethod, | |||
int | inc, | |||
int | reliable, | |||
int | newbranch | |||
) | [static] |
transmit_request: transmit generic SIP request ---
Definition at line 5681 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().
05682 { 05683 struct sip_request resp; 05684 reqprep(&resp, p, sipmethod, seqno, newbranch); 05685 add_header_contentLength(&resp, 0); 05686 add_blank_header(&resp); 05687 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 05688 }
static int transmit_request_with_auth | ( | struct sip_pvt * | p, | |
int | sipmethod, | |||
int | inc, | |||
int | reliable, | |||
int | newbranch | |||
) | [static] |
transmit_request_with_auth: Transmit SIP request, auth added ---
Definition at line 5691 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().
05692 { 05693 struct sip_request resp; 05694 05695 reqprep(&resp, p, sipmethod, seqno, newbranch); 05696 if (*p->realm) { 05697 char digest[1024]; 05698 05699 memset(digest, 0, sizeof(digest)); 05700 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 05701 if (p->options && p->options->auth_type == PROXY_AUTH) 05702 add_header(&resp, "Proxy-Authorization", digest); 05703 else if (p->options && p->options->auth_type == WWW_AUTH) 05704 add_header(&resp, "Authorization", digest); 05705 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 05706 add_header(&resp, "Proxy-Authorization", digest); 05707 } else 05708 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 05709 } 05710 /* If we are hanging up and know a cause for that, send it in clear text to make 05711 debugging easier. */ 05712 if (sipmethod == SIP_BYE) { 05713 if (p->owner && p->owner->hangupcause) { 05714 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 05715 } 05716 } 05717 05718 add_header_contentLength(&resp, 0); 05719 add_blank_header(&resp); 05720 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 05721 }
static int transmit_response | ( | struct sip_pvt * | p, | |
char * | msg, | |||
struct sip_request * | req | |||
) | [static] |
transmit_response: Transmit response, no retransmits
Definition at line 4250 of file chan_sip.c.
References __transmit_response().
04251 { 04252 return __transmit_response(p, msg, req, 0); 04253 }
static int transmit_response_reliable | ( | struct sip_pvt * | p, | |
char * | msg, | |||
struct sip_request * | req, | |||
int | fatal | |||
) | [static] |
transmit_response_reliable: Transmit response, Make sure you get a reply
Definition at line 4266 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().
04267 { 04268 return __transmit_response(p, msg, req, fatal ? 2 : 1); 04269 }
static int transmit_response_with_allow | ( | struct sip_pvt * | p, | |
char * | msg, | |||
struct sip_request * | req, | |||
int | reliable | |||
) | [static] |
transmit_response_with_allow: Append Accept header, content length before transmitting response ---
Definition at line 4296 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().
04297 { 04298 struct sip_request resp; 04299 respprep(&resp, p, msg, req); 04300 add_header(&resp, "Accept", "application/sdp"); 04301 add_header_contentLength(&resp, 0); 04302 add_blank_header(&resp); 04303 return send_response(p, &resp, reliable, 0); 04304 }
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] |
Definition at line 4307 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().
04308 { 04309 struct sip_request resp; 04310 char tmp[512]; 04311 int seqno = 0; 04312 04313 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 04314 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 04315 return -1; 04316 } 04317 /* Stale means that they sent us correct authentication, but 04318 based it on an old challenge (nonce) */ 04319 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 04320 respprep(&resp, p, msg, req); 04321 add_header(&resp, header, tmp); 04322 add_header_contentLength(&resp, 0); 04323 add_blank_header(&resp); 04324 return send_response(p, &resp, reliable, seqno); 04325 }
static int transmit_response_with_date | ( | struct sip_pvt * | p, | |
char * | msg, | |||
struct sip_request * | req | |||
) | [static] |
transmit_response_with_date: Append date and content length before transmitting response ---
Definition at line 4285 of file chan_sip.c.
References add_blank_header(), add_header_contentLength(), append_date(), respprep(), and send_response().
Referenced by register_verify().
04286 { 04287 struct sip_request resp; 04288 respprep(&resp, p, msg, req); 04289 append_date(&resp); 04290 add_header_contentLength(&resp, 0); 04291 add_blank_header(&resp); 04292 return send_response(p, &resp, 0, 0); 04293 }
static int transmit_response_with_sdp | ( | struct sip_pvt * | p, | |
char * | msg, | |||
struct sip_request * | req, | |||
int | retrans | |||
) | [static] |
transmit_response_with_sdp: Used for 200 OK and 183 early media ---
Definition at line 4616 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().
04617 { 04618 struct sip_request resp; 04619 int seqno; 04620 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 04621 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 04622 return -1; 04623 } 04624 respprep(&resp, p, msg, req); 04625 if (p->rtp) { 04626 ast_rtp_offered_from_local(p->rtp, 0); 04627 try_suggested_sip_codec(p); 04628 add_sdp(&resp, p); 04629 } else { 04630 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 04631 } 04632 return send_response(p, &resp, retrans, seqno); 04633 }
static int transmit_response_with_unsupported | ( | struct sip_pvt * | p, | |
char * | msg, | |||
struct sip_request * | req, | |||
char * | unsupported | |||
) | [static] |
transmit_response_with_unsupported: Transmit response, no retransmits
Definition at line 4256 of file chan_sip.c.
References add_header(), append_date(), respprep(), and send_response().
Referenced by handle_request_invite().
04257 { 04258 struct sip_request resp; 04259 respprep(&resp, p, msg, req); 04260 append_date(&resp); 04261 add_header(&resp, "Unsupported", unsupported); 04262 return send_response(p, &resp, 0, 0); 04263 }
static int transmit_sip_request | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
transmit_sip_request: Transmit SIP request
Definition at line 5268 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().
05269 { 05270 if (!p->initreq.headers) { 05271 /* Use this as the basis */ 05272 copy_request(&p->initreq, req); 05273 parse_request(&p->initreq); 05274 if (sip_debug_test_pvt(p)) 05275 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 05276 determine_firstline_parts(&p->initreq); 05277 } 05278 05279 return send_request(p, req, 0, p->ocseq); 05280 }
static int transmit_state_notify | ( | struct sip_pvt * | p, | |
int | state, | |||
int | full, | |||
int | substate | |||
) | [static] |
transmit_state_notify: Used in the SUBSCRIBE notification subsystem ----
Definition at line 5062 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().
05063 { 05064 char tmp[4000], from[256], to[256]; 05065 char *t = tmp, *c, *a, *mfrom, *mto; 05066 size_t maxbytes = sizeof(tmp); 05067 struct sip_request req; 05068 char hint[AST_MAX_EXTENSION]; 05069 char *statestring = "terminated"; 05070 const struct cfsubscription_types *subscriptiontype; 05071 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 05072 char *pidfstate = "--"; 05073 char *pidfnote= "Ready"; 05074 05075 memset(from, 0, sizeof(from)); 05076 memset(to, 0, sizeof(to)); 05077 memset(tmp, 0, sizeof(tmp)); 05078 05079 switch (state) { 05080 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 05081 if (global_notifyringing) 05082 statestring = "early"; 05083 else 05084 statestring = "confirmed"; 05085 local_state = NOTIFY_INUSE; 05086 pidfstate = "busy"; 05087 pidfnote = "Ringing"; 05088 break; 05089 case AST_EXTENSION_RINGING: 05090 statestring = "early"; 05091 local_state = NOTIFY_INUSE; 05092 pidfstate = "busy"; 05093 pidfnote = "Ringing"; 05094 break; 05095 case AST_EXTENSION_INUSE: 05096 statestring = "confirmed"; 05097 local_state = NOTIFY_INUSE; 05098 pidfstate = "busy"; 05099 pidfnote = "On the phone"; 05100 break; 05101 case AST_EXTENSION_BUSY: 05102 statestring = "confirmed"; 05103 local_state = NOTIFY_CLOSED; 05104 pidfstate = "busy"; 05105 pidfnote = "On the phone"; 05106 break; 05107 case AST_EXTENSION_UNAVAILABLE: 05108 statestring = "confirmed"; 05109 local_state = NOTIFY_CLOSED; 05110 pidfstate = "away"; 05111 pidfnote = "Unavailable"; 05112 break; 05113 case AST_EXTENSION_NOT_INUSE: 05114 default: 05115 /* Default setting */ 05116 break; 05117 } 05118 05119 subscriptiontype = find_subscription_type(p->subscribed); 05120 05121 /* Check which device/devices we are watching and if they are registered */ 05122 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 05123 /* If they are not registered, we will override notification and show no availability */ 05124 if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) { 05125 local_state = NOTIFY_CLOSED; 05126 pidfstate = "away"; 05127 pidfnote = "Not online"; 05128 } 05129 } 05130 05131 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 05132 c = get_in_brackets(from); 05133 if (strncmp(c, "sip:", 4)) { 05134 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 05135 return -1; 05136 } 05137 if ((a = strchr(c, ';'))) 05138 *a = '\0'; 05139 mfrom = c; 05140 05141 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 05142 c = get_in_brackets(to); 05143 if (strncmp(c, "sip:", 4)) { 05144 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 05145 return -1; 05146 } 05147 if ((a = strchr(c, ';'))) 05148 *a = '\0'; 05149 mto = c; 05150 05151 reqprep(&req, p, SIP_NOTIFY, 0, 1); 05152 05153 05154 add_header(&req, "Event", subscriptiontype->event); 05155 add_header(&req, "Content-Type", subscriptiontype->mediatype); 05156 switch(state) { 05157 case AST_EXTENSION_DEACTIVATED: 05158 if (p->subscribed == TIMEOUT) 05159 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 05160 else { 05161 add_header(&req, "Subscription-State", "terminated;reason=probation"); 05162 add_header(&req, "Retry-After", "60"); 05163 } 05164 break; 05165 case AST_EXTENSION_REMOVED: 05166 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 05167 break; 05168 break; 05169 default: 05170 if (p->expiry) 05171 add_header(&req, "Subscription-State", "active"); 05172 else /* Expired */ 05173 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 05174 } 05175 switch (p->subscribed) { 05176 case XPIDF_XML: 05177 case CPIM_PIDF_XML: 05178 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 05179 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 05180 ast_build_string(&t, &maxbytes, "<presence>\n"); 05181 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 05182 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 05183 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 05184 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 05185 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 05186 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 05187 break; 05188 case PIDF_XML: /* Eyebeam supports this format */ 05189 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 05190 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); 05191 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 05192 if (pidfstate[0] != '-') 05193 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 05194 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 05195 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 05196 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 05197 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 05198 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 05199 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 05200 else 05201 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 05202 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 05203 break; 05204 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 05205 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 05206 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); 05207 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 05208 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 05209 else 05210 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 05211 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 05212 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 05213 break; 05214 case NONE: 05215 default: 05216 break; 05217 } 05218 05219 if (t > tmp + sizeof(tmp)) 05220 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 05221 05222 add_header_contentLength(&req, strlen(tmp)); 05223 add_line(&req, tmp); 05224 05225 return send_request(p, &req, 1, p->ocseq); 05226 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 2517 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().
02518 { 02519 int fmt; 02520 char *codec; 02521 02522 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 02523 if (!codec) 02524 return; 02525 02526 fmt = ast_getformatbyname(codec); 02527 if (fmt) { 02528 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC) variable\n",codec); 02529 if (p->jointcapability & fmt) { 02530 p->jointcapability &= fmt; 02531 p->capability &= fmt; 02532 } else 02533 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 02534 } else 02535 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n",codec); 02536 return; 02537 }
int unload_module | ( | void | ) |
Cleanup all module structures, sockets, etc.
This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 13431 of file chan_sip.c.
References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free_ha(), ast_log(), ast_manager_unregister(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_unregister_application(), ast_variables_destroy(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, sip_pvt::chanvars, checksipdomain_function, clear_realm_authentication(), clear_sip_domains(), free, iflist, localaddr, sip_pvt::lock, LOG_WARNING, monitor_thread, my_clis, sip_pvt::next, sip_pvt::owner, peerl, regl, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_header_function, sip_registry_destroy(), sip_rtp, sip_tech, sipchaninfo_function, sippeer_function, sipsock, and userl.
13432 { 13433 struct sip_pvt *p, *pl; 13434 13435 /* First, take us out of the channel type list */ 13436 ast_channel_unregister(&sip_tech); 13437 13438 ast_custom_function_unregister(&sipchaninfo_function); 13439 ast_custom_function_unregister(&sippeer_function); 13440 ast_custom_function_unregister(&sip_header_function); 13441 ast_custom_function_unregister(&checksipdomain_function); 13442 13443 ast_unregister_application(app_dtmfmode); 13444 ast_unregister_application(app_sipaddheader); 13445 ast_unregister_application(app_sipgetheader); 13446 13447 ast_cli_unregister_multiple(my_clis, sizeof(my_clis) / sizeof(my_clis[0])); 13448 13449 ast_rtp_proto_unregister(&sip_rtp); 13450 13451 ast_manager_unregister("SIPpeers"); 13452 ast_manager_unregister("SIPshowpeer"); 13453 13454 if (!ast_mutex_lock(&iflock)) { 13455 /* Hangup all interfaces if they have an owner */ 13456 p = iflist; 13457 while (p) { 13458 if (p->owner) 13459 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 13460 p = p->next; 13461 } 13462 ast_mutex_unlock(&iflock); 13463 } else { 13464 ast_log(LOG_WARNING, "Unable to lock the interface list\n"); 13465 return -1; 13466 } 13467 13468 if (!ast_mutex_lock(&monlock)) { 13469 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) { 13470 pthread_cancel(monitor_thread); 13471 pthread_kill(monitor_thread, SIGURG); 13472 pthread_join(monitor_thread, NULL); 13473 } 13474 monitor_thread = AST_PTHREADT_STOP; 13475 ast_mutex_unlock(&monlock); 13476 } else { 13477 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 13478 return -1; 13479 } 13480 13481 if (!ast_mutex_lock(&iflock)) { 13482 /* Destroy all the interfaces and free their memory */ 13483 p = iflist; 13484 while (p) { 13485 pl = p; 13486 p = p->next; 13487 /* Free associated memory */ 13488 ast_mutex_destroy(&pl->lock); 13489 if (pl->chanvars) { 13490 ast_variables_destroy(pl->chanvars); 13491 pl->chanvars = NULL; 13492 } 13493 free(pl); 13494 } 13495 iflist = NULL; 13496 ast_mutex_unlock(&iflock); 13497 } else { 13498 ast_log(LOG_WARNING, "Unable to lock the interface list\n"); 13499 return -1; 13500 } 13501 13502 /* Free memory for local network address mask */ 13503 ast_free_ha(localaddr); 13504 13505 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 13506 ASTOBJ_CONTAINER_DESTROY(&userl); 13507 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 13508 ASTOBJ_CONTAINER_DESTROY(&peerl); 13509 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 13510 ASTOBJ_CONTAINER_DESTROY(®l); 13511 13512 clear_realm_authentication(authl); 13513 clear_sip_domains(); 13514 close(sipsock); 13515 sched_context_destroy(sched); 13516 13517 return 0; 13518 }
static int update_call_counter | ( | struct sip_pvt * | fup, | |
int | event | |||
) | [static] |
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 2206 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().
02207 { 02208 char name[256]; 02209 int *inuse, *call_limit; 02210 int outgoing = ast_test_flag(fup, SIP_OUTGOING); 02211 struct sip_user *u = NULL; 02212 struct sip_peer *p = NULL; 02213 02214 if (option_debug > 2) 02215 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 02216 /* Test if we need to check call limits, in order to avoid 02217 realtime lookups if we do not need it */ 02218 if (!ast_test_flag(fup, SIP_CALL_LIMIT)) 02219 return 0; 02220 02221 ast_copy_string(name, fup->username, sizeof(name)); 02222 02223 /* Check the list of users */ 02224 u = find_user(name, 1); 02225 if (u) { 02226 inuse = &u->inUse; 02227 call_limit = &u->call_limit; 02228 p = NULL; 02229 } else { 02230 /* Try to find peer */ 02231 if (!p) 02232 p = find_peer(fup->peername, NULL, 1); 02233 if (p) { 02234 inuse = &p->inUse; 02235 call_limit = &p->call_limit; 02236 ast_copy_string(name, fup->peername, sizeof(name)); 02237 } else { 02238 if (option_debug > 1) 02239 ast_log(LOG_DEBUG, "%s is not a local user, no call limit\n", name); 02240 return 0; 02241 } 02242 } 02243 switch(event) { 02244 /* incoming and outgoing affects the inUse counter */ 02245 case DEC_CALL_LIMIT: 02246 if ( *inuse > 0 ) { 02247 if (ast_test_flag(fup,SIP_INC_COUNT)) 02248 (*inuse)--; 02249 } else { 02250 *inuse = 0; 02251 } 02252 if (option_debug > 1 || sipdebug) { 02253 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 02254 } 02255 break; 02256 case INC_CALL_LIMIT: 02257 if (*call_limit > 0 ) { 02258 if (*inuse >= *call_limit) { 02259 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); 02260 if (u) 02261 ASTOBJ_UNREF(u,sip_destroy_user); 02262 else 02263 ASTOBJ_UNREF(p,sip_destroy_peer); 02264 return -1; 02265 } 02266 } 02267 (*inuse)++; 02268 ast_set_flag(fup,SIP_INC_COUNT); 02269 if (option_debug > 1 || sipdebug) { 02270 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 02271 } 02272 break; 02273 default: 02274 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 02275 } 02276 if (u) 02277 ASTOBJ_UNREF(u,sip_destroy_user); 02278 else 02279 ASTOBJ_UNREF(p,sip_destroy_peer); 02280 return 0; 02281 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
update_peer: Update peer data in database (if used) ---
Definition at line 1674 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().
01675 { 01676 int rtcachefriends = ast_test_flag(&(p->flags_page2), SIP_PAGE2_RTCACHEFRIENDS); 01677 if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTUPDATE) && 01678 (ast_test_flag(p, SIP_REALTIME) || rtcachefriends)) { 01679 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry); 01680 } 01681 }
int usecount | ( | void | ) |
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 13520 of file chan_sip.c.
References usecnt.
13521 { 13522 return usecnt; 13523 }
struct in_addr __ourip [static] |
Definition at line 413 of file chan_sip.c.
Accept calls to external SIP domains?
Definition at line 501 of file chan_sip.c.
Referenced by get_destination(), reload_config(), and sip_show_settings().
int apeerobjs = 0 [static] |
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 12997 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 12999 of file chan_sip.c.
char* app_sipgetheader = "SIPGetHeader" [static] |
Definition at line 13011 of file chan_sip.c.
Authentication list
Definition at line 884 of file chan_sip.c.
Referenced by build_reply_digest(), reload_config(), sip_do_reload(), sip_show_settings(), and unload_module().
int autocreatepeer = 0 [static] |
Auto creation of peers at registration? Default off.
Definition at line 363 of file chan_sip.c.
Referenced by register_verify(), reload_config(), and sip_show_settings().
struct sockaddr_in bindaddr = { 0, } [static] |
Definition at line 874 of file chan_sip.c.
int callevents = 0 [static] |
Definition at line 909 of file chan_sip.c.
Referenced by process_sdp(), reload_config(), and sip_show_settings().
const char channeltype[] = "SIP" [static] |
Definition at line 145 of file chan_sip.c.
struct ast_custom_function checksipdomain_function [static] |
int compactheaders = 0 [static] |
send compact sip headers
Definition at line 426 of file chan_sip.c.
Referenced by add_header(), reload_config(), and sip_show_settings().
const char config[] = "sip.conf" [static] |
Definition at line 146 of file chan_sip.c.
char debug_usage[] [static] |
Definition at line 9255 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 420 of file chan_sip.c.
Referenced by sip_do_debug(), sip_do_debug_ip(), and sip_do_debug_peer().
char default_callerid[AST_MAX_EXTENSION] = DEFAULT_CALLERID [static] |
Definition at line 343 of file chan_sip.c.
Referenced by build_rpid(), initreqprep(), reload_config(), and sip_show_settings().
char default_context[AST_MAX_CONTEXT] = DEFAULT_CONTEXT [static] |
Definition at line 334 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 121 of file chan_sip.c.
Referenced by handle_response_register(), parse_register_contact(), reload_config(), sip_send_all_registers(), sip_show_settings(), and transmit_register().
char default_fromdomain[AST_MAX_EXTENSION] = "" [static] |
Definition at line 345 of file chan_sip.c.
Referenced by reload_config(), sip_show_settings(), and transmit_register().
char default_language[MAX_LANGUAGE] = "" [static] |
Definition at line 340 of file chan_sip.c.
Referenced by build_peer(), build_user(), reload_config(), sip_show_settings(), and temp_peer().
char default_notifymime[AST_MAX_EXTENSION] = DEFAULT_NOTIFYMIME [static] |
Definition at line 348 of file chan_sip.c.
Referenced by reload_config(), sip_show_settings(), and transmit_notify_with_mwi().
int default_qualify = 0 [static] |
Default Qualify= setting
Definition at line 354 of file chan_sip.c.
Referenced by build_peer(), reload_config(), and sip_show_settings().
char default_subscribecontext[AST_MAX_CONTEXT] [static] |
Definition at line 335 of file chan_sip.c.
Referenced by build_peer(), reload_config(), and temp_peer().
char default_useragent[AST_MAX_EXTENSION] = DEFAULT_USERAGENT [static] |
Definition at line 331 of file chan_sip.c.
Referenced by initreqprep(), reload_config(), reqprep(), respprep(), sip_show_settings(), and transmit_register().
const char desc[] = "Session Initiation Protocol (SIP)" [static] |
Definition at line 144 of file chan_sip.c.
char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static] |
Definition at line 12996 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 13003 of file chan_sip.c.
char* descrip_sipgetheader [static] |
Definition at line 13014 of file chan_sip.c.
int dumphistory = 0 [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 429 of file chan_sip.c.
Referenced by reload_config().
int expiry = DEFAULT_EXPIRY [static] |
Definition at line 437 of file chan_sip.c.
Referenced by complete_dpreply(), parse_register_contact(), reg_source_db(), register_verify(), and reload_config().
time_t externexpire = 0 [static] |
char externhost[MAXHOSTNAMELEN] = "" [static] |
struct sockaddr_in externip [static] |
int externrefresh = 10 [static] |
int global_allowguest = 1 [static] |
allow unauthenticated users/peers to connect?
Definition at line 384 of file chan_sip.c.
Referenced by check_auth(), check_user_full(), handle_common_options(), reload_config(), and sip_show_settings().
int global_alwaysauthreject = 0 [static] |
Send 401 Unauthorized for all failing requests
Definition at line 352 of file chan_sip.c.
Referenced by check_user_full(), register_verify(), reload_config(), and sip_show_settings().
int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 [static] |
Codecs that we support by default:.
Definition at line 410 of file chan_sip.c.
Referenced by build_peer(), build_user(), reload_config(), sip_request_call(), and temp_peer().
struct ast_flags global_flags = {0} [static] |
global SIP_ flags
Definition at line 356 of file chan_sip.c.
Referenced by build_peer(), build_user(), check_user_full(), reload_config(), sip_alloc(), sip_show_settings(), and temp_peer().
struct ast_flags global_flags_page2 = {0} [static] |
more global SIP_ flags
Definition at line 357 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), realtime_peer(), realtime_user(), reload_config(), sip_show_settings(), and update_peer().
char global_musicclass[MAX_MUSICCLASS] = "" [static] |
Global music on hold class
Definition at line 431 of file chan_sip.c.
Referenced by build_peer(), build_user(), reload_config(), sip_show_settings(), and temp_peer().
int global_mwitime = DEFAULT_MWITIME [static] |
Time between MWI checks for peers
Definition at line 387 of file chan_sip.c.
Referenced by do_monitor(), reload_config(), and sip_show_settings().
int global_notifyringing = 1 [static] |
Send notifications on ringing
Definition at line 350 of file chan_sip.c.
Referenced by reload_config(), sip_show_settings(), and transmit_state_notify().
char global_realm[MAXHOSTNAMELEN] = DEFAULT_REALM [static] |
Default realm
Definition at line 433 of file chan_sip.c.
Referenced by check_auth(), reload_config(), sip_show_settings(), and transmit_response_with_auth().
int global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT [static] |
Definition at line 373 of file chan_sip.c.
Referenced by reload_config(), sip_show_settings(), and transmit_register().
int global_regattempts_max = 0 [static] |
Definition at line 374 of file chan_sip.c.
Referenced by handle_response_register(), reload_config(), sip_reg_timeout(), and sip_show_settings().
int global_rtautoclear [static] |
Definition at line 589 of file chan_sip.c.
int global_rtpholdtimeout = 0 [static] |
Definition at line 369 of file chan_sip.c.
Referenced by build_peer(), reload_config(), sip_show_settings(), and temp_peer().
int global_rtpkeepalive = 0 [static] |
Definition at line 371 of file chan_sip.c.
Referenced by build_peer(), reload_config(), and temp_peer().
int global_rtptimeout = 0 [static] |
Definition at line 367 of file chan_sip.c.
Referenced by build_peer(), reload_config(), sip_show_settings(), and temp_peer().
char global_vmexten[AST_MAX_EXTENSION] = DEFAULT_VMEXTEN [static] |
Definition at line 338 of file chan_sip.c.
Referenced by build_peer(), reload_config(), sip_show_settings(), and transmit_notify_with_mwi().
char history_usage[] [static] |
Initial value:
"Usage: sip history\n" " Enables recording of SIP dialog history for debugging purposes.\n" "Use 'sip show history' to view the history of a call number.\n"
Definition at line 9272 of file chan_sip.c.
sip_pvt: PVT structures are used for each SIP conversation, ie. a call
struct io_context* io [static] |
Definition at line 440 of file chan_sip.c.
Definition at line 879 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), and unload_module().
char mandescr_show_peer[] [static] |
char mandescr_show_peers[] [static] |
Initial value:
"Description: Lists SIP peers in text format with details on current status.\n" "Variables: \n" " ActionID: <id> Action ID for this transaction. Will be returned.\n"
Definition at line 7561 of file chan_sip.c.
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Definition at line 120 of file chan_sip.c.
Referenced by handle_request_subscribe(), parse_register_contact(), reload_config(), and sip_show_settings().
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
This is the thread for the monitor which checks for input on the channels which are not currently in use.
Definition at line 405 of file chan_sip.c.
struct ast_cli_entry my_clis[] [static] |
Definition at line 13342 of file chan_sip.c.
char no_debug_usage[] [static] |
Initial value:
"Usage: sip no debug\n" " Disables dumping of SIP packets for debugging purposes\n"
Definition at line 9264 of file chan_sip.c.
char no_history_usage[] [static] |
Initial value:
"Usage: sip no history\n" " Disables recording of SIP dialog history for debugging purposes\n"
Definition at line 9268 of file chan_sip.c.
int noncodeccapability = AST_RTP_DTMF [static] |
const char notify_config[] = "sip_notify.conf" [static] |
struct ast_config* notify_types |
Definition at line 882 of file chan_sip.c.
Referenced by complete_sipnotify(), reload_config(), and sip_notify().
char notify_usage[] [static] |
Initial value:
"Usage: sip notify <type> <peer> [<peer>...]\n" " Send a NOTIFY message to a SIP peer or peers\n" " Message types are defined in sip_notify.conf\n"
Definition at line 9204 of file chan_sip.c.
int ourport [static] |
Definition at line 415 of file chan_sip.c.
struct sockaddr_in outboundproxyip [static] |
int pedanticsipchecking = 0 [static] |
Extra checking ? Default off
Definition at line 361 of file chan_sip.c.
Referenced by check_user_full(), get_destination(), get_refer_info(), handle_request(), initreqprep(), register_verify(), reload_config(), sip_show_settings(), and sipsock_read().
struct ast_peer_list peerl [static] |
The peer list: Peers and Friends ---.
struct ast_codec_pref prefs [static] |
Definition at line 448 of file chan_sip.c.
char prune_realtime_usage[] [static] |
Initial value:
"Usage: sip prune realtime [peer|user] [<name>|all|like <pattern>]\n" " Prunes object(s) from the cache.\n" " Optional regular expression pattern is used to filter the objects.\n"
Definition at line 9246 of file chan_sip.c.
int recordhistory = 0 [static] |
Record SIP history. Off by default
Definition at line 428 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().
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Context for auto-extensions
Definition at line 434 of file chan_sip.c.
struct ast_register_list regl [static] |
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().
int regobjs = 0 [static] |
Definition at line 382 of file chan_sip.c.
Referenced by sip_send_all_registers(), and sip_show_objects().
int relaxdtmf = 0 [static] |
int rpeerobjs = 0 [static] |
int ruserobjs = 0 [static] |
struct sched_context* sched [static] |
Definition at line 439 of file chan_sip.c.
char show_channel_usage[] [static] |
Initial value:
"Usage: sip show channel <channel>\n" " Provides detailed status on a given SIP channel.\n"
Definition at line 9228 of file chan_sip.c.
char show_channels_usage[] [static] |
Initial value:
"Usage: sip show channels\n" " Lists all currently active SIP channels.\n"
Definition at line 9224 of file chan_sip.c.
char show_domains_usage[] [static] |
Initial value:
"Usage: sip show domains\n" " Lists all configured SIP local domains.\n" " Asterisk only responds to SIP messages to local domains.\n"
Definition at line 9199 of file chan_sip.c.
char show_history_usage[] [static] |
Initial value:
"Usage: sip show history <channel>\n" " Provides detailed dialog history on a given SIP channel.\n"
Definition at line 9232 of file chan_sip.c.
char show_inuse_usage[] [static] |
Initial value:
"Usage: sip show inuse [all]\n" " List all SIP users and peers usage counters and limits.\n" " Add option \"all\" to show all devices, not only those with a limit.\n"
Definition at line 9219 of file chan_sip.c.
char show_objects_usage[] [static] |
Initial value:
"Usage: sip show objects\n" " Shows status of known SIP objects\n"
Definition at line 9285 of file chan_sip.c.
char show_peer_usage[] [static] |
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 9241 of file chan_sip.c.
char show_peers_usage[] [static] |
Initial value:
"Usage: sip show peers [like <pattern>]\n" " Lists all known SIP peers.\n" " Optional regular expression pattern is used to filter the peer list.\n"
Definition at line 9236 of file chan_sip.c.
char show_reg_usage[] [static] |
Initial value:
"Usage: sip show registry\n" " Lists all registration requests and status.\n"
Definition at line 9251 of file chan_sip.c.
char show_settings_usage[] [static] |
Initial value:
"Usage: sip show settings\n" " Provides detailed list of the configuration of the SIP channel.\n"
Definition at line 9289 of file chan_sip.c.
char show_subscriptions_usage[] [static] |
Initial value:
"Usage: sip show subscriptions\n" " Shows active SIP subscriptions for extension states\n"
Definition at line 9281 of file chan_sip.c.
char show_user_usage[] [static] |
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 9214 of file chan_sip.c.
char show_users_usage[] [static] |
Initial value:
"Usage: sip show users [like <pattern>]\n" " Lists all known SIP users.\n" " Optional regular expression pattern is used to filter the user list.\n"
Definition at line 9209 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
enum sipmethod sip_method_list |
struct cfsip_methods sip_methods[] [static] |
XXX Note that sip_methods[i].id == i must hold or the code breaks
Referenced by __sip_ack(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), do_proxy_auth(), find_call(), find_sip_method(), get_destination(), handle_request(), handle_request_subscribe(), handle_response(), init_req(), initreqprep(), reqprep(), retrans_pkt(), sip_alloc(), and transmit_register().
struct cfsip_options sip_options[] [static] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.
Referenced by _sip_show_peer(), parse_sip_options(), and sip_show_channel().
char sip_reload_usage[] [static] |
Initial value:
"Usage: sip reload\n" " Reloads SIP configuration from sip.conf\n"
Definition at line 9277 of file chan_sip.c.
int sip_reloading = 0 [static] |
struct ast_rtp_protocol sip_rtp [static] |
sip_rtp: Interface structure with callbacks used to connect to rtp module --
Definition at line 13247 of file chan_sip.c.
Referenced by load_module(), and unload_module().
struct ast_channel_tech sip_tech [static] |
Definition of this channel for PBX channel registration.
Definition at line 935 of file chan_sip.c.
Referenced by load_module(), sip_new(), and unload_module().
struct ast_custom_function sipchaninfo_function [static] |
int sipdebug = 0 [static] |
Definition at line 419 of file chan_sip.c.
Referenced by add_sip_domain(), build_reply_digest(), check_auth(), handle_request_info(), handle_request_invite(), handle_request_subscribe(), handle_response_register(), reload_config(), sip_addheader(), sip_do_debug(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), sip_poke_peer(), sip_reregister(), transmit_invite(), transmit_register(), and transmit_reinvite_with_sdp().
int sipsock = -1 [static] |
Definition at line 871 of file chan_sip.c.
Referenced by __sip_xmit(), do_monitor(), reg_source_db(), reload_config(), sipsock_read(), and unload_module().
int speerobjs = 0 [static] |
int srvlookup = 0 [static] |
SRV Lookup on or off. Default is off, RFC behavior is on
Definition at line 359 of file chan_sip.c.
Referenced by build_peer(), reload_config(), and sip_show_settings().
struct cfsubscription_types subscription_types[] [static] |
Referenced by find_subscription_type(), and subscription_type2str().
int suserobjs = 0 [static] |
char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static] |
Definition at line 12995 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 13000 of file chan_sip.c.
char* synopsis_sipgetheader = "Get a SIP header from an incoming call" [static] |
Definition at line 13012 of file chan_sip.c.
int tos = 0 [static] |
Definition at line 422 of file chan_sip.c.
int usecnt = 0 [static] |
Definition at line 389 of file chan_sip.c.
struct ast_user_list userl [static] |
The user list: Users and friends ---.
int videosupport = 0 [static] |
Definition at line 424 of file chan_sip.c.
Referenced by add_sdp(), reload_config(), and sip_show_settings().