#include "asterisk.h"
#include <sys/mman.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <signal.h>
#include <strings.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <regex.h>
#include "asterisk/paths.h"
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/md5.h"
#include "asterisk/cdr.h"
#include "asterisk/crypto.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/app.h"
#include "asterisk/astdb.h"
#include "asterisk/musiconhold.h"
#include "asterisk/features.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/localtime.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/netsock.h"
#include "asterisk/stringfields.h"
#include "asterisk/linkedlists.h"
#include "asterisk/event.h"
#include "asterisk/astobj2.h"
#include "asterisk/timing.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/test.h"
#include "asterisk/data.h"
#include "asterisk/netsock2.h"
#include "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"
#include "jitterbuf.h"
Go to the source code of this file.
Data Structures | |
struct | active_list |
struct | addr_range |
struct | callno_entry |
struct | chan_iax2_pvt |
struct | chan_iax2_pvt::signaling_queue |
struct | create_addr_info |
struct | dpcache |
struct | dpreq_data |
struct | dynamic_list |
struct | firmwares |
struct | iax2_context |
struct | iax2_dpcache |
struct | iax2_peer |
struct | iax2_pkt_buf |
struct | iax2_registry |
struct | iax2_thread |
struct | iax2_trunk_peer |
struct | iax2_user |
struct | iax_dual |
struct | iax_firmware |
struct | iax_rr |
struct | idle_list |
struct | parsed_dial_string |
struct | peercnt |
struct | registrations |
struct | signaling_queue_entry |
struct | tpeers |
Defines | |
#define | ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" |
#define | ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" |
#define | CALLNO_TO_PTR(a) ((void *)(unsigned long)(a)) |
#define | CALLTOKEN_HASH_FORMAT "%s%d%u%d" |
#define | CALLTOKEN_IE_FORMAT "%u?%s" |
#define | DATA_EXPORT_IAX2_PEER(MEMBER) |
#define | DATA_EXPORT_IAX2_USER(MEMBER) |
#define | DEBUG_SCHED_MULTITHREAD |
#define | DEBUG_SUPPORT |
#define | DEFAULT_CONTEXT "default" |
#define | DEFAULT_DROP 3 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_THREAD_COUNT 100 |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_RETRY_TIME 1000 |
#define | DEFAULT_THREAD_COUNT 10 |
#define | DEFAULT_TRUNKDATA 640 * 10 |
#define | DONT_RESCHEDULE -2 |
#define | FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n" |
#define | FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define | FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n" |
#define | FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define | FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" |
#define | FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n" |
#define | FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define | FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define | GAMMA (0.01) |
#define | IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define | IAX_ALLOWFWDOWNLOAD (uint64_t)(1 << 26) |
#define | IAX_ALREADYGONE (uint64_t)(1 << 9) |
#define | IAX_CALLENCRYPTED(pvt) (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED)) |
#define | IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
#define | IAX_CAPABILITY_LOWBANDWIDTH |
#define | IAX_CAPABILITY_LOWFREE |
#define | IAX_CAPABILITY_MEDBANDWIDTH |
#define | IAX_CODEC_NOCAP (uint64_t)(1 << 16) |
#define | IAX_CODEC_NOPREFS (uint64_t)(1 << 15) |
#define | IAX_CODEC_USER_FIRST (uint64_t)(1 << 14) |
#define | IAX_DEBUGDIGEST(msg, key) |
#define | IAX_DELAYPBXSTART (uint64_t)(1 << 25) |
#define | IAX_DELME (uint64_t)(1 << 1) |
#define | IAX_DYNAMIC (uint64_t)(1 << 6) |
#define | IAX_ENCRYPTED (uint64_t)(1 << 12) |
#define | IAX_FORCE_ENCRYPT (uint64_t)(1 << 30) |
#define | IAX_FORCEJITTERBUF (uint64_t)(1 << 20) |
#define | IAX_HASCALLERID (uint64_t)(1 << 0) |
#define | IAX_IMMEDIATE (uint64_t)(1 << 27) |
#define | IAX_KEYPOPULATED (uint64_t)(1 << 13) |
#define | IAX_MAXAUTHREQ (uint64_t)(1 << 24) |
#define | IAX_NOTRANSFER (uint64_t)(1 << 4) |
#define | IAX_PROVISION (uint64_t)(1 << 10) |
#define | IAX_QUELCH (uint64_t)(1 << 11) |
#define | IAX_RECVCONNECTEDLINE (uint64_t)(1 << 29) |
#define | IAX_RTAUTOCLEAR (uint64_t)(1 << 19) |
#define | IAX_RTCACHEFRIENDS (uint64_t)(1 << 17) |
#define | IAX_RTIGNOREREGEXPIRE (uint64_t)(1 << 21) |
#define | IAX_RTSAVE_SYSNAME (uint64_t)(1 << 8) |
#define | IAX_RTUPDATE (uint64_t)(1 << 18) |
#define | IAX_SENDANI (uint64_t)(1 << 7) |
#define | IAX_SENDCONNECTEDLINE (uint64_t)(1 << 28) |
#define | IAX_SHRINKCALLERID (uint64_t)(1 << 31) |
#define | IAX_TEMPONLY (uint64_t)(1 << 2) |
#define | IAX_TRANSFERMEDIA (uint64_t)(1 << 23) |
#define | IAX_TRUNK (uint64_t)(1 << 3) |
#define | IAX_TRUNKTIMESTAMPS (uint64_t)(1 << 22) |
#define | IAX_USEJITTERBUF (uint64_t)(1 << 5) |
#define | MARK_IAX_SUBCLASS_TX 0x8000 |
#define | MAX_JITTER_BUFFER 50 |
#define | MAX_PEER_BUCKETS 563 |
#define | MAX_RETRY_TIME 10000 |
#define | MAX_TIMESTAMP_SKEW 160 |
#define | MAX_TRUNK_MTU 1240 |
Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240. | |
#define | MAX_TRUNKDATA 640 * 200 |
#define | MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define | MEMORY_SIZE 100 |
#define | MIN_JITTER_BUFFER 10 |
#define | MIN_RETRY_TIME 100 |
#define | MIN_REUSE_TIME 60 |
#define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
#define | SCHED_MULTITHREADED |
#define | schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__) |
#define | TRUNK_CALL_START IAX_MAX_CALLS / 2 |
#define | TS_GAP_FOR_JB_RESYNC 5000 |
#define | update_max_nontrunk() do { } while (0) |
#define | update_max_trunk() do { } while (0) |
Enumerations | |
enum | { CACHE_FLAG_EXISTS = (1 << 0), CACHE_FLAG_NONEXISTENT = (1 << 1), CACHE_FLAG_CANEXIST = (1 << 2), CACHE_FLAG_PENDING = (1 << 3), CACHE_FLAG_TIMEOUT = (1 << 4), CACHE_FLAG_TRANSMITTED = (1 << 5), CACHE_FLAG_UNKNOWN = (1 << 6), CACHE_FLAG_MATCHMORE = (1 << 7) } |
enum | { NEW_PREVENT = 0, NEW_ALLOW = 1, NEW_FORCE = 2, NEW_ALLOW_CALLTOKEN_VALIDATED = 3 } |
enum | calltoken_peer_enum { CALLTOKEN_DEFAULT = 0, CALLTOKEN_YES = 1, CALLTOKEN_AUTO = 2, CALLTOKEN_NO = 3 } |
Call token validation settings. More... | |
enum | iax2_state { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2) } |
enum | iax2_thread_iostate { IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_SCHEDREADY } |
enum | iax2_thread_type { IAX_THREAD_TYPE_POOL, IAX_THREAD_TYPE_DYNAMIC } |
enum | iax_reg_state { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH } |
enum | iax_transfer_state { TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED, TRANSFER_PASSTHROUGH, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED, TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS } |
Functions | |
static void | __attempt_transmit (const void *data) |
static void | __auth_reject (const void *nothing) |
static void | __auto_congest (const void *nothing) |
static void | __auto_hangup (const void *nothing) |
static int | __do_deliver (void *data) |
static void | __expire_registry (const void *data) |
static int | __find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno) |
static void | __get_from_jb (const void *p) |
static void | __iax2_do_register_s (const void *data) |
static void | __iax2_poke_noanswer (const void *data) |
static void | __iax2_poke_peer_s (const void *data) |
static int | __iax2_show_peers (int fd, int *total, struct mansession *s, const int argc, const char *const argv[]) |
static void | __reg_module (void) |
static int | __schedule_action (void(*func)(const void *data), const void *data, const char *funcname) |
static int | __send_command (struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, int now, int transfer, int final) |
static void | __send_lagrq (const void *data) |
static void | __send_ping (const void *data) |
static int | __unload_module (void) |
static void | __unreg_module (void) |
static int | acf_channel_read (struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen) |
static int | acf_iaxvar_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
static int | acf_iaxvar_write (struct ast_channel *chan, const char *cmd, char *data, const char *value) |
static int | add_calltoken_ignore (const char *addr) |
static void | add_empty_calltoken_ie (struct chan_iax2_pvt *pvt, struct iax_ie_data *ied) |
static int | addr_range_cmp_cb (void *obj, void *arg, int flags) |
static int | addr_range_delme_cb (void *obj, void *arg, int flags) |
static int | addr_range_hash_cb (const void *obj, const int flags) |
static int | addr_range_match_address_cb (void *obj, void *arg, int flags) |
static int | apply_context (struct iax2_context *con, const char *context) |
static int | ast_cli_netstats (struct mansession *s, int fd, int limit_fmt) |
AST_DATA_STRUCTURE (iax2_user, DATA_EXPORT_IAX2_USER) | |
AST_DATA_STRUCTURE (iax2_peer, DATA_EXPORT_IAX2_PEER) | |
static struct ast_channel * | ast_iax2_new (int callno, int state, format_t capability, const char *linkedid) |
Create new call, interface with the PBX core. | |
static int | attempt_transmit (const void *data) |
static int | auth_fail (int callno, int failcode) |
static int | auth_reject (const void *data) |
static int | authenticate (const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, struct chan_iax2_pvt *pvt) |
static int | authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey) |
static int | authenticate_request (int call_num) |
static int | authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies) |
static int | auto_congest (const void *data) |
static int | auto_hangup (const void *data) |
static void | build_callno_limits (struct ast_variable *v) |
static struct iax2_context * | build_context (const char *context) |
static void | build_ecx_key (const unsigned char *digest, struct chan_iax2_pvt *pvt) |
static void | build_encryption_keys (const unsigned char *digest, struct chan_iax2_pvt *pvt) |
static struct iax2_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create peer structure based on configuration. | |
static void | build_rand_pad (unsigned char *buf, ssize_t len) |
static struct iax2_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create in-memory user structure from configuration. | |
static int | cache_get_callno_locked (const char *data) |
static unsigned int | calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset) |
static unsigned int | calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f) |
static unsigned int | calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now) |
static int | callno_hash (const void *obj, const int flags) |
static int | calltoken_required (struct sockaddr_in *sin, const char *name, int subclass) |
static int | check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
static int | check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver) |
static int | check_srcaddr (struct sockaddr *sa, socklen_t salen) |
Check if address can be used as packet source. | |
static void | cleanup_thread_list (void *head) |
static int | complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static char * | complete_iax2_peers (const char *line, const char *word, int pos, int state, uint64_t flags) |
static char * | complete_iax2_unregister (const char *line, const char *word, int pos, int state) |
static int | complete_transfer (int callno, struct iax_ies *ies) |
static unsigned char | compress_subclass (format_t subclass) |
static void | construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) |
static int | create_addr (const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai) |
static int | create_callno_pools (void) |
static int | decode_frame (ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static int | decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static void | defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here) |
Queue the last read full frame for processing by a certain thread. | |
static void | delete_users (void) |
static void | destroy_firmware (struct iax_firmware *cur) |
static void | dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock) |
static void * | dp_lookup_thread (void *data) |
static void | encmethods_to_str (int e, struct ast_str *buf) |
static int | encrypt_frame (ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen) |
static int | expire_registry (const void *data) |
static struct iax2_dpcache * | find_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority) |
static int | find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
static int | find_callno_locked (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
static struct iax2_thread * | find_idle_thread (void) |
static struct iax2_peer * | find_peer (const char *name, int realtime) |
static struct iax2_trunk_peer * | find_tpeer (struct sockaddr_in *sin, int fd) |
static struct iax2_user * | find_user (const char *name) |
static unsigned int | fix_peerts (struct timeval *rxtrunktime, int callno, unsigned int ts) |
static void | free_context (struct iax2_context *con) |
static void | free_signaling_queue_entry (struct signaling_queue_entry *s) |
static int | function_iaxpeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
static int | get_auth_methods (const char *value) |
static int | get_encrypt_methods (const char *s) |
static int | get_from_jb (const void *p) |
static struct callno_entry * | get_unused_callno (int trunk, int validated) |
static int | handle_call_token (struct ast_iax2_full_hdr *fh, struct iax_ies *ies, struct sockaddr_in *sin, int fd) |
static char * | handle_cli_iax2_provision (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_prune_realtime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_set_debug_jb (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_set_debug_trunk (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_set_mtu (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Set trunk MTU from CLI. | |
static char * | handle_cli_iax2_show_cache (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_callno_limits (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_firmware (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_netstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show one peer in detail. | |
static char * | handle_cli_iax2_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_threads (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_test_losspct (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static void | handle_deferred_full_frames (struct iax2_thread *thread) |
Handle any deferred full frames for this thread. | |
static int | handle_error (void) |
static int | iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno) |
Acknowledgment received for OUR registration. | |
static int attribute_pure | iax2_allow_new (int frametype, int subclass, int inbound) |
static void | iax2_ami_channelupdate (struct chan_iax2_pvt *pvt) |
Send manager event at call setup to link between Asterisk channel name and IAX2 call identifiers. | |
static int | iax2_answer (struct ast_channel *c) |
static int | iax2_append_register (const char *hostname, const char *username, const char *secret, const char *porta) |
static enum ast_bridge_result | iax2_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | iax2_call (struct ast_channel *c, char *dest, int timeout) |
static int | iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
part of the IAX2 dial plan switch interface | |
static unsigned int | iax2_datetime (const char *tz) |
static void | iax2_destroy (int callno) |
static void | iax2_destroy_helper (struct chan_iax2_pvt *pvt) |
static int | iax2_devicestate (void *data) |
Part of the device state notification system ---. | |
static int | iax2_digit_begin (struct ast_channel *c, char digit) |
static int | iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
static int | iax2_do_register (struct iax2_registry *reg) |
static int | iax2_do_register_s (const void *data) |
static void | iax2_dprequest (struct iax2_dpcache *dp, int callno) |
static void * | iax2_dup_variable_datastore (void *) |
static int | iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Execute IAX2 dialplan switch. | |
static int | iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 switch interface. | |
static int | iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan) |
static void | iax2_frame_free (struct iax_frame *fr) |
static void | iax2_free_variable_datastore (void *) |
static int | iax2_getpeername (struct sockaddr_in sin, char *host, int len) |
static int | iax2_getpeertrunk (struct sockaddr_in sin) |
static int | iax2_hangup (struct ast_channel *c) |
static int | iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen) |
static int | iax2_key_rotate (const void *vpvt) |
static void | iax2_lock_owner (int callno) |
static int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 Switch interface. | |
static int | iax2_poke_noanswer (const void *data) |
static int | iax2_poke_peer (struct iax2_peer *peer, int heldcall) |
static int | iax2_poke_peer_cb (void *obj, void *arg, int flags) |
static int | iax2_poke_peer_s (const void *data) |
static int | iax2_predestroy (int callno) |
static void * | iax2_process_thread (void *data) |
static void | iax2_process_thread_cleanup (void *data) |
static int | iax2_prov_app (struct ast_channel *chan, const char *data) |
static int | iax2_provision (struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force) |
static int | iax2_queryoption (struct ast_channel *c, int option, void *data, int *datalen) |
static int | iax2_queue_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen) |
Queue a control frame on the ast_channel owner. | |
static int | iax2_queue_frame (int callno, struct ast_frame *f) |
Queue a frame to a call's owning asterisk channel. | |
static int | iax2_queue_hangup (int callno) |
Queue a hangup frame on the ast_channel owner. | |
static struct ast_frame * | iax2_read (struct ast_channel *c) |
static int | iax2_register (const char *value, int lineno) |
static struct ast_channel * | iax2_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause) |
static int | iax2_sched_add (struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data) |
static int | iax2_sched_replace (int id, struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data) |
static int | iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final) |
static int | iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen) |
static int | iax2_sendimage (struct ast_channel *c, struct ast_frame *img) |
static int | iax2_sendtext (struct ast_channel *c, const char *text) |
static int | iax2_setoption (struct ast_channel *c, int option, void *data, int datalen) |
static int | iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly) |
static int | iax2_transfer (struct ast_channel *c, const char *dest) |
static int | iax2_transmit (struct iax_frame *fr) |
static int | iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr) |
static int | iax2_vnak (int callno) |
static int | iax2_write (struct ast_channel *c, struct ast_frame *f) |
static int | iax_check_version (char *dev) |
static void | iax_debug_output (const char *data) |
static void | iax_error_output (const char *data) |
static int | iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc) |
static void | iax_outputframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen) |
static int | iax_park (struct ast_channel *chan1, struct ast_channel *chan2, const char *park_exten, const char *park_context) |
static void * | iax_park_thread (void *stuff) |
static struct iax_frame * | iaxfrdup2 (struct iax_frame *fr) |
static void | insert_idle_thread (struct iax2_thread *thread) |
static void | jb_debug_output (const char *fmt,...) |
static void | jb_error_output (const char *fmt,...) |
static void | jb_warning_output (const char *fmt,...) |
static int | load_module (void) |
Load IAX2 module, load configuraiton ---. | |
static int | load_objects (void) |
static void | lock_both (unsigned short callno0, unsigned short callno1) |
static void | log_jitterstats (unsigned short callno) |
static int | make_trunk (unsigned short callno, int locked) |
static int | manager_iax2_show_netstats (struct mansession *s, const struct message *m) |
static int | manager_iax2_show_peer_list (struct mansession *s, const struct message *m) |
callback to display iax peers in manager format | |
static int | manager_iax2_show_peers (struct mansession *s, const struct message *m) |
callback to display iax peers in manager | |
static int | manager_iax2_show_registry (struct mansession *s, const struct message *m) |
static int | match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno) |
static void | memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx) |
static void | memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx) |
static void | merge_encryption (struct chan_iax2_pvt *p, unsigned int enc) |
static void | mwi_event_cb (const struct ast_event *event, void *userdata) |
static void | network_change_event_cb (const struct ast_event *, void *) |
static int | network_change_event_sched_cb (const void *data) |
static void | network_change_event_subscribe (void) |
static void | network_change_event_unsubscribe (void) |
static void * | network_thread (void *ignore) |
static struct chan_iax2_pvt * | new_iax (struct sockaddr_in *sin, const char *host) |
static void | parse_dial_string (char *data, struct parsed_dial_string *pds) |
Parses an IAX dial string into its component parts. | |
static int | peer_cmp_cb (void *obj, void *arg, int flags) |
static int | peer_delme_cb (void *obj, void *arg, int flags) |
static void | peer_destructor (void *obj) |
static int | peer_hash_cb (const void *obj, const int flags) |
static struct iax2_peer * | peer_ref (struct iax2_peer *peer) |
static int | peer_set_sock_cb (void *obj, void *arg, int flags) |
static int | peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr) |
Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found. | |
static int | peer_status (struct iax2_peer *peer, char *status, int statuslen) |
peer_status: Report Peer status in character string | |
static struct iax2_peer * | peer_unref (struct iax2_peer *peer) |
static int | peercnt_add (struct sockaddr_in *sin) |
static int | peercnt_cmp_cb (void *obj, void *arg, int flags) |
static int | peercnt_hash_cb (const void *obj, const int flags) |
static void | peercnt_modify (unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr) |
static void | peercnt_remove (struct peercnt *peercnt) |
static int | peercnt_remove_by_addr (struct sockaddr_in *sin) |
static int | peercnt_remove_cb (const void *obj) |
static int | peers_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
static void | poke_all_peers (void) |
static int | prune_addr_range_cb (void *obj, void *arg, int flags) |
static void | prune_peers (void) |
static void | prune_users (void) |
static int | pvt_cmp_cb (void *obj, void *arg, int flags) |
static void | pvt_destructor (void *obj) |
static int | pvt_hash_cb (const void *obj, const int flags) |
static int | queue_signalling (struct chan_iax2_pvt *pvt, struct ast_frame *f) |
All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number. | |
static int | raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd) |
static struct iax2_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
static void | realtime_update_peer (const char *peername, struct ast_sockaddr *sockaddr, time_t regtime) |
static struct iax2_user * | realtime_user (const char *username, struct sockaddr_in *sin) |
static void | reg_source_db (struct iax2_peer *p) |
static void | register_peer_exten (struct iax2_peer *peer, int onoff) |
static int | register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
Verify inbound registration. | |
static int | registry_authrequest (int callno) |
static int | registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin) |
static char * | regstate2str (int regstate) |
static int | reload (void) |
static int | reload_config (void) |
static void | reload_firmware (int unload) |
static void | remove_by_peercallno (struct chan_iax2_pvt *pvt) |
static void | remove_by_transfercallno (struct chan_iax2_pvt *pvt) |
static int | replace_callno (const void *obj) |
static void | requirecalltoken_mark_auto (const char *name, int subclass) |
static void | resend_with_token (int callno, struct iax_frame *f, const char *newtoken) |
static void | save_osptoken (struct iax_frame *fr, struct iax_ies *ies) |
static void | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
static void | sched_delay_remove (struct sockaddr_in *sin, struct callno_entry *callno_entry) |
static int | schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout) |
static int | scheduled_destroy (const void *vid) |
static int | send_apathetic_reply (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno, int sockfd, struct iax_ie_data *ied) |
static int | send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int) |
static int | send_lagrq (const void *data) |
static int | send_packet (struct iax_frame *f) |
static int | send_ping (const void *data) |
static void | send_signaling (struct chan_iax2_pvt *pvt) |
This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point. | |
static int | send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | set_config (const char *config_file, int reload) |
Load configuration. | |
static void | set_config_destroy (void) |
static void | set_hangup_source_and_cause (int callno, unsigned char causecode) |
static void | set_peercnt_limit (struct peercnt *peercnt) |
static int | set_peercnt_limit_all_cb (void *obj, void *arg, int flags) |
static void | signal_condition (ast_mutex_t *lock, ast_cond_t *cond) |
static int | socket_process (struct iax2_thread *thread) |
static int | socket_process_meta (int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd, struct iax_frame *fr) |
static int | socket_read (int *id, int fd, short events, void *cbdata) |
static void | spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid) |
static int | start_network_thread (void) |
static void | stop_stuff (int callno) |
static void | store_by_peercallno (struct chan_iax2_pvt *pvt) |
static void | store_by_transfercallno (struct chan_iax2_pvt *pvt) |
static int | timing_read (int *id, int fd, short events, void *cbdata) |
static int | transfercallno_pvt_cmp_cb (void *obj, void *arg, int flags) |
static int | transfercallno_pvt_hash_cb (const void *obj, const int flags) |
static int | transmit_frame (void *data) |
static int | transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd) |
static int | try_firmware (char *s) |
static int | try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static format_t | uncompress_subclass (unsigned char csub) |
static void | unlink_peer (struct iax2_peer *peer) |
static int | unload_module (void) |
static void | unlock_both (unsigned short callno0, unsigned short callno1) |
static void | unwrap_timestamp (struct iax_frame *fr) |
static void | update_jbsched (struct chan_iax2_pvt *pvt) |
static int | update_packet (struct iax_frame *f) |
static int | update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh) |
static int | user_cmp_cb (void *obj, void *arg, int flags) |
static int | user_delme_cb (void *obj, void *arg, int flags) |
static void | user_destructor (void *obj) |
static int | user_hash_cb (const void *obj, const int flags) |
static struct iax2_user * | user_ref (struct iax2_user *user) |
static struct iax2_user * | user_unref (struct iax2_user *user) |
static int | users_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
static void | vnak_retransmit (int callno, int last) |
static int | wait_for_peercallno (struct chan_iax2_pvt *pvt) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto", } |
static char | accountcode [AST_MAX_ACCOUNT_CODE] |
static int | adsi = 0 |
static int | amaflags = 0 |
static struct ast_module_info * | ast_module_info = &__mod_info |
static int | authdebug = 1 |
static int | autokill = 0 |
static struct ao2_container * | callno_limits |
static struct ao2_container * | callno_pool |
static const unsigned int | CALLNO_POOL_BUCKETS = 2699 |
static struct ao2_container * | callno_pool_trunk |
static struct ao2_container * | calltoken_ignores |
static struct ast_cli_entry | cli_iax2 [] |
static struct sockaddr_in | debugaddr |
static uint16_t | DEFAULT_MAXCALLNO_LIMIT = 2048 |
static uint16_t | DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 |
static char | default_parkinglot [AST_MAX_CONTEXT] |
static int | defaultsockfd = -1 |
static int | delayreject = 0 |
struct { | |
iax_frame * first | |
iax_frame * last | |
} | frame_queue [IAX_MAX_CALLS+1] |
a list of frames that may need to be retransmitted | |
static int | global_max_trunk_mtu |
static uint16_t | global_maxcallno |
static uint16_t | global_maxcallno_nonval |
static int | global_rtautoclear = 120 |
static struct ast_flags64 | globalflags = { 0 } |
static format_t | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH |
static struct ast_data_entry | iax2_data_providers [] |
static int | iax2_encryption = 0 |
static int(*) | iax2_regfunk (const char *username, int onoff) = NULL |
static struct ast_switch | iax2_switch |
static struct ast_channel_tech | iax2_tech |
static struct ast_datastore_info | iax2_variable_datastore_info |
static struct ao2_container * | iax_peercallno_pvts |
Another container of iax2_pvt structures. | |
static struct ao2_container * | iax_transfercallno_pvts |
Another container of iax2_pvt structures. | |
static int | iaxactivethreadcount = 0 |
static int | iaxcompat = 0 |
static int | iaxdebug = 0 |
static int | iaxdefaultdpcache = 10 * 60 |
static int | iaxdefaulttimeout = 5 |
static int | iaxdynamicthreadcount = 0 |
static int | iaxdynamicthreadnum = 0 |
static int | iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT |
static struct ast_custom_function | iaxpeer_function |
static struct chan_iax2_pvt * | iaxs [IAX_MAX_CALLS+1] |
an array of iax2 pvt structures | |
static ast_mutex_t | iaxsl [ARRAY_LEN(iaxs)] |
chan_iax2_pvt structure locks | |
static int | iaxthreadcount = DEFAULT_THREAD_COUNT |
static int | iaxtrunkdebug = 0 |
static struct ast_custom_function | iaxvar_function |
static struct io_context * | io |
static int | jittertargetextra = 40 |
static int | lagrq_time = 10 |
static char | language [MAX_LANGUAGE] = "" |
static int | last_authmethod = 0 |
static const time_t | MAX_CALLTOKEN_DELAY = 10 |
static int | max_reg_expire |
static int | max_retries = 4 |
static int | maxauthreq = 3 |
static int | maxjitterbuffer = 1000 |
static int | maxjitterinterps = 10 |
static int | min_reg_expire |
static char | mohinterpret [MAX_MUSICCLASS] |
static char | mohsuggest [MAX_MUSICCLASS] |
static struct ast_netsock_list * | netsock |
static pthread_t | netthreadid = AST_PTHREADT_NULL |
static int | network_change_event_sched_id = -1 |
static struct ast_event_sub * | network_change_event_subscription |
static struct ast_netsock_list * | outsock |
static char * | papp = "IAX2Provision" |
static struct ao2_container * | peercnts |
static struct ao2_container * | peers |
static struct ast_data_handler | peers_data_provider |
static int | ping_time = 21 |
static struct ast_codec_pref | prefs |
struct { | |
unsigned int cos | |
unsigned int tos | |
} | qos |
static int | randomcalltokendata |
static char | regcontext [AST_MAX_CONTEXT] = "" |
static int | resyncthreshold = 1000 |
static struct ast_sched_thread * | sched |
static int | srvlookup = 0 |
static const char | tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)" |
static int | test_losspct = 0 |
static struct ast_timer * | timer |
static uint16_t | total_nonval_callno_used = 0 |
static struct ast_taskprocessor * | transmit_processor |
static int | trunk_maxmtu |
static int | trunk_nmaxmtu |
static int | trunk_timed |
static int | trunk_untimed |
static int | trunkfreq = 20 |
static int | trunkmaxsize = MAX_TRUNKDATA |
static struct ao2_container * | users |
static struct ast_data_handler | users_data_provider |
Definition in file chan_iax2.c.
#define ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" |
Referenced by ast_cli_netstats().
#define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" |
Referenced by ast_cli_netstats().
#define CALLNO_TO_PTR | ( | a | ) | ((void *)(unsigned long)(a)) |
Definition at line 243 of file chan_iax2.c.
Referenced by ast_iax2_new(), iax2_call(), iax2_hangup(), and update_jbsched().
#define CALLTOKEN_HASH_FORMAT "%s%d%u%d" |
Referenced by handle_call_token().
#define CALLTOKEN_IE_FORMAT "%u?%s" |
Referenced by handle_call_token().
#define DATA_EXPORT_IAX2_PEER | ( | MEMBER | ) |
Definition at line 14542 of file chan_iax2.c.
#define DATA_EXPORT_IAX2_USER | ( | MEMBER | ) |
Definition at line 14619 of file chan_iax2.c.
#define DEBUG_SCHED_MULTITHREAD |
Definition at line 235 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 251 of file chan_iax2.c.
#define DEFAULT_CONTEXT "default" |
Definition at line 270 of file chan_iax2.c.
Referenced by check_access(), handle_cli_iax2_show_users(), reload_config(), and users_data_provider_get().
#define DEFAULT_DROP 3 |
Definition at line 249 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 345 of file chan_iax2.c.
Referenced by build_peer(), handle_response_peerpoke(), and sip_poke_noanswer().
#define DEFAULT_FREQ_OK 60 * 1000 |
#define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 246 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 343 of file chan_iax2.c.
Referenced by build_peer(), iax2_poke_peer(), and set_config().
#define DEFAULT_RETRY_TIME 1000 |
#define DEFAULT_THREAD_COUNT 10 |
Definition at line 245 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 624 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
#define DONT_RESCHEDULE -2 |
Definition at line 367 of file chan_iax2.c.
Referenced by __send_lagrq(), __send_ping(), iax2_destroy_helper(), send_lagrq(), and send_ping().
#define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n" |
#define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n" |
#define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" |
#define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n" |
#define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define GAMMA (0.01) |
Definition at line 256 of file chan_iax2.c.
#define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define IAX_ALLOWFWDOWNLOAD (uint64_t)(1 << 26) |
Allow the FWDOWNL command?
Definition at line 433 of file chan_iax2.c.
Referenced by set_config(), and socket_process().
#define IAX_ALREADYGONE (uint64_t)(1 << 9) |
Already disconnected
Definition at line 416 of file chan_iax2.c.
Referenced by __do_deliver(), __get_from_jb(), iax2_hangup(), iax2_predestroy(), iax2_write(), pvt_destructor(), and socket_process().
#define IAX_CALLENCRYPTED | ( | pvt | ) | (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED)) |
Definition at line 348 of file chan_iax2.c.
Referenced by acf_channel_read(), iax2_send(), iax2_start_transfer(), and socket_process().
#define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
Definition at line 322 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), and set_config().
#define IAX_CAPABILITY_LOWBANDWIDTH |
Value:
(IAX_CAPABILITY_MEDBANDWIDTH & \ ~AST_FORMAT_G726 & \ ~AST_FORMAT_G726_AAL2 & \ ~AST_FORMAT_ADPCM)
Definition at line 334 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 339 of file chan_iax2.c.
#define IAX_CAPABILITY_MEDBANDWIDTH |
#define IAX_CODEC_NOCAP (uint64_t)(1 << 16) |
only consider requested format and ignore capabilities
Definition at line 423 of file chan_iax2.c.
Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), socket_process(), and users_data_provider_get().
#define IAX_CODEC_NOPREFS (uint64_t)(1 << 15) |
Force old behaviour by turning off prefs
Definition at line 422 of file chan_iax2.c.
Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), socket_process(), and users_data_provider_get().
#define IAX_CODEC_USER_FIRST (uint64_t)(1 << 14) |
are we willing to let the other guy choose the codec?
Definition at line 421 of file chan_iax2.c.
Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), socket_process(), and users_data_provider_get().
#define IAX_DEBUGDIGEST | ( | msg, | |||
key | ) |
#define IAX_DELAYPBXSTART (uint64_t)(1 << 25) |
Don't start a PBX on the channel until the peer sends us a response, so that we've achieved a three-way handshake with them before sending voice or anything else
Definition at line 432 of file chan_iax2.c.
Referenced by socket_process().
#define IAX_DELME (uint64_t)(1 << 1) |
Needs to be deleted
Definition at line 408 of file chan_iax2.c.
Referenced by build_peer(), build_user(), peer_delme_cb(), prune_peers(), prune_users(), and user_delme_cb().
#define IAX_DYNAMIC (uint64_t)(1 << 6) |
dynamic peer
Definition at line 413 of file chan_iax2.c.
Referenced by __iax2_show_peers(), build_peer(), function_iaxpeer(), handle_cli_iax2_show_peer(), manager_iax2_show_peer_list(), peers_data_provider_get(), register_verify(), and set_config().
#define IAX_ENCRYPTED (uint64_t)(1 << 12) |
Whether we should assume encrypted tx/rx
Definition at line 419 of file chan_iax2.c.
Referenced by authenticate_reply(), authenticate_request(), iax2_send(), and socket_process().
#define IAX_FORCE_ENCRYPT (uint64_t)(1 << 30) |
Forces call encryption, if encryption not possible hangup
Definition at line 437 of file chan_iax2.c.
Referenced by __find_callno(), authenticate_reply(), authenticate_verify(), build_peer(), build_user(), check_access(), create_addr(), iax2_call(), iax2_queryoption(), iax2_setoption(), set_config(), and socket_process().
#define IAX_FORCEJITTERBUF (uint64_t)(1 << 20) |
Force jitterbuffer, even when bridged to a channel that can take jitter
Definition at line 427 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_request(), schedule_delivery(), set_config(), and set_config_destroy().
#define IAX_HASCALLERID (uint64_t)(1 << 0) |
CallerID has been specified
Definition at line 407 of file chan_iax2.c.
Referenced by build_peer(), build_user(), check_access(), and update_registry().
#define IAX_IMMEDIATE (uint64_t)(1 << 27) |
Allow immediate off-hook to extension s
Definition at line 434 of file chan_iax2.c.
Referenced by build_user(), check_access(), and socket_process().
#define IAX_KEYPOPULATED (uint64_t)(1 << 13) |
Whether we have a key populated
Definition at line 420 of file chan_iax2.c.
Referenced by authenticate_reply(), decrypt_frame(), and iax2_send().
#define IAX_MAXAUTHREQ (uint64_t)(1 << 24) |
Maximum outstanding AUTHREQ restriction is in place
Definition at line 431 of file chan_iax2.c.
Referenced by authenticate_request(), authenticate_verify(), check_access(), and iax2_destroy_helper().
#define IAX_NOTRANSFER (uint64_t)(1 << 4) |
Don't native bridge
Definition at line 411 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_request(), iax2_start_transfer(), set_config(), and set_config_destroy().
#define IAX_PROVISION (uint64_t)(1 << 10) |
This is a provisioning request
Definition at line 417 of file chan_iax2.c.
Referenced by iax2_provision(), and socket_process().
#define IAX_QUELCH (uint64_t)(1 << 11) |
Whether or not we quelch audio
Definition at line 418 of file chan_iax2.c.
Referenced by iax2_write(), and socket_process().
#define IAX_RECVCONNECTEDLINE (uint64_t)(1 << 29) |
Allow receiving of connected line updates
Definition at line 436 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_request(), set_config(), set_config_destroy(), and socket_process().
#define IAX_RTAUTOCLEAR (uint64_t)(1 << 19) |
erase me on expire
Definition at line 426 of file chan_iax2.c.
Referenced by __expire_registry(), handle_cli_iax2_prune_realtime(), and set_config().
#define IAX_RTCACHEFRIENDS (uint64_t)(1 << 17) |
let realtime stay till your reload
Definition at line 424 of file chan_iax2.c.
Referenced by __expire_registry(), handle_cli_iax2_prune_realtime(), prune_peers(), prune_users(), set_config(), and update_registry().
#define IAX_RTIGNOREREGEXPIRE (uint64_t)(1 << 21) |
When using realtime, ignore registration expiration
Definition at line 428 of file chan_iax2.c.
Referenced by set_config().
#define IAX_RTSAVE_SYSNAME (uint64_t)(1 << 8) |
Save Systname on Realtime Updates
Definition at line 415 of file chan_iax2.c.
Referenced by realtime_update_peer(), and set_config().
#define IAX_RTUPDATE (uint64_t)(1 << 18) |
Send a realtime update
Definition at line 425 of file chan_iax2.c.
Referenced by __expire_registry(), set_config(), and update_registry().
#define IAX_SENDANI (uint64_t)(1 << 7) |
Send ANI along with CallerID
Definition at line 414 of file chan_iax2.c.
Referenced by build_peer(), create_addr(), iax2_call(), and iax2_request().
#define IAX_SENDCONNECTEDLINE (uint64_t)(1 << 28) |
Allow sending of connected line updates
Definition at line 435 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_indicate(), iax2_request(), set_config(), and set_config_destroy().
#define IAX_SHRINKCALLERID (uint64_t)(1 << 31) |
Turn on and off caller id shrinking
Definition at line 438 of file chan_iax2.c.
Referenced by check_access(), and set_config().
#define IAX_TEMPONLY (uint64_t)(1 << 2) |
Temporary (realtime)
Definition at line 409 of file chan_iax2.c.
Referenced by __expire_registry(), reg_source_db(), and update_registry().
#define IAX_TRANSFERMEDIA (uint64_t)(1 << 23) |
When doing IAX2 transfers, transfer media only
Definition at line 430 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_request(), set_config(), and set_config_destroy().
#define IAX_TRUNK (uint64_t)(1 << 3) |
Treat as a trunk
Definition at line 410 of file chan_iax2.c.
Referenced by __iax2_show_peers(), build_peer(), build_user(), check_access(), create_addr(), handle_cli_iax2_show_peer(), iax2_getpeertrunk(), iax2_request(), iax2_send(), manager_iax2_show_peer_list(), peers_data_provider_get(), and socket_process().
#define IAX_TRUNKTIMESTAMPS (uint64_t)(1 << 22) |
Send trunk timestamps
Definition at line 429 of file chan_iax2.c.
Referenced by iax2_trunk_queue(), send_trunk(), and set_config().
#define IAX_USEJITTERBUF (uint64_t)(1 << 5) |
Use jitter buffer
Definition at line 412 of file chan_iax2.c.
Referenced by __find_callno(), ast_cli_netstats(), build_peer(), build_user(), check_access(), create_addr(), handle_cli_iax2_show_channels(), iax2_request(), log_jitterstats(), schedule_delivery(), set_config(), and set_config_destroy().
#define MARK_IAX_SUBCLASS_TX 0x8000 |
Definition at line 632 of file chan_iax2.c.
Referenced by ast_cli_netstats(), handle_cli_iax2_show_channels(), and iax2_send().
#define MAX_JITTER_BUFFER 50 |
Definition at line 621 of file chan_iax2.c.
#define MAX_PEER_BUCKETS 563 |
This module will get much higher performance when doing a lot of user and peer lookups if the number of buckets is increased from 1. However, to maintain old behavior for Asterisk 1.4, these are set to 1 by default. When using multiple buckets, search order through these containers is considered random, so you will not be able to depend on the order the entires are specified in iax.conf for matching order.
Definition at line 883 of file chan_iax2.c.
Referenced by load_objects().
#define MAX_RETRY_TIME 10000 |
#define MAX_TIMESTAMP_SKEW 160 |
maximum difference between actual and predicted ts for sending
Definition at line 626 of file chan_iax2.c.
Referenced by ast_rtp_raw_write(), calc_timestamp(), and calc_txpeerstamp().
#define MAX_TRUNK_MTU 1240 |
Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240.
Definition at line 265 of file chan_iax2.c.
Referenced by handle_cli_iax2_set_mtu(), and set_config().
#define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 289 of file chan_iax2.c.
Referenced by set_config(), and set_config_destroy().
#define MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define MEMORY_SIZE 100 |
Definition at line 248 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 622 of file chan_iax2.c.
#define MIN_RETRY_TIME 100 |
#define MIN_REUSE_TIME 60 |
#define PTR_TO_CALLNO | ( | a | ) | ((unsigned short)(unsigned long)(a)) |
Definition at line 242 of file chan_iax2.c.
Referenced by __auto_congest(), __get_from_jb(), acf_channel_read(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit_begin(), iax2_digit_end(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_queryoption(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), iax2_write(), and scheduled_destroy().
#define SCHED_MULTITHREADED |
Definition at line 231 of file chan_iax2.c.
#define schedule_action | ( | func, | |||
data | ) | __schedule_action(func, data, __PRETTY_FUNCTION__) |
Definition at line 1486 of file chan_iax2.c.
Referenced by attempt_transmit(), auth_reject(), auto_congest(), auto_hangup(), expire_registry(), get_from_jb(), iax2_do_register_s(), iax2_poke_noanswer(), iax2_poke_peer_s(), send_lagrq(), and send_ping().
#define TRUNK_CALL_START IAX_MAX_CALLS / 2 |
Definition at line 1098 of file chan_iax2.c.
#define TS_GAP_FOR_JB_RESYNC 5000 |
Definition at line 629 of file chan_iax2.c.
#define update_max_nontrunk | ( | ) | do { } while (0) |
#define update_max_trunk | ( | ) | do { } while (0) |
anonymous enum |
Definition at line 943 of file chan_iax2.c.
00943 { 00944 /*! Extension exists */ 00945 CACHE_FLAG_EXISTS = (1 << 0), 00946 /*! Extension is nonexistent */ 00947 CACHE_FLAG_NONEXISTENT = (1 << 1), 00948 /*! Extension can exist */ 00949 CACHE_FLAG_CANEXIST = (1 << 2), 00950 /*! Waiting to hear back response */ 00951 CACHE_FLAG_PENDING = (1 << 3), 00952 /*! Timed out */ 00953 CACHE_FLAG_TIMEOUT = (1 << 4), 00954 /*! Request transmitted */ 00955 CACHE_FLAG_TRANSMITTED = (1 << 5), 00956 /*! Timeout */ 00957 CACHE_FLAG_UNKNOWN = (1 << 6), 00958 /*! Matchmore */ 00959 CACHE_FLAG_MATCHMORE = (1 << 7), 00960 };
anonymous enum |
Definition at line 1974 of file chan_iax2.c.
01974 { 01975 /* do not allow a new call number, only search ones in use for match */ 01976 NEW_PREVENT = 0, 01977 /* search for match first, then allow a new one to be allocated */ 01978 NEW_ALLOW = 1, 01979 /* do not search for match, force a new call number */ 01980 NEW_FORCE = 2, 01981 /* do not search for match, force a new call number. Signifies call number 01982 * has been calltoken validated */ 01983 NEW_ALLOW_CALLTOKEN_VALIDATED = 3, 01984 };
enum calltoken_peer_enum |
Call token validation settings.
Definition at line 446 of file chan_iax2.c.
00446 { 00447 /*! \brief Default calltoken required unless the ip is in the ignorelist */ 00448 CALLTOKEN_DEFAULT = 0, 00449 /*! \brief Require call token validation. */ 00450 CALLTOKEN_YES = 1, 00451 /*! \brief Require call token validation after a successful registration 00452 * using call token validation occurs. */ 00453 CALLTOKEN_AUTO = 2, 00454 /*! \brief Do not require call token validation. */ 00455 CALLTOKEN_NO = 3, 00456 };
enum iax2_state |
Definition at line 395 of file chan_iax2.c.
00395 { 00396 IAX_STATE_STARTED = (1 << 0), 00397 IAX_STATE_AUTHENTICATED = (1 << 1), 00398 IAX_STATE_TBD = (1 << 2), 00399 };
enum iax2_thread_iostate |
Definition at line 984 of file chan_iax2.c.
00984 { 00985 IAX_IOSTATE_IDLE, 00986 IAX_IOSTATE_READY, 00987 IAX_IOSTATE_PROCESSING, 00988 IAX_IOSTATE_SCHEDREADY, 00989 };
enum iax2_thread_type |
Definition at line 991 of file chan_iax2.c.
00991 { 00992 IAX_THREAD_TYPE_POOL, 00993 IAX_THREAD_TYPE_DYNAMIC, 00994 };
enum iax_reg_state |
REG_STATE_UNREGISTERED | |
REG_STATE_REGSENT | |
REG_STATE_AUTHSENT | |
REG_STATE_REGISTERED | |
REG_STATE_REJECTED | |
REG_STATE_TIMEOUT | |
REG_STATE_NOAUTH |
Definition at line 577 of file chan_iax2.c.
00577 { 00578 REG_STATE_UNREGISTERED = 0, 00579 REG_STATE_REGSENT, 00580 REG_STATE_AUTHSENT, 00581 REG_STATE_REGISTERED, 00582 REG_STATE_REJECTED, 00583 REG_STATE_TIMEOUT, 00584 REG_STATE_NOAUTH 00585 };
enum iax_transfer_state |
TRANSFER_NONE | |
TRANSFER_BEGIN | |
TRANSFER_READY | |
TRANSFER_RELEASED | |
TRANSFER_PASSTHROUGH | |
TRANSFER_MBEGIN | |
TRANSFER_MREADY | |
TRANSFER_MRELEASED | |
TRANSFER_MPASSTHROUGH | |
TRANSFER_MEDIA | |
TRANSFER_MEDIAPASS |
Definition at line 587 of file chan_iax2.c.
00587 { 00588 TRANSFER_NONE = 0, 00589 TRANSFER_BEGIN, 00590 TRANSFER_READY, 00591 TRANSFER_RELEASED, 00592 TRANSFER_PASSTHROUGH, 00593 TRANSFER_MBEGIN, 00594 TRANSFER_MREADY, 00595 TRANSFER_MRELEASED, 00596 TRANSFER_MPASSTHROUGH, 00597 TRANSFER_MEDIA, 00598 TRANSFER_MEDIAPASS 00599 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3490 of file chan_iax2.c.
References AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_REMOVE, ast_log(), ast_mutex_lock, ast_mutex_unlock, attempt_transmit(), iax_frame::callno, chan_iax2_pvt::error, f, frame_queue, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxs, iaxsl, iax2_trunk_peer::list, LOG_WARNING, MAX_RETRY_TIME, ast_format::name, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), send_packet(), update_packet(), and iax2_registry::us.
Referenced by attempt_transmit().
03491 { 03492 /* Attempt to transmit the frame to the remote peer... 03493 Called without iaxsl held. */ 03494 struct iax_frame *f = (struct iax_frame *)data; 03495 int freeme = 0; 03496 int callno = f->callno; 03497 /* Make sure this call is still active */ 03498 if (callno) 03499 ast_mutex_lock(&iaxsl[callno]); 03500 if (callno && iaxs[callno]) { 03501 if ((f->retries < 0) /* Already ACK'd */ || 03502 (f->retries >= max_retries) /* Too many attempts */) { 03503 /* Record an error if we've transmitted too many times */ 03504 if (f->retries >= max_retries) { 03505 if (f->transfer) { 03506 /* Transfer timeout */ 03507 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 03508 } else if (f->final) { 03509 iax2_destroy(callno); 03510 } else { 03511 if (iaxs[callno]->owner) 03512 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %u, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass.integer, f->ts, f->oseqno); 03513 iaxs[callno]->error = ETIMEDOUT; 03514 if (iaxs[callno]->owner) { 03515 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER }; 03516 /* Hangup the fd */ 03517 iax2_queue_frame(callno, &fr); /* XXX */ 03518 /* Remember, owner could disappear */ 03519 if (iaxs[callno] && iaxs[callno]->owner) 03520 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03521 } else { 03522 if (iaxs[callno]->reg) { 03523 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 03524 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 03525 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 03526 } 03527 iax2_destroy(callno); 03528 } 03529 } 03530 03531 } 03532 freeme = 1; 03533 } else { 03534 /* Update it if it needs it */ 03535 update_packet(f); 03536 /* Attempt transmission */ 03537 send_packet(f); 03538 f->retries++; 03539 /* Try again later after 10 times as long */ 03540 f->retrytime *= 10; 03541 if (f->retrytime > MAX_RETRY_TIME) 03542 f->retrytime = MAX_RETRY_TIME; 03543 /* Transfer messages max out at one second */ 03544 if (f->transfer && (f->retrytime > 1000)) 03545 f->retrytime = 1000; 03546 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 03547 } 03548 } else { 03549 /* Make sure it gets freed */ 03550 f->retries = -1; 03551 freeme = 1; 03552 } 03553 03554 if (freeme) { 03555 /* Don't attempt delivery, just remove it from the queue */ 03556 AST_LIST_REMOVE(&frame_queue[callno], f, list); 03557 ast_mutex_unlock(&iaxsl[callno]); 03558 f->retrans = -1; /* this is safe because this is the scheduled function */ 03559 /* Free the IAX frame */ 03560 iax2_frame_free(f); 03561 } else if (callno) { 03562 ast_mutex_unlock(&iaxsl[callno]); 03563 } 03564 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 8993 of file chan_iax2.c.
References AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_FACILITY_REJECTED, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, IAX_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, and send_command_final().
Referenced by auth_reject().
08994 { 08995 /* Called from IAX thread only, without iaxs lock */ 08996 int callno = (int)(long)(nothing); 08997 struct iax_ie_data ied; 08998 ast_mutex_lock(&iaxsl[callno]); 08999 if (iaxs[callno]) { 09000 memset(&ied, 0, sizeof(ied)); 09001 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 09002 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 09003 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 09004 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 09005 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 09006 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 09007 } 09008 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 09009 } 09010 ast_mutex_unlock(&iaxsl[callno]); 09011 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 4673 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock, ast_mutex_unlock, f, iax2_queue_frame(), iaxs, iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
04674 { 04675 int callno = PTR_TO_CALLNO(nothing); 04676 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } }; 04677 ast_mutex_lock(&iaxsl[callno]); 04678 if (iaxs[callno]) { 04679 iaxs[callno]->initid = -1; 04680 iax2_queue_frame(callno, &f); 04681 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 04682 } 04683 ast_mutex_unlock(&iaxsl[callno]); 04684 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 9042 of file chan_iax2.c.
References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, and send_command_final().
Referenced by auto_hangup().
09043 { 09044 /* Called from IAX thread only, without iaxs lock */ 09045 int callno = (int)(long)(nothing); 09046 struct iax_ie_data ied; 09047 ast_mutex_lock(&iaxsl[callno]); 09048 if (iaxs[callno]) { 09049 memset(&ied, 0, sizeof(ied)); 09050 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 09051 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 09052 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 09053 } 09054 ast_mutex_unlock(&iaxsl[callno]); 09055 }
static int __do_deliver | ( | void * | data | ) | [static] |
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it. This function calls iax2_queue_frame(), which may unlock and lock the mutex associated with this callno, meaning that another thread may grab it and destroy the call.
Definition at line 3276 of file chan_iax2.c.
References iax_frame::af, ast_clear_flag, AST_FRFLAG_HAS_TIMING_INFO, ast_test_flag64, iax_frame::callno, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, and iax_frame::retrans.
Referenced by __get_from_jb(), and schedule_delivery().
03277 { 03278 /* Just deliver the packet by using queueing. This is called by 03279 the IAX thread with the iaxsl lock held. */ 03280 struct iax_frame *fr = data; 03281 fr->retrans = -1; 03282 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 03283 if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE)) 03284 iax2_queue_frame(fr->callno, &fr->af); 03285 /* Free our iax frame */ 03286 iax2_frame_free(fr); 03287 /* And don't run again */ 03288 return 0; 03289 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8619 of file chan_iax2.c.
References iax2_peer::addr, ast_db_del(), ast_debug, AST_DEVICE_UNAVAILABLE, ast_devstate_changed(), ast_test_flag64, EVENT_FLAG_SYSTEM, iax2_peer::expire, iax2_peer::expiry, globalflags, iax2_regfunk, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, manager_event, iax2_peer::name, peer_unref(), peercnt_modify(), realtime_update_peer(), register_peer_exten(), and unlink_peer().
Referenced by expire_registry().
08620 { 08621 struct iax2_peer *peer = (struct iax2_peer *) data; 08622 08623 if (!peer) 08624 return; 08625 if (peer->expire == -1) { 08626 /* Removed already (possibly through CLI), ignore */ 08627 return; 08628 } 08629 08630 peer->expire = -1; 08631 08632 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name); 08633 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 08634 realtime_update_peer(peer->name, &peer->addr, 0); 08635 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08636 /* modify entry in peercnts table as _not_ registered */ 08637 peercnt_modify(0, 0, &peer->addr); 08638 /* Reset the address */ 08639 memset(&peer->addr, 0, sizeof(peer->addr)); 08640 /* Reset expiry value */ 08641 peer->expiry = min_reg_expire; 08642 if (!ast_test_flag64(peer, IAX_TEMPONLY)) 08643 ast_db_del("IAX/Registry", peer->name); 08644 register_peer_exten(peer, 0); 08645 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 08646 if (iax2_regfunk) 08647 iax2_regfunk(peer->name, 0); 08648 08649 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) 08650 unlink_peer(peer); 08651 08652 peer_unref(peer); 08653 }
static int __find_callno | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | return_locked, | |||
int | check_dcallno | |||
) | [static] |
Definition at line 2779 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::amaflags, ao2_find, ao2_ref, ast_copy_flags64, ast_debug, ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_string_field_set, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, get_unused_callno(), globalflags, iax2_getpeername(), iax2_sched_add(), IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, iax_peercallno_pvts, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, iax_transfercallno_pvts, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, iaxs, iaxsl, chan_iax2_pvt::lagid, LOG_WARNING, match(), NEW_ALLOW, new_iax(), OBJ_POINTER, parkinglot, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, replace_callno(), sched, send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, store_by_peercallno(), chan_iax2_pvt::transfer, and update_max_nontrunk.
Referenced by find_callno(), and find_callno_locked().
02780 { 02781 int res = 0; 02782 int x; 02783 /* this call is calltoken validated as long as it is either NEW_FORCE 02784 * or NEW_ALLOW_CALLTOKEN_VALIDATED */ 02785 int validated = (new > NEW_ALLOW) ? 1 : 0; 02786 char host[80]; 02787 02788 if (new <= NEW_ALLOW) { 02789 if (callno) { 02790 struct chan_iax2_pvt *pvt; 02791 struct chan_iax2_pvt tmp_pvt = { 02792 .callno = dcallno, 02793 .peercallno = callno, 02794 .transfercallno = callno, 02795 /* hack!! */ 02796 .frames_received = check_dcallno, 02797 }; 02798 02799 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 02800 /* this works for finding normal call numbers not involving transfering */ 02801 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02802 if (return_locked) { 02803 ast_mutex_lock(&iaxsl[pvt->callno]); 02804 } 02805 res = pvt->callno; 02806 ao2_ref(pvt, -1); 02807 pvt = NULL; 02808 return res; 02809 } 02810 /* this searches for transfer call numbers that might not get caught otherwise */ 02811 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr)); 02812 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer)); 02813 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02814 if (return_locked) { 02815 ast_mutex_lock(&iaxsl[pvt->callno]); 02816 } 02817 res = pvt->callno; 02818 ao2_ref(pvt, -1); 02819 pvt = NULL; 02820 return res; 02821 } 02822 } 02823 /* This will occur on the first response to a message that we initiated, 02824 * such as a PING. */ 02825 if (dcallno) { 02826 ast_mutex_lock(&iaxsl[dcallno]); 02827 } 02828 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 02829 iaxs[dcallno]->peercallno = callno; 02830 res = dcallno; 02831 store_by_peercallno(iaxs[dcallno]); 02832 if (!res || !return_locked) { 02833 ast_mutex_unlock(&iaxsl[dcallno]); 02834 } 02835 return res; 02836 } 02837 if (dcallno) { 02838 ast_mutex_unlock(&iaxsl[dcallno]); 02839 } 02840 #ifdef IAX_OLD_FIND 02841 /* If we get here, we SHOULD NOT find a call structure for this 02842 callno; if we do, it means that there is a call structure that 02843 has a peer callno but did NOT get entered into the hash table, 02844 which is bad. 02845 02846 If we find a call structure using this old, slow method, output a log 02847 message so we'll know about it. After a few months of leaving this in 02848 place, if we don't hear about people seeing these messages, we can 02849 remove this code for good. 02850 */ 02851 02852 for (x = 1; !res && x < maxnontrunkcall; x++) { 02853 ast_mutex_lock(&iaxsl[x]); 02854 if (iaxs[x]) { 02855 /* Look for an exact match */ 02856 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02857 res = x; 02858 } 02859 } 02860 if (!res || !return_locked) 02861 ast_mutex_unlock(&iaxsl[x]); 02862 } 02863 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 02864 ast_mutex_lock(&iaxsl[x]); 02865 if (iaxs[x]) { 02866 /* Look for an exact match */ 02867 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02868 res = x; 02869 } 02870 } 02871 if (!res || !return_locked) 02872 ast_mutex_unlock(&iaxsl[x]); 02873 } 02874 #endif 02875 } 02876 if (!res && (new >= NEW_ALLOW)) { 02877 struct callno_entry *callno_entry; 02878 /* It may seem odd that we look through the peer list for a name for 02879 * this *incoming* call. Well, it is weird. However, users don't 02880 * have an IP address/port number that we can match against. So, 02881 * this is just checking for a peer that has that IP/port and 02882 * assuming that we have a user of the same name. This isn't always 02883 * correct, but it will be changed if needed after authentication. */ 02884 if (!iax2_getpeername(*sin, host, sizeof(host))) 02885 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 02886 02887 if (peercnt_add(sin)) { 02888 /* This address has hit its callnumber limit. When the limit 02889 * is reached, the connection is not added to the peercnts table.*/ 02890 return 0; 02891 } 02892 02893 if (!(callno_entry = get_unused_callno(0, validated))) { 02894 /* since we ran out of space, remove the peercnt 02895 * entry we added earlier */ 02896 peercnt_remove_by_addr(sin); 02897 ast_log(LOG_WARNING, "No more space\n"); 02898 return 0; 02899 } 02900 x = callno_entry->callno; 02901 ast_mutex_lock(&iaxsl[x]); 02902 02903 iaxs[x] = new_iax(sin, host); 02904 update_max_nontrunk(); 02905 if (iaxs[x]) { 02906 if (iaxdebug) 02907 ast_debug(1, "Creating new call structure %d\n", x); 02908 iaxs[x]->callno_entry = callno_entry; 02909 iaxs[x]->sockfd = sockfd; 02910 iaxs[x]->addr.sin_port = sin->sin_port; 02911 iaxs[x]->addr.sin_family = sin->sin_family; 02912 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 02913 iaxs[x]->peercallno = callno; 02914 iaxs[x]->callno = x; 02915 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 02916 iaxs[x]->expiry = min_reg_expire; 02917 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 02918 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 02919 iaxs[x]->amaflags = amaflags; 02920 ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 02921 ast_string_field_set(iaxs[x], accountcode, accountcode); 02922 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 02923 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 02924 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot); 02925 02926 if (iaxs[x]->peercallno) { 02927 store_by_peercallno(iaxs[x]); 02928 } 02929 } else { 02930 ast_log(LOG_WARNING, "Out of resources\n"); 02931 ast_mutex_unlock(&iaxsl[x]); 02932 replace_callno(callno_entry); 02933 return 0; 02934 } 02935 if (!return_locked) 02936 ast_mutex_unlock(&iaxsl[x]); 02937 res = x; 02938 } 02939 return res; 02940 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 4067 of file chan_iax2.c.
References __do_deliver(), ast_codec_interp_len(), ast_format_rate(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_test_flag64, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_frame_subclass::codec, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, iaxsl, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, jb_frame::ms, iax2_trunk_peer::next, ast_frame::offset, PTR_TO_CALLNO, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat.
Referenced by get_from_jb().
04068 { 04069 int callno = PTR_TO_CALLNO(p); 04070 struct chan_iax2_pvt *pvt = NULL; 04071 struct iax_frame *fr; 04072 jb_frame frame; 04073 int ret; 04074 long ms; 04075 long next; 04076 struct timeval now = ast_tvnow(); 04077 04078 /* Make sure we have a valid private structure before going on */ 04079 ast_mutex_lock(&iaxsl[callno]); 04080 pvt = iaxs[callno]; 04081 if (!pvt) { 04082 /* No go! */ 04083 ast_mutex_unlock(&iaxsl[callno]); 04084 return; 04085 } 04086 04087 pvt->jbid = -1; 04088 04089 /* round up a millisecond since ast_sched_runq does; */ 04090 /* prevents us from spinning while waiting for our now */ 04091 /* to catch up with runq's now */ 04092 now.tv_usec += 1000; 04093 04094 ms = ast_tvdiff_ms(now, pvt->rxcore); 04095 04096 if(ms >= (next = jb_next(pvt->jb))) { 04097 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat)); 04098 switch(ret) { 04099 case JB_OK: 04100 fr = frame.data; 04101 __do_deliver(fr); 04102 /* __do_deliver() can cause the call to disappear */ 04103 pvt = iaxs[callno]; 04104 break; 04105 case JB_INTERP: 04106 { 04107 struct ast_frame af = { 0, }; 04108 04109 /* create an interpolation frame */ 04110 af.frametype = AST_FRAME_VOICE; 04111 af.subclass.codec = pvt->voiceformat; 04112 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000); 04113 af.src = "IAX2 JB interpolation"; 04114 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 04115 af.offset = AST_FRIENDLY_OFFSET; 04116 04117 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 04118 * which we'd need to malloc, and then it would free it. That seems like a drag */ 04119 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) { 04120 iax2_queue_frame(callno, &af); 04121 /* iax2_queue_frame() could cause the call to disappear */ 04122 pvt = iaxs[callno]; 04123 } 04124 } 04125 break; 04126 case JB_DROP: 04127 iax2_frame_free(frame.data); 04128 break; 04129 case JB_NOFRAME: 04130 case JB_EMPTY: 04131 /* do nothing */ 04132 break; 04133 default: 04134 /* shouldn't happen */ 04135 break; 04136 } 04137 } 04138 if (pvt) 04139 update_jbsched(pvt); 04140 ast_mutex_unlock(&iaxsl[callno]); 04141 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8290 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
08291 { 08292 struct iax2_registry *reg = (struct iax2_registry *)data; 08293 reg->expire = -1; 08294 iax2_do_register(reg); 08295 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 11992 of file chan_iax2.c.
References AST_DEVICE_UNAVAILABLE, ast_devstate_changed(), ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_peer::callno, EVENT_FLAG_SYSTEM, iax2_destroy(), iax2_poke_peer_s(), iax2_sched_add(), iaxsl, iax2_peer::lastms, LOG_NOTICE, manager_event, iax2_peer::name, peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, and sched.
Referenced by iax2_poke_noanswer().
11993 { 11994 struct iax2_peer *peer = (struct iax2_peer *)data; 11995 int callno; 11996 11997 if (peer->lastms > -1) { 11998 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 11999 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 12000 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 12001 } 12002 if ((callno = peer->callno) > 0) { 12003 ast_mutex_lock(&iaxsl[callno]); 12004 iax2_destroy(callno); 12005 ast_mutex_unlock(&iaxsl[callno]); 12006 } 12007 peer->callno = 0; 12008 peer->lastms = -1; 12009 /* Try again quickly */ 12010 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 12011 if (peer->pokeexpire == -1) 12012 peer_unref(peer); 12013 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9102 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
09103 { 09104 struct iax2_peer *peer = (struct iax2_peer *)data; 09105 iax2_poke_peer(peer, 0); 09106 peer_unref(peer); 09107 }
static int __iax2_show_peers | ( | int | fd, | |
int * | total, | |||
struct mansession * | s, | |||
const int | argc, | |||
const char *const | argv[] | |||
) | [static] |
Definition at line 6654 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli(), ast_copy_string(), ast_inet_ntoa(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_sockaddr_to_sin, ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag64, astman_append(), iax2_peer::encmethods, encmethods_to_str(), FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, iax2_peer::name, name, peer_status(), peer_unref(), peers, RESULT_SHOWUSAGE, RESULT_SUCCESS, status, and iax2_peer::username.
Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().
06655 { 06656 regex_t regexbuf; 06657 int havepattern = 0; 06658 int total_peers = 0; 06659 int online_peers = 0; 06660 int offline_peers = 0; 06661 int unmonitored_peers = 0; 06662 struct ao2_iterator i; 06663 06664 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n" 06665 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n" 06666 06667 struct iax2_peer *peer = NULL; 06668 char name[256]; 06669 struct ast_str *encmethods = ast_str_alloca(256); 06670 int registeredonly=0; 06671 char idtext[256] = ""; 06672 switch (argc) { 06673 case 6: 06674 if (!strcasecmp(argv[3], "registered")) 06675 registeredonly = 1; 06676 else 06677 return RESULT_SHOWUSAGE; 06678 if (!strcasecmp(argv[4], "like")) { 06679 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 06680 return RESULT_SHOWUSAGE; 06681 havepattern = 1; 06682 } else 06683 return RESULT_SHOWUSAGE; 06684 break; 06685 case 5: 06686 if (!strcasecmp(argv[3], "like")) { 06687 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 06688 return RESULT_SHOWUSAGE; 06689 havepattern = 1; 06690 } else 06691 return RESULT_SHOWUSAGE; 06692 break; 06693 case 4: 06694 if (!strcasecmp(argv[3], "registered")) 06695 registeredonly = 1; 06696 else 06697 return RESULT_SHOWUSAGE; 06698 break; 06699 case 3: 06700 break; 06701 default: 06702 return RESULT_SHOWUSAGE; 06703 } 06704 06705 06706 if (!s) 06707 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status"); 06708 06709 i = ao2_iterator_init(peers, 0); 06710 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) { 06711 char nm[20]; 06712 char status[20]; 06713 int retstatus; 06714 struct sockaddr_in peer_addr; 06715 06716 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 06717 06718 if (registeredonly && !peer_addr.sin_addr.s_addr) { 06719 continue; 06720 } 06721 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) { 06722 continue; 06723 } 06724 06725 if (!ast_strlen_zero(peer->username)) 06726 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 06727 else 06728 ast_copy_string(name, peer->name, sizeof(name)); 06729 06730 encmethods_to_str(peer->encmethods, encmethods); 06731 retstatus = peer_status(peer, status, sizeof(status)); 06732 if (retstatus > 0) 06733 online_peers++; 06734 else if (!retstatus) 06735 offline_peers++; 06736 else 06737 unmonitored_peers++; 06738 06739 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 06740 06741 if (s) { 06742 astman_append(s, 06743 "Event: PeerEntry\r\n%s" 06744 "Channeltype: IAX2\r\n" 06745 "ObjectName: %s\r\n" 06746 "ChanObjectType: peer\r\n" 06747 "IPaddress: %s\r\n" 06748 "IPport: %d\r\n" 06749 "Dynamic: %s\r\n" 06750 "Trunk: %s\r\n" 06751 "Encryption: %s\r\n" 06752 "Status: %s\r\n\r\n", 06753 idtext, 06754 name, 06755 ast_sockaddr_stringify_addr(&peer->addr), 06756 ast_sockaddr_port(&peer->addr), 06757 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no", 06758 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no", 06759 peer->encmethods ? ast_str_buffer(encmethods) : "no", 06760 status); 06761 } else { 06762 ast_cli(fd, FORMAT, name, 06763 ast_sockaddr_stringify_addr(&peer->addr), 06764 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 06765 nm, 06766 ast_sockaddr_port(&peer->addr), 06767 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ", 06768 peer->encmethods ? "(E)" : " ", 06769 status); 06770 } 06771 total_peers++; 06772 } 06773 ao2_iterator_destroy(&i); 06774 06775 if (!s) 06776 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n", 06777 total_peers, online_peers, offline_peers, unmonitored_peers); 06778 06779 if (havepattern) 06780 regfree(®exbuf); 06781 06782 if (total) 06783 *total = total_peers; 06784 06785 return RESULT_SUCCESS; 06786 #undef FORMAT 06787 #undef FORMAT2 06788 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 14844 of file chan_iax2.c.
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 1461 of file chan_iax2.c.
References ast_copy_string(), ast_debug, find_idle_thread(), IAX_IOSTATE_SCHEDREADY, signal_condition(), and thread.
01462 { 01463 struct iax2_thread *thread = NULL; 01464 static time_t lasterror; 01465 static time_t t; 01466 01467 thread = find_idle_thread(); 01468 01469 if (thread != NULL) { 01470 thread->schedfunc = func; 01471 thread->scheddata = data; 01472 thread->iostate = IAX_IOSTATE_SCHEDREADY; 01473 #ifdef DEBUG_SCHED_MULTITHREAD 01474 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 01475 #endif 01476 signal_condition(&thread->lock, &thread->cond); 01477 return 0; 01478 } 01479 time(&t); 01480 if (t != lasterror) 01481 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n"); 01482 lasterror = t; 01483 01484 return -1; 01485 }
static int __send_command | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno, | |||
int | now, | |||
int | transfer, | |||
int | final | |||
) | [static] |
Definition at line 7481 of file chan_iax2.c.
References f, iax2_send(), and queue_signalling().
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
07483 { 07484 struct ast_frame f = { 0, }; 07485 int res = 0; 07486 07487 f.frametype = type; 07488 f.subclass.integer = command; 07489 f.datalen = datalen; 07490 f.src = __FUNCTION__; 07491 f.data.ptr = (void *) data; 07492 07493 if ((res = queue_signalling(i, &f)) <= 0) { 07494 return res; 07495 } 07496 07497 return iax2_send(i, &f, ts, seqno, now, transfer, final); 07498 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1572 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, iax2_thread::callno, DONT_RESCHEDULE, iax2_sched_add(), IAX_COMMAND_LAGRQ, iaxs, iaxsl, chan_iax2_pvt::lagid, sched, send_command(), and send_lagrq().
Referenced by send_lagrq().
01573 { 01574 int callno = (long) data; 01575 01576 ast_mutex_lock(&iaxsl[callno]); 01577 01578 if (iaxs[callno]) { 01579 if (iaxs[callno]->peercallno) { 01580 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01581 if (iaxs[callno]->lagid != DONT_RESCHEDULE) { 01582 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01583 } 01584 } 01585 } else { 01586 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno); 01587 } 01588 01589 ast_mutex_unlock(&iaxsl[callno]); 01590 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1505 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, iax2_thread::callno, DONT_RESCHEDULE, iax2_sched_add(), IAX_COMMAND_PING, iaxs, iaxsl, chan_iax2_pvt::pingid, sched, send_command(), and send_ping().
Referenced by send_ping().
01506 { 01507 int callno = (long) data; 01508 01509 ast_mutex_lock(&iaxsl[callno]); 01510 01511 if (iaxs[callno]) { 01512 if (iaxs[callno]->peercallno) { 01513 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01514 if (iaxs[callno]->pingid != DONT_RESCHEDULE) { 01515 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01516 } 01517 } 01518 } else { 01519 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno); 01520 } 01521 01522 ast_mutex_unlock(&iaxsl[callno]); 01523 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 14347 of file chan_iax2.c.
References ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_context_find(), ast_data_unregister, ast_manager_unregister(), ast_mutex_destroy, ast_netsock_release(), AST_PTHREADT_NULL, ast_sched_thread_destroy(), ast_taskprocessor_unreference(), AST_TEST_UNREGISTER, ast_timer_close(), ast_unload_realtime(), ast_unregister_application(), ast_unregister_switch(), callno_limits, calltoken_ignores, cleanup_thread_list(), cli_iax2, delete_users(), iax2_destroy(), iax2_switch, iax2_tech, iax_peercallno_pvts, iax_provision_unload(), iax_transfercallno_pvts, iaxs, iaxsl, netsock, network_change_event_unsubscribe(), outsock, peercnts, peers, reload_firmware(), sched, timer, and users.
14348 { 14349 struct ast_context *con; 14350 int x; 14351 14352 network_change_event_unsubscribe(); 14353 14354 ast_manager_unregister("IAXpeers"); 14355 ast_manager_unregister("IAXpeerlist"); 14356 ast_manager_unregister("IAXnetstats"); 14357 ast_manager_unregister("IAXregistry"); 14358 ast_unregister_application(papp); 14359 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14360 ast_unregister_switch(&iax2_switch); 14361 ast_channel_unregister(&iax2_tech); 14362 14363 if (netthreadid != AST_PTHREADT_NULL) { 14364 pthread_cancel(netthreadid); 14365 pthread_kill(netthreadid, SIGURG); 14366 pthread_join(netthreadid, NULL); 14367 } 14368 14369 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14370 if (iaxs[x]) { 14371 iax2_destroy(x); 14372 } 14373 } 14374 14375 /* Call for all threads to halt */ 14376 cleanup_thread_list(&idle_list); 14377 cleanup_thread_list(&active_list); 14378 cleanup_thread_list(&dynamic_list); 14379 14380 ast_netsock_release(netsock); 14381 ast_netsock_release(outsock); 14382 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14383 if (iaxs[x]) { 14384 iax2_destroy(x); 14385 } 14386 } 14387 ast_manager_unregister( "IAXpeers" ); 14388 ast_manager_unregister( "IAXpeerlist" ); 14389 ast_manager_unregister( "IAXnetstats" ); 14390 ast_manager_unregister( "IAXregistry" ); 14391 ast_unregister_application(papp); 14392 #ifdef TEST_FRAMEWORK 14393 AST_TEST_UNREGISTER(test_iax2_peers_get); 14394 AST_TEST_UNREGISTER(test_iax2_users_get); 14395 #endif 14396 ast_data_unregister(NULL); 14397 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14398 ast_unregister_switch(&iax2_switch); 14399 ast_channel_unregister(&iax2_tech); 14400 delete_users(); 14401 iax_provision_unload(); 14402 reload_firmware(1); 14403 14404 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14405 ast_mutex_destroy(&iaxsl[x]); 14406 } 14407 14408 ao2_ref(peers, -1); 14409 ao2_ref(users, -1); 14410 ao2_ref(iax_peercallno_pvts, -1); 14411 ao2_ref(iax_transfercallno_pvts, -1); 14412 ao2_ref(peercnts, -1); 14413 ao2_ref(callno_limits, -1); 14414 ao2_ref(calltoken_ignores, -1); 14415 ao2_ref(callno_pool, -1); 14416 ao2_ref(callno_pool_trunk, -1); 14417 if (timer) { 14418 ast_timer_close(timer); 14419 } 14420 transmit_processor = ast_taskprocessor_unreference(transmit_processor); 14421 sched = ast_sched_thread_destroy(sched); 14422 14423 con = ast_context_find(regcontext); 14424 if (con) 14425 ast_context_destroy(con, "IAX2"); 14426 ast_unload_realtime("iaxpeers"); 14427 return 0; 14428 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 14844 of file chan_iax2.c.
static int acf_channel_read | ( | struct ast_channel * | chan, | |
const char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 13987 of file chan_iax2.c.
References chan_iax2_pvt::addr, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_tech, IAX_CALLENCRYPTED, iaxs, iaxsl, LOG_ERROR, chan_iax2_pvt::osptoken, PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, and chan_iax2_pvt::username.
13988 { 13989 struct chan_iax2_pvt *pvt; 13990 unsigned int callno; 13991 int res = 0; 13992 13993 if (!chan || chan->tech != &iax2_tech) { 13994 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n"); 13995 return -1; 13996 } 13997 13998 callno = PTR_TO_CALLNO(chan->tech_pvt); 13999 ast_mutex_lock(&iaxsl[callno]); 14000 if (!(pvt = iaxs[callno])) { 14001 ast_mutex_unlock(&iaxsl[callno]); 14002 return -1; 14003 } 14004 14005 if (!strcasecmp(args, "osptoken")) { 14006 ast_copy_string(buf, pvt->osptoken, buflen); 14007 } else if (!strcasecmp(args, "peerip")) { 14008 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen); 14009 } else if (!strcasecmp(args, "peername")) { 14010 ast_copy_string(buf, pvt->username, buflen); 14011 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) { 14012 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : ""); 14013 } else { 14014 res = -1; 14015 } 14016 14017 ast_mutex_unlock(&iaxsl[callno]); 14018 14019 return res; 14020 }
static int acf_iaxvar_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 9817 of file chan_iax2.c.
References ast_channel_datastore_find(), ast_copy_string(), AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_datastore::data, ast_var_t::entries, iax2_variable_datastore_info, and var.
09818 { 09819 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09820 AST_LIST_HEAD(, ast_var_t) *varlist; 09821 struct ast_var_t *var; 09822 09823 if (!variablestore) { 09824 *buf = '\0'; 09825 return 0; 09826 } 09827 varlist = variablestore->data; 09828 09829 AST_LIST_LOCK(varlist); 09830 AST_LIST_TRAVERSE(varlist, var, entries) { 09831 if (strcmp(var->name, data) == 0) { 09832 ast_copy_string(buf, var->value, len); 09833 break; 09834 } 09835 } 09836 AST_LIST_UNLOCK(varlist); 09837 return 0; 09838 }
static int acf_iaxvar_write | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
const char * | value | |||
) | [static] |
Definition at line 9840 of file chan_iax2.c.
References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc, ast_datastore_free(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_var_assign(), ast_var_delete(), ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_var_t::entries, iax2_variable_datastore_info, ast_datastore::inheritance, LOG_ERROR, and var.
09841 { 09842 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09843 AST_LIST_HEAD(, ast_var_t) *varlist; 09844 struct ast_var_t *var; 09845 09846 if (!variablestore) { 09847 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 09848 if (!variablestore) { 09849 ast_log(LOG_ERROR, "Memory allocation error\n"); 09850 return -1; 09851 } 09852 varlist = ast_calloc(1, sizeof(*varlist)); 09853 if (!varlist) { 09854 ast_datastore_free(variablestore); 09855 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09856 return -1; 09857 } 09858 09859 AST_LIST_HEAD_INIT(varlist); 09860 variablestore->data = varlist; 09861 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 09862 ast_channel_datastore_add(chan, variablestore); 09863 } else 09864 varlist = variablestore->data; 09865 09866 AST_LIST_LOCK(varlist); 09867 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) { 09868 if (strcmp(var->name, data) == 0) { 09869 AST_LIST_REMOVE_CURRENT(entries); 09870 ast_var_delete(var); 09871 break; 09872 } 09873 } 09874 AST_LIST_TRAVERSE_SAFE_END; 09875 var = ast_var_assign(data, value); 09876 if (var) 09877 AST_LIST_INSERT_TAIL(varlist, var, entries); 09878 else 09879 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09880 AST_LIST_UNLOCK(varlist); 09881 return 0; 09882 }
static int add_calltoken_ignore | ( | const char * | addr | ) | [static] |
Definition at line 2514 of file chan_iax2.c.
References ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_append_ha(), ast_copy_ha(), ast_free_ha(), ast_log(), ast_strlen_zero(), calltoken_ignores, addr_range::ha, LOG_WARNING, and OBJ_POINTER.
Referenced by set_config().
02515 { 02516 struct addr_range tmp; 02517 struct addr_range *addr_range = NULL; 02518 struct ast_ha *ha = NULL; 02519 int error = 0; 02520 02521 if (ast_strlen_zero(addr)) { 02522 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr); 02523 return -1; 02524 } 02525 02526 ha = ast_append_ha("permit", addr, NULL, &error); 02527 02528 /* check for valid config information */ 02529 if (error) { 02530 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr); 02531 return -1; 02532 } 02533 02534 ast_copy_ha(ha, &tmp.ha); 02535 /* find or create the addr_range */ 02536 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) { 02537 ao2_lock(addr_range); 02538 addr_range->delme = 0; 02539 ao2_unlock(addr_range); 02540 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02541 /* copy over config data into addr_range object */ 02542 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */ 02543 ao2_link(calltoken_ignores, addr_range); 02544 } else { 02545 ast_free_ha(ha); 02546 return -1; 02547 } 02548 02549 ast_free_ha(ha); 02550 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02551 02552 return 0; 02553 }
static void add_empty_calltoken_ie | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | ied | |||
) | [static] |
Definition at line 4751 of file chan_iax2.c.
References iax_ie_data::buf, chan_iax2_pvt::calltoken_ie_len, IAX_IE_CALLTOKEN, and iax_ie_data::pos.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_do_register(), iax2_poke_peer(), and registry_rerequest().
04752 { 04753 /* first make sure their are two empty bytes left in ied->buf */ 04754 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) { 04755 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */ 04756 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */ 04757 pvt->calltoken_ie_len = 2; 04758 } 04759 }
static int addr_range_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2165 of file chan_iax2.c.
References ast_ha::addr, ast_sockaddr_cmp_addr(), CMP_MATCH, CMP_STOP, addr_range::ha, and ast_ha::netmask.
Referenced by load_objects().
02166 { 02167 struct addr_range *lim1 = obj, *lim2 = arg; 02168 return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) && 02169 !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ? 02170 CMP_MATCH | CMP_STOP : 0; 02171 }
static int addr_range_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2150 of file chan_iax2.c.
References addr_range::delme.
Referenced by set_config_destroy().
02151 { 02152 struct addr_range *lim = obj; 02153 lim->delme = 1; 02154 return 0; 02155 }
static int addr_range_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 2157 of file chan_iax2.c.
References ast_ha::addr, ast_sockaddr_to_sin, and addr_range::ha.
Referenced by load_objects().
02158 { 02159 const struct addr_range *lim = obj; 02160 struct sockaddr_in sin; 02161 ast_sockaddr_to_sin(&lim->ha.addr, &sin); 02162 return abs((int) sin.sin_addr.s_addr); 02163 }
static int addr_range_match_address_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2185 of file chan_iax2.c.
References ast_ha::addr, ast_sockaddr_to_sin, CMP_MATCH, CMP_STOP, addr_range::ha, and ast_ha::netmask.
Referenced by calltoken_required(), and set_peercnt_limit().
02186 { 02187 struct addr_range *addr_range = obj; 02188 struct sockaddr_in *sin = arg; 02189 struct sockaddr_in ha_netmask_sin; 02190 struct sockaddr_in ha_addr_sin; 02191 02192 ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin); 02193 ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin); 02194 02195 if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) { 02196 return CMP_MATCH | CMP_STOP; 02197 } 02198 return 0; 02199 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 7539 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
07540 { 07541 while(con) { 07542 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 07543 return -1; 07544 con = con->next; 07545 } 07546 return 0; 07547 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 7240 of file chan_iax2.c.
References ACN_FORMAT1, ACN_FORMAT2, ARRAY_LEN, ast_cli(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, astman_append(), jb_info::current, iax_rr::delay, iax_rr::dropped, chan_iax2_pvt::first_iax_message, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, chan_iax2_pvt::frames_received, iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), iax_rr::jitter, jb_info::jitter, chan_iax2_pvt::last_iax_message, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, MARK_IAX_SUBCLASS_TX, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, and chan_iax2_pvt::remote_rr.
Referenced by handle_cli_iax2_show_netstats(), and manager_iax2_show_netstats().
07241 { 07242 int x; 07243 int numchans = 0; 07244 char first_message[10] = { 0, }; 07245 char last_message[10] = { 0, }; 07246 #define ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" 07247 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" 07248 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07249 ast_mutex_lock(&iaxsl[x]); 07250 if (iaxs[x]) { 07251 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 07252 jb_info jbinfo; 07253 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 07254 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 07255 07256 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07257 jb_getinfo(iaxs[x]->jb, &jbinfo); 07258 localjitter = jbinfo.jitter; 07259 localdelay = jbinfo.current - jbinfo.min; 07260 locallost = jbinfo.frames_lost; 07261 locallosspct = jbinfo.losspct/1000; 07262 localdropped = jbinfo.frames_dropped; 07263 localooo = jbinfo.frames_ooo; 07264 } else { 07265 localjitter = -1; 07266 localdelay = 0; 07267 locallost = -1; 07268 locallosspct = -1; 07269 localdropped = 0; 07270 localooo = -1; 07271 } 07272 if (s) 07273 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07274 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07275 iaxs[x]->pingtime, 07276 localjitter, 07277 localdelay, 07278 locallost, 07279 locallosspct, 07280 localdropped, 07281 localooo, 07282 iaxs[x]->frames_received/1000, 07283 iaxs[x]->remote_rr.jitter, 07284 iaxs[x]->remote_rr.delay, 07285 iaxs[x]->remote_rr.losscnt, 07286 iaxs[x]->remote_rr.losspct, 07287 iaxs[x]->remote_rr.dropped, 07288 iaxs[x]->remote_rr.ooo, 07289 iaxs[x]->remote_rr.packets/1000, 07290 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07291 first_message, 07292 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07293 last_message); 07294 else 07295 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07296 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07297 iaxs[x]->pingtime, 07298 localjitter, 07299 localdelay, 07300 locallost, 07301 locallosspct, 07302 localdropped, 07303 localooo, 07304 iaxs[x]->frames_received/1000, 07305 iaxs[x]->remote_rr.jitter, 07306 iaxs[x]->remote_rr.delay, 07307 iaxs[x]->remote_rr.losscnt, 07308 iaxs[x]->remote_rr.losspct, 07309 iaxs[x]->remote_rr.dropped, 07310 iaxs[x]->remote_rr.ooo, 07311 iaxs[x]->remote_rr.packets/1000, 07312 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07313 first_message, 07314 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07315 last_message); 07316 numchans++; 07317 } 07318 ast_mutex_unlock(&iaxsl[x]); 07319 } 07320 07321 return numchans; 07322 }
AST_DATA_STRUCTURE | ( | iax2_user | , | |
DATA_EXPORT_IAX2_USER | ||||
) |
AST_DATA_STRUCTURE | ( | iax2_peer | , | |
DATA_EXPORT_IAX2_PEER | ||||
) |
static struct ast_channel* ast_iax2_new | ( | int | callno, | |
int | state, | |||
format_t | capability, | |||
const char * | linkedid | |||
) | [static] |
Create new call, interface with the PBX core.
Definition at line 5734 of file chan_iax2.c.
References chan_iax2_pvt::accountcode, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, ast_party_caller::ani, chan_iax2_pvt::ani, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_calloc, ast_channel_alloc, ast_channel_datastore_add(), ast_channel_release(), ast_copy_string(), ast_datastore_alloc, ast_datastore_free(), ast_debug, ast_free, ast_hangup(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, ast_log(), ast_module_ref(), ast_mutex_lock, ast_mutex_unlock, ast_pbx_start(), AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_var_assign(), ast_channel::caller, chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, chan_iax2_pvt::callno, CALLNO_TO_PTR, chan_iax2_pvt::capability, chan_iax2_pvt::cid_name, chan_iax2_pvt::cid_num, ast_channel::context, chan_iax2_pvt::context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_channel::dialed, chan_iax2_pvt::dnid, ast_var_t::entries, ast_channel::exten, chan_iax2_pvt::exten, ast_party_redirecting::from, chan_iax2_pvt::host, iax2_ami_channelupdate(), iax2_tech, iax2_variable_datastore_info, iaxs, iaxsl, chan_iax2_pvt::iaxvars, ast_party_caller::id, ast_datastore::inheritance, chan_iax2_pvt::language, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_party_id::name, ast_channel::nativeformats, ast_variable::next, ast_party_dialed::number, ast_party_id::number, chan_iax2_pvt::owner, parkinglot, chan_iax2_pvt::parkinglot, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_party_number::plan, ast_party_number::presentation, ast_party_name::presentation, ast_channel::rawreadformat, ast_channel::rawwriteformat, chan_iax2_pvt::rdnis, ast_channel::readformat, ast_channel::redirecting, ast_party_dialed::str, ast_party_number::str, ast_channel::tech, ast_channel::tech_pvt, ast_party_dialed::transit_network_select, ast_party_number::valid, ast_variable::value, var, chan_iax2_pvt::vars, and ast_channel::writeformat.
Referenced by iax2_request(), and socket_process().
05735 { 05736 struct ast_channel *tmp; 05737 struct chan_iax2_pvt *i; 05738 struct ast_variable *v = NULL; 05739 05740 if (!(i = iaxs[callno])) { 05741 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 05742 return NULL; 05743 } 05744 05745 /* Don't hold call lock */ 05746 ast_mutex_unlock(&iaxsl[callno]); 05747 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "IAX2/%s-%d", i->host, i->callno); 05748 ast_mutex_lock(&iaxsl[callno]); 05749 if (i != iaxs[callno]) { 05750 if (tmp) { 05751 /* unlock and relock iaxsl[callno] to preserve locking order */ 05752 ast_mutex_unlock(&iaxsl[callno]); 05753 tmp = ast_channel_release(tmp); 05754 ast_mutex_lock(&iaxsl[callno]); 05755 } 05756 return NULL; 05757 } 05758 iax2_ami_channelupdate(i); 05759 if (!tmp) 05760 return NULL; 05761 tmp->tech = &iax2_tech; 05762 /* We can support any format by default, until we get restricted */ 05763 tmp->nativeformats = capability; 05764 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 05765 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 05766 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 05767 05768 if (!ast_strlen_zero(i->parkinglot)) 05769 ast_string_field_set(tmp, parkinglot, i->parkinglot); 05770 /* Don't use ast_set_callerid() here because it will 05771 * generate a NewCallerID event before the NewChannel event */ 05772 if (!ast_strlen_zero(i->ani)) { 05773 tmp->caller.ani.number.valid = 1; 05774 tmp->caller.ani.number.str = ast_strdup(i->ani); 05775 } else if (!ast_strlen_zero(i->cid_num)) { 05776 tmp->caller.ani.number.valid = 1; 05777 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 05778 } 05779 tmp->dialed.number.str = ast_strdup(i->dnid); 05780 if (!ast_strlen_zero(i->rdnis)) { 05781 tmp->redirecting.from.number.valid = 1; 05782 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 05783 } 05784 tmp->caller.id.name.presentation = i->calling_pres; 05785 tmp->caller.id.number.presentation = i->calling_pres; 05786 tmp->caller.id.number.plan = i->calling_ton; 05787 tmp->dialed.transit_network_select = i->calling_tns; 05788 if (!ast_strlen_zero(i->language)) 05789 ast_string_field_set(tmp, language, i->language); 05790 if (!ast_strlen_zero(i->accountcode)) 05791 ast_string_field_set(tmp, accountcode, i->accountcode); 05792 if (i->amaflags) 05793 tmp->amaflags = i->amaflags; 05794 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05795 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05796 if (i->adsi) 05797 tmp->adsicpe = i->peeradsicpe; 05798 else 05799 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05800 i->owner = tmp; 05801 i->capability = capability; 05802 05803 /* Set inherited variables */ 05804 if (i->vars) { 05805 for (v = i->vars ; v ; v = v->next) 05806 pbx_builtin_setvar_helper(tmp, v->name, v->value); 05807 } 05808 if (i->iaxvars) { 05809 struct ast_datastore *variablestore; 05810 struct ast_variable *var, *prev = NULL; 05811 AST_LIST_HEAD(, ast_var_t) *varlist; 05812 ast_debug(1, "Loading up the channel with IAXVARs\n"); 05813 varlist = ast_calloc(1, sizeof(*varlist)); 05814 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 05815 if (variablestore && varlist) { 05816 variablestore->data = varlist; 05817 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 05818 AST_LIST_HEAD_INIT(varlist); 05819 for (var = i->iaxvars; var; var = var->next) { 05820 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 05821 if (prev) 05822 ast_free(prev); 05823 prev = var; 05824 if (!newvar) { 05825 /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */ 05826 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 05827 } else { 05828 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 05829 } 05830 } 05831 if (prev) 05832 ast_free(prev); 05833 i->iaxvars = NULL; 05834 ast_channel_datastore_add(i->owner, variablestore); 05835 } else { 05836 if (variablestore) { 05837 ast_datastore_free(variablestore); 05838 } 05839 if (varlist) { 05840 ast_free(varlist); 05841 } 05842 } 05843 } 05844 05845 if (state != AST_STATE_DOWN) { 05846 if (ast_pbx_start(tmp)) { 05847 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05848 ast_hangup(tmp); 05849 i->owner = NULL; 05850 return NULL; 05851 } 05852 } 05853 05854 ast_module_ref(ast_module_info->self); 05855 return tmp; 05856 }
static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3566 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and transmit_frame().
03567 { 03568 #ifdef SCHED_MULTITHREADED 03569 if (schedule_action(__attempt_transmit, data)) 03570 #endif 03571 __attempt_transmit(data); 03572 return 0; 03573 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 9027 of file chan_iax2.c.
References auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iax2_sched_replace(), iaxs, and sched.
Referenced by socket_process().
09028 { 09029 /* Schedule sending the authentication failure in one second, to prevent 09030 guessing */ 09031 if (iaxs[callno]) { 09032 iaxs[callno]->authfail = failcode; 09033 if (delayreject) { 09034 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 09035 sched, 1000, auth_reject, (void *)(long)callno); 09036 } else 09037 auth_reject((void *)(long)callno); 09038 } 09039 return 0; 09040 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 9013 of file chan_iax2.c.
References __auth_reject(), ast_mutex_lock, ast_mutex_unlock, chan_iax2_pvt::authid, iaxs, iaxsl, and schedule_action.
Referenced by auth_fail().
09014 { 09015 int callno = (int)(long)(data); 09016 ast_mutex_lock(&iaxsl[callno]); 09017 if (iaxs[callno]) 09018 iaxs[callno]->authid = -1; 09019 ast_mutex_unlock(&iaxsl[callno]); 09020 #ifdef SCHED_MULTITHREADED 09021 if (schedule_action(__auth_reject, data)) 09022 #endif 09023 __auth_reject(data); 09024 return 0; 09025 }
static int authenticate | ( | const char * | challenge, | |
const char * | secret, | |||
const char * | keyn, | |||
int | authmethods, | |||
struct iax_ie_data * | ied, | |||
struct sockaddr_in * | sin, | |||
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 8112 of file chan_iax2.c.
References ast_inet_ntoa(), ast_key_get(), AST_KEY_PRIVATE, ast_log(), ast_sign(), ast_strlen_zero(), build_encryption_keys(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, iax_ie_append_str(), IAX_IE_MD5_RESULT, IAX_IE_PASSWORD, IAX_IE_RSA_RESULT, LOG_NOTICE, md5(), MD5Final(), MD5Init(), and MD5Update().
Referenced by action_login(), authenticate_reply(), and registry_rerequest().
08113 { 08114 int res = -1; 08115 int x; 08116 if (!ast_strlen_zero(keyn)) { 08117 if (!(authmethods & IAX_AUTH_RSA)) { 08118 if (ast_strlen_zero(secret)) 08119 ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_inet_ntoa(sin->sin_addr)); 08120 } else if (ast_strlen_zero(challenge)) { 08121 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 08122 } else { 08123 char sig[256]; 08124 struct ast_key *key; 08125 key = ast_key_get(keyn, AST_KEY_PRIVATE); 08126 if (!key) { 08127 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 08128 } else { 08129 if (ast_sign(key, (char*)challenge, sig)) { 08130 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 08131 res = -1; 08132 } else { 08133 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 08134 res = 0; 08135 } 08136 } 08137 } 08138 } 08139 /* Fall back */ 08140 if (res && !ast_strlen_zero(secret)) { 08141 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 08142 struct MD5Context md5; 08143 unsigned char digest[16]; 08144 char digres[128]; 08145 MD5Init(&md5); 08146 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 08147 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 08148 MD5Final(digest, &md5); 08149 /* If they support md5, authenticate with it. */ 08150 for (x=0;x<16;x++) 08151 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 08152 if (pvt) { 08153 build_encryption_keys(digest, pvt); 08154 } 08155 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 08156 res = 0; 08157 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 08158 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 08159 res = 0; 08160 } else 08161 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 08162 } 08163 return res; 08164 }
static int authenticate_reply | ( | struct chan_iax2_pvt * | p, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies, | |||
const char * | override, | |||
const char * | okey | |||
) | [static] |
Definition at line 8170 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_calloc, ast_channel_datastore_add(), ast_datastore_alloc, ast_datastore_free(), AST_FRAME_IAX, ast_free, AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set_flag64, ast_sockaddr_to_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_var_assign(), authenticate(), iax_ies::authmethods, iax2_peer::authmethods, chan_iax2_pvt::callno, iax_ies::challenge, ast_datastore::data, DATASTORE_INHERIT_FOREVER, iax_ies::encmethods, ast_var_t::entries, iax2_variable_datastore_info, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_FORCE_ENCRYPT, IAX_KEYPOPULATED, iaxs, iaxsl, ast_datastore::inheritance, LOG_ERROR, LOG_NOTICE, iax2_peer::mask, merge_encryption(), iax2_peer::name, iax2_peer::outkey, peer_unref(), peers, realtime_peer(), iax2_peer::secret, send_command(), iax2_peer::username, iax_ies::username, var, and iax_ies::vars.
Referenced by socket_process().
08171 { 08172 struct iax2_peer *peer = NULL; 08173 /* Start pessimistic */ 08174 int res = -1; 08175 int authmethods = 0; 08176 struct iax_ie_data ied; 08177 uint16_t callno = p->callno; 08178 08179 memset(&ied, 0, sizeof(ied)); 08180 08181 if (ies->username) 08182 ast_string_field_set(p, username, ies->username); 08183 if (ies->challenge) 08184 ast_string_field_set(p, challenge, ies->challenge); 08185 if (ies->authmethods) 08186 authmethods = ies->authmethods; 08187 if (authmethods & IAX_AUTH_MD5) 08188 merge_encryption(p, ies->encmethods); 08189 else 08190 p->encmethods = 0; 08191 08192 /* Check for override RSA authentication first */ 08193 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 08194 /* Normal password authentication */ 08195 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 08196 } else { 08197 struct ao2_iterator i = ao2_iterator_init(peers, 0); 08198 while ((peer = ao2_iterator_next(&i))) { 08199 struct sockaddr_in peer_addr; 08200 08201 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 08202 08203 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 08204 /* No peer specified at our end, or this is the peer */ 08205 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 08206 /* No username specified in peer rule, or this is the right username */ 08207 && (!peer_addr.sin_addr.s_addr || ((sin->sin_addr.s_addr & peer->mask.s_addr) == (peer_addr.sin_addr.s_addr & peer->mask.s_addr))) 08208 /* No specified host, or this is our host */ 08209 ) { 08210 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 08211 if (!res) { 08212 peer_unref(peer); 08213 break; 08214 } 08215 } 08216 peer_unref(peer); 08217 } 08218 ao2_iterator_destroy(&i); 08219 if (!peer) { 08220 /* We checked our list and didn't find one. It's unlikely, but possible, 08221 that we're trying to authenticate *to* a realtime peer */ 08222 const char *peer_name = ast_strdupa(p->peer); 08223 ast_mutex_unlock(&iaxsl[callno]); 08224 if ((peer = realtime_peer(peer_name, NULL))) { 08225 ast_mutex_lock(&iaxsl[callno]); 08226 if (!(p = iaxs[callno])) { 08227 peer_unref(peer); 08228 return -1; 08229 } 08230 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 08231 peer_unref(peer); 08232 } 08233 if (!peer) { 08234 ast_mutex_lock(&iaxsl[callno]); 08235 if (!(p = iaxs[callno])) 08236 return -1; 08237 } 08238 } 08239 } 08240 08241 if (ies->encmethods) { 08242 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 08243 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 08244 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set\n"); 08245 return -1; /* if force encryption is yes, and no encryption methods, then return -1 to hangup */ 08246 } 08247 if (!res) { 08248 struct ast_datastore *variablestore; 08249 struct ast_variable *var, *prev = NULL; 08250 AST_LIST_HEAD(, ast_var_t) *varlist; 08251 varlist = ast_calloc(1, sizeof(*varlist)); 08252 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 08253 if (variablestore && varlist && p->owner) { 08254 variablestore->data = varlist; 08255 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 08256 AST_LIST_HEAD_INIT(varlist); 08257 for (var = ies->vars; var; var = var->next) { 08258 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 08259 if (prev) 08260 ast_free(prev); 08261 prev = var; 08262 if (!newvar) { 08263 /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */ 08264 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08265 } else { 08266 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 08267 } 08268 } 08269 if (prev) 08270 ast_free(prev); 08271 ies->vars = NULL; 08272 ast_channel_datastore_add(p->owner, variablestore); 08273 } else { 08274 if (p->owner) 08275 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08276 if (variablestore) 08277 ast_datastore_free(variablestore); 08278 if (varlist) 08279 ast_free(varlist); 08280 } 08281 } 08282 08283 if (!res) 08284 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 08285 return res; 08286 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 7818 of file chan_iax2.c.
References ao2_find, AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, ast_random(), ast_set_flag64, ast_string_field_set, ast_test_flag64, chan_iax2_pvt::authmethods, chan_iax2_pvt::challenge, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_AUTHREQ, IAX_COMMAND_REJECT, IAX_ENCRYPTED, iax_ie_append_byte(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, IAX_MAXAUTHREQ, iaxs, OBJ_POINTER, send_command(), send_command_final(), user, user_unref(), chan_iax2_pvt::username, and users.
Referenced by socket_process().
07819 { 07820 struct iax_ie_data ied; 07821 int res = -1, authreq_restrict = 0; 07822 char challenge[10]; 07823 struct chan_iax2_pvt *p = iaxs[call_num]; 07824 07825 memset(&ied, 0, sizeof(ied)); 07826 07827 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 07828 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07829 struct iax2_user *user, tmp_user = { 07830 .name = p->username, 07831 }; 07832 07833 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07834 if (user) { 07835 if (user->curauthreq == user->maxauthreq) 07836 authreq_restrict = 1; 07837 else 07838 user->curauthreq++; 07839 user = user_unref(user); 07840 } 07841 } 07842 07843 /* If the AUTHREQ limit test failed, send back an error */ 07844 if (authreq_restrict) { 07845 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 07846 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 07847 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 07848 return 0; 07849 } 07850 07851 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 07852 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 07853 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 07854 ast_string_field_set(p, challenge, challenge); 07855 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 07856 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 07857 } 07858 if (p->encmethods) 07859 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 07860 07861 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 07862 07863 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 07864 07865 if (p->encmethods) 07866 ast_set_flag64(p, IAX_ENCRYPTED); 07867 07868 return res; 07869 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7871 of file chan_iax2.c.
References ao2_find, ast_atomic_fetchadd_int(), ast_check_signature(), ast_clear_flag64, ast_copy_string(), ast_key_get(), AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_flag64, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, chan_iax2_pvt::challenge, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_FORCE_ENCRYPT, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, chan_iax2_pvt::inkeys, LOG_NOTICE, LOG_WARNING, md5(), iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), OBJ_POINTER, iax_ies::password, iax_ies::rsa_result, chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, strsep(), user, user_unref(), chan_iax2_pvt::username, and users.
Referenced by socket_process().
07872 { 07873 char requeststr[256]; 07874 char md5secret[256] = ""; 07875 char secret[256] = ""; 07876 char rsasecret[256] = ""; 07877 int res = -1; 07878 int x; 07879 struct iax2_user *user, tmp_user = { 07880 .name = p->username, 07881 }; 07882 07883 if (p->authrej) { 07884 return res; 07885 } 07886 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07887 if (user) { 07888 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07889 ast_atomic_fetchadd_int(&user->curauthreq, -1); 07890 ast_clear_flag64(p, IAX_MAXAUTHREQ); 07891 } 07892 ast_string_field_set(p, host, user->name); 07893 user = user_unref(user); 07894 } 07895 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) { 07896 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.\n"); 07897 return res; 07898 } 07899 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 07900 return res; 07901 if (ies->password) 07902 ast_copy_string(secret, ies->password, sizeof(secret)); 07903 if (ies->md5_result) 07904 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07905 if (ies->rsa_result) 07906 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07907 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 07908 struct ast_key *key; 07909 char *keyn; 07910 char tmpkey[256]; 07911 char *stringp=NULL; 07912 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 07913 stringp=tmpkey; 07914 keyn = strsep(&stringp, ":"); 07915 while(keyn) { 07916 key = ast_key_get(keyn, AST_KEY_PUBLIC); 07917 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 07918 res = 0; 07919 break; 07920 } else if (!key) 07921 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 07922 keyn = strsep(&stringp, ":"); 07923 } 07924 } else if (p->authmethods & IAX_AUTH_MD5) { 07925 struct MD5Context md5; 07926 unsigned char digest[16]; 07927 char *tmppw, *stringp; 07928 07929 tmppw = ast_strdupa(p->secret); 07930 stringp = tmppw; 07931 while((tmppw = strsep(&stringp, ";"))) { 07932 MD5Init(&md5); 07933 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 07934 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 07935 MD5Final(digest, &md5); 07936 /* If they support md5, authenticate with it. */ 07937 for (x=0;x<16;x++) 07938 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 07939 if (!strcasecmp(requeststr, md5secret)) { 07940 res = 0; 07941 break; 07942 } 07943 } 07944 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 07945 if (!strcmp(secret, p->secret)) 07946 res = 0; 07947 } 07948 return res; 07949 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 4686 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), sip_call(), and sip_show_sched().
04687 { 04688 #ifdef SCHED_MULTITHREADED 04689 if (schedule_action(__auto_congest, data)) 04690 #endif 04691 __auto_congest(data); 04692 return 0; 04693 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 9057 of file chan_iax2.c.
References __auto_hangup(), ast_mutex_lock, ast_mutex_unlock, chan_iax2_pvt::autoid, iaxs, iaxsl, and schedule_action.
Referenced by iax2_dprequest(), and iax2_provision().
09058 { 09059 int callno = (int)(long)(data); 09060 ast_mutex_lock(&iaxsl[callno]); 09061 if (iaxs[callno]) { 09062 iaxs[callno]->autoid = -1; 09063 } 09064 ast_mutex_unlock(&iaxsl[callno]); 09065 #ifdef SCHED_MULTITHREADED 09066 if (schedule_action(__auto_hangup, data)) 09067 #endif 09068 __auto_hangup(data); 09069 return 0; 09070 }
static void build_callno_limits | ( | struct ast_variable * | v | ) | [static] |
Definition at line 2459 of file chan_iax2.c.
References ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_append_ha(), ast_copy_ha(), ast_free_ha(), ast_log(), callno_limits, addr_range::ha, LOG_ERROR, ast_variable::name, ast_variable::next, OBJ_POINTER, and ast_variable::value.
Referenced by set_config().
02460 { 02461 struct addr_range *addr_range = NULL; 02462 struct addr_range tmp; 02463 struct ast_ha *ha; 02464 int limit; 02465 int error; 02466 int found; 02467 02468 for (; v; v = v->next) { 02469 limit = -1; 02470 error = 0; 02471 found = 0; 02472 ha = ast_append_ha("permit", v->name, NULL, &error); 02473 02474 /* check for valid config information */ 02475 if (error) { 02476 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name); 02477 continue; 02478 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) { 02479 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value); 02480 ast_free_ha(ha); 02481 continue; 02482 } 02483 02484 ast_copy_ha(ha, &tmp.ha); 02485 /* find or create the addr_range */ 02486 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) { 02487 ao2_lock(addr_range); 02488 found = 1; 02489 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02490 ast_free_ha(ha); 02491 return; /* out of memory */ 02492 } 02493 02494 /* copy over config data into addr_range object */ 02495 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */ 02496 ast_free_ha(ha); /* cleanup the tmp ha */ 02497 addr_range->limit = limit; 02498 addr_range->delme = 0; 02499 02500 /* cleanup */ 02501 if (found) { 02502 ao2_unlock(addr_range); 02503 } else { 02504 ao2_link(callno_limits, addr_range); 02505 } 02506 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02507 } 02508 }
static struct iax2_context* build_context | ( | const char * | context | ) | [static] |
Definition at line 12249 of file chan_iax2.c.
References ast_calloc, and ast_copy_string().
Referenced by build_user().
12250 { 12251 struct iax2_context *con; 12252 12253 if ((con = ast_calloc(1, sizeof(*con)))) 12254 ast_copy_string(con->context, context, sizeof(con->context)); 12255 12256 return con; 12257 }
static void build_ecx_key | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 6197 of file chan_iax2.c.
References ast_aes_set_decrypt_key(), ast_aes_set_encrypt_key(), build_rand_pad(), chan_iax2_pvt::ecx, chan_iax2_pvt::mydcx, and chan_iax2_pvt::semirand.
Referenced by build_encryption_keys(), and iax2_key_rotate().
06198 { 06199 /* it is required to hold the corresponding decrypt key to our encrypt key 06200 * in the pvt struct because queued frames occasionally need to be decrypted and 06201 * re-encrypted when updated for a retransmission */ 06202 build_rand_pad(pvt->semirand, sizeof(pvt->semirand)); 06203 ast_aes_set_encrypt_key(digest, &pvt->ecx); 06204 ast_aes_set_decrypt_key(digest, &pvt->mydcx); 06205 }
static void build_encryption_keys | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 6191 of file chan_iax2.c.
References ast_aes_set_decrypt_key(), build_ecx_key(), and chan_iax2_pvt::dcx.
Referenced by authenticate(), and decrypt_frame().
06192 { 06193 build_ecx_key(digest, pvt); 06194 ast_aes_set_decrypt_key(digest, &pvt->dcx); 06195 }
static struct iax2_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static] |
Create peer structure based on configuration.
Definition at line 12400 of file chan_iax2.c.
References ao2_alloc, ao2_find, ast_append_ha(), ast_callerid_split(), ast_clear_flag64, ast_copy_flags64, ast_dnsmgr_lookup(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_false(), ast_free_ha(), ast_get_ip(), ast_log(), ast_parse_allow_disallow(), ast_sched_thread_del, ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_setnull(), ast_sockaddr_to_sin, ast_strdupa, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_true(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, CALLTOKEN_YES, cid_name, cid_num, context, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, get_auth_methods(), get_encrypt_methods(), globalflags, iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, inet_aton(), ast_variable::lineno, LOG_WARNING, mailbox, mwi_event_cb(), ast_variable::name, iax2_peer::name, ast_variable::next, OBJ_POINTER, peer_destructor(), peer_set_srcaddr(), peer_unref(), peercnt_modify(), peers, prefs, S_OR, sched, secret, ast_sockaddr::ss, strsep(), timer, unlink_peer(), ast_variable::value, and zonetag.
12401 { 12402 struct iax2_peer *peer = NULL; 12403 struct ast_ha *oldha = NULL; 12404 int maskfound = 0; 12405 int found = 0; 12406 int firstpass = 1; 12407 struct iax2_peer tmp_peer = { 12408 .name = name, 12409 }; 12410 12411 if (!temponly) { 12412 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 12413 if (peer && !ast_test_flag64(peer, IAX_DELME)) 12414 firstpass = 0; 12415 } 12416 12417 if (peer) { 12418 found++; 12419 if (firstpass) { 12420 oldha = peer->ha; 12421 peer->ha = NULL; 12422 } 12423 unlink_peer(peer); 12424 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 12425 peer->expire = -1; 12426 peer->pokeexpire = -1; 12427 peer->sockfd = defaultsockfd; 12428 peer->addr.ss.ss_family = AF_INET; 12429 peer->addr.len = sizeof(struct sockaddr_in); 12430 if (ast_string_field_init(peer, 32)) 12431 peer = peer_unref(peer); 12432 } 12433 12434 if (peer) { 12435 if (firstpass) { 12436 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 12437 peer->encmethods = iax2_encryption; 12438 peer->adsi = adsi; 12439 ast_string_field_set(peer,secret,""); 12440 if (!found) { 12441 ast_string_field_set(peer, name, name); 12442 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12443 peer->expiry = min_reg_expire; 12444 } 12445 peer->prefs = prefs; 12446 peer->capability = iax2_capability; 12447 peer->smoothing = 0; 12448 peer->pokefreqok = DEFAULT_FREQ_OK; 12449 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 12450 peer->maxcallno = 0; 12451 peercnt_modify(0, 0, &peer->addr); 12452 peer->calltoken_required = CALLTOKEN_DEFAULT; 12453 ast_string_field_set(peer,context,""); 12454 ast_string_field_set(peer,peercontext,""); 12455 ast_clear_flag64(peer, IAX_HASCALLERID); 12456 ast_string_field_set(peer, cid_name, ""); 12457 ast_string_field_set(peer, cid_num, ""); 12458 ast_string_field_set(peer, mohinterpret, mohinterpret); 12459 ast_string_field_set(peer, mohsuggest, mohsuggest); 12460 } 12461 12462 if (!v) { 12463 v = alt; 12464 alt = NULL; 12465 } 12466 while(v) { 12467 if (!strcasecmp(v->name, "secret")) { 12468 ast_string_field_set(peer, secret, v->value); 12469 } else if (!strcasecmp(v->name, "mailbox")) { 12470 ast_string_field_set(peer, mailbox, v->value); 12471 } else if (!strcasecmp(v->name, "hasvoicemail")) { 12472 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 12473 ast_string_field_set(peer, mailbox, name); 12474 } 12475 } else if (!strcasecmp(v->name, "mohinterpret")) { 12476 ast_string_field_set(peer, mohinterpret, v->value); 12477 } else if (!strcasecmp(v->name, "mohsuggest")) { 12478 ast_string_field_set(peer, mohsuggest, v->value); 12479 } else if (!strcasecmp(v->name, "dbsecret")) { 12480 ast_string_field_set(peer, dbsecret, v->value); 12481 } else if (!strcasecmp(v->name, "trunk")) { 12482 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK); 12483 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) { 12484 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name); 12485 ast_clear_flag64(peer, IAX_TRUNK); 12486 } 12487 } else if (!strcasecmp(v->name, "auth")) { 12488 peer->authmethods = get_auth_methods(v->value); 12489 } else if (!strcasecmp(v->name, "encryption")) { 12490 peer->encmethods |= get_encrypt_methods(v->value); 12491 if (!peer->encmethods) { 12492 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12493 } 12494 } else if (!strcasecmp(v->name, "forceencryption")) { 12495 if (ast_false(v->value)) { 12496 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12497 } else { 12498 peer->encmethods |= get_encrypt_methods(v->value); 12499 if (peer->encmethods) { 12500 ast_set_flag64(peer, IAX_FORCE_ENCRYPT); 12501 } 12502 } 12503 } else if (!strcasecmp(v->name, "transfer")) { 12504 if (!strcasecmp(v->value, "mediaonly")) { 12505 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12506 } else if (ast_true(v->value)) { 12507 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12508 } else 12509 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12510 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12511 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF); 12512 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12513 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 12514 } else if (!strcasecmp(v->name, "host")) { 12515 if (!strcasecmp(v->value, "dynamic")) { 12516 /* They'll register with us */ 12517 ast_set_flag64(peer, IAX_DYNAMIC); 12518 if (!found) { 12519 /* Initialize stuff iff we're not found, otherwise 12520 we keep going with what we had */ 12521 if (ast_sockaddr_port(&peer->addr)) { 12522 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr)); 12523 } 12524 ast_sockaddr_setnull(&peer->addr); 12525 } 12526 } else { 12527 /* Non-dynamic. Make sure we become that way if we're not */ 12528 ast_sched_thread_del(sched, peer->expire); 12529 ast_clear_flag64(peer, IAX_DYNAMIC); 12530 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) 12531 return peer_unref(peer); 12532 if (!ast_sockaddr_port(&peer->addr)) { 12533 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12534 } 12535 } 12536 if (!maskfound) 12537 inet_aton("255.255.255.255", &peer->mask); 12538 } else if (!strcasecmp(v->name, "defaultip")) { 12539 struct ast_sockaddr peer_defaddr_tmp; 12540 12541 peer_defaddr_tmp.ss.ss_family = AF_INET; 12542 if (ast_get_ip(&peer_defaddr_tmp, v->value)) { 12543 return peer_unref(peer); 12544 } 12545 ast_sockaddr_to_sin(&peer_defaddr_tmp, 12546 &peer->defaddr); 12547 } else if (!strcasecmp(v->name, "sourceaddress")) { 12548 peer_set_srcaddr(peer, v->value); 12549 } else if (!strcasecmp(v->name, "permit") || 12550 !strcasecmp(v->name, "deny")) { 12551 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL); 12552 } else if (!strcasecmp(v->name, "mask")) { 12553 maskfound++; 12554 inet_aton(v->value, &peer->mask); 12555 } else if (!strcasecmp(v->name, "context")) { 12556 ast_string_field_set(peer, context, v->value); 12557 } else if (!strcasecmp(v->name, "regexten")) { 12558 ast_string_field_set(peer, regexten, v->value); 12559 } else if (!strcasecmp(v->name, "peercontext")) { 12560 ast_string_field_set(peer, peercontext, v->value); 12561 } else if (!strcasecmp(v->name, "port")) { 12562 if (ast_test_flag64(peer, IAX_DYNAMIC)) { 12563 peer->defaddr.sin_port = htons(atoi(v->value)); 12564 } else { 12565 ast_sockaddr_set_port(&peer->addr, atoi(v->value)); 12566 } 12567 } else if (!strcasecmp(v->name, "username")) { 12568 ast_string_field_set(peer, username, v->value); 12569 } else if (!strcasecmp(v->name, "allow")) { 12570 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 12571 } else if (!strcasecmp(v->name, "disallow")) { 12572 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 12573 } else if (!strcasecmp(v->name, "callerid")) { 12574 if (!ast_strlen_zero(v->value)) { 12575 char name2[80]; 12576 char num2[80]; 12577 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12578 ast_string_field_set(peer, cid_name, name2); 12579 ast_string_field_set(peer, cid_num, num2); 12580 } else { 12581 ast_string_field_set(peer, cid_name, ""); 12582 ast_string_field_set(peer, cid_num, ""); 12583 } 12584 ast_set_flag64(peer, IAX_HASCALLERID); 12585 } else if (!strcasecmp(v->name, "fullname")) { 12586 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 12587 ast_set_flag64(peer, IAX_HASCALLERID); 12588 } else if (!strcasecmp(v->name, "cid_number")) { 12589 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 12590 ast_set_flag64(peer, IAX_HASCALLERID); 12591 } else if (!strcasecmp(v->name, "sendani")) { 12592 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI); 12593 } else if (!strcasecmp(v->name, "inkeys")) { 12594 ast_string_field_set(peer, inkeys, v->value); 12595 } else if (!strcasecmp(v->name, "outkey")) { 12596 ast_string_field_set(peer, outkey, v->value); 12597 } else if (!strcasecmp(v->name, "qualify")) { 12598 if (!strcasecmp(v->value, "no")) { 12599 peer->maxms = 0; 12600 } else if (!strcasecmp(v->value, "yes")) { 12601 peer->maxms = DEFAULT_MAXMS; 12602 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 12603 ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of iax.conf\n", peer->name, v->lineno); 12604 peer->maxms = 0; 12605 } 12606 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 12607 peer->smoothing = ast_true(v->value); 12608 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 12609 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) { 12610 ast_log(LOG_WARNING, "Qualification testing frequency of peer '%s' when OK should a number of milliseconds at line %d of iax.conf\n", peer->name, v->lineno); 12611 } 12612 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 12613 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) { 12614 ast_log(LOG_WARNING, "Qualification testing frequency of peer '%s' when NOT OK should be a number of milliseconds at line %d of iax.conf\n", peer->name, v->lineno); 12615 } 12616 } else if (!strcasecmp(v->name, "timezone")) { 12617 ast_string_field_set(peer, zonetag, v->value); 12618 } else if (!strcasecmp(v->name, "adsi")) { 12619 peer->adsi = ast_true(v->value); 12620 } else if (!strcasecmp(v->name, "connectedline")) { 12621 if (ast_true(v->value)) { 12622 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12623 } else if (!strcasecmp(v->value, "send")) { 12624 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE); 12625 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE); 12626 } else if (!strcasecmp(v->value, "receive")) { 12627 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE); 12628 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE); 12629 } else { 12630 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12631 } 12632 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 12633 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) { 12634 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 12635 } else { 12636 peercnt_modify(1, peer->maxcallno, &peer->addr); 12637 } 12638 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12639 /* default is required unless in optional ip list */ 12640 if (ast_false(v->value)) { 12641 peer->calltoken_required = CALLTOKEN_NO; 12642 } else if (!strcasecmp(v->value, "auto")) { 12643 peer->calltoken_required = CALLTOKEN_AUTO; 12644 } else if (ast_true(v->value)) { 12645 peer->calltoken_required = CALLTOKEN_YES; 12646 } else { 12647 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12648 } 12649 } /* else if (strcasecmp(v->name,"type")) */ 12650 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12651 v = v->next; 12652 if (!v) { 12653 v = alt; 12654 alt = NULL; 12655 } 12656 } 12657 if (!peer->authmethods) 12658 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12659 ast_clear_flag64(peer, IAX_DELME); 12660 } 12661 12662 if (oldha) 12663 ast_free_ha(oldha); 12664 12665 if (!ast_strlen_zero(peer->mailbox)) { 12666 char *mailbox, *context; 12667 context = mailbox = ast_strdupa(peer->mailbox); 12668 strsep(&context, "@"); 12669 if (ast_strlen_zero(context)) 12670 context = "default"; 12671 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL, 12672 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 12673 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 12674 AST_EVENT_IE_END); 12675 } 12676 12677 return peer; 12678 }
static void build_rand_pad | ( | unsigned char * | buf, | |
ssize_t | len | |||
) | [static] |
Definition at line 6181 of file chan_iax2.c.
References ast_random().
Referenced by build_ecx_key(), and update_packet().
06182 { 06183 long tmp; 06184 for (tmp = ast_random(); len > 0; tmp = ast_random()) { 06185 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len); 06186 buf += sizeof(tmp); 06187 len -= sizeof(tmp); 06188 } 06189 }
static struct iax2_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static] |
Create in-memory user structure from configuration.
Definition at line 12694 of file chan_iax2.c.
References ao2_alloc, ao2_find, ao2_unlink, ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag64, ast_copy_flags64, ast_false(), ast_free_ha(), ast_log(), ast_parse_allow_disallow(), ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_strdupa, ast_string_field_build, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_true(), ast_variable_new(), build_context(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, CALLTOKEN_YES, cid_name, cid_num, cleanup(), iax2_user::dbsecret, format, free_context(), get_auth_methods(), get_encrypt_methods(), globalflags, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_IMMEDIATE, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_user::inkeys, ast_variable::lineno, LOG_WARNING, ast_variable::name, iax2_user::name, ast_variable::next, OBJ_POINTER, parkinglot, prefs, secret, timer, user, user_destructor(), user_unref(), users, and ast_variable::value.
12695 { 12696 struct iax2_user *user = NULL; 12697 struct iax2_context *con, *conl = NULL; 12698 struct ast_ha *oldha = NULL; 12699 struct iax2_context *oldcon = NULL; 12700 int format; 12701 int firstpass=1; 12702 int oldcurauthreq = 0; 12703 char *varname = NULL, *varval = NULL; 12704 struct ast_variable *tmpvar = NULL; 12705 struct iax2_user tmp_user = { 12706 .name = name, 12707 }; 12708 12709 if (!temponly) { 12710 user = ao2_find(users, &tmp_user, OBJ_POINTER); 12711 if (user && !ast_test_flag64(user, IAX_DELME)) 12712 firstpass = 0; 12713 } 12714 12715 if (user) { 12716 if (firstpass) { 12717 oldcurauthreq = user->curauthreq; 12718 oldha = user->ha; 12719 oldcon = user->contexts; 12720 user->ha = NULL; 12721 user->contexts = NULL; 12722 } 12723 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12724 ao2_unlink(users, user); 12725 } else { 12726 user = ao2_alloc(sizeof(*user), user_destructor); 12727 } 12728 12729 if (user) { 12730 if (firstpass) { 12731 ast_string_field_free_memory(user); 12732 memset(user, 0, sizeof(struct iax2_user)); 12733 if (ast_string_field_init(user, 32)) { 12734 user = user_unref(user); 12735 goto cleanup; 12736 } 12737 user->maxauthreq = maxauthreq; 12738 user->curauthreq = oldcurauthreq; 12739 user->prefs = prefs; 12740 user->capability = iax2_capability; 12741 user->encmethods = iax2_encryption; 12742 user->adsi = adsi; 12743 user->calltoken_required = CALLTOKEN_DEFAULT; 12744 ast_string_field_set(user, name, name); 12745 ast_string_field_set(user, language, language); 12746 ast_copy_flags64(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 12747 ast_clear_flag64(user, IAX_HASCALLERID); 12748 ast_string_field_set(user, cid_name, ""); 12749 ast_string_field_set(user, cid_num, ""); 12750 ast_string_field_set(user, accountcode, accountcode); 12751 ast_string_field_set(user, mohinterpret, mohinterpret); 12752 ast_string_field_set(user, mohsuggest, mohsuggest); 12753 } 12754 if (!v) { 12755 v = alt; 12756 alt = NULL; 12757 } 12758 while(v) { 12759 if (!strcasecmp(v->name, "context")) { 12760 con = build_context(v->value); 12761 if (con) { 12762 if (conl) 12763 conl->next = con; 12764 else 12765 user->contexts = con; 12766 conl = con; 12767 } 12768 } else if (!strcasecmp(v->name, "permit") || 12769 !strcasecmp(v->name, "deny")) { 12770 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL); 12771 } else if (!strcasecmp(v->name, "setvar")) { 12772 varname = ast_strdupa(v->value); 12773 if (varname && (varval = strchr(varname,'='))) { 12774 *varval = '\0'; 12775 varval++; 12776 if((tmpvar = ast_variable_new(varname, varval, ""))) { 12777 tmpvar->next = user->vars; 12778 user->vars = tmpvar; 12779 } 12780 } 12781 } else if (!strcasecmp(v->name, "allow")) { 12782 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 12783 } else if (!strcasecmp(v->name, "disallow")) { 12784 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 12785 } else if (!strcasecmp(v->name, "trunk")) { 12786 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK); 12787 if (ast_test_flag64(user, IAX_TRUNK) && !timer) { 12788 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name); 12789 ast_clear_flag64(user, IAX_TRUNK); 12790 } 12791 } else if (!strcasecmp(v->name, "auth")) { 12792 user->authmethods = get_auth_methods(v->value); 12793 } else if (!strcasecmp(v->name, "encryption")) { 12794 user->encmethods |= get_encrypt_methods(v->value); 12795 if (!user->encmethods) { 12796 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 12797 } 12798 } else if (!strcasecmp(v->name, "forceencryption")) { 12799 if (ast_false(v->value)) { 12800 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 12801 } else { 12802 user->encmethods |= get_encrypt_methods(v->value); 12803 if (user->encmethods) { 12804 ast_set_flag64(user, IAX_FORCE_ENCRYPT); 12805 } 12806 } 12807 } else if (!strcasecmp(v->name, "transfer")) { 12808 if (!strcasecmp(v->value, "mediaonly")) { 12809 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12810 } else if (ast_true(v->value)) { 12811 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12812 } else 12813 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12814 } else if (!strcasecmp(v->name, "codecpriority")) { 12815 if(!strcasecmp(v->value, "caller")) 12816 ast_set_flag64(user, IAX_CODEC_USER_FIRST); 12817 else if(!strcasecmp(v->value, "disabled")) 12818 ast_set_flag64(user, IAX_CODEC_NOPREFS); 12819 else if(!strcasecmp(v->value, "reqonly")) { 12820 ast_set_flag64(user, IAX_CODEC_NOCAP); 12821 ast_set_flag64(user, IAX_CODEC_NOPREFS); 12822 } 12823 } else if (!strcasecmp(v->name, "immediate")) { 12824 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE); 12825 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12826 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF); 12827 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12828 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF); 12829 } else if (!strcasecmp(v->name, "dbsecret")) { 12830 ast_string_field_set(user, dbsecret, v->value); 12831 } else if (!strcasecmp(v->name, "secret")) { 12832 if (!ast_strlen_zero(user->secret)) { 12833 char *old = ast_strdupa(user->secret); 12834 12835 ast_string_field_build(user, secret, "%s;%s", old, v->value); 12836 } else 12837 ast_string_field_set(user, secret, v->value); 12838 } else if (!strcasecmp(v->name, "callerid")) { 12839 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 12840 char name2[80]; 12841 char num2[80]; 12842 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12843 ast_string_field_set(user, cid_name, name2); 12844 ast_string_field_set(user, cid_num, num2); 12845 ast_set_flag64(user, IAX_HASCALLERID); 12846 } else { 12847 ast_clear_flag64(user, IAX_HASCALLERID); 12848 ast_string_field_set(user, cid_name, ""); 12849 ast_string_field_set(user, cid_num, ""); 12850 } 12851 } else if (!strcasecmp(v->name, "fullname")) { 12852 if (!ast_strlen_zero(v->value)) { 12853 ast_string_field_set(user, cid_name, v->value); 12854 ast_set_flag64(user, IAX_HASCALLERID); 12855 } else { 12856 ast_string_field_set(user, cid_name, ""); 12857 if (ast_strlen_zero(user->cid_num)) 12858 ast_clear_flag64(user, IAX_HASCALLERID); 12859 } 12860 } else if (!strcasecmp(v->name, "cid_number")) { 12861 if (!ast_strlen_zero(v->value)) { 12862 ast_string_field_set(user, cid_num, v->value); 12863 ast_set_flag64(user, IAX_HASCALLERID); 12864 } else { 12865 ast_string_field_set(user, cid_num, ""); 12866 if (ast_strlen_zero(user->cid_name)) 12867 ast_clear_flag64(user, IAX_HASCALLERID); 12868 } 12869 } else if (!strcasecmp(v->name, "accountcode")) { 12870 ast_string_field_set(user, accountcode, v->value); 12871 } else if (!strcasecmp(v->name, "mohinterpret")) { 12872 ast_string_field_set(user, mohinterpret, v->value); 12873 } else if (!strcasecmp(v->name, "mohsuggest")) { 12874 ast_string_field_set(user, mohsuggest, v->value); 12875 } else if (!strcasecmp(v->name, "parkinglot")) { 12876 ast_string_field_set(user, parkinglot, v->value); 12877 } else if (!strcasecmp(v->name, "language")) { 12878 ast_string_field_set(user, language, v->value); 12879 } else if (!strcasecmp(v->name, "amaflags")) { 12880 format = ast_cdr_amaflags2int(v->value); 12881 if (format < 0) { 12882 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 12883 } else { 12884 user->amaflags = format; 12885 } 12886 } else if (!strcasecmp(v->name, "inkeys")) { 12887 ast_string_field_set(user, inkeys, v->value); 12888 } else if (!strcasecmp(v->name, "maxauthreq")) { 12889 user->maxauthreq = atoi(v->value); 12890 if (user->maxauthreq < 0) 12891 user->maxauthreq = 0; 12892 } else if (!strcasecmp(v->name, "adsi")) { 12893 user->adsi = ast_true(v->value); 12894 } else if (!strcasecmp(v->name, "connectedline")) { 12895 if (ast_true(v->value)) { 12896 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12897 } else if (!strcasecmp(v->value, "send")) { 12898 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE); 12899 ast_set_flag64(user, IAX_SENDCONNECTEDLINE); 12900 } else if (!strcasecmp(v->value, "receive")) { 12901 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE); 12902 ast_set_flag64(user, IAX_RECVCONNECTEDLINE); 12903 } else { 12904 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12905 } 12906 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12907 /* default is required unless in optional ip list */ 12908 if (ast_false(v->value)) { 12909 user->calltoken_required = CALLTOKEN_NO; 12910 } else if (!strcasecmp(v->value, "auto")) { 12911 user->calltoken_required = CALLTOKEN_AUTO; 12912 } else if (ast_true(v->value)) { 12913 user->calltoken_required = CALLTOKEN_YES; 12914 } else { 12915 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12916 } 12917 } /* else if (strcasecmp(v->name,"type")) */ 12918 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12919 v = v->next; 12920 if (!v) { 12921 v = alt; 12922 alt = NULL; 12923 } 12924 } 12925 if (!user->authmethods) { 12926 if (!ast_strlen_zero(user->secret)) { 12927 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12928 if (!ast_strlen_zero(user->inkeys)) 12929 user->authmethods |= IAX_AUTH_RSA; 12930 } else if (!ast_strlen_zero(user->inkeys)) { 12931 user->authmethods = IAX_AUTH_RSA; 12932 } else { 12933 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12934 } 12935 } 12936 ast_clear_flag64(user, IAX_DELME); 12937 } 12938 cleanup: 12939 if (oldha) 12940 ast_free_ha(oldha); 12941 if (oldcon) 12942 free_context(oldcon); 12943 return user; 12944 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 13591 of file chan_iax2.c.
References add_empty_calltoken_ie(), ARRAY_LEN, ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_trylock, ast_mutex_unlock, ast_strdupa, ast_string_field_set, ast_strlen_zero(), chan_iax2_pvt::capability, create_addr(), find_callno_locked(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, parse_dial_string(), secret, and send_command().
Referenced by find_cache().
13592 { 13593 struct sockaddr_in sin; 13594 int x; 13595 int callno; 13596 struct iax_ie_data ied; 13597 struct create_addr_info cai; 13598 struct parsed_dial_string pds; 13599 char *tmpstr; 13600 13601 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 13602 /* Look for an *exact match* call. Once a call is negotiated, it can only 13603 look up entries for a single context */ 13604 if (!ast_mutex_trylock(&iaxsl[x])) { 13605 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 13606 return x; 13607 ast_mutex_unlock(&iaxsl[x]); 13608 } 13609 } 13610 13611 /* No match found, we need to create a new one */ 13612 13613 memset(&cai, 0, sizeof(cai)); 13614 memset(&ied, 0, sizeof(ied)); 13615 memset(&pds, 0, sizeof(pds)); 13616 13617 tmpstr = ast_strdupa(data); 13618 parse_dial_string(tmpstr, &pds); 13619 13620 if (ast_strlen_zero(pds.peer)) { 13621 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 13622 return -1; 13623 } 13624 13625 /* Populate our address from the given */ 13626 if (create_addr(pds.peer, NULL, &sin, &cai)) 13627 return -1; 13628 13629 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n", 13630 pds.peer, pds.username, pds.password, pds.context); 13631 13632 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 13633 if (callno < 1) { 13634 ast_log(LOG_WARNING, "Unable to create call\n"); 13635 return -1; 13636 } 13637 13638 ast_string_field_set(iaxs[callno], dproot, data); 13639 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 13640 13641 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 13642 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 13643 /* the string format is slightly different from a standard dial string, 13644 because the context appears in the 'exten' position 13645 */ 13646 if (pds.exten) 13647 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 13648 if (pds.username) 13649 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 13650 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 13651 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 13652 /* Keep password handy */ 13653 if (pds.password) 13654 ast_string_field_set(iaxs[callno], secret, pds.password); 13655 if (pds.key) 13656 ast_string_field_set(iaxs[callno], outkey, pds.key); 13657 /* Start the call going */ 13658 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 13659 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 13660 13661 return callno; 13662 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 6034 of file chan_iax2.c.
References ast_debug, ast_random(), ast_samp2tv(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, and chan_iax2_pvt::rxcore.
Referenced by schedule_delivery().
06035 { 06036 /* Returns where in "receive time" we are. That is, how many ms 06037 since we received (or would have received) the frame with timestamp 0 */ 06038 int ms; 06039 #ifdef IAXTESTS 06040 int jit; 06041 #endif /* IAXTESTS */ 06042 /* Setup rxcore if necessary */ 06043 if (ast_tvzero(p->rxcore)) { 06044 p->rxcore = ast_tvnow(); 06045 if (iaxdebug) 06046 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 06047 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 06048 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 06049 #if 1 06050 if (iaxdebug) 06051 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 06052 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 06053 #endif 06054 } 06055 06056 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 06057 #ifdef IAXTESTS 06058 if (test_jit) { 06059 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 06060 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 06061 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 06062 jit = -jit; 06063 ms += jit; 06064 } 06065 } 06066 if (test_late) { 06067 ms += test_late; 06068 test_late = 0; 06069 } 06070 #endif /* IAXTESTS */ 06071 return ms; 06072 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 5902 of file chan_iax2.c.
References ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_samp2tv(), ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, f, iaxs, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, and chan_iax2_pvt::offset.
Referenced by iax2_send(), and socket_process().
05903 { 05904 int ms; 05905 int voice = 0; 05906 int genuine = 0; 05907 int adjust; 05908 int rate = ast_format_rate(f->subclass.codec) / 1000; 05909 struct timeval *delivery = NULL; 05910 05911 05912 /* What sort of frame do we have?: voice is self-explanatory 05913 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 05914 non-genuine frames are CONTROL frames [ringing etc], DTMF 05915 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 05916 the others need a timestamp slaved to the voice frames so that they go in sequence 05917 */ 05918 if (f->frametype == AST_FRAME_VOICE) { 05919 voice = 1; 05920 delivery = &f->delivery; 05921 } else if (f->frametype == AST_FRAME_IAX) { 05922 genuine = 1; 05923 } else if (f->frametype == AST_FRAME_CNG) { 05924 p->notsilenttx = 0; 05925 } 05926 05927 if (ast_tvzero(p->offset)) { 05928 p->offset = ast_tvnow(); 05929 /* Round to nearest 20ms for nice looking traces */ 05930 p->offset.tv_usec -= p->offset.tv_usec % 20000; 05931 } 05932 /* If the timestamp is specified, just send it as is */ 05933 if (ts) 05934 return ts; 05935 /* If we have a time that the frame arrived, always use it to make our timestamp */ 05936 if (delivery && !ast_tvzero(*delivery)) { 05937 ms = ast_tvdiff_ms(*delivery, p->offset); 05938 if (ms < 0) { 05939 ms = 0; 05940 } 05941 if (iaxdebug) 05942 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 05943 } else { 05944 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 05945 if (ms < 0) 05946 ms = 0; 05947 if (voice) { 05948 /* On a voice frame, use predicted values if appropriate */ 05949 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 05950 /* Adjust our txcore, keeping voice and non-voice synchronized */ 05951 /* AN EXPLANATION: 05952 When we send voice, we usually send "calculated" timestamps worked out 05953 on the basis of the number of samples sent. When we send other frames, 05954 we usually send timestamps worked out from the real clock. 05955 The problem is that they can tend to drift out of step because the 05956 source channel's clock and our clock may not be exactly at the same rate. 05957 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 05958 for this call. Moving it adjusts timestamps for non-voice frames. 05959 We make the adjustment in the style of a moving average. Each time we 05960 adjust p->offset by 10% of the difference between our clock-derived 05961 timestamp and the predicted timestamp. That's why you see "10000" 05962 below even though IAX2 timestamps are in milliseconds. 05963 The use of a moving average avoids offset moving too radically. 05964 Generally, "adjust" roams back and forth around 0, with offset hardly 05965 changing at all. But if a consistent different starts to develop it 05966 will be eliminated over the course of 10 frames (200-300msecs) 05967 */ 05968 adjust = (ms - p->nextpred); 05969 if (adjust < 0) 05970 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 05971 else if (adjust > 0) 05972 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 05973 05974 if (!p->nextpred) { 05975 p->nextpred = ms; /*f->samples / rate;*/ 05976 if (p->nextpred <= p->lastsent) 05977 p->nextpred = p->lastsent + 3; 05978 } 05979 ms = p->nextpred; 05980 } else { 05981 /* in this case, just use the actual 05982 * time, since we're either way off 05983 * (shouldn't happen), or we're ending a 05984 * silent period -- and seed the next 05985 * predicted time. Also, round ms to the 05986 * next multiple of frame size (so our 05987 * silent periods are multiples of 05988 * frame size too) */ 05989 05990 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 05991 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 05992 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 05993 05994 if (f->samples >= rate) /* check to make sure we don't core dump */ 05995 { 05996 int diff = ms % (f->samples / rate); 05997 if (diff) 05998 ms += f->samples/rate - diff; 05999 } 06000 06001 p->nextpred = ms; 06002 p->notsilenttx = 1; 06003 } 06004 } else if ( f->frametype == AST_FRAME_VIDEO ) { 06005 /* 06006 * IAX2 draft 03 says that timestamps MUST be in order. 06007 * It does not say anything about several frames having the same timestamp 06008 * When transporting video, we can have a frame that spans multiple iax packets 06009 * (so called slices), so it would make sense to use the same timestamp for all of 06010 * them 06011 * We do want to make sure that frames don't go backwards though 06012 */ 06013 if ( (unsigned int)ms < p->lastsent ) 06014 ms = p->lastsent; 06015 } else { 06016 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 06017 it's a genuine frame */ 06018 if (genuine) { 06019 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 06020 if (ms <= p->lastsent) 06021 ms = p->lastsent + 3; 06022 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 06023 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 06024 ms = p->lastsent + 3; 06025 } 06026 } 06027 } 06028 p->lastsent = ms; 06029 if (voice) 06030 p->nextpred = p->nextpred + f->samples / rate; 06031 return ms; 06032 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | now | |||
) | [static] |
Definition at line 5858 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvzero(), iax2_trunk_peer::lastsent, iax2_trunk_peer::lasttxtime, MAX_TIMESTAMP_SKEW, iax2_trunk_peer::trunkact, and iax2_trunk_peer::txtrunktime.
Referenced by send_trunk().
05859 { 05860 unsigned long int mssincetx; /* unsigned to handle overflows */ 05861 long int ms, pred; 05862 05863 tpeer->trunkact = *now; 05864 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime); 05865 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 05866 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 05867 tpeer->txtrunktime = *now; 05868 tpeer->lastsent = 999999; 05869 } 05870 /* Update last transmit time now */ 05871 tpeer->lasttxtime = *now; 05872 05873 /* Calculate ms offset */ 05874 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime); 05875 /* Predict from last value */ 05876 pred = tpeer->lastsent + sampms; 05877 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 05878 ms = pred; 05879 05880 /* We never send the same timestamp twice, so fudge a little if we must */ 05881 if (ms == tpeer->lastsent) 05882 ms = tpeer->lastsent + 1; 05883 tpeer->lastsent = ms; 05884 return ms; 05885 }
static int callno_hash | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 2682 of file chan_iax2.c.
References ast_random().
Referenced by create_callno_pools().
02683 { 02684 return abs(ast_random()); 02685 }
static int calltoken_required | ( | struct sockaddr_in * | sin, | |
const char * | name, | |||
int | subclass | |||
) | [static] |
Definition at line 2206 of file chan_iax2.c.
References addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_inet_ntoa(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, calltoken_ignores, CALLTOKEN_NO, iax2_peer::calltoken_required, find_peer(), find_user(), IAX_COMMAND_NEW, peer_unref(), realtime_peer(), realtime_user(), S_OR, user, and user_unref().
Referenced by handle_call_token().
02207 { 02208 struct addr_range *addr_range; 02209 struct iax2_peer *peer = NULL; 02210 struct iax2_user *user = NULL; 02211 /* if no username is given, check for guest accounts */ 02212 const char *find = S_OR(name, "guest"); 02213 int res = 1; /* required by default */ 02214 int optional = 0; 02215 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT; 02216 /* There are only two cases in which calltoken validation is not required. 02217 * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and 02218 * the peer definition has not set the requirecalltoken option. 02219 * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no. 02220 */ 02221 02222 /* ----- Case 1 ----- */ 02223 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) { 02224 ao2_ref(addr_range, -1); 02225 optional = 1; 02226 } 02227 02228 /* ----- Case 2 ----- */ 02229 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) { 02230 calltoken_required = user->calltoken_required; 02231 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) { 02232 calltoken_required = user->calltoken_required; 02233 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) { 02234 calltoken_required = peer->calltoken_required; 02235 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) { 02236 calltoken_required = peer->calltoken_required; 02237 } 02238 02239 if (peer) { 02240 peer_unref(peer); 02241 } 02242 if (user) { 02243 user_unref(user); 02244 } 02245 02246 ast_debug(1, "Determining if address %s with username %s requires calltoken validation. Optional = %d calltoken_required = %d \n", ast_inet_ntoa(sin->sin_addr), name, optional, calltoken_required); 02247 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) || 02248 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) { 02249 res = 0; 02250 } 02251 02252 return res; 02253 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7550 of file chan_iax2.c.
References chan_iax2_pvt::adsi, iax_ies::adsicpe, chan_iax2_pvt::amaflags, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags64, ast_db_get(), ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_SENSE_ALLOW, AST_SENSE_DENY, ast_set2_flag64, ast_set_flag64, ast_shrink_phone_number(), ast_sockaddr_from_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_variable_new(), chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, chan_iax2_pvt::calling_pres, iax_ies::calling_pres, chan_iax2_pvt::calling_tns, iax_ies::calling_tns, chan_iax2_pvt::calling_ton, iax_ies::calling_ton, chan_iax2_pvt::capability, iax_ies::capability, cid_name, cid_num, iax_ies::codec_prefs, chan_iax2_pvt::context, context, DEFAULT_CONTEXT, iax_ies::dnid, chan_iax2_pvt::encmethods, exten, ast_variable::file, iax_ies::format, globalflags, iax2_getpeertrunk(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_IMMEDIATE, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iax_ies::language, LOG_WARNING, ast_variable::name, ast_variable::next, parkinglot, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, chan_iax2_pvt::prefs, prefs, iax_ies::rdnis, realtime_user(), secret, user, user_unref(), iax_ies::username, users, ast_variable::value, chan_iax2_pvt::vars, iax_ies::version, and version.
Referenced by socket_process().
07551 { 07552 /* Start pessimistic */ 07553 int res = -1; 07554 int version = 2; 07555 struct iax2_user *user = NULL, *best = NULL; 07556 int bestscore = 0; 07557 int gotcapability = 0; 07558 struct ast_variable *v = NULL, *tmpvar = NULL; 07559 struct ao2_iterator i; 07560 struct ast_sockaddr addr; 07561 07562 if (!iaxs[callno]) 07563 return res; 07564 if (ies->called_number) 07565 ast_string_field_set(iaxs[callno], exten, ies->called_number); 07566 if (ies->calling_number) { 07567 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) { 07568 ast_shrink_phone_number(ies->calling_number); 07569 } 07570 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 07571 } 07572 if (ies->calling_name) 07573 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 07574 if (ies->calling_ani) 07575 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 07576 if (ies->dnid) 07577 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 07578 if (ies->rdnis) 07579 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 07580 if (ies->called_context) 07581 ast_string_field_set(iaxs[callno], context, ies->called_context); 07582 if (ies->language) 07583 ast_string_field_set(iaxs[callno], language, ies->language); 07584 if (ies->username) 07585 ast_string_field_set(iaxs[callno], username, ies->username); 07586 if (ies->calling_ton > -1) 07587 iaxs[callno]->calling_ton = ies->calling_ton; 07588 if (ies->calling_tns > -1) 07589 iaxs[callno]->calling_tns = ies->calling_tns; 07590 if (ies->calling_pres > -1) 07591 iaxs[callno]->calling_pres = ies->calling_pres; 07592 if (ies->format) 07593 iaxs[callno]->peerformat = ies->format; 07594 if (ies->adsicpe) 07595 iaxs[callno]->peeradsicpe = ies->adsicpe; 07596 if (ies->capability) { 07597 gotcapability = 1; 07598 iaxs[callno]->peercapability = ies->capability; 07599 } 07600 if (ies->version) 07601 version = ies->version; 07602 07603 /* Use provided preferences until told otherwise for actual preferences */ 07604 if (ies->codec_prefs) { 07605 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 07606 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 07607 } 07608 07609 if (!gotcapability) 07610 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 07611 if (version > IAX_PROTO_VERSION) { 07612 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 07613 ast_inet_ntoa(sin->sin_addr), version); 07614 return res; 07615 } 07616 /* Search the userlist for a compatible entry, and fill in the rest */ 07617 ast_sockaddr_from_sin(&addr, sin); 07618 i = ao2_iterator_init(users, 0); 07619 while ((user = ao2_iterator_next(&i))) { 07620 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 07621 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 07622 && ast_apply_ha(user->ha, &addr) == AST_SENSE_ALLOW /* Access is permitted from this IP */ 07623 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 07624 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 07625 if (!ast_strlen_zero(iaxs[callno]->username)) { 07626 /* Exact match, stop right now. */ 07627 if (best) 07628 user_unref(best); 07629 best = user; 07630 break; 07631 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 07632 /* No required authentication */ 07633 if (user->ha) { 07634 /* There was host authentication and we passed, bonus! */ 07635 if (bestscore < 4) { 07636 bestscore = 4; 07637 if (best) 07638 user_unref(best); 07639 best = user; 07640 continue; 07641 } 07642 } else { 07643 /* No host access, but no secret, either, not bad */ 07644 if (bestscore < 3) { 07645 bestscore = 3; 07646 if (best) 07647 user_unref(best); 07648 best = user; 07649 continue; 07650 } 07651 } 07652 } else { 07653 if (user->ha) { 07654 /* Authentication, but host access too, eh, it's something.. */ 07655 if (bestscore < 2) { 07656 bestscore = 2; 07657 if (best) 07658 user_unref(best); 07659 best = user; 07660 continue; 07661 } 07662 } else { 07663 /* Authentication and no host access... This is our baseline */ 07664 if (bestscore < 1) { 07665 bestscore = 1; 07666 if (best) 07667 user_unref(best); 07668 best = user; 07669 continue; 07670 } 07671 } 07672 } 07673 } 07674 user_unref(user); 07675 } 07676 ao2_iterator_destroy(&i); 07677 user = best; 07678 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 07679 user = realtime_user(iaxs[callno]->username, sin); 07680 if (user && (ast_apply_ha(user->ha, &addr) == AST_SENSE_DENY /* Access is denied from this IP */ 07681 || (!ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 07682 !apply_context(user->contexts, iaxs[callno]->context)))) { /* Context is permitted */ 07683 user = user_unref(user); 07684 } 07685 } 07686 if (user) { 07687 /* We found our match (use the first) */ 07688 /* copy vars */ 07689 for (v = user->vars ; v ; v = v->next) { 07690 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) { 07691 tmpvar->next = iaxs[callno]->vars; 07692 iaxs[callno]->vars = tmpvar; 07693 } 07694 } 07695 /* If a max AUTHREQ restriction is in place, activate it */ 07696 if (user->maxauthreq > 0) 07697 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ); 07698 iaxs[callno]->prefs = user->prefs; 07699 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT); 07700 iaxs[callno]->encmethods = user->encmethods; 07701 /* Store the requested username if not specified */ 07702 if (ast_strlen_zero(iaxs[callno]->username)) 07703 ast_string_field_set(iaxs[callno], username, user->name); 07704 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 07705 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK); 07706 iaxs[callno]->capability = user->capability; 07707 /* And use the default context */ 07708 if (ast_strlen_zero(iaxs[callno]->context)) { 07709 if (user->contexts) 07710 ast_string_field_set(iaxs[callno], context, user->contexts->context); 07711 else 07712 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT); 07713 } 07714 /* And any input keys */ 07715 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 07716 /* And the permitted authentication methods */ 07717 iaxs[callno]->authmethods = user->authmethods; 07718 iaxs[callno]->adsi = user->adsi; 07719 /* If the user has callerid, override the remote caller id. */ 07720 if (ast_test_flag64(user, IAX_HASCALLERID)) { 07721 iaxs[callno]->calling_tns = 0; 07722 iaxs[callno]->calling_ton = 0; 07723 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 07724 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 07725 ast_string_field_set(iaxs[callno], ani, user->cid_num); 07726 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 07727 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 07728 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 07729 } /* else user is allowed to set their own CID settings */ 07730 if (!ast_strlen_zero(user->accountcode)) 07731 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 07732 if (!ast_strlen_zero(user->mohinterpret)) 07733 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 07734 if (!ast_strlen_zero(user->mohsuggest)) 07735 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 07736 if (!ast_strlen_zero(user->parkinglot)) 07737 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot); 07738 if (user->amaflags) 07739 iaxs[callno]->amaflags = user->amaflags; 07740 if (!ast_strlen_zero(user->language)) 07741 ast_string_field_set(iaxs[callno], language, user->language); 07742 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 07743 /* Keep this check last */ 07744 if (!ast_strlen_zero(user->dbsecret)) { 07745 char *family, *key=NULL; 07746 char buf[80]; 07747 family = ast_strdupa(user->dbsecret); 07748 key = strchr(family, '/'); 07749 if (key) { 07750 *key = '\0'; 07751 key++; 07752 } 07753 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 07754 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 07755 else 07756 ast_string_field_set(iaxs[callno], secret, buf); 07757 } else 07758 ast_string_field_set(iaxs[callno], secret, user->secret); 07759 res = 0; 07760 user = user_unref(user); 07761 } else { 07762 /* user was not found, but we should still fake an AUTHREQ. 07763 * Set authmethods to the last known authmethod used by the system 07764 * Set a fake secret, it's not looked at, just required to attempt authentication. 07765 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 07766 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 07767 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07768 iaxs[callno]->authrej = 1; 07769 if (!ast_strlen_zero(iaxs[callno]->username)) { 07770 /* only send the AUTHREQ if a username was specified. */ 07771 res = 0; 07772 } 07773 } 07774 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 07775 return res; 07776 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 9424 of file chan_iax2.c.
References ast_debug, iax2_provision(), and iax_provision_version().
Referenced by socket_process().
09425 { 09426 unsigned int ourver; 09427 char rsi[80]; 09428 snprintf(rsi, sizeof(rsi), "si-%s", si); 09429 if (iax_provision_version(&ourver, rsi, 1)) 09430 return 0; 09431 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 09432 if (ourver != ver) 09433 iax2_provision(sin, sockfd, NULL, rsi, 1); 09434 return 0; 09435 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 12275 of file chan_iax2.c.
References ast_debug, ast_log(), errno, and LOG_ERROR.
Referenced by peer_set_srcaddr().
12276 { 12277 int sd; 12278 int res; 12279 12280 sd = socket(AF_INET, SOCK_DGRAM, 0); 12281 if (sd < 0) { 12282 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 12283 return -1; 12284 } 12285 12286 res = bind(sd, sa, salen); 12287 if (res < 0) { 12288 ast_debug(1, "Can't bind: %s\n", strerror(errno)); 12289 close(sd); 12290 return 1; 12291 } 12292 12293 close(sd); 12294 return 0; 12295 }
static void cleanup_thread_list | ( | void * | head | ) | [static] |
Definition at line 14327 of file chan_iax2.c.
References AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, iax2_thread::list, signal_condition(), and thread.
Referenced by __unload_module().
14328 { 14329 AST_LIST_HEAD(iax2_thread_list, iax2_thread); 14330 struct iax2_thread_list *list_head = head; 14331 struct iax2_thread *thread; 14332 14333 AST_LIST_LOCK(list_head); 14334 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) { 14335 pthread_t thread_id = thread->threadid; 14336 14337 thread->stop = 1; 14338 signal_condition(&thread->lock, &thread->cond); 14339 14340 AST_LIST_UNLOCK(list_head); 14341 pthread_join(thread_id, NULL); 14342 AST_LIST_LOCK(list_head); 14343 } 14344 AST_LIST_UNLOCK(list_head); 14345 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 8340 of file chan_iax2.c.
References ARRAY_LEN, ast_copy_string(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_UNKNOWN, iax_ies::called_number, iax2_dpcache::callno, iax_ies::dpstatus, iax2_dpcache::expiry, iax2_dpcache::exten, exten, iax2_dpcache::flags, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, matchmore(), iax2_dpcache::orig, iax2_dpcache::peer_list, iax_ies::refresh, status, and iax2_dpcache::waiters.
Referenced by socket_process().
08341 { 08342 char exten[256] = ""; 08343 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0; 08344 struct iax2_dpcache *dp = NULL; 08345 08346 if (ies->called_number) 08347 ast_copy_string(exten, ies->called_number, sizeof(exten)); 08348 08349 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 08350 status = CACHE_FLAG_EXISTS; 08351 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 08352 status = CACHE_FLAG_CANEXIST; 08353 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 08354 status = CACHE_FLAG_NONEXISTENT; 08355 08356 if (ies->refresh) 08357 expiry = ies->refresh; 08358 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 08359 matchmore = CACHE_FLAG_MATCHMORE; 08360 08361 AST_LIST_LOCK(&dpcache); 08362 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) { 08363 if (strcmp(dp->exten, exten)) 08364 continue; 08365 AST_LIST_REMOVE_CURRENT(peer_list); 08366 dp->callno = 0; 08367 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 08368 if (dp->flags & CACHE_FLAG_PENDING) { 08369 dp->flags &= ~CACHE_FLAG_PENDING; 08370 dp->flags |= status; 08371 dp->flags |= matchmore; 08372 } 08373 /* Wake up waiters */ 08374 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 08375 if (dp->waiters[x] > -1) { 08376 if (write(dp->waiters[x], "asdf", 4) < 0) { 08377 } 08378 } 08379 } 08380 } 08381 AST_LIST_TRAVERSE_SAFE_END; 08382 AST_LIST_UNLOCK(&dpcache); 08383 08384 return 0; 08385 }
static char * complete_iax2_peers | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state, | |||
uint64_t | flags | |||
) | [static] |
Definition at line 3833 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, ast_test_flag64, iax2_peer::name, peer_unref(), and peers.
Referenced by handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), and handle_cli_iax2_show_peer().
03834 { 03835 int which = 0; 03836 struct iax2_peer *peer; 03837 char *res = NULL; 03838 int wordlen = strlen(word); 03839 struct ao2_iterator i; 03840 03841 i = ao2_iterator_init(peers, 0); 03842 while ((peer = ao2_iterator_next(&i))) { 03843 if (!strncasecmp(peer->name, word, wordlen) && ++which > state 03844 && (!flags || ast_test_flag64(peer, flags))) { 03845 res = ast_strdup(peer->name); 03846 peer_unref(peer); 03847 break; 03848 } 03849 peer_unref(peer); 03850 } 03851 ao2_iterator_destroy(&i); 03852 03853 return res; 03854 }
static char * complete_iax2_unregister | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 6903 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, iax2_peer::expire, iax2_peer::name, peer_unref(), and peers.
Referenced by handle_cli_iax2_unregister().
06904 { 06905 int which = 0; 06906 struct iax2_peer *p = NULL; 06907 char *res = NULL; 06908 int wordlen = strlen(word); 06909 06910 /* 0 - iax2; 1 - unregister; 2 - <peername> */ 06911 if (pos == 2) { 06912 struct ao2_iterator i = ao2_iterator_init(peers, 0); 06913 while ((p = ao2_iterator_next(&i))) { 06914 if (!strncasecmp(p->name, word, wordlen) && 06915 ++which > state && p->expire > 0) { 06916 res = ast_strdup(p->name); 06917 peer_unref(p); 06918 break; 06919 } 06920 peer_unref(p); 06921 } 06922 ao2_iterator_destroy(&i); 06923 } 06924 06925 return res; 06926 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 8387 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, AST_LIST_TRAVERSE, ast_log(), iax_ies::callno, jb_frame::data, DEFAULT_RETRY_TIME, frame_queue, iax2_frame_free(), iaxs, chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), JB_OK, jb_reset(), chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::lastsent, iax_frame::list, LOG_WARNING, chan_iax2_pvt::nextpred, chan_iax2_pvt::offset, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), chan_iax2_pvt::pingtime, remove_by_peercallno(), remove_by_transfercallno(), iax_frame::retries, chan_iax2_pvt::rseqno, chan_iax2_pvt::rxcore, store_by_peercallno(), chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, TRANSFER_NONE, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, chan_iax2_pvt::videoformat, and chan_iax2_pvt::voiceformat.
Referenced by socket_process().
08388 { 08389 int peercallno = 0; 08390 struct chan_iax2_pvt *pvt = iaxs[callno]; 08391 struct iax_frame *cur; 08392 jb_frame frame; 08393 08394 if (ies->callno) 08395 peercallno = ies->callno; 08396 08397 if (peercallno < 1) { 08398 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08399 return -1; 08400 } 08401 remove_by_transfercallno(pvt); 08402 /* since a transfer has taken place, the address will change. 08403 * This must be accounted for in the peercnts table. Remove 08404 * the old address and add the new one */ 08405 peercnt_remove_by_addr(&pvt->addr); 08406 peercnt_add(&pvt->transfer); 08407 /* now copy over the new address */ 08408 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 08409 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 08410 /* Reset sequence numbers */ 08411 pvt->oseqno = 0; 08412 pvt->rseqno = 0; 08413 pvt->iseqno = 0; 08414 pvt->aseqno = 0; 08415 08416 if (pvt->peercallno) { 08417 remove_by_peercallno(pvt); 08418 } 08419 pvt->peercallno = peercallno; 08420 /*this is where the transfering call swiches hash tables */ 08421 store_by_peercallno(pvt); 08422 pvt->transferring = TRANSFER_NONE; 08423 pvt->svoiceformat = -1; 08424 pvt->voiceformat = 0; 08425 pvt->svideoformat = -1; 08426 pvt->videoformat = 0; 08427 pvt->transfercallno = 0; 08428 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 08429 memset(&pvt->offset, 0, sizeof(pvt->offset)); 08430 /* reset jitterbuffer */ 08431 while(jb_getall(pvt->jb,&frame) == JB_OK) 08432 iax2_frame_free(frame.data); 08433 jb_reset(pvt->jb); 08434 pvt->lag = 0; 08435 pvt->last = 0; 08436 pvt->lastsent = 0; 08437 pvt->nextpred = 0; 08438 pvt->pingtime = DEFAULT_RETRY_TIME; 08439 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) { 08440 /* We must cancel any packets that would have been transmitted 08441 because now we're talking to someone new. It's okay, they 08442 were transmitted to someone that didn't care anyway. */ 08443 cur->retries = -1; 08444 } 08445 return 0; 08446 }
static unsigned char compress_subclass | ( | format_t | subclass | ) | [static] |
Definition at line 1608 of file chan_iax2.c.
References ast_log(), IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.
Referenced by iax2_send(), raw_hangup(), and send_apathetic_reply().
01609 { 01610 int x; 01611 int power=-1; 01612 /* If it's 64 or smaller, just return it */ 01613 if (subclass < IAX_FLAG_SC_LOG) 01614 return subclass; 01615 /* Otherwise find its power */ 01616 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01617 if (subclass & (1LL << x)) { 01618 if (power > -1) { 01619 ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass); 01620 return 0; 01621 } else 01622 power = x; 01623 } 01624 } 01625 return power | IAX_FLAG_SC_LOG; 01626 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 9437 of file chan_iax2.c.
References jb_info::current, jb_info::frames_dropped, jb_info::frames_in, jb_info::frames_lost, jb_info::frames_ooo, iax_ie_append_int(), iax_ie_append_short(), IAX_IE_RR_DELAY, IAX_IE_RR_DROPPED, IAX_IE_RR_JITTER, IAX_IE_RR_LOSS, IAX_IE_RR_OOO, IAX_IE_RR_PKTS, chan_iax2_pvt::jb, jb_getinfo(), jb_info::jitter, jb_info::losspct, and jb_info::min.
Referenced by socket_process().
09438 { 09439 jb_info stats; 09440 jb_getinfo(pvt->jb, &stats); 09441 09442 memset(iep, 0, sizeof(*iep)); 09443 09444 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 09445 if(stats.frames_in == 0) stats.frames_in = 1; 09446 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 09447 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 09448 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 09449 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 09450 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 09451 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 4572 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ast_clear_flag64, ast_codec_pref_convert(), ast_codec_pref_prepend(), ast_copy_flags64, ast_copy_string(), ast_db_get(), ast_debug, ast_get_ip_or_srv(), ast_log(), ast_sockaddr_to_sin, ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, iax2_peer::cid_name, create_addr_info::cid_name, iax2_peer::cid_num, create_addr_info::cid_num, iax2_peer::context, create_addr_info::context, iax2_peer::dbsecret, iax2_peer::defaddr, iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, IAX_DEFAULT_PORTNO, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, iax2_peer::mohinterpret, create_addr_info::mohinterpret, iax2_peer::mohsuggest, create_addr_info::mohsuggest, ast_channel::nativeformats, iax2_peer::outkey, create_addr_info::outkey, peer_unref(), iax2_peer::peercontext, create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, iax2_peer::secret, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, ast_sockaddr::ss, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag.
04573 { 04574 struct iax2_peer *peer; 04575 int res = -1; 04576 struct ast_codec_pref ourprefs; 04577 struct sockaddr_in peer_addr; 04578 04579 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK); 04580 cai->sockfd = defaultsockfd; 04581 cai->maxtime = 0; 04582 sin->sin_family = AF_INET; 04583 04584 if (!(peer = find_peer(peername, 1))) { 04585 struct ast_sockaddr sin_tmp; 04586 04587 cai->found = 0; 04588 sin_tmp.ss.ss_family = AF_INET; 04589 if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) { 04590 ast_log(LOG_WARNING, "No such host: %s\n", peername); 04591 return -1; 04592 } 04593 ast_sockaddr_to_sin(&sin_tmp, sin); 04594 if (sin->sin_port == 0) { 04595 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 04596 } 04597 /* use global iax prefs for unknown peer/user */ 04598 /* But move the calling channel's native codec to the top of the preference list */ 04599 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 04600 if (c) 04601 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04602 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04603 return 0; 04604 } 04605 04606 cai->found = 1; 04607 04608 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 04609 04610 /* if the peer has no address (current or default), return failure */ 04611 if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) { 04612 goto return_unref; 04613 } 04614 04615 /* if the peer is being monitored and is currently unreachable, return failure */ 04616 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 04617 goto return_unref; 04618 04619 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 04620 cai->maxtime = peer->maxms; 04621 cai->capability = peer->capability; 04622 cai->encmethods = peer->encmethods; 04623 cai->sockfd = peer->sockfd; 04624 cai->adsi = peer->adsi; 04625 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 04626 /* Move the calling channel's native codec to the top of the preference list */ 04627 if (c) { 04628 ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats); 04629 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04630 } 04631 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04632 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 04633 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 04634 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 04635 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 04636 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 04637 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num)); 04638 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name)); 04639 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 04640 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 04641 if (ast_strlen_zero(peer->dbsecret)) { 04642 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 04643 } else { 04644 char *family; 04645 char *key = NULL; 04646 04647 family = ast_strdupa(peer->dbsecret); 04648 key = strchr(family, '/'); 04649 if (key) 04650 *key++ = '\0'; 04651 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 04652 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 04653 goto return_unref; 04654 } 04655 } 04656 04657 if (peer_addr.sin_addr.s_addr) { 04658 sin->sin_addr = peer_addr.sin_addr; 04659 sin->sin_port = peer_addr.sin_port; 04660 } else { 04661 sin->sin_addr = peer->defaddr.sin_addr; 04662 sin->sin_port = peer->defaddr.sin_port; 04663 } 04664 04665 res = 0; 04666 04667 return_unref: 04668 peer_unref(peer); 04669 04670 return res; 04671 }
static int create_callno_pools | ( | void | ) | [static] |
Definition at line 2687 of file chan_iax2.c.
References ao2_alloc, ao2_container_alloc, ao2_link, ao2_ref, and callno_hash().
Referenced by load_objects().
02688 { 02689 uint16_t i; 02690 02691 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02692 return -1; 02693 } 02694 02695 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02696 return -1; 02697 } 02698 02699 /* start at 2, 0 and 1 are reserved */ 02700 for (i = 2; i <= IAX_MAX_CALLS; i++) { 02701 struct callno_entry *callno_entry; 02702 02703 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) { 02704 return -1; 02705 } 02706 02707 callno_entry->callno = i; 02708 02709 if (i < TRUNK_CALL_START) { 02710 ao2_link(callno_pool, callno_entry); 02711 } else { 02712 ao2_link(callno_pool_trunk, callno_entry); 02713 } 02714 02715 ao2_ref(callno_entry, -1); 02716 } 02717 02718 return 0; 02719 }
static int decode_frame | ( | ast_aes_decrypt_key * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 6255 of file chan_iax2.c.
References ast_debug, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, f, IAX_FLAG_FULL, memcpy_decrypt(), ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::type, and uncompress_subclass().
Referenced by decrypt_frame(), and update_packet().
06256 { 06257 int padding; 06258 unsigned char *workspace; 06259 06260 workspace = alloca(*datalen); 06261 memset(f, 0, sizeof(*f)); 06262 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06263 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06264 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 06265 return -1; 06266 /* Decrypt */ 06267 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 06268 06269 padding = 16 + (workspace[15] & 0x0f); 06270 if (iaxdebug) 06271 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 06272 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 06273 return -1; 06274 06275 *datalen -= padding; 06276 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06277 f->frametype = fh->type; 06278 if (f->frametype == AST_FRAME_VIDEO) { 06279 f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06280 } else if (f->frametype == AST_FRAME_VOICE) { 06281 f->subclass.codec = uncompress_subclass(fh->csub); 06282 } else { 06283 f->subclass.integer = uncompress_subclass(fh->csub); 06284 } 06285 } else { 06286 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06287 if (iaxdebug) 06288 ast_debug(1, "Decoding mini with length %d\n", *datalen); 06289 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 06290 return -1; 06291 /* Decrypt */ 06292 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 06293 padding = 16 + (workspace[15] & 0x0f); 06294 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 06295 return -1; 06296 *datalen -= padding; 06297 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06298 } 06299 return 0; 06300 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 6343 of file chan_iax2.c.
References ast_set_flag64, ast_strdupa, ast_test_flag64, build_encryption_keys(), decode_frame(), f, IAX_KEYPOPULATED, iaxs, md5(), MD5Final(), MD5Init(), MD5Update(), secret, and strsep().
Referenced by socket_process().
06344 { 06345 int res=-1; 06346 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) { 06347 /* Search for possible keys, given secrets */ 06348 struct MD5Context md5; 06349 unsigned char digest[16]; 06350 char *tmppw, *stringp; 06351 06352 tmppw = ast_strdupa(iaxs[callno]->secret); 06353 stringp = tmppw; 06354 while ((tmppw = strsep(&stringp, ";"))) { 06355 MD5Init(&md5); 06356 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 06357 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 06358 MD5Final(digest, &md5); 06359 build_encryption_keys(digest, iaxs[callno]); 06360 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06361 if (!res) { 06362 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED); 06363 break; 06364 } 06365 } 06366 } else 06367 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06368 return res; 06369 }
static void defer_full_frame | ( | struct iax2_thread * | from_here, | |
struct iax2_thread * | to_here | |||
) | [static] |
Queue the last read full frame for processing by a certain thread.
If there are already any full frames queued, they are sorted by sequence number.
Definition at line 9584 of file chan_iax2.c.
References ast_calloc, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock, ast_mutex_unlock, iax2_pkt_buf::buf, iax2_thread::buf, iax2_thread::buf_len, iax2_thread::full_frames, iax2_thread::lock, and ast_iax2_full_hdr::oseqno.
Referenced by socket_read().
09585 { 09586 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 09587 struct ast_iax2_full_hdr *fh, *cur_fh; 09588 09589 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 09590 return; 09591 09592 pkt_buf->len = from_here->buf_len; 09593 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 09594 09595 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 09596 ast_mutex_lock(&to_here->lock); 09597 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 09598 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 09599 if (fh->oseqno < cur_fh->oseqno) { 09600 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry); 09601 break; 09602 } 09603 } 09604 AST_LIST_TRAVERSE_SAFE_END 09605 09606 if (!cur_pkt_buf) 09607 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 09608 09609 ast_mutex_unlock(&to_here->lock); 09610 }
static void delete_users | ( | void | ) | [static] |
Definition at line 12964 of file chan_iax2.c.
References ao2_callback, ast_dnsmgr_release(), ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_del, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::entry, iax2_registry::expire, iax2_destroy(), iaxs, iaxsl, peer_delme_cb(), peers, chan_iax2_pvt::reg, sched, user_delme_cb(), and users.
12965 { 12966 struct iax2_registry *reg; 12967 12968 ao2_callback(users, 0, user_delme_cb, NULL); 12969 12970 AST_LIST_LOCK(®istrations); 12971 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 12972 if (sched) { 12973 ast_sched_thread_del(sched, reg->expire); 12974 } 12975 if (reg->callno) { 12976 int callno = reg->callno; 12977 ast_mutex_lock(&iaxsl[callno]); 12978 if (iaxs[callno]) { 12979 iaxs[callno]->reg = NULL; 12980 iax2_destroy(callno); 12981 } 12982 ast_mutex_unlock(&iaxsl[callno]); 12983 } 12984 if (reg->dnsmgr) 12985 ast_dnsmgr_release(reg->dnsmgr); 12986 ast_free(reg); 12987 } 12988 AST_LIST_UNLOCK(®istrations); 12989 12990 ao2_callback(peers, 0, peer_delme_cb, NULL); 12991 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 3017 of file chan_iax2.c.
References ast_free, ast_iax2_firmware_header::datalen, iax_firmware::fd, and iax_firmware::fwh.
Referenced by reload_firmware().
03018 { 03019 /* Close firmware */ 03020 if (cur->fwh) { 03021 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 03022 } 03023 close(cur->fd); 03024 ast_free(cur); 03025 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 9239 of file chan_iax2.c.
References ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_IAX, ast_ignore_pattern(), ast_matchmore_extension(), ast_mutex_lock, ast_mutex_unlock, ast_parking_ext_valid(), IAX_COMMAND_DPREP, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_NUMBER, IAX_IE_DPSTATUS, IAX_IE_REFRESH, iaxs, iaxsl, and send_command().
Referenced by dp_lookup_thread(), and socket_process().
09240 { 09241 unsigned short dpstatus = 0; 09242 struct iax_ie_data ied1; 09243 int mm; 09244 09245 memset(&ied1, 0, sizeof(ied1)); 09246 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 09247 /* Must be started */ 09248 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 09249 dpstatus = IAX_DPSTATUS_EXISTS; 09250 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 09251 dpstatus = IAX_DPSTATUS_CANEXIST; 09252 } else { 09253 dpstatus = IAX_DPSTATUS_NONEXISTENT; 09254 } 09255 if (ast_ignore_pattern(context, callednum)) 09256 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 09257 if (mm) 09258 dpstatus |= IAX_DPSTATUS_MATCHMORE; 09259 if (!skiplock) 09260 ast_mutex_lock(&iaxsl[callno]); 09261 if (iaxs[callno]) { 09262 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 09263 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 09264 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 09265 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 09266 } 09267 if (!skiplock) 09268 ast_mutex_unlock(&iaxsl[callno]); 09269 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 9271 of file chan_iax2.c.
References ast_free, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, and dp_lookup().
Referenced by spawn_dp_lookup().
09272 { 09273 /* Look up for dpreq */ 09274 struct dpreq_data *dpr = data; 09275 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 09276 if (dpr->callerid) 09277 ast_free(dpr->callerid); 09278 ast_free(dpr); 09279 return NULL; 09280 }
static void encmethods_to_str | ( | int | e, | |
struct ast_str * | buf | |||
) | [static] |
Definition at line 1542 of file chan_iax2.c.
References ast_str_append(), ast_str_set(), ast_str_strlen(), iax2_thread::buf, IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.
Referenced by __iax2_show_peers(), handle_cli_iax2_show_peer(), manager_iax2_show_peer_list(), and peers_data_provider_get().
01543 { 01544 ast_str_set(&buf, 0, "("); 01545 if (e & IAX_ENCRYPT_AES128) { 01546 ast_str_append(&buf, 0, "aes128"); 01547 } 01548 if (e & IAX_ENCRYPT_KEYROTATE) { 01549 ast_str_append(&buf, 0, ",keyrotate"); 01550 } 01551 if (ast_str_strlen(buf) > 1) { 01552 ast_str_append(&buf, 0, ")"); 01553 } else { 01554 ast_str_set(&buf, 0, "No"); 01555 } 01556 }
static int encrypt_frame | ( | ast_aes_encrypt_key * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 6302 of file chan_iax2.c.
References ast_debug, ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, IAX_FLAG_FULL, memcpy_encrypt(), ast_iax2_full_hdr::scallno, and ast_iax2_full_hdr::type.
Referenced by iax2_send(), and update_packet().
06303 { 06304 int padding; 06305 unsigned char *workspace; 06306 workspace = alloca(*datalen + 32); 06307 if (!workspace) 06308 return -1; 06309 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06310 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06311 if (iaxdebug) 06312 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 06313 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 06314 padding = 16 + (padding & 0xf); 06315 memcpy(workspace, poo, padding); 06316 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06317 workspace[15] &= 0xf0; 06318 workspace[15] |= (padding & 0xf); 06319 if (iaxdebug) 06320 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]); 06321 *datalen += padding; 06322 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 06323 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 06324 memcpy(poo, workspace + *datalen - 32, 32); 06325 } else { 06326 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06327 if (iaxdebug) 06328 ast_debug(1, "Encoding mini frame with length %d\n", *datalen); 06329 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 06330 padding = 16 + (padding & 0xf); 06331 memcpy(workspace, poo, padding); 06332 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06333 workspace[15] &= 0xf0; 06334 workspace[15] |= (padding & 0x0f); 06335 *datalen += padding; 06336 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 06337 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 06338 memcpy(poo, workspace + *datalen - 32, 32); 06339 } 06340 return 0; 06341 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8655 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by handle_cli_iax2_prune_realtime(), handle_cli_iax2_unregister(), reg_source_db(), and update_registry().
08656 { 08657 #ifdef SCHED_MULTITHREADED 08658 if (schedule_action(__expire_registry, data)) 08659 #endif 08660 __expire_registry(data); 08661 return 0; 08662 }
static struct iax2_dpcache* find_cache | ( | struct ast_channel * | chan, | |
const char * | data, | |||
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) | [static] |
Definition at line 13664 of file chan_iax2.c.
References ARRAY_LEN, ast_calloc, ast_channel_defer_dtmf(), ast_channel_undefer_dtmf(), ast_copy_string(), ast_free, ast_frfree, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_mutex_unlock, ast_read(), ast_test_flag, ast_tvcmp(), ast_tvnow(), ast_waitfor_nandfds(), CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, cache_get_callno_locked(), iax2_dpcache::callno, errno, iax2_dpcache::expiry, iax2_dpcache::exten, f, iax2_dpcache::flags, iax2_dprequest(), IAX_STATE_STARTED, iaxs, iaxsl, LOG_WARNING, iax2_dpcache::orig, iax2_dpcache::peercontext, state, and iax2_dpcache::waiters.
Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore().
13665 { 13666 struct iax2_dpcache *dp = NULL; 13667 struct timeval now = ast_tvnow(); 13668 int x, com[2], timeout, old = 0, outfd, doabort, callno; 13669 struct ast_channel *c = NULL; 13670 struct ast_frame *f = NULL; 13671 13672 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) { 13673 if (ast_tvcmp(now, dp->expiry) > 0) { 13674 AST_LIST_REMOVE_CURRENT(cache_list); 13675 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno) 13676 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno); 13677 else 13678 ast_free(dp); 13679 continue; 13680 } 13681 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 13682 break; 13683 } 13684 AST_LIST_TRAVERSE_SAFE_END; 13685 13686 if (!dp) { 13687 /* No matching entry. Create a new one. */ 13688 /* First, can we make a callno? */ 13689 if ((callno = cache_get_callno_locked(data)) < 0) { 13690 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 13691 return NULL; 13692 } 13693 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 13694 ast_mutex_unlock(&iaxsl[callno]); 13695 return NULL; 13696 } 13697 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 13698 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 13699 dp->expiry = ast_tvnow(); 13700 dp->orig = dp->expiry; 13701 /* Expires in 30 mins by default */ 13702 dp->expiry.tv_sec += iaxdefaultdpcache; 13703 dp->flags = CACHE_FLAG_PENDING; 13704 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) 13705 dp->waiters[x] = -1; 13706 /* Insert into the lists */ 13707 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list); 13708 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list); 13709 /* Send the request if we're already up */ 13710 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 13711 iax2_dprequest(dp, callno); 13712 ast_mutex_unlock(&iaxsl[callno]); 13713 } 13714 13715 /* By here we must have a dp */ 13716 if (dp->flags & CACHE_FLAG_PENDING) { 13717 /* Okay, here it starts to get nasty. We need a pipe now to wait 13718 for a reply to come back so long as it's pending */ 13719 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13720 /* Find an empty slot */ 13721 if (dp->waiters[x] < 0) 13722 break; 13723 } 13724 if (x >= ARRAY_LEN(dp->waiters)) { 13725 ast_log(LOG_WARNING, "No more waiter positions available\n"); 13726 return NULL; 13727 } 13728 if (pipe(com)) { 13729 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 13730 return NULL; 13731 } 13732 dp->waiters[x] = com[1]; 13733 /* Okay, now we wait */ 13734 timeout = iaxdefaulttimeout * 1000; 13735 /* Temporarily unlock */ 13736 AST_LIST_UNLOCK(&dpcache); 13737 /* Defer any dtmf */ 13738 if (chan) 13739 old = ast_channel_defer_dtmf(chan); 13740 doabort = 0; 13741 while(timeout) { 13742 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 13743 if (outfd > -1) 13744 break; 13745 if (!c) 13746 continue; 13747 if (!(f = ast_read(c))) { 13748 doabort = 1; 13749 break; 13750 } 13751 ast_frfree(f); 13752 } 13753 if (!timeout) { 13754 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 13755 } 13756 AST_LIST_LOCK(&dpcache); 13757 dp->waiters[x] = -1; 13758 close(com[1]); 13759 close(com[0]); 13760 if (doabort) { 13761 /* Don't interpret anything, just abort. Not sure what th epoint 13762 of undeferring dtmf on a hung up channel is but hey whatever */ 13763 if (!old && chan) 13764 ast_channel_undefer_dtmf(chan); 13765 return NULL; 13766 } 13767 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 13768 /* Now to do non-independent analysis the results of our wait */ 13769 if (dp->flags & CACHE_FLAG_PENDING) { 13770 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 13771 pending. Don't let it take as long to timeout. */ 13772 dp->flags &= ~CACHE_FLAG_PENDING; 13773 dp->flags |= CACHE_FLAG_TIMEOUT; 13774 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 13775 systems without leaving it unavailable once the server comes back online */ 13776 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 13777 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13778 if (dp->waiters[x] > -1) { 13779 if (write(dp->waiters[x], "asdf", 4) < 0) { 13780 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 13781 } 13782 } 13783 } 13784 } 13785 } 13786 /* Our caller will obtain the rest */ 13787 if (!old && chan) 13788 ast_channel_undefer_dtmf(chan); 13789 } 13790 return dp; 13791 }
static int find_callno | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | full_frame | |||
) | [static] |
Definition at line 2942 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
02942 { 02943 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 02944 }
static int find_callno_locked | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | full_frame | |||
) | [static] |
Definition at line 2946 of file chan_iax2.c.
References __find_callno().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_provision(), iax2_request(), and socket_process_meta().
02946 { 02947 02948 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 02949 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static] |
Definition at line 1394 of file chan_iax2.c.
References ast_atomic_fetchadd_int(), ast_calloc, ast_cond_destroy, ast_cond_init, ast_cond_wait, ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, iax2_process_thread(), IAX_THREAD_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxdynamicthreadnum, iaxmaxthreadcount, iax2_trunk_peer::list, and thread.
Referenced by __schedule_action(), and socket_read().
01395 { 01396 struct iax2_thread *thread = NULL; 01397 01398 /* Pop the head of the idle list off */ 01399 AST_LIST_LOCK(&idle_list); 01400 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 01401 AST_LIST_UNLOCK(&idle_list); 01402 01403 /* If we popped a thread off the idle list, just return it */ 01404 if (thread) { 01405 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01406 return thread; 01407 } 01408 01409 /* Pop the head of the dynamic list off */ 01410 AST_LIST_LOCK(&dynamic_list); 01411 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 01412 AST_LIST_UNLOCK(&dynamic_list); 01413 01414 /* If we popped a thread off the dynamic list, just return it */ 01415 if (thread) { 01416 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01417 return thread; 01418 } 01419 01420 /* If we can't create a new dynamic thread for any reason, return no thread at all */ 01421 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread)))) 01422 return NULL; 01423 01424 /* Set default values */ 01425 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1); 01426 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1); 01427 thread->type = IAX_THREAD_TYPE_DYNAMIC; 01428 01429 /* Initialize lock and condition */ 01430 ast_mutex_init(&thread->lock); 01431 ast_cond_init(&thread->cond, NULL); 01432 ast_mutex_init(&thread->init_lock); 01433 ast_cond_init(&thread->init_cond, NULL); 01434 ast_mutex_lock(&thread->init_lock); 01435 01436 /* Create thread and send it on it's way */ 01437 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 01438 ast_cond_destroy(&thread->cond); 01439 ast_mutex_destroy(&thread->lock); 01440 ast_mutex_unlock(&thread->init_lock); 01441 ast_cond_destroy(&thread->init_cond); 01442 ast_mutex_destroy(&thread->init_lock); 01443 ast_free(thread); 01444 return NULL; 01445 } 01446 01447 /* this thread is not processing a full frame (since it is idle), 01448 so ensure that the field for the full frame call number is empty */ 01449 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01450 01451 /* Wait for the thread to be ready before returning it to the caller */ 01452 ast_cond_wait(&thread->init_cond, &thread->init_lock); 01453 01454 /* Done with init_lock */ 01455 ast_mutex_unlock(&thread->init_lock); 01456 01457 return thread; 01458 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Definition at line 1686 of file chan_iax2.c.
References ao2_find, iax2_peer::name, OBJ_POINTER, peers, and realtime_peer().
01687 { 01688 struct iax2_peer *peer = NULL; 01689 struct iax2_peer tmp_peer = { 01690 .name = name, 01691 }; 01692 01693 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01694 01695 /* Now go for realtime if applicable */ 01696 if(!peer && realtime) 01697 peer = realtime_peer(name, NULL); 01698 01699 return peer; 01700 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static] |
Definition at line 6074 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_calloc, ast_debug, ast_inet_ntoa(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_init, ast_mutex_lock, ast_tvnow(), inaddrcmp(), iax2_trunk_peer::list, and iax2_trunk_peer::lock.
Referenced by iax2_trunk_queue(), and socket_process_meta().
06075 { 06076 struct iax2_trunk_peer *tpeer = NULL; 06077 06078 /* Finds and locks trunk peer */ 06079 AST_LIST_LOCK(&tpeers); 06080 06081 AST_LIST_TRAVERSE(&tpeers, tpeer, list) { 06082 if (!inaddrcmp(&tpeer->addr, sin)) { 06083 ast_mutex_lock(&tpeer->lock); 06084 break; 06085 } 06086 } 06087 06088 if (!tpeer) { 06089 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 06090 ast_mutex_init(&tpeer->lock); 06091 tpeer->lastsent = 9999; 06092 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 06093 tpeer->trunkact = ast_tvnow(); 06094 ast_mutex_lock(&tpeer->lock); 06095 tpeer->sockfd = fd; 06096 #ifdef SO_NO_CHECK 06097 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 06098 #endif 06099 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 06100 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list); 06101 } 06102 } 06103 06104 AST_LIST_UNLOCK(&tpeers); 06105 06106 return tpeer; 06107 }
static struct iax2_user* find_user | ( | const char * | name | ) | [static] |
Definition at line 1714 of file chan_iax2.c.
References ao2_find, iax2_user::name, OBJ_POINTER, and users.
01715 { 01716 struct iax2_user tmp_user = { 01717 .name = name, 01718 }; 01719 01720 return ao2_find(users, &tmp_user, OBJ_POINTER); 01721 }
static unsigned int fix_peerts | ( | struct timeval * | rxtrunktime, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 5887 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process_meta().
05888 { 05889 long ms; /* NOT unsigned */ 05890 if (ast_tvzero(iaxs[callno]->rxcore)) { 05891 /* Initialize rxcore time if appropriate */ 05892 iaxs[callno]->rxcore = ast_tvnow(); 05893 /* Round to nearest 20ms so traces look pretty */ 05894 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 05895 } 05896 /* Calculate difference between trunk and channel */ 05897 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore); 05898 /* Return as the sum of trunk time and the difference between trunk and real time */ 05899 return ms + ts; 05900 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 12106 of file chan_iax2.c.
References ast_free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
12107 { 12108 struct iax2_context *conl; 12109 while(con) { 12110 conl = con; 12111 con = con->next; 12112 ast_free(conl); 12113 } 12114 }
static void free_signaling_queue_entry | ( | struct signaling_queue_entry * | s | ) | [static] |
Definition at line 1820 of file chan_iax2.c.
References ast_free, ast_frame::data, ast_frame::datalen, signaling_queue_entry::f, and ast_frame::ptr.
Referenced by pvt_destructor(), queue_signalling(), and send_signaling().
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 13914 of file chan_iax2.c.
References iax2_peer::addr, ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_test_flag64, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::expire, find_peer(), iax2_tech, IAX_DYNAMIC, iaxs, iax2_peer::mailbox, peer_status(), peer_unref(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.
13915 { 13916 struct iax2_peer *peer; 13917 char *peername, *colname; 13918 13919 peername = ast_strdupa(data); 13920 13921 /* if our channel, return the IP address of the endpoint of current channel */ 13922 if (!strcmp(peername,"CURRENTCHANNEL")) { 13923 unsigned short callno; 13924 if (chan->tech != &iax2_tech) 13925 return -1; 13926 callno = PTR_TO_CALLNO(chan->tech_pvt); 13927 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 13928 return 0; 13929 } 13930 13931 if ((colname = strchr(peername, ','))) 13932 *colname++ = '\0'; 13933 else 13934 colname = "ip"; 13935 13936 if (!(peer = find_peer(peername, 1))) 13937 return -1; 13938 13939 if (!strcasecmp(colname, "ip")) { 13940 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len); 13941 } else if (!strcasecmp(colname, "status")) { 13942 peer_status(peer, buf, len); 13943 } else if (!strcasecmp(colname, "mailbox")) { 13944 ast_copy_string(buf, peer->mailbox, len); 13945 } else if (!strcasecmp(colname, "context")) { 13946 ast_copy_string(buf, peer->context, len); 13947 } else if (!strcasecmp(colname, "expire")) { 13948 snprintf(buf, len, "%d", peer->expire); 13949 } else if (!strcasecmp(colname, "dynamic")) { 13950 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 13951 } else if (!strcasecmp(colname, "callerid_name")) { 13952 ast_copy_string(buf, peer->cid_name, len); 13953 } else if (!strcasecmp(colname, "callerid_num")) { 13954 ast_copy_string(buf, peer->cid_num, len); 13955 } else if (!strcasecmp(colname, "codecs")) { 13956 ast_getformatname_multiple(buf, len -1, peer->capability); 13957 } else if (!strncasecmp(colname, "codec[", 6)) { 13958 char *codecnum, *ptr; 13959 int codec = 0; 13960 13961 /* skip over "codec" to the '[' */ 13962 codecnum = colname + 5; 13963 *codecnum = '\0'; 13964 codecnum++; 13965 if ((ptr = strchr(codecnum, ']'))) { 13966 *ptr = '\0'; 13967 } 13968 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) { 13969 ast_copy_string(buf, ast_getformatname(codec), len); 13970 } else { 13971 buf[0] = '\0'; 13972 } 13973 } else { 13974 buf[0] = '\0'; 13975 } 13976 13977 peer_unref(peer); 13978 13979 return 0; 13980 }
static int get_auth_methods | ( | const char * | value | ) | [static] |
Definition at line 12259 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
12260 { 12261 int methods = 0; 12262 if (strstr(value, "rsa")) 12263 methods |= IAX_AUTH_RSA; 12264 if (strstr(value, "md5")) 12265 methods |= IAX_AUTH_MD5; 12266 if (strstr(value, "plaintext")) 12267 methods |= IAX_AUTH_PLAINTEXT; 12268 return methods; 12269 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1558 of file chan_iax2.c.
References ast_true(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.
Referenced by build_peer(), build_user(), and set_config().
01559 { 01560 int e; 01561 if (!strcasecmp(s, "aes128")) 01562 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01563 else if (ast_true(s)) 01564 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01565 else 01566 e = 0; 01567 return e; 01568 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 4143 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
04144 { 04145 #ifdef SCHED_MULTITHREADED 04146 if (schedule_action(__get_from_jb, data)) 04147 #endif 04148 __get_from_jb(data); 04149 return 0; 04150 }
static struct callno_entry * get_unused_callno | ( | int | trunk, | |
int | validated | |||
) | [static] |
Definition at line 2620 of file chan_iax2.c.
References ao2_container_count(), ao2_find, ao2_lock, ao2_unlock, ast_log(), LOG_WARNING, OBJ_CONTINUE, OBJ_POINTER, OBJ_UNLINK, and callno_entry::validated.
Referenced by __find_callno(), and make_trunk().
02621 { 02622 struct callno_entry *callno_entry = NULL; 02623 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) { 02624 ast_log(LOG_WARNING, "Out of CallNumbers\n"); 02625 /* Minor optimization for the extreme case. */ 02626 return NULL; 02627 } 02628 02629 /* the callno_pool container is locked here primarily to ensure thread 02630 * safety of the total_nonval_callno_used check and increment */ 02631 ao2_lock(callno_pool); 02632 02633 /* only a certain number of nonvalidated call numbers should be allocated. 02634 * If there ever is an attack, this separates the calltoken validating 02635 * users from the non calltoken validating users. */ 02636 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) { 02637 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval); 02638 ao2_unlock(callno_pool); 02639 return NULL; 02640 } 02641 02642 /* unlink the object from the container, taking over ownership 02643 * of the reference the container had to the object */ 02644 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE); 02645 02646 if (callno_entry) { 02647 callno_entry->validated = validated; 02648 if (!validated) { 02649 total_nonval_callno_used++; 02650 } 02651 } 02652 02653 ao2_unlock(callno_pool); 02654 return callno_entry; 02655 }
static int handle_call_token | ( | struct ast_iax2_full_hdr * | fh, | |
struct iax_ies * | ies, | |||
struct sockaddr_in * | sin, | |||
int | fd | |||
) | [static] |
Definition at line 4883 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), ast_sha1_hash(), ast_str_alloca, ast_str_buffer(), ast_str_set(), iax_ie_data::buf, iax_ies::calltoken, CALLTOKEN_HASH_FORMAT, CALLTOKEN_IE_FORMAT, calltoken_required(), iax_ies::calltokendata, ast_iax2_full_hdr::csub, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, iax_ie_append_str(), IAX_IE_CALLTOKEN, ast_iax2_full_hdr::iseqno, LOG_ERROR, LOG_WARNING, requirecalltoken_mark_auto(), S_OR, ast_iax2_full_hdr::scallno, send_apathetic_reply(), ast_iax2_full_hdr::ts, uncompress_subclass(), and iax_ies::username.
Referenced by socket_process().
04885 { 04886 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d" /* address + port + ts + randomcalldata */ 04887 #define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */ 04888 struct ast_str *buf = ast_str_alloca(256); 04889 time_t t = time(NULL); 04890 char hash[41]; /* 40 char sha1 hash */ 04891 int subclass = uncompress_subclass(fh->csub); 04892 04893 /* ----- Case 1 ----- */ 04894 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */ 04895 struct iax_ie_data ied = { 04896 .buf = { 0 }, 04897 .pos = 0, 04898 }; 04899 04900 /* create the hash with their address data and our timestamp */ 04901 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata); 04902 ast_sha1_hash(hash, ast_str_buffer(buf)); 04903 04904 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash); 04905 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf)); 04906 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied); 04907 04908 return 1; 04909 04910 /* ----- Case 2 ----- */ 04911 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */ 04912 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */ 04913 char *rec_ts = NULL; /* received timestamp */ 04914 unsigned int rec_time; /* received time_t */ 04915 04916 /* split the timestamp from the hash data */ 04917 rec_hash = strchr((char *) ies->calltokendata, '?'); 04918 if (rec_hash) { 04919 *rec_hash++ = '\0'; 04920 rec_ts = (char *) ies->calltokendata; 04921 } 04922 04923 /* check that we have valid data before we do any comparisons */ 04924 if (!rec_hash || !rec_ts) { 04925 goto reject; 04926 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) { 04927 goto reject; 04928 } 04929 04930 /* create a hash with their address and the _TOKEN'S_ timestamp */ 04931 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata); 04932 ast_sha1_hash(hash, ast_str_buffer(buf)); 04933 04934 /* compare hashes and then check timestamp delay */ 04935 if (strcmp(hash, rec_hash)) { 04936 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr)); 04937 goto reject; /* received hash does not match ours, reject */ 04938 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) { 04939 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr)); 04940 goto reject; /* too much delay, reject */ 04941 } 04942 04943 /* at this point the call token is valid, returning 0 04944 * will allow socket_process to continue as usual */ 04945 requirecalltoken_mark_auto(ies->username, subclass); 04946 return 0; 04947 04948 /* ----- Case 3 ----- */ 04949 } else { /* calltokens are not supported for this client, how do we respond? */ 04950 if (calltoken_required(sin, ies->username, subclass)) { 04951 ast_log(LOG_ERROR, "Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenoptional list or setting user %s requirecalltoken=no\n", ast_inet_ntoa(sin->sin_addr), S_OR(ies->username, "guest")); 04952 goto reject; 04953 } 04954 return 0; /* calltoken is not required for this addr, so permit it. */ 04955 } 04956 04957 reject: 04958 /* received frame has failed calltoken inspection, send apathetic reject messages */ 04959 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) { 04960 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04961 } else { 04962 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04963 } 04964 04965 return 1; 04966 }
static char* handle_cli_iax2_provision | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 11953 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, iax2_provision(), iax_prov_complete_template(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
11954 { 11955 int force = 0; 11956 int res; 11957 11958 switch (cmd) { 11959 case CLI_INIT: 11960 e->command = "iax2 provision"; 11961 e->usage = 11962 "Usage: iax2 provision <host> <template> [forced]\n" 11963 " Provisions the given peer or IP address using a template\n" 11964 " matching either 'template' or '*' if the template is not\n" 11965 " found. If 'forced' is specified, even empty provisioning\n" 11966 " fields will be provisioned as empty fields.\n"; 11967 return NULL; 11968 case CLI_GENERATE: 11969 if (a->pos == 3) 11970 return iax_prov_complete_template(a->line, a->word, a->pos, a->n); 11971 return NULL; 11972 } 11973 11974 if (a->argc < 4) 11975 return CLI_SHOWUSAGE; 11976 if (a->argc > 4) { 11977 if (!strcasecmp(a->argv[4], "forced")) 11978 force = 1; 11979 else 11980 return CLI_SHOWUSAGE; 11981 } 11982 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force); 11983 if (res < 0) 11984 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]); 11985 else if (res < 1) 11986 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]); 11987 else 11988 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : ""); 11989 return CLI_SUCCESS; 11990 }
static char* handle_cli_iax2_prune_realtime | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3575 of file chan_iax2.c.
References ao2_unlink, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_complete(), ast_set_flag64, ast_test_flag64, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), expire_registry(), ast_cli_args::fd, find_peer(), find_user(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, ast_cli_args::line, ast_cli_args::n, peer_ref(), peer_unref(), ast_cli_args::pos, prune_peers(), prune_users(), ast_cli_entry::usage, user, user_unref(), users, and ast_cli_args::word.
03576 { 03577 struct iax2_peer *peer = NULL; 03578 struct iax2_user *user = NULL; 03579 static const char * const choices[] = { "all", NULL }; 03580 char *cmplt; 03581 03582 switch (cmd) { 03583 case CLI_INIT: 03584 e->command = "iax2 prune realtime"; 03585 e->usage = 03586 "Usage: iax2 prune realtime [<peername>|all]\n" 03587 " Prunes object(s) from the cache\n"; 03588 return NULL; 03589 case CLI_GENERATE: 03590 if (a->pos == 3) { 03591 cmplt = ast_cli_complete(a->word, choices, a->n); 03592 if (!cmplt) 03593 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS); 03594 return cmplt; 03595 } 03596 return NULL; 03597 } 03598 if (a->argc != 4) 03599 return CLI_SHOWUSAGE; 03600 if (!strcmp(a->argv[3], "all")) { 03601 prune_users(); 03602 prune_peers(); 03603 ast_cli(a->fd, "Cache flushed successfully.\n"); 03604 return CLI_SUCCESS; 03605 } 03606 peer = find_peer(a->argv[3], 0); 03607 user = find_user(a->argv[3]); 03608 if (peer || user) { 03609 if (peer) { 03610 if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 03611 ast_set_flag64(peer, IAX_RTAUTOCLEAR); 03612 expire_registry(peer_ref(peer)); 03613 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]); 03614 } else { 03615 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]); 03616 } 03617 peer_unref(peer); 03618 } 03619 if (user) { 03620 if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 03621 ast_set_flag64(user, IAX_RTAUTOCLEAR); 03622 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]); 03623 } else { 03624 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]); 03625 } 03626 ao2_unlink(users,user); 03627 user_unref(user); 03628 } 03629 } else { 03630 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]); 03631 } 03632 03633 return CLI_SUCCESS; 03634 }
static char* handle_cli_iax2_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 13568 of file chan_iax2.c.
References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, reload_config(), and ast_cli_entry::usage.
13569 { 13570 switch (cmd) { 13571 case CLI_INIT: 13572 e->command = "iax2 reload"; 13573 e->usage = 13574 "Usage: iax2 reload\n" 13575 " Reloads IAX configuration from iax.conf\n"; 13576 return NULL; 13577 case CLI_GENERATE: 13578 return NULL; 13579 } 13580 13581 reload_config(); 13582 13583 return CLI_SUCCESS; 13584 }
static char* handle_cli_iax2_set_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7347 of file chan_iax2.c.
References iax2_peer::addr, ao2_ref, ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_inet_ntoa(), ast_sockaddr_to_sin, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), debugaddr, ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
07348 { 07349 switch (cmd) { 07350 case CLI_INIT: 07351 e->command = "iax2 set debug {on|off|peer}"; 07352 e->usage = 07353 "Usage: iax2 set debug {on|off|peer peername}\n" 07354 " Enables/Disables dumping of IAX packets for debugging purposes.\n"; 07355 return NULL; 07356 case CLI_GENERATE: 07357 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) 07358 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 07359 return NULL; 07360 } 07361 07362 if (a->argc < e->args || a->argc > e->args + 1) 07363 return CLI_SHOWUSAGE; 07364 07365 if (!strcasecmp(a->argv[3], "peer")) { 07366 struct iax2_peer *peer; 07367 struct sockaddr_in peer_addr; 07368 07369 07370 if (a->argc != e->args + 1) 07371 return CLI_SHOWUSAGE; 07372 07373 peer = find_peer(a->argv[4], 1); 07374 07375 if (!peer) { 07376 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]); 07377 return CLI_FAILURE; 07378 } 07379 07380 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 07381 07382 debugaddr.sin_addr = peer_addr.sin_addr; 07383 debugaddr.sin_port = peer_addr.sin_port; 07384 07385 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n", 07386 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 07387 07388 ao2_ref(peer, -1); 07389 } else if (!strncasecmp(a->argv[3], "on", 2)) { 07390 iaxdebug = 1; 07391 ast_cli(a->fd, "IAX2 Debugging Enabled\n"); 07392 } else { 07393 iaxdebug = 0; 07394 memset(&debugaddr, 0, sizeof(debugaddr)); 07395 ast_cli(a->fd, "IAX2 Debugging Disabled\n"); 07396 } 07397 return CLI_SUCCESS; 07398 }
static char* handle_cli_iax2_set_debug_jb | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7426 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), and ast_cli_entry::usage.
07427 { 07428 switch (cmd) { 07429 case CLI_INIT: 07430 e->command = "iax2 set debug jb {on|off}"; 07431 e->usage = 07432 "Usage: iax2 set debug jb {on|off}\n" 07433 " Enables/Disables jitterbuffer debugging information\n"; 07434 return NULL; 07435 case CLI_GENERATE: 07436 return NULL; 07437 } 07438 07439 if (a->argc != e->args) 07440 return CLI_SHOWUSAGE; 07441 07442 if (!strncasecmp(a->argv[e->args -1], "on", 2)) { 07443 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 07444 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 07445 } else { 07446 jb_setoutput(jb_error_output, jb_warning_output, NULL); 07447 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 07448 } 07449 return CLI_SUCCESS; 07450 }
static char* handle_cli_iax2_set_debug_trunk | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7400 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
07401 { 07402 switch (cmd) { 07403 case CLI_INIT: 07404 e->command = "iax2 set debug trunk {on|off}"; 07405 e->usage = 07406 "Usage: iax2 set debug trunk {on|off}\n" 07407 " Enables/Disables debugging of IAX trunking\n"; 07408 return NULL; 07409 case CLI_GENERATE: 07410 return NULL; 07411 } 07412 07413 if (a->argc != e->args) 07414 return CLI_SHOWUSAGE; 07415 07416 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 07417 iaxtrunkdebug = 1; 07418 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n"); 07419 } else { 07420 iaxtrunkdebug = 0; 07421 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n"); 07422 } 07423 return CLI_SUCCESS; 07424 }
static char* handle_cli_iax2_set_mtu | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Set trunk MTU from CLI.
Definition at line 3902 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, MAX_TRUNK_MTU, and ast_cli_entry::usage.
03903 { 03904 int mtuv; 03905 03906 switch (cmd) { 03907 case CLI_INIT: 03908 e->command = "iax2 set mtu"; 03909 e->usage = 03910 "Usage: iax2 set mtu <value>\n" 03911 " Set the system-wide IAX IP mtu to <value> bytes net or\n" 03912 " zero to disable. Disabling means that the operating system\n" 03913 " must handle fragmentation of UDP packets when the IAX2 trunk\n" 03914 " packet exceeds the UDP payload size. This is substantially\n" 03915 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n" 03916 " greater for G.711 samples.\n"; 03917 return NULL; 03918 case CLI_GENERATE: 03919 return NULL; 03920 } 03921 03922 if (a->argc != 4) 03923 return CLI_SHOWUSAGE; 03924 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0) 03925 mtuv = MAX_TRUNK_MTU; 03926 else 03927 mtuv = atoi(a->argv[3]); 03928 03929 if (mtuv == 0) { 03930 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 03931 global_max_trunk_mtu = 0; 03932 return CLI_SUCCESS; 03933 } 03934 if (mtuv < 172 || mtuv > 4000) { 03935 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 03936 return CLI_SHOWUSAGE; 03937 } 03938 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 03939 global_max_trunk_mtu = mtuv; 03940 return CLI_SUCCESS; 03941 }
static char* handle_cli_iax2_show_cache | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3943 of file chan_iax2.c.
References ARRAY_LEN, ast_cli(), ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_tvnow(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, CACHE_FLAG_TRANSMITTED, CACHE_FLAG_UNKNOWN, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, iax2_dpcache::expiry, iax2_dpcache::exten, ast_cli_args::fd, iax2_dpcache::flags, iax2_dpcache::peercontext, ast_cli_entry::usage, and iax2_dpcache::waiters.
03944 { 03945 struct iax2_dpcache *dp = NULL; 03946 char tmp[1024], *pc = NULL; 03947 int s, x, y; 03948 struct timeval now = ast_tvnow(); 03949 03950 switch (cmd) { 03951 case CLI_INIT: 03952 e->command = "iax2 show cache"; 03953 e->usage = 03954 "Usage: iax2 show cache\n" 03955 " Display currently cached IAX Dialplan results.\n"; 03956 return NULL; 03957 case CLI_GENERATE: 03958 return NULL; 03959 } 03960 03961 AST_LIST_LOCK(&dpcache); 03962 03963 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 03964 03965 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) { 03966 s = dp->expiry.tv_sec - now.tv_sec; 03967 tmp[0] = '\0'; 03968 if (dp->flags & CACHE_FLAG_EXISTS) 03969 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 03970 if (dp->flags & CACHE_FLAG_NONEXISTENT) 03971 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 03972 if (dp->flags & CACHE_FLAG_CANEXIST) 03973 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 03974 if (dp->flags & CACHE_FLAG_PENDING) 03975 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 03976 if (dp->flags & CACHE_FLAG_TIMEOUT) 03977 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 03978 if (dp->flags & CACHE_FLAG_TRANSMITTED) 03979 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 03980 if (dp->flags & CACHE_FLAG_MATCHMORE) 03981 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 03982 if (dp->flags & CACHE_FLAG_UNKNOWN) 03983 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 03984 /* Trim trailing pipe */ 03985 if (!ast_strlen_zero(tmp)) { 03986 tmp[strlen(tmp) - 1] = '\0'; 03987 } else { 03988 ast_copy_string(tmp, "(none)", sizeof(tmp)); 03989 } 03990 y = 0; 03991 pc = strchr(dp->peercontext, '@'); 03992 if (!pc) { 03993 pc = dp->peercontext; 03994 } else { 03995 pc++; 03996 } 03997 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 03998 if (dp->waiters[x] > -1) 03999 y++; 04000 } 04001 if (s > 0) { 04002 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 04003 } else { 04004 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 04005 } 04006 } 04007 04008 AST_LIST_UNLOCK(&dpcache); 04009 04010 return CLI_SUCCESS; 04011 }
static char* handle_cli_iax2_show_callno_limits | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2555 of file chan_iax2.c.
References peercnt::addr, ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_inet_ntoa(), CLI_GENERATE, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, peercnt::cur, ast_cli_args::fd, peercnt::limit, peercnts, and ast_cli_entry::usage.
02556 { 02557 struct ao2_iterator i; 02558 struct peercnt *peercnt; 02559 struct sockaddr_in sin; 02560 int found = 0; 02561 02562 switch (cmd) { 02563 case CLI_INIT: 02564 e->command = "iax2 show callnumber usage"; 02565 e->usage = 02566 "Usage: iax2 show callnumber usage [IP address]\n" 02567 " Shows current IP addresses which are consuming iax2 call numbers\n"; 02568 return NULL; 02569 case CLI_GENERATE: 02570 return NULL; 02571 case CLI_HANDLER: 02572 if (a->argc < 4 || a->argc > 5) 02573 return CLI_SHOWUSAGE; 02574 02575 if (a->argc == 4) { 02576 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit"); 02577 } 02578 02579 i = ao2_iterator_init(peercnts, 0); 02580 while ((peercnt = ao2_iterator_next(&i))) { 02581 sin.sin_addr.s_addr = peercnt->addr; 02582 if (a->argc == 5) { 02583 if (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr))) { 02584 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit"); 02585 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02586 ao2_ref(peercnt, -1); 02587 found = 1; 02588 break; 02589 } 02590 } else { 02591 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02592 } 02593 ao2_ref(peercnt, -1); 02594 } 02595 ao2_iterator_destroy(&i); 02596 02597 if (a->argc == 4) { 02598 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n" 02599 "Non-CallToken Validated Callno Used: %d\n", 02600 global_maxcallno_nonval, 02601 total_nonval_callno_used); 02602 02603 ast_cli(a->fd, "Total Available Callno: %d\n" 02604 "Regular Callno Available: %d\n" 02605 "Trunk Callno Available: %d\n", 02606 ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk), 02607 ao2_container_count(callno_pool), 02608 ao2_container_count(callno_pool_trunk)); 02609 } else if (a->argc == 5 && !found) { 02610 ast_cli(a->fd, "No call number table entries for %s found\n", a->argv[4] ); 02611 } 02612 02613 02614 return CLI_SUCCESS; 02615 default: 02616 return NULL; 02617 } 02618 }
static char* handle_cli_iax2_show_channels | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7174 of file chan_iax2.c.
References ast_cli_args::argc, ARRAY_LEN, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, iax2_registry::callno, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, jb_info::current, iax_rr::delay, ast_cli_args::fd, FORMAT, FORMAT2, iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, MARK_IAX_SUBCLASS_TX, jb_info::min, ast_channel::name, chan_iax2_pvt::owner, chan_iax2_pvt::remote_rr, S_OR, and ast_cli_entry::usage.
07175 { 07176 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" 07177 #define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n" 07178 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 07179 int x; 07180 int numchans = 0; 07181 char first_message[10] = { 0, }; 07182 char last_message[10] = { 0, }; 07183 07184 switch (cmd) { 07185 case CLI_INIT: 07186 e->command = "iax2 show channels"; 07187 e->usage = 07188 "Usage: iax2 show channels\n" 07189 " Lists all currently active IAX channels.\n"; 07190 return NULL; 07191 case CLI_GENERATE: 07192 return NULL; 07193 } 07194 07195 if (a->argc != 3) 07196 return CLI_SHOWUSAGE; 07197 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg"); 07198 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07199 ast_mutex_lock(&iaxsl[x]); 07200 if (iaxs[x]) { 07201 int lag, jitter, localdelay; 07202 jb_info jbinfo; 07203 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07204 jb_getinfo(iaxs[x]->jb, &jbinfo); 07205 jitter = jbinfo.jitter; 07206 localdelay = jbinfo.current - jbinfo.min; 07207 } else { 07208 jitter = -1; 07209 localdelay = 0; 07210 } 07211 07212 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 07213 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 07214 lag = iaxs[x]->remote_rr.delay; 07215 ast_cli(a->fd, FORMAT, 07216 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07217 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 07218 S_OR(iaxs[x]->username, "(None)"), 07219 iaxs[x]->callno, iaxs[x]->peercallno, 07220 iaxs[x]->oseqno, iaxs[x]->iseqno, 07221 lag, 07222 jitter, 07223 localdelay, 07224 ast_getformatname(iaxs[x]->voiceformat), 07225 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07226 first_message, 07227 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07228 last_message); 07229 numchans++; 07230 } 07231 ast_mutex_unlock(&iaxsl[x]); 07232 } 07233 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 07234 return CLI_SUCCESS; 07235 #undef FORMAT 07236 #undef FORMAT2 07237 #undef FORMATB 07238 }
static char* handle_cli_iax2_show_firmware | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6960 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, ast_cli_args::fd, iax_firmware::fwh, iax_firmware::list, ast_cli_entry::usage, and ast_iax2_firmware_header::version.
06961 { 06962 struct iax_firmware *cur = NULL; 06963 06964 switch (cmd) { 06965 case CLI_INIT: 06966 e->command = "iax2 show firmware"; 06967 e->usage = 06968 "Usage: iax2 show firmware\n" 06969 " Lists all known IAX firmware images.\n"; 06970 return NULL; 06971 case CLI_GENERATE: 06972 return NULL; 06973 } 06974 06975 if (a->argc != 3 && a->argc != 4) 06976 return CLI_SHOWUSAGE; 06977 06978 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size"); 06979 AST_LIST_LOCK(&firmwares); 06980 AST_LIST_TRAVERSE(&firmwares, cur, list) { 06981 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) { 06982 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname, 06983 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen)); 06984 } 06985 } 06986 AST_LIST_UNLOCK(&firmwares); 06987 06988 return CLI_SUCCESS; 06989 }
static char* handle_cli_iax2_show_netstats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7324 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli(), ast_cli_netstats(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
07325 { 07326 int numchans = 0; 07327 07328 switch (cmd) { 07329 case CLI_INIT: 07330 e->command = "iax2 show netstats"; 07331 e->usage = 07332 "Usage: iax2 show netstats\n" 07333 " Lists network status for all currently active IAX channels.\n"; 07334 return NULL; 07335 case CLI_GENERATE: 07336 return NULL; 07337 } 07338 if (a->argc != 3) 07339 return CLI_SHOWUSAGE; 07340 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 07341 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n"); 07342 numchans = ast_cli_netstats(NULL, a->fd, 1); 07343 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 07344 return CLI_SUCCESS; 07345 }
static char* handle_cli_iax2_show_peer | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Show one peer in detail.
Definition at line 3750 of file chan_iax2.c.
References iax2_peer::addr, ast_cli_args::argc, ast_cli_args::argv, ast_callerid_merge(), ast_cli(), ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_sockaddr_to_sin, ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag64, CALLTOKEN_AUTO, iax2_peer::calltoken_required, CALLTOKEN_YES, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), iax2_peer::context, iax2_peer::defaddr, iax2_peer::encmethods, encmethods_to_str(), iax2_peer::expire, ast_cli_args::fd, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_TRUNK, ast_cli_args::line, iax2_peer::mailbox, iax2_peer::maxcallno, ast_cli_args::n, iax2_peer::name, iax2_peer::parkinglot, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, ast_cli_args::pos, iax2_peer::prefs, iax2_peer::secret, iax2_peer::smoothing, status, ast_cli_entry::usage, iax2_peer::username, and ast_cli_args::word.
03751 { 03752 char status[30]; 03753 char cbuf[256]; 03754 struct iax2_peer *peer; 03755 char codec_buf[512]; 03756 struct ast_str *encmethods = ast_str_alloca(256); 03757 int x = 0, codec = 0, load_realtime = 0; 03758 03759 switch (cmd) { 03760 case CLI_INIT: 03761 e->command = "iax2 show peer"; 03762 e->usage = 03763 "Usage: iax2 show peer <name>\n" 03764 " Display details on specific IAX peer\n"; 03765 return NULL; 03766 case CLI_GENERATE: 03767 if (a->pos == 3) 03768 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 03769 return NULL; 03770 } 03771 03772 if (a->argc < 4) 03773 return CLI_SHOWUSAGE; 03774 03775 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0; 03776 03777 peer = find_peer(a->argv[3], load_realtime); 03778 if (peer) { 03779 struct sockaddr_in peer_addr; 03780 03781 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 03782 03783 encmethods_to_str(peer->encmethods, encmethods); 03784 ast_cli(a->fd, "\n\n"); 03785 ast_cli(a->fd, " * Name : %s\n", peer->name); 03786 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>"); 03787 ast_cli(a->fd, " Context : %s\n", peer->context); 03788 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot); 03789 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox); 03790 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 03791 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno); 03792 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No")); 03793 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 03794 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 03795 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 03796 ast_cli(a->fd, " Expire : %d\n", peer->expire); 03797 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No")); 03798 ast_cli(a->fd, " Addr->IP : %s Port %d\n", peer_addr.sin_addr.s_addr ? ast_inet_ntoa(peer_addr.sin_addr) : "(Unspecified)", ntohs(peer_addr.sin_port)); 03799 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 03800 ast_cli(a->fd, " Username : %s\n", peer->username); 03801 ast_cli(a->fd, " Codecs : "); 03802 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 03803 ast_cli(a->fd, "%s\n", codec_buf); 03804 03805 ast_cli(a->fd, " Codec Order : ("); 03806 for(x = 0; x < 32 ; x++) { 03807 codec = ast_codec_pref_index(&peer->prefs,x); 03808 if(!codec) 03809 break; 03810 ast_cli(a->fd, "%s", ast_getformatname(codec)); 03811 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 03812 ast_cli(a->fd, "|"); 03813 } 03814 03815 if (!x) 03816 ast_cli(a->fd, "none"); 03817 ast_cli(a->fd, ")\n"); 03818 03819 ast_cli(a->fd, " Status : "); 03820 peer_status(peer, status, sizeof(status)); 03821 ast_cli(a->fd, "%s\n",status); 03822 ast_cli(a->fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 03823 ast_cli(a->fd, "\n"); 03824 peer_unref(peer); 03825 } else { 03826 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]); 03827 ast_cli(a->fd, "\n"); 03828 } 03829 03830 return CLI_SUCCESS; 03831 }
static char* handle_cli_iax2_show_peers | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6928 of file chan_iax2.c.
References __iax2_show_peers(), ast_cli_args::argc, ast_cli_args::argv, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, RESULT_FAILURE, RESULT_SHOWUSAGE, and ast_cli_entry::usage.
06929 { 06930 switch (cmd) { 06931 case CLI_INIT: 06932 e->command = "iax2 show peers"; 06933 e->usage = 06934 "Usage: iax2 show peers [registered] [like <pattern>]\n" 06935 " Lists all known IAX2 peers.\n" 06936 " Optional 'registered' argument lists only peers with known addresses.\n" 06937 " Optional regular expression pattern is used to filter the peer list.\n"; 06938 return NULL; 06939 case CLI_GENERATE: 06940 return NULL; 06941 } 06942 06943 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) { 06944 case RESULT_SHOWUSAGE: 06945 return CLI_SHOWUSAGE; 06946 case RESULT_FAILURE: 06947 return CLI_FAILURE; 06948 default: 06949 return CLI_SUCCESS; 06950 } 06951 }
static char* handle_cli_iax2_show_registry | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7083 of file chan_iax2.c.
References iax2_registry::addr, ast_cli_args::argc, ast_cli(), ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sockaddr_stringify(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_registry::dnsmgr, iax2_registry::entry, ast_cli_args::fd, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), iax2_registry::us, ast_cli_entry::usage, and iax2_registry::username.
07084 { 07085 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 07086 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 07087 struct iax2_registry *reg = NULL; 07088 char host[80]; 07089 char perceived[80]; 07090 int counter = 0; 07091 07092 switch (cmd) { 07093 case CLI_INIT: 07094 e->command = "iax2 show registry"; 07095 e->usage = 07096 "Usage: iax2 show registry\n" 07097 " Lists all registration requests and status.\n"; 07098 return NULL; 07099 case CLI_GENERATE: 07100 return NULL; 07101 } 07102 if (a->argc != 3) 07103 return CLI_SHOWUSAGE; 07104 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 07105 AST_LIST_LOCK(®istrations); 07106 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07107 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07108 if (reg->us.sin_addr.s_addr) 07109 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07110 else 07111 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07112 ast_cli(a->fd, FORMAT, host, 07113 (reg->dnsmgr) ? "Y" : "N", 07114 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 07115 counter++; 07116 } 07117 AST_LIST_UNLOCK(®istrations); 07118 ast_cli(a->fd, "%d IAX2 registrations.\n", counter); 07119 return CLI_SUCCESS; 07120 #undef FORMAT 07121 #undef FORMAT2 07122 }
static char* handle_cli_iax2_show_stats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3856 of file chan_iax2.c.
References ast_cli_args::argc, ARRAY_LEN, ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, iax_frame::final, frame_queue, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iaxsl, iax2_trunk_peer::list, iax_frame::retries, and ast_cli_entry::usage.
03857 { 03858 struct iax_frame *cur; 03859 int cnt = 0, dead = 0, final = 0, i = 0; 03860 03861 switch (cmd) { 03862 case CLI_INIT: 03863 e->command = "iax2 show stats"; 03864 e->usage = 03865 "Usage: iax2 show stats\n" 03866 " Display statistics on IAX channel driver.\n"; 03867 return NULL; 03868 case CLI_GENERATE: 03869 return NULL; 03870 } 03871 03872 if (a->argc != 3) 03873 return CLI_SHOWUSAGE; 03874 03875 for (i = 0; i < ARRAY_LEN(frame_queue); i++) { 03876 ast_mutex_lock(&iaxsl[i]); 03877 AST_LIST_TRAVERSE(&frame_queue[i], cur, list) { 03878 if (cur->retries < 0) 03879 dead++; 03880 if (cur->final) 03881 final++; 03882 cnt++; 03883 } 03884 ast_mutex_unlock(&iaxsl[i]); 03885 } 03886 03887 ast_cli(a->fd, " IAX Statistics\n"); 03888 ast_cli(a->fd, "---------------------\n"); 03889 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 03890 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed, 03891 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu); 03892 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 03893 03894 trunk_timed = trunk_untimed = 0; 03895 if (trunk_maxmtu > trunk_nmaxmtu) 03896 trunk_nmaxmtu = trunk_maxmtu; 03897 03898 return CLI_SUCCESS; 03899 }
static char* handle_cli_iax2_show_threads | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6790 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, IAX_THREAD_TYPE_DYNAMIC, iaxthreadcount, iax2_thread::list, thread, and ast_cli_entry::usage.
06791 { 06792 struct iax2_thread *thread = NULL; 06793 time_t t; 06794 int threadcount = 0, dynamiccount = 0; 06795 char type; 06796 06797 switch (cmd) { 06798 case CLI_INIT: 06799 e->command = "iax2 show threads"; 06800 e->usage = 06801 "Usage: iax2 show threads\n" 06802 " Lists status of IAX helper threads\n"; 06803 return NULL; 06804 case CLI_GENERATE: 06805 return NULL; 06806 } 06807 if (a->argc != 3) 06808 return CLI_SHOWUSAGE; 06809 06810 ast_cli(a->fd, "IAX2 Thread Information\n"); 06811 time(&t); 06812 ast_cli(a->fd, "Idle Threads:\n"); 06813 AST_LIST_LOCK(&idle_list); 06814 AST_LIST_TRAVERSE(&idle_list, thread, list) { 06815 #ifdef DEBUG_SCHED_MULTITHREAD 06816 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06817 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06818 #else 06819 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06820 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06821 #endif 06822 threadcount++; 06823 } 06824 AST_LIST_UNLOCK(&idle_list); 06825 ast_cli(a->fd, "Active Threads:\n"); 06826 AST_LIST_LOCK(&active_list); 06827 AST_LIST_TRAVERSE(&active_list, thread, list) { 06828 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) 06829 type = 'D'; 06830 else 06831 type = 'P'; 06832 #ifdef DEBUG_SCHED_MULTITHREAD 06833 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 06834 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06835 #else 06836 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 06837 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06838 #endif 06839 threadcount++; 06840 } 06841 AST_LIST_UNLOCK(&active_list); 06842 ast_cli(a->fd, "Dynamic Threads:\n"); 06843 AST_LIST_LOCK(&dynamic_list); 06844 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 06845 #ifdef DEBUG_SCHED_MULTITHREAD 06846 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06847 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06848 #else 06849 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06850 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06851 #endif 06852 dynamiccount++; 06853 } 06854 AST_LIST_UNLOCK(&dynamic_list); 06855 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 06856 return CLI_SUCCESS; 06857 }
static char* handle_cli_iax2_show_users | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6581 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_strlen_zero(), ast_test_flag64, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, DEFAULT_CONTEXT, ast_cli_args::fd, FORMAT, FORMAT2, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, ast_cli_entry::usage, user, user_unref(), and users.
06582 { 06583 regex_t regexbuf; 06584 int havepattern = 0; 06585 06586 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 06587 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 06588 06589 struct iax2_user *user = NULL; 06590 char auth[90]; 06591 char *pstr = ""; 06592 struct ao2_iterator i; 06593 06594 switch (cmd) { 06595 case CLI_INIT: 06596 e->command = "iax2 show users [like]"; 06597 e->usage = 06598 "Usage: iax2 show users [like <pattern>]\n" 06599 " Lists all known IAX2 users.\n" 06600 " Optional regular expression pattern is used to filter the user list.\n"; 06601 return NULL; 06602 case CLI_GENERATE: 06603 return NULL; 06604 } 06605 06606 switch (a->argc) { 06607 case 5: 06608 if (!strcasecmp(a->argv[3], "like")) { 06609 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 06610 return CLI_SHOWUSAGE; 06611 havepattern = 1; 06612 } else 06613 return CLI_SHOWUSAGE; 06614 case 3: 06615 break; 06616 default: 06617 return CLI_SHOWUSAGE; 06618 } 06619 06620 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 06621 i = ao2_iterator_init(users, 0); 06622 for (; (user = ao2_iterator_next(&i)); user_unref(user)) { 06623 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 06624 continue; 06625 06626 if (!ast_strlen_zero(user->secret)) { 06627 ast_copy_string(auth,user->secret, sizeof(auth)); 06628 } else if (!ast_strlen_zero(user->inkeys)) { 06629 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 06630 } else 06631 ast_copy_string(auth, "-no secret-", sizeof(auth)); 06632 06633 if(ast_test_flag64(user, IAX_CODEC_NOCAP)) 06634 pstr = "REQ Only"; 06635 else if(ast_test_flag64(user, IAX_CODEC_NOPREFS)) 06636 pstr = "Disabled"; 06637 else 06638 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 06639 06640 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 06641 user->contexts ? user->contexts->context : DEFAULT_CONTEXT, 06642 user->ha ? "Yes" : "No", pstr); 06643 } 06644 ao2_iterator_destroy(&i); 06645 06646 if (havepattern) 06647 regfree(®exbuf); 06648 06649 return CLI_SUCCESS; 06650 #undef FORMAT 06651 #undef FORMAT2 06652 }
static char* handle_cli_iax2_test_losspct | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3636 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.
03637 { 03638 switch (cmd) { 03639 case CLI_INIT: 03640 e->command = "iax2 test losspct"; 03641 e->usage = 03642 "Usage: iax2 test losspct <percentage>\n" 03643 " For testing, throws away <percentage> percent of incoming packets\n"; 03644 return NULL; 03645 case CLI_GENERATE: 03646 return NULL; 03647 } 03648 if (a->argc != 4) 03649 return CLI_SHOWUSAGE; 03650 03651 test_losspct = atoi(a->argv[3]); 03652 03653 return CLI_SUCCESS; 03654 }
static char* handle_cli_iax2_unregister | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6859 of file chan_iax2.c.
References ao2_find, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_unregister(), iax2_peer::expire, expire_registry(), ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, iax2_peer::name, OBJ_POINTER, peer_ref(), peer_unref(), peers, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
06860 { 06861 struct iax2_peer *p; 06862 06863 switch (cmd) { 06864 case CLI_INIT: 06865 e->command = "iax2 unregister"; 06866 e->usage = 06867 "Usage: iax2 unregister <peername>\n" 06868 " Unregister (force expiration) an IAX2 peer from the registry.\n"; 06869 return NULL; 06870 case CLI_GENERATE: 06871 return complete_iax2_unregister(a->line, a->word, a->pos, a->n); 06872 } 06873 06874 if (a->argc != 3) 06875 return CLI_SHOWUSAGE; 06876 06877 p = find_peer(a->argv[2], 1); 06878 if (p) { 06879 if (p->expire > 0) { 06880 struct iax2_peer tmp_peer = { 06881 .name = a->argv[2], 06882 }; 06883 struct iax2_peer *peer; 06884 06885 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 06886 if (peer) { 06887 expire_registry(peer_ref(peer)); /* will release its own reference when done */ 06888 peer_unref(peer); /* ref from ao2_find() */ 06889 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]); 06890 } else { 06891 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]); 06892 } 06893 } else { 06894 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 06895 } 06896 peer_unref(p); 06897 } else { 06898 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]); 06899 } 06900 return CLI_SUCCESS; 06901 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 9554 of file chan_iax2.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock, ast_mutex_unlock, iax2_pkt_buf::buf, iax2_pkt_buf::entry, iax2_pkt_buf::len, socket_process(), and thread.
09555 { 09556 struct iax2_pkt_buf *pkt_buf; 09557 09558 ast_mutex_lock(&thread->lock); 09559 09560 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 09561 ast_mutex_unlock(&thread->lock); 09562 09563 thread->buf = pkt_buf->buf; 09564 thread->buf_len = pkt_buf->len; 09565 thread->buf_size = pkt_buf->len + 1; 09566 09567 socket_process(thread); 09568 09569 thread->buf = NULL; 09570 ast_free(pkt_buf); 09571 09572 ast_mutex_lock(&thread->lock); 09573 } 09574 09575 ast_mutex_unlock(&thread->lock); 09576 }
static int handle_error | ( | void | ) | [static] |
Definition at line 3291 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), errno, LOG_WARNING, and netsocket.
Referenced by send_packet(), socket_read(), and transmit_trunk().
03292 { 03293 /* XXX Ideally we should figure out why an error occurred and then abort those 03294 rather than continuing to try. Unfortunately, the published interface does 03295 not seem to work XXX */ 03296 #if 0 03297 struct sockaddr_in *sin; 03298 int res; 03299 struct msghdr m; 03300 struct sock_extended_err e; 03301 m.msg_name = NULL; 03302 m.msg_namelen = 0; 03303 m.msg_iov = NULL; 03304 m.msg_control = &e; 03305 m.msg_controllen = sizeof(e); 03306 m.msg_flags = 0; 03307 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 03308 if (res < 0) 03309 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 03310 else { 03311 if (m.msg_controllen) { 03312 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 03313 if (sin) 03314 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 03315 else 03316 ast_log(LOG_WARNING, "No address detected??\n"); 03317 } else { 03318 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 03319 } 03320 } 03321 #endif 03322 return 0; 03323 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 8449 of file chan_iax2.c.
References iax2_registry::addr, iax_ies::apparent_addr, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_sockaddr_to_sin, ast_verb, iax_ies::calling_number, EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), iax2_sched_replace(), iaxs, inaddrcmp(), LOG_WARNING, manager_event, iax2_registry::messages, iax_ies::msgcount, iax2_registry::refresh, iax_ies::refresh, refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, sched, iax2_registry::us, and iax_ies::username.
Referenced by socket_process().
08450 { 08451 struct iax2_registry *reg; 08452 /* Start pessimistic */ 08453 char peer[256] = ""; 08454 char msgstatus[60]; 08455 int refresh = 60; 08456 char ourip[256] = "<Unspecified>"; 08457 struct sockaddr_in oldus; 08458 struct sockaddr_in us; 08459 int oldmsgs; 08460 struct sockaddr_in reg_addr; 08461 08462 memset(&us, 0, sizeof(us)); 08463 if (ies->apparent_addr) { 08464 memmove(&us, ies->apparent_addr, sizeof(us)); 08465 } 08466 if (ies->username) { 08467 ast_copy_string(peer, ies->username, sizeof(peer)); 08468 } 08469 if (ies->refresh) { 08470 refresh = ies->refresh; 08471 } 08472 if (ies->calling_number) { 08473 /* We don't do anything with it really, but maybe we should */ 08474 } 08475 reg = iaxs[callno]->reg; 08476 if (!reg) { 08477 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 08478 return -1; 08479 } 08480 memcpy(&oldus, ®->us, sizeof(oldus)); 08481 oldmsgs = reg->messages; 08482 ast_sockaddr_to_sin(®->addr, ®_addr); 08483 if (inaddrcmp(®_addr, sin)) { 08484 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08485 return -1; 08486 } 08487 memcpy(®->us, &us, sizeof(reg->us)); 08488 if (ies->msgcount >= 0) { 08489 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 08490 } 08491 /* always refresh the registration at the interval requested by the server 08492 we are registering to 08493 */ 08494 reg->refresh = refresh; 08495 reg->expire = iax2_sched_replace(reg->expire, sched, 08496 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08497 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 08498 if (reg->messages > 255) { 08499 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 08500 } else if (reg->messages > 1) { 08501 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages); 08502 } else if (reg->messages > 0) { 08503 ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus)); 08504 } else { 08505 ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus)); 08506 } 08507 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 08508 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 08509 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 08510 } 08511 reg->regstate = REG_STATE_REGISTERED; 08512 return 0; 08513 }
static int attribute_pure iax2_allow_new | ( | int | frametype, | |
int | subclass, | |||
int | inbound | |||
) | [inline, static] |
Definition at line 2756 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_FWDOWNL, IAX_COMMAND_NEW, IAX_COMMAND_POKE, IAX_COMMAND_REGREL, and IAX_COMMAND_REGREQ.
Referenced by resend_with_token(), and socket_process().
02757 { 02758 if (frametype != AST_FRAME_IAX) { 02759 return 0; 02760 } 02761 switch (subclass) { 02762 case IAX_COMMAND_NEW: 02763 case IAX_COMMAND_REGREQ: 02764 case IAX_COMMAND_FWDOWNL: 02765 case IAX_COMMAND_REGREL: 02766 return 1; 02767 case IAX_COMMAND_POKE: 02768 if (!inbound) { 02769 return 1; 02770 } 02771 break; 02772 } 02773 return 0; 02774 }
static void iax2_ami_channelupdate | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Send manager event at call setup to link between Asterisk channel name and IAX2 call identifiers.
Definition at line 1323 of file chan_iax2.c.
References chan_iax2_pvt::callno, EVENT_FLAG_SYSTEM, manager_event, ast_channel::name, chan_iax2_pvt::owner, chan_iax2_pvt::peer, and chan_iax2_pvt::peercallno.
Referenced by ast_iax2_new(), and iax2_answer().
01324 { 01325 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 01326 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n", 01327 pvt->owner ? pvt->owner->name : "", 01328 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : ""); 01329 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5633 of file chan_iax2.c.
References AST_CONTROL_ANSWER, ast_debug, AST_FRAME_CONTROL, ast_mutex_lock, ast_mutex_unlock, iax2_ami_channelupdate(), iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
05634 { 05635 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05636 ast_debug(1, "Answering IAX2 call\n"); 05637 ast_mutex_lock(&iaxsl[callno]); 05638 if (iaxs[callno]) 05639 iax2_ami_channelupdate(iaxs[callno]); 05640 ast_mutex_unlock(&iaxsl[callno]); 05641 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 05642 }
static int iax2_append_register | ( | const char * | hostname, | |
const char * | username, | |||
const char * | secret, | |||
const char * | porta | |||
) | [static] |
Definition at line 8515 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), ast_dnsmgr_lookup(), ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_sockaddr_set_port, iax2_registry::entry, IAX_DEFAULT_PORTNO, and IAX_DEFAULT_REG_EXPIRE.
Referenced by iax2_register().
08517 { 08518 struct iax2_registry *reg; 08519 08520 if (!(reg = ast_calloc(1, sizeof(*reg)))) 08521 return -1; 08522 08523 reg->addr.ss.ss_family = AF_INET; 08524 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) { 08525 ast_free(reg); 08526 return -1; 08527 } 08528 08529 ast_copy_string(reg->username, username, sizeof(reg->username)); 08530 08531 if (secret) 08532 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 08533 08534 reg->expire = -1; 08535 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 08536 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO); 08537 08538 AST_LIST_LOCK(®istrations); 08539 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 08540 AST_LIST_UNLOCK(®istrations); 08541 08542 return 0; 08543 }
static enum ast_bridge_result iax2_bridge | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1, | |||
int | flags, | |||
struct ast_frame ** | fo, | |||
struct ast_channel ** | rc, | |||
int | timeoutms | |||
) | [static] |
Definition at line 5478 of file chan_iax2.c.
References AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, ast_mutex_lock, ast_mutex_unlock, ast_verb, chan_iax2_pvt::bridgecallno, f, iax2_tech, iaxs, iaxsl, lock_both(), PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, and unlock_both().
05479 { 05480 struct ast_channel *cs[3]; 05481 struct ast_channel *who, *other; 05482 int to = -1; 05483 int res = -1; 05484 int transferstarted=0; 05485 struct ast_frame *f; 05486 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 05487 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 05488 struct timeval waittimer = {0, 0}; 05489 05490 /* We currently do not support native bridging if a timeoutms value has been provided */ 05491 if (timeoutms > 0) { 05492 return AST_BRIDGE_FAILED; 05493 } 05494 05495 timeoutms = -1; 05496 05497 lock_both(callno0, callno1); 05498 if (!iaxs[callno0] || !iaxs[callno1]) { 05499 unlock_both(callno0, callno1); 05500 return AST_BRIDGE_FAILED; 05501 } 05502 /* Put them in native bridge mode */ 05503 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 05504 iaxs[callno0]->bridgecallno = callno1; 05505 iaxs[callno1]->bridgecallno = callno0; 05506 } 05507 unlock_both(callno0, callno1); 05508 05509 /* If not, try to bridge until we can execute a transfer, if we can */ 05510 cs[0] = c0; 05511 cs[1] = c1; 05512 for (/* ever */;;) { 05513 /* Check in case we got masqueraded into */ 05514 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 05515 ast_verb(3, "Can't masquerade, we're different...\n"); 05516 /* Remove from native mode */ 05517 if (c0->tech == &iax2_tech) { 05518 ast_mutex_lock(&iaxsl[callno0]); 05519 iaxs[callno0]->bridgecallno = 0; 05520 ast_mutex_unlock(&iaxsl[callno0]); 05521 } 05522 if (c1->tech == &iax2_tech) { 05523 ast_mutex_lock(&iaxsl[callno1]); 05524 iaxs[callno1]->bridgecallno = 0; 05525 ast_mutex_unlock(&iaxsl[callno1]); 05526 } 05527 return AST_BRIDGE_FAILED_NOWARN; 05528 } 05529 if (c0->nativeformats != c1->nativeformats) { 05530 char buf0[256]; 05531 char buf1[256]; 05532 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats); 05533 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats); 05534 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1); 05535 /* Remove from native mode */ 05536 lock_both(callno0, callno1); 05537 if (iaxs[callno0]) 05538 iaxs[callno0]->bridgecallno = 0; 05539 if (iaxs[callno1]) 05540 iaxs[callno1]->bridgecallno = 0; 05541 unlock_both(callno0, callno1); 05542 return AST_BRIDGE_FAILED_NOWARN; 05543 } 05544 /* check if transfered and if we really want native bridging */ 05545 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) { 05546 /* Try the transfer */ 05547 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 05548 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA))) 05549 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 05550 transferstarted = 1; 05551 } 05552 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 05553 /* Call has been transferred. We're no longer involved */ 05554 struct timeval now = ast_tvnow(); 05555 if (ast_tvzero(waittimer)) { 05556 waittimer = now; 05557 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 05558 c0->_softhangup |= AST_SOFTHANGUP_DEV; 05559 c1->_softhangup |= AST_SOFTHANGUP_DEV; 05560 *fo = NULL; 05561 *rc = c0; 05562 res = AST_BRIDGE_COMPLETE; 05563 break; 05564 } 05565 } 05566 to = 1000; 05567 who = ast_waitfor_n(cs, 2, &to); 05568 if (timeoutms > -1) { 05569 timeoutms -= (1000 - to); 05570 if (timeoutms < 0) 05571 timeoutms = 0; 05572 } 05573 if (!who) { 05574 if (!timeoutms) { 05575 res = AST_BRIDGE_RETRY; 05576 break; 05577 } 05578 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 05579 res = AST_BRIDGE_FAILED; 05580 break; 05581 } 05582 continue; 05583 } 05584 f = ast_read(who); 05585 if (!f) { 05586 *fo = NULL; 05587 *rc = who; 05588 res = AST_BRIDGE_COMPLETE; 05589 break; 05590 } 05591 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass.integer != AST_CONTROL_SRCUPDATE)) { 05592 *fo = f; 05593 *rc = who; 05594 res = AST_BRIDGE_COMPLETE; 05595 break; 05596 } 05597 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 05598 if ((f->frametype == AST_FRAME_VOICE) || 05599 (f->frametype == AST_FRAME_TEXT) || 05600 (f->frametype == AST_FRAME_VIDEO) || 05601 (f->frametype == AST_FRAME_IMAGE) || 05602 (f->frametype == AST_FRAME_DTMF) || 05603 (f->frametype == AST_FRAME_CONTROL)) { 05604 /* monitored dtmf take out of the bridge. 05605 * check if we monitor the specific source. 05606 */ 05607 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 05608 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 05609 *rc = who; 05610 *fo = f; 05611 res = AST_BRIDGE_COMPLETE; 05612 /* Remove from native mode */ 05613 break; 05614 } 05615 /* everything else goes to the other side */ 05616 ast_write(other, f); 05617 } 05618 ast_frfree(f); 05619 /* Swap who gets priority */ 05620 cs[2] = cs[0]; 05621 cs[0] = cs[1]; 05622 cs[1] = cs[2]; 05623 } 05624 lock_both(callno0, callno1); 05625 if(iaxs[callno0]) 05626 iaxs[callno0]->bridgecallno = 0; 05627 if(iaxs[callno1]) 05628 iaxs[callno1]->bridgecallno = 0; 05629 unlock_both(callno0, callno1); 05630 return res; 05631 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 5026 of file chan_iax2.c.
References ast_channel::_state, add_empty_calltoken_ie(), chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_party_connected_line::ani, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, ast_channel_datastore_find(), ast_copy_string(), ast_debug, AST_FRAME_IAX, AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_party_id_presentation(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_var_name(), ast_var_value(), auto_congest(), CALLNO_TO_PTR, capability, ast_channel::connected, context, ast_channel::context, create_addr(), ast_datastore::data, ast_channel::dialed, chan_iax2_pvt::encmethods, ast_party_redirecting::from, ast_channel::hangupcause, iax2_datetime(), iax2_sched_add(), iax2_variable_datastore_info, IAX_COMMAND_NEW, IAX_FORCE_ENCRYPT, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_raw(), iax_ie_append_short(), iax_ie_append_str(), iax_ie_append_versioned_uint64(), IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CAPABILITY, IAX_IE_CAPABILITY2, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_FORMAT2, IAX_IE_LANGUAGE, IAX_IE_OSPTOKEN, IAX_IE_RDNIS, IAX_IE_USERNAME, IAX_IE_VARIABLE, IAX_IE_VERSION, IAX_MAX_OSPBLOCK_SIZE, IAX_MAX_OSPTOKEN_SIZE, IAX_PROTO_VERSION, IAX_SENDANI, iaxs, iaxsl, ast_party_connected_line::id, chan_iax2_pvt::initid, ast_channel::language, LOG_WARNING, chan_iax2_pvt::maxtime, chan_iax2_pvt::mohinterpret, chan_iax2_pvt::mohsuggest, ast_party_id::name, ast_channel::name, ast_channel::nativeformats, ast_party_dialed::number, ast_party_id::number, parse_dial_string(), pbx_builtin_getvar_helper(), chan_iax2_pvt::pingtime, ast_party_number::plan, PTR_TO_CALLNO, ast_channel::redirecting, sched, secret, send_command(), chan_iax2_pvt::sockfd, ast_party_dialed::str, ast_party_name::str, ast_party_number::str, ast_channel::tech_pvt, ast_party_dialed::transit_network_select, chan_iax2_pvt::username, ast_party_name::valid, ast_party_number::valid, and var.
05027 { 05028 struct sockaddr_in sin; 05029 char *l=NULL, *n=NULL, *tmpstr; 05030 struct iax_ie_data ied; 05031 char *defaultrdest = "s"; 05032 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05033 struct parsed_dial_string pds; 05034 struct create_addr_info cai; 05035 struct ast_var_t *var; 05036 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL); 05037 const char* osp_token_ptr; 05038 unsigned int osp_token_length; 05039 unsigned char osp_block_index; 05040 unsigned int osp_block_length; 05041 unsigned char osp_buffer[256]; 05042 05043 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 05044 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 05045 return -1; 05046 } 05047 05048 memset(&cai, 0, sizeof(cai)); 05049 cai.encmethods = iax2_encryption; 05050 05051 memset(&pds, 0, sizeof(pds)); 05052 tmpstr = ast_strdupa(dest); 05053 parse_dial_string(tmpstr, &pds); 05054 05055 if (ast_strlen_zero(pds.peer)) { 05056 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 05057 return -1; 05058 } 05059 if (!pds.exten) { 05060 pds.exten = defaultrdest; 05061 } 05062 if (create_addr(pds.peer, c, &sin, &cai)) { 05063 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 05064 return -1; 05065 } 05066 if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) { 05067 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n"); 05068 c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05069 return -1; 05070 } 05071 if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 05072 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n"); 05073 return -1; 05074 } 05075 if (!pds.username && !ast_strlen_zero(cai.username)) 05076 pds.username = cai.username; 05077 if (!pds.password && !ast_strlen_zero(cai.secret)) 05078 pds.password = cai.secret; 05079 if (!pds.key && !ast_strlen_zero(cai.outkey)) 05080 pds.key = cai.outkey; 05081 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 05082 pds.context = cai.peercontext; 05083 05084 /* Keep track of the context for outgoing calls too */ 05085 ast_copy_string(c->context, cai.context, sizeof(c->context)); 05086 05087 if (pds.port) 05088 sin.sin_port = htons(atoi(pds.port)); 05089 05090 l = c->connected.id.number.valid ? c->connected.id.number.str : NULL; 05091 n = c->connected.id.name.valid ? c->connected.id.name.str : NULL; 05092 05093 /* Now build request */ 05094 memset(&ied, 0, sizeof(ied)); 05095 05096 /* On new call, first IE MUST be IAX version of caller */ 05097 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 05098 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 05099 if (pds.options && strchr(pds.options, 'a')) { 05100 /* Request auto answer */ 05101 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 05102 } 05103 05104 /* WARNING: this breaks down at 190 bits! */ 05105 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 05106 05107 if (l) { 05108 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 05109 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05110 ast_party_id_presentation(&c->connected.id)); 05111 } else if (n) { 05112 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05113 ast_party_id_presentation(&c->connected.id)); 05114 } else { 05115 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 05116 } 05117 05118 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan); 05119 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select); 05120 05121 if (n) 05122 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 05123 if (ast_test_flag64(iaxs[callno], IAX_SENDANI) 05124 && c->connected.ani.number.valid 05125 && c->connected.ani.number.str) { 05126 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str); 05127 } 05128 05129 if (!ast_strlen_zero(c->language)) 05130 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 05131 if (!ast_strlen_zero(c->dialed.number.str)) { 05132 iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str); 05133 } 05134 if (c->redirecting.from.number.valid 05135 && !ast_strlen_zero(c->redirecting.from.number.str)) { 05136 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str); 05137 } 05138 05139 if (pds.context) 05140 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 05141 05142 if (pds.username) 05143 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 05144 05145 if (cai.encmethods) 05146 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 05147 05148 ast_mutex_lock(&iaxsl[callno]); 05149 05150 if (!ast_strlen_zero(c->context)) 05151 ast_string_field_set(iaxs[callno], context, c->context); 05152 05153 if (pds.username) 05154 ast_string_field_set(iaxs[callno], username, pds.username); 05155 05156 iaxs[callno]->encmethods = cai.encmethods; 05157 05158 iaxs[callno]->adsi = cai.adsi; 05159 05160 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 05161 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 05162 05163 if (pds.key) 05164 ast_string_field_set(iaxs[callno], outkey, pds.key); 05165 if (pds.password) 05166 ast_string_field_set(iaxs[callno], secret, pds.password); 05167 05168 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats); 05169 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats); 05170 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability); 05171 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability); 05172 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 05173 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 05174 05175 if (iaxs[callno]->maxtime) { 05176 /* Initialize pingtime and auto-congest time */ 05177 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 05178 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 05179 } else if (autokill) { 05180 iaxs[callno]->pingtime = autokill / 2; 05181 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 05182 } 05183 05184 /* Check if there is an OSP token */ 05185 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN"); 05186 if (!ast_strlen_zero(osp_token_ptr)) { 05187 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) { 05188 osp_block_index = 0; 05189 while (osp_token_length > 0) { 05190 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length; 05191 osp_buffer[0] = osp_block_index; 05192 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length); 05193 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1); 05194 osp_block_index++; 05195 osp_token_ptr += osp_block_length; 05196 osp_token_length -= osp_block_length; 05197 } 05198 } else 05199 ast_log(LOG_WARNING, "OSP token is too long\n"); 05200 } else if (iaxdebug) 05201 ast_debug(1, "OSP token is undefined\n"); 05202 05203 /* send the command using the appropriate socket for this peer */ 05204 iaxs[callno]->sockfd = cai.sockfd; 05205 05206 /* Add remote vars */ 05207 if (variablestore) { 05208 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data; 05209 ast_debug(1, "Found an IAX variable store on this channel\n"); 05210 AST_LIST_LOCK(variablelist); 05211 AST_LIST_TRAVERSE(variablelist, var, entries) { 05212 char tmp[256]; 05213 int i; 05214 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var)); 05215 /* Automatically divide the value up into sized chunks */ 05216 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) { 05217 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i); 05218 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp); 05219 } 05220 } 05221 AST_LIST_UNLOCK(variablelist); 05222 } 05223 05224 /* Transmit the string in a "NEW" request */ 05225 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 05226 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 05227 05228 ast_mutex_unlock(&iaxsl[callno]); 05229 ast_setstate(c, AST_STATE_RINGING); 05230 05231 return 0; 05232 }
static int iax2_canmatch | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
part of the IAX2 dial plan switch interface
Definition at line 13817 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_CANEXIST, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
13818 { 13819 int res = 0; 13820 struct iax2_dpcache *dp = NULL; 13821 #if 0 13822 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13823 #endif 13824 if ((priority != 1) && (priority != 2)) 13825 return 0; 13826 13827 AST_LIST_LOCK(&dpcache); 13828 if ((dp = find_cache(chan, data, context, exten, priority))) { 13829 if (dp->flags & CACHE_FLAG_CANEXIST) 13830 res = 1; 13831 } else { 13832 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13833 } 13834 AST_LIST_UNLOCK(&dpcache); 13835 13836 return res; 13837 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 4695 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), ast_tvnow(), ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, and ast_tm::tm_year.
Referenced by iax2_call(), and update_registry().
04696 { 04697 struct timeval t = ast_tvnow(); 04698 struct ast_tm tm; 04699 unsigned int tmp; 04700 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz); 04701 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 04702 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 04703 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 04704 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 04705 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 04706 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 04707 return tmp; 04708 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 3397 of file chan_iax2.c.
References ao2_ref, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_queue_hangup(), DEADLOCK_AVOIDANCE, iax2_destroy_helper(), iaxs, iaxsl, chan_iax2_pvt::owner, chan_iax2_pvt::peercallno, remove_by_peercallno(), remove_by_transfercallno(), chan_iax2_pvt::transfercallno, and update_max_trunk.
Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __unload_module(), delete_users(), iax2_do_register(), iax2_hangup(), iax2_poke_peer(), peer_destructor(), scheduled_destroy(), and socket_process().
03398 { 03399 struct chan_iax2_pvt *pvt = NULL; 03400 struct ast_channel *owner = NULL; 03401 03402 retry: 03403 if ((pvt = iaxs[callno])) { 03404 #if 0 03405 /* iax2_destroy_helper gets called from this function later on. When 03406 * called twice, we get the (previously) familiar FRACK! errors in 03407 * devmode, from the scheduler. An alternative to this approach is to 03408 * reset the scheduler entries to -1 when they're deleted in 03409 * iax2_destroy_helper(). That approach was previously decided to be 03410 * "wrong" because "the memory is going to be deallocated anyway. Why 03411 * should we be resetting those values?" */ 03412 iax2_destroy_helper(pvt); 03413 #endif 03414 } 03415 03416 owner = pvt ? pvt->owner : NULL; 03417 03418 if (owner) { 03419 if (ast_channel_trylock(owner)) { 03420 ast_debug(3, "Avoiding IAX destroy deadlock\n"); 03421 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03422 goto retry; 03423 } 03424 } 03425 03426 if (!owner) { 03427 iaxs[callno] = NULL; 03428 } 03429 03430 if (pvt) { 03431 if (!owner) { 03432 pvt->owner = NULL; 03433 } else { 03434 /* If there's an owner, prod it to give up */ 03435 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 03436 * because we already hold the owner channel lock. */ 03437 ast_queue_hangup(owner); 03438 } 03439 03440 if (pvt->peercallno) { 03441 remove_by_peercallno(pvt); 03442 } 03443 03444 if (pvt->transfercallno) { 03445 remove_by_transfercallno(pvt); 03446 } 03447 03448 if (!owner) { 03449 ao2_ref(pvt, -1); 03450 pvt = NULL; 03451 } 03452 } 03453 03454 if (owner) { 03455 ast_channel_unlock(owner); 03456 } 03457 03458 if (callno & TRUNK_CALL_START) { 03459 update_max_trunk(); 03460 } 03461 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1771 of file chan_iax2.c.
References ao2_find, ast_atomic_fetchadd_int(), ast_clear_flag64, AST_SCHED_DEL_SPINLOCK, ast_sched_thread_del, ast_sched_thread_get_context(), ast_test_flag64, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::callno, DONT_RESCHEDULE, IAX_MAXAUTHREQ, iaxsl, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::lagid, iax2_user::name, OBJ_POINTER, chan_iax2_pvt::pingid, sched, user, user_unref(), chan_iax2_pvt::username, and users.
Referenced by iax2_destroy(), iax2_predestroy(), pvt_destructor(), and stop_stuff().
01772 { 01773 /* Decrement AUTHREQ count if needed */ 01774 if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) { 01775 struct iax2_user *user; 01776 struct iax2_user tmp_user = { 01777 .name = pvt->username, 01778 }; 01779 01780 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01781 if (user) { 01782 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01783 user_unref(user); 01784 } 01785 01786 ast_clear_flag64(pvt, IAX_MAXAUTHREQ); 01787 } 01788 /* No more pings or lagrq's */ 01789 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]); 01790 pvt->pingid = DONT_RESCHEDULE; 01791 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]); 01792 pvt->lagid = DONT_RESCHEDULE; 01793 ast_sched_thread_del(sched, pvt->autoid); 01794 ast_sched_thread_del(sched, pvt->authid); 01795 ast_sched_thread_del(sched, pvt->initid); 01796 ast_sched_thread_del(sched, pvt->jbid); 01797 ast_sched_thread_del(sched, pvt->keyrotateid); 01798 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 14023 of file chan_iax2.c.
References iax2_peer::addr, ast_debug, AST_DEVICE_INVALID, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_log(), ast_sockaddr_ipv4(), ast_strdupa, ast_strlen_zero(), iax2_peer::defaddr, find_peer(), iax2_peer::historicms, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, parse_dial_string(), and peer_unref().
14024 { 14025 struct parsed_dial_string pds; 14026 char *tmp = ast_strdupa(data); 14027 struct iax2_peer *p; 14028 int res = AST_DEVICE_INVALID; 14029 14030 memset(&pds, 0, sizeof(pds)); 14031 parse_dial_string(tmp, &pds); 14032 14033 if (ast_strlen_zero(pds.peer)) { 14034 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 14035 return res; 14036 } 14037 14038 ast_debug(3, "Checking device state for device %s\n", pds.peer); 14039 14040 /* SLD: FIXME: second call to find_peer during registration */ 14041 if (!(p = find_peer(pds.peer, 1))) 14042 return res; 14043 14044 res = AST_DEVICE_UNAVAILABLE; 14045 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 14046 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 14047 14048 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) && 14049 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 14050 /* Peer is registered, or have default IP address 14051 and a valid registration */ 14052 if (p->historicms == 0 || p->historicms <= p->maxms) 14053 /* let the core figure out whether it is in use or not */ 14054 res = AST_DEVICE_UNKNOWN; 14055 } 14056 14057 peer_unref(p); 14058 14059 return res; 14060 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 4296 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04297 { 04298 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 04299 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 4301 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04302 { 04303 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 04304 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 11811 of file chan_iax2.c.
References add_empty_calltoken_ie(), iax2_registry::addr, ast_debug, ast_dnsmgr_changed(), ast_dnsmgr_refresh(), AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_ipv4(), ast_sockaddr_to_sin, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno_locked(), iax2_destroy(), iax2_do_register_s(), iax2_sched_replace(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), and iax2_registry::username.
Referenced by __iax2_do_register_s(), load_module(), network_change_event_sched_cb(), and reload_config().
11812 { 11813 struct iax_ie_data ied; 11814 if (iaxdebug) 11815 ast_debug(1, "Sending registration request for '%s'\n", reg->username); 11816 11817 if (reg->dnsmgr && 11818 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) { 11819 /* Maybe the IP has changed, force DNS refresh */ 11820 ast_dnsmgr_refresh(reg->dnsmgr); 11821 } 11822 11823 /* 11824 * if IP has Changed, free allocated call to create a new one with new IP 11825 * call has the pointer to IP and must be updated to the new one 11826 */ 11827 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 11828 int callno = reg->callno; 11829 ast_mutex_lock(&iaxsl[callno]); 11830 iax2_destroy(callno); 11831 ast_mutex_unlock(&iaxsl[callno]); 11832 reg->callno = 0; 11833 } 11834 if (!ast_sockaddr_ipv4(®->addr)) { 11835 if (iaxdebug) 11836 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username); 11837 /* Setup the next registration attempt */ 11838 reg->expire = iax2_sched_replace(reg->expire, sched, 11839 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11840 return -1; 11841 } 11842 11843 if (!reg->callno) { 11844 struct sockaddr_in reg_addr; 11845 11846 ast_debug(3, "Allocate call number\n"); 11847 11848 ast_sockaddr_to_sin(®->addr, ®_addr); 11849 11850 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0); 11851 if (reg->callno < 1) { 11852 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 11853 return -1; 11854 } else 11855 ast_debug(3, "Registration created on call %d\n", reg->callno); 11856 iaxs[reg->callno]->reg = reg; 11857 ast_mutex_unlock(&iaxsl[reg->callno]); 11858 } 11859 /* Setup the next registration a little early */ 11860 reg->expire = iax2_sched_replace(reg->expire, sched, 11861 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11862 /* Send the request */ 11863 memset(&ied, 0, sizeof(ied)); 11864 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 11865 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 11866 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */ 11867 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 11868 reg->regstate = REG_STATE_REGSENT; 11869 return 0; 11870 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8297 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
08298 { 08299 #ifdef SCHED_MULTITHREADED 08300 if (schedule_action(__iax2_do_register_s, data)) 08301 #endif 08302 __iax2_do_register_s(data); 08303 return 0; 08304 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 9072 of file chan_iax2.c.
References AST_FRAME_IAX, auto_hangup(), chan_iax2_pvt::autoid, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, iax2_sched_replace(), IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iaxs, sched, and send_command().
Referenced by find_cache(), and socket_process().
09073 { 09074 struct iax_ie_data ied; 09075 /* Auto-hangup with 30 seconds of inactivity */ 09076 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 09077 sched, 30000, auto_hangup, (void *)(long)callno); 09078 memset(&ied, 0, sizeof(ied)); 09079 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 09080 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 09081 dp->flags |= CACHE_FLAG_TRANSMITTED; 09082 }
static void * iax2_dup_variable_datastore | ( | void * | ) | [static] |
Definition at line 1337 of file chan_iax2.c.
References ast_calloc, AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_var_assign(), ast_var_name(), ast_var_value(), ast_var_t::entries, and LOG_ERROR.
01338 { 01339 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist; 01340 struct ast_var_t *oldvar, *newvar; 01341 01342 newlist = ast_calloc(sizeof(*newlist), 1); 01343 if (!newlist) { 01344 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n"); 01345 return NULL; 01346 } 01347 01348 AST_LIST_HEAD_INIT(newlist); 01349 AST_LIST_LOCK(oldlist); 01350 AST_LIST_TRAVERSE(oldlist, oldvar, entries) { 01351 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar)); 01352 if (newvar) 01353 AST_LIST_INSERT_TAIL(newlist, newvar, entries); 01354 else 01355 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar)); 01356 } 01357 AST_LIST_UNLOCK(oldlist); 01358 return newlist; 01359 }
static int iax2_exec | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Execute IAX2 dialplan switch.
Definition at line 13863 of file chan_iax2.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_verb, CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_exec(), and pbx_findapp().
13864 { 13865 char odata[256]; 13866 char req[256]; 13867 char *ncontext; 13868 struct iax2_dpcache *dp = NULL; 13869 struct ast_app *dial = NULL; 13870 #if 0 13871 ast_log(LOG_NOTICE, "iax2_exec: con: %s, exten: %s, pri: %d, cid: %s, data: %s, newstack: %d\n", context, exten, priority, callerid ? callerid : "<unknown>", data, newstack); 13872 #endif 13873 if (priority == 2) { 13874 /* Indicate status, can be overridden in dialplan */ 13875 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 13876 if (dialstatus) { 13877 dial = pbx_findapp(dialstatus); 13878 if (dial) 13879 pbx_exec(chan, dial, ""); 13880 } 13881 return -1; 13882 } else if (priority != 1) 13883 return -1; 13884 13885 AST_LIST_LOCK(&dpcache); 13886 if ((dp = find_cache(chan, data, context, exten, priority))) { 13887 if (dp->flags & CACHE_FLAG_EXISTS) { 13888 ast_copy_string(odata, data, sizeof(odata)); 13889 ncontext = strchr(odata, '/'); 13890 if (ncontext) { 13891 *ncontext = '\0'; 13892 ncontext++; 13893 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 13894 } else { 13895 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 13896 } 13897 ast_verb(3, "Executing Dial('%s')\n", req); 13898 } else { 13899 AST_LIST_UNLOCK(&dpcache); 13900 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 13901 return -1; 13902 } 13903 } 13904 AST_LIST_UNLOCK(&dpcache); 13905 13906 if ((dial = pbx_findapp("Dial"))) 13907 return pbx_exec(chan, dial, req); 13908 else 13909 ast_log(LOG_WARNING, "No dial application registered\n"); 13910 13911 return -1; 13912 }
static int iax2_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Part of the IAX2 switch interface.
Definition at line 13794 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
13795 { 13796 int res = 0; 13797 struct iax2_dpcache *dp = NULL; 13798 #if 0 13799 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13800 #endif 13801 if ((priority != 1) && (priority != 2)) 13802 return 0; 13803 13804 AST_LIST_LOCK(&dpcache); 13805 if ((dp = find_cache(chan, data, context, exten, priority))) { 13806 if (dp->flags & CACHE_FLAG_EXISTS) 13807 res = 1; 13808 } else { 13809 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13810 } 13811 AST_LIST_UNLOCK(&dpcache); 13812 13813 return res; 13814 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 4323 of file chan_iax2.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, iax_frame::callno, iaxs, iaxsl, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt.
04324 { 04325 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 04326 ast_mutex_lock(&iaxsl[callno]); 04327 if (iaxs[callno]) 04328 iaxs[callno]->owner = newchan; 04329 else 04330 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 04331 ast_mutex_unlock(&iaxsl[callno]); 04332 return 0; 04333 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1800 of file chan_iax2.c.
References ast_sched_thread_del, iax_frame_free(), iax_frame::retrans, and sched.
Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), pvt_destructor(), resend_with_token(), and schedule_delivery().
01801 { 01802 ast_sched_thread_del(sched, fr->retrans); 01803 iax_frame_free(fr); 01804 }
static void iax2_free_variable_datastore | ( | void * | ) | [static] |
Definition at line 1361 of file chan_iax2.c.
References ast_free, AST_LIST_HEAD, AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and ast_var_t::entries.
01362 { 01363 AST_LIST_HEAD(, ast_var_t) *oldlist = old; 01364 struct ast_var_t *oldvar; 01365 01366 AST_LIST_LOCK(oldlist); 01367 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) { 01368 ast_free(oldvar); 01369 } 01370 AST_LIST_UNLOCK(oldlist); 01371 AST_LIST_HEAD_DESTROY(oldlist); 01372 ast_free(oldlist); 01373 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1734 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_copy_string(), ast_sockaddr_to_sin, iax2_peer::name, peer_unref(), peers, and realtime_peer().
Referenced by __find_callno().
01735 { 01736 struct iax2_peer *peer = NULL; 01737 int res = 0; 01738 struct ao2_iterator i; 01739 01740 i = ao2_iterator_init(peers, 0); 01741 while ((peer = ao2_iterator_next(&i))) { 01742 struct sockaddr_in peer_addr; 01743 01744 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 01745 01746 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01747 (peer_addr.sin_port == sin.sin_port)) { 01748 ast_copy_string(host, peer->name, len); 01749 peer_unref(peer); 01750 res = 1; 01751 break; 01752 } 01753 peer_unref(peer); 01754 } 01755 ao2_iterator_destroy(&i); 01756 01757 if (!peer) { 01758 peer = realtime_peer(NULL, &sin); 01759 if (peer) { 01760 ast_copy_string(host, peer->name, len); 01761 peer_unref(peer); 01762 res = 1; 01763 } 01764 } 01765 01766 return res; 01767 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 5708 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_sockaddr_to_sin, ast_test_flag64, IAX_TRUNK, peer_unref(), and peers.
Referenced by check_access().
05709 { 05710 struct iax2_peer *peer; 05711 int res = 0; 05712 struct ao2_iterator i; 05713 05714 i = ao2_iterator_init(peers, 0); 05715 while ((peer = ao2_iterator_next(&i))) { 05716 struct sockaddr_in peer_addr; 05717 05718 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 05719 05720 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 05721 (peer_addr.sin_port == sin.sin_port)) { 05722 res = ast_test_flag64(peer, IAX_TRUNK); 05723 peer_unref(peer); 05724 break; 05725 } 05726 peer_unref(peer); 05727 } 05728 ao2_iterator_destroy(&i); 05729 05730 return res; 05731 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5234 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_add(), ast_test_flag64, ast_verb, CALLNO_TO_PTR, ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, LOG_ERROR, LOG_WARNING, ast_channel::name, PTR_TO_CALLNO, sched, scheduled_destroy(), send_command_final(), and ast_channel::tech_pvt.
05235 { 05236 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05237 struct iax_ie_data ied; 05238 int alreadygone; 05239 memset(&ied, 0, sizeof(ied)); 05240 ast_mutex_lock(&iaxsl[callno]); 05241 if (callno && iaxs[callno]) { 05242 ast_debug(1, "We're hanging up %s now...\n", c->name); 05243 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE); 05244 /* Send the hangup unless we have had a transmission error or are already gone */ 05245 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 05246 if (!iaxs[callno]->error && !alreadygone) { 05247 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 05248 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 05249 } 05250 if (!iaxs[callno]) { 05251 ast_mutex_unlock(&iaxsl[callno]); 05252 return 0; 05253 } 05254 } 05255 /* Explicitly predestroy it */ 05256 iax2_predestroy(callno); 05257 /* If we were already gone to begin with, destroy us now */ 05258 if (iaxs[callno] && alreadygone) { 05259 ast_debug(1, "Really destroying %s now...\n", c->name); 05260 iax2_destroy(callno); 05261 } else if (iaxs[callno]) { 05262 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) { 05263 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno); 05264 iax2_destroy(callno); 05265 } 05266 } 05267 } else if (c->tech_pvt) { 05268 /* If this call no longer exists, but the channel still 05269 * references it we need to set the channel's tech_pvt to null 05270 * to avoid ast_channel_free() trying to free it. 05271 */ 05272 c->tech_pvt = NULL; 05273 } 05274 ast_mutex_unlock(&iaxsl[callno]); 05275 ast_verb(3, "Hungup '%s'\n", c->name); 05276 return 0; 05277 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 5644 of file chan_iax2.c.
References AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_CONTROL, ast_moh_start(), ast_moh_stop(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, IAX_SENDCONNECTEDLINE, iaxs, iaxsl, chan_iax2_pvt::mohinterpret, PTR_TO_CALLNO, send_command(), ast_channel::tech_pvt, and wait_for_peercallno().
05645 { 05646 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05647 struct chan_iax2_pvt *pvt; 05648 int res = 0; 05649 05650 if (iaxdebug) 05651 ast_debug(1, "Indicating condition %d\n", condition); 05652 05653 ast_mutex_lock(&iaxsl[callno]); 05654 pvt = iaxs[callno]; 05655 05656 if (wait_for_peercallno(pvt)) { 05657 res = -1; 05658 goto done; 05659 } 05660 05661 switch (condition) { 05662 case AST_CONTROL_HOLD: 05663 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05664 ast_moh_start(c, data, pvt->mohinterpret); 05665 goto done; 05666 } 05667 break; 05668 case AST_CONTROL_UNHOLD: 05669 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05670 ast_moh_stop(c); 05671 goto done; 05672 } 05673 break; 05674 case AST_CONTROL_CONNECTED_LINE: 05675 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE)) 05676 goto done; 05677 break; 05678 } 05679 05680 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 05681 05682 done: 05683 ast_mutex_unlock(&iaxsl[callno]); 05684 05685 return res; 05686 }
static int iax2_key_rotate | ( | const void * | vpvt | ) | [static] |
Definition at line 5396 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_sched_thread_add(), iax_ie_data::buf, build_ecx_key(), chan_iax2_pvt::callno, IAX_COMMAND_RTKEY, IAX_DEBUGDIGEST, iax_ie_append_raw(), IAX_IE_CHALLENGE, iaxsl, chan_iax2_pvt::keyrotateid, md5(), MD5Final(), MD5Init(), MD5Update(), iax_ie_data::pos, sched, and send_command().
Referenced by iax2_send().
05397 { 05398 int res = 0; 05399 struct chan_iax2_pvt *pvt = (void *) vpvt; 05400 struct MD5Context md5; 05401 char key[17] = ""; 05402 struct iax_ie_data ied = { 05403 .pos = 0, 05404 }; 05405 05406 ast_mutex_lock(&iaxsl[pvt->callno]); 05407 pvt->keyrotateid = 05408 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt); 05409 05410 snprintf(key, sizeof(key), "%lX", ast_random()); 05411 05412 MD5Init(&md5); 05413 MD5Update(&md5, (unsigned char *) key, strlen(key)); 05414 MD5Final((unsigned char *) key, &md5); 05415 05416 IAX_DEBUGDIGEST("Sending", key); 05417 05418 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16); 05419 05420 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1); 05421 05422 build_ecx_key((unsigned char *) key, pvt); 05423 05424 ast_mutex_unlock(&iaxsl[pvt->callno]); 05425 05426 return res; 05427 }
static void iax2_lock_owner | ( | int | callno | ) | [static] |
Definition at line 1260 of file chan_iax2.c.
References ast_channel_trylock, DEADLOCK_AVOIDANCE, iaxs, and iaxsl.
Referenced by iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), schedule_delivery(), set_hangup_source_and_cause(), and socket_process().
01261 { 01262 for (;;) { 01263 if (!iaxs[callno] || !iaxs[callno]->owner) { 01264 /* There is no owner lock to get. */ 01265 break; 01266 } 01267 if (!ast_channel_trylock(iaxs[callno]->owner)) { 01268 /* We got the lock */ 01269 break; 01270 } 01271 /* Avoid deadlock by pausing and trying again */ 01272 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01273 } 01274 }
static int iax2_matchmore | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Part of the IAX2 Switch interface.
Definition at line 13840 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_MATCHMORE, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
13841 { 13842 int res = 0; 13843 struct iax2_dpcache *dp = NULL; 13844 #if 0 13845 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13846 #endif 13847 if ((priority != 1) && (priority != 2)) 13848 return 0; 13849 13850 AST_LIST_LOCK(&dpcache); 13851 if ((dp = find_cache(chan, data, context, exten, priority))) { 13852 if (dp->flags & CACHE_FLAG_MATCHMORE) 13853 res = 1; 13854 } else { 13855 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13856 } 13857 AST_LIST_UNLOCK(&dpcache); 13858 13859 return res; 13860 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 12015 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
12016 { 12017 struct iax2_peer *peer = (struct iax2_peer *)data; 12018 peer->pokeexpire = -1; 12019 #ifdef SCHED_MULTITHREADED 12020 if (schedule_action(__iax2_poke_noanswer, data)) 12021 #endif 12022 __iax2_poke_noanswer(data); 12023 peer_unref(peer); 12024 return 0; 12025 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 12036 of file chan_iax2.c.
References add_empty_calltoken_ie(), iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_del, ast_sockaddr_ipv4(), ast_sockaddr_to_sin, iax_ie_data::buf, iax2_peer::callno, DEFAULT_MAXMS, iax2_peer::dnsmgr, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), iax2_sched_add(), IAX_COMMAND_POKE, iaxs, iaxsl, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, iax2_peer::name, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax_ie_data::pos, sched, send_command(), and iax2_peer::sockfd.
Referenced by __iax2_poke_peer_s(), iax2_poke_peer_cb(), poke_all_peers(), reg_source_db(), and update_registry().
12037 { 12038 int callno; 12039 struct sockaddr_in peer_addr; 12040 12041 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) { 12042 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 12043 immediately after clearing things out */ 12044 peer->lastms = 0; 12045 peer->historicms = 0; 12046 peer->pokeexpire = -1; 12047 peer->callno = 0; 12048 return 0; 12049 } 12050 12051 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 12052 12053 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 12054 if ((callno = peer->callno) > 0) { 12055 ast_log(LOG_NOTICE, "Still have a callno...\n"); 12056 ast_mutex_lock(&iaxsl[callno]); 12057 iax2_destroy(callno); 12058 ast_mutex_unlock(&iaxsl[callno]); 12059 } 12060 if (heldcall) 12061 ast_mutex_unlock(&iaxsl[heldcall]); 12062 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0); 12063 if (heldcall) 12064 ast_mutex_lock(&iaxsl[heldcall]); 12065 if (peer->callno < 1) { 12066 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 12067 return -1; 12068 } 12069 12070 /* Speed up retransmission times for this qualify call */ 12071 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 12072 iaxs[peer->callno]->peerpoke = peer; 12073 12074 if (peer->pokeexpire > -1) { 12075 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 12076 peer->pokeexpire = -1; 12077 peer_unref(peer); 12078 } 12079 } 12080 12081 /* Queue up a new task to handle no reply */ 12082 /* If the host is already unreachable then use the unreachable interval instead */ 12083 if (peer->lastms < 0) 12084 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 12085 else 12086 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 12087 12088 if (peer->pokeexpire == -1) 12089 peer_unref(peer); 12090 12091 /* And send the poke */ 12092 ast_mutex_lock(&iaxsl[callno]); 12093 if (iaxs[callno]) { 12094 struct iax_ie_data ied = { 12095 .buf = { 0 }, 12096 .pos = 0, 12097 }; 12098 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 12099 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1); 12100 } 12101 ast_mutex_unlock(&iaxsl[callno]); 12102 12103 return 0; 12104 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12027 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
12028 { 12029 struct iax2_peer *peer = obj; 12030 12031 iax2_poke_peer(peer, 0); 12032 12033 return 0; 12034 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9109 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
09110 { 09111 struct iax2_peer *peer = (struct iax2_peer *)data; 09112 peer->pokeexpire = -1; 09113 #ifdef SCHED_MULTITHREADED 09114 if (schedule_action(__iax2_poke_peer_s, data)) 09115 #endif 09116 __iax2_poke_peer_s(data); 09117 return 0; 09118 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 3374 of file chan_iax2.c.
References ast_module_unref(), ast_set_flag64, ast_test_flag64, iax2_destroy_helper(), iax2_queue_hangup(), IAX_ALREADYGONE, iaxs, chan_iax2_pvt::owner, and ast_channel::tech_pvt.
Referenced by iax2_hangup(), and send_command_final().
03375 { 03376 struct ast_channel *c = NULL; 03377 struct chan_iax2_pvt *pvt = iaxs[callno]; 03378 03379 if (!pvt) 03380 return -1; 03381 03382 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) { 03383 iax2_destroy_helper(pvt); 03384 ast_set_flag64(pvt, IAX_ALREADYGONE); 03385 } 03386 03387 if ((c = pvt->owner)) { 03388 c->tech_pvt = NULL; 03389 iax2_queue_hangup(callno); 03390 pvt->owner = NULL; 03391 ast_module_unref(ast_module_info->self); 03392 } 03393 03394 return 0; 03395 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 11666 of file chan_iax2.c.
References ast_atomic_fetchadd_int(), ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), iax2_process_thread_cleanup(), IAX_THREAD_TYPE_DYNAMIC, iaxactivethreadcount, insert_idle_thread(), signal_condition(), and thread.
Referenced by find_idle_thread(), and start_network_thread().
11667 { 11668 struct iax2_thread *thread = data; 11669 struct timeval wait; 11670 struct timespec ts; 11671 int put_into_idle = 0; 11672 int first_time = 1; 11673 int old_state; 11674 11675 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1); 11676 11677 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state); 11678 pthread_cleanup_push(iax2_process_thread_cleanup, data); 11679 11680 for (;;) { 11681 /* Wait for something to signal us to be awake */ 11682 ast_mutex_lock(&thread->lock); 11683 11684 if (thread->stop) { 11685 ast_mutex_unlock(&thread->lock); 11686 break; 11687 } 11688 11689 /* Flag that we're ready to accept signals */ 11690 if (first_time) { 11691 signal_condition(&thread->init_lock, &thread->init_cond); 11692 first_time = 0; 11693 } 11694 11695 /* Put into idle list if applicable */ 11696 if (put_into_idle) { 11697 insert_idle_thread(thread); 11698 } 11699 11700 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 11701 struct iax2_thread *t = NULL; 11702 /* Wait to be signalled or time out */ 11703 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11704 ts.tv_sec = wait.tv_sec; 11705 ts.tv_nsec = wait.tv_usec * 1000; 11706 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11707 /* This thread was never put back into the available dynamic 11708 * thread list, so just go away. */ 11709 if (!put_into_idle || thread->stop) { 11710 ast_mutex_unlock(&thread->lock); 11711 break; 11712 } 11713 AST_LIST_LOCK(&dynamic_list); 11714 /* Account for the case where this thread is acquired *right* after a timeout */ 11715 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 11716 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1); 11717 AST_LIST_UNLOCK(&dynamic_list); 11718 if (t) { 11719 /* This dynamic thread timed out waiting for a task and was 11720 * not acquired immediately after the timeout, 11721 * so it's time to go away. */ 11722 ast_mutex_unlock(&thread->lock); 11723 break; 11724 } 11725 /* Someone grabbed our thread *right* after we timed out. 11726 * Wait for them to set us up with something to do and signal 11727 * us to continue. */ 11728 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11729 ts.tv_sec = wait.tv_sec; 11730 ts.tv_nsec = wait.tv_usec * 1000; 11731 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11732 ast_mutex_unlock(&thread->lock); 11733 break; 11734 } 11735 } 11736 } else { 11737 ast_cond_wait(&thread->cond, &thread->lock); 11738 } 11739 11740 /* Go back into our respective list */ 11741 put_into_idle = 1; 11742 11743 ast_mutex_unlock(&thread->lock); 11744 11745 if (thread->stop) { 11746 break; 11747 } 11748 11749 if (thread->iostate == IAX_IOSTATE_IDLE) 11750 continue; 11751 11752 /* See what we need to do */ 11753 switch (thread->iostate) { 11754 case IAX_IOSTATE_READY: 11755 thread->actions++; 11756 thread->iostate = IAX_IOSTATE_PROCESSING; 11757 socket_process(thread); 11758 handle_deferred_full_frames(thread); 11759 break; 11760 case IAX_IOSTATE_SCHEDREADY: 11761 thread->actions++; 11762 thread->iostate = IAX_IOSTATE_PROCESSING; 11763 #ifdef SCHED_MULTITHREADED 11764 thread->schedfunc(thread->scheddata); 11765 #endif 11766 default: 11767 break; 11768 } 11769 time(&thread->checktime); 11770 thread->iostate = IAX_IOSTATE_IDLE; 11771 #ifdef DEBUG_SCHED_MULTITHREAD 11772 thread->curfunc[0]='\0'; 11773 #endif 11774 11775 /* The network thread added us to the active_thread list when we were given 11776 * frames to process, Now that we are done, we must remove ourselves from 11777 * the active list, and return to the idle list */ 11778 AST_LIST_LOCK(&active_list); 11779 AST_LIST_REMOVE(&active_list, thread, list); 11780 AST_LIST_UNLOCK(&active_list); 11781 11782 /* Make sure another frame didn't sneak in there after we thought we were done. */ 11783 handle_deferred_full_frames(thread); 11784 } 11785 11786 /*! 11787 * \note For some reason, idle threads are exiting without being removed 11788 * from an idle list, which is causing memory corruption. Forcibly remove 11789 * it from the list, if it's there. 11790 */ 11791 AST_LIST_LOCK(&idle_list); 11792 AST_LIST_REMOVE(&idle_list, thread, list); 11793 AST_LIST_UNLOCK(&idle_list); 11794 11795 AST_LIST_LOCK(&dynamic_list); 11796 AST_LIST_REMOVE(&dynamic_list, thread, list); 11797 AST_LIST_UNLOCK(&dynamic_list); 11798 11799 if (!thread->stop) { 11800 /* Nobody asked me to stop so nobody is waiting to join me. */ 11801 pthread_detach(pthread_self()); 11802 } 11803 11804 /* I am exiting here on my own volition, I need to clean up my own data structures 11805 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 11806 */ 11807 pthread_cleanup_pop(1); 11808 return NULL; 11809 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 11654 of file chan_iax2.c.
References ast_atomic_dec_and_test(), ast_cond_destroy, ast_free, ast_mutex_destroy, iaxactivethreadcount, and thread.
Referenced by iax2_process_thread().
11655 { 11656 struct iax2_thread *thread = data; 11657 ast_mutex_destroy(&thread->lock); 11658 ast_cond_destroy(&thread->cond); 11659 ast_mutex_destroy(&thread->init_lock); 11660 ast_cond_destroy(&thread->init_cond); 11661 ast_free(thread); 11662 /* Ignore check_return warning from Coverity for ast_atomic_dec_and_test below */ 11663 ast_atomic_dec_and_test(&iaxactivethreadcount); 11664 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
const char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 11872 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_unlock, ast_set_flag64, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, create_addr(), find_callno_locked(), iax2_sched_replace(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), iaxs, iaxsl, NEW_FORCE, iax_ie_data::pos, sched, and send_command().
Referenced by check_provisioning(), handle_cli_iax2_provision(), and iax2_prov_app().
11873 { 11874 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 11875 is found for template */ 11876 struct iax_ie_data provdata; 11877 struct iax_ie_data ied; 11878 unsigned int sig; 11879 struct sockaddr_in sin; 11880 int callno; 11881 struct create_addr_info cai; 11882 11883 memset(&cai, 0, sizeof(cai)); 11884 11885 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template); 11886 11887 if (iax_provision_build(&provdata, &sig, template, force)) { 11888 ast_debug(1, "No provisioning found for template '%s'\n", template); 11889 return 0; 11890 } 11891 11892 if (end) { 11893 memcpy(&sin, end, sizeof(sin)); 11894 cai.sockfd = sockfd; 11895 } else if (create_addr(dest, NULL, &sin, &cai)) 11896 return -1; 11897 11898 /* Build the rest of the message */ 11899 memset(&ied, 0, sizeof(ied)); 11900 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 11901 11902 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 11903 if (!callno) 11904 return -1; 11905 11906 if (iaxs[callno]) { 11907 /* Schedule autodestruct in case they don't ever give us anything back */ 11908 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 11909 sched, 15000, auto_hangup, (void *)(long)callno); 11910 ast_set_flag64(iaxs[callno], IAX_PROVISION); 11911 /* Got a call number now, so go ahead and send the provisioning information */ 11912 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 11913 } 11914 ast_mutex_unlock(&iaxsl[callno]); 11915 11916 return 1; 11917 }
static int iax2_queryoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int * | datalen | |||
) | [static] |
Definition at line 5373 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_unlock, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, ast_test_flag64, chan_iax2_pvt::callno, IAX_FORCE_ENCRYPT, iaxs, iaxsl, PTR_TO_CALLNO, and ast_channel::tech_pvt.
05374 { 05375 switch (option) { 05376 case AST_OPTION_SECURE_SIGNALING: 05377 case AST_OPTION_SECURE_MEDIA: 05378 { 05379 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05380 ast_mutex_lock(&iaxsl[callno]); 05381 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0; 05382 ast_mutex_unlock(&iaxsl[callno]); 05383 return 0; 05384 } 05385 default: 05386 return -1; 05387 } 05388 }
static int iax2_queue_control_data | ( | int | callno, | |
enum ast_control_frame_type | control, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Queue a control frame on the ast_channel owner.
This function queues a control frame on the owner of the IAX2 pvt struct that is active for the given call number.
Definition at line 3007 of file chan_iax2.c.
References ast_channel_unlock, ast_queue_control_data(), iax2_lock_owner(), iaxs, and chan_iax2_pvt::owner.
Referenced by socket_process().
03009 { 03010 iax2_lock_owner(callno); 03011 if (iaxs[callno] && iaxs[callno]->owner) { 03012 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 03013 ast_channel_unlock(iaxs[callno]->owner); 03014 } 03015 return 0; 03016 }
static int iax2_queue_frame | ( | int | callno, | |
struct ast_frame * | f | |||
) | [static] |
Queue a frame to a call's owning asterisk channel.
Definition at line 2961 of file chan_iax2.c.
References ast_channel_unlock, ast_queue_frame(), f, iax2_lock_owner(), iaxs, and chan_iax2_pvt::owner.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), __get_from_jb(), and socket_process().
02962 { 02963 iax2_lock_owner(callno); 02964 if (iaxs[callno] && iaxs[callno]->owner) { 02965 ast_queue_frame(iaxs[callno]->owner, f); 02966 ast_channel_unlock(iaxs[callno]->owner); 02967 } 02968 return 0; 02969 }
static int iax2_queue_hangup | ( | int | callno | ) | [static] |
Queue a hangup frame on the ast_channel owner.
This function queues a hangup frame on the owner of the IAX2 pvt struct that is active for the given call number.
Definition at line 2984 of file chan_iax2.c.
References ast_channel_unlock, ast_queue_hangup(), iax2_lock_owner(), iaxs, and chan_iax2_pvt::owner.
Referenced by iax2_predestroy().
02985 { 02986 iax2_lock_owner(callno); 02987 if (iaxs[callno] && iaxs[callno]->owner) { 02988 ast_queue_hangup(iaxs[callno]->owner); 02989 ast_channel_unlock(iaxs[callno]->owner); 02990 } 02991 return 0; 02992 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5390 of file chan_iax2.c.
References ast_debug, and ast_null_frame.
05391 { 05392 ast_debug(1, "I should never be called!\n"); 05393 return &ast_null_frame; 05394 }
static int iax2_register | ( | const char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 8545 of file chan_iax2.c.
References ast_copy_string(), ast_log(), copy(), hostname, iax2_append_register(), LOG_WARNING, secret, and strsep().
Referenced by set_config().
08546 { 08547 char copy[256]; 08548 char *username, *hostname, *secret; 08549 char *porta; 08550 char *stringp=NULL; 08551 08552 if (!value) 08553 return -1; 08554 08555 ast_copy_string(copy, value, sizeof(copy)); 08556 stringp = copy; 08557 username = strsep(&stringp, "@"); 08558 hostname = strsep(&stringp, "@"); 08559 08560 if (!hostname) { 08561 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 08562 return -1; 08563 } 08564 08565 stringp = username; 08566 username = strsep(&stringp, ":"); 08567 secret = strsep(&stringp, ":"); 08568 stringp = hostname; 08569 hostname = strsep(&stringp, ":"); 08570 porta = strsep(&stringp, ":"); 08571 08572 if (porta && !atoi(porta)) { 08573 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 08574 return -1; 08575 } 08576 08577 return iax2_append_register(hostname, username, secret, porta); 08578 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 12116 of file chan_iax2.c.
References ast_best_codec(), AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_flags64, ast_getformatname(), ast_hangup(), ast_iax2_new(), ast_log(), ast_mutex_unlock, AST_STATE_DOWN, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_translator_best_choice(), create_addr(), find_callno_locked(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iaxsl, ast_channel::linkedid, LOG_WARNING, make_trunk(), chan_iax2_pvt::maxtime, ast_channel::name, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), chan_iax2_pvt::peer, ast_channel::readformat, and ast_channel::writeformat.
12117 { 12118 int callno; 12119 int res; 12120 format_t fmt, native; 12121 struct sockaddr_in sin; 12122 struct ast_channel *c; 12123 struct parsed_dial_string pds; 12124 struct create_addr_info cai; 12125 char *tmpstr; 12126 12127 memset(&pds, 0, sizeof(pds)); 12128 tmpstr = ast_strdupa(data); 12129 parse_dial_string(tmpstr, &pds); 12130 12131 if (ast_strlen_zero(pds.peer)) { 12132 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 12133 return NULL; 12134 } 12135 12136 memset(&cai, 0, sizeof(cai)); 12137 cai.capability = iax2_capability; 12138 12139 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12140 12141 /* Populate our address from the given */ 12142 if (create_addr(pds.peer, NULL, &sin, &cai)) { 12143 *cause = AST_CAUSE_UNREGISTERED; 12144 return NULL; 12145 } 12146 12147 if (pds.port) 12148 sin.sin_port = htons(atoi(pds.port)); 12149 12150 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 12151 if (callno < 1) { 12152 ast_log(LOG_WARNING, "Unable to create call\n"); 12153 *cause = AST_CAUSE_CONGESTION; 12154 return NULL; 12155 } 12156 12157 /* If this is a trunk, update it now */ 12158 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12159 if (ast_test_flag64(&cai, IAX_TRUNK)) { 12160 int new_callno; 12161 if ((new_callno = make_trunk(callno, 1)) != -1) 12162 callno = new_callno; 12163 } 12164 iaxs[callno]->maxtime = cai.maxtime; 12165 if (cai.found) 12166 ast_string_field_set(iaxs[callno], host, pds.peer); 12167 12168 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL); 12169 12170 ast_mutex_unlock(&iaxsl[callno]); 12171 12172 if (c) { 12173 /* Choose a format we can live with */ 12174 if (c->nativeformats & format) 12175 c->nativeformats &= format; 12176 else { 12177 native = c->nativeformats; 12178 fmt = format; 12179 res = ast_translator_best_choice(&fmt, &native); 12180 if (res < 0) { 12181 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 12182 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 12183 ast_hangup(c); 12184 return NULL; 12185 } 12186 c->nativeformats = native; 12187 } 12188 c->readformat = ast_best_codec(c->nativeformats); 12189 c->writeformat = c->readformat; 12190 } 12191 12192 return c; 12193 }
static int iax2_sched_add | ( | struct ast_sched_thread * | st, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 1497 of file chan_iax2.c.
References ast_sched_thread_add().
Referenced by __attempt_transmit(), __find_callno(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), iax2_call(), iax2_poke_peer(), make_trunk(), network_change_event_cb(), reg_source_db(), sched_delay_remove(), socket_process(), transmit_frame(), and update_registry().
01499 { 01500 return ast_sched_thread_add(st, when, callback, data); 01501 }
static int iax2_sched_replace | ( | int | id, | |
struct ast_sched_thread * | st, | |||
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 1489 of file chan_iax2.c.
References ast_sched_thread_add(), and ast_sched_thread_del.
Referenced by auth_fail(), iax2_ack_registry(), iax2_do_register(), iax2_dprequest(), iax2_provision(), and update_jbsched().
01491 { 01492 ast_sched_thread_del(st, id); 01493 01494 return ast_sched_thread_add(st, when, callback, data); 01495 }
static int iax2_send | ( | struct chan_iax2_pvt * | pvt, | |
struct ast_frame * | f, | |||
unsigned int | ts, | |||
int | seqno, | |||
int | now, | |||
int | transfer, | |||
int | final | |||
) | [static] |
Definition at line 6371 of file chan_iax2.c.
References iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag64, calc_timestamp(), ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, chan_iax2_pvt::callno, iax_frame::callno, ast_frame_subclass::codec, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, ast_frame::datalen, iax_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, iax_frame::encmethods, encrypt_frame(), f, iax_frame::final, chan_iax2_pvt::first_iax_message, ast_frame::frametype, iax2_key_rotate(), iax2_transmit(), iax2_trunk_queue(), IAX_CALLENCRYPTED, IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_outputframe(), IAX_TRUNK, ast_frame_subclass::integer, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::last_iax_message, chan_iax2_pvt::lastsent, chan_iax2_pvt::lastvsent, LOG_NOTICE, LOG_WARNING, MARK_IAX_SUBCLASS_TX, MAX_RETRY_TIME, MIN_RETRY_TIME, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, ast_frame::ptr, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, iax_frame::transfer, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.
Referenced by __send_command(), iax2_write(), send_signaling(), and socket_process().
06372 { 06373 /* Queue a packet for delivery on a given private structure. Use "ts" for 06374 timestamp, or calculate if ts is 0. Send immediately without retransmission 06375 or delayed, with retransmission */ 06376 struct ast_iax2_full_hdr *fh; 06377 struct ast_iax2_mini_hdr *mh; 06378 struct ast_iax2_video_hdr *vh; 06379 struct { 06380 struct iax_frame fr2; 06381 unsigned char buffer[4096]; 06382 } frb; 06383 struct iax_frame *fr; 06384 int res; 06385 int sendmini=0; 06386 unsigned int lastsent; 06387 unsigned int fts; 06388 06389 frb.fr2.afdatalen = sizeof(frb.buffer); 06390 06391 if (!pvt) { 06392 ast_log(LOG_WARNING, "No private structure for packet?\n"); 06393 return -1; 06394 } 06395 06396 lastsent = pvt->lastsent; 06397 06398 /* Calculate actual timestamp */ 06399 fts = calc_timestamp(pvt, ts, f); 06400 06401 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 06402 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 06403 * increment the "predicted timestamps" for voice, if we're predicting */ 06404 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 06405 return 0; 06406 #if 0 06407 ast_log(LOG_NOTICE, 06408 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n", 06409 *("=!" + (f->frametype == AST_FRAME_VOICE)), 06410 IAX_CALLENCRYPTED(pvt) ? "" : "not ", 06411 pvt->keyrotateid != -1 ? "" : "no " 06412 ); 06413 #endif 06414 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) { 06415 iax2_key_rotate(pvt); 06416 } 06417 06418 if ((ast_test_flag64(pvt, IAX_TRUNK) || 06419 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 06420 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 06421 /* High two bytes are the same on timestamp, or sending on a trunk */ && 06422 (f->frametype == AST_FRAME_VOICE) 06423 /* is a voice frame */ && 06424 (f->subclass.codec == pvt->svoiceformat) 06425 /* is the same type */ ) { 06426 /* Force immediate rather than delayed transmission */ 06427 now = 1; 06428 /* Mark that mini-style frame is appropriate */ 06429 sendmini = 1; 06430 } 06431 if ( f->frametype == AST_FRAME_VIDEO ) { 06432 /* 06433 * If the lower 15 bits of the timestamp roll over, or if 06434 * the video format changed then send a full frame. 06435 * Otherwise send a mini video frame 06436 */ 06437 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 06438 ((f->subclass.codec & ~0x1LL) == pvt->svideoformat) 06439 ) { 06440 now = 1; 06441 sendmini = 1; 06442 } else { 06443 now = 0; 06444 sendmini = 0; 06445 } 06446 pvt->lastvsent = fts; 06447 } 06448 if (f->frametype == AST_FRAME_IAX) { 06449 /* 0x8000 marks this message as TX:, this bit will be stripped later */ 06450 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX; 06451 if (!pvt->first_iax_message) { 06452 pvt->first_iax_message = pvt->last_iax_message; 06453 } 06454 } 06455 /* Allocate an iax_frame */ 06456 if (now) { 06457 fr = &frb.fr2; 06458 } else 06459 fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag64(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO)); 06460 if (!fr) { 06461 ast_log(LOG_WARNING, "Out of memory\n"); 06462 return -1; 06463 } 06464 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 06465 iax_frame_wrap(fr, f); 06466 06467 fr->ts = fts; 06468 fr->callno = pvt->callno; 06469 fr->transfer = transfer; 06470 fr->final = final; 06471 fr->encmethods = 0; 06472 if (!sendmini) { 06473 /* We need a full frame */ 06474 if (seqno > -1) 06475 fr->oseqno = seqno; 06476 else 06477 fr->oseqno = pvt->oseqno++; 06478 fr->iseqno = pvt->iseqno; 06479 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr)); 06480 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 06481 fh->ts = htonl(fr->ts); 06482 fh->oseqno = fr->oseqno; 06483 if (transfer) { 06484 fh->iseqno = 0; 06485 } else 06486 fh->iseqno = fr->iseqno; 06487 /* Keep track of the last thing we've acknowledged */ 06488 if (!transfer) 06489 pvt->aseqno = fr->iseqno; 06490 fh->type = fr->af.frametype & 0xFF; 06491 06492 if (fr->af.frametype == AST_FRAME_VIDEO) { 06493 fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6); 06494 } else if (fr->af.frametype == AST_FRAME_VOICE) { 06495 fh->csub = compress_subclass(fr->af.subclass.codec); 06496 } else { 06497 fh->csub = compress_subclass(fr->af.subclass.integer); 06498 } 06499 06500 if (transfer) { 06501 fr->dcallno = pvt->transfercallno; 06502 } else 06503 fr->dcallno = pvt->peercallno; 06504 fh->dcallno = htons(fr->dcallno); 06505 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 06506 fr->data = fh; 06507 fr->retries = 0; 06508 /* Retry after 2x the ping time has passed */ 06509 fr->retrytime = pvt->pingtime * 2; 06510 if (fr->retrytime < MIN_RETRY_TIME) 06511 fr->retrytime = MIN_RETRY_TIME; 06512 if (fr->retrytime > MAX_RETRY_TIME) 06513 fr->retrytime = MAX_RETRY_TIME; 06514 /* Acks' don't get retried */ 06515 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK)) 06516 fr->retries = -1; 06517 else if (f->frametype == AST_FRAME_VOICE) 06518 pvt->svoiceformat = f->subclass.codec; 06519 else if (f->frametype == AST_FRAME_VIDEO) 06520 pvt->svideoformat = f->subclass.codec & ~0x1LL; 06521 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06522 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06523 if (fr->transfer) 06524 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06525 else 06526 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06527 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 06528 fr->encmethods = pvt->encmethods; 06529 fr->ecx = pvt->ecx; 06530 fr->mydcx = pvt->mydcx; 06531 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand)); 06532 } else 06533 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06534 } 06535 06536 if (now) { 06537 res = send_packet(fr); 06538 } else 06539 res = iax2_transmit(fr); 06540 } else { 06541 if (ast_test_flag64(pvt, IAX_TRUNK)) { 06542 iax2_trunk_queue(pvt, fr); 06543 res = 0; 06544 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 06545 /* Video frame have no sequence number */ 06546 fr->oseqno = -1; 06547 fr->iseqno = -1; 06548 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr)); 06549 vh->zeros = 0; 06550 vh->callno = htons(0x8000 | fr->callno); 06551 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0)); 06552 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 06553 fr->data = vh; 06554 fr->retries = -1; 06555 res = send_packet(fr); 06556 } else { 06557 /* Mini-frames have no sequence number */ 06558 fr->oseqno = -1; 06559 fr->iseqno = -1; 06560 /* Mini frame will do */ 06561 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr)); 06562 mh->callno = htons(fr->callno); 06563 mh->ts = htons(fr->ts & 0xFFFF); 06564 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 06565 fr->data = mh; 06566 fr->retries = -1; 06567 if (pvt->transferring == TRANSFER_MEDIAPASS) 06568 fr->transfer = 1; 06569 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06570 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06571 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 06572 } else 06573 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06574 } 06575 res = send_packet(fr); 06576 } 06577 } 06578 return res; 06579 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 4318 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04319 { 04320 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 04321 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 4313 of file chan_iax2.c.
References AST_FRAME_IMAGE, ast_frame::data, ast_frame::datalen, ast_frame_subclass::integer, ast_frame::ptr, PTR_TO_CALLNO, send_command_locked(), ast_frame::subclass, and ast_channel::tech_pvt.
04314 { 04315 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1); 04316 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 4306 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04307 { 04308 04309 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 04310 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 04311 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 5301 of file chan_iax2.c.
References ast_clear_flag64, AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_free, ast_malloc, ast_mutex_lock, ast_mutex_unlock, AST_OPTION_AUDIO_MODE, AST_OPTION_DIGIT_DETECT, AST_OPTION_FAX_DETECT, AST_OPTION_FLAG_REQUEST, AST_OPTION_OPRMODE, AST_OPTION_RELAXDTMF, AST_OPTION_RXGAIN, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_OPTION_TXGAIN, ast_set_flag64, errno, IAX_FORCE_ENCRYPT, iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().
05302 { 05303 struct ast_option_header *h; 05304 int res; 05305 05306 switch (option) { 05307 case AST_OPTION_TXGAIN: 05308 case AST_OPTION_RXGAIN: 05309 /* these two cannot be sent, because they require a result */ 05310 errno = ENOSYS; 05311 return -1; 05312 case AST_OPTION_OPRMODE: 05313 errno = EINVAL; 05314 return -1; 05315 case AST_OPTION_SECURE_SIGNALING: 05316 case AST_OPTION_SECURE_MEDIA: 05317 { 05318 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05319 ast_mutex_lock(&iaxsl[callno]); 05320 if ((*(int *) data)) { 05321 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05322 } else { 05323 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05324 } 05325 ast_mutex_unlock(&iaxsl[callno]); 05326 return 0; 05327 } 05328 /* These options are sent to the other side across the network where 05329 * they will be passed to whatever channel is bridged there. Don't 05330 * do anything silly like pass an option that transmits pointers to 05331 * memory on this machine to a remote machine to use */ 05332 case AST_OPTION_TONE_VERIFY: 05333 case AST_OPTION_TDD: 05334 case AST_OPTION_RELAXDTMF: 05335 case AST_OPTION_AUDIO_MODE: 05336 case AST_OPTION_DIGIT_DETECT: 05337 case AST_OPTION_FAX_DETECT: 05338 { 05339 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05340 struct chan_iax2_pvt *pvt; 05341 05342 ast_mutex_lock(&iaxsl[callno]); 05343 pvt = iaxs[callno]; 05344 05345 if (wait_for_peercallno(pvt)) { 05346 ast_mutex_unlock(&iaxsl[callno]); 05347 return -1; 05348 } 05349 05350 ast_mutex_unlock(&iaxsl[callno]); 05351 05352 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 05353 return -1; 05354 } 05355 05356 h->flag = AST_OPTION_FLAG_REQUEST; 05357 h->option = htons(option); 05358 memcpy(h->data, data, datalen); 05359 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 05360 AST_CONTROL_OPTION, 0, (unsigned char *) h, 05361 datalen + sizeof(*h), -1); 05362 ast_free(h); 05363 return res; 05364 } 05365 default: 05366 return -1; 05367 } 05368 05369 /* Just in case someone does a break instead of a return */ 05370 return -1; 05371 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 5429 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_random(), ast_set_flag64, IAX_CALLENCRYPTED, IAX_COMMAND_TXREQ, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), IAX_IE_CALLNO, IAX_IE_TRANSFERID, IAX_NOTRANSFER, iaxs, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.
05430 { 05431 int res; 05432 struct iax_ie_data ied0; 05433 struct iax_ie_data ied1; 05434 unsigned int transferid = (unsigned int)ast_random(); 05435 05436 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) { 05437 ast_debug(1, "transfers are not supported for encrypted calls at this time\n"); 05438 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER); 05439 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER); 05440 return 0; 05441 } 05442 05443 memset(&ied0, 0, sizeof(ied0)); 05444 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 05445 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 05446 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 05447 05448 memset(&ied1, 0, sizeof(ied1)); 05449 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 05450 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 05451 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 05452 05453 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 05454 if (res) 05455 return -1; 05456 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 05457 if (res) 05458 return -1; 05459 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05460 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05461 return 0; 05462 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 5688 of file chan_iax2.c.
References AST_CONTROL_TRANSFER, ast_copy_string(), ast_debug, AST_FRAME_IAX, ast_queue_control_data(), AST_TRANSFER_SUCCESS, chan_iax2_pvt::callno, context, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, ast_channel::name, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
05689 { 05690 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05691 struct iax_ie_data ied = { "", }; 05692 char tmp[256], *context; 05693 enum ast_control_transfer message = AST_TRANSFER_SUCCESS; 05694 ast_copy_string(tmp, dest, sizeof(tmp)); 05695 context = strchr(tmp, '@'); 05696 if (context) { 05697 *context = '\0'; 05698 context++; 05699 } 05700 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 05701 if (context) 05702 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 05703 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest); 05704 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message)); 05705 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 05706 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 4289 of file chan_iax2.c.
References ast_taskprocessor_push(), iax_frame::sentyet, and transmit_frame().
Referenced by iax2_send().
04290 { 04291 fr->sentyet = 0; 04292 04293 return ast_taskprocessor_push(transmit_processor, transmit_frame, fr); 04294 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 9163 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
09164 { 09165 /* Drop when trunk is about 5 seconds idle */ 09166 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 09167 return 1; 09168 return 0; 09169 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 6109 of file chan_iax2.c.
References iax2_trunk_peer::addr, chan_iax2_pvt::addr, iax_frame::af, ast_debug, ast_inet_ntoa(), ast_log(), ast_mutex_unlock, ast_realloc, ast_test_flag64, ast_tvnow(), ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, DEFAULT_TRUNKDATA, f, find_tpeer(), globalflags, IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_iax2_meta_trunk_mini::mini, send_trunk(), chan_iax2_pvt::sockfd, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, iax_frame::ts, and ast_iax2_mini_hdr::ts.
Referenced by iax2_send().
06110 { 06111 struct ast_frame *f; 06112 struct iax2_trunk_peer *tpeer; 06113 void *tmp, *ptr; 06114 struct timeval now; 06115 struct ast_iax2_meta_trunk_entry *met; 06116 struct ast_iax2_meta_trunk_mini *mtm; 06117 06118 f = &fr->af; 06119 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 06120 if (tpeer) { 06121 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 06122 /* Need to reallocate space */ 06123 if (tpeer->trunkdataalloc < trunkmaxsize) { 06124 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 06125 ast_mutex_unlock(&tpeer->lock); 06126 return -1; 06127 } 06128 06129 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 06130 tpeer->trunkdata = tmp; 06131 ast_debug(1, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc); 06132 } else { 06133 ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s:%d\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 06134 ast_mutex_unlock(&tpeer->lock); 06135 return -1; 06136 } 06137 } 06138 06139 /* Append to meta frame */ 06140 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 06141 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) { 06142 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06143 mtm->len = htons(f->datalen); 06144 mtm->mini.callno = htons(pvt->callno); 06145 mtm->mini.ts = htons(0xffff & fr->ts); 06146 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 06147 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 06148 } else { 06149 met = (struct ast_iax2_meta_trunk_entry *)ptr; 06150 /* Store call number and length in meta header */ 06151 met->callno = htons(pvt->callno); 06152 met->len = htons(f->datalen); 06153 /* Advance pointers/decrease length past trunk entry header */ 06154 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 06155 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 06156 } 06157 /* Copy actual trunk data */ 06158 memcpy(ptr, f->data.ptr, f->datalen); 06159 tpeer->trunkdatalen += f->datalen; 06160 06161 tpeer->calls++; 06162 06163 /* track the largest mtu we actually have sent */ 06164 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 06165 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 06166 06167 /* if we have enough for a full MTU, ship it now without waiting */ 06168 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) { 06169 now = ast_tvnow(); 06170 send_trunk(tpeer, &now); 06171 trunk_untimed ++; 06172 } 06173 06174 ast_mutex_unlock(&tpeer->lock); 06175 } 06176 return 0; 06177 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 9084 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process(), and socket_process_meta().
09085 { 09086 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 09087 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 7452 of file chan_iax2.c.
References ast_debug, AST_FRAME_NULL, AST_FRAME_VOICE, ast_mutex_lock, ast_mutex_unlock, ast_test_flag, ast_test_flag64, errno, f, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, PTR_TO_CALLNO, state, and ast_channel::tech_pvt.
07453 { 07454 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 07455 int res = -1; 07456 ast_mutex_lock(&iaxsl[callno]); 07457 if (iaxs[callno]) { 07458 /* If there's an outstanding error, return failure now */ 07459 if (!iaxs[callno]->error) { 07460 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) 07461 res = 0; 07462 /* Don't waste bandwidth sending null frames */ 07463 else if (f->frametype == AST_FRAME_NULL) 07464 res = 0; 07465 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH)) 07466 res = 0; 07467 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 07468 res = 0; 07469 else 07470 /* Simple, just queue for transmission */ 07471 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 07472 } else { 07473 ast_debug(1, "Write error: %s\n", strerror(errno)); 07474 } 07475 } 07476 /* If it's already gone, just return */ 07477 ast_mutex_unlock(&iaxsl[callno]); 07478 return res; 07479 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 3166 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_iax2_firmware_header::devname, iax_firmware::fwh, iax2_trunk_peer::list, and ast_iax2_firmware_header::version.
Referenced by update_registry().
03167 { 03168 int res = 0; 03169 struct iax_firmware *cur = NULL; 03170 03171 if (ast_strlen_zero(dev)) 03172 return 0; 03173 03174 AST_LIST_LOCK(&firmwares); 03175 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03176 if (!strcmp(dev, (char *)cur->fwh->devname)) { 03177 res = ntohs(cur->fwh->version); 03178 break; 03179 } 03180 } 03181 AST_LIST_UNLOCK(&firmwares); 03182 03183 return res; 03184 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 1120 of file chan_iax2.c.
References ast_verbose.
Referenced by load_module().
01121 { 01122 if (iaxdebug) 01123 ast_verbose("%s", data); 01124 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 1126 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
01127 { 01128 ast_log(LOG_WARNING, "%s", data); 01129 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 3186 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, iax_firmware::fwh, iax_ie_append(), iax_ie_append_int(), iax_ie_append_raw(), IAX_IE_FWBLOCKDATA, IAX_IE_FWBLOCKDESC, and iax2_trunk_peer::list.
Referenced by socket_process().
03187 { 03188 int res = -1; 03189 unsigned int bs = desc & 0xff; 03190 unsigned int start = (desc >> 8) & 0xffffff; 03191 unsigned int bytes; 03192 struct iax_firmware *cur; 03193 03194 if (ast_strlen_zero((char *)dev) || !bs) 03195 return -1; 03196 03197 start *= bs; 03198 03199 AST_LIST_LOCK(&firmwares); 03200 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03201 if (strcmp((char *)dev, (char *)cur->fwh->devname)) 03202 continue; 03203 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 03204 if (start < ntohl(cur->fwh->datalen)) { 03205 bytes = ntohl(cur->fwh->datalen) - start; 03206 if (bytes > bs) 03207 bytes = bs; 03208 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 03209 } else { 03210 bytes = 0; 03211 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 03212 } 03213 if (bytes == bs) 03214 res = 0; 03215 else 03216 res = 1; 03217 break; 03218 } 03219 AST_LIST_UNLOCK(&firmwares); 03220 03221 return res; 03222 }
static void iax_outputframe | ( | struct iax_frame * | f, | |
struct ast_iax2_full_hdr * | fhi, | |||
int | rx, | |||
struct sockaddr_in * | sin, | |||
int | datalen | |||
) | [static] |
Definition at line 1103 of file chan_iax2.c.
References debugaddr, f, and iax_showframe().
Referenced by iax2_send(), raw_hangup(), send_apathetic_reply(), and socket_process().
01104 { 01105 if (iaxdebug || 01106 (sin && debugaddr.sin_addr.s_addr && 01107 (!ntohs(debugaddr.sin_port) || 01108 debugaddr.sin_port == sin->sin_port) && 01109 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) { 01110 if (iaxdebug) { 01111 iax_showframe(f, fhi, rx, sin, datalen); 01112 } else { 01113 iaxdebug = 1; 01114 iax_showframe(f, fhi, rx, sin, datalen); 01115 iaxdebug = 0; 01116 } 01117 } 01118 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2, | |||
const char * | park_exten, | |||
const char * | park_context | |||
) | [static] |
DO NOT hold any locks while calling iax_park
Definition at line 9334 of file chan_iax2.c.
References ast_channel::accountcode, ast_channel::amaflags, ast_calloc, ast_channel_alloc, ast_channel_masquerade(), ast_copy_string(), ast_do_masquerade(), ast_free, ast_hangup(), ast_pthread_create_detached_background, AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_channel::context, ast_channel::exten, iax_park_thread(), ast_channel::linkedid, ast_channel::name, ast_channel::parkinglot, parkinglot, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_process().
09335 { 09336 struct iax_dual *d; 09337 struct ast_channel *chan1m, *chan2m;/* Chan2m: The transferer, chan1m: The transferee */ 09338 pthread_t th; 09339 09340 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name); 09341 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name); 09342 d = ast_calloc(1, sizeof(*d)); 09343 if (!chan1m || !chan2m || !d) { 09344 if (chan1m) { 09345 ast_hangup(chan1m); 09346 } 09347 if (chan2m) { 09348 ast_hangup(chan2m); 09349 } 09350 ast_free(d); 09351 return -1; 09352 } 09353 d->park_exten = ast_strdup(park_exten); 09354 d->park_context = ast_strdup(park_context); 09355 if (!d->park_exten || !d->park_context) { 09356 ast_hangup(chan1m); 09357 ast_hangup(chan2m); 09358 ast_free(d->park_exten); 09359 ast_free(d->park_context); 09360 ast_free(d); 09361 return -1; 09362 } 09363 09364 /* Make formats okay */ 09365 chan1m->readformat = chan1->readformat; 09366 chan1m->writeformat = chan1->writeformat; 09367 09368 /* Prepare for taking over the channel */ 09369 if (ast_channel_masquerade(chan1m, chan1)) { 09370 ast_hangup(chan1m); 09371 ast_hangup(chan2m); 09372 ast_free(d->park_exten); 09373 ast_free(d->park_context); 09374 ast_free(d); 09375 return -1; 09376 } 09377 09378 /* Setup the extensions and such */ 09379 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 09380 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 09381 chan1m->priority = chan1->priority; 09382 09383 ast_do_masquerade(chan1m); 09384 09385 /* We make a clone of the peer channel too, so we can play 09386 back the announcement */ 09387 09388 /* Make formats okay */ 09389 chan2m->readformat = chan2->readformat; 09390 chan2m->writeformat = chan2->writeformat; 09391 ast_string_field_set(chan2m, parkinglot, chan2->parkinglot); 09392 09393 /* Prepare for taking over the channel */ 09394 if (ast_channel_masquerade(chan2m, chan2)) { 09395 ast_hangup(chan1m); 09396 ast_hangup(chan2m); 09397 ast_free(d->park_exten); 09398 ast_free(d->park_context); 09399 ast_free(d); 09400 return -1; 09401 } 09402 09403 /* Setup the extensions and such */ 09404 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 09405 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 09406 chan2m->priority = chan2->priority; 09407 09408 ast_do_masquerade(chan2m); 09409 09410 d->chan1 = chan1m; /* Transferee */ 09411 d->chan2 = chan2m; /* Transferer */ 09412 if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) { 09413 /* Could not start thread */ 09414 ast_hangup(chan1m); 09415 ast_hangup(chan2m); 09416 ast_free(d->park_exten); 09417 ast_free(d->park_context); 09418 ast_free(d); 09419 return -1; 09420 } 09421 return 0; 09422 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 9307 of file chan_iax2.c.
References ast_debug, ast_free, ast_hangup(), ast_log(), ast_park_call_exten(), iax_dual::chan1, iax_dual::chan2, ext, LOG_NOTICE, ast_channel::name, iax_dual::park_context, and iax_dual::park_exten.
Referenced by iax_park().
09308 { 09309 struct iax_dual *d; 09310 int res; 09311 int ext = 0; 09312 09313 d = stuff; 09314 09315 ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n", 09316 d->chan2->name, d->chan1->name); 09317 09318 res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext); 09319 if (res) { 09320 /* Parking failed. */ 09321 ast_hangup(d->chan1); 09322 } else { 09323 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 09324 } 09325 ast_hangup(d->chan2); 09326 09327 ast_free(d->park_exten); 09328 ast_free(d->park_context); 09329 ast_free(d); 09330 return NULL; 09331 }
Definition at line 1957 of file chan_iax2.c.
References iax_frame::af, iax_frame::afdatalen, iax_frame::cacheable, ast_frame::datalen, DIRECTION_INGRESS, iax_frame_new(), and iax_frame_wrap().
Referenced by socket_process(), and socket_process_meta().
01958 { 01959 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01960 if (new) { 01961 size_t afdatalen = new->afdatalen; 01962 memcpy(new, fr, sizeof(*new)); 01963 iax_frame_wrap(new, &fr->af); 01964 new->afdatalen = afdatalen; 01965 new->data = NULL; 01966 new->datalen = 0; 01967 new->direction = DIRECTION_INGRESS; 01968 new->retrans = -1; 01969 } 01970 return new; 01971 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 1379 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, IAX_THREAD_TYPE_DYNAMIC, iax2_trunk_peer::list, and thread.
Referenced by iax2_process_thread().
01380 { 01381 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 01382 AST_LIST_LOCK(&dynamic_list); 01383 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 01384 AST_LIST_UNLOCK(&dynamic_list); 01385 } else { 01386 AST_LIST_LOCK(&idle_list); 01387 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 01388 AST_LIST_UNLOCK(&idle_list); 01389 } 01390 01391 return; 01392 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 1155 of file chan_iax2.c.
References args, and ast_verbose.
Referenced by handle_cli_iax2_set_debug_jb().
01156 { 01157 va_list args; 01158 char buf[1024]; 01159 01160 va_start(args, fmt); 01161 vsnprintf(buf, sizeof(buf), fmt, args); 01162 va_end(args); 01163 01164 ast_verbose("%s", buf); 01165 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 1131 of file chan_iax2.c.
References args, ast_log(), and LOG_ERROR.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
01132 { 01133 va_list args; 01134 char buf[1024]; 01135 01136 va_start(args, fmt); 01137 vsnprintf(buf, sizeof(buf), fmt, args); 01138 va_end(args); 01139 01140 ast_log(LOG_ERROR, "%s", buf); 01141 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 1143 of file chan_iax2.c.
References args, ast_log(), and LOG_WARNING.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
01144 { 01145 va_list args; 01146 char buf[1024]; 01147 01148 va_start(args, fmt); 01149 vsnprintf(buf, sizeof(buf), fmt, args); 01150 va_end(args); 01151 01152 ast_log(LOG_WARNING, "%s", buf); 01153 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 14721 of file chan_iax2.c.
References __unload_module(), ao2_callback, ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register, ast_data_register_multiple, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_mutex_init, ast_netsock_init(), ast_netsock_list_alloc(), ast_random(), ast_realtime_require_field(), ast_register_application_xml, ast_register_switch(), ast_sched_thread_create(), ast_sched_thread_destroy(), AST_TEST_REGISTER, ast_timer_close(), ast_timer_open(), ast_timer_set_rate(), ast_verb, cli_iax2, config, iax2_registry::entry, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, iax2_data_providers, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), iax_error_output(), iax_provision_reload(), iax_set_error(), iax_set_output(), iaxpeer_function, iaxs, iaxsl, iaxvar_function, io, io_context_create(), io_context_destroy(), jb_error_output(), jb_setoutput(), jb_warning_output(), load_objects(), LOG_ERROR, manager_iax2_show_netstats(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_iax2_show_registry(), netsock, network_change_event_subscribe(), outsock, peer_set_sock_cb(), peers, reload_firmware(), RQ_CHAR, RQ_UINTEGER2, sched, SENTINEL, set_config(), start_network_thread(), and timer.
14722 { 14723 static const char config[] = "iax.conf"; 14724 int x = 0; 14725 struct iax2_registry *reg = NULL; 14726 14727 if (load_objects()) { 14728 return AST_MODULE_LOAD_FAILURE; 14729 } 14730 14731 memset(iaxs, 0, sizeof(iaxs)); 14732 14733 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14734 ast_mutex_init(&iaxsl[x]); 14735 } 14736 14737 if (!(sched = ast_sched_thread_create())) { 14738 ast_log(LOG_ERROR, "Failed to create scheduler thread\n"); 14739 return AST_MODULE_LOAD_FAILURE; 14740 } 14741 14742 if (!(io = io_context_create())) { 14743 ast_log(LOG_ERROR, "Failed to create I/O context\n"); 14744 sched = ast_sched_thread_destroy(sched); 14745 return AST_MODULE_LOAD_FAILURE; 14746 } 14747 14748 if (!(netsock = ast_netsock_list_alloc())) { 14749 ast_log(LOG_ERROR, "Failed to create netsock list\n"); 14750 io_context_destroy(io); 14751 sched = ast_sched_thread_destroy(sched); 14752 return AST_MODULE_LOAD_FAILURE; 14753 } 14754 ast_netsock_init(netsock); 14755 14756 outsock = ast_netsock_list_alloc(); 14757 if (!outsock) { 14758 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 14759 io_context_destroy(io); 14760 sched = ast_sched_thread_destroy(sched); 14761 return AST_MODULE_LOAD_FAILURE; 14762 } 14763 ast_netsock_init(outsock); 14764 14765 randomcalltokendata = ast_random(); 14766 14767 iax_set_output(iax_debug_output); 14768 iax_set_error(iax_error_output); 14769 jb_setoutput(jb_error_output, jb_warning_output, NULL); 14770 14771 if ((timer = ast_timer_open())) { 14772 ast_timer_set_rate(timer, 1000 / trunkfreq); 14773 } 14774 14775 if (set_config(config, 0) == -1) { 14776 if (timer) { 14777 ast_timer_close(timer); 14778 } 14779 return AST_MODULE_LOAD_DECLINE; 14780 } 14781 14782 #ifdef TEST_FRAMEWORK 14783 AST_TEST_REGISTER(test_iax2_peers_get); 14784 AST_TEST_REGISTER(test_iax2_users_get); 14785 #endif 14786 14787 /* Register AstData providers */ 14788 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers)); 14789 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14790 14791 ast_register_application_xml(papp, iax2_prov_app); 14792 14793 ast_custom_function_register(&iaxpeer_function); 14794 ast_custom_function_register(&iaxvar_function); 14795 14796 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers); 14797 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list); 14798 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats); 14799 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry); 14800 14801 if (ast_channel_register(&iax2_tech)) { 14802 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 14803 __unload_module(); 14804 return AST_MODULE_LOAD_FAILURE; 14805 } 14806 14807 if (ast_register_switch(&iax2_switch)) { 14808 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 14809 } 14810 14811 if (start_network_thread()) { 14812 ast_log(LOG_ERROR, "Unable to start network thread\n"); 14813 __unload_module(); 14814 return AST_MODULE_LOAD_FAILURE; 14815 } else { 14816 ast_verb(2, "IAX Ready and Listening\n"); 14817 } 14818 14819 AST_LIST_LOCK(®istrations); 14820 AST_LIST_TRAVERSE(®istrations, reg, entry) 14821 iax2_do_register(reg); 14822 AST_LIST_UNLOCK(®istrations); 14823 14824 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 14825 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 14826 14827 14828 reload_firmware(0); 14829 iax_provision_reload(0); 14830 14831 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL); 14832 14833 network_change_event_subscribe(); 14834 14835 return AST_MODULE_LOAD_SUCCESS; 14836 }
static int load_objects | ( | void | ) | [static] |
Definition at line 14483 of file chan_iax2.c.
References addr_range_cmp_cb(), addr_range_hash_cb(), ao2_container_alloc, ao2_ref, AST_MODULE_LOAD_FAILURE, ast_taskprocessor_get(), callno_limits, calltoken_ignores, create_callno_pools(), iax_peercallno_pvts, iax_transfercallno_pvts, MAX_PEER_BUCKETS, MAX_USER_BUCKETS, peer_cmp_cb(), peer_hash_cb(), peercnt_cmp_cb(), peercnt_hash_cb(), peercnts, peers, pvt_cmp_cb(), pvt_hash_cb(), TPS_REF_DEFAULT, transfercallno_pvt_cmp_cb(), transfercallno_pvt_hash_cb(), user_cmp_cb(), user_hash_cb(), and users.
Referenced by load_module().
14484 { 14485 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL; 14486 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL; 14487 14488 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) { 14489 goto container_fail; 14490 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) { 14491 goto container_fail; 14492 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) { 14493 goto container_fail; 14494 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) { 14495 goto container_fail; 14496 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) { 14497 goto container_fail; 14498 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14499 goto container_fail; 14500 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14501 goto container_fail; 14502 } else if (create_callno_pools()) { 14503 goto container_fail; 14504 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) { 14505 goto container_fail; 14506 } 14507 14508 return 0; 14509 14510 container_fail: 14511 if (peers) { 14512 ao2_ref(peers, -1); 14513 } 14514 if (users) { 14515 ao2_ref(users, -1); 14516 } 14517 if (iax_peercallno_pvts) { 14518 ao2_ref(iax_peercallno_pvts, -1); 14519 } 14520 if (iax_transfercallno_pvts) { 14521 ao2_ref(iax_transfercallno_pvts, -1); 14522 } 14523 if (peercnts) { 14524 ao2_ref(peercnts, -1); 14525 } 14526 if (callno_limits) { 14527 ao2_ref(callno_limits, -1); 14528 } 14529 if (calltoken_ignores) { 14530 ao2_ref(calltoken_ignores, -1); 14531 } 14532 if (callno_pool) { 14533 ao2_ref(callno_pool, -1); 14534 } 14535 if (callno_pool_trunk) { 14536 ao2_ref(callno_pool_trunk, -1); 14537 } 14538 return AST_MODULE_LOAD_FAILURE; 14539 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 5464 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_trylock, DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
05465 { 05466 ast_mutex_lock(&iaxsl[callno0]); 05467 while (ast_mutex_trylock(&iaxsl[callno1])) { 05468 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 05469 } 05470 }
static void log_jitterstats | ( | unsigned short | callno | ) | [static] |
Definition at line 9494 of file chan_iax2.c.
References ast_debug, ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, jb_info::current, iax_rr::delay, iax_rr::dropped, EVENT_FLAG_REPORTING, jb_info::frames_dropped, jb_info::frames_in, jb_info::frames_lost, jb_info::frames_ooo, IAX_USEJITTERBUF, iaxs, iaxsl, ast_channel::jb, jb_getinfo(), iax_rr::jitter, jb_info::jitter, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, manager_event, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, and chan_iax2_pvt::remote_rr.
Referenced by socket_process().
09495 { 09496 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1; 09497 jb_info jbinfo; 09498 09499 ast_mutex_lock(&iaxsl[callno]); 09500 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) { 09501 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) { 09502 jb_getinfo(iaxs[callno]->jb, &jbinfo); 09503 localjitter = jbinfo.jitter; 09504 localdelay = jbinfo.current - jbinfo.min; 09505 locallost = jbinfo.frames_lost; 09506 locallosspct = jbinfo.losspct/1000; 09507 localdropped = jbinfo.frames_dropped; 09508 localooo = jbinfo.frames_ooo; 09509 localpackets = jbinfo.frames_in; 09510 } 09511 ast_debug(3, "JB STATS:%s ping=%d ljitterms=%d ljbdelayms=%d ltotlost=%d lrecentlosspct=%d ldropped=%d looo=%d lrecvd=%d rjitterms=%d rjbdelayms=%d rtotlost=%d rrecentlosspct=%d rdropped=%d rooo=%d rrecvd=%d\n", 09512 iaxs[callno]->owner->name, 09513 iaxs[callno]->pingtime, 09514 localjitter, 09515 localdelay, 09516 locallost, 09517 locallosspct, 09518 localdropped, 09519 localooo, 09520 localpackets, 09521 iaxs[callno]->remote_rr.jitter, 09522 iaxs[callno]->remote_rr.delay, 09523 iaxs[callno]->remote_rr.losscnt, 09524 iaxs[callno]->remote_rr.losspct/1000, 09525 iaxs[callno]->remote_rr.dropped, 09526 iaxs[callno]->remote_rr.ooo, 09527 iaxs[callno]->remote_rr.packets); 09528 manager_event(EVENT_FLAG_REPORTING, "JitterBufStats", "Owner: %s\r\nPing: %d\r\nLocalJitter: %d\r\nLocalJBDelay: %d\r\nLocalTotalLost: %d\r\nLocalLossPercent: %d\r\nLocalDropped: %d\r\nLocalooo: %d\r\nLocalReceived: %d\r\nRemoteJitter: %d\r\nRemoteJBDelay: %d\r\nRemoteTotalLost: %d\r\nRemoteLossPercent: %d\r\nRemoteDropped: %d\r\nRemoteooo: %d\r\nRemoteReceived: %d\r\n", 09529 iaxs[callno]->owner->name, 09530 iaxs[callno]->pingtime, 09531 localjitter, 09532 localdelay, 09533 locallost, 09534 locallosspct, 09535 localdropped, 09536 localooo, 09537 localpackets, 09538 iaxs[callno]->remote_rr.jitter, 09539 iaxs[callno]->remote_rr.delay, 09540 iaxs[callno]->remote_rr.losscnt, 09541 iaxs[callno]->remote_rr.losspct/1000, 09542 iaxs[callno]->remote_rr.dropped, 09543 iaxs[callno]->remote_rr.ooo, 09544 iaxs[callno]->remote_rr.packets); 09545 } 09546 ast_mutex_unlock(&iaxsl[callno]); 09547 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 2052 of file chan_iax2.c.
References ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_del, chan_iax2_pvt::callno, callno_entry::callno, chan_iax2_pvt::callno_entry, get_unused_callno(), iax2_sched_add(), iaxs, iaxsl, chan_iax2_pvt::lagid, LOG_WARNING, MIN_REUSE_TIME, chan_iax2_pvt::pingid, replace_callno(), sched, send_lagrq(), send_ping(), update_max_nontrunk, update_max_trunk, and callno_entry::validated.
Referenced by iax2_request(), and socket_process().
02053 { 02054 int x; 02055 int res= 0; 02056 struct callno_entry *callno_entry; 02057 if (iaxs[callno]->oseqno) { 02058 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 02059 return -1; 02060 } 02061 if (callno & TRUNK_CALL_START) { 02062 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 02063 return -1; 02064 } 02065 02066 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) { 02067 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 02068 return -1; 02069 } 02070 02071 x = callno_entry->callno; 02072 ast_mutex_lock(&iaxsl[x]); 02073 02074 /*! 02075 * \note We delete these before switching the slot, because if 02076 * they fire in the meantime, they will generate a warning. 02077 */ 02078 ast_sched_thread_del(sched, iaxs[callno]->pingid); 02079 ast_sched_thread_del(sched, iaxs[callno]->lagid); 02080 iaxs[callno]->lagid = iaxs[callno]->pingid = -1; 02081 iaxs[x] = iaxs[callno]; 02082 iaxs[x]->callno = x; 02083 02084 /* since we copied over the pvt from a different callno, make sure the old entry is replaced 02085 * before assigning the new one */ 02086 if (iaxs[x]->callno_entry) { 02087 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry); 02088 } 02089 iaxs[x]->callno_entry = callno_entry; 02090 02091 iaxs[callno] = NULL; 02092 /* Update the two timers that should have been started */ 02093 iaxs[x]->pingid = iax2_sched_add(sched, 02094 ping_time * 1000, send_ping, (void *)(long)x); 02095 iaxs[x]->lagid = iax2_sched_add(sched, 02096 lagrq_time * 1000, send_lagrq, (void *)(long)x); 02097 02098 if (locked) 02099 ast_mutex_unlock(&iaxsl[callno]); 02100 res = x; 02101 if (!locked) 02102 ast_mutex_unlock(&iaxsl[x]); 02103 02104 ast_debug(1, "Made call %d into trunk call %d\n", callno, x); 02105 /* We move this call from a non-trunked to a trunked call */ 02106 update_max_trunk(); 02107 update_max_nontrunk(); 02108 return res; 02109 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 6953 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), and RESULT_SUCCESS.
Referenced by load_module().
06954 { 06955 ast_cli_netstats(s, -1, 0); 06956 astman_append(s, "\r\n"); 06957 return RESULT_SUCCESS; 06958 }
static int manager_iax2_show_peer_list | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
callback to display iax peers in manager format
Definition at line 7016 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_copy_string(), ast_inet_ntoa(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag64, astman_append(), astman_get_header(), iax2_peer::encmethods, encmethods_to_str(), IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, iax2_peer::name, peer_status(), peer_unref(), peers, RESULT_SUCCESS, status, and iax2_peer::username.
Referenced by load_module().
07017 { 07018 struct iax2_peer *peer = NULL; 07019 int peer_count = 0; 07020 char nm[20]; 07021 char status[20]; 07022 const char *id = astman_get_header(m,"ActionID"); 07023 char idtext[256] = ""; 07024 struct ast_str *encmethods = ast_str_alloca(256); 07025 struct ao2_iterator i; 07026 07027 if (!ast_strlen_zero(id)) 07028 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07029 07030 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext); 07031 07032 07033 i = ao2_iterator_init(peers, 0); 07034 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) { 07035 encmethods_to_str(peer->encmethods, encmethods); 07036 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext); 07037 if (!ast_strlen_zero(peer->username)) { 07038 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username); 07039 } else { 07040 astman_append(s, "ObjectName: %s\r\n", peer->name); 07041 } 07042 astman_append(s, "ChanObjectType: peer\r\n"); 07043 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr)); 07044 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 07045 astman_append(s, "Mask: %s\r\n", nm); 07046 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr)); 07047 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 07048 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 07049 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 07050 peer_status(peer, status, sizeof(status)); 07051 astman_append(s, "Status: %s\r\n\r\n", status); 07052 peer_count++; 07053 } 07054 ao2_iterator_destroy(&i); 07055 07056 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count); 07057 return RESULT_SUCCESS; 07058 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
callback to display iax peers in manager
Definition at line 6992 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), and total.
Referenced by load_module().
06993 { 06994 static const char * const a[] = { "iax2", "show", "peers" }; 06995 const char *id = astman_get_header(m,"ActionID"); 06996 char idtext[256] = ""; 06997 int total = 0; 06998 06999 if (!ast_strlen_zero(id)) 07000 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07001 07002 astman_send_listack(s, m, "Peer status list will follow", "start"); 07003 /* List the peers in separate manager events */ 07004 __iax2_show_peers(-1, &total, s, 3, a); 07005 /* Send final confirmation */ 07006 astman_append(s, 07007 "Event: PeerlistComplete\r\n" 07008 "EventList: Complete\r\n" 07009 "ListItems: %d\r\n" 07010 "%s" 07011 "\r\n", total, idtext); 07012 return 0; 07013 }
static int manager_iax2_show_registry | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 7124 of file chan_iax2.c.
References iax2_registry::addr, ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sockaddr_stringify(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), iax2_registry::dnsmgr, iax2_registry::entry, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), total, iax2_registry::us, and iax2_registry::username.
Referenced by load_module().
07125 { 07126 const char *id = astman_get_header(m, "ActionID"); 07127 struct iax2_registry *reg = NULL; 07128 char idtext[256] = ""; 07129 char host[80] = ""; 07130 char perceived[80] = ""; 07131 int total = 0; 07132 07133 if (!ast_strlen_zero(id)) 07134 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07135 07136 astman_send_listack(s, m, "Registrations will follow", "start"); 07137 07138 AST_LIST_LOCK(®istrations); 07139 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07140 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07141 07142 if (reg->us.sin_addr.s_addr) { 07143 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07144 } else { 07145 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07146 } 07147 07148 astman_append(s, 07149 "Event: RegistryEntry\r\n" 07150 "%s" 07151 "Host: %s\r\n" 07152 "DNSmanager: %s\r\n" 07153 "Username: %s\r\n" 07154 "Perceived: %s\r\n" 07155 "Refresh: %d\r\n" 07156 "State: %s\r\n" 07157 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, 07158 reg->refresh, regstate2str(reg->regstate)); 07159 07160 total++; 07161 } 07162 AST_LIST_UNLOCK(®istrations); 07163 07164 astman_append(s, 07165 "Event: RegistrationsComplete\r\n" 07166 "EventList: Complete\r\n" 07167 "ListItems: %d\r\n" 07168 "%s" 07169 "\r\n", total, idtext); 07170 07171 return 0; 07172 }
static int match | ( | struct sockaddr_in * | sin, | |
unsigned short | callno, | |||
unsigned short | dcallno, | |||
const struct chan_iax2_pvt * | cur, | |||
int | check_dcallno | |||
) | [static] |
Definition at line 1986 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.
Referenced by __find_callno(), __get_header(), ast_parse_device_state(), ast_srtp_add_stream(), ast_srtp_change_source(), check_blacklist(), find_by_name(), find_command(), handle_updates(), internal_ao2_callback(), lua_find_extension(), misdn_update_redirecting(), pbx_find_extension(), pvt_cmp_cb(), realtime_switch_common(), transfercallno_pvt_cmp_cb(), and xmldoc_attribute_match().
01987 { 01988 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01989 (cur->addr.sin_port == sin->sin_port)) { 01990 /* This is the main host */ 01991 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01992 (check_dcallno ? dcallno == cur->callno : 1) ) { 01993 /* That's us. Be sure we keep track of the peer call number */ 01994 return 1; 01995 } 01996 } 01997 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01998 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01999 /* We're transferring */ 02000 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 02001 return 1; 02002 } 02003 return 0; 02004 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
ast_aes_decrypt_key * | dcx | |||
) | [static] |
Definition at line 6207 of file chan_iax2.c.
References ast_aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
06208 { 06209 #if 0 06210 /* Debug with "fake encryption" */ 06211 int x; 06212 if (len % 16) 06213 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06214 for (x=0;x<len;x++) 06215 dst[x] = src[x] ^ 0xff; 06216 #else 06217 unsigned char lastblock[16] = { 0 }; 06218 int x; 06219 while(len > 0) { 06220 ast_aes_decrypt(src, dst, dcx); 06221 for (x=0;x<16;x++) 06222 dst[x] ^= lastblock[x]; 06223 memcpy(lastblock, src, sizeof(lastblock)); 06224 dst += 16; 06225 src += 16; 06226 len -= 16; 06227 } 06228 #endif 06229 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
ast_aes_encrypt_key * | ecx | |||
) | [static] |
Definition at line 6231 of file chan_iax2.c.
References ast_aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
06232 { 06233 #if 0 06234 /* Debug with "fake encryption" */ 06235 int x; 06236 if (len % 16) 06237 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06238 for (x=0;x<len;x++) 06239 dst[x] = src[x] ^ 0xff; 06240 #else 06241 unsigned char curblock[16] = { 0 }; 06242 int x; 06243 while(len > 0) { 06244 for (x=0;x<16;x++) 06245 curblock[x] ^= src[x]; 06246 ast_aes_encrypt(curblock, dst, ecx); 06247 memcpy(curblock, dst, sizeof(curblock)); 06248 dst += 16; 06249 src += 16; 06250 len -= 16; 06251 } 06252 #endif 06253 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 7797 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, IAX_ENCRYPT_AES128, IAX_ENCRYPT_KEYROTATE, and chan_iax2_pvt::keyrotateid.
Referenced by authenticate_reply(), and socket_process().
07798 { 07799 /* Select exactly one common encryption if there are any */ 07800 p->encmethods &= enc; 07801 if (p->encmethods) { 07802 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */ 07803 p->keyrotateid = -2; 07804 } 07805 if (p->encmethods & IAX_ENCRYPT_AES128) 07806 p->encmethods = IAX_ENCRYPT_AES128; 07807 else 07808 p->encmethods = 0; 07809 } 07810 }
static void mwi_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 1276 of file chan_iax2.c.
01277 { 01278 /* The MWI subscriptions exist just so the core knows we care about those 01279 * mailboxes. However, we just grab the events out of the cache when it 01280 * is time to send MWI, since it is only sent with a REGACK. */ 01281 }
static void network_change_event_cb | ( | const struct ast_event * | , | |
void * | ||||
) | [static] |
Definition at line 1311 of file chan_iax2.c.
References ast_debug, iax2_sched_add(), network_change_event_sched_cb(), and sched.
Referenced by network_change_event_subscribe().
01312 { 01313 ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n"); 01314 if (network_change_event_sched_id == -1) { 01315 network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL); 01316 } 01317 01318 }
static int network_change_event_sched_cb | ( | const void * | data | ) | [static] |
Definition at line 1298 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax2_registry::entry, and iax2_do_register().
Referenced by network_change_event_cb().
01299 { 01300 struct iax2_registry *reg; 01301 network_change_event_sched_id = -1; 01302 AST_LIST_LOCK(®istrations); 01303 AST_LIST_TRAVERSE(®istrations, reg, entry) { 01304 iax2_do_register(reg); 01305 } 01306 AST_LIST_UNLOCK(®istrations); 01307 01308 return 0; 01309 }
static void network_change_event_subscribe | ( | void | ) | [static] |
Definition at line 1283 of file chan_iax2.c.
References AST_EVENT_IE_END, AST_EVENT_NETWORK_CHANGE, ast_event_subscribe(), network_change_event_cb(), and network_change_event_subscription.
Referenced by load_module(), and set_config().
01284 { 01285 if (!network_change_event_subscription) { 01286 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE, 01287 network_change_event_cb, "IAX2 Network Change", NULL, AST_EVENT_IE_END); 01288 } 01289 }
static void network_change_event_unsubscribe | ( | void | ) | [static] |
Definition at line 1291 of file chan_iax2.c.
References ast_event_unsubscribe(), and network_change_event_subscription.
Referenced by __unload_module(), set_config(), and unload_module().
01292 { 01293 if (network_change_event_subscription) { 01294 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription); 01295 } 01296 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 12195 of file chan_iax2.c.
References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), ast_timer_fd(), io, timer, and timing_read().
Referenced by start_network_thread().
12196 { 12197 if (timer) { 12198 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL); 12199 } 12200 12201 for (;;) { 12202 pthread_testcancel(); 12203 /* Wake up once a second just in case SIGURG was sent while 12204 * we weren't in poll(), to make sure we don't hang when trying 12205 * to unload. */ 12206 ast_io_wait(io, 1000); 12207 } 12208 12209 return NULL; 12210 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static] |
Definition at line 1915 of file chan_iax2.c.
References ao2_alloc, ao2_ref, AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, ast_string_field_set, exten, jb_new(), jb_setconf(), jb_conf::max_contig_interp, jb_conf::max_jitterbuf, prefs, pvt_destructor(), jb_conf::resync_threshold, and jb_conf::target_extra.
Referenced by __find_callno().
01916 { 01917 struct chan_iax2_pvt *tmp; 01918 jb_conf jbconf; 01919 01920 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01921 return NULL; 01922 } 01923 01924 if (ast_string_field_init(tmp, 32)) { 01925 ao2_ref(tmp, -1); 01926 tmp = NULL; 01927 return NULL; 01928 } 01929 01930 tmp->prefs = prefs; 01931 tmp->pingid = -1; 01932 tmp->lagid = -1; 01933 tmp->autoid = -1; 01934 tmp->authid = -1; 01935 tmp->initid = -1; 01936 tmp->keyrotateid = -1; 01937 01938 ast_string_field_set(tmp,exten, "s"); 01939 ast_string_field_set(tmp,host, host); 01940 01941 tmp->jb = jb_new(); 01942 tmp->jbid = -1; 01943 jbconf.max_jitterbuf = maxjitterbuffer; 01944 jbconf.resync_threshold = resyncthreshold; 01945 jbconf.max_contig_interp = maxjitterinterps; 01946 jbconf.target_extra = jittertargetextra; 01947 jb_setconf(tmp->jb,&jbconf); 01948 01949 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries); 01950 01951 tmp->hold_signaling = 1; 01952 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue); 01953 01954 return tmp; 01955 }
static void parse_dial_string | ( | char * | data, | |
struct parsed_dial_string * | pds | |||
) | [static] |
Parses an IAX dial string into its component parts.
data | the string to be parsed | |
pds | pointer to a struct parsed_dial_string to be filled in |
The dial string format is: [username[:password]@]peer[:port][/exten[@context]][/options]
Definition at line 4986 of file chan_iax2.c.
References ast_strip_quoted(), ast_strlen_zero(), parsed_dial_string::context, parsed_dial_string::exten, parsed_dial_string::key, parsed_dial_string::options, parsed_dial_string::password, parsed_dial_string::peer, parsed_dial_string::port, strsep(), and parsed_dial_string::username.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_devicestate(), and iax2_request().
04987 { 04988 if (ast_strlen_zero(data)) 04989 return; 04990 04991 pds->peer = strsep(&data, "/"); 04992 pds->exten = strsep(&data, "/"); 04993 pds->options = data; 04994 04995 if (pds->exten) { 04996 data = pds->exten; 04997 pds->exten = strsep(&data, "@"); 04998 pds->context = data; 04999 } 05000 05001 if (strchr(pds->peer, '@')) { 05002 data = pds->peer; 05003 pds->username = strsep(&data, "@"); 05004 pds->peer = data; 05005 } 05006 05007 if (pds->username) { 05008 data = pds->username; 05009 pds->username = strsep(&data, ":"); 05010 pds->password = data; 05011 } 05012 05013 data = pds->peer; 05014 pds->peer = strsep(&data, ":"); 05015 pds->port = data; 05016 05017 /* check for a key name wrapped in [] in the secret position, if found, 05018 move it to the key field instead 05019 */ 05020 if (pds->password && (pds->password[0] == '[')) { 05021 pds->key = ast_strip_quoted(pds->password, "[", "]"); 05022 pds->password = NULL; 05023 } 05024 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1655 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and iax2_peer::name.
Referenced by load_module(), and load_objects().
01656 { 01657 struct iax2_peer *peer = obj, *peer2 = arg; 01658 01659 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0; 01660 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12946 of file chan_iax2.c.
References ast_set_flag64, and IAX_DELME.
Referenced by delete_users().
12947 { 12948 struct iax2_peer *peer = obj; 12949 12950 ast_set_flag64(peer, IAX_DELME); 12951 12952 return 0; 12953 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 12375 of file chan_iax2.c.
References ast_dnsmgr_release(), ast_event_unsubscribe(), ast_free_ha(), ast_mutex_lock, ast_mutex_unlock, ast_string_field_free_memory, iax2_peer::callno, iax2_peer::dnsmgr, iax2_peer::ha, iax2_destroy(), iaxsl, iax2_peer::mwi_event_sub, and register_peer_exten().
Referenced by build_peer().
12376 { 12377 struct iax2_peer *peer = obj; 12378 int callno = peer->callno; 12379 12380 ast_free_ha(peer->ha); 12381 12382 if (callno > 0) { 12383 ast_mutex_lock(&iaxsl[callno]); 12384 iax2_destroy(callno); 12385 ast_mutex_unlock(&iaxsl[callno]); 12386 } 12387 12388 register_peer_exten(peer, 0); 12389 12390 if (peer->dnsmgr) 12391 ast_dnsmgr_release(peer->dnsmgr); 12392 12393 if (peer->mwi_event_sub) 12394 ast_event_unsubscribe(peer->mwi_event_sub); 12395 12396 ast_string_field_free_memory(peer); 12397 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1645 of file chan_iax2.c.
References ast_str_hash(), and iax2_peer::name.
Referenced by load_module(), and load_objects().
01646 { 01647 const struct iax2_peer *peer = obj; 01648 01649 return ast_str_hash(peer->name); 01650 }
Definition at line 1702 of file chan_iax2.c.
References ao2_ref.
Referenced by __iax2_poke_noanswer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_unregister(), iax2_poke_peer(), reg_source_db(), socket_process(), and update_registry().
01703 { 01704 ao2_ref(peer, +1); 01705 return peer; 01706 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 14437 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
14438 { 14439 struct iax2_peer *peer = obj; 14440 14441 if (peer->sockfd < 0) 14442 peer->sockfd = defaultsockfd; 14443 14444 return 0; 14445 }
static int peer_set_srcaddr | ( | struct iax2_peer * | peer, | |
const char * | srcaddr | |||
) | [static] |
Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found.
Definition at line 12300 of file chan_iax2.c.
References ast_debug, ast_get_ip(), ast_log(), ast_netsock_bind(), ast_netsock_find(), ast_netsock_sockfd(), ast_netsock_unref(), ast_sockaddr_to_sin, ast_strdupa, check_srcaddr(), IAX_DEFAULT_PORTNO, io, LOG_WARNING, iax2_peer::name, netsock, outsock, qos, socket_read(), iax2_peer::sockfd, ast_sockaddr::ss, and strsep().
Referenced by build_peer().
12301 { 12302 struct sockaddr_in sin; 12303 struct ast_sockaddr sin_tmp; 12304 int nonlocal = 1; 12305 int port = IAX_DEFAULT_PORTNO; 12306 int sockfd = defaultsockfd; 12307 char *tmp; 12308 char *addr; 12309 char *portstr; 12310 12311 if (!(tmp = ast_strdupa(srcaddr))) 12312 return -1; 12313 12314 addr = strsep(&tmp, ":"); 12315 portstr = tmp; 12316 12317 if (portstr) { 12318 port = atoi(portstr); 12319 if (port < 1) 12320 port = IAX_DEFAULT_PORTNO; 12321 } 12322 12323 sin_tmp.ss.ss_family = AF_INET; 12324 if (!ast_get_ip(&sin_tmp, addr)) { 12325 struct ast_netsock *sock; 12326 int res; 12327 12328 ast_sockaddr_to_sin(&sin_tmp, &sin); 12329 sin.sin_port = 0; 12330 sin.sin_family = AF_INET; 12331 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 12332 if (res == 0) { 12333 /* ip address valid. */ 12334 sin.sin_port = htons(port); 12335 if (!(sock = ast_netsock_find(netsock, &sin))) 12336 sock = ast_netsock_find(outsock, &sin); 12337 if (sock) { 12338 sockfd = ast_netsock_sockfd(sock); 12339 nonlocal = 0; 12340 } else { 12341 unsigned int orig_saddr = sin.sin_addr.s_addr; 12342 /* INADDR_ANY matches anyway! */ 12343 sin.sin_addr.s_addr = INADDR_ANY; 12344 if (ast_netsock_find(netsock, &sin)) { 12345 sin.sin_addr.s_addr = orig_saddr; 12346 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL); 12347 if (sock) { 12348 sockfd = ast_netsock_sockfd(sock); 12349 ast_netsock_unref(sock); 12350 nonlocal = 0; 12351 } else { 12352 nonlocal = 2; 12353 } 12354 } 12355 } 12356 } 12357 } 12358 12359 peer->sockfd = sockfd; 12360 12361 if (nonlocal == 1) { 12362 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 12363 srcaddr, peer->name); 12364 return -1; 12365 } else if (nonlocal == 2) { 12366 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 12367 srcaddr, peer->name); 12368 return -1; 12369 } else { 12370 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 12371 return 0; 12372 } 12373 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 3727 of file chan_iax2.c.
References ast_copy_string(), iax2_peer::lastms, and iax2_peer::maxms.
Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), function_iaxpeer(), function_sippeer(), handle_cli_iax2_show_peer(), manager_iax2_show_peer_list(), and peers_data_provider_get().
03728 { 03729 int res = 0; 03730 if (peer->maxms) { 03731 if (peer->lastms < 0) { 03732 ast_copy_string(status, "UNREACHABLE", statuslen); 03733 } else if (peer->lastms > peer->maxms) { 03734 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 03735 res = 1; 03736 } else if (peer->lastms) { 03737 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 03738 res = 1; 03739 } else { 03740 ast_copy_string(status, "UNKNOWN", statuslen); 03741 } 03742 } else { 03743 ast_copy_string(status, "Unmonitored", statuslen); 03744 res = -1; 03745 } 03746 return res; 03747 }
Definition at line 1708 of file chan_iax2.c.
References ao2_ref.
Referenced by __expire_registry(), __iax2_poke_noanswer(), __iax2_poke_peer_s(), __iax2_show_peers(), authenticate_reply(), build_peer(), calltoken_required(), complete_iax2_peers(), complete_iax2_unregister(), create_addr(), function_iaxpeer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_peer(), handle_cli_iax2_unregister(), iax2_devicestate(), iax2_getpeername(), iax2_getpeertrunk(), iax2_poke_noanswer(), iax2_poke_peer(), manager_iax2_show_peer_list(), peers_data_provider_get(), poke_all_peers(), prune_peers(), reg_source_db(), registry_authrequest(), requirecalltoken_mark_auto(), set_config(), socket_process(), unlink_peer(), and update_registry().
01709 { 01710 ao2_ref(peer, -1); 01711 return NULL; 01712 }
static int peercnt_add | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2349 of file chan_iax2.c.
References peercnt::addr, ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_debug, ast_inet_ntoa(), ast_log(), LOG_ERROR, OBJ_POINTER, peercnts, and set_peercnt_limit().
Referenced by __find_callno(), and complete_transfer().
02350 { 02351 struct peercnt *peercnt; 02352 unsigned long addr = sin->sin_addr.s_addr; 02353 int res = 0; 02354 struct peercnt tmp = { 02355 .addr = addr, 02356 }; 02357 02358 /* Reasoning for peercnts container lock: Two identical ip addresses 02359 * could be added by different threads at the "same time". Without the container 02360 * lock, both threads could alloc space for the same object and attempt 02361 * to link to table. With the lock, one would create the object and link 02362 * to table while the other would find the already created peercnt object 02363 * rather than creating a new one. */ 02364 ao2_lock(peercnts); 02365 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02366 ao2_lock(peercnt); 02367 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) { 02368 ao2_lock(peercnt); 02369 /* create and set defaults */ 02370 peercnt->addr = addr; 02371 set_peercnt_limit(peercnt); 02372 /* guarantees it does not go away after unlocking table 02373 * ao2_find automatically adds this */ 02374 ao2_link(peercnts, peercnt); 02375 } else { 02376 ao2_unlock(peercnts); 02377 return -1; 02378 } 02379 02380 /* check to see if the address has hit its callno limit. If not increment cur. */ 02381 if (peercnt->limit > peercnt->cur) { 02382 peercnt->cur++; 02383 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr)); 02384 } else { /* max num call numbers for this peer has been reached! */ 02385 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr)); 02386 res = -1; 02387 } 02388 02389 /* clean up locks and ref count */ 02390 ao2_unlock(peercnt); 02391 ao2_unlock(peercnts); 02392 ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */ 02393 02394 return res; 02395 }
static int peercnt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2179 of file chan_iax2.c.
References peercnt::addr, CMP_MATCH, and CMP_STOP.
Referenced by load_objects().
02180 { 02181 struct peercnt *peercnt1 = obj, *peercnt2 = arg; 02182 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0; 02183 }
static int peercnt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 2173 of file chan_iax2.c.
References peercnt::addr.
Referenced by load_objects().
static void peercnt_modify | ( | unsigned char | reg, | |
uint16_t | limit, | |||
struct ast_sockaddr * | sockaddr | |||
) | [static] |
Definition at line 2316 of file chan_iax2.c.
References peercnt::addr, ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), ast_sockaddr_to_sin, peercnt::limit, OBJ_POINTER, peercnts, peercnt::reg, and set_peercnt_limit().
Referenced by __expire_registry(), build_peer(), and update_registry().
02317 { 02318 /* this function turns off and on custom callno limits set by peer registration */ 02319 struct peercnt *peercnt; 02320 struct peercnt tmp = { 02321 .addr = 0, 02322 }; 02323 struct sockaddr_in sin; 02324 02325 ast_sockaddr_to_sin(sockaddr, &sin); 02326 02327 tmp.addr = sin.sin_addr.s_addr; 02328 02329 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02330 peercnt->reg = reg; 02331 if (limit) { 02332 peercnt->limit = limit; 02333 } else { 02334 set_peercnt_limit(peercnt); 02335 } 02336 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg); 02337 ao2_ref(peercnt, -1); /* decrement ref from find */ 02338 } 02339 }
static void peercnt_remove | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2401 of file chan_iax2.c.
References peercnt::addr, ao2_lock, ao2_unlink, ao2_unlock, ast_debug, ast_inet_ntoa(), peercnt::cur, and peercnts.
Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().
02402 { 02403 struct sockaddr_in sin = { 02404 .sin_addr.s_addr = peercnt->addr, 02405 }; 02406 02407 /* 02408 * Container locked here since peercnt may be unlinked from 02409 * list. If left unlocked, peercnt_add could try and grab this 02410 * entry from the table and modify it at the "same time" this 02411 * thread attemps to unlink it. 02412 */ 02413 ao2_lock(peercnts); 02414 peercnt->cur--; 02415 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr)); 02416 /* if this was the last connection from the peer remove it from table */ 02417 if (peercnt->cur == 0) { 02418 ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */ 02419 } 02420 ao2_unlock(peercnts); 02421 }
static int peercnt_remove_by_addr | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2441 of file chan_iax2.c.
References peercnt::addr, ao2_find, ao2_ref, OBJ_POINTER, peercnt_remove(), and peercnts.
Referenced by __find_callno(), and complete_transfer().
02442 { 02443 struct peercnt *peercnt; 02444 struct peercnt tmp = { 02445 .addr = sin->sin_addr.s_addr, 02446 }; 02447 02448 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02449 peercnt_remove(peercnt); 02450 ao2_ref(peercnt, -1); /* decrement ref from find */ 02451 } 02452 return 0; 02453 }
static int peercnt_remove_cb | ( | const void * | obj | ) | [static] |
Definition at line 2427 of file chan_iax2.c.
References ao2_ref, and peercnt_remove().
Referenced by sched_delay_remove().
02428 { 02429 struct peercnt *peercnt = (struct peercnt *) obj; 02430 02431 peercnt_remove(peercnt); 02432 ao2_ref(peercnt, -1); /* decrement ref from scheduler */ 02433 02434 return 0; 02435 }
static int peers_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 14571 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_inet_ntoa(), ast_sockaddr_port, ast_sockaddr_stringify_host(), ast_str_alloca, ast_str_buffer(), ast_test_flag64, iax2_peer::capability, iax2_peer::encmethods, encmethods_to_str(), IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, peer_status(), peer_unref(), peers, and status.
14573 { 14574 struct ast_data *data_peer; 14575 struct iax2_peer *peer; 14576 struct ao2_iterator i; 14577 char status[20]; 14578 struct ast_str *encmethods = ast_str_alloca(256); 14579 14580 i = ao2_iterator_init(peers, 0); 14581 while ((peer = ao2_iterator_next(&i))) { 14582 data_peer = ast_data_add_node(data_root, "peer"); 14583 if (!data_peer) { 14584 peer_unref(peer); 14585 continue; 14586 } 14587 14588 ast_data_add_structure(iax2_peer, data_peer, peer); 14589 14590 ast_data_add_codecs(data_peer, "codecs", peer->capability); 14591 14592 peer_status(peer, status, sizeof(status)); 14593 ast_data_add_str(data_peer, "status", status); 14594 14595 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr)); 14596 14597 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask)); 14598 14599 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr)); 14600 14601 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK)); 14602 14603 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC)); 14604 14605 encmethods_to_str(peer->encmethods, encmethods); 14606 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no"); 14607 14608 peer_unref(peer); 14609 14610 if (!ast_data_search_match(search, data_peer)) { 14611 ast_data_remove_node(data_root, data_peer); 14612 } 14613 } 14614 ao2_iterator_destroy(&i); 14615 14616 return 0; 14617 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 13525 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, iax2_poke_peer(), peer_unref(), and peers.
Referenced by reload_config().
13526 { 13527 struct ao2_iterator i; 13528 struct iax2_peer *peer; 13529 13530 i = ao2_iterator_init(peers, 0); 13531 while ((peer = ao2_iterator_next(&i))) { 13532 iax2_poke_peer(peer, 0); 13533 peer_unref(peer); 13534 } 13535 ao2_iterator_destroy(&i); 13536 }
static int prune_addr_range_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2305 of file chan_iax2.c.
References CMP_MATCH, and addr_range::delme.
Referenced by reload_config().
02306 { 02307 struct addr_range *addr_range = obj; 02308 02309 return addr_range->delme ? CMP_MATCH : 0; 02310 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 13009 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_test_flag64, IAX_DELME, IAX_RTCACHEFRIENDS, peer_unref(), peers, and unlink_peer().
13010 { 13011 struct iax2_peer *peer; 13012 struct ao2_iterator i; 13013 13014 i = ao2_iterator_init(peers, 0); 13015 while ((peer = ao2_iterator_next(&i))) { 13016 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 13017 unlink_peer(peer); 13018 } 13019 peer_unref(peer); 13020 } 13021 ao2_iterator_destroy(&i); 13022 }
static void prune_users | ( | void | ) | [static] |
Definition at line 12993 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_unlink, ast_test_flag64, IAX_DELME, IAX_RTCACHEFRIENDS, user, user_unref(), and users.
Referenced by handle_cli_iax2_prune_realtime(), and reload_config().
12994 { 12995 struct iax2_user *user; 12996 struct ao2_iterator i; 12997 12998 i = ao2_iterator_init(users, 0); 12999 while ((user = ao2_iterator_next(&i))) { 13000 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 13001 ao2_unlink(users, user); 13002 } 13003 user_unref(user); 13004 } 13005 ao2_iterator_destroy(&i); 13006 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 14454 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().
14455 { 14456 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14457 14458 /* The frames_received field is used to hold whether we're matching 14459 * against a full frame or not ... */ 14460 14461 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 14462 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14463 }
static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1868 of file chan_iax2.c.
References chan_iax2_pvt::addr, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, ast_mutex_lock, ast_mutex_unlock, ast_set_flag64, ast_string_field_free_memory, ast_variables_destroy(), iax2_registry::callno, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, jb_frame::data, frame_queue, free_signaling_queue_entry(), iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxsl, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, iax2_trunk_peer::list, iax2_trunk_peer::next, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, sched_delay_remove(), chan_iax2_pvt::signaling_queue, and chan_iax2_pvt::vars.
01869 { 01870 struct chan_iax2_pvt *pvt = obj; 01871 struct iax_frame *cur = NULL; 01872 struct signaling_queue_entry *s = NULL; 01873 01874 ast_mutex_lock(&iaxsl[pvt->callno]); 01875 01876 iax2_destroy_helper(pvt); 01877 01878 sched_delay_remove(&pvt->addr, pvt->callno_entry); 01879 pvt->callno_entry = NULL; 01880 01881 /* Already gone */ 01882 ast_set_flag64(pvt, IAX_ALREADYGONE); 01883 01884 AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) { 01885 /* Cancel any pending transmissions */ 01886 cur->retries = -1; 01887 } 01888 01889 ast_mutex_unlock(&iaxsl[pvt->callno]); 01890 01891 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01892 free_signaling_queue_entry(s); 01893 } 01894 01895 if (pvt->reg) { 01896 pvt->reg->callno = 0; 01897 } 01898 01899 if (!pvt->owner) { 01900 jb_frame frame; 01901 if (pvt->vars) { 01902 ast_variables_destroy(pvt->vars); 01903 pvt->vars = NULL; 01904 } 01905 01906 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01907 iax2_frame_free(frame.data); 01908 } 01909 01910 jb_destroy(pvt->jb); 01911 ast_string_field_free_memory(pvt); 01912 } 01913 }
static int pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 14447 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
14448 { 14449 const struct chan_iax2_pvt *pvt = obj; 14450 14451 return pvt->peercallno; 14452 }
static int queue_signalling | ( | struct chan_iax2_pvt * | pvt, | |
struct ast_frame * | f | |||
) | [static] |
All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number.
Definition at line 1843 of file chan_iax2.c.
References ast_calloc, AST_FRAME_IAX, AST_LIST_INSERT_TAIL, ast_malloc, ast_frame::data, ast_frame::datalen, signaling_queue_entry::f, f, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, iax2_trunk_peer::next, ast_frame::ptr, and chan_iax2_pvt::signaling_queue.
Referenced by __send_command().
01844 { 01845 struct signaling_queue_entry *qe; 01846 01847 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) { 01848 return 1; /* do not queue this frame */ 01849 } else if (!(qe = ast_calloc(1, sizeof(struct signaling_queue_entry)))) { 01850 return -1; /* out of memory */ 01851 } 01852 01853 /* copy ast_frame into our queue entry */ 01854 qe->f = *f; 01855 if (qe->f.datalen) { 01856 /* if there is data in this frame copy it over as well */ 01857 if (!(qe->f.data.ptr = ast_malloc(qe->f.datalen))) { 01858 free_signaling_queue_entry(qe); 01859 return -1; 01860 } 01861 memcpy(qe->f.data.ptr, f->data.ptr, qe->f.datalen); 01862 } 01863 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, qe, next); 01864 01865 return 0; 01866 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 7778 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_inet_ntoa(), compress_subclass(), ast_iax2_full_hdr::csub, ast_iax2_full_hdr::dcallno, IAX_COMMAND_INVAL, IAX_FLAG_FULL, iax_outputframe(), ast_iax2_full_hdr::iseqno, option_debug, ast_iax2_full_hdr::oseqno, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type.
Referenced by socket_process().
07779 { 07780 struct ast_iax2_full_hdr fh; 07781 fh.scallno = htons(src | IAX_FLAG_FULL); 07782 fh.dcallno = htons(dst); 07783 fh.ts = 0; 07784 fh.oseqno = 0; 07785 fh.iseqno = 0; 07786 fh.type = AST_FRAME_IAX; 07787 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 07788 iax_outputframe(NULL, &fh, 0, sin, 0); 07789 #if 0 07790 if (option_debug) 07791 #endif 07792 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n", 07793 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 07794 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 07795 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 4339 of file chan_iax2.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.
04340 { 04341 struct ast_variable *var = NULL; 04342 struct ast_variable *tmp; 04343 struct iax2_peer *peer=NULL; 04344 time_t regseconds = 0, nowtime; 04345 int dynamic=0; 04346 04347 if (peername) { 04348 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL); 04349 if (!var && sin) 04350 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04351 } else if (sin) { 04352 char porta[25]; 04353 sprintf(porta, "%d", ntohs(sin->sin_port)); 04354 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04355 if (var) { 04356 /* We'll need the peer name in order to build the structure! */ 04357 for (tmp = var; tmp; tmp = tmp->next) { 04358 if (!strcasecmp(tmp->name, "name")) 04359 peername = tmp->value; 04360 } 04361 } 04362 } 04363 if (!var && peername) { /* Last ditch effort */ 04364 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL); 04365 /*!\note 04366 * If this one loaded something, then we need to ensure that the host 04367 * field matched. The only reason why we can't have this as a criteria 04368 * is because we only have the IP address and the host field might be 04369 * set as a name (and the reverse PTR might not match). 04370 */ 04371 if (var && sin) { 04372 for (tmp = var; tmp; tmp = tmp->next) { 04373 if (!strcasecmp(tmp->name, "host")) { 04374 struct ast_hostent ahp; 04375 struct hostent *hp; 04376 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) { 04377 /* No match */ 04378 ast_variables_destroy(var); 04379 var = NULL; 04380 } 04381 break; 04382 } 04383 } 04384 } 04385 } 04386 if (!var) 04387 return NULL; 04388 04389 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 04390 04391 if (!peer) { 04392 ast_variables_destroy(var); 04393 return NULL; 04394 } 04395 04396 for (tmp = var; tmp; tmp = tmp->next) { 04397 /* Make sure it's not a user only... */ 04398 if (!strcasecmp(tmp->name, "type")) { 04399 if (strcasecmp(tmp->value, "friend") && 04400 strcasecmp(tmp->value, "peer")) { 04401 /* Whoops, we weren't supposed to exist! */ 04402 peer = peer_unref(peer); 04403 break; 04404 } 04405 } else if (!strcasecmp(tmp->name, "regseconds")) { 04406 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 04407 } else if (!strcasecmp(tmp->name, "ipaddr")) { 04408 if (!ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE)) { 04409 ast_log(LOG_WARNING, "Failed to parse sockaddr '%s' for ipaddr of realtime peer '%s'\n", tmp->value, tmp->name); 04410 } 04411 } else if (!strcasecmp(tmp->name, "port")) { 04412 ast_sockaddr_set_port(&peer->addr, atoi(tmp->value)); 04413 } else if (!strcasecmp(tmp->name, "host")) { 04414 if (!strcasecmp(tmp->value, "dynamic")) 04415 dynamic = 1; 04416 } 04417 } 04418 04419 ast_variables_destroy(var); 04420 04421 if (!peer) 04422 return NULL; 04423 04424 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04425 ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 04426 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) { 04427 if (peer->expire > -1) { 04428 if (!ast_sched_thread_del(sched, peer->expire)) { 04429 peer->expire = -1; 04430 peer_unref(peer); 04431 } 04432 } 04433 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 04434 if (peer->expire == -1) 04435 peer_unref(peer); 04436 } 04437 ao2_link(peers, peer); 04438 if (ast_test_flag64(peer, IAX_DYNAMIC)) 04439 reg_source_db(peer); 04440 } else { 04441 ast_set_flag64(peer, IAX_TEMPONLY); 04442 } 04443 04444 if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 04445 time(&nowtime); 04446 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 04447 memset(&peer->addr, 0, sizeof(peer->addr)); 04448 realtime_update_peer(peer->name, &peer->addr, 0); 04449 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 04450 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04451 } 04452 else { 04453 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 04454 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04455 } 04456 } 04457 04458 return peer; 04459 }
static void realtime_update_peer | ( | const char * | peername, | |
struct ast_sockaddr * | sockaddr, | |||
time_t | regtime | |||
) | [static] |
Definition at line 4532 of file chan_iax2.c.
References ast_config_AST_SYSTEM_NAME, ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_strlen_zero(), ast_test_flag64, ast_update_realtime(), globalflags, IAX_RTSAVE_SYSNAME, and SENTINEL.
Referenced by __expire_registry(), update_peer(), and update_registry().
04533 { 04534 char port[10]; 04535 char regseconds[20]; 04536 const char *sysname = ast_config_AST_SYSTEM_NAME; 04537 char *syslabel = NULL; 04538 04539 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 04540 sysname = NULL; 04541 else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME)) 04542 syslabel = "regserver"; 04543 04544 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 04545 snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr)); 04546 ast_update_realtime("iaxpeers", "name", peername, 04547 "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port, 04548 "regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslable can be NULL */ 04549 }
static struct iax2_user * realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 4461 of file chan_iax2.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.
04462 { 04463 struct ast_variable *var; 04464 struct ast_variable *tmp; 04465 struct iax2_user *user=NULL; 04466 04467 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL); 04468 if (!var) 04469 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04470 if (!var && sin) { 04471 char porta[6]; 04472 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 04473 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04474 if (!var) 04475 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04476 } 04477 if (!var) { /* Last ditch effort */ 04478 var = ast_load_realtime("iaxusers", "name", username, SENTINEL); 04479 /*!\note 04480 * If this one loaded something, then we need to ensure that the host 04481 * field matched. The only reason why we can't have this as a criteria 04482 * is because we only have the IP address and the host field might be 04483 * set as a name (and the reverse PTR might not match). 04484 */ 04485 if (var) { 04486 for (tmp = var; tmp; tmp = tmp->next) { 04487 if (!strcasecmp(tmp->name, "host")) { 04488 struct ast_hostent ahp; 04489 struct hostent *hp; 04490 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) { 04491 /* No match */ 04492 ast_variables_destroy(var); 04493 var = NULL; 04494 } 04495 break; 04496 } 04497 } 04498 } 04499 } 04500 if (!var) 04501 return NULL; 04502 04503 tmp = var; 04504 while(tmp) { 04505 /* Make sure it's not a peer only... */ 04506 if (!strcasecmp(tmp->name, "type")) { 04507 if (strcasecmp(tmp->value, "friend") && 04508 strcasecmp(tmp->value, "user")) { 04509 return NULL; 04510 } 04511 } 04512 tmp = tmp->next; 04513 } 04514 04515 user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)); 04516 04517 ast_variables_destroy(var); 04518 04519 if (!user) 04520 return NULL; 04521 04522 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04523 ast_set_flag64(user, IAX_RTCACHEFRIENDS); 04524 ao2_link(users, user); 04525 } else { 04526 ast_set_flag64(user, IAX_TEMPONLY); 04527 } 04528 04529 return user; 04530 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 8666 of file chan_iax2.c.
References iax2_peer::addr, ast_db_get(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_log(), ast_sched_thread_del, ast_sockaddr_parse(), ast_sockaddr_stringify(), ast_test_flag64, ast_verb, iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), IAX_TEMPONLY, LOG_NOTICE, iax2_peer::name, PARSE_PORT_REQUIRE, peer_ref(), peer_unref(), register_peer_exten(), and sched.
Referenced by build_peer(), set_config(), and temp_peer().
08667 { 08668 char data[80]; 08669 char *expiry; 08670 08671 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) { 08672 return; 08673 } 08674 08675 expiry = strrchr(data, ':'); 08676 if (!expiry) { 08677 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data); 08678 return; 08679 } 08680 *expiry++ = '\0'; 08681 08682 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) { 08683 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data); 08684 return; 08685 } 08686 08687 p->expiry = atoi(expiry); 08688 08689 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name, 08690 ast_sockaddr_stringify(&p->addr), p->expiry); 08691 08692 iax2_poke_peer(p, 0); 08693 if (p->expire > -1) { 08694 if (!ast_sched_thread_del(sched, p->expire)) { 08695 p->expire = -1; 08696 peer_unref(p); 08697 } 08698 } 08699 08700 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08701 08702 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08703 if (p->expire == -1) { 08704 peer_unref(p); 08705 } 08706 08707 if (iax2_regfunk) { 08708 iax2_regfunk(p->name, 1); 08709 } 08710 08711 register_peer_exten(p, 1); 08712 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 8581 of file chan_iax2.c.
References ast_add_extension(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr, ast_strdup, ast_strlen_zero(), ext, iax2_peer::name, iax2_peer::regexten, S_OR, and strsep().
Referenced by __expire_registry(), expire_register(), handle_response_peerpoke(), parse_register_contact(), peer_destructor(), reg_source_db(), sip_destroy_peer(), sip_poke_noanswer(), and update_registry().
08582 { 08583 char multi[256]; 08584 char *stringp, *ext; 08585 if (!ast_strlen_zero(regcontext)) { 08586 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 08587 stringp = multi; 08588 while((ext = strsep(&stringp, "&"))) { 08589 if (onoff) { 08590 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 08591 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 08592 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2"); 08593 } else 08594 ast_context_remove_extension(regcontext, ext, 1, NULL); 08595 } 08596 } 08597 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 7952 of file chan_iax2.c.
References ast_apply_ha(), ast_check_signature(), ast_clear_flag, ast_copy_string(), ast_inet_ntoa(), ast_key_get(), AST_KEY_PUBLIC, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set_flag, ast_sockaddr_from_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, iax2_peer::authmethods, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, iaxs, iaxsl, iax2_peer::inkeys, LOG_NOTICE, LOG_WARNING, md5(), iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_peer::name, iax_ies::password, iax_ies::refresh, iax_ies::rsa_result, iax2_peer::secret, secret, state, strsep(), and iax_ies::username.
Referenced by handle_request_register(), and socket_process().
07953 { 07954 char requeststr[256] = ""; 07955 char peer[256] = ""; 07956 char md5secret[256] = ""; 07957 char rsasecret[256] = ""; 07958 char secret[256] = ""; 07959 struct iax2_peer *p = NULL; 07960 struct ast_key *key; 07961 char *keyn; 07962 int x; 07963 int expire = 0; 07964 int res = -1; 07965 struct ast_sockaddr addr; 07966 07967 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07968 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 07969 if (ies->username) 07970 ast_copy_string(peer, ies->username, sizeof(peer)); 07971 if (ies->password) 07972 ast_copy_string(secret, ies->password, sizeof(secret)); 07973 if (ies->md5_result) 07974 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07975 if (ies->rsa_result) 07976 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07977 if (ies->refresh) 07978 expire = ies->refresh; 07979 07980 if (ast_strlen_zero(peer)) { 07981 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 07982 return -1; 07983 } 07984 07985 /* SLD: first call to lookup peer during registration */ 07986 ast_mutex_unlock(&iaxsl[callno]); 07987 p = find_peer(peer, 1); 07988 ast_mutex_lock(&iaxsl[callno]); 07989 if (!p || !iaxs[callno]) { 07990 if (iaxs[callno]) { 07991 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 07992 /* Anything, as long as it's non-blank */ 07993 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07994 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 07995 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 07996 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 07997 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 07998 * to be plaintext, indicating it is an authmethod used by other peers on the system. 07999 * 08000 * If none of these cases exist, res will be returned as 0 without authentication indicating 08001 * an AUTHREQ needs to be sent out. */ 08002 08003 if (ast_strlen_zero(iaxs[callno]->challenge) && 08004 !(!ast_strlen_zero(secret) && plaintext)) { 08005 /* by setting res to 0, an REGAUTH will be sent */ 08006 res = 0; 08007 } 08008 } 08009 if (authdebug && !p) 08010 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 08011 goto return_unref; 08012 } 08013 08014 if (!ast_test_flag64(p, IAX_DYNAMIC)) { 08015 if (authdebug) 08016 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 08017 goto return_unref; 08018 } 08019 08020 ast_sockaddr_from_sin(&addr, sin); 08021 if (!ast_apply_ha(p->ha, &addr)) { 08022 if (authdebug) 08023 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 08024 goto return_unref; 08025 } 08026 ast_string_field_set(iaxs[callno], secret, p->secret); 08027 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 08028 /* Check secret against what we have on file */ 08029 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 08030 if (!ast_strlen_zero(p->inkeys)) { 08031 char tmpkeys[256]; 08032 char *stringp=NULL; 08033 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 08034 stringp=tmpkeys; 08035 keyn = strsep(&stringp, ":"); 08036 while(keyn) { 08037 key = ast_key_get(keyn, AST_KEY_PUBLIC); 08038 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 08039 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08040 break; 08041 } else if (!key) 08042 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 08043 keyn = strsep(&stringp, ":"); 08044 } 08045 if (!keyn) { 08046 if (authdebug) 08047 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 08048 goto return_unref; 08049 } 08050 } else { 08051 if (authdebug) 08052 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 08053 goto return_unref; 08054 } 08055 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 08056 struct MD5Context md5; 08057 unsigned char digest[16]; 08058 char *tmppw, *stringp; 08059 08060 tmppw = ast_strdupa(p->secret); 08061 stringp = tmppw; 08062 while((tmppw = strsep(&stringp, ";"))) { 08063 MD5Init(&md5); 08064 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 08065 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 08066 MD5Final(digest, &md5); 08067 for (x=0;x<16;x++) 08068 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 08069 if (!strcasecmp(requeststr, md5secret)) 08070 break; 08071 } 08072 if (tmppw) { 08073 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08074 } else { 08075 if (authdebug) 08076 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 08077 goto return_unref; 08078 } 08079 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 08080 /* They've provided a plain text password and we support that */ 08081 if (strcmp(secret, p->secret)) { 08082 if (authdebug) 08083 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 08084 goto return_unref; 08085 } else 08086 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08087 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 08088 /* if challenge has been sent, but no challenge response if given, reject. */ 08089 goto return_unref; 08090 } 08091 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08092 08093 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 08094 res = 0; 08095 08096 return_unref: 08097 if (iaxs[callno]) { 08098 ast_string_field_set(iaxs[callno], peer, peer); 08099 08100 /* Choose lowest expiry number */ 08101 if (expire && (expire < iaxs[callno]->expiry)) { 08102 iaxs[callno]->expiry = expire; 08103 } 08104 } 08105 08106 if (p) { 08107 peer_unref(p); 08108 } 08109 return res; 08110 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 8888 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_strdupa, ast_string_field_set, chan_iax2_pvt::authmethods, iax2_peer::authmethods, find_peer(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_COMMAND_REGAUTH, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CHALLENGE, IAX_IE_USERNAME, iaxs, iaxsl, peer_unref(), and send_command().
Referenced by socket_process().
08889 { 08890 struct iax_ie_data ied; 08891 struct iax2_peer *p; 08892 char challenge[10]; 08893 const char *peer_name; 08894 int sentauthmethod; 08895 08896 peer_name = ast_strdupa(iaxs[callno]->peer); 08897 08898 /* SLD: third call to find_peer in registration */ 08899 ast_mutex_unlock(&iaxsl[callno]); 08900 if ((p = find_peer(peer_name, 1))) { 08901 last_authmethod = p->authmethods; 08902 } 08903 08904 ast_mutex_lock(&iaxsl[callno]); 08905 if (!iaxs[callno]) 08906 goto return_unref; 08907 08908 memset(&ied, 0, sizeof(ied)); 08909 /* The selection of which delayed reject is sent may leak information, 08910 * if it sets a static response. For example, if a host is known to only 08911 * use MD5 authentication, then an RSA response would indicate that the 08912 * peer does not exist, and vice-versa. 08913 * Therefore, we use whatever the last peer used (which may vary over the 08914 * course of a server, which should leak minimal information). */ 08915 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 08916 if (!p) { 08917 iaxs[callno]->authmethods = sentauthmethod; 08918 } 08919 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 08920 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 08921 /* Build the challenge */ 08922 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 08923 ast_string_field_set(iaxs[callno], challenge, challenge); 08924 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 08925 } 08926 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 08927 08928 return_unref: 08929 if (p) { 08930 peer_unref(p); 08931 } 08932 08933 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 08934 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 8936 of file chan_iax2.c.
References add_empty_calltoken_ie(), iax2_registry::addr, ast_copy_string(), AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_sockaddr_to_sin, ast_strlen_zero(), authenticate(), iax_ies::authmethods, iax_ies::challenge, IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, iax2_registry::regstate, iax2_registry::secret, send_command(), iax2_registry::username, and iax_ies::username.
Referenced by socket_process().
08937 { 08938 struct iax2_registry *reg; 08939 /* Start pessimistic */ 08940 struct iax_ie_data ied; 08941 char peer[256] = ""; 08942 char challenge[256] = ""; 08943 int res; 08944 int authmethods = 0; 08945 if (ies->authmethods) 08946 authmethods = ies->authmethods; 08947 if (ies->username) 08948 ast_copy_string(peer, ies->username, sizeof(peer)); 08949 if (ies->challenge) 08950 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 08951 memset(&ied, 0, sizeof(ied)); 08952 reg = iaxs[callno]->reg; 08953 if (reg) { 08954 struct sockaddr_in reg_addr; 08955 08956 ast_sockaddr_to_sin(®->addr, ®_addr); 08957 08958 if (inaddrcmp(®_addr, sin)) { 08959 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08960 return -1; 08961 } 08962 if (ast_strlen_zero(reg->secret)) { 08963 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 08964 reg->regstate = REG_STATE_NOAUTH; 08965 return -1; 08966 } 08967 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08968 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08969 if (reg->secret[0] == '[') { 08970 char tmpkey[256]; 08971 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 08972 tmpkey[strlen(tmpkey) - 1] = '\0'; 08973 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL); 08974 } else 08975 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL); 08976 if (!res) { 08977 reg->regstate = REG_STATE_AUTHSENT; 08978 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 08979 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08980 } else 08981 return -1; 08982 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 08983 } else 08984 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 08985 return -1; 08986 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 7061 of file chan_iax2.c.
References REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.
Referenced by handle_cli_iax2_show_registry(), handle_response_register(), manager_iax2_show_registry(), manager_show_registry(), sip_reg_timeout(), and sip_show_registry().
07062 { 07063 switch(regstate) { 07064 case REG_STATE_UNREGISTERED: 07065 return "Unregistered"; 07066 case REG_STATE_REGSENT: 07067 return "Request Sent"; 07068 case REG_STATE_AUTHSENT: 07069 return "Auth. Sent"; 07070 case REG_STATE_REGISTERED: 07071 return "Registered"; 07072 case REG_STATE_REJECTED: 07073 return "Rejected"; 07074 case REG_STATE_TIMEOUT: 07075 return "Timeout"; 07076 case REG_STATE_NOAUTH: 07077 return "No Authentication"; 07078 default: 07079 return "Unknown"; 07080 } 07081 }
static int reload | ( | void | ) | [static] |
Definition at line 13586 of file chan_iax2.c.
References reload_config().
13587 { 13588 return reload_config(); 13589 }
static int reload_config | ( | void | ) | [static] |
Definition at line 13537 of file chan_iax2.c.
References ao2_callback, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_unload_realtime(), callno_limits, calltoken_ignores, config, debugaddr, iax2_registry::entry, iax2_do_register(), iax_provision_reload(), OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, peercnts, poke_all_peers(), prune_addr_range_cb(), prune_peers(), prune_users(), reload_firmware(), set_config(), and set_peercnt_limit_all_cb().
13538 { 13539 static const char config[] = "iax.conf"; 13540 struct iax2_registry *reg; 13541 13542 if (set_config(config, 1) > 0) { 13543 prune_peers(); 13544 prune_users(); 13545 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13546 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13547 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL); 13548 trunk_timed = trunk_untimed = 0; 13549 trunk_nmaxmtu = trunk_maxmtu = 0; 13550 memset(&debugaddr, '\0', sizeof(debugaddr)); 13551 13552 AST_LIST_LOCK(®istrations); 13553 AST_LIST_TRAVERSE(®istrations, reg, entry) 13554 iax2_do_register(reg); 13555 AST_LIST_UNLOCK(®istrations); 13556 13557 /* Qualify hosts, too */ 13558 poke_all_peers(); 13559 } 13560 13561 reload_firmware(0); 13562 iax_provision_reload(1); 13563 ast_unload_realtime("iaxpeers"); 13564 13565 return 0; 13566 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 3225 of file chan_iax2.c.
References ast_config_AST_DATA_DIR, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verb, iax_firmware::dead, destroy_firmware(), errno, iax2_trunk_peer::list, LOG_WARNING, and try_firmware().
Referenced by __unload_module(), load_module(), and reload_config().
03226 { 03227 struct iax_firmware *cur = NULL; 03228 DIR *fwd; 03229 struct dirent *de; 03230 char dir[256], fn[256]; 03231 03232 AST_LIST_LOCK(&firmwares); 03233 03234 /* Mark all as dead */ 03235 AST_LIST_TRAVERSE(&firmwares, cur, list) 03236 cur->dead = 1; 03237 03238 /* Now that we have marked them dead... load new ones */ 03239 if (!unload) { 03240 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR); 03241 fwd = opendir(dir); 03242 if (fwd) { 03243 while((de = readdir(fwd))) { 03244 if (de->d_name[0] != '.') { 03245 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 03246 if (!try_firmware(fn)) { 03247 ast_verb(2, "Loaded firmware '%s'\n", de->d_name); 03248 } 03249 } 03250 } 03251 closedir(fwd); 03252 } else 03253 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 03254 } 03255 03256 /* Clean up leftovers */ 03257 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) { 03258 if (!cur->dead) 03259 continue; 03260 AST_LIST_REMOVE_CURRENT(list); 03261 destroy_firmware(cur); 03262 } 03263 AST_LIST_TRAVERSE_SAFE_END; 03264 03265 AST_LIST_UNLOCK(&firmwares); 03266 }
static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2140 of file chan_iax2.c.
References ao2_unlink, ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by complete_transfer(), iax2_destroy(), resend_with_token(), and socket_process().
02141 { 02142 if (!pvt->peercallno) { 02143 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 02144 return; 02145 } 02146 02147 ao2_unlink(iax_peercallno_pvts, pvt); 02148 }
static void remove_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2121 of file chan_iax2.c.
References ao2_unlink, ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by complete_transfer(), and iax2_destroy().
02122 { 02123 if (!pvt->transfercallno) { 02124 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 02125 return; 02126 } 02127 02128 ao2_unlink(iax_transfercallno_pvts, pvt); 02129 }
static int replace_callno | ( | const void * | obj | ) | [static] |
Definition at line 2657 of file chan_iax2.c.
References ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_log(), callno_entry::callno, LOG_ERROR, and callno_entry::validated.
Referenced by __find_callno(), make_trunk(), and sched_delay_remove().
02658 { 02659 struct callno_entry *callno_entry = (struct callno_entry *) obj; 02660 02661 /* the callno_pool container is locked here primarily to ensure thread 02662 * safety of the total_nonval_callno_used check and decrement */ 02663 ao2_lock(callno_pool); 02664 02665 if (!callno_entry->validated && (total_nonval_callno_used != 0)) { 02666 total_nonval_callno_used--; 02667 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) { 02668 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno); 02669 } 02670 02671 if (callno_entry->callno < TRUNK_CALL_START) { 02672 ao2_link(callno_pool, callno_entry); 02673 } else { 02674 ao2_link(callno_pool_trunk, callno_entry); 02675 } 02676 ao2_ref(callno_entry, -1); /* only container ref remains */ 02677 02678 ao2_unlock(callno_pool); 02679 return 0; 02680 }
static void requirecalltoken_mark_auto | ( | const char * | name, | |
int | subclass | |||
) | [static] |
Definition at line 4843 of file chan_iax2.c.
References ast_strlen_zero(), CALLTOKEN_AUTO, iax2_peer::calltoken_required, CALLTOKEN_YES, find_peer(), find_user(), IAX_COMMAND_NEW, peer_unref(), user, and user_unref().
Referenced by handle_call_token().
04844 { 04845 struct iax2_user *user = NULL; 04846 struct iax2_peer *peer = NULL; 04847 04848 if (ast_strlen_zero(name)) { 04849 return; /* no username given */ 04850 } 04851 04852 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) { 04853 user->calltoken_required = CALLTOKEN_YES; 04854 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) { 04855 peer->calltoken_required = CALLTOKEN_YES; 04856 } 04857 04858 if (peer) { 04859 peer_unref(peer); 04860 } 04861 if (user) { 04862 user_unref(user); 04863 } 04864 }
static void resend_with_token | ( | int | callno, | |
struct iax_frame * | f, | |||
const char * | newtoken | |||
) | [static] |
Definition at line 4761 of file chan_iax2.c.
References chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_LIST_REMOVE, iax_ie_data::buf, chan_iax2_pvt::calltoken_ie_len, f, frame_queue, iax2_allow_new(), iax2_frame_free(), iax_ie_append_str(), IAX_IE_CALLTOKEN, iaxs, chan_iax2_pvt::iseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, remove_by_peercallno(), chan_iax2_pvt::rseqno, and send_command().
Referenced by socket_process().
04762 { 04763 struct chan_iax2_pvt *pvt = iaxs[callno]; 04764 int frametype = f->af.frametype; 04765 int subclass = f->af.subclass.integer; 04766 struct { 04767 struct ast_iax2_full_hdr fh; 04768 struct iax_ie_data ied; 04769 } data = { 04770 .ied.buf = { 0 }, 04771 .ied.pos = 0, 04772 }; 04773 /* total len - header len gives us the frame's IE len */ 04774 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr); 04775 04776 if (!pvt) { 04777 return; /* this should not be possible if called from socket_process() */ 04778 } 04779 04780 /* 04781 * Check to make sure last frame sent is valid for call token resend 04782 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 04783 * 2. Frame should _NOT_ already have a destination callno 04784 * 3. Frame must be a valid iax_frame subclass capable of starting dialog 04785 * 4. Pvt must have a calltoken_ie_len which represents the number of 04786 * bytes at the end of the frame used for the previous calltoken ie. 04787 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length 04788 * 6. Total length of f->data must be _LESS_ than size of our data struct 04789 * because f->data must be able to fit within data. 04790 */ 04791 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0) 04792 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) || 04793 (f->datalen > sizeof(data))) { 04794 04795 return; /* ignore resend, token was not valid for the dialog */ 04796 } 04797 04798 /* token is valid 04799 * 1. Copy frame data over 04800 * 2. Redo calltoken IE, it will always be the last ie in the frame. 04801 * NOTE: Having the ie always be last is not protocol specified, 04802 * it is only an implementation choice. Since we only expect the ie to 04803 * be last for frames we have sent, this can no way be affected by 04804 * another end point. 04805 * 3. Remove frame from queue 04806 * 4. Free old frame 04807 * 5. Clear previous seqnos 04808 * 6. Resend with CALLTOKEN ie. 04809 */ 04810 04811 /* ---1.--- */ 04812 memcpy(&data, f->data, f->datalen); 04813 data.ied.pos = ie_data_pos; 04814 04815 /* ---2.--- */ 04816 /* move to the beginning of the calltoken ie so we can write over it */ 04817 data.ied.pos -= pvt->calltoken_ie_len; 04818 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken); 04819 04820 /* make sure to update token length incase it ever has to be stripped off again */ 04821 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */ 04822 04823 /* ---3.--- */ 04824 AST_LIST_REMOVE(&frame_queue[callno], f, list); 04825 04826 /* ---4.--- */ 04827 iax2_frame_free(f); 04828 04829 /* ---5.--- */ 04830 pvt->oseqno = 0; 04831 pvt->rseqno = 0; 04832 pvt->iseqno = 0; 04833 pvt->aseqno = 0; 04834 if (pvt->peercallno) { 04835 remove_by_peercallno(pvt); 04836 pvt->peercallno = 0; 04837 } 04838 04839 /* ---6.--- */ 04840 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1); 04841 }
Definition at line 9464 of file chan_iax2.c.
References ast_string_field_set, iax_frame::callno, IAX_MAX_OSPBLOCK_NUM, IAX_MAX_OSPBLOCK_SIZE, IAX_MAX_OSPBUFF_SIZE, iaxs, iax_ies::ospblocklength, and iax_ies::osptokenblock.
Referenced by socket_process().
09465 { 09466 int i; 09467 unsigned int length, offset = 0; 09468 char full_osptoken[IAX_MAX_OSPBUFF_SIZE]; 09469 09470 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) { 09471 length = ies->ospblocklength[i]; 09472 if (length != 0) { 09473 if (length > IAX_MAX_OSPBLOCK_SIZE) { 09474 /* OSP token block length wrong, clear buffer */ 09475 offset = 0; 09476 break; 09477 } else { 09478 memcpy(full_osptoken + offset, ies->osptokenblock[i], length); 09479 offset += length; 09480 } 09481 } else { 09482 break; 09483 } 09484 } 09485 *(full_osptoken + offset) = '\0'; 09486 if (strlen(full_osptoken) != offset) { 09487 /* OSP token length wrong, clear buffer */ 09488 *full_osptoken = '\0'; 09489 } 09490 09491 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken); 09492 }
Definition at line 9453 of file chan_iax2.c.
References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iaxs, iax_rr::jitter, iax_rr::losscnt, iax_rr::losspct, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::remote_rr, iax_ies::rr_delay, iax_ies::rr_dropped, iax_ies::rr_jitter, iax_ies::rr_loss, iax_ies::rr_ooo, and iax_ies::rr_pkts.
Referenced by socket_process().
09454 { 09455 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 09456 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 09457 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 09458 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 09459 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 09460 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 09461 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 09462 }
static void sched_delay_remove | ( | struct sockaddr_in * | sin, | |
struct callno_entry * | callno_entry | |||
) | [static] |
Definition at line 2729 of file chan_iax2.c.
References peercnt::addr, ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), iax2_sched_add(), MIN_REUSE_TIME, OBJ_POINTER, peercnt_remove_cb(), peercnts, replace_callno(), and sched.
Referenced by pvt_destructor().
02730 { 02731 int i; 02732 struct peercnt *peercnt; 02733 struct peercnt tmp = { 02734 .addr = sin->sin_addr.s_addr, 02735 }; 02736 02737 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02738 /* refcount is incremented with ao2_find. keep that ref for the scheduler */ 02739 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME); 02740 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt); 02741 if (i == -1) { 02742 ao2_ref(peercnt, -1); 02743 } 02744 } 02745 02746 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry); 02747 }
static int schedule_delivery | ( | struct iax_frame * | fr, | |
int | updatehistory, | |||
int | fromtrunk, | |||
unsigned int * | tsout | |||
) | [static] |
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it.
Definition at line 4158 of file chan_iax2.c.
References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_channel_unlock, ast_codec_get_samples(), ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_samp2tv(), ast_sched_thread_del, ast_test_flag64, ast_tv(), ast_tvadd(), ast_tvzero(), ast_channel::bridge, calc_rxstamp(), iax_frame::callno, ast_frame_subclass::codec, jb_frame::data, ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_lock_owner(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, sched, ast_frame::subclass, iax_frame::ts, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process(), and socket_process_meta().
04159 { 04160 int type, len; 04161 int ret; 04162 int needfree = 0; 04163 struct ast_channel *owner = NULL; 04164 struct ast_channel *bridge = NULL; 04165 04166 /* 04167 * Clear fr->af.data if there is no data in the buffer. Things 04168 * like AST_CONTROL_HOLD without a suggested music class must 04169 * have a NULL pointer. 04170 */ 04171 if (!fr->af.datalen) { 04172 memset(&fr->af.data, 0, sizeof(fr->af.data)); 04173 } 04174 04175 /* Attempt to recover wrapped timestamps */ 04176 unwrap_timestamp(fr); 04177 04178 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 04179 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 04180 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 04181 else { 04182 #if 0 04183 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 04184 #endif 04185 fr->af.delivery = ast_tv(0,0); 04186 } 04187 04188 type = JB_TYPE_CONTROL; 04189 len = 0; 04190 04191 if(fr->af.frametype == AST_FRAME_VOICE) { 04192 type = JB_TYPE_VOICE; 04193 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000); 04194 } else if(fr->af.frametype == AST_FRAME_CNG) { 04195 type = JB_TYPE_SILENCE; 04196 } 04197 04198 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 04199 if (tsout) 04200 *tsout = fr->ts; 04201 __do_deliver(fr); 04202 return -1; 04203 } 04204 04205 iax2_lock_owner(fr->callno); 04206 if (!iaxs[fr->callno]) { 04207 /* The call dissappeared so discard this frame that we could not send. */ 04208 iax2_frame_free(fr); 04209 return -1; 04210 } 04211 if ((owner = iaxs[fr->callno]->owner)) 04212 bridge = ast_bridged_channel(owner); 04213 04214 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 04215 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 04216 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 04217 jb_frame frame; 04218 04219 ast_channel_unlock(owner); 04220 04221 /* deliver any frames in the jb */ 04222 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 04223 __do_deliver(frame.data); 04224 /* __do_deliver() can make the call disappear */ 04225 if (!iaxs[fr->callno]) 04226 return -1; 04227 } 04228 04229 jb_reset(iaxs[fr->callno]->jb); 04230 04231 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid); 04232 04233 /* deliver this frame now */ 04234 if (tsout) 04235 *tsout = fr->ts; 04236 __do_deliver(fr); 04237 return -1; 04238 } 04239 if (owner) { 04240 ast_channel_unlock(owner); 04241 } 04242 04243 /* insert into jitterbuffer */ 04244 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 04245 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 04246 calc_rxstamp(iaxs[fr->callno],fr->ts)); 04247 if (ret == JB_DROP) { 04248 needfree++; 04249 } else if (ret == JB_SCHED) { 04250 update_jbsched(iaxs[fr->callno]); 04251 } 04252 if (tsout) 04253 *tsout = fr->ts; 04254 if (needfree) { 04255 /* Free our iax frame */ 04256 iax2_frame_free(fr); 04257 return -1; 04258 } 04259 return 0; 04260 }
static int scheduled_destroy | ( | const void * | vid | ) | [static] |
Definition at line 1806 of file chan_iax2.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_destroy(), iaxs, iaxsl, LOG_DEBUG, option_debug, and PTR_TO_CALLNO.
Referenced by iax2_hangup().
01807 { 01808 unsigned short callno = PTR_TO_CALLNO(vid); 01809 ast_mutex_lock(&iaxsl[callno]); 01810 if (iaxs[callno]) { 01811 if (option_debug) { 01812 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno); 01813 } 01814 iax2_destroy(callno); 01815 } 01816 ast_mutex_unlock(&iaxsl[callno]); 01817 return 0; 01818 }
static int send_apathetic_reply | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | command, | |||
int | ts, | |||
unsigned char | seqno, | |||
int | sockfd, | |||
struct iax_ie_data * | ied | |||
) | [static] |
Definition at line 4721 of file chan_iax2.c.
References AST_FRAME_IAX, iax_ie_data::buf, compress_subclass(), f, IAX_FLAG_RETRANS, iax_outputframe(), and iax_ie_data::pos.
Referenced by handle_call_token(), and socket_process().
04724 { 04725 struct { 04726 struct ast_iax2_full_hdr f; 04727 struct iax_ie_data ied; 04728 } data; 04729 size_t size = sizeof(struct ast_iax2_full_hdr); 04730 04731 if (ied) { 04732 size += ied->pos; 04733 memcpy(&data.ied, ied->buf, ied->pos); 04734 } 04735 04736 data.f.scallno = htons(0x8000 | callno); 04737 data.f.dcallno = htons(dcallno & ~IAX_FLAG_RETRANS); 04738 data.f.ts = htonl(ts); 04739 data.f.iseqno = seqno; 04740 data.f.oseqno = 0; 04741 data.f.type = AST_FRAME_IAX; 04742 data.f.csub = compress_subclass(command); 04743 04744 if (iaxdebug) { 04745 iax_outputframe(NULL, &data.f, 0, sin, size - sizeof(struct ast_iax2_full_hdr)); 04746 } 04747 04748 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin)); 04749 }
static int send_command | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 7500 of file chan_iax2.c.
References __send_command().
Referenced by __attempt_transmit(), __send_lagrq(), __send_ping(), authenticate_reply(), authenticate_request(), cache_get_callno_locked(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_indicate(), iax2_key_rotate(), iax2_poke_peer(), iax2_provision(), iax2_start_transfer(), registry_authrequest(), registry_rerequest(), resend_with_token(), send_command_locked(), and socket_process().
07501 { 07502 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 07503 }
static int send_command_final | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno | |||
) | [static] |
Definition at line 7519 of file chan_iax2.c.
References __send_command(), chan_iax2_pvt::callno, iax2_predestroy(), and iaxs.
Referenced by __auth_reject(), __auto_hangup(), authenticate_request(), iax2_hangup(), socket_process(), and update_registry().
07520 { 07521 int call_num = i->callno; 07522 /* It is assumed that the callno has already been locked */ 07523 iax2_predestroy(i->callno); 07524 if (!iaxs[call_num]) 07525 return -1; 07526 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 07527 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 7529 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
07530 { 07531 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 07532 }
static int send_command_locked | ( | unsigned short | callno, | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 7505 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_unlock, iaxs, iaxsl, and send_command().
Referenced by iax2_answer(), iax2_digit_begin(), iax2_digit_end(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), and iax2_transfer().
07506 { 07507 int res; 07508 ast_mutex_lock(&iaxsl[callno]); 07509 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 07510 ast_mutex_unlock(&iaxsl[callno]); 07511 return res; 07512 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | ||||
) | [static] |
Definition at line 7534 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
07535 { 07536 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 07537 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1592 of file chan_iax2.c.
References __send_lagrq(), ast_mutex_lock, ast_mutex_unlock, iax2_thread::callno, DONT_RESCHEDULE, iaxs, iaxsl, chan_iax2_pvt::lagid, and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01593 { 01594 int callno = (long) data; 01595 ast_mutex_lock(&iaxsl[callno]); 01596 if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) { 01597 iaxs[callno]->lagid = -1; 01598 } 01599 ast_mutex_unlock(&iaxsl[callno]); 01600 01601 #ifdef SCHED_MULTITHREADED 01602 if (schedule_action(__send_lagrq, data)) 01603 #endif 01604 __send_lagrq(data); 01605 return 0; 01606 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3338 of file chan_iax2.c.
References chan_iax2_pvt::addr, ast_debug, ast_inet_ntoa(), errno, f, handle_error(), iax_showframe(), iaxs, chan_iax2_pvt::peercallno, iax2_trunk_peer::sockfd, and chan_iax2_pvt::transfer.
Referenced by __attempt_transmit(), iax2_send(), transmit_frame(), and vnak_retransmit().
03339 { 03340 int res; 03341 int callno = f->callno; 03342 03343 /* Don't send if there was an error, but return error instead */ 03344 if (!callno || !iaxs[callno] || iaxs[callno]->error) 03345 return -1; 03346 03347 /* Called with iaxsl held */ 03348 if (iaxdebug) 03349 ast_debug(3, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port)); 03350 03351 if (f->transfer) { 03352 if (iaxdebug) 03353 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03354 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer)); 03355 } else { 03356 if (iaxdebug) 03357 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03358 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr)); 03359 } 03360 if (res < 0) { 03361 if (iaxdebug) 03362 ast_debug(1, "Received error: %s\n", strerror(errno)); 03363 handle_error(); 03364 } else 03365 res = 0; 03366 03367 return res; 03368 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1525 of file chan_iax2.c.
References __send_ping(), ast_mutex_lock, ast_mutex_unlock, iax2_thread::callno, DONT_RESCHEDULE, iaxs, iaxsl, chan_iax2_pvt::pingid, and schedule_action.
Referenced by __find_callno(), __send_ping(), do_monitor(), init_phone_step2(), and make_trunk().
01526 { 01527 int callno = (long) data; 01528 ast_mutex_lock(&iaxsl[callno]); 01529 if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) { 01530 iaxs[callno]->pingid = -1; 01531 } 01532 ast_mutex_unlock(&iaxsl[callno]); 01533 01534 #ifdef SCHED_MULTITHREADED 01535 if (schedule_action(__send_ping, data)) 01536 #endif 01537 __send_ping(data); 01538 01539 return 0; 01540 }
static void send_signaling | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point.
Definition at line 1830 of file chan_iax2.c.
References AST_LIST_REMOVE_HEAD, signaling_queue_entry::f, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, iax2_send(), iax2_trunk_peer::next, and chan_iax2_pvt::signaling_queue.
Referenced by socket_process().
01831 { 01832 struct signaling_queue_entry *s = NULL; 01833 01834 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01835 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0); 01836 free_signaling_queue_entry(s); 01837 } 01838 pvt->hold_signaling = 0; 01839 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 9120 of file chan_iax2.c.
References iax2_trunk_peer::addr, iax_frame::afdata, ast_debug, ast_inet_ntoa(), ast_test_flag64, calc_txpeerstamp(), iax2_trunk_peer::calls, ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, globalflags, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, iax_frame::retrans, iax2_trunk_peer::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, ast_iax2_meta_trunk_hdr::ts, and ast_iax2_meta_hdr::zeros.
Referenced by iax2_trunk_queue(), and timing_read().
09121 { 09122 int res = 0; 09123 struct iax_frame *fr; 09124 struct ast_iax2_meta_hdr *meta; 09125 struct ast_iax2_meta_trunk_hdr *mth; 09126 int calls = 0; 09127 09128 /* Point to frame */ 09129 fr = (struct iax_frame *)tpeer->trunkdata; 09130 /* Point to meta data */ 09131 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 09132 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 09133 if (tpeer->trunkdatalen) { 09134 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 09135 meta->zeros = 0; 09136 meta->metacmd = IAX_META_TRUNK; 09137 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) 09138 meta->cmddata = IAX_META_TRUNK_MINI; 09139 else 09140 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 09141 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 09142 /* And the rest of the ast_iax2 header */ 09143 fr->direction = DIRECTION_OUTGRESS; 09144 fr->retrans = -1; 09145 fr->transfer = 0; 09146 /* Any appropriate call will do */ 09147 fr->data = fr->afdata; 09148 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 09149 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 09150 calls = tpeer->calls; 09151 #if 0 09152 ast_debug(1, "Trunking %d call chunks in %d bytes to %s:%d, ts=%d\n", calls, fr->datalen, ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), ntohl(mth->ts)); 09153 #endif 09154 /* Reset transmit trunk side data */ 09155 tpeer->trunkdatalen = 0; 09156 tpeer->calls = 0; 09157 } 09158 if (res < 0) 09159 return res; 09160 return calls; 09161 }
static int set_config | ( | const char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 13041 of file chan_iax2.c.
References add_calltoken_ignore(), ao2_link, ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, ast_clear_flag64, ast_config_destroy(), ast_config_load, ast_context_find_or_create(), ast_copy_string(), ast_false(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_netsock_bind(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_allow_disallow(), ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_str2cos(), ast_str2tos(), ast_strlen_zero(), ast_test_flag64, ast_timer_set_rate(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, build_callno_limits(), build_peer(), build_user(), capability, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), globalflags, iax2_register(), IAX_ALLOWFWDOWNLOAD, IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTSAVE_SYSNAME, IAX_RTUPDATE, IAX_SENDCONNECTEDLINE, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxmaxthreadcount, iaxthreadcount, io, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_TRUNK_MTU, MAX_TRUNKDATA, ast_variable::name, netsock, network_change_event_subscribe(), network_change_event_unsubscribe(), ast_variable::next, outsock, peer_unref(), peers, prefs, qos, reg_source_db(), secret, set_config_destroy(), socket_read(), timer, user, user_unref(), users, and ast_variable::value.
Referenced by load_module(), reload(), reload_config(), and reload_module().
13042 { 13043 struct ast_config *cfg, *ucfg; 13044 format_t capability = iax2_capability; 13045 struct ast_variable *v; 13046 char *cat; 13047 const char *utype; 13048 const char *tosval; 13049 int format; 13050 int portno = IAX_DEFAULT_PORTNO; 13051 int x; 13052 int mtuv; 13053 int subscribe_network_change = 1; 13054 struct iax2_user *user; 13055 struct iax2_peer *peer; 13056 struct ast_netsock *ns; 13057 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 13058 #if 0 13059 static unsigned short int last_port=0; 13060 #endif 13061 13062 cfg = ast_config_load(config_file, config_flags); 13063 13064 if (!cfg) { 13065 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 13066 return -1; 13067 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 13068 ucfg = ast_config_load("users.conf", config_flags); 13069 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) 13070 return 0; 13071 /* Otherwise we need to reread both files */ 13072 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 13073 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) { 13074 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 13075 ast_config_destroy(ucfg); 13076 return 0; 13077 } 13078 if (!cfg) { 13079 /* should have been able to load the config here */ 13080 ast_log(LOG_ERROR, "Unable to load config %s again\n", config_file); 13081 return -1; 13082 } 13083 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 13084 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 13085 return 0; 13086 } else { /* iax.conf changed, gotta reread users.conf, too */ 13087 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 13088 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 13089 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n"); 13090 ast_config_destroy(cfg); 13091 return 0; 13092 } 13093 } 13094 13095 if (reload) { 13096 set_config_destroy(); 13097 } 13098 13099 /* Reset global codec prefs */ 13100 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 13101 13102 /* Reset Global Flags */ 13103 memset(&globalflags, 0, sizeof(globalflags)); 13104 ast_set_flag64(&globalflags, IAX_RTUPDATE); 13105 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 13106 13107 #ifdef SO_NO_CHECK 13108 nochecksums = 0; 13109 #endif 13110 /* Reset default parking lot */ 13111 default_parkinglot[0] = '\0'; 13112 13113 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 13114 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 13115 global_max_trunk_mtu = MAX_TRUNK_MTU; 13116 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT; 13117 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL; 13118 13119 maxauthreq = 3; 13120 13121 srvlookup = 0; 13122 13123 v = ast_variable_browse(cfg, "general"); 13124 13125 /* Seed initial tos value */ 13126 tosval = ast_variable_retrieve(cfg, "general", "tos"); 13127 if (tosval) { 13128 if (ast_str2tos(tosval, &qos.tos)) 13129 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n"); 13130 } 13131 /* Seed initial cos value */ 13132 tosval = ast_variable_retrieve(cfg, "general", "cos"); 13133 if (tosval) { 13134 if (ast_str2cos(tosval, &qos.cos)) 13135 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n"); 13136 } 13137 while(v) { 13138 if (!strcasecmp(v->name, "bindport")){ 13139 if (reload) 13140 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 13141 else 13142 portno = atoi(v->value); 13143 } else if (!strcasecmp(v->name, "pingtime")) 13144 ping_time = atoi(v->value); 13145 else if (!strcasecmp(v->name, "iaxthreadcount")) { 13146 if (reload) { 13147 if (atoi(v->value) != iaxthreadcount) 13148 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 13149 } else { 13150 iaxthreadcount = atoi(v->value); 13151 if (iaxthreadcount < 1) { 13152 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 13153 iaxthreadcount = 1; 13154 } else if (iaxthreadcount > 256) { 13155 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 13156 iaxthreadcount = 256; 13157 } 13158 } 13159 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 13160 if (reload) { 13161 AST_LIST_LOCK(&dynamic_list); 13162 iaxmaxthreadcount = atoi(v->value); 13163 AST_LIST_UNLOCK(&dynamic_list); 13164 } else { 13165 iaxmaxthreadcount = atoi(v->value); 13166 if (iaxmaxthreadcount < 0) { 13167 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 13168 iaxmaxthreadcount = 0; 13169 } else if (iaxmaxthreadcount > 256) { 13170 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 13171 iaxmaxthreadcount = 256; 13172 } 13173 } 13174 } else if (!strcasecmp(v->name, "nochecksums")) { 13175 #ifdef SO_NO_CHECK 13176 if (ast_true(v->value)) 13177 nochecksums = 1; 13178 else 13179 nochecksums = 0; 13180 #else 13181 if (ast_true(v->value)) 13182 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 13183 #endif 13184 } 13185 else if (!strcasecmp(v->name, "maxjitterbuffer")) 13186 maxjitterbuffer = atoi(v->value); 13187 else if (!strcasecmp(v->name, "resyncthreshold")) 13188 resyncthreshold = atoi(v->value); 13189 else if (!strcasecmp(v->name, "maxjitterinterps")) 13190 maxjitterinterps = atoi(v->value); 13191 else if (!strcasecmp(v->name, "jittertargetextra")) 13192 jittertargetextra = atoi(v->value); 13193 else if (!strcasecmp(v->name, "lagrqtime")) 13194 lagrq_time = atoi(v->value); 13195 else if (!strcasecmp(v->name, "maxregexpire")) 13196 max_reg_expire = atoi(v->value); 13197 else if (!strcasecmp(v->name, "minregexpire")) 13198 min_reg_expire = atoi(v->value); 13199 else if (!strcasecmp(v->name, "bindaddr")) { 13200 if (reload) { 13201 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 13202 } else { 13203 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) { 13204 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 13205 } else { 13206 if (strchr(v->value, ':')) 13207 ast_verb(2, "Binding IAX2 to '%s'\n", v->value); 13208 else 13209 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno); 13210 if (defaultsockfd < 0) 13211 defaultsockfd = ast_netsock_sockfd(ns); 13212 ast_netsock_unref(ns); 13213 } 13214 } 13215 } else if (!strcasecmp(v->name, "authdebug")) { 13216 authdebug = ast_true(v->value); 13217 } else if (!strcasecmp(v->name, "encryption")) { 13218 iax2_encryption |= get_encrypt_methods(v->value); 13219 if (!iax2_encryption) { 13220 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13221 } 13222 } else if (!strcasecmp(v->name, "forceencryption")) { 13223 if (ast_false(v->value)) { 13224 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13225 } else { 13226 iax2_encryption |= get_encrypt_methods(v->value); 13227 if (iax2_encryption) { 13228 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13229 } 13230 } 13231 } else if (!strcasecmp(v->name, "transfer")) { 13232 if (!strcasecmp(v->value, "mediaonly")) { 13233 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 13234 } else if (ast_true(v->value)) { 13235 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 13236 } else 13237 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 13238 } else if (!strcasecmp(v->name, "codecpriority")) { 13239 if(!strcasecmp(v->value, "caller")) 13240 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST); 13241 else if(!strcasecmp(v->value, "disabled")) 13242 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13243 else if(!strcasecmp(v->value, "reqonly")) { 13244 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP); 13245 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13246 } 13247 } else if (!strcasecmp(v->name, "jitterbuffer")) 13248 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 13249 else if (!strcasecmp(v->name, "forcejitterbuffer")) 13250 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 13251 else if (!strcasecmp(v->name, "delayreject")) 13252 delayreject = ast_true(v->value); 13253 else if (!strcasecmp(v->name, "allowfwdownload")) 13254 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 13255 else if (!strcasecmp(v->name, "rtcachefriends")) 13256 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 13257 else if (!strcasecmp(v->name, "rtignoreregexpire")) 13258 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 13259 else if (!strcasecmp(v->name, "rtupdate")) 13260 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE); 13261 else if (!strcasecmp(v->name, "rtsavesysname")) 13262 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME); 13263 else if (!strcasecmp(v->name, "trunktimestamps")) 13264 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 13265 else if (!strcasecmp(v->name, "rtautoclear")) { 13266 int i = atoi(v->value); 13267 if(i > 0) 13268 global_rtautoclear = i; 13269 else 13270 i = 0; 13271 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 13272 } else if (!strcasecmp(v->name, "trunkfreq")) { 13273 trunkfreq = atoi(v->value); 13274 if (trunkfreq < 10) { 13275 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 10ms instead.\n"); 13276 trunkfreq = 10; 13277 } else if (trunkfreq > 1000) { 13278 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 1000ms instead.\n"); 13279 trunkfreq = 1000; 13280 } 13281 if (timer) { 13282 ast_timer_set_rate(timer, 1000 / trunkfreq); 13283 } 13284 } else if (!strcasecmp(v->name, "trunkmtu")) { 13285 mtuv = atoi(v->value); 13286 if (mtuv == 0 ) 13287 global_max_trunk_mtu = 0; 13288 else if (mtuv >= 172 && mtuv < 4000) 13289 global_max_trunk_mtu = mtuv; 13290 else 13291 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n", 13292 mtuv, v->lineno); 13293 } else if (!strcasecmp(v->name, "trunkmaxsize")) { 13294 trunkmaxsize = atoi(v->value); 13295 if (trunkmaxsize == 0) 13296 trunkmaxsize = MAX_TRUNKDATA; 13297 } else if (!strcasecmp(v->name, "autokill")) { 13298 if (sscanf(v->value, "%30d", &x) == 1) { 13299 if (x >= 0) 13300 autokill = x; 13301 else 13302 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 13303 } else if (ast_true(v->value)) { 13304 autokill = DEFAULT_MAXMS; 13305 } else { 13306 autokill = 0; 13307 } 13308 } else if (!strcasecmp(v->name, "bandwidth")) { 13309 if (!strcasecmp(v->value, "low")) { 13310 capability = IAX_CAPABILITY_LOWBANDWIDTH; 13311 } else if (!strcasecmp(v->value, "medium")) { 13312 capability = IAX_CAPABILITY_MEDBANDWIDTH; 13313 } else if (!strcasecmp(v->value, "high")) { 13314 capability = IAX_CAPABILITY_FULLBANDWIDTH; 13315 } else 13316 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 13317 } else if (!strcasecmp(v->name, "allow")) { 13318 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 13319 } else if (!strcasecmp(v->name, "disallow")) { 13320 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 13321 } else if (!strcasecmp(v->name, "register")) { 13322 iax2_register(v->value, v->lineno); 13323 } else if (!strcasecmp(v->name, "iaxcompat")) { 13324 iaxcompat = ast_true(v->value); 13325 } else if (!strcasecmp(v->name, "regcontext")) { 13326 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 13327 /* Create context if it doesn't exist already */ 13328 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2"); 13329 } else if (!strcasecmp(v->name, "tos")) { 13330 if (ast_str2tos(v->value, &qos.tos)) 13331 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno); 13332 } else if (!strcasecmp(v->name, "cos")) { 13333 if (ast_str2cos(v->value, &qos.cos)) 13334 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno); 13335 } else if (!strcasecmp(v->name, "parkinglot")) { 13336 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot)); 13337 } else if (!strcasecmp(v->name, "accountcode")) { 13338 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 13339 } else if (!strcasecmp(v->name, "mohinterpret")) { 13340 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 13341 } else if (!strcasecmp(v->name, "mohsuggest")) { 13342 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 13343 } else if (!strcasecmp(v->name, "amaflags")) { 13344 format = ast_cdr_amaflags2int(v->value); 13345 if (format < 0) { 13346 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 13347 } else { 13348 amaflags = format; 13349 } 13350 } else if (!strcasecmp(v->name, "language")) { 13351 ast_copy_string(language, v->value, sizeof(language)); 13352 } else if (!strcasecmp(v->name, "maxauthreq")) { 13353 maxauthreq = atoi(v->value); 13354 if (maxauthreq < 0) 13355 maxauthreq = 0; 13356 } else if (!strcasecmp(v->name, "adsi")) { 13357 adsi = ast_true(v->value); 13358 } else if (!strcasecmp(v->name, "srvlookup")) { 13359 srvlookup = ast_true(v->value); 13360 } else if (!strcasecmp(v->name, "connectedline")) { 13361 if (ast_true(v->value)) { 13362 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13363 } else if (!strcasecmp(v->value, "send")) { 13364 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13365 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13366 } else if (!strcasecmp(v->value, "receive")) { 13367 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13368 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13369 } else { 13370 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13371 } 13372 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 13373 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) { 13374 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno); 13375 } 13376 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) { 13377 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) { 13378 ast_log(LOG_WARNING, "maxcallnumbers_nonvalidated must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 13379 } 13380 } else if (!strcasecmp(v->name, "calltokenoptional")) { 13381 if (add_calltoken_ignore(v->value)) { 13382 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno); 13383 } 13384 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) { 13385 if (ast_true(v->value)) { 13386 subscribe_network_change = 1; 13387 } else if (ast_false(v->value)) { 13388 subscribe_network_change = 0; 13389 } else { 13390 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno); 13391 } 13392 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 13393 if (ast_true(v->value)) { 13394 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 13395 } else if (ast_false(v->value)) { 13396 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID); 13397 } else { 13398 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 13399 } 13400 }/*else if (strcasecmp(v->name,"type")) */ 13401 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 13402 v = v->next; 13403 } 13404 13405 if (subscribe_network_change) { 13406 network_change_event_subscribe(); 13407 } else { 13408 network_change_event_unsubscribe(); 13409 } 13410 13411 if (defaultsockfd < 0) { 13412 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) { 13413 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 13414 } else { 13415 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 13416 defaultsockfd = ast_netsock_sockfd(ns); 13417 ast_netsock_unref(ns); 13418 } 13419 } 13420 if (reload) { 13421 ast_netsock_release(outsock); 13422 outsock = ast_netsock_list_alloc(); 13423 if (!outsock) { 13424 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 13425 return -1; 13426 } 13427 ast_netsock_init(outsock); 13428 } 13429 13430 if (min_reg_expire > max_reg_expire) { 13431 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 13432 min_reg_expire, max_reg_expire, max_reg_expire); 13433 min_reg_expire = max_reg_expire; 13434 } 13435 iax2_capability = capability; 13436 13437 if (ucfg) { 13438 struct ast_variable *gen; 13439 int genhasiax; 13440 int genregisteriax; 13441 const char *hasiax, *registeriax; 13442 13443 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 13444 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 13445 gen = ast_variable_browse(ucfg, "general"); 13446 cat = ast_category_browse(ucfg, NULL); 13447 while (cat) { 13448 if (strcasecmp(cat, "general")) { 13449 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 13450 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 13451 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 13452 /* Start with general parameters, then specific parameters, user and peer */ 13453 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 13454 if (user) { 13455 ao2_link(users, user); 13456 user = user_unref(user); 13457 } 13458 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 13459 if (peer) { 13460 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13461 reg_source_db(peer); 13462 ao2_link(peers, peer); 13463 peer = peer_unref(peer); 13464 } 13465 } 13466 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 13467 char tmp[256]; 13468 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 13469 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 13470 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 13471 if (!host) 13472 host = ast_variable_retrieve(ucfg, "general", "host"); 13473 if (!username) 13474 username = ast_variable_retrieve(ucfg, "general", "username"); 13475 if (!secret) 13476 secret = ast_variable_retrieve(ucfg, "general", "secret"); 13477 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 13478 if (!ast_strlen_zero(secret)) 13479 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 13480 else 13481 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 13482 iax2_register(tmp, 0); 13483 } 13484 } 13485 } 13486 cat = ast_category_browse(ucfg, cat); 13487 } 13488 ast_config_destroy(ucfg); 13489 } 13490 13491 cat = ast_category_browse(cfg, NULL); 13492 while(cat) { 13493 if (strcasecmp(cat, "general")) { 13494 utype = ast_variable_retrieve(cfg, cat, "type"); 13495 if (!strcasecmp(cat, "callnumberlimits")) { 13496 build_callno_limits(ast_variable_browse(cfg, cat)); 13497 } else if (utype) { 13498 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 13499 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 13500 if (user) { 13501 ao2_link(users, user); 13502 user = user_unref(user); 13503 } 13504 } 13505 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 13506 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 13507 if (peer) { 13508 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13509 reg_source_db(peer); 13510 ao2_link(peers, peer); 13511 peer = peer_unref(peer); 13512 } 13513 } else if (strcasecmp(utype, "user")) { 13514 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 13515 } 13516 } else 13517 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 13518 } 13519 cat = ast_category_browse(cfg, cat); 13520 } 13521 ast_config_destroy(cfg); 13522 return 1; 13523 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 13024 of file chan_iax2.c.
References addr_range_delme_cb(), ao2_callback, ast_clear_flag64, callno_limits, calltoken_ignores, delete_users(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, MAX_TRUNKDATA, and OBJ_NODATA.
Referenced by set_config().
13025 { 13026 strcpy(accountcode, ""); 13027 strcpy(language, ""); 13028 strcpy(mohinterpret, ""); 13029 strcpy(mohsuggest, ""); 13030 trunkmaxsize = MAX_TRUNKDATA; 13031 amaflags = 0; 13032 delayreject = 0; 13033 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | 13034 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13035 delete_users(); 13036 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL); 13037 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL); 13038 }
static void set_hangup_source_and_cause | ( | int | callno, | |
unsigned char | causecode | |||
) | [static] |
Definition at line 9890 of file chan_iax2.c.
References ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_mutex_lock, ast_mutex_unlock, ast_set_hangupsource(), ast_strdupa, ast_channel::hangupcause, iax2_lock_owner(), iaxs, iaxsl, ast_channel::name, name, and chan_iax2_pvt::owner.
Referenced by socket_process().
09891 { 09892 iax2_lock_owner(callno); 09893 if (iaxs[callno] && iaxs[callno]->owner) { 09894 struct ast_channel *owner; 09895 const char *name; 09896 09897 owner = iaxs[callno]->owner; 09898 if (causecode) { 09899 owner->hangupcause = causecode; 09900 } 09901 name = ast_strdupa(owner->name); 09902 ast_channel_ref(owner); 09903 ast_channel_unlock(owner); 09904 ast_mutex_unlock(&iaxsl[callno]); 09905 ast_set_hangupsource(owner, name, 0); 09906 ast_channel_unref(owner); 09907 ast_mutex_lock(&iaxsl[callno]); 09908 } 09909 }
static void set_peercnt_limit | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2265 of file chan_iax2.c.
References peercnt::addr, addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_inet_ntoa(), callno_limits, addr_range::limit, peercnt::limit, and peercnt::reg.
Referenced by peercnt_add(), peercnt_modify(), and set_peercnt_limit_all_cb().
02266 { 02267 uint16_t limit = global_maxcallno; 02268 struct addr_range *addr_range; 02269 struct sockaddr_in sin = { 02270 .sin_addr.s_addr = peercnt->addr, 02271 }; 02272 02273 02274 if (peercnt->reg && peercnt->limit) { 02275 return; /* this peercnt has a custom limit set by a registration */ 02276 } 02277 02278 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) { 02279 limit = addr_range->limit; 02280 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr)); 02281 ao2_ref(addr_range, -1); 02282 } 02283 02284 peercnt->limit = limit; 02285 }
static int set_peercnt_limit_all_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2291 of file chan_iax2.c.
References ast_debug, and set_peercnt_limit().
Referenced by reload_config().
02292 { 02293 struct peercnt *peercnt = obj; 02294 02295 set_peercnt_limit(peercnt); 02296 ast_debug(1, "Reset limits for peercnts table\n"); 02297 02298 return 0; 02299 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 1052 of file chan_iax2.c.
References ast_cond_signal, ast_mutex_lock, and ast_mutex_unlock.
Referenced by __schedule_action(), cleanup_thread_list(), iax2_process_thread(), and socket_read().
01053 { 01054 ast_mutex_lock(lock); 01055 ast_cond_signal(cond); 01056 ast_mutex_unlock(lock); 01057 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 9911 of file chan_iax2.c.
References ast_aes_set_decrypt_key(), ast_async_goto(), ast_best_codec(), ast_bridged_channel(), ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_channel_datastore_add(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_clear_flag, ast_clear_flag64, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), ast_connected_line_parse_data(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, ast_devstate_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_free, ast_getformatname(), ast_getformatname_multiple(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_event, ast_mutex_lock, ast_mutex_unlock, ast_parking_ext_valid(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_party_id_presentation(), ast_sched_thread_del, ast_set_callerid(), ast_set_flag, ast_set_flag64, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_var_assign(), ast_variables_destroy(), ast_verb, auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax_ies::called_number, chan_iax2_pvt::calling_pres, iax_ies::callno, iax2_peer::callno, iax2_dpcache::callno, chan_iax2_pvt::callno, iax_ies::calltoken, iax_ies::calltokendata, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, check_access(), check_provisioning(), cid_name, cid_num, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), connected, construct_rr(), context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, decrypt_frame(), iax_ies::devicetype, dp_lookup(), iax_ies::encmethods, ast_var_t::entries, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, f, iax_frame::final, find_callno(), chan_iax2_pvt::first_iax_message, iax2_dpcache::flags, iax_ies::format, format, frame_queue, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, globalflags, handle_call_token(), ast_channel::hangupcause, iax2_peer::historicms, iax2_ack_registry(), iax2_allow_new(), iax2_destroy(), iax2_dprequest(), iax2_lock_owner(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), iax2_send(), iax2_variable_datastore_info, iax2_vnak(), IAX_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CALLENCRYPTED, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_RTKEY, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DEBUGDIGEST, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, IAX_FORCE_ENCRYPT, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), iax_ie_append_versioned_uint64(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_FORMAT2, IAX_IE_IAX_UNKNOWN, IAX_IMMEDIATE, iax_outputframe(), iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, IAX_RECVCONNECTEDLINE, IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iax_ies::iax_unknown, iaxfrdup2(), iaxs, iaxsl, inaddrcmp(), ast_datastore::inheritance, chan_iax2_pvt::iseqno, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, LOG_ERROR, log_jitterstats(), LOG_NOTICE, LOG_WARNING, make_trunk(), manager_event, iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, iax_ies::musiconhold, iax2_peer::name, ast_channel::name, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, iax_frame::oseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, iax_ies::provver, iax_ies::provverpres, raw_hangup(), iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rseqno, S_COR, S_OR, save_osptoken(), save_rr(), sched, schedule_delivery(), send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), send_signaling(), iax_ies::serviceident, set_hangup_source_and_cause(), iax2_peer::smoothing, socket_process_meta(), spawn_dp_lookup(), stop_stuff(), store_by_peercallno(), thread, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, try_transfer(), iax_frame::ts, uncompress_subclass(), update_registry(), iax_ies::username, var, iax_ies::vars, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.
Referenced by handle_deferred_full_frames().
09912 { 09913 struct sockaddr_in sin; 09914 int res; 09915 int updatehistory=1; 09916 int new = NEW_PREVENT; 09917 int dcallno = 0; 09918 char decrypted = 0; 09919 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 09920 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 09921 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 09922 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 09923 struct iax_frame *fr; 09924 struct iax_frame *cur; 09925 struct ast_frame f = { 0, }; 09926 struct ast_channel *c = NULL; 09927 struct iax2_dpcache *dp; 09928 struct iax2_peer *peer; 09929 struct iax_ies ies; 09930 struct iax_ie_data ied0, ied1; 09931 format_t format; 09932 int fd; 09933 int exists; 09934 int minivid = 0; 09935 char empty[32]=""; /* Safety measure */ 09936 struct iax_frame *duped_fr; 09937 char host_pref_buf[128]; 09938 char caller_pref_buf[128]; 09939 struct ast_codec_pref pref; 09940 char *using_prefs = "mine"; 09941 09942 /* allocate an iax_frame with 4096 bytes of data buffer */ 09943 fr = alloca(sizeof(*fr) + 4096); 09944 memset(fr, 0, sizeof(*fr)); 09945 fr->afdatalen = 4096; /* From alloca() above */ 09946 09947 /* Copy frequently used parameters to the stack */ 09948 res = thread->buf_len; 09949 fd = thread->iofd; 09950 memcpy(&sin, &thread->iosin, sizeof(sin)); 09951 09952 if (res < sizeof(*mh)) { 09953 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh)); 09954 return 1; 09955 } 09956 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 09957 if (res < sizeof(*vh)) { 09958 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a video frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 09959 return 1; 09960 } 09961 09962 /* This is a video frame, get call number */ 09963 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 09964 minivid = 1; 09965 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) 09966 return socket_process_meta(res, meta, &sin, fd, fr); 09967 09968 #ifdef DEBUG_SUPPORT 09969 if (res >= sizeof(*fh)) 09970 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 09971 #endif 09972 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 09973 if (res < sizeof(*fh)) { 09974 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a full frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 09975 return 1; 09976 } 09977 09978 /* Get the destination call number */ 09979 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 09980 09981 09982 /* check to make sure this full frame isn't encrypted before we attempt 09983 * to look inside of it. If it is encrypted, decrypt it first. Its ok if the 09984 * callno is not found here, that just means one hasn't been allocated for 09985 * this connection yet. */ 09986 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) { 09987 ast_mutex_lock(&iaxsl[fr->callno]); 09988 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) { 09989 if (decrypt_frame(fr->callno, fh, &f, &res)) { 09990 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 09991 ast_mutex_unlock(&iaxsl[fr->callno]); 09992 return 1; 09993 } 09994 decrypted = 1; 09995 } 09996 ast_mutex_unlock(&iaxsl[fr->callno]); 09997 } 09998 09999 /* Retrieve the type and subclass */ 10000 f.frametype = fh->type; 10001 if (f.frametype == AST_FRAME_VIDEO) { 10002 f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 10003 } else if (f.frametype == AST_FRAME_VOICE) { 10004 f.subclass.codec = uncompress_subclass(fh->csub); 10005 } else { 10006 f.subclass.integer = uncompress_subclass(fh->csub); 10007 } 10008 10009 /* Deal with POKE/PONG without allocating a callno */ 10010 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) { 10011 /* Reply back with a PONG, but don't care about the result. */ 10012 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10013 return 1; 10014 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) { 10015 /* Ignore */ 10016 return 1; 10017 } 10018 10019 f.datalen = res - sizeof(*fh); 10020 if (f.datalen) { 10021 if (f.frametype == AST_FRAME_IAX) { 10022 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) { 10023 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 10024 ast_variables_destroy(ies.vars); 10025 return 1; 10026 } 10027 f.data.ptr = NULL; 10028 f.datalen = 0; 10029 } else { 10030 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr); 10031 memset(&ies, 0, sizeof(ies)); 10032 } 10033 } else { 10034 if (f.frametype == AST_FRAME_IAX) 10035 f.data.ptr = NULL; 10036 else 10037 f.data.ptr = empty; 10038 memset(&ies, 0, sizeof(ies)); 10039 } 10040 10041 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) { 10042 /* only set NEW_ALLOW if calltoken checks out */ 10043 if (handle_call_token(fh, &ies, &sin, fd)) { 10044 ast_variables_destroy(ies.vars); 10045 return 1; 10046 } 10047 10048 if (ies.calltoken && ies.calltokendata) { 10049 /* if we've gotten this far, and the calltoken ie data exists, 10050 * then calltoken validation _MUST_ have taken place. If calltoken 10051 * data is provided, it is always validated reguardless of any 10052 * calltokenoptional or requirecalltoken options */ 10053 new = NEW_ALLOW_CALLTOKEN_VALIDATED; 10054 } else { 10055 new = NEW_ALLOW; 10056 } 10057 } 10058 } else { 10059 /* Don't know anything about it yet */ 10060 f.frametype = AST_FRAME_NULL; 10061 f.subclass.integer = 0; 10062 memset(&ies, 0, sizeof(ies)); 10063 } 10064 10065 if (!fr->callno) { 10066 int check_dcallno = 0; 10067 10068 /* 10069 * We enforce accurate destination call numbers for ACKs. This forces the other 10070 * end to know the destination call number before call setup can complete. 10071 * 10072 * Discussed in the following thread: 10073 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 10074 */ 10075 10076 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) { 10077 check_dcallno = 1; 10078 } 10079 10080 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) { 10081 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) { 10082 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10083 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) { 10084 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10085 } 10086 ast_variables_destroy(ies.vars); 10087 return 1; 10088 } 10089 } 10090 10091 if (fr->callno > 0) 10092 ast_mutex_lock(&iaxsl[fr->callno]); 10093 10094 if (!fr->callno || !iaxs[fr->callno]) { 10095 /* A call arrived for a nonexistent destination. Unless it's an "inval" 10096 frame, reply with an inval */ 10097 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10098 /* We can only raw hangup control frames */ 10099 if (((f.subclass.integer != IAX_COMMAND_INVAL) && 10100 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10101 (f.subclass.integer != IAX_COMMAND_TXACC) && 10102 (f.subclass.integer != IAX_COMMAND_FWDOWNL))|| 10103 (f.frametype != AST_FRAME_IAX)) 10104 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 10105 fd); 10106 } 10107 if (fr->callno > 0) 10108 ast_mutex_unlock(&iaxsl[fr->callno]); 10109 ast_variables_destroy(ies.vars); 10110 return 1; 10111 } 10112 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) { 10113 if (decrypt_frame(fr->callno, fh, &f, &res)) { 10114 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 10115 ast_variables_destroy(ies.vars); 10116 ast_mutex_unlock(&iaxsl[fr->callno]); 10117 return 1; 10118 } 10119 decrypted = 1; 10120 } 10121 10122 #ifdef DEBUG_SUPPORT 10123 if (decrypted) { 10124 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 10125 } 10126 #endif 10127 10128 10129 /* count this frame */ 10130 iaxs[fr->callno]->frames_received++; 10131 10132 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 10133 f.subclass.integer != IAX_COMMAND_TXCNT && /* for attended transfer */ 10134 f.subclass.integer != IAX_COMMAND_TXACC) { /* for attended transfer */ 10135 unsigned short new_peercallno; 10136 10137 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 10138 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 10139 if (iaxs[fr->callno]->peercallno) { 10140 remove_by_peercallno(iaxs[fr->callno]); 10141 } 10142 iaxs[fr->callno]->peercallno = new_peercallno; 10143 store_by_peercallno(iaxs[fr->callno]); 10144 } 10145 } 10146 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10147 if (iaxdebug) 10148 ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer); 10149 /* Check if it's out of order (and not an ACK or INVAL) */ 10150 fr->oseqno = fh->oseqno; 10151 fr->iseqno = fh->iseqno; 10152 fr->ts = ntohl(fh->ts); 10153 #ifdef IAXTESTS 10154 if (test_resync) { 10155 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 10156 fr->ts += test_resync; 10157 } 10158 #endif /* IAXTESTS */ 10159 #if 0 10160 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 10161 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 10162 (f.subclass == IAX_COMMAND_NEW || 10163 f.subclass == IAX_COMMAND_AUTHREQ || 10164 f.subclass == IAX_COMMAND_ACCEPT || 10165 f.subclass == IAX_COMMAND_REJECT)) ) ) 10166 #endif 10167 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 10168 updatehistory = 0; 10169 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 10170 (iaxs[fr->callno]->iseqno || 10171 ((f.subclass.integer != IAX_COMMAND_TXCNT) && 10172 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10173 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10174 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10175 (f.subclass.integer != IAX_COMMAND_TXACC)) || 10176 (f.frametype != AST_FRAME_IAX))) { 10177 if ( 10178 ((f.subclass.integer != IAX_COMMAND_ACK) && 10179 (f.subclass.integer != IAX_COMMAND_INVAL) && 10180 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10181 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10182 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10183 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10184 (f.subclass.integer != IAX_COMMAND_TXACC) && 10185 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10186 (f.frametype != AST_FRAME_IAX)) { 10187 /* If it's not an ACK packet, it's out of order. */ 10188 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 10189 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer); 10190 /* Check to see if we need to request retransmission, 10191 * and take sequence number wraparound into account */ 10192 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 10193 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 10194 if ((f.frametype != AST_FRAME_IAX) || 10195 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) { 10196 ast_debug(1, "Acking anyway\n"); 10197 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 10198 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 10199 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10200 } 10201 } else { 10202 /* Send a VNAK requesting retransmission */ 10203 iax2_vnak(fr->callno); 10204 } 10205 ast_variables_destroy(ies.vars); 10206 ast_mutex_unlock(&iaxsl[fr->callno]); 10207 return 1; 10208 } 10209 } else { 10210 /* Increment unless it's an ACK or VNAK */ 10211 if (((f.subclass.integer != IAX_COMMAND_ACK) && 10212 (f.subclass.integer != IAX_COMMAND_INVAL) && 10213 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10214 (f.subclass.integer != IAX_COMMAND_TXACC) && 10215 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10216 (f.frametype != AST_FRAME_IAX)) 10217 iaxs[fr->callno]->iseqno++; 10218 } 10219 /* Ensure text frames are NULL-terminated */ 10220 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 10221 if (res < thread->buf_size) 10222 thread->buf[res++] = '\0'; 10223 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 10224 thread->buf[res - 1] = '\0'; 10225 } 10226 10227 /* Handle implicit ACKing unless this is an INVAL, and only if this is 10228 from the real peer, not the transfer peer */ 10229 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10230 ((f.subclass.integer != IAX_COMMAND_INVAL) || 10231 (f.frametype != AST_FRAME_IAX))) { 10232 unsigned char x; 10233 int call_to_destroy; 10234 /* First we have to qualify that the ACKed value is within our window */ 10235 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno)) 10236 x = fr->iseqno; 10237 else 10238 x = iaxs[fr->callno]->oseqno; 10239 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 10240 /* The acknowledgement is within our window. Time to acknowledge everything 10241 that it says to */ 10242 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 10243 /* Ack the packet with the given timestamp */ 10244 if (iaxdebug) 10245 ast_debug(1, "Cancelling transmission of packet %d\n", x); 10246 call_to_destroy = 0; 10247 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10248 /* If it's our call, and our timestamp, mark -1 retries */ 10249 if (x == cur->oseqno) { 10250 cur->retries = -1; 10251 /* Destroy call if this is the end */ 10252 if (cur->final) 10253 call_to_destroy = fr->callno; 10254 } 10255 } 10256 if (call_to_destroy) { 10257 if (iaxdebug) 10258 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy); 10259 ast_mutex_lock(&iaxsl[call_to_destroy]); 10260 iax2_destroy(call_to_destroy); 10261 ast_mutex_unlock(&iaxsl[call_to_destroy]); 10262 } 10263 } 10264 /* Note how much we've received acknowledgement for */ 10265 if (iaxs[fr->callno]) 10266 iaxs[fr->callno]->rseqno = fr->iseqno; 10267 else { 10268 /* Stop processing now */ 10269 ast_variables_destroy(ies.vars); 10270 ast_mutex_unlock(&iaxsl[fr->callno]); 10271 return 1; 10272 } 10273 } else { 10274 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 10275 } 10276 } 10277 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10278 ((f.frametype != AST_FRAME_IAX) || 10279 ((f.subclass.integer != IAX_COMMAND_TXACC) && 10280 (f.subclass.integer != IAX_COMMAND_TXCNT)))) { 10281 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 10282 ast_variables_destroy(ies.vars); 10283 ast_mutex_unlock(&iaxsl[fr->callno]); 10284 return 1; 10285 } 10286 10287 /* when we receive the first full frame for a new incoming channel, 10288 it is safe to start the PBX on the channel because we have now 10289 completed a 3-way handshake with the peer */ 10290 if ((f.frametype == AST_FRAME_VOICE) || 10291 (f.frametype == AST_FRAME_VIDEO) || 10292 (f.frametype == AST_FRAME_IAX)) { 10293 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 10294 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10295 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) { 10296 ast_variables_destroy(ies.vars); 10297 ast_mutex_unlock(&iaxsl[fr->callno]); 10298 return 1; 10299 } 10300 } 10301 10302 if (ies.vars) { 10303 struct ast_datastore *variablestore = NULL; 10304 struct ast_variable *var, *prev = NULL; 10305 AST_LIST_HEAD(, ast_var_t) *varlist; 10306 10307 iax2_lock_owner(fr->callno); 10308 if (!iaxs[fr->callno]) { 10309 ast_variables_destroy(ies.vars); 10310 ast_mutex_unlock(&iaxsl[fr->callno]); 10311 return 1; 10312 } 10313 if ((c = iaxs[fr->callno]->owner)) { 10314 varlist = ast_calloc(1, sizeof(*varlist)); 10315 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 10316 10317 if (variablestore && varlist) { 10318 variablestore->data = varlist; 10319 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 10320 AST_LIST_HEAD_INIT(varlist); 10321 ast_debug(1, "I can haz IAX vars?\n"); 10322 for (var = ies.vars; var; var = var->next) { 10323 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 10324 if (prev) { 10325 ast_free(prev); 10326 } 10327 prev = var; 10328 if (!newvar) { 10329 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 10330 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10331 } else { 10332 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 10333 } 10334 } 10335 if (prev) { 10336 ast_free(prev); 10337 } 10338 ies.vars = NULL; 10339 ast_channel_datastore_add(c, variablestore); 10340 } else { 10341 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10342 if (variablestore) { 10343 ast_datastore_free(variablestore); 10344 } 10345 if (varlist) { 10346 ast_free(varlist); 10347 } 10348 } 10349 ast_channel_unlock(c); 10350 } else { 10351 /* No channel yet, so transfer the variables directly over to the pvt, 10352 * for later inheritance. */ 10353 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n"); 10354 for (var = ies.vars; var && var->next; var = var->next); 10355 if (var) { 10356 var->next = iaxs[fr->callno]->iaxvars; 10357 iaxs[fr->callno]->iaxvars = ies.vars; 10358 ies.vars = NULL; 10359 } 10360 } 10361 } 10362 10363 if (ies.vars) { 10364 ast_debug(1, "I have IAX variables, but they were not processed\n"); 10365 } 10366 } 10367 10368 /* once we receive our first IAX Full Frame that is not CallToken related, send all 10369 * queued signaling frames that were being held. */ 10370 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) { 10371 send_signaling(iaxs[fr->callno]); 10372 } 10373 10374 if (f.frametype == AST_FRAME_VOICE) { 10375 if (f.subclass.codec != iaxs[fr->callno]->voiceformat) { 10376 iaxs[fr->callno]->voiceformat = f.subclass.codec; 10377 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec)); 10378 if (iaxs[fr->callno]->owner) { 10379 iax2_lock_owner(fr->callno); 10380 if (iaxs[fr->callno]) { 10381 if (iaxs[fr->callno]->owner) { 10382 format_t orignative; 10383 10384 orignative = iaxs[fr->callno]->owner->nativeformats; 10385 iaxs[fr->callno]->owner->nativeformats = f.subclass.codec; 10386 if (iaxs[fr->callno]->owner->readformat) 10387 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 10388 iaxs[fr->callno]->owner->nativeformats = orignative; 10389 ast_channel_unlock(iaxs[fr->callno]->owner); 10390 } 10391 } else { 10392 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n"); 10393 /* Free remote variables (if any) */ 10394 if (ies.vars) { 10395 ast_variables_destroy(ies.vars); 10396 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n"); 10397 ies.vars = NULL; 10398 } 10399 ast_mutex_unlock(&iaxsl[fr->callno]); 10400 return 1; 10401 } 10402 } 10403 } 10404 } 10405 if (f.frametype == AST_FRAME_VIDEO) { 10406 if (f.subclass.codec != iaxs[fr->callno]->videoformat) { 10407 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL)); 10408 iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL; 10409 } 10410 } 10411 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) { 10412 if (f.subclass.integer == AST_CONTROL_BUSY) { 10413 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 10414 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) { 10415 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 10416 } 10417 } 10418 if (f.frametype == AST_FRAME_IAX) { 10419 ast_sched_thread_del(sched, iaxs[fr->callno]->initid); 10420 /* Handle the IAX pseudo frame itself */ 10421 if (iaxdebug) 10422 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer); 10423 10424 /* Update last ts unless the frame's timestamp originated with us. */ 10425 if (iaxs[fr->callno]->last < fr->ts && 10426 f.subclass.integer != IAX_COMMAND_ACK && 10427 f.subclass.integer != IAX_COMMAND_PONG && 10428 f.subclass.integer != IAX_COMMAND_LAGRP) { 10429 iaxs[fr->callno]->last = fr->ts; 10430 if (iaxdebug) 10431 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 10432 } 10433 iaxs[fr->callno]->last_iax_message = f.subclass.integer; 10434 if (!iaxs[fr->callno]->first_iax_message) { 10435 iaxs[fr->callno]->first_iax_message = f.subclass.integer; 10436 } 10437 switch(f.subclass.integer) { 10438 case IAX_COMMAND_ACK: 10439 /* Do nothing */ 10440 break; 10441 case IAX_COMMAND_QUELCH: 10442 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10443 /* Generate Manager Hold event, if necessary*/ 10444 if (iaxs[fr->callno]->owner) { 10445 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10446 "Status: On\r\n" 10447 "Channel: %s\r\n" 10448 "Uniqueid: %s\r\n", 10449 iaxs[fr->callno]->owner->name, 10450 iaxs[fr->callno]->owner->uniqueid); 10451 } 10452 10453 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH); 10454 if (ies.musiconhold) { 10455 iax2_lock_owner(fr->callno); 10456 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) { 10457 break; 10458 } 10459 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10460 const char *moh_suggest = iaxs[fr->callno]->mohsuggest; 10461 10462 /* 10463 * We already hold the owner lock so we do not 10464 * need to check iaxs[fr->callno] after it returns. 10465 */ 10466 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 10467 S_OR(moh_suggest, NULL), 10468 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0); 10469 } 10470 ast_channel_unlock(iaxs[fr->callno]->owner); 10471 } 10472 } 10473 break; 10474 case IAX_COMMAND_UNQUELCH: 10475 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10476 iax2_lock_owner(fr->callno); 10477 if (!iaxs[fr->callno]) { 10478 break; 10479 } 10480 /* Generate Manager Unhold event, if necessary */ 10481 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) { 10482 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10483 "Status: Off\r\n" 10484 "Channel: %s\r\n" 10485 "Uniqueid: %s\r\n", 10486 iaxs[fr->callno]->owner->name, 10487 iaxs[fr->callno]->owner->uniqueid); 10488 } 10489 10490 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH); 10491 if (!iaxs[fr->callno]->owner) { 10492 break; 10493 } 10494 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10495 /* 10496 * We already hold the owner lock so we do not 10497 * need to check iaxs[fr->callno] after it returns. 10498 */ 10499 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 10500 } 10501 ast_channel_unlock(iaxs[fr->callno]->owner); 10502 } 10503 break; 10504 case IAX_COMMAND_TXACC: 10505 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 10506 /* Ack the packet with the given timestamp */ 10507 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10508 /* Cancel any outstanding txcnt's */ 10509 if (cur->transfer) { 10510 cur->retries = -1; 10511 } 10512 } 10513 memset(&ied1, 0, sizeof(ied1)); 10514 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 10515 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 10516 iaxs[fr->callno]->transferring = TRANSFER_READY; 10517 } 10518 break; 10519 case IAX_COMMAND_NEW: 10520 /* Ignore if it's already up */ 10521 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 10522 break; 10523 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 10524 ast_mutex_unlock(&iaxsl[fr->callno]); 10525 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 10526 ast_mutex_lock(&iaxsl[fr->callno]); 10527 if (!iaxs[fr->callno]) { 10528 break; 10529 } 10530 } 10531 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 10532 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) { 10533 int new_callno; 10534 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 10535 fr->callno = new_callno; 10536 } 10537 /* For security, always ack immediately */ 10538 if (delayreject) 10539 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10540 if (check_access(fr->callno, &sin, &ies)) { 10541 /* They're not allowed on */ 10542 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10543 if (authdebug) 10544 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 10545 break; 10546 } 10547 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) { 10548 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10549 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n"); 10550 break; 10551 } 10552 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 10553 const char *context, *exten, *cid_num; 10554 10555 context = ast_strdupa(iaxs[fr->callno]->context); 10556 exten = ast_strdupa(iaxs[fr->callno]->exten); 10557 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 10558 10559 /* This might re-enter the IAX code and need the lock */ 10560 ast_mutex_unlock(&iaxsl[fr->callno]); 10561 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 10562 ast_mutex_lock(&iaxsl[fr->callno]); 10563 10564 if (!iaxs[fr->callno]) { 10565 break; 10566 } 10567 } else 10568 exists = 0; 10569 /* Get OSP token if it does exist */ 10570 save_osptoken(fr, &ies); 10571 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 10572 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 10573 memset(&ied0, 0, sizeof(ied0)); 10574 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10575 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10576 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10577 if (!iaxs[fr->callno]) { 10578 break; 10579 } 10580 if (authdebug) 10581 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 10582 } else { 10583 /* Select an appropriate format */ 10584 10585 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10586 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10587 using_prefs = "reqonly"; 10588 } else { 10589 using_prefs = "disabled"; 10590 } 10591 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 10592 memset(&pref, 0, sizeof(pref)); 10593 strcpy(caller_pref_buf, "disabled"); 10594 strcpy(host_pref_buf, "disabled"); 10595 } else { 10596 using_prefs = "mine"; 10597 /* If the information elements are in here... use them */ 10598 if (ies.codec_prefs) 10599 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 10600 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10601 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 10602 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10603 pref = iaxs[fr->callno]->rprefs; 10604 using_prefs = "caller"; 10605 } else { 10606 pref = iaxs[fr->callno]->prefs; 10607 } 10608 } else 10609 pref = iaxs[fr->callno]->prefs; 10610 10611 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 10612 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 10613 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 10614 } 10615 if (!format) { 10616 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) 10617 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 10618 if (!format) { 10619 memset(&ied0, 0, sizeof(ied0)); 10620 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10621 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10622 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10623 if (!iaxs[fr->callno]) { 10624 break; 10625 } 10626 if (authdebug) { 10627 char tmp[256], tmp2[256], tmp3[256]; 10628 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10629 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", 10630 ast_inet_ntoa(sin.sin_addr), 10631 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10632 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10633 } else { 10634 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10635 ast_inet_ntoa(sin.sin_addr), 10636 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10637 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10638 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10639 } 10640 } 10641 } else { 10642 /* Pick one... */ 10643 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10644 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 10645 format = 0; 10646 } else { 10647 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10648 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 10649 memset(&pref, 0, sizeof(pref)); 10650 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10651 strcpy(caller_pref_buf,"disabled"); 10652 strcpy(host_pref_buf,"disabled"); 10653 } else { 10654 using_prefs = "mine"; 10655 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10656 /* Do the opposite of what we tried above. */ 10657 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10658 pref = iaxs[fr->callno]->prefs; 10659 } else { 10660 pref = iaxs[fr->callno]->rprefs; 10661 using_prefs = "caller"; 10662 } 10663 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 10664 } else /* if no codec_prefs IE do it the old way */ 10665 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10666 } 10667 } 10668 10669 if (!format) { 10670 char tmp[256], tmp2[256], tmp3[256]; 10671 memset(&ied0, 0, sizeof(ied0)); 10672 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10673 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10674 ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 10675 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10676 if (!iaxs[fr->callno]) { 10677 break; 10678 } 10679 if (authdebug) { 10680 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10681 ast_inet_ntoa(sin.sin_addr), 10682 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10683 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10684 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10685 } 10686 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10687 break; 10688 } 10689 } 10690 } 10691 if (format) { 10692 /* No authentication required, let them in */ 10693 memset(&ied1, 0, sizeof(ied1)); 10694 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 10695 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 10696 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 10697 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 10698 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10699 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n" 10700 "%srequested format = %s,\n" 10701 "%srequested prefs = %s,\n" 10702 "%sactual format = %s,\n" 10703 "%shost prefs = %s,\n" 10704 "%spriority = %s\n", 10705 ast_inet_ntoa(sin.sin_addr), 10706 VERBOSE_PREFIX_4, 10707 ast_getformatname(iaxs[fr->callno]->peerformat), 10708 VERBOSE_PREFIX_4, 10709 caller_pref_buf, 10710 VERBOSE_PREFIX_4, 10711 ast_getformatname(format), 10712 VERBOSE_PREFIX_4, 10713 host_pref_buf, 10714 VERBOSE_PREFIX_4, 10715 using_prefs); 10716 10717 iaxs[fr->callno]->chosenformat = format; 10718 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10719 } else { 10720 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10721 /* If this is a TBD call, we're ready but now what... */ 10722 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 10723 } 10724 } 10725 } 10726 break; 10727 } 10728 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 10729 merge_encryption(iaxs[fr->callno],ies.encmethods); 10730 else 10731 iaxs[fr->callno]->encmethods = 0; 10732 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 10733 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 10734 break; 10735 case IAX_COMMAND_DPREQ: 10736 /* Request status in the dialplan */ 10737 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 10738 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 10739 if (iaxcompat) { 10740 /* Spawn a thread for the lookup */ 10741 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 10742 } else { 10743 /* Just look it up */ 10744 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 10745 } 10746 } 10747 break; 10748 case IAX_COMMAND_HANGUP: 10749 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10750 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno); 10751 /* Set hangup cause according to remote and hangupsource */ 10752 if (iaxs[fr->callno]->owner) { 10753 set_hangup_source_and_cause(fr->callno, ies.causecode); 10754 if (!iaxs[fr->callno]) { 10755 break; 10756 } 10757 } 10758 10759 /* Send ack immediately, before we destroy */ 10760 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10761 iax2_destroy(fr->callno); 10762 break; 10763 case IAX_COMMAND_REJECT: 10764 /* Set hangup cause according to remote and hangup source */ 10765 if (iaxs[fr->callno]->owner) { 10766 set_hangup_source_and_cause(fr->callno, ies.causecode); 10767 if (!iaxs[fr->callno]) { 10768 break; 10769 } 10770 } 10771 10772 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10773 if (iaxs[fr->callno]->owner && authdebug) 10774 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 10775 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 10776 ies.cause ? ies.cause : "<Unknown>"); 10777 ast_debug(1, "Immediately destroying %d, having received reject\n", 10778 fr->callno); 10779 } 10780 /* Send ack immediately, before we destroy */ 10781 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 10782 fr->ts, NULL, 0, fr->iseqno); 10783 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) 10784 iaxs[fr->callno]->error = EPERM; 10785 iax2_destroy(fr->callno); 10786 break; 10787 case IAX_COMMAND_TRANSFER: 10788 { 10789 struct ast_channel *bridged_chan; 10790 struct ast_channel *owner; 10791 10792 iax2_lock_owner(fr->callno); 10793 if (!iaxs[fr->callno]) { 10794 /* Initiating call went away before we could transfer. */ 10795 break; 10796 } 10797 owner = iaxs[fr->callno]->owner; 10798 bridged_chan = owner ? ast_bridged_channel(owner) : NULL; 10799 if (bridged_chan && ies.called_number) { 10800 const char *context; 10801 10802 context = ast_strdupa(iaxs[fr->callno]->context); 10803 10804 ast_channel_ref(owner); 10805 ast_channel_ref(bridged_chan); 10806 ast_channel_unlock(owner); 10807 ast_mutex_unlock(&iaxsl[fr->callno]); 10808 10809 /* Set BLINDTRANSFER channel variables */ 10810 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name); 10811 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name); 10812 10813 /* DO NOT hold any locks while calling ast_parking_ext_valid() */ 10814 if (ast_parking_ext_valid(ies.called_number, owner, context)) { 10815 ast_debug(1, "Parking call '%s'\n", bridged_chan->name); 10816 if (iax_park(bridged_chan, owner, ies.called_number, context)) { 10817 ast_log(LOG_WARNING, "Failed to park call '%s'\n", 10818 bridged_chan->name); 10819 } 10820 } else { 10821 if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) { 10822 ast_log(LOG_WARNING, 10823 "Async goto of '%s' to '%s@%s' failed\n", 10824 bridged_chan->name, ies.called_number, context); 10825 } else { 10826 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", 10827 bridged_chan->name, ies.called_number, context); 10828 } 10829 } 10830 ast_channel_unref(owner); 10831 ast_channel_unref(bridged_chan); 10832 10833 ast_mutex_lock(&iaxsl[fr->callno]); 10834 } else { 10835 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno); 10836 if (owner) { 10837 ast_channel_unlock(owner); 10838 } 10839 } 10840 10841 break; 10842 } 10843 case IAX_COMMAND_ACCEPT: 10844 /* Ignore if call is already up or needs authentication or is a TBD */ 10845 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 10846 break; 10847 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10848 /* Send ack immediately, before we destroy */ 10849 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10850 iax2_destroy(fr->callno); 10851 break; 10852 } 10853 if (ies.format) { 10854 iaxs[fr->callno]->peerformat = ies.format; 10855 } else { 10856 if (iaxs[fr->callno]->owner) 10857 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 10858 else 10859 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 10860 } 10861 ast_verb(3, "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat)); 10862 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 10863 memset(&ied0, 0, sizeof(ied0)); 10864 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10865 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10866 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10867 if (!iaxs[fr->callno]) { 10868 break; 10869 } 10870 if (authdebug) { 10871 char tmp1[256], tmp2[256]; 10872 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n", 10873 ast_inet_ntoa(sin.sin_addr), 10874 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 10875 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10876 } 10877 } else { 10878 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10879 iax2_lock_owner(fr->callno); 10880 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 10881 /* Switch us to use a compatible format */ 10882 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 10883 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 10884 10885 /* Setup read/write formats properly. */ 10886 if (iaxs[fr->callno]->owner->writeformat) 10887 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 10888 if (iaxs[fr->callno]->owner->readformat) 10889 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 10890 ast_channel_unlock(iaxs[fr->callno]->owner); 10891 } 10892 } 10893 if (iaxs[fr->callno]) { 10894 AST_LIST_LOCK(&dpcache); 10895 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list) 10896 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) 10897 iax2_dprequest(dp, fr->callno); 10898 AST_LIST_UNLOCK(&dpcache); 10899 } 10900 break; 10901 case IAX_COMMAND_POKE: 10902 /* Send back a pong packet with the original timestamp */ 10903 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 10904 break; 10905 case IAX_COMMAND_PING: 10906 { 10907 struct iax_ie_data pingied; 10908 construct_rr(iaxs[fr->callno], &pingied); 10909 /* Send back a pong packet with the original timestamp */ 10910 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 10911 } 10912 break; 10913 case IAX_COMMAND_PONG: 10914 /* Calculate ping time */ 10915 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 10916 /* save RR info */ 10917 save_rr(fr, &ies); 10918 10919 /* Good time to write jb stats for this call */ 10920 log_jitterstats(fr->callno); 10921 10922 if (iaxs[fr->callno]->peerpoke) { 10923 peer = iaxs[fr->callno]->peerpoke; 10924 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 10925 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 10926 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 10927 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 10928 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name); /* Activate notification */ 10929 } 10930 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 10931 if (iaxs[fr->callno]->pingtime > peer->maxms) { 10932 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 10933 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 10934 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 10935 } 10936 } 10937 peer->lastms = iaxs[fr->callno]->pingtime; 10938 if (peer->smoothing && (peer->lastms > -1)) 10939 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 10940 else if (peer->smoothing && peer->lastms < 0) 10941 peer->historicms = (0 + peer->historicms) / 2; 10942 else 10943 peer->historicms = iaxs[fr->callno]->pingtime; 10944 10945 /* Remove scheduled iax2_poke_noanswer */ 10946 if (peer->pokeexpire > -1) { 10947 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 10948 peer_unref(peer); 10949 peer->pokeexpire = -1; 10950 } 10951 } 10952 /* Schedule the next cycle */ 10953 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 10954 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 10955 else 10956 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 10957 if (peer->pokeexpire == -1) 10958 peer_unref(peer); 10959 /* and finally send the ack */ 10960 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10961 /* And wrap up the qualify call */ 10962 iax2_destroy(fr->callno); 10963 peer->callno = 0; 10964 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 10965 } 10966 break; 10967 case IAX_COMMAND_LAGRQ: 10968 case IAX_COMMAND_LAGRP: 10969 f.src = "LAGRQ"; 10970 f.mallocd = 0; 10971 f.offset = 0; 10972 f.samples = 0; 10973 iax_frame_wrap(fr, &f); 10974 if (f.subclass.integer == IAX_COMMAND_LAGRQ) { 10975 /* Received a LAGRQ - echo back a LAGRP */ 10976 fr->af.subclass.integer = IAX_COMMAND_LAGRP; 10977 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 10978 } else { 10979 /* Received LAGRP in response to our LAGRQ */ 10980 unsigned int ts; 10981 /* This is a reply we've been given, actually measure the difference */ 10982 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 10983 iaxs[fr->callno]->lag = ts - fr->ts; 10984 if (iaxdebug) 10985 ast_debug(1, "Peer %s lag measured as %dms\n", 10986 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 10987 } 10988 break; 10989 case IAX_COMMAND_AUTHREQ: 10990 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 10991 ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 10992 break; 10993 } 10994 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 10995 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 10996 .subclass.integer = AST_CONTROL_HANGUP, 10997 }; 10998 ast_log(LOG_WARNING, 10999 "I don't know how to authenticate %s to %s\n", 11000 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 11001 iax2_queue_frame(fr->callno, &hangup_fr); 11002 } 11003 break; 11004 case IAX_COMMAND_AUTHREP: 11005 /* For security, always ack immediately */ 11006 if (delayreject) 11007 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11008 /* Ignore once we've started */ 11009 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 11010 ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 11011 break; 11012 } 11013 if (authenticate_verify(iaxs[fr->callno], &ies)) { 11014 if (authdebug) 11015 ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->username); 11016 memset(&ied0, 0, sizeof(ied0)); 11017 auth_fail(fr->callno, IAX_COMMAND_REJECT); 11018 break; 11019 } 11020 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 11021 /* This might re-enter the IAX code and need the lock */ 11022 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 11023 } else 11024 exists = 0; 11025 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 11026 if (authdebug) 11027 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 11028 memset(&ied0, 0, sizeof(ied0)); 11029 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 11030 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 11031 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11032 if (!iaxs[fr->callno]) { 11033 break; 11034 } 11035 } else { 11036 /* Select an appropriate format */ 11037 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 11038 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11039 using_prefs = "reqonly"; 11040 } else { 11041 using_prefs = "disabled"; 11042 } 11043 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 11044 memset(&pref, 0, sizeof(pref)); 11045 strcpy(caller_pref_buf, "disabled"); 11046 strcpy(host_pref_buf, "disabled"); 11047 } else { 11048 using_prefs = "mine"; 11049 if (ies.codec_prefs) 11050 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 11051 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 11052 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 11053 pref = iaxs[fr->callno]->rprefs; 11054 using_prefs = "caller"; 11055 } else { 11056 pref = iaxs[fr->callno]->prefs; 11057 } 11058 } else /* if no codec_prefs IE do it the old way */ 11059 pref = iaxs[fr->callno]->prefs; 11060 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 11061 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 11062 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 11063 } 11064 if (!format) { 11065 char tmp1[256], tmp2[256], tmp3[256]; 11066 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11067 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n", 11068 ast_getformatname(iaxs[fr->callno]->peerformat), 11069 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability)); 11070 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 11071 } 11072 if (!format) { 11073 if (authdebug) { 11074 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11075 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr), 11076 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11077 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 11078 } else { 11079 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 11080 ast_inet_ntoa(sin.sin_addr), 11081 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11082 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 11083 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 11084 } 11085 } 11086 memset(&ied0, 0, sizeof(ied0)); 11087 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 11088 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 11089 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11090 if (!iaxs[fr->callno]) { 11091 break; 11092 } 11093 } else { 11094 /* Pick one... */ 11095 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11096 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 11097 format = 0; 11098 } else { 11099 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 11100 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 11101 memset(&pref, 0, sizeof(pref)); 11102 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 11103 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 11104 strcpy(caller_pref_buf,"disabled"); 11105 strcpy(host_pref_buf,"disabled"); 11106 } else { 11107 using_prefs = "mine"; 11108 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 11109 /* Do the opposite of what we tried above. */ 11110 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 11111 pref = iaxs[fr->callno]->prefs; 11112 } else { 11113 pref = iaxs[fr->callno]->rprefs; 11114 using_prefs = "caller"; 11115 } 11116 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 11117 } else /* if no codec_prefs IE do it the old way */ 11118 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 11119 } 11120 } 11121 if (!format) { 11122 char tmp1[256], tmp2[256], tmp3[256]; 11123 ast_log(LOG_ERROR, "No best format in %s???\n", 11124 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 11125 if (authdebug) { 11126 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11127 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", 11128 ast_inet_ntoa(sin.sin_addr), 11129 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11130 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 11131 } else { 11132 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 11133 ast_inet_ntoa(sin.sin_addr), 11134 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11135 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 11136 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 11137 } 11138 } 11139 memset(&ied0, 0, sizeof(ied0)); 11140 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 11141 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 11142 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11143 if (!iaxs[fr->callno]) { 11144 break; 11145 } 11146 } 11147 } 11148 } 11149 if (format) { 11150 /* Authentication received */ 11151 memset(&ied1, 0, sizeof(ied1)); 11152 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 11153 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 11154 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 11155 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 11156 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11157 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n" 11158 "%srequested format = %s,\n" 11159 "%srequested prefs = %s,\n" 11160 "%sactual format = %s,\n" 11161 "%shost prefs = %s,\n" 11162 "%spriority = %s\n", 11163 ast_inet_ntoa(sin.sin_addr), 11164 VERBOSE_PREFIX_4, 11165 ast_getformatname(iaxs[fr->callno]->peerformat), 11166 VERBOSE_PREFIX_4, 11167 caller_pref_buf, 11168 VERBOSE_PREFIX_4, 11169 ast_getformatname(format), 11170 VERBOSE_PREFIX_4, 11171 host_pref_buf, 11172 VERBOSE_PREFIX_4, 11173 using_prefs); 11174 11175 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11176 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL))) 11177 iax2_destroy(fr->callno); 11178 else if (ies.vars) { 11179 struct ast_datastore *variablestore; 11180 struct ast_variable *var, *prev = NULL; 11181 AST_LIST_HEAD(, ast_var_t) *varlist; 11182 varlist = ast_calloc(1, sizeof(*varlist)); 11183 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 11184 if (variablestore && varlist) { 11185 variablestore->data = varlist; 11186 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11187 AST_LIST_HEAD_INIT(varlist); 11188 ast_debug(1, "I can haz IAX vars? w00t\n"); 11189 for (var = ies.vars; var; var = var->next) { 11190 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 11191 if (prev) 11192 ast_free(prev); 11193 prev = var; 11194 if (!newvar) { 11195 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 11196 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11197 } else { 11198 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 11199 } 11200 } 11201 if (prev) 11202 ast_free(prev); 11203 ies.vars = NULL; 11204 ast_channel_datastore_add(c, variablestore); 11205 } else { 11206 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11207 if (variablestore) 11208 ast_datastore_free(variablestore); 11209 if (varlist) 11210 ast_free(varlist); 11211 } 11212 } 11213 } else { 11214 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11215 /* If this is a TBD call, we're ready but now what... */ 11216 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 11217 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) { 11218 goto immediatedial; 11219 } 11220 } 11221 } 11222 } 11223 break; 11224 case IAX_COMMAND_DIAL: 11225 immediatedial: 11226 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 11227 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11228 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 11229 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 11230 if (authdebug) 11231 ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 11232 memset(&ied0, 0, sizeof(ied0)); 11233 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 11234 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 11235 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11236 if (!iaxs[fr->callno]) { 11237 break; 11238 } 11239 } else { 11240 char tmp[256]; 11241 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11242 ast_verb(3, "Accepting DIAL from %s, formats = %s\n", 11243 ast_inet_ntoa(sin.sin_addr), 11244 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat)); 11245 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11246 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 11247 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL))) 11248 iax2_destroy(fr->callno); 11249 else if (ies.vars) { 11250 struct ast_datastore *variablestore; 11251 struct ast_variable *var, *prev = NULL; 11252 AST_LIST_HEAD(, ast_var_t) *varlist; 11253 varlist = ast_calloc(1, sizeof(*varlist)); 11254 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 11255 ast_debug(1, "I can haz IAX vars? w00t\n"); 11256 if (variablestore && varlist) { 11257 variablestore->data = varlist; 11258 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11259 AST_LIST_HEAD_INIT(varlist); 11260 for (var = ies.vars; var; var = var->next) { 11261 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 11262 if (prev) 11263 ast_free(prev); 11264 prev = var; 11265 if (!newvar) { 11266 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 11267 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11268 } else { 11269 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 11270 } 11271 } 11272 if (prev) 11273 ast_free(prev); 11274 ies.vars = NULL; 11275 ast_channel_datastore_add(c, variablestore); 11276 } else { 11277 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11278 if (variablestore) 11279 ast_datastore_free(variablestore); 11280 if (varlist) 11281 ast_free(varlist); 11282 } 11283 } 11284 } 11285 } 11286 break; 11287 case IAX_COMMAND_INVAL: 11288 iaxs[fr->callno]->error = ENOTCONN; 11289 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno); 11290 iax2_destroy(fr->callno); 11291 ast_debug(1, "Destroying call %d\n", fr->callno); 11292 break; 11293 case IAX_COMMAND_VNAK: 11294 ast_debug(1, "Received VNAK: resending outstanding frames\n"); 11295 /* Force retransmission */ 11296 vnak_retransmit(fr->callno, fr->iseqno); 11297 break; 11298 case IAX_COMMAND_REGREQ: 11299 case IAX_COMMAND_REGREL: 11300 /* For security, always ack immediately */ 11301 if (delayreject) 11302 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11303 if (register_verify(fr->callno, &sin, &ies)) { 11304 if (!iaxs[fr->callno]) { 11305 break; 11306 } 11307 /* Send delayed failure */ 11308 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 11309 break; 11310 } 11311 if (!iaxs[fr->callno]) { 11312 break; 11313 } 11314 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 11315 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 11316 11317 if (f.subclass.integer == IAX_COMMAND_REGREL) { 11318 memset(&sin, 0, sizeof(sin)); 11319 sin.sin_family = AF_INET; 11320 } 11321 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) { 11322 ast_log(LOG_WARNING, "Registry error\n"); 11323 } 11324 if (!iaxs[fr->callno]) { 11325 break; 11326 } 11327 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 11328 ast_mutex_unlock(&iaxsl[fr->callno]); 11329 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 11330 ast_mutex_lock(&iaxsl[fr->callno]); 11331 } 11332 break; 11333 } 11334 registry_authrequest(fr->callno); 11335 break; 11336 case IAX_COMMAND_REGACK: 11337 if (iax2_ack_registry(&ies, &sin, fr->callno)) 11338 ast_log(LOG_WARNING, "Registration failure\n"); 11339 /* Send ack immediately, before we destroy */ 11340 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11341 iax2_destroy(fr->callno); 11342 break; 11343 case IAX_COMMAND_REGREJ: 11344 if (iaxs[fr->callno]->reg) { 11345 if (authdebug) { 11346 ast_log(LOG_NOTICE, "Registration of '%s' rejected: '%s' from: '%s'\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>", ast_inet_ntoa(sin.sin_addr)); 11347 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>"); 11348 } 11349 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 11350 } 11351 /* Send ack immediately, before we destroy */ 11352 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11353 iax2_destroy(fr->callno); 11354 break; 11355 case IAX_COMMAND_REGAUTH: 11356 /* Authentication request */ 11357 if (registry_rerequest(&ies, fr->callno, &sin)) { 11358 memset(&ied0, 0, sizeof(ied0)); 11359 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 11360 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 11361 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11362 } 11363 break; 11364 case IAX_COMMAND_TXREJ: 11365 iaxs[fr->callno]->transferring = 0; 11366 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 11367 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 11368 if (iaxs[fr->callno]->bridgecallno) { 11369 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 11370 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 11371 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 11372 } 11373 } 11374 break; 11375 case IAX_COMMAND_TXREADY: 11376 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 11377 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 11378 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 11379 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 11380 else 11381 iaxs[fr->callno]->transferring = TRANSFER_READY; 11382 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 11383 if (iaxs[fr->callno]->bridgecallno) { 11384 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 11385 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 11386 /* They're both ready, now release them. */ 11387 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 11388 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 11389 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 11390 11391 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 11392 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 11393 11394 memset(&ied0, 0, sizeof(ied0)); 11395 memset(&ied1, 0, sizeof(ied1)); 11396 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11397 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11398 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 11399 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 11400 } else { 11401 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 11402 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 11403 11404 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 11405 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 11406 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 11407 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 11408 11409 /* Stop doing lag & ping requests */ 11410 stop_stuff(fr->callno); 11411 stop_stuff(iaxs[fr->callno]->bridgecallno); 11412 11413 memset(&ied0, 0, sizeof(ied0)); 11414 memset(&ied1, 0, sizeof(ied1)); 11415 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11416 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11417 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 11418 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 11419 } 11420 11421 } 11422 } 11423 } 11424 break; 11425 case IAX_COMMAND_TXREQ: 11426 try_transfer(iaxs[fr->callno], &ies); 11427 break; 11428 case IAX_COMMAND_TXCNT: 11429 if (iaxs[fr->callno]->transferring) 11430 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 11431 break; 11432 case IAX_COMMAND_TXREL: 11433 /* Send ack immediately, rather than waiting until we've changed addresses */ 11434 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11435 complete_transfer(fr->callno, &ies); 11436 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 11437 break; 11438 case IAX_COMMAND_TXMEDIA: 11439 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 11440 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 11441 /* Cancel any outstanding frames and start anew */ 11442 if (cur->transfer) { 11443 cur->retries = -1; 11444 } 11445 } 11446 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 11447 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 11448 } 11449 break; 11450 case IAX_COMMAND_RTKEY: 11451 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) { 11452 ast_log(LOG_WARNING, 11453 "we've been told to rotate our encryption key, " 11454 "but this isn't an encrypted call. bad things will happen.\n" 11455 ); 11456 break; 11457 } 11458 11459 IAX_DEBUGDIGEST("Receiving", ies.challenge); 11460 11461 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx); 11462 break; 11463 case IAX_COMMAND_DPREP: 11464 complete_dpreply(iaxs[fr->callno], &ies); 11465 break; 11466 case IAX_COMMAND_UNSUPPORT: 11467 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 11468 break; 11469 case IAX_COMMAND_FWDOWNL: 11470 /* Firmware download */ 11471 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 11472 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 11473 break; 11474 } 11475 memset(&ied0, 0, sizeof(ied0)); 11476 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 11477 if (res < 0) 11478 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11479 else if (res > 0) 11480 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11481 else 11482 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11483 break; 11484 case IAX_COMMAND_CALLTOKEN: 11485 { 11486 struct iax_frame *cur; 11487 /* find last sent frame */ 11488 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) { 11489 resend_with_token(fr->callno, cur, (char *) ies.calltokendata); 11490 } 11491 break; 11492 } 11493 default: 11494 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno); 11495 memset(&ied0, 0, sizeof(ied0)); 11496 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer); 11497 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 11498 } 11499 /* Free remote variables (if any) */ 11500 if (ies.vars) { 11501 ast_variables_destroy(ies.vars); 11502 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n"); 11503 ies.vars = NULL; 11504 } 11505 11506 /* Don't actually pass these frames along */ 11507 if ((f.subclass.integer != IAX_COMMAND_ACK) && 11508 (f.subclass.integer != IAX_COMMAND_TXCNT) && 11509 (f.subclass.integer != IAX_COMMAND_TXACC) && 11510 (f.subclass.integer != IAX_COMMAND_INVAL) && 11511 (f.subclass.integer != IAX_COMMAND_VNAK)) { 11512 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 11513 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11514 } 11515 ast_mutex_unlock(&iaxsl[fr->callno]); 11516 return 1; 11517 } 11518 /* Unless this is an ACK or INVAL frame, ack it */ 11519 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 11520 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11521 } else if (minivid) { 11522 f.frametype = AST_FRAME_VIDEO; 11523 if (iaxs[fr->callno]->videoformat > 0) 11524 f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0); 11525 else { 11526 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 11527 iax2_vnak(fr->callno); 11528 ast_variables_destroy(ies.vars); 11529 ast_mutex_unlock(&iaxsl[fr->callno]); 11530 return 1; 11531 } 11532 f.datalen = res - sizeof(*vh); 11533 if (f.datalen) 11534 f.data.ptr = thread->buf + sizeof(*vh); 11535 else 11536 f.data.ptr = NULL; 11537 #ifdef IAXTESTS 11538 if (test_resync) { 11539 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 11540 } else 11541 #endif /* IAXTESTS */ 11542 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 11543 } else { 11544 /* A mini frame */ 11545 f.frametype = AST_FRAME_VOICE; 11546 if (iaxs[fr->callno]->voiceformat > 0) 11547 f.subclass.codec = iaxs[fr->callno]->voiceformat; 11548 else { 11549 ast_debug(1, "Received mini frame before first full voice frame\n"); 11550 iax2_vnak(fr->callno); 11551 ast_variables_destroy(ies.vars); 11552 ast_mutex_unlock(&iaxsl[fr->callno]); 11553 return 1; 11554 } 11555 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 11556 if (f.datalen < 0) { 11557 ast_log(LOG_WARNING, "Datalen < 0?\n"); 11558 ast_variables_destroy(ies.vars); 11559 ast_mutex_unlock(&iaxsl[fr->callno]); 11560 return 1; 11561 } 11562 if (f.datalen) 11563 f.data.ptr = thread->buf + sizeof(*mh); 11564 else 11565 f.data.ptr = NULL; 11566 #ifdef IAXTESTS 11567 if (test_resync) { 11568 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 11569 } else 11570 #endif /* IAXTESTS */ 11571 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 11572 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 11573 } 11574 /* Don't pass any packets until we're started */ 11575 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 11576 ast_variables_destroy(ies.vars); 11577 ast_mutex_unlock(&iaxsl[fr->callno]); 11578 return 1; 11579 } 11580 /* Don't allow connected line updates unless we are configured to */ 11581 if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) { 11582 struct ast_party_connected_line connected; 11583 11584 if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) { 11585 ast_variables_destroy(ies.vars); 11586 ast_mutex_unlock(&iaxsl[fr->callno]); 11587 return 1; 11588 } 11589 11590 /* Initialize defaults */ 11591 ast_party_connected_line_init(&connected); 11592 connected.id.number.presentation = iaxs[fr->callno]->calling_pres; 11593 connected.id.name.presentation = iaxs[fr->callno]->calling_pres; 11594 11595 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) { 11596 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str); 11597 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str); 11598 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id); 11599 11600 if (iaxs[fr->callno]->owner) { 11601 ast_set_callerid(iaxs[fr->callno]->owner, 11602 S_COR(connected.id.number.valid, connected.id.number.str, ""), 11603 S_COR(connected.id.name.valid, connected.id.name.str, ""), 11604 NULL); 11605 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation; 11606 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation; 11607 } 11608 } 11609 ast_party_connected_line_free(&connected); 11610 } 11611 /* Common things */ 11612 f.src = "IAX2"; 11613 f.mallocd = 0; 11614 f.offset = 0; 11615 f.len = 0; 11616 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 11617 f.samples = ast_codec_get_samples(&f); 11618 /* We need to byteswap incoming slinear samples from network byte order */ 11619 if (f.subclass.codec == AST_FORMAT_SLINEAR) 11620 ast_frame_byteswap_be(&f); 11621 } else 11622 f.samples = 0; 11623 iax_frame_wrap(fr, &f); 11624 11625 /* If this is our most recent packet, use it as our basis for timestamping */ 11626 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11627 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 11628 fr->outoforder = 0; 11629 } else { 11630 if (iaxdebug && iaxs[fr->callno]) 11631 ast_debug(1, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass.integer, fr->ts, iaxs[fr->callno]->last); 11632 fr->outoforder = -1; 11633 } 11634 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 11635 duped_fr = iaxfrdup2(fr); 11636 if (duped_fr) { 11637 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 11638 } 11639 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11640 iaxs[fr->callno]->last = fr->ts; 11641 #if 1 11642 if (iaxdebug) 11643 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 11644 #endif 11645 } 11646 11647 /* Always run again */ 11648 ast_variables_destroy(ies.vars); 11649 ast_mutex_unlock(&iaxsl[fr->callno]); 11650 return 1; 11651 }
static int socket_process_meta | ( | int | packet_len, | |
struct ast_iax2_meta_hdr * | meta, | |||
struct sockaddr_in * | sin, | |||
int | sockfd, | |||
struct iax_frame * | fr | |||
) | [static] |
Definition at line 9691 of file chan_iax2.c.
References ast_codec_get_samples(), AST_FRAME_VOICE, ast_inet_ntoa(), ast_log(), ast_mutex_unlock, ast_test_flag, ast_tvnow(), ast_tvzero(), iax_frame::callno, ast_iax2_mini_hdr::callno, f, find_callno_locked(), find_tpeer(), fix_peerts(), iax2_vnak(), IAX_FLAG_FULL, iax_frame_wrap(), IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_STATE_STARTED, iaxfrdup2(), iaxs, iaxsl, chan_iax2_pvt::last, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_iax2_meta_trunk_mini::mini, NEW_PREVENT, iax_frame::outoforder, iax2_trunk_peer::rxtrunktime, schedule_delivery(), iax2_trunk_peer::trunkact, iax_frame::ts, ast_iax2_mini_hdr::ts, and chan_iax2_pvt::voiceformat.
Referenced by socket_process().
09693 { 09694 unsigned char metatype; 09695 struct ast_iax2_meta_trunk_mini *mtm; 09696 struct ast_iax2_meta_trunk_hdr *mth; 09697 struct ast_iax2_meta_trunk_entry *mte; 09698 struct iax2_trunk_peer *tpeer; 09699 unsigned int ts; 09700 void *ptr; 09701 struct timeval rxtrunktime; 09702 struct ast_frame f = { 0, }; 09703 09704 if (packet_len < sizeof(*meta)) { 09705 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 09706 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09707 return 1; 09708 } 09709 09710 if (meta->metacmd != IAX_META_TRUNK) 09711 return 1; 09712 09713 if (packet_len < (sizeof(*meta) + sizeof(*mth))) { 09714 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len, 09715 (int) (sizeof(*meta) + sizeof(*mth))); 09716 return 1; 09717 } 09718 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 09719 ts = ntohl(mth->ts); 09720 metatype = meta->cmddata; 09721 packet_len -= (sizeof(*meta) + sizeof(*mth)); 09722 ptr = mth->data; 09723 tpeer = find_tpeer(sin, sockfd); 09724 if (!tpeer) { 09725 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 09726 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09727 return 1; 09728 } 09729 tpeer->trunkact = ast_tvnow(); 09730 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 09731 tpeer->rxtrunktime = tpeer->trunkact; 09732 rxtrunktime = tpeer->rxtrunktime; 09733 ast_mutex_unlock(&tpeer->lock); 09734 while (packet_len >= sizeof(*mte)) { 09735 /* Process channels */ 09736 unsigned short callno, trunked_ts, len; 09737 09738 if (metatype == IAX_META_TRUNK_MINI) { 09739 mtm = (struct ast_iax2_meta_trunk_mini *) ptr; 09740 ptr += sizeof(*mtm); 09741 packet_len -= sizeof(*mtm); 09742 len = ntohs(mtm->len); 09743 callno = ntohs(mtm->mini.callno); 09744 trunked_ts = ntohs(mtm->mini.ts); 09745 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 09746 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 09747 ptr += sizeof(*mte); 09748 packet_len -= sizeof(*mte); 09749 len = ntohs(mte->len); 09750 callno = ntohs(mte->callno); 09751 trunked_ts = 0; 09752 } else { 09753 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09754 break; 09755 } 09756 /* Stop if we don't have enough data */ 09757 if (len > packet_len) 09758 break; 09759 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0); 09760 if (!fr->callno) 09761 continue; 09762 09763 /* If it's a valid call, deliver the contents. If not, we 09764 drop it, since we don't have a scallno to use for an INVAL */ 09765 /* Process as a mini frame */ 09766 memset(&f, 0, sizeof(f)); 09767 f.frametype = AST_FRAME_VOICE; 09768 if (!iaxs[fr->callno]) { 09769 /* drop it */ 09770 } else if (iaxs[fr->callno]->voiceformat == 0) { 09771 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 09772 iax2_vnak(fr->callno); 09773 } else { 09774 f.subclass.codec = iaxs[fr->callno]->voiceformat; 09775 f.datalen = len; 09776 if (f.datalen >= 0) { 09777 if (f.datalen) 09778 f.data.ptr = ptr; 09779 else 09780 f.data.ptr = NULL; 09781 if (trunked_ts) 09782 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 09783 else 09784 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 09785 /* Don't pass any packets until we're started */ 09786 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09787 struct iax_frame *duped_fr; 09788 09789 /* Common things */ 09790 f.src = "IAX2"; 09791 f.mallocd = 0; 09792 f.offset = 0; 09793 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 09794 f.samples = ast_codec_get_samples(&f); 09795 else 09796 f.samples = 0; 09797 fr->outoforder = 0; 09798 iax_frame_wrap(fr, &f); 09799 duped_fr = iaxfrdup2(fr); 09800 if (duped_fr) 09801 schedule_delivery(duped_fr, 1, 1, &fr->ts); 09802 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) 09803 iaxs[fr->callno]->last = fr->ts; 09804 } 09805 } else { 09806 ast_log(LOG_WARNING, "Datalen < 0?\n"); 09807 } 09808 } 09809 ast_mutex_unlock(&iaxsl[fr->callno]); 09810 ptr += len; 09811 packet_len -= len; 09812 } 09813 09814 return 1; 09815 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 9612 of file chan_iax2.c.
References ast_copy_string(), ast_debug, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), iax2_thread::callno, ast_iax2_full_hdr::csub, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), iax2_thread::list, LOG_WARNING, ast_iax2_full_hdr::scallno, signal_condition(), iax2_thread::sin, thread, and ast_iax2_full_hdr::type.
Referenced by network_thread(), peer_set_srcaddr(), and set_config().
09613 { 09614 struct iax2_thread *thread; 09615 socklen_t len; 09616 time_t t; 09617 static time_t last_errtime = 0; 09618 struct ast_iax2_full_hdr *fh; 09619 09620 if (!(thread = find_idle_thread())) { 09621 time(&t); 09622 if (t != last_errtime) 09623 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n"); 09624 last_errtime = t; 09625 usleep(1); 09626 return 1; 09627 } 09628 09629 len = sizeof(thread->iosin); 09630 thread->iofd = fd; 09631 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 09632 thread->buf_size = sizeof(thread->readbuf); 09633 thread->buf = thread->readbuf; 09634 if (thread->buf_len < 0) { 09635 if (errno != ECONNREFUSED && errno != EAGAIN) 09636 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 09637 handle_error(); 09638 thread->iostate = IAX_IOSTATE_IDLE; 09639 signal_condition(&thread->lock, &thread->cond); 09640 return 1; 09641 } 09642 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 09643 thread->iostate = IAX_IOSTATE_IDLE; 09644 signal_condition(&thread->lock, &thread->cond); 09645 return 1; 09646 } 09647 09648 /* Determine if this frame is a full frame; if so, and any thread is currently 09649 processing a full frame for the same callno from this peer, then drop this 09650 frame (and the peer will retransmit it) */ 09651 fh = (struct ast_iax2_full_hdr *) thread->buf; 09652 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 09653 struct iax2_thread *cur = NULL; 09654 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 09655 09656 AST_LIST_LOCK(&active_list); 09657 AST_LIST_TRAVERSE(&active_list, cur, list) { 09658 if ((cur->ffinfo.callno == callno) && 09659 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 09660 break; 09661 } 09662 if (cur) { 09663 /* we found another thread processing a full frame for this call, 09664 so queue it up for processing later. */ 09665 defer_full_frame(thread, cur); 09666 AST_LIST_UNLOCK(&active_list); 09667 thread->iostate = IAX_IOSTATE_IDLE; 09668 signal_condition(&thread->lock, &thread->cond); 09669 return 1; 09670 } else { 09671 /* this thread is going to process this frame, so mark it */ 09672 thread->ffinfo.callno = callno; 09673 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 09674 thread->ffinfo.type = fh->type; 09675 thread->ffinfo.csub = fh->csub; 09676 AST_LIST_INSERT_HEAD(&active_list, thread, list); 09677 } 09678 AST_LIST_UNLOCK(&active_list); 09679 } 09680 09681 /* Mark as ready and send on its way */ 09682 thread->iostate = IAX_IOSTATE_READY; 09683 #ifdef DEBUG_SCHED_MULTITHREAD 09684 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 09685 #endif 09686 signal_condition(&thread->lock, &thread->cond); 09687 09688 return 1; 09689 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 9282 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), ast_log(), ast_pthread_create_detached, ast_strdup, dp_lookup_thread(), and LOG_WARNING.
Referenced by socket_process().
09283 { 09284 pthread_t newthread; 09285 struct dpreq_data *dpr; 09286 09287 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 09288 return; 09289 09290 dpr->callno = callno; 09291 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 09292 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 09293 if (callerid) 09294 dpr->callerid = ast_strdup(callerid); 09295 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) { 09296 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 09297 } 09298 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 12212 of file chan_iax2.c.
References ast_calloc, ast_cond_destroy, ast_cond_init, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_destroy, ast_mutex_init, ast_pthread_create_background, iax2_process_thread(), IAX_THREAD_TYPE_POOL, iaxthreadcount, iax2_thread::list, LOG_WARNING, and thread.
Referenced by load_module().
12213 { 12214 struct iax2_thread *thread; 12215 int threadcount = 0; 12216 int x; 12217 for (x = 0; x < iaxthreadcount; x++) { 12218 thread = ast_calloc(1, sizeof(*thread)); 12219 if (thread) { 12220 thread->type = IAX_THREAD_TYPE_POOL; 12221 thread->threadnum = ++threadcount; 12222 ast_mutex_init(&thread->lock); 12223 ast_cond_init(&thread->cond, NULL); 12224 ast_mutex_init(&thread->init_lock); 12225 ast_cond_init(&thread->init_cond, NULL); 12226 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 12227 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 12228 ast_mutex_destroy(&thread->lock); 12229 ast_cond_destroy(&thread->cond); 12230 ast_mutex_destroy(&thread->init_lock); 12231 ast_cond_destroy(&thread->init_cond); 12232 ast_free(thread); 12233 thread = NULL; 12234 continue; 12235 } 12236 AST_LIST_LOCK(&idle_list); 12237 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 12238 AST_LIST_UNLOCK(&idle_list); 12239 } 12240 } 12241 if (ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL)) { 12242 ast_log(LOG_ERROR, "Failed to create new thread!\n"); 12243 return -1; 12244 } 12245 ast_verb(2, "%d helper threads started\n", threadcount); 12246 return 0; 12247 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 8988 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
08989 { 08990 iax2_destroy_helper(iaxs[callno]); 08991 }
static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2130 of file chan_iax2.c.
References ao2_link, ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by __find_callno(), complete_transfer(), and socket_process().
02131 { 02132 if (!pvt->peercallno) { 02133 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 02134 return; 02135 } 02136 02137 ao2_link(iax_peercallno_pvts, pvt); 02138 }
static void store_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2111 of file chan_iax2.c.
References ao2_link, ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by try_transfer().
02112 { 02113 if (!pvt->transfercallno) { 02114 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 02115 return; 02116 } 02117 02118 ao2_link(iax_transfercallno_pvts, pvt); 02119 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 9171 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_debug, ast_free, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_timer_ack(), ast_tvnow(), ast_verbose, iax2_trunk_expired(), iax2_trunk_peer::lock, send_trunk(), timer, totalcalls, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.
Referenced by network_thread().
09172 { 09173 int res, processed = 0, totalcalls = 0; 09174 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL; 09175 struct timeval now = ast_tvnow(); 09176 09177 if (iaxtrunkdebug) 09178 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize); 09179 09180 if (timer) { 09181 ast_timer_ack(timer, 1); 09182 } 09183 09184 /* For each peer that supports trunking... */ 09185 AST_LIST_LOCK(&tpeers); 09186 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) { 09187 processed++; 09188 res = 0; 09189 ast_mutex_lock(&tpeer->lock); 09190 /* We can drop a single tpeer per pass. That makes all this logic 09191 substantially easier */ 09192 if (!drop && iax2_trunk_expired(tpeer, &now)) { 09193 /* Take it out of the list, but don't free it yet, because it 09194 could be in use */ 09195 AST_LIST_REMOVE_CURRENT(list); 09196 drop = tpeer; 09197 } else { 09198 res = send_trunk(tpeer, &now); 09199 trunk_timed++; 09200 if (iaxtrunkdebug) 09201 ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %d bytes backloged and has hit a high water mark of %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc); 09202 } 09203 totalcalls += res; 09204 res = 0; 09205 ast_mutex_unlock(&tpeer->lock); 09206 } 09207 AST_LIST_TRAVERSE_SAFE_END; 09208 AST_LIST_UNLOCK(&tpeers); 09209 09210 if (drop) { 09211 ast_mutex_lock(&drop->lock); 09212 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 09213 because by the time they could get tpeerlock, we've already grabbed it */ 09214 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 09215 if (drop->trunkdata) { 09216 ast_free(drop->trunkdata); 09217 drop->trunkdata = NULL; 09218 } 09219 ast_mutex_unlock(&drop->lock); 09220 ast_mutex_destroy(&drop->lock); 09221 ast_free(drop); 09222 09223 } 09224 09225 if (iaxtrunkdebug) 09226 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 09227 iaxtrunkdebug = 0; 09228 09229 return 1; 09230 }
static int transfercallno_pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 14472 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().
Referenced by load_objects().
14473 { 14474 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14475 14476 /* The frames_received field is used to hold whether we're matching 14477 * against a full frame or not ... */ 14478 14479 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 14480 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14481 }
static int transfercallno_pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 14465 of file chan_iax2.c.
References chan_iax2_pvt::transfercallno.
Referenced by load_objects().
14466 { 14467 const struct chan_iax2_pvt *pvt = obj; 14468 14469 return pvt->transfercallno; 14470 }
static int transmit_frame | ( | void * | data | ) | [static] |
Definition at line 4262 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, ast_mutex_lock, ast_mutex_unlock, attempt_transmit(), iax_frame::callno, frame_queue, iax2_sched_add(), iax_frame_free(), iaxs, iaxsl, iax2_trunk_peer::list, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, sched, send_packet(), and iax_frame::sentyet.
Referenced by iax2_transmit().
04263 { 04264 struct iax_frame *fr = data; 04265 04266 ast_mutex_lock(&iaxsl[fr->callno]); 04267 04268 fr->sentyet = 1; 04269 04270 if (iaxs[fr->callno]) { 04271 send_packet(fr); 04272 } 04273 04274 if (fr->retries < 0) { 04275 ast_mutex_unlock(&iaxsl[fr->callno]); 04276 /* No retransmit requested */ 04277 iax_frame_free(fr); 04278 } else { 04279 /* We need reliable delivery. Schedule a retransmission */ 04280 AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list); 04281 fr->retries++; 04282 fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr); 04283 ast_mutex_unlock(&iaxsl[fr->callno]); 04284 } 04285 04286 return 0; 04287 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 3325 of file chan_iax2.c.
References ast_debug, errno, f, and handle_error().
Referenced by send_trunk().
03326 { 03327 int res; 03328 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 03329 sizeof(*sin)); 03330 if (res < 0) { 03331 ast_debug(1, "Received error: %s\n", strerror(errno)); 03332 handle_error(); 03333 } else 03334 res = 0; 03335 return res; 03336 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 3027 of file chan_iax2.c.
References ast_calloc, AST_FILE_MODE, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_strlen_zero(), ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, iax_firmware::dead, ast_iax2_firmware_header::devname, errno, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, iax2_trunk_peer::list, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), and ast_iax2_firmware_header::version.
Referenced by reload_firmware().
03028 { 03029 struct stat stbuf; 03030 struct iax_firmware *cur = NULL; 03031 int ifd, fd, res, len, chunk; 03032 struct ast_iax2_firmware_header *fwh, fwh2; 03033 struct MD5Context md5; 03034 unsigned char sum[16], buf[1024]; 03035 char *s2, *last; 03036 03037 if (!(s2 = alloca(strlen(s) + 100))) { 03038 ast_log(LOG_WARNING, "Alloca failed!\n"); 03039 return -1; 03040 } 03041 03042 last = strrchr(s, '/'); 03043 if (last) 03044 last++; 03045 else 03046 last = s; 03047 03048 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 03049 03050 if ((res = stat(s, &stbuf) < 0)) { 03051 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 03052 return -1; 03053 } 03054 03055 /* Make sure it's not a directory */ 03056 if (S_ISDIR(stbuf.st_mode)) 03057 return -1; 03058 ifd = open(s, O_RDONLY); 03059 if (ifd < 0) { 03060 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 03061 return -1; 03062 } 03063 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE); 03064 if (fd < 0) { 03065 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 03066 close(ifd); 03067 return -1; 03068 } 03069 /* Unlink our newly created file */ 03070 unlink(s2); 03071 03072 /* Now copy the firmware into it */ 03073 len = stbuf.st_size; 03074 while(len) { 03075 chunk = len; 03076 if (chunk > sizeof(buf)) 03077 chunk = sizeof(buf); 03078 res = read(ifd, buf, chunk); 03079 if (res != chunk) { 03080 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 03081 close(ifd); 03082 close(fd); 03083 return -1; 03084 } 03085 res = write(fd, buf, chunk); 03086 if (res != chunk) { 03087 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 03088 close(ifd); 03089 close(fd); 03090 return -1; 03091 } 03092 len -= chunk; 03093 } 03094 close(ifd); 03095 /* Return to the beginning */ 03096 lseek(fd, 0, SEEK_SET); 03097 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 03098 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 03099 close(fd); 03100 return -1; 03101 } 03102 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 03103 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 03104 close(fd); 03105 return -1; 03106 } 03107 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 03108 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 03109 close(fd); 03110 return -1; 03111 } 03112 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 03113 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 03114 close(fd); 03115 return -1; 03116 } 03117 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 03118 if (fwh == MAP_FAILED) { 03119 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 03120 close(fd); 03121 return -1; 03122 } 03123 MD5Init(&md5); 03124 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 03125 MD5Final(sum, &md5); 03126 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 03127 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 03128 munmap((void*)fwh, stbuf.st_size); 03129 close(fd); 03130 return -1; 03131 } 03132 03133 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03134 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 03135 /* Found a candidate */ 03136 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 03137 /* The version we have on loaded is older, load this one instead */ 03138 break; 03139 /* This version is no newer than what we have. Don't worry about it. 03140 We'll consider it a proper load anyhow though */ 03141 munmap((void*)fwh, stbuf.st_size); 03142 close(fd); 03143 return 0; 03144 } 03145 } 03146 03147 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) { 03148 cur->fd = -1; 03149 AST_LIST_INSERT_TAIL(&firmwares, cur, list); 03150 } 03151 03152 if (cur) { 03153 if (cur->fwh) 03154 munmap((void*)cur->fwh, cur->mmaplen); 03155 if (cur->fd > -1) 03156 close(cur->fd); 03157 cur->fwh = fwh; 03158 cur->fd = fd; 03159 cur->mmaplen = stbuf.st_size; 03160 cur->dead = 0; 03161 } 03162 03163 return 0; 03164 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 8306 of file chan_iax2.c.
References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log(), iax_ies::callno, IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, inet_aton(), LOG_WARNING, send_command_transfer(), store_by_transfercallno(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, TRANSFER_NONE, chan_iax2_pvt::transfercallno, iax_ies::transferid, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
08307 { 08308 int newcall = 0; 08309 char newip[256]; 08310 struct iax_ie_data ied; 08311 struct sockaddr_in new = { 0, }; 08312 08313 memset(&ied, 0, sizeof(ied)); 08314 if (ies->apparent_addr) 08315 memmove(&new, ies->apparent_addr, sizeof(new)); 08316 if (ies->callno) 08317 newcall = ies->callno; 08318 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 08319 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08320 return -1; 08321 } 08322 pvt->transfercallno = newcall; 08323 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 08324 inet_aton(newip, &pvt->transfer.sin_addr); 08325 pvt->transfer.sin_family = AF_INET; 08326 pvt->transferid = ies->transferid; 08327 /* only store by transfercallno if this is a new transfer, 08328 * just in case we get a duplicate TXREQ */ 08329 if (pvt->transferring == TRANSFER_NONE) { 08330 store_by_transfercallno(pvt); 08331 } 08332 pvt->transferring = TRANSFER_BEGIN; 08333 08334 if (ies->transferid) 08335 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 08336 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 08337 return 0; 08338 }
static format_t uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1628 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), handle_call_token(), and socket_process().
01629 { 01630 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01631 if (csub & IAX_FLAG_SC_LOG) { 01632 /* special case for 'compressed' -1 */ 01633 if (csub == 0xff) 01634 return -1; 01635 else 01636 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01637 } 01638 else 01639 return csub; 01640 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 8600 of file chan_iax2.c.
References ao2_unlink, ast_sched_thread_del, iax2_peer::expire, peer_unref(), peers, iax2_peer::pokeexpire, and sched.
Referenced by __expire_registry(), build_peer(), and prune_peers().
08601 { 08602 if (peer->expire > -1) { 08603 if (!ast_sched_thread_del(sched, peer->expire)) { 08604 peer->expire = -1; 08605 peer_unref(peer); 08606 } 08607 } 08608 08609 if (peer->pokeexpire > -1) { 08610 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 08611 peer->pokeexpire = -1; 08612 peer_unref(peer); 08613 } 08614 } 08615 08616 ao2_unlink(peers, peer); 08617 }
static int unload_module | ( | void | ) | [static] |
Definition at line 14430 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), iaxpeer_function, and iaxvar_function.
14431 { 14432 ast_custom_function_unregister(&iaxpeer_function); 14433 ast_custom_function_unregister(&iaxvar_function); 14434 return __unload_module(); 14435 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 5472 of file chan_iax2.c.
References ast_mutex_unlock, and iaxsl.
Referenced by iax2_bridge().
05473 { 05474 ast_mutex_unlock(&iaxsl[callno1]); 05475 ast_mutex_unlock(&iaxsl[callno0]); 05476 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 4015 of file chan_iax2.c.
References iax_frame::af, ast_debug, AST_FRAME_VIDEO, iax_frame::callno, ast_frame::frametype, iaxs, chan_iax2_pvt::last, and iax_frame::ts.
Referenced by schedule_delivery().
04016 { 04017 /* Video mini frames only encode the lower 15 bits of the session 04018 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 04019 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 04020 const int lower_mask = (1 << ts_shift) - 1; 04021 const int upper_mask = ~lower_mask; 04022 const int last_upper = iaxs[fr->callno]->last & upper_mask; 04023 04024 if ( (fr->ts & upper_mask) == last_upper ) { 04025 const int x = fr->ts - iaxs[fr->callno]->last; 04026 const int threshold = (ts_shift == 15) ? 25000 : 50000; 04027 04028 if (x < -threshold) { 04029 /* Sudden big jump backwards in timestamp: 04030 What likely happened here is that miniframe timestamp has circled but we haven't 04031 gotten the update from the main packet. We'll just pretend that we did, and 04032 update the timestamp appropriately. */ 04033 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 04034 if (iaxdebug) 04035 ast_debug(1, "schedule_delivery: pushed forward timestamp\n"); 04036 } else if (x > threshold) { 04037 /* Sudden apparent big jump forwards in timestamp: 04038 What's likely happened is this is an old miniframe belonging to the previous 04039 top 15 or 16-bit timestamp that has turned up out of order. 04040 Adjust the timestamp appropriately. */ 04041 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 04042 if (iaxdebug) 04043 ast_debug(1, "schedule_delivery: pushed back timestamp\n"); 04044 } 04045 } 04046 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 4050 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), iax2_sched_replace(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, chan_iax2_pvt::rxcore, and sched.
Referenced by __get_from_jb(), and schedule_delivery().
04051 { 04052 int when; 04053 04054 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 04055 04056 when = jb_next(pvt->jb) - when; 04057 04058 if (when <= 0) { 04059 /* XXX should really just empty until when > 0.. */ 04060 when = 1; 04061 } 04062 04063 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 04064 CALLNO_TO_PTR(pvt->callno)); 04065 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3463 of file chan_iax2.c.
References build_rand_pad(), ast_iax2_full_hdr::dcallno, decode_frame(), encrypt_frame(), f, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, and chan_iax2_pvt::iseqno.
Referenced by __attempt_transmit().
03464 { 03465 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 03466 struct ast_iax2_full_hdr *fh = f->data; 03467 struct ast_frame af; 03468 03469 /* if frame is encrypted. decrypt before updating it. */ 03470 if (f->encmethods) { 03471 decode_frame(&f->mydcx, fh, &af, &f->datalen); 03472 } 03473 /* Mark this as a retransmission */ 03474 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 03475 /* Update iseqno */ 03476 f->iseqno = iaxs[f->callno]->iseqno; 03477 fh->iseqno = f->iseqno; 03478 03479 /* Now re-encrypt the frame */ 03480 if (f->encmethods) { 03481 /* since this is a retransmit frame, create a new random padding 03482 * before re-encrypting. */ 03483 build_rand_pad(f->semirand, sizeof(f->semirand)); 03484 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen); 03485 } 03486 return 0; 03487 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 8720 of file chan_iax2.c.
References iax2_peer::addr, ast_app_inboxcount(), ast_db_del(), ast_db_put(), AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_del, ast_sockaddr_cmp(), ast_sockaddr_from_sin, ast_sockaddr_to_sin, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_verb, iax2_peer::cid_name, iax2_peer::cid_num, context, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), globalflags, iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxs, iaxsl, LOG_NOTICE, LOG_WARNING, mailbox, iax2_peer::mailbox, manager_event, iax2_peer::maxcallno, iax2_peer::name, peer_ref(), peer_unref(), peercnt_modify(), iax_ie_data::pos, realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, state, strsep(), version, and iax2_peer::zonetag.
Referenced by socket_process().
08721 { 08722 /* Called from IAX thread only, with proper iaxsl lock */ 08723 struct iax_ie_data ied = { 08724 .pos = 0, 08725 }; 08726 struct iax2_peer *p; 08727 int msgcount; 08728 char data[80]; 08729 int version; 08730 const char *peer_name; 08731 int res = -1; 08732 struct ast_sockaddr sockaddr; 08733 08734 ast_sockaddr_from_sin(&sockaddr, sin); 08735 08736 peer_name = ast_strdupa(iaxs[callno]->peer); 08737 08738 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 08739 ast_mutex_unlock(&iaxsl[callno]); 08740 if (!(p = find_peer(peer_name, 1))) { 08741 ast_mutex_lock(&iaxsl[callno]); 08742 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 08743 return -1; 08744 } 08745 ast_mutex_lock(&iaxsl[callno]); 08746 if (!iaxs[callno]) 08747 goto return_unref; 08748 08749 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 08750 if (sin->sin_addr.s_addr) { 08751 time_t nowtime; 08752 time(&nowtime); 08753 realtime_update_peer(peer_name, &sockaddr, nowtime); 08754 } else { 08755 realtime_update_peer(peer_name, &sockaddr, 0); 08756 } 08757 } 08758 08759 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) { 08760 if (iax2_regfunk) { 08761 iax2_regfunk(p->name, 1); 08762 } 08763 08764 /* modify entry in peercnts table as _not_ registered */ 08765 peercnt_modify(0, 0, &p->addr); 08766 08767 /* Stash the IP address from which they registered */ 08768 ast_sockaddr_from_sin(&p->addr, sin); 08769 08770 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 08771 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 08772 ast_db_put("IAX/Registry", p->name, data); 08773 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 08774 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 08775 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 08776 register_peer_exten(p, 1); 08777 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08778 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) { 08779 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name, 08780 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 08781 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 08782 register_peer_exten(p, 0); 08783 ast_db_del("IAX/Registry", p->name); 08784 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */ 08785 } 08786 /* Update the host */ 08787 /* Verify that the host is really there */ 08788 iax2_poke_peer(p, callno); 08789 } 08790 08791 /* modify entry in peercnts table as registered */ 08792 if (p->maxcallno) { 08793 peercnt_modify(1, p->maxcallno, &p->addr); 08794 } 08795 08796 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 08797 if (!iaxs[callno]) { 08798 res = -1; 08799 goto return_unref; 08800 } 08801 08802 /* Store socket fd */ 08803 p->sockfd = fd; 08804 /* Setup the expiry */ 08805 if (p->expire > -1) { 08806 if (!ast_sched_thread_del(sched, p->expire)) { 08807 p->expire = -1; 08808 peer_unref(p); 08809 } 08810 } 08811 /* treat an unspecified refresh interval as the minimum */ 08812 if (!refresh) 08813 refresh = min_reg_expire; 08814 if (refresh > max_reg_expire) { 08815 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08816 p->name, max_reg_expire, refresh); 08817 p->expiry = max_reg_expire; 08818 } else if (refresh < min_reg_expire) { 08819 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08820 p->name, min_reg_expire, refresh); 08821 p->expiry = min_reg_expire; 08822 } else { 08823 p->expiry = refresh; 08824 } 08825 if (p->expiry && sin->sin_addr.s_addr) { 08826 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08827 if (p->expire == -1) 08828 peer_unref(p); 08829 } 08830 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 08831 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 08832 if (sin->sin_addr.s_addr) { 08833 struct sockaddr_in peer_addr; 08834 08835 ast_sockaddr_to_sin(&p->addr, &peer_addr); 08836 08837 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 08838 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr); 08839 if (!ast_strlen_zero(p->mailbox)) { 08840 struct ast_event *event; 08841 int new, old; 08842 char *mailbox, *context; 08843 08844 context = mailbox = ast_strdupa(p->mailbox); 08845 strsep(&context, "@"); 08846 if (ast_strlen_zero(context)) 08847 context = "default"; 08848 08849 event = ast_event_get_cached(AST_EVENT_MWI, 08850 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 08851 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 08852 AST_EVENT_IE_END); 08853 if (event) { 08854 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 08855 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 08856 ast_event_destroy(event); 08857 } else { /* Fall back on checking the mailbox directly */ 08858 ast_app_inboxcount(p->mailbox, &new, &old); 08859 } 08860 08861 if (new > 255) { 08862 new = 255; 08863 } 08864 if (old > 255) { 08865 old = 255; 08866 } 08867 msgcount = (old << 8) | new; 08868 08869 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 08870 } 08871 if (ast_test_flag64(p, IAX_HASCALLERID)) { 08872 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 08873 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 08874 } 08875 } 08876 version = iax_check_version(devtype); 08877 if (version) 08878 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 08879 08880 res = 0; 08881 08882 return_unref: 08883 peer_unref(p); 08884 08885 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 08886 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1675 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and user.
Referenced by load_objects().
01676 { 01677 struct iax2_user *user = obj, *user2 = arg; 01678 01679 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0; 01680 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12955 of file chan_iax2.c.
References ast_set_flag64, IAX_DELME, and user.
Referenced by delete_users().
12956 { 12957 struct iax2_user *user = obj; 12958 12959 ast_set_flag64(user, IAX_DELME); 12960 12961 return 0; 12962 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 12680 of file chan_iax2.c.
References ast_free_ha(), ast_string_field_free_memory, ast_variables_destroy(), free_context(), and user.
Referenced by build_user().
12681 { 12682 struct iax2_user *user = obj; 12683 12684 ast_free_ha(user->ha); 12685 free_context(user->contexts); 12686 if(user->vars) { 12687 ast_variables_destroy(user->vars); 12688 user->vars = NULL; 12689 } 12690 ast_string_field_free_memory(user); 12691 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1665 of file chan_iax2.c.
References ast_str_hash(), and user.
Referenced by load_objects().
01666 { 01667 const struct iax2_user *user = obj; 01668 01669 return ast_str_hash(user->name); 01670 }
Definition at line 1728 of file chan_iax2.c.
Referenced by authenticate_request(), authenticate_verify(), build_user(), calltoken_required(), check_access(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_users(), iax2_destroy_helper(), prune_users(), requirecalltoken_mark_auto(), set_config(), and users_data_provider_get().
static int users_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 14635 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cdr_flags2str(), ast_copy_string(), ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_password(), ast_data_add_str(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_strlen_zero(), ast_test_flag64, DEFAULT_CONTEXT, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, user, user_unref(), and users.
14637 { 14638 struct ast_data *data_user, *data_authmethods, *data_enum_node; 14639 struct iax2_user *user; 14640 struct ao2_iterator i; 14641 char auth[90]; 14642 char *pstr = ""; 14643 14644 i = ao2_iterator_init(users, 0); 14645 for (; (user = ao2_iterator_next(&i)); user_unref(user)) { 14646 data_user = ast_data_add_node(data_root, "user"); 14647 if (!data_user) { 14648 continue; 14649 } 14650 14651 ast_data_add_structure(iax2_user, data_user, user); 14652 14653 ast_data_add_codecs(data_user, "codecs", user->capability); 14654 14655 if (!ast_strlen_zero(user->secret)) { 14656 ast_copy_string(auth, user->secret, sizeof(auth)); 14657 } else if (!ast_strlen_zero(user->inkeys)) { 14658 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys); 14659 } else { 14660 ast_copy_string(auth, "no secret", sizeof(auth)); 14661 } 14662 ast_data_add_password(data_user, "secret", auth); 14663 14664 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT); 14665 14666 /* authmethods */ 14667 data_authmethods = ast_data_add_node(data_user, "authmethods"); 14668 if (!data_authmethods) { 14669 ast_data_remove_node(data_root, data_user); 14670 continue; 14671 } 14672 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA); 14673 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5); 14674 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT); 14675 14676 /* amaflags */ 14677 data_enum_node = ast_data_add_node(data_user, "amaflags"); 14678 if (!data_enum_node) { 14679 ast_data_remove_node(data_root, data_user); 14680 continue; 14681 } 14682 ast_data_add_int(data_enum_node, "value", user->amaflags); 14683 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags)); 14684 14685 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0); 14686 14687 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) { 14688 pstr = "REQ only"; 14689 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) { 14690 pstr = "disabled"; 14691 } else { 14692 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host"; 14693 } 14694 ast_data_add_str(data_user, "codec-preferences", pstr); 14695 14696 if (!ast_data_search_match(search, data_user)) { 14697 ast_data_remove_node(data_root, data_user); 14698 } 14699 } 14700 ao2_iterator_destroy(&i); 14701 14702 return 0; 14703 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 9089 of file chan_iax2.c.
References AST_LIST_TRAVERSE, f, frame_queue, iax_frame::list, and send_packet().
Referenced by socket_process().
09090 { 09091 struct iax_frame *f; 09092 09093 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) { 09094 /* Send a copy immediately */ 09095 if (((unsigned char) (f->oseqno - last) < 128) && 09096 (f->retries >= 0)) { 09097 send_packet(f); 09098 } 09099 } 09100 }
static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 5282 of file chan_iax2.c.
References chan_iax2_pvt::callno, DEADLOCK_AVOIDANCE, iaxs, iaxsl, and chan_iax2_pvt::peercallno.
Referenced by iax2_indicate(), and iax2_setoption().
05283 { 05284 unsigned short callno = pvt->callno; 05285 05286 if (!pvt->peercallno) { 05287 /* We don't know the remote side's call number, yet. :( */ 05288 int count = 10; 05289 while (count-- && pvt && !pvt->peercallno) { 05290 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 05291 pvt = iaxs[callno]; 05292 } 05293 if (!pvt || !pvt->peercallno) { 05294 return -1; 05295 } 05296 } 05297 05298 return 0; 05299 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto", } [static] |
Definition at line 14844 of file chan_iax2.c.
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 383 of file chan_iax2.c.
Referenced by __ast_channel_alloc_ap(), __oh323_new(), ast_async_goto(), ast_call_forward(), ast_cdr_setaccount(), ast_cel_fabricate_channel_from_event(), ast_do_masquerade(), ast_set_owners_and_peers(), begin_dial_channel(), build_peer(), check_peer_ok(), create_addr_from_peer(), dahdi_new(), dial_exec_full(), do_forward(), findmeexec(), func_channel_write_real(), gtalk_new(), jingle_new(), local_call(), mgcp_new(), sip_new(), skinny_new(), and tds_log().
int adsi = 0 [static] |
Definition at line 387 of file chan_iax2.c.
int amaflags = 0 [static] |
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 14844 of file chan_iax2.c.
int authdebug = 1 [static] |
Definition at line 294 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 295 of file chan_iax2.c.
struct ao2_container* callno_limits [static] |
Table containing custom callno limit rules for a range of ip addresses.
Definition at line 894 of file chan_iax2.c.
Referenced by __unload_module(), build_callno_limits(), load_objects(), reload_config(), set_config_destroy(), and set_peercnt_limit().
struct ao2_container* callno_pool [static] |
table of available call numbers
Definition at line 849 of file chan_iax2.c.
const unsigned int CALLNO_POOL_BUCKETS = 2699 [static] |
Definition at line 854 of file chan_iax2.c.
struct ao2_container* callno_pool_trunk [static] |
table of available trunk call numbers
Definition at line 852 of file chan_iax2.c.
struct ao2_container* calltoken_ignores [static] |
Table containing ip addresses not requiring calltoken validation
Definition at line 897 of file chan_iax2.c.
Referenced by __unload_module(), add_calltoken_ignore(), calltoken_required(), load_objects(), reload_config(), and set_config_destroy().
struct ast_cli_entry cli_iax2[] [static] |
unsigned int cos |
Definition at line 305 of file chan_iax2.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1101 of file chan_iax2.c.
Referenced by handle_cli_iax2_set_debug(), iax_outputframe(), reload_config(), sip_debug_test_addr(), sip_do_debug(), sip_do_debug_ip(), and sip_do_debug_peer().
uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048 [static] |
Definition at line 899 of file chan_iax2.c.
uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static] |
Definition at line 901 of file chan_iax2.c.
char default_parkinglot[AST_MAX_CONTEXT] [static] |
Definition at line 272 of file chan_iax2.c.
Referenced by create_dynamic_parkinglot(), handle_parkedcalls(), load_config(), park_call_exec(), park_space_reserve(), parked_call_exec(), reload_config(), sip_alloc(), and xfer_park_call_helper().
int defaultsockfd = -1 [static] |
Definition at line 317 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 388 of file chan_iax2.c.
Definition at line 865 of file chan_iax2.c.
struct { ... } frame_queue[IAX_MAX_CALLS + 1] [static] |
a list of frames that may need to be retransmitted
Contents protected by the iaxsl[] locks
Referenced by __attempt_transmit(), complete_transfer(), handle_cli_iax2_show_stats(), pvt_destructor(), resend_with_token(), socket_process(), transmit_frame(), and vnak_retransmit().
int global_max_trunk_mtu [static] |
Maximum MTU, 0 if not used
Definition at line 267 of file chan_iax2.c.
uint16_t global_maxcallno [static] |
Definition at line 903 of file chan_iax2.c.
uint16_t global_maxcallno_nonval [static] |
Total num of call numbers allowed to be allocated without calltoken validation
Definition at line 906 of file chan_iax2.c.
int global_rtautoclear = 120 [static] |
Definition at line 439 of file chan_iax2.c.
struct ast_flags64 globalflags = { 0 } [static] |
Definition at line 391 of file chan_iax2.c.
format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 369 of file chan_iax2.c.
struct ast_data_entry iax2_data_providers[] [static] |
Initial value:
{ AST_DATA_ENTRY("asterisk/channel/iax2/peers", &peers_data_provider), AST_DATA_ENTRY("asterisk/channel/iax2/users", &users_data_provider), }
Definition at line 14715 of file chan_iax2.c.
Referenced by load_module().
int iax2_encryption = 0 [static] |
Definition at line 389 of file chan_iax2.c.
int(*) iax2_regfunk(const char *username, int onoff) = NULL [static] |
Definition at line 319 of file chan_iax2.c.
Referenced by __expire_registry(), reg_source_db(), and update_registry().
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 1216 of file chan_iax2.c.
Referenced by __unload_module(), acf_channel_read(), ast_iax2_new(), function_iaxpeer(), iax2_bridge(), iax2_prov_app(), and load_module().
struct ast_datastore_info iax2_variable_datastore_info [static] |
Initial value:
{ .type = "IAX2_VARIABLE", .duplicate = iax2_dup_variable_datastore, .destroy = iax2_free_variable_datastore, }
Definition at line 1331 of file chan_iax2.c.
Referenced by acf_iaxvar_read(), acf_iaxvar_write(), ast_iax2_new(), authenticate_reply(), iax2_call(), and socket_process().
struct ao2_container* iax_peercallno_pvts [static] |
Another container of iax2_pvt structures.
Active IAX2 pvt structs are also stored in this container, if they are a part of an active call where we know the remote side's call number. The reason for this is that incoming media frames do not contain our call number. So, instead of having to iterate the entire iaxs array, we use this container to look up calls where the remote side is using a given call number.
Definition at line 1078 of file chan_iax2.c.
Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_peercallno(), and store_by_peercallno().
struct ao2_container* iax_transfercallno_pvts [static] |
Another container of iax2_pvt structures.
*
Active IAX2 pvt stucts used during transfering a call are stored here.
Definition at line 1094 of file chan_iax2.c.
Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_transfercallno(), and store_by_transfercallno().
int iaxactivethreadcount = 0 [static] |
Definition at line 638 of file chan_iax2.c.
Referenced by iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 296 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 371 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 299 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 301 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
int iaxdynamicthreadnum = 0 [static] |
int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static] |
struct ast_custom_function iaxpeer_function [static] |
Initial value:
{ .name = "IAXPEER", .read = function_iaxpeer, }
Definition at line 13982 of file chan_iax2.c.
Referenced by load_module(), and unload_module().
struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS+1] [static] |
an array of iax2 pvt structures
The container for active chan_iax2_pvt structures is implemented as an array for extremely quick direct access to the correct pvt structure based on the local call number. The local call number is used as the index into the array where the associated pvt structure is stored.
Definition at line 1067 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __find_callno(), __get_from_jb(), __send_lagrq(), __send_ping(), __unload_module(), acf_channel_read(), ast_cli_netstats(), ast_iax2_new(), auth_fail(), auth_reject(), authenticate_reply(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), dp_lookup(), find_cache(), fix_peerts(), function_iaxpeer(), handle_cli_iax2_show_channels(), iax2_ack_registry(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_lock_owner(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_queryoption(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_setoption(), iax2_start_transfer(), iax2_vnak(), iax2_write(), load_module(), log_jitterstats(), make_trunk(), register_verify(), registry_authrequest(), registry_rerequest(), resend_with_token(), save_osptoken(), save_rr(), schedule_delivery(), scheduled_destroy(), send_command_final(), send_command_locked(), send_lagrq(), send_packet(), send_ping(), set_hangup_source_and_cause(), socket_process(), socket_process_meta(), stop_stuff(), transmit_frame(), unwrap_timestamp(), update_packet(), update_registry(), and wait_for_peercallno().
ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static] |
chan_iax2_pvt structure locks
These locks are used when accessing a pvt structure in the iaxs array. The index used here is the same as used in the iaxs array. It is the local call number for the associated pvt struct.
Definition at line 1087 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __find_callno(), __get_from_jb(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), __unload_module(), acf_channel_read(), ast_cli_netstats(), ast_iax2_new(), auth_reject(), authenticate_reply(), auto_hangup(), cache_get_callno_locked(), delete_users(), dp_lookup(), find_cache(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_stats(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_destroy_helper(), iax2_do_register(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_key_rotate(), iax2_lock_owner(), iax2_poke_peer(), iax2_provision(), iax2_queryoption(), iax2_request(), iax2_setoption(), iax2_write(), load_module(), lock_both(), log_jitterstats(), make_trunk(), peer_destructor(), pvt_destructor(), register_verify(), registry_authrequest(), scheduled_destroy(), send_command_locked(), send_lagrq(), send_ping(), set_hangup_source_and_cause(), socket_process(), socket_process_meta(), transmit_frame(), unlock_both(), update_registry(), and wait_for_peercallno().
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 634 of file chan_iax2.c.
Referenced by handle_cli_iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 373 of file chan_iax2.c.
struct ast_custom_function iaxvar_function [static] |
Initial value:
{ .name = "IAXVAR", .read = acf_iaxvar_read, .write = acf_iaxvar_write, }
Definition at line 9884 of file chan_iax2.c.
Referenced by load_module(), and unload_module().
struct io_context* io [static] |
Definition at line 364 of file chan_iax2.c.
int jittertargetextra = 40 [static] |
Definition at line 287 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 283 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 274 of file chan_iax2.c.
Definition at line 865 of file chan_iax2.c.
int last_authmethod = 0 [static] |
Definition at line 297 of file chan_iax2.c.
const time_t MAX_CALLTOKEN_DELAY = 10 [static] |
Definition at line 871 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 309 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 281 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 280 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 284 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 286 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 308 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 384 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 385 of file chan_iax2.c.
Referenced by build_peer(), check_peer_ok(), create_addr_from_peer(), set_peer_defaults(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 315 of file chan_iax2.c.
Referenced by __unload_module(), ast_netsock_destroy(), load_module(), peer_set_srcaddr(), and set_config().
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
Definition at line 393 of file chan_iax2.c.
int network_change_event_sched_id = -1 [static] |
Definition at line 278 of file chan_iax2.c.
Referenced by network_change_event_cb(), and network_change_event_sched_cb().
struct ast_event_sub* network_change_event_subscription [static] |
subscription id for network change events
Definition at line 277 of file chan_iax2.c.
Referenced by network_change_event_subscribe(), and network_change_event_unsubscribe().
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 316 of file chan_iax2.c.
Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().
char* papp = "IAX2Provision" [static] |
Definition at line 11919 of file chan_iax2.c.
struct ao2_container* peercnts [static] |
Table containing peercnt objects for every ip address consuming a callno
Definition at line 891 of file chan_iax2.c.
Referenced by __unload_module(), handle_cli_iax2_show_callno_limits(), load_objects(), peercnt_add(), peercnt_modify(), peercnt_remove(), peercnt_remove_by_addr(), reload_config(), and sched_delay_remove().
struct ao2_container* peers [static] |
Definition at line 885 of file chan_iax2.c.
Referenced by __iax2_show_peers(), __unload_module(), authenticate_reply(), build_peer(), complete_iax2_peers(), complete_iax2_unregister(), delete_users(), find_peer(), get_insecure_variable_from_sipregs(), handle_cli_iax2_unregister(), iax2_getpeername(), iax2_getpeertrunk(), load_module(), load_objects(), manager_iax2_show_peer_list(), peers_data_provider_get(), poke_all_peers(), prune_peers(), set_config(), and unlink_peer().
struct ast_data_handler peers_data_provider [static] |
Initial value:
{ .version = AST_DATA_HANDLER_VERSION, .get = peers_data_provider_get }
Definition at line 14705 of file chan_iax2.c.
int ping_time = 21 [static] |
Definition at line 282 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 258 of file chan_iax2.c.
Referenced by ast_best_codec(), ast_rtp_codecs_packetization_set(), build_peer(), build_user(), check_access(), create_addr(), gtalk_create_member(), gtalk_load_config(), jingle_create_member(), jingle_load_config(), new_iax(), set_config(), set_local_capabilities(), and set_peer_capabilities().
struct { ... } qos [static] |
Referenced by config_load(), config_parse_variables(), peer_set_srcaddr(), reload_config(), set_config(), and start_rtp().
int randomcalltokendata [static] |
Definition at line 869 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 275 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 285 of file chan_iax2.c.
struct ast_sched_thread* sched [static] |
Definition at line 365 of file chan_iax2.c.
int srvlookup = 0 [static] |
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 260 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 375 of file chan_iax2.c.
Definition at line 313 of file chan_iax2.c.
Referenced by __unload_module(), build_peer(), build_user(), check_timer(), find_timer(), kqueue_timer_hash(), kqueue_timer_open(), load_module(), network_thread(), pthread_timer_ack(), pthread_timer_close(), pthread_timer_destructor(), pthread_timer_disable_continuous(), pthread_timer_enable_continuous(), pthread_timer_get_event(), pthread_timer_hash(), pthread_timer_open(), pthread_timer_set_rate(), read_pipe(), run_timer(), set_config(), softmix_bridge_create(), softmix_bridge_thread(), timer_destroy(), timerfd_timer_hash(), timerfd_timer_open(), timing_read(), timing_test(), and write_byte().
unsigned int tos |
Definition at line 304 of file chan_iax2.c.
uint16_t total_nonval_callno_used = 0 [static] |
Definition at line 908 of file chan_iax2.c.
struct ast_taskprocessor* transmit_processor [static] |
Definition at line 867 of file chan_iax2.c.
int trunk_maxmtu [static] |
Definition at line 268 of file chan_iax2.c.
int trunk_nmaxmtu [static] |
Trunk MTU statistics
Definition at line 268 of file chan_iax2.c.
int trunk_timed [static] |
Definition at line 268 of file chan_iax2.c.
int trunk_untimed [static] |
Definition at line 268 of file chan_iax2.c.
int trunkfreq = 20 [static] |
Definition at line 291 of file chan_iax2.c.
int trunkmaxsize = MAX_TRUNKDATA [static] |
Definition at line 292 of file chan_iax2.c.
struct ao2_container* users [static] |
Definition at line 888 of file chan_iax2.c.
Referenced by __unload_module(), authenticate_request(), authenticate_verify(), build_user(), check_access(), delete_users(), find_user(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_users(), iax2_destroy_helper(), load_module(), load_objects(), pp_each_user_helper(), prune_users(), set_config(), unload_module(), and users_data_provider_get().
struct ast_data_handler users_data_provider [static] |
Initial value:
{ .version = AST_DATA_HANDLER_VERSION, .get = users_data_provider_get }
Definition at line 14710 of file chan_iax2.c.