#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 |
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 *parkexten) |
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 void | update_max_nontrunk (void) |
static void | update_max_trunk (void) |
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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .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 | maxnontrunkcall = 1 |
static int | maxtrunkcall = TRUNK_CALL_START |
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 238 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 14403 of file chan_iax2.c.
#define DATA_EXPORT_IAX2_USER | ( | MEMBER | ) |
Definition at line 14480 of file chan_iax2.c.
#define DEBUG_SCHED_MULTITHREAD |
Definition at line 230 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 246 of file chan_iax2.c.
#define DEFAULT_CONTEXT "default" |
Definition at line 265 of file chan_iax2.c.
Referenced by check_access(), handle_cli_iax2_show_users(), and users_data_provider_get().
#define DEFAULT_DROP 3 |
Definition at line 244 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 340 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 241 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 338 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 240 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 619 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
#define DONT_RESCHEDULE -2 |
Definition at line 362 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 251 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 428 of file chan_iax2.c.
Referenced by set_config(), and socket_process().
#define IAX_ALREADYGONE (uint64_t)(1 << 9) |
Already disconnected
Definition at line 411 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 343 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 317 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 329 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 334 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 418 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 417 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 416 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 427 of file chan_iax2.c.
Referenced by socket_process().
#define IAX_DELME (uint64_t)(1 << 1) |
Needs to be deleted
Definition at line 403 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 408 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 414 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 432 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 422 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 402 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 429 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 415 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 426 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 406 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 412 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 413 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 431 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 421 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 419 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 423 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 410 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 420 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 409 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 430 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 433 of file chan_iax2.c.
Referenced by check_access(), and set_config().
#define IAX_TEMPONLY (uint64_t)(1 << 2) |
Temporary (realtime)
Definition at line 404 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 425 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 405 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 424 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 407 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 627 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 616 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 878 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 621 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 260 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 284 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 243 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 617 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 237 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 226 of file chan_iax2.c.
#define schedule_action | ( | func, | |||
data | ) | __schedule_action(func, data, __PRETTY_FUNCTION__) |
Definition at line 1487 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 1093 of file chan_iax2.c.
Referenced by __find_callno(), create_callno_pools(), make_trunk(), replace_callno(), update_max_nontrunk(), and update_max_trunk().
#define TS_GAP_FOR_JB_RESYNC 5000 |
Definition at line 624 of file chan_iax2.c.
anonymous enum |
Definition at line 938 of file chan_iax2.c.
00938 { 00939 /*! Extension exists */ 00940 CACHE_FLAG_EXISTS = (1 << 0), 00941 /*! Extension is nonexistent */ 00942 CACHE_FLAG_NONEXISTENT = (1 << 1), 00943 /*! Extension can exist */ 00944 CACHE_FLAG_CANEXIST = (1 << 2), 00945 /*! Waiting to hear back response */ 00946 CACHE_FLAG_PENDING = (1 << 3), 00947 /*! Timed out */ 00948 CACHE_FLAG_TIMEOUT = (1 << 4), 00949 /*! Request transmitted */ 00950 CACHE_FLAG_TRANSMITTED = (1 << 5), 00951 /*! Timeout */ 00952 CACHE_FLAG_UNKNOWN = (1 << 6), 00953 /*! Matchmore */ 00954 CACHE_FLAG_MATCHMORE = (1 << 7), 00955 };
anonymous enum |
Definition at line 1972 of file chan_iax2.c.
01972 { 01973 /* do not allow a new call number, only search ones in use for match */ 01974 NEW_PREVENT = 0, 01975 /* search for match first, then allow a new one to be allocated */ 01976 NEW_ALLOW = 1, 01977 /* do not search for match, force a new call number */ 01978 NEW_FORCE = 2, 01979 /* do not search for match, force a new call number. Signifies call number 01980 * has been calltoken validated */ 01981 NEW_ALLOW_CALLTOKEN_VALIDATED = 3, 01982 };
enum calltoken_peer_enum |
Call token validation settings.
Definition at line 441 of file chan_iax2.c.
00441 { 00442 /*! \brief Default calltoken required unless the ip is in the ignorelist */ 00443 CALLTOKEN_DEFAULT = 0, 00444 /*! \brief Require call token validation. */ 00445 CALLTOKEN_YES = 1, 00446 /*! \brief Require call token validation after a successful registration 00447 * using call token validation occurs. */ 00448 CALLTOKEN_AUTO = 2, 00449 /*! \brief Do not require call token validation. */ 00450 CALLTOKEN_NO = 3, 00451 };
enum iax2_state |
Definition at line 390 of file chan_iax2.c.
00390 { 00391 IAX_STATE_STARTED = (1 << 0), 00392 IAX_STATE_AUTHENTICATED = (1 << 1), 00393 IAX_STATE_TBD = (1 << 2), 00394 };
enum iax2_thread_iostate |
Definition at line 979 of file chan_iax2.c.
00979 { 00980 IAX_IOSTATE_IDLE, 00981 IAX_IOSTATE_READY, 00982 IAX_IOSTATE_PROCESSING, 00983 IAX_IOSTATE_SCHEDREADY, 00984 };
enum iax2_thread_type |
Definition at line 986 of file chan_iax2.c.
00986 { 00987 IAX_THREAD_TYPE_POOL, 00988 IAX_THREAD_TYPE_DYNAMIC, 00989 };
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 572 of file chan_iax2.c.
00572 { 00573 REG_STATE_UNREGISTERED = 0, 00574 REG_STATE_REGSENT, 00575 REG_STATE_AUTHSENT, 00576 REG_STATE_REGISTERED, 00577 REG_STATE_REJECTED, 00578 REG_STATE_TIMEOUT, 00579 REG_STATE_NOAUTH 00580 };
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 582 of file chan_iax2.c.
00582 { 00583 TRANSFER_NONE = 0, 00584 TRANSFER_BEGIN, 00585 TRANSFER_READY, 00586 TRANSFER_RELEASED, 00587 TRANSFER_PASSTHROUGH, 00588 TRANSFER_MBEGIN, 00589 TRANSFER_MREADY, 00590 TRANSFER_MRELEASED, 00591 TRANSFER_MPASSTHROUGH, 00592 TRANSFER_MEDIA, 00593 TRANSFER_MEDIAPASS 00594 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3465 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().
03466 { 03467 /* Attempt to transmit the frame to the remote peer... 03468 Called without iaxsl held. */ 03469 struct iax_frame *f = (struct iax_frame *)data; 03470 int freeme = 0; 03471 int callno = f->callno; 03472 /* Make sure this call is still active */ 03473 if (callno) 03474 ast_mutex_lock(&iaxsl[callno]); 03475 if (callno && iaxs[callno]) { 03476 if ((f->retries < 0) /* Already ACK'd */ || 03477 (f->retries >= max_retries) /* Too many attempts */) { 03478 /* Record an error if we've transmitted too many times */ 03479 if (f->retries >= max_retries) { 03480 if (f->transfer) { 03481 /* Transfer timeout */ 03482 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 03483 } else if (f->final) { 03484 iax2_destroy(callno); 03485 } else { 03486 if (iaxs[callno]->owner) 03487 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); 03488 iaxs[callno]->error = ETIMEDOUT; 03489 if (iaxs[callno]->owner) { 03490 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER }; 03491 /* Hangup the fd */ 03492 iax2_queue_frame(callno, &fr); /* XXX */ 03493 /* Remember, owner could disappear */ 03494 if (iaxs[callno] && iaxs[callno]->owner) 03495 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03496 } else { 03497 if (iaxs[callno]->reg) { 03498 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 03499 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 03500 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 03501 } 03502 iax2_destroy(callno); 03503 } 03504 } 03505 03506 } 03507 freeme = 1; 03508 } else { 03509 /* Update it if it needs it */ 03510 update_packet(f); 03511 /* Attempt transmission */ 03512 send_packet(f); 03513 f->retries++; 03514 /* Try again later after 10 times as long */ 03515 f->retrytime *= 10; 03516 if (f->retrytime > MAX_RETRY_TIME) 03517 f->retrytime = MAX_RETRY_TIME; 03518 /* Transfer messages max out at one second */ 03519 if (f->transfer && (f->retrytime > 1000)) 03520 f->retrytime = 1000; 03521 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 03522 } 03523 } else { 03524 /* Make sure it gets freed */ 03525 f->retries = -1; 03526 freeme = 1; 03527 } 03528 03529 if (freeme) { 03530 /* Don't attempt delivery, just remove it from the queue */ 03531 AST_LIST_REMOVE(&frame_queue[callno], f, list); 03532 ast_mutex_unlock(&iaxsl[callno]); 03533 f->retrans = -1; /* this is safe because this is the scheduled function */ 03534 /* Free the IAX frame */ 03535 iax2_frame_free(f); 03536 } else if (callno) { 03537 ast_mutex_unlock(&iaxsl[callno]); 03538 } 03539 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 8941 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().
08942 { 08943 /* Called from IAX thread only, without iaxs lock */ 08944 int callno = (int)(long)(nothing); 08945 struct iax_ie_data ied; 08946 ast_mutex_lock(&iaxsl[callno]); 08947 if (iaxs[callno]) { 08948 memset(&ied, 0, sizeof(ied)); 08949 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 08950 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 08951 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 08952 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 08953 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 08954 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08955 } 08956 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 08957 } 08958 ast_mutex_unlock(&iaxsl[callno]); 08959 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 4635 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().
04636 { 04637 int callno = PTR_TO_CALLNO(nothing); 04638 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } }; 04639 ast_mutex_lock(&iaxsl[callno]); 04640 if (iaxs[callno]) { 04641 iaxs[callno]->initid = -1; 04642 iax2_queue_frame(callno, &f); 04643 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 04644 } 04645 ast_mutex_unlock(&iaxsl[callno]); 04646 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 8990 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().
08991 { 08992 /* Called from IAX thread only, without iaxs lock */ 08993 int callno = (int)(long)(nothing); 08994 struct iax_ie_data ied; 08995 ast_mutex_lock(&iaxsl[callno]); 08996 if (iaxs[callno]) { 08997 memset(&ied, 0, sizeof(ied)); 08998 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 08999 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 09000 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 09001 } 09002 ast_mutex_unlock(&iaxsl[callno]); 09003 }
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 3251 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().
03252 { 03253 /* Just deliver the packet by using queueing. This is called by 03254 the IAX thread with the iaxsl lock held. */ 03255 struct iax_frame *fr = data; 03256 fr->retrans = -1; 03257 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 03258 if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE)) 03259 iax2_queue_frame(fr->callno, &fr->af); 03260 /* Free our iax frame */ 03261 iax2_frame_free(fr); 03262 /* And don't run again */ 03263 return 0; 03264 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8572 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().
08573 { 08574 struct iax2_peer *peer = (struct iax2_peer *) data; 08575 08576 if (!peer) 08577 return; 08578 08579 peer->expire = -1; 08580 08581 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name); 08582 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 08583 realtime_update_peer(peer->name, &peer->addr, 0); 08584 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08585 /* modify entry in peercnts table as _not_ registered */ 08586 peercnt_modify(0, 0, &peer->addr); 08587 /* Reset the address */ 08588 memset(&peer->addr, 0, sizeof(peer->addr)); 08589 /* Reset expiry value */ 08590 peer->expiry = min_reg_expire; 08591 if (!ast_test_flag64(peer, IAX_TEMPONLY)) 08592 ast_db_del("IAX/Registry", peer->name); 08593 register_peer_exten(peer, 0); 08594 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 08595 if (iax2_regfunk) 08596 iax2_regfunk(peer->name, 0); 08597 08598 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) 08599 unlink_peer(peer); 08600 08601 peer_unref(peer); 08602 }
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 2754 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, TRUNK_CALL_START, and update_max_nontrunk().
Referenced by find_callno(), and find_callno_locked().
02755 { 02756 int res = 0; 02757 int x; 02758 /* this call is calltoken validated as long as it is either NEW_FORCE 02759 * or NEW_ALLOW_CALLTOKEN_VALIDATED */ 02760 int validated = (new > NEW_ALLOW) ? 1 : 0; 02761 char host[80]; 02762 02763 if (new <= NEW_ALLOW) { 02764 if (callno) { 02765 struct chan_iax2_pvt *pvt; 02766 struct chan_iax2_pvt tmp_pvt = { 02767 .callno = dcallno, 02768 .peercallno = callno, 02769 .transfercallno = callno, 02770 /* hack!! */ 02771 .frames_received = check_dcallno, 02772 }; 02773 02774 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 02775 /* this works for finding normal call numbers not involving transfering */ 02776 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02777 if (return_locked) { 02778 ast_mutex_lock(&iaxsl[pvt->callno]); 02779 } 02780 res = pvt->callno; 02781 ao2_ref(pvt, -1); 02782 pvt = NULL; 02783 return res; 02784 } 02785 /* this searches for transfer call numbers that might not get caught otherwise */ 02786 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr)); 02787 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer)); 02788 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02789 if (return_locked) { 02790 ast_mutex_lock(&iaxsl[pvt->callno]); 02791 } 02792 res = pvt->callno; 02793 ao2_ref(pvt, -1); 02794 pvt = NULL; 02795 return res; 02796 } 02797 } 02798 /* This will occur on the first response to a message that we initiated, 02799 * such as a PING. */ 02800 if (dcallno) { 02801 ast_mutex_lock(&iaxsl[dcallno]); 02802 } 02803 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 02804 iaxs[dcallno]->peercallno = callno; 02805 res = dcallno; 02806 store_by_peercallno(iaxs[dcallno]); 02807 if (!res || !return_locked) { 02808 ast_mutex_unlock(&iaxsl[dcallno]); 02809 } 02810 return res; 02811 } 02812 if (dcallno) { 02813 ast_mutex_unlock(&iaxsl[dcallno]); 02814 } 02815 #ifdef IAX_OLD_FIND 02816 /* If we get here, we SHOULD NOT find a call structure for this 02817 callno; if we do, it means that there is a call structure that 02818 has a peer callno but did NOT get entered into the hash table, 02819 which is bad. 02820 02821 If we find a call structure using this old, slow method, output a log 02822 message so we'll know about it. After a few months of leaving this in 02823 place, if we don't hear about people seeing these messages, we can 02824 remove this code for good. 02825 */ 02826 02827 for (x = 1; !res && x < maxnontrunkcall; x++) { 02828 ast_mutex_lock(&iaxsl[x]); 02829 if (iaxs[x]) { 02830 /* Look for an exact match */ 02831 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02832 res = x; 02833 } 02834 } 02835 if (!res || !return_locked) 02836 ast_mutex_unlock(&iaxsl[x]); 02837 } 02838 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 02839 ast_mutex_lock(&iaxsl[x]); 02840 if (iaxs[x]) { 02841 /* Look for an exact match */ 02842 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02843 res = x; 02844 } 02845 } 02846 if (!res || !return_locked) 02847 ast_mutex_unlock(&iaxsl[x]); 02848 } 02849 #endif 02850 } 02851 if (!res && (new >= NEW_ALLOW)) { 02852 struct callno_entry *callno_entry; 02853 /* It may seem odd that we look through the peer list for a name for 02854 * this *incoming* call. Well, it is weird. However, users don't 02855 * have an IP address/port number that we can match against. So, 02856 * this is just checking for a peer that has that IP/port and 02857 * assuming that we have a user of the same name. This isn't always 02858 * correct, but it will be changed if needed after authentication. */ 02859 if (!iax2_getpeername(*sin, host, sizeof(host))) 02860 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 02861 02862 if (peercnt_add(sin)) { 02863 /* This address has hit its callnumber limit. When the limit 02864 * is reached, the connection is not added to the peercnts table.*/ 02865 return 0; 02866 } 02867 02868 if (!(callno_entry = get_unused_callno(0, validated))) { 02869 /* since we ran out of space, remove the peercnt 02870 * entry we added earlier */ 02871 peercnt_remove_by_addr(sin); 02872 ast_log(LOG_WARNING, "No more space\n"); 02873 return 0; 02874 } 02875 x = callno_entry->callno; 02876 ast_mutex_lock(&iaxsl[x]); 02877 02878 iaxs[x] = new_iax(sin, host); 02879 update_max_nontrunk(); 02880 if (iaxs[x]) { 02881 if (iaxdebug) 02882 ast_debug(1, "Creating new call structure %d\n", x); 02883 iaxs[x]->callno_entry = callno_entry; 02884 iaxs[x]->sockfd = sockfd; 02885 iaxs[x]->addr.sin_port = sin->sin_port; 02886 iaxs[x]->addr.sin_family = sin->sin_family; 02887 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 02888 iaxs[x]->peercallno = callno; 02889 iaxs[x]->callno = x; 02890 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 02891 iaxs[x]->expiry = min_reg_expire; 02892 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 02893 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 02894 iaxs[x]->amaflags = amaflags; 02895 ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 02896 ast_string_field_set(iaxs[x], accountcode, accountcode); 02897 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 02898 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 02899 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot); 02900 02901 if (iaxs[x]->peercallno) { 02902 store_by_peercallno(iaxs[x]); 02903 } 02904 } else { 02905 ast_log(LOG_WARNING, "Out of resources\n"); 02906 ast_mutex_unlock(&iaxsl[x]); 02907 replace_callno(callno_entry); 02908 return 0; 02909 } 02910 if (!return_locked) 02911 ast_mutex_unlock(&iaxsl[x]); 02912 res = x; 02913 } 02914 return res; 02915 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 4042 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().
04043 { 04044 int callno = PTR_TO_CALLNO(p); 04045 struct chan_iax2_pvt *pvt = NULL; 04046 struct iax_frame *fr; 04047 jb_frame frame; 04048 int ret; 04049 long ms; 04050 long next; 04051 struct timeval now = ast_tvnow(); 04052 04053 /* Make sure we have a valid private structure before going on */ 04054 ast_mutex_lock(&iaxsl[callno]); 04055 pvt = iaxs[callno]; 04056 if (!pvt) { 04057 /* No go! */ 04058 ast_mutex_unlock(&iaxsl[callno]); 04059 return; 04060 } 04061 04062 pvt->jbid = -1; 04063 04064 /* round up a millisecond since ast_sched_runq does; */ 04065 /* prevents us from spinning while waiting for our now */ 04066 /* to catch up with runq's now */ 04067 now.tv_usec += 1000; 04068 04069 ms = ast_tvdiff_ms(now, pvt->rxcore); 04070 04071 if(ms >= (next = jb_next(pvt->jb))) { 04072 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat)); 04073 switch(ret) { 04074 case JB_OK: 04075 fr = frame.data; 04076 __do_deliver(fr); 04077 /* __do_deliver() can cause the call to disappear */ 04078 pvt = iaxs[callno]; 04079 break; 04080 case JB_INTERP: 04081 { 04082 struct ast_frame af = { 0, }; 04083 04084 /* create an interpolation frame */ 04085 af.frametype = AST_FRAME_VOICE; 04086 af.subclass.codec = pvt->voiceformat; 04087 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000); 04088 af.src = "IAX2 JB interpolation"; 04089 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 04090 af.offset = AST_FRIENDLY_OFFSET; 04091 04092 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 04093 * which we'd need to malloc, and then it would free it. That seems like a drag */ 04094 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) { 04095 iax2_queue_frame(callno, &af); 04096 /* iax2_queue_frame() could cause the call to disappear */ 04097 pvt = iaxs[callno]; 04098 } 04099 } 04100 break; 04101 case JB_DROP: 04102 iax2_frame_free(frame.data); 04103 break; 04104 case JB_NOFRAME: 04105 case JB_EMPTY: 04106 /* do nothing */ 04107 break; 04108 default: 04109 /* shouldn't happen */ 04110 break; 04111 } 04112 } 04113 if (pvt) 04114 update_jbsched(pvt); 04115 ast_mutex_unlock(&iaxsl[callno]); 04116 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8248 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
08249 { 08250 struct iax2_registry *reg = (struct iax2_registry *)data; 08251 reg->expire = -1; 08252 iax2_do_register(reg); 08253 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 11874 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().
11875 { 11876 struct iax2_peer *peer = (struct iax2_peer *)data; 11877 int callno; 11878 11879 if (peer->lastms > -1) { 11880 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 11881 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 11882 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 11883 } 11884 if ((callno = peer->callno) > 0) { 11885 ast_mutex_lock(&iaxsl[callno]); 11886 iax2_destroy(callno); 11887 ast_mutex_unlock(&iaxsl[callno]); 11888 } 11889 peer->callno = 0; 11890 peer->lastms = -1; 11891 /* Try again quickly */ 11892 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 11893 if (peer->pokeexpire == -1) 11894 peer_unref(peer); 11895 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9050 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
09051 { 09052 struct iax2_peer *peer = (struct iax2_peer *)data; 09053 iax2_poke_peer(peer, 0); 09054 peer_unref(peer); 09055 }
static int __iax2_show_peers | ( | int | fd, | |
int * | total, | |||
struct mansession * | s, | |||
const int | argc, | |||
const char *const | argv[] | |||
) | [static] |
Definition at line 6613 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().
06614 { 06615 regex_t regexbuf; 06616 int havepattern = 0; 06617 int total_peers = 0; 06618 int online_peers = 0; 06619 int offline_peers = 0; 06620 int unmonitored_peers = 0; 06621 struct ao2_iterator i; 06622 06623 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n" 06624 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n" 06625 06626 struct iax2_peer *peer = NULL; 06627 char name[256]; 06628 struct ast_str *encmethods = ast_str_alloca(256); 06629 int registeredonly=0; 06630 char idtext[256] = ""; 06631 switch (argc) { 06632 case 6: 06633 if (!strcasecmp(argv[3], "registered")) 06634 registeredonly = 1; 06635 else 06636 return RESULT_SHOWUSAGE; 06637 if (!strcasecmp(argv[4], "like")) { 06638 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 06639 return RESULT_SHOWUSAGE; 06640 havepattern = 1; 06641 } else 06642 return RESULT_SHOWUSAGE; 06643 break; 06644 case 5: 06645 if (!strcasecmp(argv[3], "like")) { 06646 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 06647 return RESULT_SHOWUSAGE; 06648 havepattern = 1; 06649 } else 06650 return RESULT_SHOWUSAGE; 06651 break; 06652 case 4: 06653 if (!strcasecmp(argv[3], "registered")) 06654 registeredonly = 1; 06655 else 06656 return RESULT_SHOWUSAGE; 06657 break; 06658 case 3: 06659 break; 06660 default: 06661 return RESULT_SHOWUSAGE; 06662 } 06663 06664 06665 if (!s) 06666 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status"); 06667 06668 i = ao2_iterator_init(peers, 0); 06669 for (peer = ao2_iterator_next(&i); peer; 06670 peer_unref(peer), peer = ao2_iterator_next(&i)) { 06671 char nm[20]; 06672 char status[20]; 06673 int retstatus; 06674 struct sockaddr_in peer_addr; 06675 06676 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 06677 06678 if (registeredonly && !peer_addr.sin_addr.s_addr) { 06679 continue; 06680 } 06681 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) { 06682 continue; 06683 } 06684 06685 if (!ast_strlen_zero(peer->username)) 06686 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 06687 else 06688 ast_copy_string(name, peer->name, sizeof(name)); 06689 06690 encmethods_to_str(peer->encmethods, encmethods); 06691 retstatus = peer_status(peer, status, sizeof(status)); 06692 if (retstatus > 0) 06693 online_peers++; 06694 else if (!retstatus) 06695 offline_peers++; 06696 else 06697 unmonitored_peers++; 06698 06699 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 06700 06701 if (s) { 06702 astman_append(s, 06703 "Event: PeerEntry\r\n%s" 06704 "Channeltype: IAX2\r\n" 06705 "ObjectName: %s\r\n" 06706 "ChanObjectType: peer\r\n" 06707 "IPaddress: %s\r\n" 06708 "IPport: %d\r\n" 06709 "Dynamic: %s\r\n" 06710 "Trunk: %s\r\n" 06711 "Encryption: %s\r\n" 06712 "Status: %s\r\n\r\n", 06713 idtext, 06714 name, 06715 ast_sockaddr_stringify_addr(&peer->addr), 06716 ast_sockaddr_port(&peer->addr), 06717 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no", 06718 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no", 06719 peer->encmethods ? ast_str_buffer(encmethods) : "no", 06720 status); 06721 } else { 06722 ast_cli(fd, FORMAT, name, 06723 ast_sockaddr_stringify_addr(&peer->addr), 06724 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 06725 nm, 06726 ast_sockaddr_port(&peer->addr), 06727 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ", 06728 peer->encmethods ? "(E)" : " ", 06729 status); 06730 } 06731 total_peers++; 06732 } 06733 ao2_iterator_destroy(&i); 06734 06735 if (!s) 06736 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n", 06737 total_peers, online_peers, offline_peers, unmonitored_peers); 06738 06739 if (havepattern) 06740 regfree(®exbuf); 06741 06742 if (total) 06743 *total = total_peers; 06744 06745 return RESULT_SUCCESS; 06746 #undef FORMAT 06747 #undef FORMAT2 06748 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 14708 of file chan_iax2.c.
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 1462 of file chan_iax2.c.
References ast_copy_string(), ast_debug, find_idle_thread(), IAX_IOSTATE_SCHEDREADY, signal_condition(), and thread.
01463 { 01464 struct iax2_thread *thread = NULL; 01465 static time_t lasterror; 01466 static time_t t; 01467 01468 thread = find_idle_thread(); 01469 01470 if (thread != NULL) { 01471 thread->schedfunc = func; 01472 thread->scheddata = data; 01473 thread->iostate = IAX_IOSTATE_SCHEDREADY; 01474 #ifdef DEBUG_SCHED_MULTITHREAD 01475 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 01476 #endif 01477 signal_condition(&thread->lock, &thread->cond); 01478 return 0; 01479 } 01480 time(&t); 01481 if (t != lasterror) 01482 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n"); 01483 lasterror = t; 01484 01485 return -1; 01486 }
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 7440 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().
07442 { 07443 struct ast_frame f = { 0, }; 07444 int res = 0; 07445 07446 f.frametype = type; 07447 f.subclass.integer = command; 07448 f.datalen = datalen; 07449 f.src = __FUNCTION__; 07450 f.data.ptr = (void *) data; 07451 07452 if ((res = queue_signalling(i, &f)) <= 0) { 07453 return res; 07454 } 07455 07456 return iax2_send(i, &f, ts, seqno, now, transfer, final); 07457 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1573 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().
01574 { 01575 int callno = (long) data; 01576 01577 ast_mutex_lock(&iaxsl[callno]); 01578 01579 if (iaxs[callno]) { 01580 if (iaxs[callno]->peercallno) { 01581 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01582 if (iaxs[callno]->lagid != DONT_RESCHEDULE) { 01583 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01584 } 01585 } 01586 } else { 01587 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno); 01588 } 01589 01590 ast_mutex_unlock(&iaxsl[callno]); 01591 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1506 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().
01507 { 01508 int callno = (long) data; 01509 01510 ast_mutex_lock(&iaxsl[callno]); 01511 01512 if (iaxs[callno]) { 01513 if (iaxs[callno]->peercallno) { 01514 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01515 if (iaxs[callno]->pingid != DONT_RESCHEDULE) { 01516 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01517 } 01518 } 01519 } else { 01520 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno); 01521 } 01522 01523 ast_mutex_unlock(&iaxsl[callno]); 01524 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 14208 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, papp, peercnts, peers, reload_firmware(), sched, timer, and users.
14209 { 14210 struct ast_context *con; 14211 int x; 14212 14213 network_change_event_unsubscribe(); 14214 14215 ast_manager_unregister("IAXpeers"); 14216 ast_manager_unregister("IAXpeerlist"); 14217 ast_manager_unregister("IAXnetstats"); 14218 ast_manager_unregister("IAXregistry"); 14219 ast_unregister_application(papp); 14220 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14221 ast_unregister_switch(&iax2_switch); 14222 ast_channel_unregister(&iax2_tech); 14223 14224 if (netthreadid != AST_PTHREADT_NULL) { 14225 pthread_cancel(netthreadid); 14226 pthread_kill(netthreadid, SIGURG); 14227 pthread_join(netthreadid, NULL); 14228 } 14229 14230 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14231 if (iaxs[x]) { 14232 iax2_destroy(x); 14233 } 14234 } 14235 14236 /* Call for all threads to halt */ 14237 cleanup_thread_list(&idle_list); 14238 cleanup_thread_list(&active_list); 14239 cleanup_thread_list(&dynamic_list); 14240 14241 ast_netsock_release(netsock); 14242 ast_netsock_release(outsock); 14243 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14244 if (iaxs[x]) { 14245 iax2_destroy(x); 14246 } 14247 } 14248 ast_manager_unregister( "IAXpeers" ); 14249 ast_manager_unregister( "IAXpeerlist" ); 14250 ast_manager_unregister( "IAXnetstats" ); 14251 ast_manager_unregister( "IAXregistry" ); 14252 ast_unregister_application(papp); 14253 #ifdef TEST_FRAMEWORK 14254 AST_TEST_UNREGISTER(test_iax2_peers_get); 14255 AST_TEST_UNREGISTER(test_iax2_users_get); 14256 #endif 14257 ast_data_unregister(NULL); 14258 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14259 ast_unregister_switch(&iax2_switch); 14260 ast_channel_unregister(&iax2_tech); 14261 delete_users(); 14262 iax_provision_unload(); 14263 reload_firmware(1); 14264 14265 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14266 ast_mutex_destroy(&iaxsl[x]); 14267 } 14268 14269 ao2_ref(peers, -1); 14270 ao2_ref(users, -1); 14271 ao2_ref(iax_peercallno_pvts, -1); 14272 ao2_ref(iax_transfercallno_pvts, -1); 14273 ao2_ref(peercnts, -1); 14274 ao2_ref(callno_limits, -1); 14275 ao2_ref(calltoken_ignores, -1); 14276 ao2_ref(callno_pool, -1); 14277 ao2_ref(callno_pool_trunk, -1); 14278 if (timer) { 14279 ast_timer_close(timer); 14280 } 14281 transmit_processor = ast_taskprocessor_unreference(transmit_processor); 14282 sched = ast_sched_thread_destroy(sched); 14283 14284 con = ast_context_find(regcontext); 14285 if (con) 14286 ast_context_destroy(con, "IAX2"); 14287 ast_unload_realtime("iaxpeers"); 14288 return 0; 14289 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 14708 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 13848 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.
13849 { 13850 struct chan_iax2_pvt *pvt; 13851 unsigned int callno; 13852 int res = 0; 13853 13854 if (!chan || chan->tech != &iax2_tech) { 13855 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n"); 13856 return -1; 13857 } 13858 13859 callno = PTR_TO_CALLNO(chan->tech_pvt); 13860 ast_mutex_lock(&iaxsl[callno]); 13861 if (!(pvt = iaxs[callno])) { 13862 ast_mutex_unlock(&iaxsl[callno]); 13863 return -1; 13864 } 13865 13866 if (!strcasecmp(args, "osptoken")) { 13867 ast_copy_string(buf, pvt->osptoken, buflen); 13868 } else if (!strcasecmp(args, "peerip")) { 13869 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen); 13870 } else if (!strcasecmp(args, "peername")) { 13871 ast_copy_string(buf, pvt->username, buflen); 13872 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) { 13873 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : ""); 13874 } else { 13875 res = -1; 13876 } 13877 13878 ast_mutex_unlock(&iaxsl[callno]); 13879 13880 return res; 13881 }
static int acf_iaxvar_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 9718 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.
09719 { 09720 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09721 AST_LIST_HEAD(, ast_var_t) *varlist; 09722 struct ast_var_t *var; 09723 09724 if (!variablestore) { 09725 *buf = '\0'; 09726 return 0; 09727 } 09728 varlist = variablestore->data; 09729 09730 AST_LIST_LOCK(varlist); 09731 AST_LIST_TRAVERSE(varlist, var, entries) { 09732 if (strcmp(var->name, data) == 0) { 09733 ast_copy_string(buf, var->value, len); 09734 break; 09735 } 09736 } 09737 AST_LIST_UNLOCK(varlist); 09738 return 0; 09739 }
static int acf_iaxvar_write | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
const char * | value | |||
) | [static] |
Definition at line 9741 of file chan_iax2.c.
References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc, 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.
09742 { 09743 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09744 AST_LIST_HEAD(, ast_var_t) *varlist; 09745 struct ast_var_t *var; 09746 09747 if (!variablestore) { 09748 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 09749 if (!variablestore) { 09750 ast_log(LOG_ERROR, "Memory allocation error\n"); 09751 return -1; 09752 } 09753 varlist = ast_calloc(1, sizeof(*varlist)); 09754 if (!varlist) { 09755 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09756 return -1; 09757 } 09758 09759 AST_LIST_HEAD_INIT(varlist); 09760 variablestore->data = varlist; 09761 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 09762 ast_channel_datastore_add(chan, variablestore); 09763 } else 09764 varlist = variablestore->data; 09765 09766 AST_LIST_LOCK(varlist); 09767 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) { 09768 if (strcmp(var->name, data) == 0) { 09769 AST_LIST_REMOVE_CURRENT(entries); 09770 ast_var_delete(var); 09771 break; 09772 } 09773 } 09774 AST_LIST_TRAVERSE_SAFE_END; 09775 var = ast_var_assign(data, value); 09776 if (var) 09777 AST_LIST_INSERT_TAIL(varlist, var, entries); 09778 else 09779 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09780 AST_LIST_UNLOCK(varlist); 09781 return 0; 09782 }
static int add_calltoken_ignore | ( | const char * | addr | ) | [static] |
Definition at line 2496 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().
02497 { 02498 struct addr_range tmp; 02499 struct addr_range *addr_range = NULL; 02500 struct ast_ha *ha = NULL; 02501 int error = 0; 02502 02503 if (ast_strlen_zero(addr)) { 02504 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr); 02505 return -1; 02506 } 02507 02508 ha = ast_append_ha("permit", addr, NULL, &error); 02509 02510 /* check for valid config information */ 02511 if (error) { 02512 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr); 02513 return -1; 02514 } 02515 02516 ast_copy_ha(ha, &tmp.ha); 02517 /* find or create the addr_range */ 02518 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) { 02519 ao2_lock(addr_range); 02520 addr_range->delme = 0; 02521 ao2_unlock(addr_range); 02522 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02523 /* copy over config data into addr_range object */ 02524 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */ 02525 ao2_link(calltoken_ignores, addr_range); 02526 } else { 02527 ast_free_ha(ha); 02528 return -1; 02529 } 02530 02531 ast_free_ha(ha); 02532 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02533 02534 return 0; 02535 }
static void add_empty_calltoken_ie | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | ied | |||
) | [static] |
Definition at line 4709 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().
04710 { 04711 /* first make sure their are two empty bytes left in ied->buf */ 04712 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) { 04713 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */ 04714 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */ 04715 pvt->calltoken_ie_len = 2; 04716 } 04717 }
static int addr_range_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2148 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().
02149 { 02150 struct addr_range *lim1 = obj, *lim2 = arg; 02151 return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) && 02152 !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ? 02153 CMP_MATCH | CMP_STOP : 0; 02154 }
static int addr_range_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2133 of file chan_iax2.c.
References addr_range::delme.
Referenced by set_config_destroy().
02134 { 02135 struct addr_range *lim = obj; 02136 lim->delme = 1; 02137 return 0; 02138 }
static int addr_range_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 2140 of file chan_iax2.c.
References ast_ha::addr, ast_sockaddr_to_sin, and addr_range::ha.
Referenced by load_objects().
02141 { 02142 const struct addr_range *lim = obj; 02143 struct sockaddr_in sin; 02144 ast_sockaddr_to_sin(&lim->ha.addr, &sin); 02145 return abs((int) sin.sin_addr.s_addr); 02146 }
static int addr_range_match_address_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2168 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().
02169 { 02170 struct addr_range *addr_range = obj; 02171 struct sockaddr_in *sin = arg; 02172 struct sockaddr_in ha_netmask_sin; 02173 struct sockaddr_in ha_addr_sin; 02174 02175 ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin); 02176 ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin); 02177 02178 if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) { 02179 return CMP_MATCH | CMP_STOP; 02180 } 02181 return 0; 02182 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 7498 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
07499 { 07500 while(con) { 07501 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 07502 return -1; 07503 con = con->next; 07504 } 07505 return 0; 07506 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 7199 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().
07200 { 07201 int x; 07202 int numchans = 0; 07203 char first_message[10] = { 0, }; 07204 char last_message[10] = { 0, }; 07205 #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" 07206 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" 07207 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07208 ast_mutex_lock(&iaxsl[x]); 07209 if (iaxs[x]) { 07210 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 07211 jb_info jbinfo; 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 07215 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07216 jb_getinfo(iaxs[x]->jb, &jbinfo); 07217 localjitter = jbinfo.jitter; 07218 localdelay = jbinfo.current - jbinfo.min; 07219 locallost = jbinfo.frames_lost; 07220 locallosspct = jbinfo.losspct/1000; 07221 localdropped = jbinfo.frames_dropped; 07222 localooo = jbinfo.frames_ooo; 07223 } else { 07224 localjitter = -1; 07225 localdelay = 0; 07226 locallost = -1; 07227 locallosspct = -1; 07228 localdropped = 0; 07229 localooo = -1; 07230 } 07231 if (s) 07232 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07233 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07234 iaxs[x]->pingtime, 07235 localjitter, 07236 localdelay, 07237 locallost, 07238 locallosspct, 07239 localdropped, 07240 localooo, 07241 iaxs[x]->frames_received/1000, 07242 iaxs[x]->remote_rr.jitter, 07243 iaxs[x]->remote_rr.delay, 07244 iaxs[x]->remote_rr.losscnt, 07245 iaxs[x]->remote_rr.losspct, 07246 iaxs[x]->remote_rr.dropped, 07247 iaxs[x]->remote_rr.ooo, 07248 iaxs[x]->remote_rr.packets/1000, 07249 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07250 first_message, 07251 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07252 last_message); 07253 else 07254 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07255 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07256 iaxs[x]->pingtime, 07257 localjitter, 07258 localdelay, 07259 locallost, 07260 locallosspct, 07261 localdropped, 07262 localooo, 07263 iaxs[x]->frames_received/1000, 07264 iaxs[x]->remote_rr.jitter, 07265 iaxs[x]->remote_rr.delay, 07266 iaxs[x]->remote_rr.losscnt, 07267 iaxs[x]->remote_rr.losspct, 07268 iaxs[x]->remote_rr.dropped, 07269 iaxs[x]->remote_rr.ooo, 07270 iaxs[x]->remote_rr.packets/1000, 07271 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07272 first_message, 07273 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07274 last_message); 07275 numchans++; 07276 } 07277 ast_mutex_unlock(&iaxsl[x]); 07278 } 07279 07280 return numchans; 07281 }
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 5692 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().
05693 { 05694 struct ast_channel *tmp; 05695 struct chan_iax2_pvt *i; 05696 struct ast_variable *v = NULL; 05697 05698 if (!(i = iaxs[callno])) { 05699 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 05700 return NULL; 05701 } 05702 05703 /* Don't hold call lock */ 05704 ast_mutex_unlock(&iaxsl[callno]); 05705 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); 05706 ast_mutex_lock(&iaxsl[callno]); 05707 if (i != iaxs[callno]) { 05708 if (tmp) { 05709 /* unlock and relock iaxsl[callno] to preserve locking order */ 05710 ast_mutex_unlock(&iaxsl[callno]); 05711 tmp = ast_channel_release(tmp); 05712 ast_mutex_lock(&iaxsl[callno]); 05713 } 05714 return NULL; 05715 } 05716 iax2_ami_channelupdate(i); 05717 if (!tmp) 05718 return NULL; 05719 tmp->tech = &iax2_tech; 05720 /* We can support any format by default, until we get restricted */ 05721 tmp->nativeformats = capability; 05722 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 05723 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 05724 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 05725 05726 if (!ast_strlen_zero(i->parkinglot)) 05727 ast_string_field_set(tmp, parkinglot, i->parkinglot); 05728 /* Don't use ast_set_callerid() here because it will 05729 * generate a NewCallerID event before the NewChannel event */ 05730 if (!ast_strlen_zero(i->ani)) { 05731 tmp->caller.ani.number.valid = 1; 05732 tmp->caller.ani.number.str = ast_strdup(i->ani); 05733 } else if (!ast_strlen_zero(i->cid_num)) { 05734 tmp->caller.ani.number.valid = 1; 05735 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 05736 } 05737 tmp->dialed.number.str = ast_strdup(i->dnid); 05738 tmp->redirecting.from.number.valid = 1; 05739 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 05740 tmp->caller.id.name.presentation = i->calling_pres; 05741 tmp->caller.id.number.presentation = i->calling_pres; 05742 tmp->caller.id.number.plan = i->calling_ton; 05743 tmp->dialed.transit_network_select = i->calling_tns; 05744 if (!ast_strlen_zero(i->language)) 05745 ast_string_field_set(tmp, language, i->language); 05746 if (!ast_strlen_zero(i->accountcode)) 05747 ast_string_field_set(tmp, accountcode, i->accountcode); 05748 if (i->amaflags) 05749 tmp->amaflags = i->amaflags; 05750 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05751 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05752 if (i->adsi) 05753 tmp->adsicpe = i->peeradsicpe; 05754 else 05755 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05756 i->owner = tmp; 05757 i->capability = capability; 05758 05759 /* Set inherited variables */ 05760 if (i->vars) { 05761 for (v = i->vars ; v ; v = v->next) 05762 pbx_builtin_setvar_helper(tmp, v->name, v->value); 05763 } 05764 if (i->iaxvars) { 05765 struct ast_datastore *variablestore; 05766 struct ast_variable *var, *prev = NULL; 05767 AST_LIST_HEAD(, ast_var_t) *varlist; 05768 ast_debug(1, "Loading up the channel with IAXVARs\n"); 05769 varlist = ast_calloc(1, sizeof(*varlist)); 05770 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 05771 if (variablestore && varlist) { 05772 variablestore->data = varlist; 05773 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 05774 AST_LIST_HEAD_INIT(varlist); 05775 for (var = i->iaxvars; var; var = var->next) { 05776 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 05777 if (prev) 05778 ast_free(prev); 05779 prev = var; 05780 if (!newvar) { 05781 /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */ 05782 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 05783 } else { 05784 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 05785 } 05786 } 05787 if (prev) 05788 ast_free(prev); 05789 i->iaxvars = NULL; 05790 ast_channel_datastore_add(i->owner, variablestore); 05791 } else { 05792 if (variablestore) { 05793 ast_datastore_free(variablestore); 05794 } 05795 if (varlist) { 05796 ast_free(varlist); 05797 } 05798 } 05799 } 05800 05801 if (state != AST_STATE_DOWN) { 05802 if (ast_pbx_start(tmp)) { 05803 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05804 ast_hangup(tmp); 05805 i->owner = NULL; 05806 return NULL; 05807 } 05808 } 05809 05810 ast_module_ref(ast_module_info->self); 05811 return tmp; 05812 }
static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3541 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and transmit_frame().
03542 { 03543 #ifdef SCHED_MULTITHREADED 03544 if (schedule_action(__attempt_transmit, data)) 03545 #endif 03546 __attempt_transmit(data); 03547 return 0; 03548 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 8975 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().
08976 { 08977 /* Schedule sending the authentication failure in one second, to prevent 08978 guessing */ 08979 if (iaxs[callno]) { 08980 iaxs[callno]->authfail = failcode; 08981 if (delayreject) { 08982 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 08983 sched, 1000, auth_reject, (void *)(long)callno); 08984 } else 08985 auth_reject((void *)(long)callno); 08986 } 08987 return 0; 08988 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 8961 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().
08962 { 08963 int callno = (int)(long)(data); 08964 ast_mutex_lock(&iaxsl[callno]); 08965 if (iaxs[callno]) 08966 iaxs[callno]->authid = -1; 08967 ast_mutex_unlock(&iaxsl[callno]); 08968 #ifdef SCHED_MULTITHREADED 08969 if (schedule_action(__auth_reject, data)) 08970 #endif 08971 __auth_reject(data); 08972 return 0; 08973 }
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 8070 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().
08071 { 08072 int res = -1; 08073 int x; 08074 if (!ast_strlen_zero(keyn)) { 08075 if (!(authmethods & IAX_AUTH_RSA)) { 08076 if (ast_strlen_zero(secret)) 08077 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)); 08078 } else if (ast_strlen_zero(challenge)) { 08079 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 08080 } else { 08081 char sig[256]; 08082 struct ast_key *key; 08083 key = ast_key_get(keyn, AST_KEY_PRIVATE); 08084 if (!key) { 08085 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 08086 } else { 08087 if (ast_sign(key, (char*)challenge, sig)) { 08088 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 08089 res = -1; 08090 } else { 08091 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 08092 res = 0; 08093 } 08094 } 08095 } 08096 } 08097 /* Fall back */ 08098 if (res && !ast_strlen_zero(secret)) { 08099 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 08100 struct MD5Context md5; 08101 unsigned char digest[16]; 08102 char digres[128]; 08103 MD5Init(&md5); 08104 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 08105 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 08106 MD5Final(digest, &md5); 08107 /* If they support md5, authenticate with it. */ 08108 for (x=0;x<16;x++) 08109 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 08110 if (pvt) { 08111 build_encryption_keys(digest, pvt); 08112 } 08113 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 08114 res = 0; 08115 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 08116 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 08117 res = 0; 08118 } else 08119 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 08120 } 08121 return res; 08122 }
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 8128 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().
08129 { 08130 struct iax2_peer *peer = NULL; 08131 /* Start pessimistic */ 08132 int res = -1; 08133 int authmethods = 0; 08134 struct iax_ie_data ied; 08135 uint16_t callno = p->callno; 08136 08137 memset(&ied, 0, sizeof(ied)); 08138 08139 if (ies->username) 08140 ast_string_field_set(p, username, ies->username); 08141 if (ies->challenge) 08142 ast_string_field_set(p, challenge, ies->challenge); 08143 if (ies->authmethods) 08144 authmethods = ies->authmethods; 08145 if (authmethods & IAX_AUTH_MD5) 08146 merge_encryption(p, ies->encmethods); 08147 else 08148 p->encmethods = 0; 08149 08150 /* Check for override RSA authentication first */ 08151 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 08152 /* Normal password authentication */ 08153 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 08154 } else { 08155 struct ao2_iterator i = ao2_iterator_init(peers, 0); 08156 while ((peer = ao2_iterator_next(&i))) { 08157 struct sockaddr_in peer_addr; 08158 08159 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 08160 08161 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 08162 /* No peer specified at our end, or this is the peer */ 08163 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 08164 /* No username specified in peer rule, or this is the right username */ 08165 && (!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))) 08166 /* No specified host, or this is our host */ 08167 ) { 08168 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 08169 if (!res) { 08170 peer_unref(peer); 08171 break; 08172 } 08173 } 08174 peer_unref(peer); 08175 } 08176 ao2_iterator_destroy(&i); 08177 if (!peer) { 08178 /* We checked our list and didn't find one. It's unlikely, but possible, 08179 that we're trying to authenticate *to* a realtime peer */ 08180 const char *peer_name = ast_strdupa(p->peer); 08181 ast_mutex_unlock(&iaxsl[callno]); 08182 if ((peer = realtime_peer(peer_name, NULL))) { 08183 ast_mutex_lock(&iaxsl[callno]); 08184 if (!(p = iaxs[callno])) { 08185 peer_unref(peer); 08186 return -1; 08187 } 08188 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 08189 peer_unref(peer); 08190 } 08191 if (!peer) { 08192 ast_mutex_lock(&iaxsl[callno]); 08193 if (!(p = iaxs[callno])) 08194 return -1; 08195 } 08196 } 08197 } 08198 08199 if (ies->encmethods) { 08200 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 08201 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 08202 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set"); 08203 return -1; /* if force encryption is yes, and no encryption methods, then return -1 to hangup */ 08204 } 08205 if (!res) { 08206 struct ast_datastore *variablestore; 08207 struct ast_variable *var, *prev = NULL; 08208 AST_LIST_HEAD(, ast_var_t) *varlist; 08209 varlist = ast_calloc(1, sizeof(*varlist)); 08210 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 08211 if (variablestore && varlist && p->owner) { 08212 variablestore->data = varlist; 08213 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 08214 AST_LIST_HEAD_INIT(varlist); 08215 for (var = ies->vars; var; var = var->next) { 08216 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 08217 if (prev) 08218 ast_free(prev); 08219 prev = var; 08220 if (!newvar) { 08221 /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */ 08222 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08223 } else { 08224 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 08225 } 08226 } 08227 if (prev) 08228 ast_free(prev); 08229 ies->vars = NULL; 08230 ast_channel_datastore_add(p->owner, variablestore); 08231 } else { 08232 if (p->owner) 08233 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08234 if (variablestore) 08235 ast_datastore_free(variablestore); 08236 if (varlist) 08237 ast_free(varlist); 08238 } 08239 } 08240 08241 if (!res) 08242 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 08243 return res; 08244 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 7776 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().
07777 { 07778 struct iax_ie_data ied; 07779 int res = -1, authreq_restrict = 0; 07780 char challenge[10]; 07781 struct chan_iax2_pvt *p = iaxs[call_num]; 07782 07783 memset(&ied, 0, sizeof(ied)); 07784 07785 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 07786 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07787 struct iax2_user *user, tmp_user = { 07788 .name = p->username, 07789 }; 07790 07791 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07792 if (user) { 07793 if (user->curauthreq == user->maxauthreq) 07794 authreq_restrict = 1; 07795 else 07796 user->curauthreq++; 07797 user = user_unref(user); 07798 } 07799 } 07800 07801 /* If the AUTHREQ limit test failed, send back an error */ 07802 if (authreq_restrict) { 07803 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 07804 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 07805 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 07806 return 0; 07807 } 07808 07809 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 07810 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 07811 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 07812 ast_string_field_set(p, challenge, challenge); 07813 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 07814 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 07815 } 07816 if (p->encmethods) 07817 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 07818 07819 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 07820 07821 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 07822 07823 if (p->encmethods) 07824 ast_set_flag64(p, IAX_ENCRYPTED); 07825 07826 return res; 07827 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7829 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().
07830 { 07831 char requeststr[256]; 07832 char md5secret[256] = ""; 07833 char secret[256] = ""; 07834 char rsasecret[256] = ""; 07835 int res = -1; 07836 int x; 07837 struct iax2_user *user, tmp_user = { 07838 .name = p->username, 07839 }; 07840 07841 if (p->authrej) { 07842 return res; 07843 } 07844 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07845 if (user) { 07846 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07847 ast_atomic_fetchadd_int(&user->curauthreq, -1); 07848 ast_clear_flag64(p, IAX_MAXAUTHREQ); 07849 } 07850 ast_string_field_set(p, host, user->name); 07851 user = user_unref(user); 07852 } 07853 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) { 07854 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled."); 07855 return res; 07856 } 07857 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 07858 return res; 07859 if (ies->password) 07860 ast_copy_string(secret, ies->password, sizeof(secret)); 07861 if (ies->md5_result) 07862 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07863 if (ies->rsa_result) 07864 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07865 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 07866 struct ast_key *key; 07867 char *keyn; 07868 char tmpkey[256]; 07869 char *stringp=NULL; 07870 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 07871 stringp=tmpkey; 07872 keyn = strsep(&stringp, ":"); 07873 while(keyn) { 07874 key = ast_key_get(keyn, AST_KEY_PUBLIC); 07875 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 07876 res = 0; 07877 break; 07878 } else if (!key) 07879 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 07880 keyn = strsep(&stringp, ":"); 07881 } 07882 } else if (p->authmethods & IAX_AUTH_MD5) { 07883 struct MD5Context md5; 07884 unsigned char digest[16]; 07885 char *tmppw, *stringp; 07886 07887 tmppw = ast_strdupa(p->secret); 07888 stringp = tmppw; 07889 while((tmppw = strsep(&stringp, ";"))) { 07890 MD5Init(&md5); 07891 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 07892 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 07893 MD5Final(digest, &md5); 07894 /* If they support md5, authenticate with it. */ 07895 for (x=0;x<16;x++) 07896 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 07897 if (!strcasecmp(requeststr, md5secret)) { 07898 res = 0; 07899 break; 07900 } 07901 } 07902 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 07903 if (!strcmp(secret, p->secret)) 07904 res = 0; 07905 } 07906 return res; 07907 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 4648 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), sip_call(), and sip_show_sched().
04649 { 04650 #ifdef SCHED_MULTITHREADED 04651 if (schedule_action(__auto_congest, data)) 04652 #endif 04653 __auto_congest(data); 04654 return 0; 04655 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 9005 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().
09006 { 09007 int callno = (int)(long)(data); 09008 ast_mutex_lock(&iaxsl[callno]); 09009 if (iaxs[callno]) { 09010 iaxs[callno]->autoid = -1; 09011 } 09012 ast_mutex_unlock(&iaxsl[callno]); 09013 #ifdef SCHED_MULTITHREADED 09014 if (schedule_action(__auto_hangup, data)) 09015 #endif 09016 __auto_hangup(data); 09017 return 0; 09018 }
static void build_callno_limits | ( | struct ast_variable * | v | ) | [static] |
Definition at line 2441 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().
02442 { 02443 struct addr_range *addr_range = NULL; 02444 struct addr_range tmp; 02445 struct ast_ha *ha; 02446 int limit; 02447 int error; 02448 int found; 02449 02450 for (; v; v = v->next) { 02451 limit = -1; 02452 error = 0; 02453 found = 0; 02454 ha = ast_append_ha("permit", v->name, NULL, &error); 02455 02456 /* check for valid config information */ 02457 if (error) { 02458 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name); 02459 continue; 02460 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) { 02461 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value); 02462 ast_free_ha(ha); 02463 continue; 02464 } 02465 02466 ast_copy_ha(ha, &tmp.ha); 02467 /* find or create the addr_range */ 02468 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) { 02469 ao2_lock(addr_range); 02470 found = 1; 02471 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02472 ast_free_ha(ha); 02473 return; /* out of memory */ 02474 } 02475 02476 /* copy over config data into addr_range object */ 02477 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */ 02478 ast_free_ha(ha); /* cleanup the tmp ha */ 02479 addr_range->limit = limit; 02480 addr_range->delme = 0; 02481 02482 /* cleanup */ 02483 if (found) { 02484 ao2_unlock(addr_range); 02485 } else { 02486 ao2_link(callno_limits, addr_range); 02487 } 02488 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02489 } 02490 }
static struct iax2_context* build_context | ( | const char * | context | ) | [static] |
Definition at line 12128 of file chan_iax2.c.
References ast_calloc, and ast_copy_string().
Referenced by build_user().
12129 { 12130 struct iax2_context *con; 12131 12132 if ((con = ast_calloc(1, sizeof(*con)))) 12133 ast_copy_string(con->context, context, sizeof(con->context)); 12134 12135 return con; 12136 }
static void build_ecx_key | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 6155 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().
06156 { 06157 /* it is required to hold the corresponding decrypt key to our encrypt key 06158 * in the pvt struct because queued frames occasionally need to be decrypted and 06159 * re-encrypted when updated for a retransmission */ 06160 build_rand_pad(pvt->semirand, sizeof(pvt->semirand)); 06161 ast_aes_set_encrypt_key(digest, &pvt->ecx); 06162 ast_aes_set_decrypt_key(digest, &pvt->mydcx); 06163 }
static void build_encryption_keys | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 6149 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().
06150 { 06151 build_ecx_key(digest, pvt); 06152 ast_aes_set_decrypt_key(digest, &pvt->dcx); 06153 }
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 12278 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, iax2_peer::dbsecret, 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(), iax2_peer::peercontext, peers, prefs, S_OR, sched, secret, strsep(), timer, unlink_peer(), ast_variable::value, and zonetag.
12279 { 12280 struct iax2_peer *peer = NULL; 12281 struct ast_ha *oldha = NULL; 12282 int maskfound = 0; 12283 int found = 0; 12284 int firstpass = 1; 12285 struct iax2_peer tmp_peer = { 12286 .name = name, 12287 }; 12288 12289 if (!temponly) { 12290 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 12291 if (peer && !ast_test_flag64(peer, IAX_DELME)) 12292 firstpass = 0; 12293 } 12294 12295 if (peer) { 12296 found++; 12297 if (firstpass) { 12298 oldha = peer->ha; 12299 peer->ha = NULL; 12300 } 12301 unlink_peer(peer); 12302 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 12303 peer->expire = -1; 12304 peer->pokeexpire = -1; 12305 peer->sockfd = defaultsockfd; 12306 if (ast_string_field_init(peer, 32)) 12307 peer = peer_unref(peer); 12308 } 12309 12310 if (peer) { 12311 if (firstpass) { 12312 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 12313 peer->encmethods = iax2_encryption; 12314 peer->adsi = adsi; 12315 ast_string_field_set(peer,secret,""); 12316 if (!found) { 12317 ast_string_field_set(peer, name, name); 12318 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12319 peer->expiry = min_reg_expire; 12320 } 12321 peer->prefs = prefs; 12322 peer->capability = iax2_capability; 12323 peer->smoothing = 0; 12324 peer->pokefreqok = DEFAULT_FREQ_OK; 12325 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 12326 peer->maxcallno = 0; 12327 peercnt_modify(0, 0, &peer->addr); 12328 peer->calltoken_required = CALLTOKEN_DEFAULT; 12329 ast_string_field_set(peer,context,""); 12330 ast_string_field_set(peer,peercontext,""); 12331 ast_clear_flag64(peer, IAX_HASCALLERID); 12332 ast_string_field_set(peer, cid_name, ""); 12333 ast_string_field_set(peer, cid_num, ""); 12334 ast_string_field_set(peer, mohinterpret, mohinterpret); 12335 ast_string_field_set(peer, mohsuggest, mohsuggest); 12336 } 12337 12338 if (!v) { 12339 v = alt; 12340 alt = NULL; 12341 } 12342 while(v) { 12343 if (!strcasecmp(v->name, "secret")) { 12344 ast_string_field_set(peer, secret, v->value); 12345 } else if (!strcasecmp(v->name, "mailbox")) { 12346 ast_string_field_set(peer, mailbox, v->value); 12347 } else if (!strcasecmp(v->name, "hasvoicemail")) { 12348 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 12349 ast_string_field_set(peer, mailbox, name); 12350 } 12351 } else if (!strcasecmp(v->name, "mohinterpret")) { 12352 ast_string_field_set(peer, mohinterpret, v->value); 12353 } else if (!strcasecmp(v->name, "mohsuggest")) { 12354 ast_string_field_set(peer, mohsuggest, v->value); 12355 } else if (!strcasecmp(v->name, "dbsecret")) { 12356 ast_string_field_set(peer, dbsecret, v->value); 12357 } else if (!strcasecmp(v->name, "trunk")) { 12358 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK); 12359 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) { 12360 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name); 12361 ast_clear_flag64(peer, IAX_TRUNK); 12362 } 12363 } else if (!strcasecmp(v->name, "auth")) { 12364 peer->authmethods = get_auth_methods(v->value); 12365 } else if (!strcasecmp(v->name, "encryption")) { 12366 peer->encmethods |= get_encrypt_methods(v->value); 12367 if (!peer->encmethods) { 12368 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12369 } 12370 } else if (!strcasecmp(v->name, "forceencryption")) { 12371 if (ast_false(v->value)) { 12372 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12373 } else { 12374 peer->encmethods |= get_encrypt_methods(v->value); 12375 if (peer->encmethods) { 12376 ast_set_flag64(peer, IAX_FORCE_ENCRYPT); 12377 } 12378 } 12379 } else if (!strcasecmp(v->name, "transfer")) { 12380 if (!strcasecmp(v->value, "mediaonly")) { 12381 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12382 } else if (ast_true(v->value)) { 12383 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12384 } else 12385 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12386 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12387 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF); 12388 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12389 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 12390 } else if (!strcasecmp(v->name, "host")) { 12391 if (!strcasecmp(v->value, "dynamic")) { 12392 /* They'll register with us */ 12393 ast_set_flag64(peer, IAX_DYNAMIC); 12394 if (!found) { 12395 /* Initialize stuff iff we're not found, otherwise 12396 we keep going with what we had */ 12397 if (ast_sockaddr_port(&peer->addr)) { 12398 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr)); 12399 } 12400 ast_sockaddr_setnull(&peer->addr); 12401 } 12402 } else { 12403 /* Non-dynamic. Make sure we become that way if we're not */ 12404 ast_sched_thread_del(sched, peer->expire); 12405 ast_clear_flag64(peer, IAX_DYNAMIC); 12406 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) 12407 return peer_unref(peer); 12408 if (!ast_sockaddr_port(&peer->addr)) { 12409 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12410 } 12411 } 12412 if (!maskfound) 12413 inet_aton("255.255.255.255", &peer->mask); 12414 } else if (!strcasecmp(v->name, "defaultip")) { 12415 struct ast_sockaddr peer_defaddr_tmp; 12416 12417 if (ast_get_ip(&peer_defaddr_tmp, v->value)) { 12418 return peer_unref(peer); 12419 } 12420 ast_sockaddr_to_sin(&peer_defaddr_tmp, 12421 &peer->defaddr); 12422 } else if (!strcasecmp(v->name, "sourceaddress")) { 12423 peer_set_srcaddr(peer, v->value); 12424 } else if (!strcasecmp(v->name, "permit") || 12425 !strcasecmp(v->name, "deny")) { 12426 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL); 12427 } else if (!strcasecmp(v->name, "mask")) { 12428 maskfound++; 12429 inet_aton(v->value, &peer->mask); 12430 } else if (!strcasecmp(v->name, "context")) { 12431 ast_string_field_set(peer, context, v->value); 12432 } else if (!strcasecmp(v->name, "regexten")) { 12433 ast_string_field_set(peer, regexten, v->value); 12434 } else if (!strcasecmp(v->name, "peercontext")) { 12435 ast_string_field_set(peer, peercontext, v->value); 12436 } else if (!strcasecmp(v->name, "port")) { 12437 if (ast_test_flag64(peer, IAX_DYNAMIC)) { 12438 peer->defaddr.sin_port = htons(atoi(v->value)); 12439 } else { 12440 ast_sockaddr_set_port(&peer->addr, atoi(v->value)); 12441 } 12442 } else if (!strcasecmp(v->name, "username")) { 12443 ast_string_field_set(peer, username, v->value); 12444 } else if (!strcasecmp(v->name, "allow")) { 12445 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 12446 } else if (!strcasecmp(v->name, "disallow")) { 12447 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 12448 } else if (!strcasecmp(v->name, "callerid")) { 12449 if (!ast_strlen_zero(v->value)) { 12450 char name2[80]; 12451 char num2[80]; 12452 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12453 ast_string_field_set(peer, cid_name, name2); 12454 ast_string_field_set(peer, cid_num, num2); 12455 } else { 12456 ast_string_field_set(peer, cid_name, ""); 12457 ast_string_field_set(peer, cid_num, ""); 12458 } 12459 ast_set_flag64(peer, IAX_HASCALLERID); 12460 } else if (!strcasecmp(v->name, "fullname")) { 12461 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 12462 ast_set_flag64(peer, IAX_HASCALLERID); 12463 } else if (!strcasecmp(v->name, "cid_number")) { 12464 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 12465 ast_set_flag64(peer, IAX_HASCALLERID); 12466 } else if (!strcasecmp(v->name, "sendani")) { 12467 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI); 12468 } else if (!strcasecmp(v->name, "inkeys")) { 12469 ast_string_field_set(peer, inkeys, v->value); 12470 } else if (!strcasecmp(v->name, "outkey")) { 12471 ast_string_field_set(peer, outkey, v->value); 12472 } else if (!strcasecmp(v->name, "qualify")) { 12473 if (!strcasecmp(v->value, "no")) { 12474 peer->maxms = 0; 12475 } else if (!strcasecmp(v->value, "yes")) { 12476 peer->maxms = DEFAULT_MAXMS; 12477 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 12478 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); 12479 peer->maxms = 0; 12480 } 12481 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 12482 peer->smoothing = ast_true(v->value); 12483 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 12484 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) { 12485 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); 12486 } 12487 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 12488 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) { 12489 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); 12490 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 12491 } else if (!strcasecmp(v->name, "timezone")) { 12492 ast_string_field_set(peer, zonetag, v->value); 12493 } else if (!strcasecmp(v->name, "adsi")) { 12494 peer->adsi = ast_true(v->value); 12495 } else if (!strcasecmp(v->name, "connectedline")) { 12496 if (ast_true(v->value)) { 12497 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12498 } else if (!strcasecmp(v->value, "send")) { 12499 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE); 12500 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE); 12501 } else if (!strcasecmp(v->value, "receive")) { 12502 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE); 12503 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE); 12504 } else { 12505 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12506 } 12507 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 12508 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) { 12509 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 12510 } else { 12511 peercnt_modify(1, peer->maxcallno, &peer->addr); 12512 } 12513 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12514 /* default is required unless in optional ip list */ 12515 if (ast_false(v->value)) { 12516 peer->calltoken_required = CALLTOKEN_NO; 12517 } else if (!strcasecmp(v->value, "auto")) { 12518 peer->calltoken_required = CALLTOKEN_AUTO; 12519 } else if (ast_true(v->value)) { 12520 peer->calltoken_required = CALLTOKEN_YES; 12521 } else { 12522 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12523 } 12524 } /* else if (strcasecmp(v->name,"type")) */ 12525 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12526 v = v->next; 12527 if (!v) { 12528 v = alt; 12529 alt = NULL; 12530 } 12531 } 12532 if (!peer->authmethods) 12533 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12534 ast_clear_flag64(peer, IAX_DELME); 12535 } 12536 12537 if (oldha) 12538 ast_free_ha(oldha); 12539 12540 if (!ast_strlen_zero(peer->mailbox)) { 12541 char *mailbox, *context; 12542 context = mailbox = ast_strdupa(peer->mailbox); 12543 strsep(&context, "@"); 12544 if (ast_strlen_zero(context)) 12545 context = "default"; 12546 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL, 12547 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 12548 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 12549 AST_EVENT_IE_END); 12550 } 12551 12552 return peer; 12553 }
static void build_rand_pad | ( | unsigned char * | buf, | |
ssize_t | len | |||
) | [static] |
Definition at line 6139 of file chan_iax2.c.
References ast_random().
Referenced by build_ecx_key(), and update_packet().
06140 { 06141 long tmp; 06142 for (tmp = ast_random(); len > 0; tmp = ast_random()) { 06143 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len); 06144 buf += sizeof(tmp); 06145 len -= sizeof(tmp); 06146 } 06147 }
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 12569 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.
12570 { 12571 struct iax2_user *user = NULL; 12572 struct iax2_context *con, *conl = NULL; 12573 struct ast_ha *oldha = NULL; 12574 struct iax2_context *oldcon = NULL; 12575 int format; 12576 int firstpass=1; 12577 int oldcurauthreq = 0; 12578 char *varname = NULL, *varval = NULL; 12579 struct ast_variable *tmpvar = NULL; 12580 struct iax2_user tmp_user = { 12581 .name = name, 12582 }; 12583 12584 if (!temponly) { 12585 user = ao2_find(users, &tmp_user, OBJ_POINTER); 12586 if (user && !ast_test_flag64(user, IAX_DELME)) 12587 firstpass = 0; 12588 } 12589 12590 if (user) { 12591 if (firstpass) { 12592 oldcurauthreq = user->curauthreq; 12593 oldha = user->ha; 12594 oldcon = user->contexts; 12595 user->ha = NULL; 12596 user->contexts = NULL; 12597 } 12598 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12599 ao2_unlink(users, user); 12600 } else { 12601 user = ao2_alloc(sizeof(*user), user_destructor); 12602 } 12603 12604 if (user) { 12605 if (firstpass) { 12606 ast_string_field_free_memory(user); 12607 memset(user, 0, sizeof(struct iax2_user)); 12608 if (ast_string_field_init(user, 32)) { 12609 user = user_unref(user); 12610 goto cleanup; 12611 } 12612 user->maxauthreq = maxauthreq; 12613 user->curauthreq = oldcurauthreq; 12614 user->prefs = prefs; 12615 user->capability = iax2_capability; 12616 user->encmethods = iax2_encryption; 12617 user->adsi = adsi; 12618 user->calltoken_required = CALLTOKEN_DEFAULT; 12619 ast_string_field_set(user, name, name); 12620 ast_string_field_set(user, language, language); 12621 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); 12622 ast_clear_flag64(user, IAX_HASCALLERID); 12623 ast_string_field_set(user, cid_name, ""); 12624 ast_string_field_set(user, cid_num, ""); 12625 ast_string_field_set(user, accountcode, accountcode); 12626 ast_string_field_set(user, mohinterpret, mohinterpret); 12627 ast_string_field_set(user, mohsuggest, mohsuggest); 12628 } 12629 if (!v) { 12630 v = alt; 12631 alt = NULL; 12632 } 12633 while(v) { 12634 if (!strcasecmp(v->name, "context")) { 12635 con = build_context(v->value); 12636 if (con) { 12637 if (conl) 12638 conl->next = con; 12639 else 12640 user->contexts = con; 12641 conl = con; 12642 } 12643 } else if (!strcasecmp(v->name, "permit") || 12644 !strcasecmp(v->name, "deny")) { 12645 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL); 12646 } else if (!strcasecmp(v->name, "setvar")) { 12647 varname = ast_strdupa(v->value); 12648 if (varname && (varval = strchr(varname,'='))) { 12649 *varval = '\0'; 12650 varval++; 12651 if((tmpvar = ast_variable_new(varname, varval, ""))) { 12652 tmpvar->next = user->vars; 12653 user->vars = tmpvar; 12654 } 12655 } 12656 } else if (!strcasecmp(v->name, "allow")) { 12657 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 12658 } else if (!strcasecmp(v->name, "disallow")) { 12659 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 12660 } else if (!strcasecmp(v->name, "trunk")) { 12661 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK); 12662 if (ast_test_flag64(user, IAX_TRUNK) && !timer) { 12663 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name); 12664 ast_clear_flag64(user, IAX_TRUNK); 12665 } 12666 } else if (!strcasecmp(v->name, "auth")) { 12667 user->authmethods = get_auth_methods(v->value); 12668 } else if (!strcasecmp(v->name, "encryption")) { 12669 user->encmethods |= get_encrypt_methods(v->value); 12670 if (!user->encmethods) { 12671 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 12672 } 12673 } else if (!strcasecmp(v->name, "forceencryption")) { 12674 if (ast_false(v->value)) { 12675 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 12676 } else { 12677 user->encmethods |= get_encrypt_methods(v->value); 12678 if (user->encmethods) { 12679 ast_set_flag64(user, IAX_FORCE_ENCRYPT); 12680 } 12681 } 12682 } else if (!strcasecmp(v->name, "transfer")) { 12683 if (!strcasecmp(v->value, "mediaonly")) { 12684 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12685 } else if (ast_true(v->value)) { 12686 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12687 } else 12688 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12689 } else if (!strcasecmp(v->name, "codecpriority")) { 12690 if(!strcasecmp(v->value, "caller")) 12691 ast_set_flag64(user, IAX_CODEC_USER_FIRST); 12692 else if(!strcasecmp(v->value, "disabled")) 12693 ast_set_flag64(user, IAX_CODEC_NOPREFS); 12694 else if(!strcasecmp(v->value, "reqonly")) { 12695 ast_set_flag64(user, IAX_CODEC_NOCAP); 12696 ast_set_flag64(user, IAX_CODEC_NOPREFS); 12697 } 12698 } else if (!strcasecmp(v->name, "immediate")) { 12699 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE); 12700 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12701 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF); 12702 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12703 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF); 12704 } else if (!strcasecmp(v->name, "dbsecret")) { 12705 ast_string_field_set(user, dbsecret, v->value); 12706 } else if (!strcasecmp(v->name, "secret")) { 12707 if (!ast_strlen_zero(user->secret)) { 12708 char *old = ast_strdupa(user->secret); 12709 12710 ast_string_field_build(user, secret, "%s;%s", old, v->value); 12711 } else 12712 ast_string_field_set(user, secret, v->value); 12713 } else if (!strcasecmp(v->name, "callerid")) { 12714 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 12715 char name2[80]; 12716 char num2[80]; 12717 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12718 ast_string_field_set(user, cid_name, name2); 12719 ast_string_field_set(user, cid_num, num2); 12720 ast_set_flag64(user, IAX_HASCALLERID); 12721 } else { 12722 ast_clear_flag64(user, IAX_HASCALLERID); 12723 ast_string_field_set(user, cid_name, ""); 12724 ast_string_field_set(user, cid_num, ""); 12725 } 12726 } else if (!strcasecmp(v->name, "fullname")) { 12727 if (!ast_strlen_zero(v->value)) { 12728 ast_string_field_set(user, cid_name, v->value); 12729 ast_set_flag64(user, IAX_HASCALLERID); 12730 } else { 12731 ast_string_field_set(user, cid_name, ""); 12732 if (ast_strlen_zero(user->cid_num)) 12733 ast_clear_flag64(user, IAX_HASCALLERID); 12734 } 12735 } else if (!strcasecmp(v->name, "cid_number")) { 12736 if (!ast_strlen_zero(v->value)) { 12737 ast_string_field_set(user, cid_num, v->value); 12738 ast_set_flag64(user, IAX_HASCALLERID); 12739 } else { 12740 ast_string_field_set(user, cid_num, ""); 12741 if (ast_strlen_zero(user->cid_name)) 12742 ast_clear_flag64(user, IAX_HASCALLERID); 12743 } 12744 } else if (!strcasecmp(v->name, "accountcode")) { 12745 ast_string_field_set(user, accountcode, v->value); 12746 } else if (!strcasecmp(v->name, "mohinterpret")) { 12747 ast_string_field_set(user, mohinterpret, v->value); 12748 } else if (!strcasecmp(v->name, "mohsuggest")) { 12749 ast_string_field_set(user, mohsuggest, v->value); 12750 } else if (!strcasecmp(v->name, "parkinglot")) { 12751 ast_string_field_set(user, parkinglot, v->value); 12752 } else if (!strcasecmp(v->name, "language")) { 12753 ast_string_field_set(user, language, v->value); 12754 } else if (!strcasecmp(v->name, "amaflags")) { 12755 format = ast_cdr_amaflags2int(v->value); 12756 if (format < 0) { 12757 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 12758 } else { 12759 user->amaflags = format; 12760 } 12761 } else if (!strcasecmp(v->name, "inkeys")) { 12762 ast_string_field_set(user, inkeys, v->value); 12763 } else if (!strcasecmp(v->name, "maxauthreq")) { 12764 user->maxauthreq = atoi(v->value); 12765 if (user->maxauthreq < 0) 12766 user->maxauthreq = 0; 12767 } else if (!strcasecmp(v->name, "adsi")) { 12768 user->adsi = ast_true(v->value); 12769 } else if (!strcasecmp(v->name, "connectedline")) { 12770 if (ast_true(v->value)) { 12771 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12772 } else if (!strcasecmp(v->value, "send")) { 12773 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE); 12774 ast_set_flag64(user, IAX_SENDCONNECTEDLINE); 12775 } else if (!strcasecmp(v->value, "receive")) { 12776 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE); 12777 ast_set_flag64(user, IAX_RECVCONNECTEDLINE); 12778 } else { 12779 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12780 } 12781 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12782 /* default is required unless in optional ip list */ 12783 if (ast_false(v->value)) { 12784 user->calltoken_required = CALLTOKEN_NO; 12785 } else if (!strcasecmp(v->value, "auto")) { 12786 user->calltoken_required = CALLTOKEN_AUTO; 12787 } else if (ast_true(v->value)) { 12788 user->calltoken_required = CALLTOKEN_YES; 12789 } else { 12790 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12791 } 12792 } /* else if (strcasecmp(v->name,"type")) */ 12793 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12794 v = v->next; 12795 if (!v) { 12796 v = alt; 12797 alt = NULL; 12798 } 12799 } 12800 if (!user->authmethods) { 12801 if (!ast_strlen_zero(user->secret)) { 12802 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12803 if (!ast_strlen_zero(user->inkeys)) 12804 user->authmethods |= IAX_AUTH_RSA; 12805 } else if (!ast_strlen_zero(user->inkeys)) { 12806 user->authmethods = IAX_AUTH_RSA; 12807 } else { 12808 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12809 } 12810 } 12811 ast_clear_flag64(user, IAX_DELME); 12812 } 12813 cleanup: 12814 if (oldha) 12815 ast_free_ha(oldha); 12816 if (oldcon) 12817 free_context(oldcon); 12818 return user; 12819 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 13453 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().
13454 { 13455 struct sockaddr_in sin; 13456 int x; 13457 int callno; 13458 struct iax_ie_data ied; 13459 struct create_addr_info cai; 13460 struct parsed_dial_string pds; 13461 char *tmpstr; 13462 13463 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 13464 /* Look for an *exact match* call. Once a call is negotiated, it can only 13465 look up entries for a single context */ 13466 if (!ast_mutex_trylock(&iaxsl[x])) { 13467 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 13468 return x; 13469 ast_mutex_unlock(&iaxsl[x]); 13470 } 13471 } 13472 13473 /* No match found, we need to create a new one */ 13474 13475 memset(&cai, 0, sizeof(cai)); 13476 memset(&ied, 0, sizeof(ied)); 13477 memset(&pds, 0, sizeof(pds)); 13478 13479 tmpstr = ast_strdupa(data); 13480 parse_dial_string(tmpstr, &pds); 13481 13482 if (ast_strlen_zero(pds.peer)) { 13483 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 13484 return -1; 13485 } 13486 13487 /* Populate our address from the given */ 13488 if (create_addr(pds.peer, NULL, &sin, &cai)) 13489 return -1; 13490 13491 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n", 13492 pds.peer, pds.username, pds.password, pds.context); 13493 13494 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 13495 if (callno < 1) { 13496 ast_log(LOG_WARNING, "Unable to create call\n"); 13497 return -1; 13498 } 13499 13500 ast_string_field_set(iaxs[callno], dproot, data); 13501 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 13502 13503 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 13504 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 13505 /* the string format is slightly different from a standard dial string, 13506 because the context appears in the 'exten' position 13507 */ 13508 if (pds.exten) 13509 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 13510 if (pds.username) 13511 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 13512 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 13513 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 13514 /* Keep password handy */ 13515 if (pds.password) 13516 ast_string_field_set(iaxs[callno], secret, pds.password); 13517 if (pds.key) 13518 ast_string_field_set(iaxs[callno], outkey, pds.key); 13519 /* Start the call going */ 13520 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 13521 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 13522 13523 return callno; 13524 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 5991 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().
05992 { 05993 /* Returns where in "receive time" we are. That is, how many ms 05994 since we received (or would have received) the frame with timestamp 0 */ 05995 int ms; 05996 #ifdef IAXTESTS 05997 int jit; 05998 #endif /* IAXTESTS */ 05999 /* Setup rxcore if necessary */ 06000 if (ast_tvzero(p->rxcore)) { 06001 p->rxcore = ast_tvnow(); 06002 if (iaxdebug) 06003 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 06004 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 06005 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 06006 #if 1 06007 if (iaxdebug) 06008 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 06009 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 06010 #endif 06011 } 06012 06013 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 06014 #ifdef IAXTESTS 06015 if (test_jit) { 06016 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 06017 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 06018 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 06019 jit = -jit; 06020 ms += jit; 06021 } 06022 } 06023 if (test_late) { 06024 ms += test_late; 06025 test_late = 0; 06026 } 06027 #endif /* IAXTESTS */ 06028 return ms; 06029 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 5858 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().
05859 { 05860 int ms; 05861 int voice = 0; 05862 int genuine = 0; 05863 int adjust; 05864 int rate = ast_format_rate(f->subclass.codec) / 1000; 05865 struct timeval *delivery = NULL; 05866 05867 05868 /* What sort of frame do we have?: voice is self-explanatory 05869 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 05870 non-genuine frames are CONTROL frames [ringing etc], DTMF 05871 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 05872 the others need a timestamp slaved to the voice frames so that they go in sequence 05873 */ 05874 if (f) { 05875 if (f->frametype == AST_FRAME_VOICE) { 05876 voice = 1; 05877 delivery = &f->delivery; 05878 } else if (f->frametype == AST_FRAME_IAX) { 05879 genuine = 1; 05880 } else if (f->frametype == AST_FRAME_CNG) { 05881 p->notsilenttx = 0; 05882 } 05883 } 05884 if (ast_tvzero(p->offset)) { 05885 p->offset = ast_tvnow(); 05886 /* Round to nearest 20ms for nice looking traces */ 05887 p->offset.tv_usec -= p->offset.tv_usec % 20000; 05888 } 05889 /* If the timestamp is specified, just send it as is */ 05890 if (ts) 05891 return ts; 05892 /* If we have a time that the frame arrived, always use it to make our timestamp */ 05893 if (delivery && !ast_tvzero(*delivery)) { 05894 ms = ast_tvdiff_ms(*delivery, p->offset); 05895 if (ms < 0) { 05896 ms = 0; 05897 } 05898 if (iaxdebug) 05899 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 05900 } else { 05901 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 05902 if (ms < 0) 05903 ms = 0; 05904 if (voice) { 05905 /* On a voice frame, use predicted values if appropriate */ 05906 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 05907 /* Adjust our txcore, keeping voice and non-voice synchronized */ 05908 /* AN EXPLANATION: 05909 When we send voice, we usually send "calculated" timestamps worked out 05910 on the basis of the number of samples sent. When we send other frames, 05911 we usually send timestamps worked out from the real clock. 05912 The problem is that they can tend to drift out of step because the 05913 source channel's clock and our clock may not be exactly at the same rate. 05914 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 05915 for this call. Moving it adjusts timestamps for non-voice frames. 05916 We make the adjustment in the style of a moving average. Each time we 05917 adjust p->offset by 10% of the difference between our clock-derived 05918 timestamp and the predicted timestamp. That's why you see "10000" 05919 below even though IAX2 timestamps are in milliseconds. 05920 The use of a moving average avoids offset moving too radically. 05921 Generally, "adjust" roams back and forth around 0, with offset hardly 05922 changing at all. But if a consistent different starts to develop it 05923 will be eliminated over the course of 10 frames (200-300msecs) 05924 */ 05925 adjust = (ms - p->nextpred); 05926 if (adjust < 0) 05927 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 05928 else if (adjust > 0) 05929 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 05930 05931 if (!p->nextpred) { 05932 p->nextpred = ms; /*f->samples / rate;*/ 05933 if (p->nextpred <= p->lastsent) 05934 p->nextpred = p->lastsent + 3; 05935 } 05936 ms = p->nextpred; 05937 } else { 05938 /* in this case, just use the actual 05939 * time, since we're either way off 05940 * (shouldn't happen), or we're ending a 05941 * silent period -- and seed the next 05942 * predicted time. Also, round ms to the 05943 * next multiple of frame size (so our 05944 * silent periods are multiples of 05945 * frame size too) */ 05946 05947 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 05948 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 05949 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 05950 05951 if (f->samples >= rate) /* check to make sure we don't core dump */ 05952 { 05953 int diff = ms % (f->samples / rate); 05954 if (diff) 05955 ms += f->samples/rate - diff; 05956 } 05957 05958 p->nextpred = ms; 05959 p->notsilenttx = 1; 05960 } 05961 } else if ( f->frametype == AST_FRAME_VIDEO ) { 05962 /* 05963 * IAX2 draft 03 says that timestamps MUST be in order. 05964 * It does not say anything about several frames having the same timestamp 05965 * When transporting video, we can have a frame that spans multiple iax packets 05966 * (so called slices), so it would make sense to use the same timestamp for all of 05967 * them 05968 * We do want to make sure that frames don't go backwards though 05969 */ 05970 if ( (unsigned int)ms < p->lastsent ) 05971 ms = p->lastsent; 05972 } else { 05973 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 05974 it's a genuine frame */ 05975 if (genuine) { 05976 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 05977 if (ms <= p->lastsent) 05978 ms = p->lastsent + 3; 05979 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 05980 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 05981 ms = p->lastsent + 3; 05982 } 05983 } 05984 } 05985 p->lastsent = ms; 05986 if (voice) 05987 p->nextpred = p->nextpred + f->samples / rate; 05988 return ms; 05989 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | now | |||
) | [static] |
Definition at line 5814 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().
05815 { 05816 unsigned long int mssincetx; /* unsigned to handle overflows */ 05817 long int ms, pred; 05818 05819 tpeer->trunkact = *now; 05820 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime); 05821 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 05822 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 05823 tpeer->txtrunktime = *now; 05824 tpeer->lastsent = 999999; 05825 } 05826 /* Update last transmit time now */ 05827 tpeer->lasttxtime = *now; 05828 05829 /* Calculate ms offset */ 05830 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime); 05831 /* Predict from last value */ 05832 pred = tpeer->lastsent + sampms; 05833 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 05834 ms = pred; 05835 05836 /* We never send the same timestamp twice, so fudge a little if we must */ 05837 if (ms == tpeer->lastsent) 05838 ms = tpeer->lastsent + 1; 05839 tpeer->lastsent = ms; 05840 return ms; 05841 }
static int callno_hash | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 2657 of file chan_iax2.c.
References ast_random().
Referenced by create_callno_pools().
02658 { 02659 return abs(ast_random()); 02660 }
static int calltoken_required | ( | struct sockaddr_in * | sin, | |
const char * | name, | |||
int | subclass | |||
) | [static] |
Definition at line 2189 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().
02190 { 02191 struct addr_range *addr_range; 02192 struct iax2_peer *peer = NULL; 02193 struct iax2_user *user = NULL; 02194 /* if no username is given, check for guest accounts */ 02195 const char *find = S_OR(name, "guest"); 02196 int res = 1; /* required by default */ 02197 int optional = 0; 02198 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT; 02199 /* There are only two cases in which calltoken validation is not required. 02200 * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and 02201 * the peer definition has not set the requirecalltoken option. 02202 * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no. 02203 */ 02204 02205 /* ----- Case 1 ----- */ 02206 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) { 02207 ao2_ref(addr_range, -1); 02208 optional = 1; 02209 } 02210 02211 /* ----- Case 2 ----- */ 02212 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) { 02213 calltoken_required = user->calltoken_required; 02214 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) { 02215 calltoken_required = user->calltoken_required; 02216 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) { 02217 calltoken_required = peer->calltoken_required; 02218 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) { 02219 calltoken_required = peer->calltoken_required; 02220 } 02221 02222 if (peer) { 02223 peer_unref(peer); 02224 } 02225 if (user) { 02226 user_unref(user); 02227 } 02228 02229 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); 02230 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) || 02231 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) { 02232 res = 0; 02233 } 02234 02235 return res; 02236 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7509 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_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().
07510 { 07511 /* Start pessimistic */ 07512 int res = -1; 07513 int version = 2; 07514 struct iax2_user *user = NULL, *best = NULL; 07515 int bestscore = 0; 07516 int gotcapability = 0; 07517 struct ast_variable *v = NULL, *tmpvar = NULL; 07518 struct ao2_iterator i; 07519 struct ast_sockaddr addr; 07520 07521 if (!iaxs[callno]) 07522 return res; 07523 if (ies->called_number) 07524 ast_string_field_set(iaxs[callno], exten, ies->called_number); 07525 if (ies->calling_number) { 07526 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) { 07527 ast_shrink_phone_number(ies->calling_number); 07528 } 07529 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 07530 } 07531 if (ies->calling_name) 07532 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 07533 if (ies->calling_ani) 07534 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 07535 if (ies->dnid) 07536 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 07537 if (ies->rdnis) 07538 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 07539 if (ies->called_context) 07540 ast_string_field_set(iaxs[callno], context, ies->called_context); 07541 if (ies->language) 07542 ast_string_field_set(iaxs[callno], language, ies->language); 07543 if (ies->username) 07544 ast_string_field_set(iaxs[callno], username, ies->username); 07545 if (ies->calling_ton > -1) 07546 iaxs[callno]->calling_ton = ies->calling_ton; 07547 if (ies->calling_tns > -1) 07548 iaxs[callno]->calling_tns = ies->calling_tns; 07549 if (ies->calling_pres > -1) 07550 iaxs[callno]->calling_pres = ies->calling_pres; 07551 if (ies->format) 07552 iaxs[callno]->peerformat = ies->format; 07553 if (ies->adsicpe) 07554 iaxs[callno]->peeradsicpe = ies->adsicpe; 07555 if (ies->capability) { 07556 gotcapability = 1; 07557 iaxs[callno]->peercapability = ies->capability; 07558 } 07559 if (ies->version) 07560 version = ies->version; 07561 07562 /* Use provided preferences until told otherwise for actual preferences */ 07563 if (ies->codec_prefs) { 07564 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 07565 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 07566 } 07567 07568 if (!gotcapability) 07569 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 07570 if (version > IAX_PROTO_VERSION) { 07571 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 07572 ast_inet_ntoa(sin->sin_addr), version); 07573 return res; 07574 } 07575 /* Search the userlist for a compatible entry, and fill in the rest */ 07576 i = ao2_iterator_init(users, 0); 07577 ast_sockaddr_from_sin(&addr, sin); 07578 while ((user = ao2_iterator_next(&i))) { 07579 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 07580 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 07581 && ast_apply_ha(user->ha, &addr) /* Access is permitted from this IP */ 07582 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 07583 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 07584 if (!ast_strlen_zero(iaxs[callno]->username)) { 07585 /* Exact match, stop right now. */ 07586 if (best) 07587 user_unref(best); 07588 best = user; 07589 break; 07590 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 07591 /* No required authentication */ 07592 if (user->ha) { 07593 /* There was host authentication and we passed, bonus! */ 07594 if (bestscore < 4) { 07595 bestscore = 4; 07596 if (best) 07597 user_unref(best); 07598 best = user; 07599 continue; 07600 } 07601 } else { 07602 /* No host access, but no secret, either, not bad */ 07603 if (bestscore < 3) { 07604 bestscore = 3; 07605 if (best) 07606 user_unref(best); 07607 best = user; 07608 continue; 07609 } 07610 } 07611 } else { 07612 if (user->ha) { 07613 /* Authentication, but host access too, eh, it's something.. */ 07614 if (bestscore < 2) { 07615 bestscore = 2; 07616 if (best) 07617 user_unref(best); 07618 best = user; 07619 continue; 07620 } 07621 } else { 07622 /* Authentication and no host access... This is our baseline */ 07623 if (bestscore < 1) { 07624 bestscore = 1; 07625 if (best) 07626 user_unref(best); 07627 best = user; 07628 continue; 07629 } 07630 } 07631 } 07632 } 07633 user_unref(user); 07634 } 07635 ao2_iterator_destroy(&i); 07636 user = best; 07637 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 07638 user = realtime_user(iaxs[callno]->username, sin); 07639 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 07640 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 07641 user = user_unref(user); 07642 } 07643 } 07644 if (user) { 07645 /* We found our match (use the first) */ 07646 /* copy vars */ 07647 for (v = user->vars ; v ; v = v->next) { 07648 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) { 07649 tmpvar->next = iaxs[callno]->vars; 07650 iaxs[callno]->vars = tmpvar; 07651 } 07652 } 07653 /* If a max AUTHREQ restriction is in place, activate it */ 07654 if (user->maxauthreq > 0) 07655 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ); 07656 iaxs[callno]->prefs = user->prefs; 07657 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT); 07658 iaxs[callno]->encmethods = user->encmethods; 07659 /* Store the requested username if not specified */ 07660 if (ast_strlen_zero(iaxs[callno]->username)) 07661 ast_string_field_set(iaxs[callno], username, user->name); 07662 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 07663 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK); 07664 iaxs[callno]->capability = user->capability; 07665 /* And use the default context */ 07666 if (ast_strlen_zero(iaxs[callno]->context)) { 07667 if (user->contexts) 07668 ast_string_field_set(iaxs[callno], context, user->contexts->context); 07669 else 07670 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT); 07671 } 07672 /* And any input keys */ 07673 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 07674 /* And the permitted authentication methods */ 07675 iaxs[callno]->authmethods = user->authmethods; 07676 iaxs[callno]->adsi = user->adsi; 07677 /* If the user has callerid, override the remote caller id. */ 07678 if (ast_test_flag64(user, IAX_HASCALLERID)) { 07679 iaxs[callno]->calling_tns = 0; 07680 iaxs[callno]->calling_ton = 0; 07681 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 07682 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 07683 ast_string_field_set(iaxs[callno], ani, user->cid_num); 07684 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 07685 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 07686 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 07687 } /* else user is allowed to set their own CID settings */ 07688 if (!ast_strlen_zero(user->accountcode)) 07689 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 07690 if (!ast_strlen_zero(user->mohinterpret)) 07691 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 07692 if (!ast_strlen_zero(user->mohsuggest)) 07693 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 07694 if (!ast_strlen_zero(user->parkinglot)) 07695 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot); 07696 if (user->amaflags) 07697 iaxs[callno]->amaflags = user->amaflags; 07698 if (!ast_strlen_zero(user->language)) 07699 ast_string_field_set(iaxs[callno], language, user->language); 07700 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 07701 /* Keep this check last */ 07702 if (!ast_strlen_zero(user->dbsecret)) { 07703 char *family, *key=NULL; 07704 char buf[80]; 07705 family = ast_strdupa(user->dbsecret); 07706 key = strchr(family, '/'); 07707 if (key) { 07708 *key = '\0'; 07709 key++; 07710 } 07711 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 07712 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 07713 else 07714 ast_string_field_set(iaxs[callno], secret, buf); 07715 } else 07716 ast_string_field_set(iaxs[callno], secret, user->secret); 07717 res = 0; 07718 user = user_unref(user); 07719 } else { 07720 /* user was not found, but we should still fake an AUTHREQ. 07721 * Set authmethods to the last known authmethod used by the system 07722 * Set a fake secret, it's not looked at, just required to attempt authentication. 07723 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 07724 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 07725 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07726 iaxs[callno]->authrej = 1; 07727 if (!ast_strlen_zero(iaxs[callno]->username)) { 07728 /* only send the AUTHREQ if a username was specified. */ 07729 res = 0; 07730 } 07731 } 07732 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 07733 return res; 07734 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 9325 of file chan_iax2.c.
References ast_debug, iax2_provision(), and iax_provision_version().
Referenced by socket_process().
09326 { 09327 unsigned int ourver; 09328 char rsi[80]; 09329 snprintf(rsi, sizeof(rsi), "si-%s", si); 09330 if (iax_provision_version(&ourver, rsi, 1)) 09331 return 0; 09332 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 09333 if (ourver != ver) 09334 iax2_provision(sin, sockfd, NULL, rsi, 1); 09335 return 0; 09336 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 12154 of file chan_iax2.c.
References ast_debug, ast_log(), errno, and LOG_ERROR.
Referenced by peer_set_srcaddr().
12155 { 12156 int sd; 12157 int res; 12158 12159 sd = socket(AF_INET, SOCK_DGRAM, 0); 12160 if (sd < 0) { 12161 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 12162 return -1; 12163 } 12164 12165 res = bind(sd, sa, salen); 12166 if (res < 0) { 12167 ast_debug(1, "Can't bind: %s\n", strerror(errno)); 12168 close(sd); 12169 return 1; 12170 } 12171 12172 close(sd); 12173 return 0; 12174 }
static void cleanup_thread_list | ( | void * | head | ) | [static] |
Definition at line 14188 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().
14189 { 14190 AST_LIST_HEAD(iax2_thread_list, iax2_thread); 14191 struct iax2_thread_list *list_head = head; 14192 struct iax2_thread *thread; 14193 14194 AST_LIST_LOCK(list_head); 14195 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) { 14196 pthread_t thread_id = thread->threadid; 14197 14198 thread->stop = 1; 14199 signal_condition(&thread->lock, &thread->cond); 14200 14201 AST_LIST_UNLOCK(list_head); 14202 pthread_join(thread_id, NULL); 14203 AST_LIST_LOCK(list_head); 14204 } 14205 AST_LIST_UNLOCK(list_head); 14206 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 8299 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().
08300 { 08301 char exten[256] = ""; 08302 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0; 08303 struct iax2_dpcache *dp = NULL; 08304 08305 if (ies->called_number) 08306 ast_copy_string(exten, ies->called_number, sizeof(exten)); 08307 08308 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 08309 status = CACHE_FLAG_EXISTS; 08310 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 08311 status = CACHE_FLAG_CANEXIST; 08312 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 08313 status = CACHE_FLAG_NONEXISTENT; 08314 08315 if (ies->refresh) 08316 expiry = ies->refresh; 08317 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 08318 matchmore = CACHE_FLAG_MATCHMORE; 08319 08320 AST_LIST_LOCK(&dpcache); 08321 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) { 08322 if (strcmp(dp->exten, exten)) 08323 continue; 08324 AST_LIST_REMOVE_CURRENT(peer_list); 08325 dp->callno = 0; 08326 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 08327 if (dp->flags & CACHE_FLAG_PENDING) { 08328 dp->flags &= ~CACHE_FLAG_PENDING; 08329 dp->flags |= status; 08330 dp->flags |= matchmore; 08331 } 08332 /* Wake up waiters */ 08333 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 08334 if (dp->waiters[x] > -1) { 08335 if (write(dp->waiters[x], "asdf", 4) < 0) { 08336 } 08337 } 08338 } 08339 } 08340 AST_LIST_TRAVERSE_SAFE_END; 08341 AST_LIST_UNLOCK(&dpcache); 08342 08343 return 0; 08344 }
static char * complete_iax2_peers | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state, | |||
uint64_t | flags | |||
) | [static] |
Definition at line 3808 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().
03809 { 03810 int which = 0; 03811 struct iax2_peer *peer; 03812 char *res = NULL; 03813 int wordlen = strlen(word); 03814 struct ao2_iterator i; 03815 03816 i = ao2_iterator_init(peers, 0); 03817 while ((peer = ao2_iterator_next(&i))) { 03818 if (!strncasecmp(peer->name, word, wordlen) && ++which > state 03819 && (!flags || ast_test_flag64(peer, flags))) { 03820 res = ast_strdup(peer->name); 03821 peer_unref(peer); 03822 break; 03823 } 03824 peer_unref(peer); 03825 } 03826 ao2_iterator_destroy(&i); 03827 03828 return res; 03829 }
static char * complete_iax2_unregister | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 6862 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().
06863 { 06864 int which = 0; 06865 struct iax2_peer *p = NULL; 06866 char *res = NULL; 06867 int wordlen = strlen(word); 06868 06869 /* 0 - iax2; 1 - unregister; 2 - <peername> */ 06870 if (pos == 2) { 06871 struct ao2_iterator i = ao2_iterator_init(peers, 0); 06872 while ((p = ao2_iterator_next(&i))) { 06873 if (!strncasecmp(p->name, word, wordlen) && 06874 ++which > state && p->expire > 0) { 06875 res = ast_strdup(p->name); 06876 peer_unref(p); 06877 break; 06878 } 06879 peer_unref(p); 06880 } 06881 ao2_iterator_destroy(&i); 06882 } 06883 06884 return res; 06885 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 8346 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().
08347 { 08348 int peercallno = 0; 08349 struct chan_iax2_pvt *pvt = iaxs[callno]; 08350 struct iax_frame *cur; 08351 jb_frame frame; 08352 08353 if (ies->callno) 08354 peercallno = ies->callno; 08355 08356 if (peercallno < 1) { 08357 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08358 return -1; 08359 } 08360 remove_by_transfercallno(pvt); 08361 /* since a transfer has taken place, the address will change. 08362 * This must be accounted for in the peercnts table. Remove 08363 * the old address and add the new one */ 08364 peercnt_remove_by_addr(&pvt->addr); 08365 peercnt_add(&pvt->transfer); 08366 /* now copy over the new address */ 08367 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 08368 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 08369 /* Reset sequence numbers */ 08370 pvt->oseqno = 0; 08371 pvt->rseqno = 0; 08372 pvt->iseqno = 0; 08373 pvt->aseqno = 0; 08374 08375 if (pvt->peercallno) { 08376 remove_by_peercallno(pvt); 08377 } 08378 pvt->peercallno = peercallno; 08379 /*this is where the transfering call swiches hash tables */ 08380 store_by_peercallno(pvt); 08381 pvt->transferring = TRANSFER_NONE; 08382 pvt->svoiceformat = -1; 08383 pvt->voiceformat = 0; 08384 pvt->svideoformat = -1; 08385 pvt->videoformat = 0; 08386 pvt->transfercallno = 0; 08387 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 08388 memset(&pvt->offset, 0, sizeof(pvt->offset)); 08389 /* reset jitterbuffer */ 08390 while(jb_getall(pvt->jb,&frame) == JB_OK) 08391 iax2_frame_free(frame.data); 08392 jb_reset(pvt->jb); 08393 pvt->lag = 0; 08394 pvt->last = 0; 08395 pvt->lastsent = 0; 08396 pvt->nextpred = 0; 08397 pvt->pingtime = DEFAULT_RETRY_TIME; 08398 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) { 08399 /* We must cancel any packets that would have been transmitted 08400 because now we're talking to someone new. It's okay, they 08401 were transmitted to someone that didn't care anyway. */ 08402 cur->retries = -1; 08403 } 08404 return 0; 08405 }
static unsigned char compress_subclass | ( | format_t | subclass | ) | [static] |
Definition at line 1609 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().
01610 { 01611 int x; 01612 int power=-1; 01613 /* If it's 64 or smaller, just return it */ 01614 if (subclass < IAX_FLAG_SC_LOG) 01615 return subclass; 01616 /* Otherwise find its power */ 01617 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01618 if (subclass & (1LL << x)) { 01619 if (power > -1) { 01620 ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass); 01621 return 0; 01622 } else 01623 power = x; 01624 } 01625 } 01626 return power | IAX_FLAG_SC_LOG; 01627 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 9338 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().
09339 { 09340 jb_info stats; 09341 jb_getinfo(pvt->jb, &stats); 09342 09343 memset(iep, 0, sizeof(*iep)); 09344 09345 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 09346 if(stats.frames_in == 0) stats.frames_in = 1; 09347 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 09348 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 09349 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 09350 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 09351 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 09352 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 4536 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.
04537 { 04538 struct iax2_peer *peer; 04539 int res = -1; 04540 struct ast_codec_pref ourprefs; 04541 struct sockaddr_in peer_addr; 04542 04543 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK); 04544 cai->sockfd = defaultsockfd; 04545 cai->maxtime = 0; 04546 sin->sin_family = AF_INET; 04547 04548 if (!(peer = find_peer(peername, 1))) { 04549 struct ast_sockaddr sin_tmp; 04550 04551 cai->found = 0; 04552 sin_tmp.ss.ss_family = AF_INET; 04553 if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) { 04554 ast_log(LOG_WARNING, "No such host: %s\n", peername); 04555 return -1; 04556 } 04557 ast_sockaddr_to_sin(&sin_tmp, sin); 04558 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 04559 /* use global iax prefs for unknown peer/user */ 04560 /* But move the calling channel's native codec to the top of the preference list */ 04561 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 04562 if (c) 04563 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04564 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04565 return 0; 04566 } 04567 04568 cai->found = 1; 04569 04570 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 04571 04572 /* if the peer has no address (current or default), return failure */ 04573 if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) { 04574 goto return_unref; 04575 } 04576 04577 /* if the peer is being monitored and is currently unreachable, return failure */ 04578 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 04579 goto return_unref; 04580 04581 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 04582 cai->maxtime = peer->maxms; 04583 cai->capability = peer->capability; 04584 cai->encmethods = peer->encmethods; 04585 cai->sockfd = peer->sockfd; 04586 cai->adsi = peer->adsi; 04587 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 04588 /* Move the calling channel's native codec to the top of the preference list */ 04589 if (c) { 04590 ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats); 04591 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04592 } 04593 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04594 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 04595 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 04596 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 04597 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 04598 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 04599 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num)); 04600 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name)); 04601 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 04602 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 04603 if (ast_strlen_zero(peer->dbsecret)) { 04604 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 04605 } else { 04606 char *family; 04607 char *key = NULL; 04608 04609 family = ast_strdupa(peer->dbsecret); 04610 key = strchr(family, '/'); 04611 if (key) 04612 *key++ = '\0'; 04613 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 04614 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 04615 goto return_unref; 04616 } 04617 } 04618 04619 if (peer_addr.sin_addr.s_addr) { 04620 sin->sin_addr = peer_addr.sin_addr; 04621 sin->sin_port = peer_addr.sin_port; 04622 } else { 04623 sin->sin_addr = peer->defaddr.sin_addr; 04624 sin->sin_port = peer->defaddr.sin_port; 04625 } 04626 04627 res = 0; 04628 04629 return_unref: 04630 peer_unref(peer); 04631 04632 return res; 04633 }
static int create_callno_pools | ( | void | ) | [static] |
Definition at line 2662 of file chan_iax2.c.
References ao2_alloc, ao2_container_alloc, ao2_link, ao2_ref, callno_hash(), and TRUNK_CALL_START.
Referenced by load_objects().
02663 { 02664 uint16_t i; 02665 02666 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02667 return -1; 02668 } 02669 02670 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02671 return -1; 02672 } 02673 02674 /* start at 2, 0 and 1 are reserved */ 02675 for (i = 2; i <= IAX_MAX_CALLS; i++) { 02676 struct callno_entry *callno_entry; 02677 02678 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) { 02679 return -1; 02680 } 02681 02682 callno_entry->callno = i; 02683 02684 if (i < TRUNK_CALL_START) { 02685 ao2_link(callno_pool, callno_entry); 02686 } else { 02687 ao2_link(callno_pool_trunk, callno_entry); 02688 } 02689 02690 ao2_ref(callno_entry, -1); 02691 } 02692 02693 return 0; 02694 }
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 6213 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().
06214 { 06215 int padding; 06216 unsigned char *workspace; 06217 06218 workspace = alloca(*datalen); 06219 memset(f, 0, sizeof(*f)); 06220 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06221 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06222 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 06223 return -1; 06224 /* Decrypt */ 06225 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 06226 06227 padding = 16 + (workspace[15] & 0x0f); 06228 if (iaxdebug) 06229 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 06230 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 06231 return -1; 06232 06233 *datalen -= padding; 06234 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06235 f->frametype = fh->type; 06236 if (f->frametype == AST_FRAME_VIDEO) { 06237 f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06238 } else if (f->frametype == AST_FRAME_VOICE) { 06239 f->subclass.codec = uncompress_subclass(fh->csub); 06240 } else { 06241 f->subclass.integer = uncompress_subclass(fh->csub); 06242 } 06243 } else { 06244 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06245 if (iaxdebug) 06246 ast_debug(1, "Decoding mini with length %d\n", *datalen); 06247 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 06248 return -1; 06249 /* Decrypt */ 06250 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 06251 padding = 16 + (workspace[15] & 0x0f); 06252 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 06253 return -1; 06254 *datalen -= padding; 06255 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06256 } 06257 return 0; 06258 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 6301 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().
06302 { 06303 int res=-1; 06304 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) { 06305 /* Search for possible keys, given secrets */ 06306 struct MD5Context md5; 06307 unsigned char digest[16]; 06308 char *tmppw, *stringp; 06309 06310 tmppw = ast_strdupa(iaxs[callno]->secret); 06311 stringp = tmppw; 06312 while ((tmppw = strsep(&stringp, ";"))) { 06313 MD5Init(&md5); 06314 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 06315 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 06316 MD5Final(digest, &md5); 06317 build_encryption_keys(digest, iaxs[callno]); 06318 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06319 if (!res) { 06320 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED); 06321 break; 06322 } 06323 } 06324 } else 06325 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06326 return res; 06327 }
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 9485 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().
09486 { 09487 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 09488 struct ast_iax2_full_hdr *fh, *cur_fh; 09489 09490 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 09491 return; 09492 09493 pkt_buf->len = from_here->buf_len; 09494 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 09495 09496 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 09497 ast_mutex_lock(&to_here->lock); 09498 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 09499 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 09500 if (fh->oseqno < cur_fh->oseqno) { 09501 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry); 09502 break; 09503 } 09504 } 09505 AST_LIST_TRAVERSE_SAFE_END 09506 09507 if (!cur_pkt_buf) 09508 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 09509 09510 ast_mutex_unlock(&to_here->lock); 09511 }
static void delete_users | ( | void | ) | [static] |
Definition at line 12839 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.
12840 { 12841 struct iax2_registry *reg; 12842 12843 ao2_callback(users, 0, user_delme_cb, NULL); 12844 12845 AST_LIST_LOCK(®istrations); 12846 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 12847 if (sched) { 12848 ast_sched_thread_del(sched, reg->expire); 12849 } 12850 if (reg->callno) { 12851 int callno = reg->callno; 12852 ast_mutex_lock(&iaxsl[callno]); 12853 if (iaxs[callno]) { 12854 iaxs[callno]->reg = NULL; 12855 iax2_destroy(callno); 12856 } 12857 ast_mutex_unlock(&iaxsl[callno]); 12858 } 12859 if (reg->dnsmgr) 12860 ast_dnsmgr_release(reg->dnsmgr); 12861 ast_free(reg); 12862 } 12863 AST_LIST_UNLOCK(®istrations); 12864 12865 ao2_callback(peers, 0, peer_delme_cb, NULL); 12866 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 2992 of file chan_iax2.c.
References ast_free, ast_iax2_firmware_header::datalen, iax_firmware::fd, and iax_firmware::fwh.
Referenced by reload_firmware().
02993 { 02994 /* Close firmware */ 02995 if (cur->fwh) { 02996 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 02997 } 02998 close(cur->fd); 02999 ast_free(cur); 03000 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 9187 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().
09188 { 09189 unsigned short dpstatus = 0; 09190 struct iax_ie_data ied1; 09191 int mm; 09192 09193 memset(&ied1, 0, sizeof(ied1)); 09194 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 09195 /* Must be started */ 09196 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 09197 dpstatus = IAX_DPSTATUS_EXISTS; 09198 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 09199 dpstatus = IAX_DPSTATUS_CANEXIST; 09200 } else { 09201 dpstatus = IAX_DPSTATUS_NONEXISTENT; 09202 } 09203 if (ast_ignore_pattern(context, callednum)) 09204 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 09205 if (mm) 09206 dpstatus |= IAX_DPSTATUS_MATCHMORE; 09207 if (!skiplock) 09208 ast_mutex_lock(&iaxsl[callno]); 09209 if (iaxs[callno]) { 09210 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 09211 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 09212 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 09213 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 09214 } 09215 if (!skiplock) 09216 ast_mutex_unlock(&iaxsl[callno]); 09217 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 9219 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().
09220 { 09221 /* Look up for dpreq */ 09222 struct dpreq_data *dpr = data; 09223 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 09224 if (dpr->callerid) 09225 ast_free(dpr->callerid); 09226 ast_free(dpr); 09227 return NULL; 09228 }
static void encmethods_to_str | ( | int | e, | |
struct ast_str * | buf | |||
) | [static] |
Definition at line 1543 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().
01544 { 01545 ast_str_set(&buf, 0, "("); 01546 if (e & IAX_ENCRYPT_AES128) { 01547 ast_str_append(&buf, 0, "aes128"); 01548 } 01549 if (e & IAX_ENCRYPT_KEYROTATE) { 01550 ast_str_append(&buf, 0, ",keyrotate"); 01551 } 01552 if (ast_str_strlen(buf) > 1) { 01553 ast_str_append(&buf, 0, ")"); 01554 } else { 01555 ast_str_set(&buf, 0, "No"); 01556 } 01557 }
static int encrypt_frame | ( | ast_aes_encrypt_key * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 6260 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().
06261 { 06262 int padding; 06263 unsigned char *workspace; 06264 workspace = alloca(*datalen + 32); 06265 if (!workspace) 06266 return -1; 06267 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06268 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06269 if (iaxdebug) 06270 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 06271 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 06272 padding = 16 + (padding & 0xf); 06273 memcpy(workspace, poo, padding); 06274 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06275 workspace[15] &= 0xf0; 06276 workspace[15] |= (padding & 0xf); 06277 if (iaxdebug) 06278 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]); 06279 *datalen += padding; 06280 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 06281 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 06282 memcpy(poo, workspace + *datalen - 32, 32); 06283 } else { 06284 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06285 if (iaxdebug) 06286 ast_debug(1, "Encoding mini frame with length %d\n", *datalen); 06287 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 06288 padding = 16 + (padding & 0xf); 06289 memcpy(workspace, poo, padding); 06290 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06291 workspace[15] &= 0xf0; 06292 workspace[15] |= (padding & 0x0f); 06293 *datalen += padding; 06294 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 06295 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 06296 memcpy(poo, workspace + *datalen - 32, 32); 06297 } 06298 return 0; 06299 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8604 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().
08605 { 08606 #ifdef SCHED_MULTITHREADED 08607 if (schedule_action(__expire_registry, data)) 08608 #endif 08609 __expire_registry(data); 08610 return 0; 08611 }
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 13526 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().
13527 { 13528 struct iax2_dpcache *dp = NULL; 13529 struct timeval now = ast_tvnow(); 13530 int x, com[2], timeout, old = 0, outfd, doabort, callno; 13531 struct ast_channel *c = NULL; 13532 struct ast_frame *f = NULL; 13533 13534 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) { 13535 if (ast_tvcmp(now, dp->expiry) > 0) { 13536 AST_LIST_REMOVE_CURRENT(cache_list); 13537 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno) 13538 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno); 13539 else 13540 ast_free(dp); 13541 continue; 13542 } 13543 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 13544 break; 13545 } 13546 AST_LIST_TRAVERSE_SAFE_END; 13547 13548 if (!dp) { 13549 /* No matching entry. Create a new one. */ 13550 /* First, can we make a callno? */ 13551 if ((callno = cache_get_callno_locked(data)) < 0) { 13552 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 13553 return NULL; 13554 } 13555 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 13556 ast_mutex_unlock(&iaxsl[callno]); 13557 return NULL; 13558 } 13559 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 13560 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 13561 dp->expiry = ast_tvnow(); 13562 dp->orig = dp->expiry; 13563 /* Expires in 30 mins by default */ 13564 dp->expiry.tv_sec += iaxdefaultdpcache; 13565 dp->flags = CACHE_FLAG_PENDING; 13566 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) 13567 dp->waiters[x] = -1; 13568 /* Insert into the lists */ 13569 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list); 13570 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list); 13571 /* Send the request if we're already up */ 13572 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 13573 iax2_dprequest(dp, callno); 13574 ast_mutex_unlock(&iaxsl[callno]); 13575 } 13576 13577 /* By here we must have a dp */ 13578 if (dp->flags & CACHE_FLAG_PENDING) { 13579 /* Okay, here it starts to get nasty. We need a pipe now to wait 13580 for a reply to come back so long as it's pending */ 13581 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13582 /* Find an empty slot */ 13583 if (dp->waiters[x] < 0) 13584 break; 13585 } 13586 if (x >= ARRAY_LEN(dp->waiters)) { 13587 ast_log(LOG_WARNING, "No more waiter positions available\n"); 13588 return NULL; 13589 } 13590 if (pipe(com)) { 13591 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 13592 return NULL; 13593 } 13594 dp->waiters[x] = com[1]; 13595 /* Okay, now we wait */ 13596 timeout = iaxdefaulttimeout * 1000; 13597 /* Temporarily unlock */ 13598 AST_LIST_UNLOCK(&dpcache); 13599 /* Defer any dtmf */ 13600 if (chan) 13601 old = ast_channel_defer_dtmf(chan); 13602 doabort = 0; 13603 while(timeout) { 13604 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 13605 if (outfd > -1) 13606 break; 13607 if (!c) 13608 continue; 13609 if (!(f = ast_read(c))) { 13610 doabort = 1; 13611 break; 13612 } 13613 ast_frfree(f); 13614 } 13615 if (!timeout) { 13616 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 13617 } 13618 AST_LIST_LOCK(&dpcache); 13619 dp->waiters[x] = -1; 13620 close(com[1]); 13621 close(com[0]); 13622 if (doabort) { 13623 /* Don't interpret anything, just abort. Not sure what th epoint 13624 of undeferring dtmf on a hung up channel is but hey whatever */ 13625 if (!old && chan) 13626 ast_channel_undefer_dtmf(chan); 13627 return NULL; 13628 } 13629 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 13630 /* Now to do non-independent analysis the results of our wait */ 13631 if (dp->flags & CACHE_FLAG_PENDING) { 13632 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 13633 pending. Don't let it take as long to timeout. */ 13634 dp->flags &= ~CACHE_FLAG_PENDING; 13635 dp->flags |= CACHE_FLAG_TIMEOUT; 13636 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 13637 systems without leaving it unavailable once the server comes back online */ 13638 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 13639 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13640 if (dp->waiters[x] > -1) { 13641 if (write(dp->waiters[x], "asdf", 4) < 0) { 13642 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 13643 } 13644 } 13645 } 13646 } 13647 } 13648 /* Our caller will obtain the rest */ 13649 if (!old && chan) 13650 ast_channel_undefer_dtmf(chan); 13651 } 13652 return dp; 13653 }
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 2917 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
02917 { 02918 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 02919 }
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 2921 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().
02921 { 02922 02923 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 02924 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static] |
Definition at line 1395 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().
01396 { 01397 struct iax2_thread *thread = NULL; 01398 01399 /* Pop the head of the idle list off */ 01400 AST_LIST_LOCK(&idle_list); 01401 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 01402 AST_LIST_UNLOCK(&idle_list); 01403 01404 /* If we popped a thread off the idle list, just return it */ 01405 if (thread) { 01406 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01407 return thread; 01408 } 01409 01410 /* Pop the head of the dynamic list off */ 01411 AST_LIST_LOCK(&dynamic_list); 01412 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 01413 AST_LIST_UNLOCK(&dynamic_list); 01414 01415 /* If we popped a thread off the dynamic list, just return it */ 01416 if (thread) { 01417 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01418 return thread; 01419 } 01420 01421 /* If we can't create a new dynamic thread for any reason, return no thread at all */ 01422 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread)))) 01423 return NULL; 01424 01425 /* Set default values */ 01426 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1); 01427 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1); 01428 thread->type = IAX_THREAD_TYPE_DYNAMIC; 01429 01430 /* Initialize lock and condition */ 01431 ast_mutex_init(&thread->lock); 01432 ast_cond_init(&thread->cond, NULL); 01433 ast_mutex_init(&thread->init_lock); 01434 ast_cond_init(&thread->init_cond, NULL); 01435 ast_mutex_lock(&thread->init_lock); 01436 01437 /* Create thread and send it on it's way */ 01438 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 01439 ast_cond_destroy(&thread->cond); 01440 ast_mutex_destroy(&thread->lock); 01441 ast_mutex_unlock(&thread->init_lock); 01442 ast_cond_destroy(&thread->init_cond); 01443 ast_mutex_destroy(&thread->init_lock); 01444 ast_free(thread); 01445 return NULL; 01446 } 01447 01448 /* this thread is not processing a full frame (since it is idle), 01449 so ensure that the field for the full frame call number is empty */ 01450 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01451 01452 /* Wait for the thread to be ready before returning it to the caller */ 01453 ast_cond_wait(&thread->init_cond, &thread->init_lock); 01454 01455 /* Done with init_lock */ 01456 ast_mutex_unlock(&thread->init_lock); 01457 01458 return thread; 01459 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Definition at line 1687 of file chan_iax2.c.
References ao2_find, iax2_peer::name, OBJ_POINTER, peers, and realtime_peer().
01688 { 01689 struct iax2_peer *peer = NULL; 01690 struct iax2_peer tmp_peer = { 01691 .name = name, 01692 }; 01693 01694 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01695 01696 /* Now go for realtime if applicable */ 01697 if(!peer && realtime) 01698 peer = realtime_peer(name, NULL); 01699 01700 return peer; 01701 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static] |
Definition at line 6031 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().
06032 { 06033 struct iax2_trunk_peer *tpeer = NULL; 06034 06035 /* Finds and locks trunk peer */ 06036 AST_LIST_LOCK(&tpeers); 06037 06038 AST_LIST_TRAVERSE(&tpeers, tpeer, list) { 06039 if (!inaddrcmp(&tpeer->addr, sin)) { 06040 ast_mutex_lock(&tpeer->lock); 06041 break; 06042 } 06043 } 06044 06045 if (!tpeer) { 06046 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 06047 ast_mutex_init(&tpeer->lock); 06048 tpeer->lastsent = 9999; 06049 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 06050 tpeer->trunkact = ast_tvnow(); 06051 ast_mutex_lock(&tpeer->lock); 06052 tpeer->sockfd = fd; 06053 #ifdef SO_NO_CHECK 06054 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 06055 #endif 06056 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 06057 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list); 06058 } 06059 } 06060 06061 AST_LIST_UNLOCK(&tpeers); 06062 06063 return tpeer; 06064 }
static struct iax2_user* find_user | ( | const char * | name | ) | [static] |
Definition at line 1715 of file chan_iax2.c.
References ao2_find, iax2_user::name, OBJ_POINTER, and users.
01716 { 01717 struct iax2_user tmp_user = { 01718 .name = name, 01719 }; 01720 01721 return ao2_find(users, &tmp_user, OBJ_POINTER); 01722 }
static unsigned int fix_peerts | ( | struct timeval * | rxtrunktime, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 5843 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process_meta().
05844 { 05845 long ms; /* NOT unsigned */ 05846 if (ast_tvzero(iaxs[callno]->rxcore)) { 05847 /* Initialize rxcore time if appropriate */ 05848 iaxs[callno]->rxcore = ast_tvnow(); 05849 /* Round to nearest 20ms so traces look pretty */ 05850 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 05851 } 05852 /* Calculate difference between trunk and channel */ 05853 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore); 05854 /* Return as the sum of trunk time and the difference between trunk and real time */ 05855 return ms + ts; 05856 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 11988 of file chan_iax2.c.
References ast_free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
11989 { 11990 struct iax2_context *conl; 11991 while(con) { 11992 conl = con; 11993 con = con->next; 11994 ast_free(conl); 11995 } 11996 }
static void free_signaling_queue_entry | ( | struct signaling_queue_entry * | s | ) | [static] |
Definition at line 1821 of file chan_iax2.c.
References ast_free, ast_frame::data, 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 13776 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.
13777 { 13778 struct iax2_peer *peer; 13779 char *peername, *colname; 13780 13781 peername = ast_strdupa(data); 13782 13783 /* if our channel, return the IP address of the endpoint of current channel */ 13784 if (!strcmp(peername,"CURRENTCHANNEL")) { 13785 unsigned short callno; 13786 if (chan->tech != &iax2_tech) 13787 return -1; 13788 callno = PTR_TO_CALLNO(chan->tech_pvt); 13789 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 13790 return 0; 13791 } 13792 13793 if ((colname = strchr(peername, ','))) 13794 *colname++ = '\0'; 13795 else 13796 colname = "ip"; 13797 13798 if (!(peer = find_peer(peername, 1))) 13799 return -1; 13800 13801 if (!strcasecmp(colname, "ip")) { 13802 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len); 13803 } else if (!strcasecmp(colname, "status")) { 13804 peer_status(peer, buf, len); 13805 } else if (!strcasecmp(colname, "mailbox")) { 13806 ast_copy_string(buf, peer->mailbox, len); 13807 } else if (!strcasecmp(colname, "context")) { 13808 ast_copy_string(buf, peer->context, len); 13809 } else if (!strcasecmp(colname, "expire")) { 13810 snprintf(buf, len, "%d", peer->expire); 13811 } else if (!strcasecmp(colname, "dynamic")) { 13812 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 13813 } else if (!strcasecmp(colname, "callerid_name")) { 13814 ast_copy_string(buf, peer->cid_name, len); 13815 } else if (!strcasecmp(colname, "callerid_num")) { 13816 ast_copy_string(buf, peer->cid_num, len); 13817 } else if (!strcasecmp(colname, "codecs")) { 13818 ast_getformatname_multiple(buf, len -1, peer->capability); 13819 } else if (!strncasecmp(colname, "codec[", 6)) { 13820 char *codecnum, *ptr; 13821 int codec = 0; 13822 13823 codecnum = strchr(colname, '['); 13824 *codecnum = '\0'; 13825 codecnum++; 13826 if ((ptr = strchr(codecnum, ']'))) { 13827 *ptr = '\0'; 13828 } 13829 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) { 13830 ast_copy_string(buf, ast_getformatname(codec), len); 13831 } else { 13832 buf[0] = '\0'; 13833 } 13834 } else { 13835 buf[0] = '\0'; 13836 } 13837 13838 peer_unref(peer); 13839 13840 return 0; 13841 }
static int get_auth_methods | ( | const char * | value | ) | [static] |
Definition at line 12138 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
12139 { 12140 int methods = 0; 12141 if (strstr(value, "rsa")) 12142 methods |= IAX_AUTH_RSA; 12143 if (strstr(value, "md5")) 12144 methods |= IAX_AUTH_MD5; 12145 if (strstr(value, "plaintext")) 12146 methods |= IAX_AUTH_PLAINTEXT; 12147 return methods; 12148 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1559 of file chan_iax2.c.
References ast_true(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.
Referenced by build_peer(), build_user(), and set_config().
01560 { 01561 int e; 01562 if (!strcasecmp(s, "aes128")) 01563 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01564 else if (ast_true(s)) 01565 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01566 else 01567 e = 0; 01568 return e; 01569 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 4118 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
04119 { 04120 #ifdef SCHED_MULTITHREADED 04121 if (schedule_action(__get_from_jb, data)) 04122 #endif 04123 __get_from_jb(data); 04124 return 0; 04125 }
static struct callno_entry * get_unused_callno | ( | int | trunk, | |
int | validated | |||
) | [static] |
Definition at line 2595 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().
02596 { 02597 struct callno_entry *callno_entry = NULL; 02598 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) { 02599 ast_log(LOG_WARNING, "Out of CallNumbers\n"); 02600 /* Minor optimization for the extreme case. */ 02601 return NULL; 02602 } 02603 02604 /* the callno_pool container is locked here primarily to ensure thread 02605 * safety of the total_nonval_callno_used check and increment */ 02606 ao2_lock(callno_pool); 02607 02608 /* only a certain number of nonvalidated call numbers should be allocated. 02609 * If there ever is an attack, this separates the calltoken validating 02610 * users from the non calltoken validating users. */ 02611 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) { 02612 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval); 02613 ao2_unlock(callno_pool); 02614 return NULL; 02615 } 02616 02617 /* unlink the object from the container, taking over ownership 02618 * of the reference the container had to the object */ 02619 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE); 02620 02621 if (callno_entry) { 02622 callno_entry->validated = validated; 02623 if (!validated) { 02624 total_nonval_callno_used++; 02625 } 02626 } 02627 02628 ao2_unlock(callno_pool); 02629 return callno_entry; 02630 }
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 4841 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().
04843 { 04844 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d" /* address + port + ts + randomcalldata */ 04845 #define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */ 04846 struct ast_str *buf = ast_str_alloca(256); 04847 time_t t = time(NULL); 04848 char hash[41]; /* 40 char sha1 hash */ 04849 int subclass = uncompress_subclass(fh->csub); 04850 04851 /* ----- Case 1 ----- */ 04852 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */ 04853 struct iax_ie_data ied = { 04854 .buf = { 0 }, 04855 .pos = 0, 04856 }; 04857 04858 /* create the hash with their address data and our timestamp */ 04859 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata); 04860 ast_sha1_hash(hash, ast_str_buffer(buf)); 04861 04862 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash); 04863 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf)); 04864 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied); 04865 04866 return 1; 04867 04868 /* ----- Case 2 ----- */ 04869 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */ 04870 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */ 04871 char *rec_ts = NULL; /* received timestamp */ 04872 unsigned int rec_time; /* received time_t */ 04873 04874 /* split the timestamp from the hash data */ 04875 rec_hash = strchr((char *) ies->calltokendata, '?'); 04876 if (rec_hash) { 04877 *rec_hash++ = '\0'; 04878 rec_ts = (char *) ies->calltokendata; 04879 } 04880 04881 /* check that we have valid data before we do any comparisons */ 04882 if (!rec_hash || !rec_ts) { 04883 goto reject; 04884 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) { 04885 goto reject; 04886 } 04887 04888 /* create a hash with their address and the _TOKEN'S_ timestamp */ 04889 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata); 04890 ast_sha1_hash(hash, ast_str_buffer(buf)); 04891 04892 /* compare hashes and then check timestamp delay */ 04893 if (strcmp(hash, rec_hash)) { 04894 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr)); 04895 goto reject; /* received hash does not match ours, reject */ 04896 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) { 04897 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr)); 04898 goto reject; /* too much delay, reject */ 04899 } 04900 04901 /* at this point the call token is valid, returning 0 04902 * will allow socket_process to continue as usual */ 04903 requirecalltoken_mark_auto(ies->username, subclass); 04904 return 0; 04905 04906 /* ----- Case 3 ----- */ 04907 } else { /* calltokens are not supported for this client, how do we respond? */ 04908 if (calltoken_required(sin, ies->username, subclass)) { 04909 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")); 04910 goto reject; 04911 } 04912 return 0; /* calltoken is not required for this addr, so permit it. */ 04913 } 04914 04915 reject: 04916 /* received frame has failed calltoken inspection, send apathetic reject messages */ 04917 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) { 04918 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04919 } else { 04920 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04921 } 04922 04923 return 1; 04924 }
static char* handle_cli_iax2_provision | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 11835 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.
11836 { 11837 int force = 0; 11838 int res; 11839 11840 switch (cmd) { 11841 case CLI_INIT: 11842 e->command = "iax2 provision"; 11843 e->usage = 11844 "Usage: iax2 provision <host> <template> [forced]\n" 11845 " Provisions the given peer or IP address using a template\n" 11846 " matching either 'template' or '*' if the template is not\n" 11847 " found. If 'forced' is specified, even empty provisioning\n" 11848 " fields will be provisioned as empty fields.\n"; 11849 return NULL; 11850 case CLI_GENERATE: 11851 if (a->pos == 3) 11852 return iax_prov_complete_template(a->line, a->word, a->pos, a->n); 11853 return NULL; 11854 } 11855 11856 if (a->argc < 4) 11857 return CLI_SHOWUSAGE; 11858 if (a->argc > 4) { 11859 if (!strcasecmp(a->argv[4], "forced")) 11860 force = 1; 11861 else 11862 return CLI_SHOWUSAGE; 11863 } 11864 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force); 11865 if (res < 0) 11866 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]); 11867 else if (res < 1) 11868 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]); 11869 else 11870 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : ""); 11871 return CLI_SUCCESS; 11872 }
static char* handle_cli_iax2_prune_realtime | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3550 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.
03551 { 03552 struct iax2_peer *peer = NULL; 03553 struct iax2_user *user = NULL; 03554 static const char * const choices[] = { "all", NULL }; 03555 char *cmplt; 03556 03557 switch (cmd) { 03558 case CLI_INIT: 03559 e->command = "iax2 prune realtime"; 03560 e->usage = 03561 "Usage: iax2 prune realtime [<peername>|all]\n" 03562 " Prunes object(s) from the cache\n"; 03563 return NULL; 03564 case CLI_GENERATE: 03565 if (a->pos == 3) { 03566 cmplt = ast_cli_complete(a->word, choices, a->n); 03567 if (!cmplt) 03568 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS); 03569 return cmplt; 03570 } 03571 return NULL; 03572 } 03573 if (a->argc != 4) 03574 return CLI_SHOWUSAGE; 03575 if (!strcmp(a->argv[3], "all")) { 03576 prune_users(); 03577 prune_peers(); 03578 ast_cli(a->fd, "Cache flushed successfully.\n"); 03579 return CLI_SUCCESS; 03580 } 03581 peer = find_peer(a->argv[3], 0); 03582 user = find_user(a->argv[3]); 03583 if (peer || user) { 03584 if (peer) { 03585 if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 03586 ast_set_flag64(peer, IAX_RTAUTOCLEAR); 03587 expire_registry(peer_ref(peer)); 03588 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]); 03589 } else { 03590 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]); 03591 } 03592 peer_unref(peer); 03593 } 03594 if (user) { 03595 if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 03596 ast_set_flag64(user, IAX_RTAUTOCLEAR); 03597 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]); 03598 } else { 03599 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]); 03600 } 03601 ao2_unlink(users,user); 03602 user_unref(user); 03603 } 03604 } else { 03605 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]); 03606 } 03607 03608 return CLI_SUCCESS; 03609 }
static char* handle_cli_iax2_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 13430 of file chan_iax2.c.
References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, reload_config(), and ast_cli_entry::usage.
13431 { 13432 switch (cmd) { 13433 case CLI_INIT: 13434 e->command = "iax2 reload"; 13435 e->usage = 13436 "Usage: iax2 reload\n" 13437 " Reloads IAX configuration from iax.conf\n"; 13438 return NULL; 13439 case CLI_GENERATE: 13440 return NULL; 13441 } 13442 13443 reload_config(); 13444 13445 return CLI_SUCCESS; 13446 }
static char* handle_cli_iax2_set_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7306 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.
07307 { 07308 switch (cmd) { 07309 case CLI_INIT: 07310 e->command = "iax2 set debug {on|off|peer}"; 07311 e->usage = 07312 "Usage: iax2 set debug {on|off|peer peername}\n" 07313 " Enables/Disables dumping of IAX packets for debugging purposes.\n"; 07314 return NULL; 07315 case CLI_GENERATE: 07316 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) 07317 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 07318 return NULL; 07319 } 07320 07321 if (a->argc < e->args || a->argc > e->args + 1) 07322 return CLI_SHOWUSAGE; 07323 07324 if (!strcasecmp(a->argv[3], "peer")) { 07325 struct iax2_peer *peer; 07326 struct sockaddr_in peer_addr; 07327 07328 07329 if (a->argc != e->args + 1) 07330 return CLI_SHOWUSAGE; 07331 07332 peer = find_peer(a->argv[4], 1); 07333 07334 if (!peer) { 07335 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]); 07336 return CLI_FAILURE; 07337 } 07338 07339 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 07340 07341 debugaddr.sin_addr = peer_addr.sin_addr; 07342 debugaddr.sin_port = peer_addr.sin_port; 07343 07344 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n", 07345 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 07346 07347 ao2_ref(peer, -1); 07348 } else if (!strncasecmp(a->argv[3], "on", 2)) { 07349 iaxdebug = 1; 07350 ast_cli(a->fd, "IAX2 Debugging Enabled\n"); 07351 } else { 07352 iaxdebug = 0; 07353 memset(&debugaddr, 0, sizeof(debugaddr)); 07354 ast_cli(a->fd, "IAX2 Debugging Disabled\n"); 07355 } 07356 return CLI_SUCCESS; 07357 }
static char* handle_cli_iax2_set_debug_jb | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7385 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.
07386 { 07387 switch (cmd) { 07388 case CLI_INIT: 07389 e->command = "iax2 set debug jb {on|off}"; 07390 e->usage = 07391 "Usage: iax2 set debug jb {on|off}\n" 07392 " Enables/Disables jitterbuffer debugging information\n"; 07393 return NULL; 07394 case CLI_GENERATE: 07395 return NULL; 07396 } 07397 07398 if (a->argc != e->args) 07399 return CLI_SHOWUSAGE; 07400 07401 if (!strncasecmp(a->argv[e->args -1], "on", 2)) { 07402 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 07403 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 07404 } else { 07405 jb_setoutput(jb_error_output, jb_warning_output, NULL); 07406 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 07407 } 07408 return CLI_SUCCESS; 07409 }
static char* handle_cli_iax2_set_debug_trunk | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7359 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.
07360 { 07361 switch (cmd) { 07362 case CLI_INIT: 07363 e->command = "iax2 set debug trunk {on|off}"; 07364 e->usage = 07365 "Usage: iax2 set debug trunk {on|off}\n" 07366 " Enables/Disables debugging of IAX trunking\n"; 07367 return NULL; 07368 case CLI_GENERATE: 07369 return NULL; 07370 } 07371 07372 if (a->argc != e->args) 07373 return CLI_SHOWUSAGE; 07374 07375 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 07376 iaxtrunkdebug = 1; 07377 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n"); 07378 } else { 07379 iaxtrunkdebug = 0; 07380 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n"); 07381 } 07382 return CLI_SUCCESS; 07383 }
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 3877 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.
03878 { 03879 int mtuv; 03880 03881 switch (cmd) { 03882 case CLI_INIT: 03883 e->command = "iax2 set mtu"; 03884 e->usage = 03885 "Usage: iax2 set mtu <value>\n" 03886 " Set the system-wide IAX IP mtu to <value> bytes net or\n" 03887 " zero to disable. Disabling means that the operating system\n" 03888 " must handle fragmentation of UDP packets when the IAX2 trunk\n" 03889 " packet exceeds the UDP payload size. This is substantially\n" 03890 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n" 03891 " greater for G.711 samples.\n"; 03892 return NULL; 03893 case CLI_GENERATE: 03894 return NULL; 03895 } 03896 03897 if (a->argc != 4) 03898 return CLI_SHOWUSAGE; 03899 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0) 03900 mtuv = MAX_TRUNK_MTU; 03901 else 03902 mtuv = atoi(a->argv[3]); 03903 03904 if (mtuv == 0) { 03905 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 03906 global_max_trunk_mtu = 0; 03907 return CLI_SUCCESS; 03908 } 03909 if (mtuv < 172 || mtuv > 4000) { 03910 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 03911 return CLI_SHOWUSAGE; 03912 } 03913 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 03914 global_max_trunk_mtu = mtuv; 03915 return CLI_SUCCESS; 03916 }
static char* handle_cli_iax2_show_cache | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3918 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.
03919 { 03920 struct iax2_dpcache *dp = NULL; 03921 char tmp[1024], *pc = NULL; 03922 int s, x, y; 03923 struct timeval now = ast_tvnow(); 03924 03925 switch (cmd) { 03926 case CLI_INIT: 03927 e->command = "iax2 show cache"; 03928 e->usage = 03929 "Usage: iax2 show cache\n" 03930 " Display currently cached IAX Dialplan results.\n"; 03931 return NULL; 03932 case CLI_GENERATE: 03933 return NULL; 03934 } 03935 03936 AST_LIST_LOCK(&dpcache); 03937 03938 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 03939 03940 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) { 03941 s = dp->expiry.tv_sec - now.tv_sec; 03942 tmp[0] = '\0'; 03943 if (dp->flags & CACHE_FLAG_EXISTS) 03944 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 03945 if (dp->flags & CACHE_FLAG_NONEXISTENT) 03946 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 03947 if (dp->flags & CACHE_FLAG_CANEXIST) 03948 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 03949 if (dp->flags & CACHE_FLAG_PENDING) 03950 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 03951 if (dp->flags & CACHE_FLAG_TIMEOUT) 03952 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 03953 if (dp->flags & CACHE_FLAG_TRANSMITTED) 03954 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 03955 if (dp->flags & CACHE_FLAG_MATCHMORE) 03956 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 03957 if (dp->flags & CACHE_FLAG_UNKNOWN) 03958 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 03959 /* Trim trailing pipe */ 03960 if (!ast_strlen_zero(tmp)) { 03961 tmp[strlen(tmp) - 1] = '\0'; 03962 } else { 03963 ast_copy_string(tmp, "(none)", sizeof(tmp)); 03964 } 03965 y = 0; 03966 pc = strchr(dp->peercontext, '@'); 03967 if (!pc) { 03968 pc = dp->peercontext; 03969 } else { 03970 pc++; 03971 } 03972 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 03973 if (dp->waiters[x] > -1) 03974 y++; 03975 } 03976 if (s > 0) { 03977 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 03978 } else { 03979 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 03980 } 03981 } 03982 03983 AST_LIST_UNLOCK(&dpcache); 03984 03985 return CLI_SUCCESS; 03986 }
static char* handle_cli_iax2_show_callno_limits | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2537 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.
02538 { 02539 struct ao2_iterator i; 02540 struct peercnt *peercnt; 02541 struct sockaddr_in sin; 02542 int found = 0; 02543 02544 switch (cmd) { 02545 case CLI_INIT: 02546 e->command = "iax2 show callnumber usage"; 02547 e->usage = 02548 "Usage: iax2 show callnumber usage [IP address]\n" 02549 " Shows current IP addresses which are consuming iax2 call numbers\n"; 02550 return NULL; 02551 case CLI_GENERATE: 02552 return NULL; 02553 case CLI_HANDLER: 02554 if (a->argc < 4 || a->argc > 5) 02555 return CLI_SHOWUSAGE; 02556 02557 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit"); 02558 i = ao2_iterator_init(peercnts, 0); 02559 while ((peercnt = ao2_iterator_next(&i))) { 02560 sin.sin_addr.s_addr = peercnt->addr; 02561 if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) { 02562 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02563 found = 1; 02564 break; 02565 } else { 02566 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02567 } 02568 ao2_ref(peercnt, -1); 02569 } 02570 ao2_iterator_destroy(&i); 02571 02572 if (a->argc == 4) { 02573 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n" 02574 "Non-CallToken Validated Callno Used: %d\n", 02575 global_maxcallno_nonval, 02576 total_nonval_callno_used); 02577 02578 ast_cli(a->fd, "Total Available Callno: %d\n" 02579 "Regular Callno Available: %d\n" 02580 "Trunk Callno Available: %d\n", 02581 ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk), 02582 ao2_container_count(callno_pool), 02583 ao2_container_count(callno_pool_trunk)); 02584 } else if (a->argc == 5 && !found) { 02585 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] ); 02586 } 02587 02588 02589 return CLI_SUCCESS; 02590 default: 02591 return NULL; 02592 } 02593 }
static char* handle_cli_iax2_show_channels | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7133 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.
07134 { 07135 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" 07136 #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" 07137 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 07138 int x; 07139 int numchans = 0; 07140 char first_message[10] = { 0, }; 07141 char last_message[10] = { 0, }; 07142 07143 switch (cmd) { 07144 case CLI_INIT: 07145 e->command = "iax2 show channels"; 07146 e->usage = 07147 "Usage: iax2 show channels\n" 07148 " Lists all currently active IAX channels.\n"; 07149 return NULL; 07150 case CLI_GENERATE: 07151 return NULL; 07152 } 07153 07154 if (a->argc != 3) 07155 return CLI_SHOWUSAGE; 07156 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg"); 07157 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07158 ast_mutex_lock(&iaxsl[x]); 07159 if (iaxs[x]) { 07160 int lag, jitter, localdelay; 07161 jb_info jbinfo; 07162 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07163 jb_getinfo(iaxs[x]->jb, &jbinfo); 07164 jitter = jbinfo.jitter; 07165 localdelay = jbinfo.current - jbinfo.min; 07166 } else { 07167 jitter = -1; 07168 localdelay = 0; 07169 } 07170 07171 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 07172 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 07173 lag = iaxs[x]->remote_rr.delay; 07174 ast_cli(a->fd, FORMAT, 07175 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07176 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 07177 S_OR(iaxs[x]->username, "(None)"), 07178 iaxs[x]->callno, iaxs[x]->peercallno, 07179 iaxs[x]->oseqno, iaxs[x]->iseqno, 07180 lag, 07181 jitter, 07182 localdelay, 07183 ast_getformatname(iaxs[x]->voiceformat), 07184 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07185 first_message, 07186 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07187 last_message); 07188 numchans++; 07189 } 07190 ast_mutex_unlock(&iaxsl[x]); 07191 } 07192 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 07193 return CLI_SUCCESS; 07194 #undef FORMAT 07195 #undef FORMAT2 07196 #undef FORMATB 07197 }
static char* handle_cli_iax2_show_firmware | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6919 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.
06920 { 06921 struct iax_firmware *cur = NULL; 06922 06923 switch (cmd) { 06924 case CLI_INIT: 06925 e->command = "iax2 show firmware"; 06926 e->usage = 06927 "Usage: iax2 show firmware\n" 06928 " Lists all known IAX firmware images.\n"; 06929 return NULL; 06930 case CLI_GENERATE: 06931 return NULL; 06932 } 06933 06934 if (a->argc != 3 && a->argc != 4) 06935 return CLI_SHOWUSAGE; 06936 06937 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size"); 06938 AST_LIST_LOCK(&firmwares); 06939 AST_LIST_TRAVERSE(&firmwares, cur, list) { 06940 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) { 06941 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname, 06942 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen)); 06943 } 06944 } 06945 AST_LIST_UNLOCK(&firmwares); 06946 06947 return CLI_SUCCESS; 06948 }
static char* handle_cli_iax2_show_netstats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7283 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.
07284 { 07285 int numchans = 0; 07286 07287 switch (cmd) { 07288 case CLI_INIT: 07289 e->command = "iax2 show netstats"; 07290 e->usage = 07291 "Usage: iax2 show netstats\n" 07292 " Lists network status for all currently active IAX channels.\n"; 07293 return NULL; 07294 case CLI_GENERATE: 07295 return NULL; 07296 } 07297 if (a->argc != 3) 07298 return CLI_SHOWUSAGE; 07299 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 07300 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n"); 07301 numchans = ast_cli_netstats(NULL, a->fd, 1); 07302 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 07303 return CLI_SUCCESS; 07304 }
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 3725 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.
03726 { 03727 char status[30]; 03728 char cbuf[256]; 03729 struct iax2_peer *peer; 03730 char codec_buf[512]; 03731 struct ast_str *encmethods = ast_str_alloca(256); 03732 int x = 0, codec = 0, load_realtime = 0; 03733 03734 switch (cmd) { 03735 case CLI_INIT: 03736 e->command = "iax2 show peer"; 03737 e->usage = 03738 "Usage: iax2 show peer <name>\n" 03739 " Display details on specific IAX peer\n"; 03740 return NULL; 03741 case CLI_GENERATE: 03742 if (a->pos == 3) 03743 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 03744 return NULL; 03745 } 03746 03747 if (a->argc < 4) 03748 return CLI_SHOWUSAGE; 03749 03750 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0; 03751 03752 peer = find_peer(a->argv[3], load_realtime); 03753 if (peer) { 03754 struct sockaddr_in peer_addr; 03755 03756 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 03757 03758 encmethods_to_str(peer->encmethods, encmethods); 03759 ast_cli(a->fd, "\n\n"); 03760 ast_cli(a->fd, " * Name : %s\n", peer->name); 03761 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>"); 03762 ast_cli(a->fd, " Context : %s\n", peer->context); 03763 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot); 03764 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox); 03765 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 03766 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno); 03767 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No")); 03768 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 03769 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 03770 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 03771 ast_cli(a->fd, " Expire : %d\n", peer->expire); 03772 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No")); 03773 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)); 03774 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 03775 ast_cli(a->fd, " Username : %s\n", peer->username); 03776 ast_cli(a->fd, " Codecs : "); 03777 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 03778 ast_cli(a->fd, "%s\n", codec_buf); 03779 03780 ast_cli(a->fd, " Codec Order : ("); 03781 for(x = 0; x < 32 ; x++) { 03782 codec = ast_codec_pref_index(&peer->prefs,x); 03783 if(!codec) 03784 break; 03785 ast_cli(a->fd, "%s", ast_getformatname(codec)); 03786 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 03787 ast_cli(a->fd, "|"); 03788 } 03789 03790 if (!x) 03791 ast_cli(a->fd, "none"); 03792 ast_cli(a->fd, ")\n"); 03793 03794 ast_cli(a->fd, " Status : "); 03795 peer_status(peer, status, sizeof(status)); 03796 ast_cli(a->fd, "%s\n",status); 03797 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"); 03798 ast_cli(a->fd, "\n"); 03799 peer_unref(peer); 03800 } else { 03801 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]); 03802 ast_cli(a->fd, "\n"); 03803 } 03804 03805 return CLI_SUCCESS; 03806 }
static char* handle_cli_iax2_show_peers | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6887 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.
06888 { 06889 switch (cmd) { 06890 case CLI_INIT: 06891 e->command = "iax2 show peers"; 06892 e->usage = 06893 "Usage: iax2 show peers [registered] [like <pattern>]\n" 06894 " Lists all known IAX2 peers.\n" 06895 " Optional 'registered' argument lists only peers with known addresses.\n" 06896 " Optional regular expression pattern is used to filter the peer list.\n"; 06897 return NULL; 06898 case CLI_GENERATE: 06899 return NULL; 06900 } 06901 06902 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) { 06903 case RESULT_SHOWUSAGE: 06904 return CLI_SHOWUSAGE; 06905 case RESULT_FAILURE: 06906 return CLI_FAILURE; 06907 default: 06908 return CLI_SUCCESS; 06909 } 06910 }
static char* handle_cli_iax2_show_registry | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7042 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.
07043 { 07044 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 07045 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 07046 struct iax2_registry *reg = NULL; 07047 char host[80]; 07048 char perceived[80]; 07049 int counter = 0; 07050 07051 switch (cmd) { 07052 case CLI_INIT: 07053 e->command = "iax2 show registry"; 07054 e->usage = 07055 "Usage: iax2 show registry\n" 07056 " Lists all registration requests and status.\n"; 07057 return NULL; 07058 case CLI_GENERATE: 07059 return NULL; 07060 } 07061 if (a->argc != 3) 07062 return CLI_SHOWUSAGE; 07063 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 07064 AST_LIST_LOCK(®istrations); 07065 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07066 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07067 if (reg->us.sin_addr.s_addr) 07068 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07069 else 07070 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07071 ast_cli(a->fd, FORMAT, host, 07072 (reg->dnsmgr) ? "Y" : "N", 07073 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 07074 counter++; 07075 } 07076 AST_LIST_UNLOCK(®istrations); 07077 ast_cli(a->fd, "%d IAX2 registrations.\n", counter); 07078 return CLI_SUCCESS; 07079 #undef FORMAT 07080 #undef FORMAT2 07081 }
static char* handle_cli_iax2_show_stats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3831 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.
03832 { 03833 struct iax_frame *cur; 03834 int cnt = 0, dead = 0, final = 0, i = 0; 03835 03836 switch (cmd) { 03837 case CLI_INIT: 03838 e->command = "iax2 show stats"; 03839 e->usage = 03840 "Usage: iax2 show stats\n" 03841 " Display statistics on IAX channel driver.\n"; 03842 return NULL; 03843 case CLI_GENERATE: 03844 return NULL; 03845 } 03846 03847 if (a->argc != 3) 03848 return CLI_SHOWUSAGE; 03849 03850 for (i = 0; i < ARRAY_LEN(frame_queue); i++) { 03851 ast_mutex_lock(&iaxsl[i]); 03852 AST_LIST_TRAVERSE(&frame_queue[i], cur, list) { 03853 if (cur->retries < 0) 03854 dead++; 03855 if (cur->final) 03856 final++; 03857 cnt++; 03858 } 03859 ast_mutex_unlock(&iaxsl[i]); 03860 } 03861 03862 ast_cli(a->fd, " IAX Statistics\n"); 03863 ast_cli(a->fd, "---------------------\n"); 03864 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 03865 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed, 03866 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu); 03867 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 03868 03869 trunk_timed = trunk_untimed = 0; 03870 if (trunk_maxmtu > trunk_nmaxmtu) 03871 trunk_nmaxmtu = trunk_maxmtu; 03872 03873 return CLI_SUCCESS; 03874 }
static char* handle_cli_iax2_show_threads | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6750 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.
06751 { 06752 struct iax2_thread *thread = NULL; 06753 time_t t; 06754 int threadcount = 0, dynamiccount = 0; 06755 char type; 06756 06757 switch (cmd) { 06758 case CLI_INIT: 06759 e->command = "iax2 show threads"; 06760 e->usage = 06761 "Usage: iax2 show threads\n" 06762 " Lists status of IAX helper threads\n"; 06763 return NULL; 06764 case CLI_GENERATE: 06765 return NULL; 06766 } 06767 if (a->argc != 3) 06768 return CLI_SHOWUSAGE; 06769 06770 ast_cli(a->fd, "IAX2 Thread Information\n"); 06771 time(&t); 06772 ast_cli(a->fd, "Idle Threads:\n"); 06773 AST_LIST_LOCK(&idle_list); 06774 AST_LIST_TRAVERSE(&idle_list, thread, list) { 06775 #ifdef DEBUG_SCHED_MULTITHREAD 06776 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06777 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06778 #else 06779 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06780 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06781 #endif 06782 threadcount++; 06783 } 06784 AST_LIST_UNLOCK(&idle_list); 06785 ast_cli(a->fd, "Active Threads:\n"); 06786 AST_LIST_LOCK(&active_list); 06787 AST_LIST_TRAVERSE(&active_list, thread, list) { 06788 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) 06789 type = 'D'; 06790 else 06791 type = 'P'; 06792 #ifdef DEBUG_SCHED_MULTITHREAD 06793 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 06794 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06795 #else 06796 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 06797 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06798 #endif 06799 threadcount++; 06800 } 06801 AST_LIST_UNLOCK(&active_list); 06802 ast_cli(a->fd, "Dynamic Threads:\n"); 06803 AST_LIST_LOCK(&dynamic_list); 06804 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 06805 #ifdef DEBUG_SCHED_MULTITHREAD 06806 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06807 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06808 #else 06809 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06810 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06811 #endif 06812 dynamiccount++; 06813 } 06814 AST_LIST_UNLOCK(&dynamic_list); 06815 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 06816 return CLI_SUCCESS; 06817 }
static char* handle_cli_iax2_show_users | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6539 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.
06540 { 06541 regex_t regexbuf; 06542 int havepattern = 0; 06543 06544 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 06545 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 06546 06547 struct iax2_user *user = NULL; 06548 char auth[90]; 06549 char *pstr = ""; 06550 struct ao2_iterator i; 06551 06552 switch (cmd) { 06553 case CLI_INIT: 06554 e->command = "iax2 show users [like]"; 06555 e->usage = 06556 "Usage: iax2 show users [like <pattern>]\n" 06557 " Lists all known IAX2 users.\n" 06558 " Optional regular expression pattern is used to filter the user list.\n"; 06559 return NULL; 06560 case CLI_GENERATE: 06561 return NULL; 06562 } 06563 06564 switch (a->argc) { 06565 case 5: 06566 if (!strcasecmp(a->argv[3], "like")) { 06567 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 06568 return CLI_SHOWUSAGE; 06569 havepattern = 1; 06570 } else 06571 return CLI_SHOWUSAGE; 06572 case 3: 06573 break; 06574 default: 06575 return CLI_SHOWUSAGE; 06576 } 06577 06578 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 06579 i = ao2_iterator_init(users, 0); 06580 for (user = ao2_iterator_next(&i); user; 06581 user_unref(user), user = ao2_iterator_next(&i)) { 06582 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 06583 continue; 06584 06585 if (!ast_strlen_zero(user->secret)) { 06586 ast_copy_string(auth,user->secret, sizeof(auth)); 06587 } else if (!ast_strlen_zero(user->inkeys)) { 06588 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 06589 } else 06590 ast_copy_string(auth, "-no secret-", sizeof(auth)); 06591 06592 if(ast_test_flag64(user, IAX_CODEC_NOCAP)) 06593 pstr = "REQ Only"; 06594 else if(ast_test_flag64(user, IAX_CODEC_NOPREFS)) 06595 pstr = "Disabled"; 06596 else 06597 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 06598 06599 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 06600 user->contexts ? user->contexts->context : DEFAULT_CONTEXT, 06601 user->ha ? "Yes" : "No", pstr); 06602 } 06603 ao2_iterator_destroy(&i); 06604 06605 if (havepattern) 06606 regfree(®exbuf); 06607 06608 return CLI_SUCCESS; 06609 #undef FORMAT 06610 #undef FORMAT2 06611 }
static char* handle_cli_iax2_test_losspct | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3611 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.
03612 { 03613 switch (cmd) { 03614 case CLI_INIT: 03615 e->command = "iax2 test losspct"; 03616 e->usage = 03617 "Usage: iax2 test losspct <percentage>\n" 03618 " For testing, throws away <percentage> percent of incoming packets\n"; 03619 return NULL; 03620 case CLI_GENERATE: 03621 return NULL; 03622 } 03623 if (a->argc != 4) 03624 return CLI_SHOWUSAGE; 03625 03626 test_losspct = atoi(a->argv[3]); 03627 03628 return CLI_SUCCESS; 03629 }
static char* handle_cli_iax2_unregister | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6819 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.
06820 { 06821 struct iax2_peer *p; 06822 06823 switch (cmd) { 06824 case CLI_INIT: 06825 e->command = "iax2 unregister"; 06826 e->usage = 06827 "Usage: iax2 unregister <peername>\n" 06828 " Unregister (force expiration) an IAX2 peer from the registry.\n"; 06829 return NULL; 06830 case CLI_GENERATE: 06831 return complete_iax2_unregister(a->line, a->word, a->pos, a->n); 06832 } 06833 06834 if (a->argc != 3) 06835 return CLI_SHOWUSAGE; 06836 06837 p = find_peer(a->argv[2], 1); 06838 if (p) { 06839 if (p->expire > 0) { 06840 struct iax2_peer tmp_peer = { 06841 .name = a->argv[2], 06842 }; 06843 struct iax2_peer *peer; 06844 06845 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 06846 if (peer) { 06847 expire_registry(peer_ref(peer)); /* will release its own reference when done */ 06848 peer_unref(peer); /* ref from ao2_find() */ 06849 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]); 06850 } else { 06851 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]); 06852 } 06853 } else { 06854 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 06855 } 06856 } else { 06857 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]); 06858 } 06859 return CLI_SUCCESS; 06860 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 9455 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.
09456 { 09457 struct iax2_pkt_buf *pkt_buf; 09458 09459 ast_mutex_lock(&thread->lock); 09460 09461 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 09462 ast_mutex_unlock(&thread->lock); 09463 09464 thread->buf = pkt_buf->buf; 09465 thread->buf_len = pkt_buf->len; 09466 thread->buf_size = pkt_buf->len + 1; 09467 09468 socket_process(thread); 09469 09470 thread->buf = NULL; 09471 ast_free(pkt_buf); 09472 09473 ast_mutex_lock(&thread->lock); 09474 } 09475 09476 ast_mutex_unlock(&thread->lock); 09477 }
static int handle_error | ( | void | ) | [static] |
Definition at line 3266 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().
03267 { 03268 /* XXX Ideally we should figure out why an error occurred and then abort those 03269 rather than continuing to try. Unfortunately, the published interface does 03270 not seem to work XXX */ 03271 #if 0 03272 struct sockaddr_in *sin; 03273 int res; 03274 struct msghdr m; 03275 struct sock_extended_err e; 03276 m.msg_name = NULL; 03277 m.msg_namelen = 0; 03278 m.msg_iov = NULL; 03279 m.msg_control = &e; 03280 m.msg_controllen = sizeof(e); 03281 m.msg_flags = 0; 03282 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 03283 if (res < 0) 03284 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 03285 else { 03286 if (m.msg_controllen) { 03287 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 03288 if (sin) 03289 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 03290 else 03291 ast_log(LOG_WARNING, "No address detected??\n"); 03292 } else { 03293 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 03294 } 03295 } 03296 #endif 03297 return 0; 03298 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 8408 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().
08409 { 08410 struct iax2_registry *reg; 08411 /* Start pessimistic */ 08412 char peer[256] = ""; 08413 char msgstatus[60]; 08414 int refresh = 60; 08415 char ourip[256] = "<Unspecified>"; 08416 struct sockaddr_in oldus; 08417 struct sockaddr_in us; 08418 int oldmsgs; 08419 struct sockaddr_in reg_addr; 08420 08421 memset(&us, 0, sizeof(us)); 08422 if (ies->apparent_addr) 08423 memmove(&us, ies->apparent_addr, sizeof(us)); 08424 if (ies->username) 08425 ast_copy_string(peer, ies->username, sizeof(peer)); 08426 if (ies->refresh) 08427 refresh = ies->refresh; 08428 if (ies->calling_number) { 08429 /* We don't do anything with it really, but maybe we should */ 08430 } 08431 reg = iaxs[callno]->reg; 08432 if (!reg) { 08433 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 08434 return -1; 08435 } 08436 memcpy(&oldus, ®->us, sizeof(oldus)); 08437 oldmsgs = reg->messages; 08438 ast_sockaddr_to_sin(®->addr, ®_addr); 08439 if (inaddrcmp(®_addr, sin)) { 08440 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08441 return -1; 08442 } 08443 memcpy(®->us, &us, sizeof(reg->us)); 08444 if (ies->msgcount >= 0) 08445 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 08446 /* always refresh the registration at the interval requested by the server 08447 we are registering to 08448 */ 08449 reg->refresh = refresh; 08450 reg->expire = iax2_sched_replace(reg->expire, sched, 08451 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08452 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 08453 if (reg->messages > 255) 08454 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 08455 else if (reg->messages > 1) 08456 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 08457 else if (reg->messages > 0) 08458 ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus)); 08459 else 08460 ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus)); 08461 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 08462 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 08463 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 08464 } 08465 reg->regstate = REG_STATE_REGISTERED; 08466 return 0; 08467 }
static int attribute_pure iax2_allow_new | ( | int | frametype, | |
int | subclass, | |||
int | inbound | |||
) | [inline, static] |
Definition at line 2731 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().
02732 { 02733 if (frametype != AST_FRAME_IAX) { 02734 return 0; 02735 } 02736 switch (subclass) { 02737 case IAX_COMMAND_NEW: 02738 case IAX_COMMAND_REGREQ: 02739 case IAX_COMMAND_FWDOWNL: 02740 case IAX_COMMAND_REGREL: 02741 return 1; 02742 case IAX_COMMAND_POKE: 02743 if (!inbound) { 02744 return 1; 02745 } 02746 break; 02747 } 02748 return 0; 02749 }
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 1324 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().
01325 { 01326 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 01327 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n", 01328 pvt->owner ? pvt->owner->name : "", 01329 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : ""); 01330 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5591 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.
05592 { 05593 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05594 ast_debug(1, "Answering IAX2 call\n"); 05595 ast_mutex_lock(&iaxsl[callno]); 05596 if (iaxs[callno]) 05597 iax2_ami_channelupdate(iaxs[callno]); 05598 ast_mutex_unlock(&iaxsl[callno]); 05599 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 05600 }
static int iax2_append_register | ( | const char * | hostname, | |
const char * | username, | |||
const char * | secret, | |||
const char * | porta | |||
) | [static] |
Definition at line 8469 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().
08471 { 08472 struct iax2_registry *reg; 08473 08474 if (!(reg = ast_calloc(1, sizeof(*reg)))) 08475 return -1; 08476 08477 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) { 08478 ast_free(reg); 08479 return -1; 08480 } 08481 08482 ast_copy_string(reg->username, username, sizeof(reg->username)); 08483 08484 if (secret) 08485 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 08486 08487 reg->expire = -1; 08488 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 08489 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO); 08490 08491 AST_LIST_LOCK(®istrations); 08492 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 08493 AST_LIST_UNLOCK(®istrations); 08494 08495 return 0; 08496 }
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 5436 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().
05437 { 05438 struct ast_channel *cs[3]; 05439 struct ast_channel *who, *other; 05440 int to = -1; 05441 int res = -1; 05442 int transferstarted=0; 05443 struct ast_frame *f; 05444 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 05445 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 05446 struct timeval waittimer = {0, 0}; 05447 05448 /* We currently do not support native bridging if a timeoutms value has been provided */ 05449 if (timeoutms > 0) { 05450 return AST_BRIDGE_FAILED; 05451 } 05452 05453 timeoutms = -1; 05454 05455 lock_both(callno0, callno1); 05456 if (!iaxs[callno0] || !iaxs[callno1]) { 05457 unlock_both(callno0, callno1); 05458 return AST_BRIDGE_FAILED; 05459 } 05460 /* Put them in native bridge mode */ 05461 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 05462 iaxs[callno0]->bridgecallno = callno1; 05463 iaxs[callno1]->bridgecallno = callno0; 05464 } 05465 unlock_both(callno0, callno1); 05466 05467 /* If not, try to bridge until we can execute a transfer, if we can */ 05468 cs[0] = c0; 05469 cs[1] = c1; 05470 for (/* ever */;;) { 05471 /* Check in case we got masqueraded into */ 05472 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 05473 ast_verb(3, "Can't masquerade, we're different...\n"); 05474 /* Remove from native mode */ 05475 if (c0->tech == &iax2_tech) { 05476 ast_mutex_lock(&iaxsl[callno0]); 05477 iaxs[callno0]->bridgecallno = 0; 05478 ast_mutex_unlock(&iaxsl[callno0]); 05479 } 05480 if (c1->tech == &iax2_tech) { 05481 ast_mutex_lock(&iaxsl[callno1]); 05482 iaxs[callno1]->bridgecallno = 0; 05483 ast_mutex_unlock(&iaxsl[callno1]); 05484 } 05485 return AST_BRIDGE_FAILED_NOWARN; 05486 } 05487 if (c0->nativeformats != c1->nativeformats) { 05488 char buf0[256]; 05489 char buf1[256]; 05490 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats); 05491 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats); 05492 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1); 05493 /* Remove from native mode */ 05494 lock_both(callno0, callno1); 05495 if (iaxs[callno0]) 05496 iaxs[callno0]->bridgecallno = 0; 05497 if (iaxs[callno1]) 05498 iaxs[callno1]->bridgecallno = 0; 05499 unlock_both(callno0, callno1); 05500 return AST_BRIDGE_FAILED_NOWARN; 05501 } 05502 /* check if transfered and if we really want native bridging */ 05503 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) { 05504 /* Try the transfer */ 05505 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 05506 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA))) 05507 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 05508 transferstarted = 1; 05509 } 05510 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 05511 /* Call has been transferred. We're no longer involved */ 05512 struct timeval now = ast_tvnow(); 05513 if (ast_tvzero(waittimer)) { 05514 waittimer = now; 05515 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 05516 c0->_softhangup |= AST_SOFTHANGUP_DEV; 05517 c1->_softhangup |= AST_SOFTHANGUP_DEV; 05518 *fo = NULL; 05519 *rc = c0; 05520 res = AST_BRIDGE_COMPLETE; 05521 break; 05522 } 05523 } 05524 to = 1000; 05525 who = ast_waitfor_n(cs, 2, &to); 05526 if (timeoutms > -1) { 05527 timeoutms -= (1000 - to); 05528 if (timeoutms < 0) 05529 timeoutms = 0; 05530 } 05531 if (!who) { 05532 if (!timeoutms) { 05533 res = AST_BRIDGE_RETRY; 05534 break; 05535 } 05536 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 05537 res = AST_BRIDGE_FAILED; 05538 break; 05539 } 05540 continue; 05541 } 05542 f = ast_read(who); 05543 if (!f) { 05544 *fo = NULL; 05545 *rc = who; 05546 res = AST_BRIDGE_COMPLETE; 05547 break; 05548 } 05549 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass.integer != AST_CONTROL_SRCUPDATE)) { 05550 *fo = f; 05551 *rc = who; 05552 res = AST_BRIDGE_COMPLETE; 05553 break; 05554 } 05555 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 05556 if ((f->frametype == AST_FRAME_VOICE) || 05557 (f->frametype == AST_FRAME_TEXT) || 05558 (f->frametype == AST_FRAME_VIDEO) || 05559 (f->frametype == AST_FRAME_IMAGE) || 05560 (f->frametype == AST_FRAME_DTMF) || 05561 (f->frametype == AST_FRAME_CONTROL)) { 05562 /* monitored dtmf take out of the bridge. 05563 * check if we monitor the specific source. 05564 */ 05565 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 05566 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 05567 *rc = who; 05568 *fo = f; 05569 res = AST_BRIDGE_COMPLETE; 05570 /* Remove from native mode */ 05571 break; 05572 } 05573 /* everything else goes to the other side */ 05574 ast_write(other, f); 05575 } 05576 ast_frfree(f); 05577 /* Swap who gets priority */ 05578 cs[2] = cs[0]; 05579 cs[0] = cs[1]; 05580 cs[1] = cs[2]; 05581 } 05582 lock_both(callno0, callno1); 05583 if(iaxs[callno0]) 05584 iaxs[callno0]->bridgecallno = 0; 05585 if(iaxs[callno1]) 05586 iaxs[callno1]->bridgecallno = 0; 05587 unlock_both(callno0, callno1); 05588 return res; 05589 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 4984 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.
04985 { 04986 struct sockaddr_in sin; 04987 char *l=NULL, *n=NULL, *tmpstr; 04988 struct iax_ie_data ied; 04989 char *defaultrdest = "s"; 04990 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04991 struct parsed_dial_string pds; 04992 struct create_addr_info cai; 04993 struct ast_var_t *var; 04994 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL); 04995 const char* osp_token_ptr; 04996 unsigned int osp_token_length; 04997 unsigned char osp_block_index; 04998 unsigned int osp_block_length; 04999 unsigned char osp_buffer[256]; 05000 05001 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 05002 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 05003 return -1; 05004 } 05005 05006 memset(&cai, 0, sizeof(cai)); 05007 cai.encmethods = iax2_encryption; 05008 05009 memset(&pds, 0, sizeof(pds)); 05010 tmpstr = ast_strdupa(dest); 05011 parse_dial_string(tmpstr, &pds); 05012 05013 if (ast_strlen_zero(pds.peer)) { 05014 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 05015 return -1; 05016 } 05017 if (!pds.exten) { 05018 pds.exten = defaultrdest; 05019 } 05020 if (create_addr(pds.peer, c, &sin, &cai)) { 05021 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 05022 return -1; 05023 } 05024 if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) { 05025 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n"); 05026 c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05027 return -1; 05028 } 05029 if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 05030 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n"); 05031 return -1; 05032 } 05033 if (!pds.username && !ast_strlen_zero(cai.username)) 05034 pds.username = cai.username; 05035 if (!pds.password && !ast_strlen_zero(cai.secret)) 05036 pds.password = cai.secret; 05037 if (!pds.key && !ast_strlen_zero(cai.outkey)) 05038 pds.key = cai.outkey; 05039 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 05040 pds.context = cai.peercontext; 05041 05042 /* Keep track of the context for outgoing calls too */ 05043 ast_copy_string(c->context, cai.context, sizeof(c->context)); 05044 05045 if (pds.port) 05046 sin.sin_port = htons(atoi(pds.port)); 05047 05048 l = c->connected.id.number.valid ? c->connected.id.number.str : NULL; 05049 n = c->connected.id.name.valid ? c->connected.id.name.str : NULL; 05050 05051 /* Now build request */ 05052 memset(&ied, 0, sizeof(ied)); 05053 05054 /* On new call, first IE MUST be IAX version of caller */ 05055 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 05056 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 05057 if (pds.options && strchr(pds.options, 'a')) { 05058 /* Request auto answer */ 05059 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 05060 } 05061 05062 /* WARNING: this breaks down at 190 bits! */ 05063 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 05064 05065 if (l) { 05066 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 05067 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05068 ast_party_id_presentation(&c->connected.id)); 05069 } else if (n) { 05070 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05071 ast_party_id_presentation(&c->connected.id)); 05072 } else { 05073 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 05074 } 05075 05076 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan); 05077 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select); 05078 05079 if (n) 05080 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 05081 if (ast_test_flag64(iaxs[callno], IAX_SENDANI) 05082 && c->connected.ani.number.valid 05083 && c->connected.ani.number.str) { 05084 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str); 05085 } 05086 05087 if (!ast_strlen_zero(c->language)) 05088 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 05089 if (!ast_strlen_zero(c->dialed.number.str)) { 05090 iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str); 05091 } 05092 if (c->redirecting.from.number.valid 05093 && !ast_strlen_zero(c->redirecting.from.number.str)) { 05094 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str); 05095 } 05096 05097 if (pds.context) 05098 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 05099 05100 if (pds.username) 05101 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 05102 05103 if (cai.encmethods) 05104 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 05105 05106 ast_mutex_lock(&iaxsl[callno]); 05107 05108 if (!ast_strlen_zero(c->context)) 05109 ast_string_field_set(iaxs[callno], context, c->context); 05110 05111 if (pds.username) 05112 ast_string_field_set(iaxs[callno], username, pds.username); 05113 05114 iaxs[callno]->encmethods = cai.encmethods; 05115 05116 iaxs[callno]->adsi = cai.adsi; 05117 05118 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 05119 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 05120 05121 if (pds.key) 05122 ast_string_field_set(iaxs[callno], outkey, pds.key); 05123 if (pds.password) 05124 ast_string_field_set(iaxs[callno], secret, pds.password); 05125 05126 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats); 05127 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats); 05128 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability); 05129 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability); 05130 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 05131 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 05132 05133 if (iaxs[callno]->maxtime) { 05134 /* Initialize pingtime and auto-congest time */ 05135 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 05136 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 05137 } else if (autokill) { 05138 iaxs[callno]->pingtime = autokill / 2; 05139 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 05140 } 05141 05142 /* Check if there is an OSP token */ 05143 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN"); 05144 if (!ast_strlen_zero(osp_token_ptr)) { 05145 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) { 05146 osp_block_index = 0; 05147 while (osp_token_length > 0) { 05148 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length; 05149 osp_buffer[0] = osp_block_index; 05150 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length); 05151 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1); 05152 osp_block_index++; 05153 osp_token_ptr += osp_block_length; 05154 osp_token_length -= osp_block_length; 05155 } 05156 } else 05157 ast_log(LOG_WARNING, "OSP token is too long\n"); 05158 } else if (iaxdebug) 05159 ast_debug(1, "OSP token is undefined\n"); 05160 05161 /* send the command using the appropriate socket for this peer */ 05162 iaxs[callno]->sockfd = cai.sockfd; 05163 05164 /* Add remote vars */ 05165 if (variablestore) { 05166 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data; 05167 ast_debug(1, "Found an IAX variable store on this channel\n"); 05168 AST_LIST_LOCK(variablelist); 05169 AST_LIST_TRAVERSE(variablelist, var, entries) { 05170 char tmp[256]; 05171 int i; 05172 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var)); 05173 /* Automatically divide the value up into sized chunks */ 05174 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) { 05175 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i); 05176 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp); 05177 } 05178 } 05179 AST_LIST_UNLOCK(variablelist); 05180 } 05181 05182 /* Transmit the string in a "NEW" request */ 05183 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 05184 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 05185 05186 ast_mutex_unlock(&iaxsl[callno]); 05187 ast_setstate(c, AST_STATE_RINGING); 05188 05189 return 0; 05190 }
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 13679 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.
13680 { 13681 int res = 0; 13682 struct iax2_dpcache *dp = NULL; 13683 #if 0 13684 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13685 #endif 13686 if ((priority != 1) && (priority != 2)) 13687 return 0; 13688 13689 AST_LIST_LOCK(&dpcache); 13690 if ((dp = find_cache(chan, data, context, exten, priority))) { 13691 if (dp->flags & CACHE_FLAG_CANEXIST) 13692 res = 1; 13693 } else { 13694 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13695 } 13696 AST_LIST_UNLOCK(&dpcache); 13697 13698 return res; 13699 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 4657 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().
04658 { 04659 struct timeval t = ast_tvnow(); 04660 struct ast_tm tm; 04661 unsigned int tmp; 04662 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz); 04663 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 04664 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 04665 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 04666 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 04667 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 04668 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 04669 return tmp; 04670 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 3372 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().
03373 { 03374 struct chan_iax2_pvt *pvt = NULL; 03375 struct ast_channel *owner = NULL; 03376 03377 retry: 03378 if ((pvt = iaxs[callno])) { 03379 #if 0 03380 /* iax2_destroy_helper gets called from this function later on. When 03381 * called twice, we get the (previously) familiar FRACK! errors in 03382 * devmode, from the scheduler. An alternative to this approach is to 03383 * reset the scheduler entries to -1 when they're deleted in 03384 * iax2_destroy_helper(). That approach was previously decided to be 03385 * "wrong" because "the memory is going to be deallocated anyway. Why 03386 * should we be resetting those values?" */ 03387 iax2_destroy_helper(pvt); 03388 #endif 03389 } 03390 03391 owner = pvt ? pvt->owner : NULL; 03392 03393 if (owner) { 03394 if (ast_channel_trylock(owner)) { 03395 ast_debug(3, "Avoiding IAX destroy deadlock\n"); 03396 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03397 goto retry; 03398 } 03399 } 03400 03401 if (!owner) { 03402 iaxs[callno] = NULL; 03403 } 03404 03405 if (pvt) { 03406 if (!owner) { 03407 pvt->owner = NULL; 03408 } else { 03409 /* If there's an owner, prod it to give up */ 03410 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 03411 * because we already hold the owner channel lock. */ 03412 ast_queue_hangup(owner); 03413 } 03414 03415 if (pvt->peercallno) { 03416 remove_by_peercallno(pvt); 03417 } 03418 03419 if (pvt->transfercallno) { 03420 remove_by_transfercallno(pvt); 03421 } 03422 03423 if (!owner) { 03424 ao2_ref(pvt, -1); 03425 pvt = NULL; 03426 } 03427 } 03428 03429 if (owner) { 03430 ast_channel_unlock(owner); 03431 } 03432 03433 if (callno & 0x4000) { 03434 update_max_trunk(); 03435 } 03436 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1772 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().
01773 { 01774 /* Decrement AUTHREQ count if needed */ 01775 if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) { 01776 struct iax2_user *user; 01777 struct iax2_user tmp_user = { 01778 .name = pvt->username, 01779 }; 01780 01781 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01782 if (user) { 01783 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01784 user_unref(user); 01785 } 01786 01787 ast_clear_flag64(pvt, IAX_MAXAUTHREQ); 01788 } 01789 /* No more pings or lagrq's */ 01790 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]); 01791 pvt->pingid = DONT_RESCHEDULE; 01792 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]); 01793 pvt->lagid = DONT_RESCHEDULE; 01794 ast_sched_thread_del(sched, pvt->autoid); 01795 ast_sched_thread_del(sched, pvt->authid); 01796 ast_sched_thread_del(sched, pvt->initid); 01797 ast_sched_thread_del(sched, pvt->jbid); 01798 ast_sched_thread_del(sched, pvt->keyrotateid); 01799 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 13884 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().
13885 { 13886 struct parsed_dial_string pds; 13887 char *tmp = ast_strdupa(data); 13888 struct iax2_peer *p; 13889 int res = AST_DEVICE_INVALID; 13890 13891 memset(&pds, 0, sizeof(pds)); 13892 parse_dial_string(tmp, &pds); 13893 13894 if (ast_strlen_zero(pds.peer)) { 13895 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 13896 return res; 13897 } 13898 13899 ast_debug(3, "Checking device state for device %s\n", pds.peer); 13900 13901 /* SLD: FIXME: second call to find_peer during registration */ 13902 if (!(p = find_peer(pds.peer, 1))) 13903 return res; 13904 13905 res = AST_DEVICE_UNAVAILABLE; 13906 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 13907 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 13908 13909 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) && 13910 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 13911 /* Peer is registered, or have default IP address 13912 and a valid registration */ 13913 if (p->historicms == 0 || p->historicms <= p->maxms) 13914 /* let the core figure out whether it is in use or not */ 13915 res = AST_DEVICE_UNKNOWN; 13916 } 13917 13918 peer_unref(p); 13919 13920 return res; 13921 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 4262 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04263 { 04264 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 04265 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 4267 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04268 { 04269 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 04270 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 11693 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().
11694 { 11695 struct iax_ie_data ied; 11696 if (iaxdebug) 11697 ast_debug(1, "Sending registration request for '%s'\n", reg->username); 11698 11699 if (reg->dnsmgr && 11700 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) { 11701 /* Maybe the IP has changed, force DNS refresh */ 11702 ast_dnsmgr_refresh(reg->dnsmgr); 11703 } 11704 11705 /* 11706 * if IP has Changed, free allocated call to create a new one with new IP 11707 * call has the pointer to IP and must be updated to the new one 11708 */ 11709 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 11710 int callno = reg->callno; 11711 ast_mutex_lock(&iaxsl[callno]); 11712 iax2_destroy(callno); 11713 ast_mutex_unlock(&iaxsl[callno]); 11714 reg->callno = 0; 11715 } 11716 if (!ast_sockaddr_ipv4(®->addr)) { 11717 if (iaxdebug) 11718 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username); 11719 /* Setup the next registration attempt */ 11720 reg->expire = iax2_sched_replace(reg->expire, sched, 11721 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11722 return -1; 11723 } 11724 11725 if (!reg->callno) { 11726 struct sockaddr_in reg_addr; 11727 11728 ast_debug(3, "Allocate call number\n"); 11729 11730 ast_sockaddr_to_sin(®->addr, ®_addr); 11731 11732 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0); 11733 if (reg->callno < 1) { 11734 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 11735 return -1; 11736 } else 11737 ast_debug(3, "Registration created on call %d\n", reg->callno); 11738 iaxs[reg->callno]->reg = reg; 11739 ast_mutex_unlock(&iaxsl[reg->callno]); 11740 } 11741 /* Setup the next registration a little early */ 11742 reg->expire = iax2_sched_replace(reg->expire, sched, 11743 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11744 /* Send the request */ 11745 memset(&ied, 0, sizeof(ied)); 11746 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 11747 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 11748 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */ 11749 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 11750 reg->regstate = REG_STATE_REGSENT; 11751 return 0; 11752 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8255 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
08256 { 08257 #ifdef SCHED_MULTITHREADED 08258 if (schedule_action(__iax2_do_register_s, data)) 08259 #endif 08260 __iax2_do_register_s(data); 08261 return 0; 08262 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 9020 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().
09021 { 09022 struct iax_ie_data ied; 09023 /* Auto-hangup with 30 seconds of inactivity */ 09024 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 09025 sched, 30000, auto_hangup, (void *)(long)callno); 09026 memset(&ied, 0, sizeof(ied)); 09027 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 09028 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 09029 dp->flags |= CACHE_FLAG_TRANSMITTED; 09030 }
static void * iax2_dup_variable_datastore | ( | void * | ) | [static] |
Definition at line 1338 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.
01339 { 01340 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist; 01341 struct ast_var_t *oldvar, *newvar; 01342 01343 newlist = ast_calloc(sizeof(*newlist), 1); 01344 if (!newlist) { 01345 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n"); 01346 return NULL; 01347 } 01348 01349 AST_LIST_HEAD_INIT(newlist); 01350 AST_LIST_LOCK(oldlist); 01351 AST_LIST_TRAVERSE(oldlist, oldvar, entries) { 01352 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar)); 01353 if (newvar) 01354 AST_LIST_INSERT_TAIL(newlist, newvar, entries); 01355 else 01356 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar)); 01357 } 01358 AST_LIST_UNLOCK(oldlist); 01359 return newlist; 01360 }
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 13725 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().
13726 { 13727 char odata[256]; 13728 char req[256]; 13729 char *ncontext; 13730 struct iax2_dpcache *dp = NULL; 13731 struct ast_app *dial = NULL; 13732 #if 0 13733 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); 13734 #endif 13735 if (priority == 2) { 13736 /* Indicate status, can be overridden in dialplan */ 13737 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 13738 if (dialstatus) { 13739 dial = pbx_findapp(dialstatus); 13740 if (dial) 13741 pbx_exec(chan, dial, ""); 13742 } 13743 return -1; 13744 } else if (priority != 1) 13745 return -1; 13746 13747 AST_LIST_LOCK(&dpcache); 13748 if ((dp = find_cache(chan, data, context, exten, priority))) { 13749 if (dp->flags & CACHE_FLAG_EXISTS) { 13750 ast_copy_string(odata, data, sizeof(odata)); 13751 ncontext = strchr(odata, '/'); 13752 if (ncontext) { 13753 *ncontext = '\0'; 13754 ncontext++; 13755 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 13756 } else { 13757 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 13758 } 13759 ast_verb(3, "Executing Dial('%s')\n", req); 13760 } else { 13761 AST_LIST_UNLOCK(&dpcache); 13762 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 13763 return -1; 13764 } 13765 } 13766 AST_LIST_UNLOCK(&dpcache); 13767 13768 if ((dial = pbx_findapp("Dial"))) 13769 return pbx_exec(chan, dial, req); 13770 else 13771 ast_log(LOG_WARNING, "No dial application registered\n"); 13772 13773 return -1; 13774 }
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 13656 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.
13657 { 13658 int res = 0; 13659 struct iax2_dpcache *dp = NULL; 13660 #if 0 13661 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13662 #endif 13663 if ((priority != 1) && (priority != 2)) 13664 return 0; 13665 13666 AST_LIST_LOCK(&dpcache); 13667 if ((dp = find_cache(chan, data, context, exten, priority))) { 13668 if (dp->flags & CACHE_FLAG_EXISTS) 13669 res = 1; 13670 } else { 13671 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13672 } 13673 AST_LIST_UNLOCK(&dpcache); 13674 13675 return res; 13676 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 4289 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.
04290 { 04291 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 04292 ast_mutex_lock(&iaxsl[callno]); 04293 if (iaxs[callno]) 04294 iaxs[callno]->owner = newchan; 04295 else 04296 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 04297 ast_mutex_unlock(&iaxsl[callno]); 04298 return 0; 04299 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1801 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().
01802 { 01803 ast_sched_thread_del(sched, fr->retrans); 01804 iax_frame_free(fr); 01805 }
static void iax2_free_variable_datastore | ( | void * | ) | [static] |
Definition at line 1362 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.
01363 { 01364 AST_LIST_HEAD(, ast_var_t) *oldlist = old; 01365 struct ast_var_t *oldvar; 01366 01367 AST_LIST_LOCK(oldlist); 01368 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) { 01369 ast_free(oldvar); 01370 } 01371 AST_LIST_UNLOCK(oldlist); 01372 AST_LIST_HEAD_DESTROY(oldlist); 01373 ast_free(oldlist); 01374 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1735 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().
01736 { 01737 struct iax2_peer *peer = NULL; 01738 int res = 0; 01739 struct ao2_iterator i; 01740 01741 i = ao2_iterator_init(peers, 0); 01742 while ((peer = ao2_iterator_next(&i))) { 01743 struct sockaddr_in peer_addr; 01744 01745 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 01746 01747 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01748 (peer_addr.sin_port == sin.sin_port)) { 01749 ast_copy_string(host, peer->name, len); 01750 peer_unref(peer); 01751 res = 1; 01752 break; 01753 } 01754 peer_unref(peer); 01755 } 01756 ao2_iterator_destroy(&i); 01757 01758 if (!peer) { 01759 peer = realtime_peer(NULL, &sin); 01760 if (peer) { 01761 ast_copy_string(host, peer->name, len); 01762 peer_unref(peer); 01763 res = 1; 01764 } 01765 } 01766 01767 return res; 01768 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 5666 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().
05667 { 05668 struct iax2_peer *peer; 05669 int res = 0; 05670 struct ao2_iterator i; 05671 05672 i = ao2_iterator_init(peers, 0); 05673 while ((peer = ao2_iterator_next(&i))) { 05674 struct sockaddr_in peer_addr; 05675 05676 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 05677 05678 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 05679 (peer_addr.sin_port == sin.sin_port)) { 05680 res = ast_test_flag64(peer, IAX_TRUNK); 05681 peer_unref(peer); 05682 break; 05683 } 05684 peer_unref(peer); 05685 } 05686 ao2_iterator_destroy(&i); 05687 05688 return res; 05689 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5192 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.
05193 { 05194 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05195 struct iax_ie_data ied; 05196 int alreadygone; 05197 memset(&ied, 0, sizeof(ied)); 05198 ast_mutex_lock(&iaxsl[callno]); 05199 if (callno && iaxs[callno]) { 05200 ast_debug(1, "We're hanging up %s now...\n", c->name); 05201 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE); 05202 /* Send the hangup unless we have had a transmission error or are already gone */ 05203 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 05204 if (!iaxs[callno]->error && !alreadygone) { 05205 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 05206 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 05207 } 05208 if (!iaxs[callno]) { 05209 ast_mutex_unlock(&iaxsl[callno]); 05210 return 0; 05211 } 05212 } 05213 /* Explicitly predestroy it */ 05214 iax2_predestroy(callno); 05215 /* If we were already gone to begin with, destroy us now */ 05216 if (iaxs[callno] && alreadygone) { 05217 ast_debug(1, "Really destroying %s now...\n", c->name); 05218 iax2_destroy(callno); 05219 } else if (iaxs[callno]) { 05220 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) { 05221 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno); 05222 iax2_destroy(callno); 05223 } 05224 } 05225 } else if (c->tech_pvt) { 05226 /* If this call no longer exists, but the channel still 05227 * references it we need to set the channel's tech_pvt to null 05228 * to avoid ast_channel_free() trying to free it. 05229 */ 05230 c->tech_pvt = NULL; 05231 } 05232 ast_mutex_unlock(&iaxsl[callno]); 05233 ast_verb(3, "Hungup '%s'\n", c->name); 05234 return 0; 05235 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 5602 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().
05603 { 05604 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05605 struct chan_iax2_pvt *pvt; 05606 int res = 0; 05607 05608 if (iaxdebug) 05609 ast_debug(1, "Indicating condition %d\n", condition); 05610 05611 ast_mutex_lock(&iaxsl[callno]); 05612 pvt = iaxs[callno]; 05613 05614 if (wait_for_peercallno(pvt)) { 05615 res = -1; 05616 goto done; 05617 } 05618 05619 switch (condition) { 05620 case AST_CONTROL_HOLD: 05621 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05622 ast_moh_start(c, data, pvt->mohinterpret); 05623 goto done; 05624 } 05625 break; 05626 case AST_CONTROL_UNHOLD: 05627 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05628 ast_moh_stop(c); 05629 goto done; 05630 } 05631 break; 05632 case AST_CONTROL_CONNECTED_LINE: 05633 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE)) 05634 goto done; 05635 break; 05636 } 05637 05638 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 05639 05640 done: 05641 ast_mutex_unlock(&iaxsl[callno]); 05642 05643 return res; 05644 }
static int iax2_key_rotate | ( | const void * | vpvt | ) | [static] |
Definition at line 5354 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().
05355 { 05356 int res = 0; 05357 struct chan_iax2_pvt *pvt = (void *) vpvt; 05358 struct MD5Context md5; 05359 char key[17] = ""; 05360 struct iax_ie_data ied = { 05361 .pos = 0, 05362 }; 05363 05364 ast_mutex_lock(&iaxsl[pvt->callno]); 05365 pvt->keyrotateid = 05366 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt); 05367 05368 snprintf(key, sizeof(key), "%lX", ast_random()); 05369 05370 MD5Init(&md5); 05371 MD5Update(&md5, (unsigned char *) key, strlen(key)); 05372 MD5Final((unsigned char *) key, &md5); 05373 05374 IAX_DEBUGDIGEST("Sending", key); 05375 05376 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16); 05377 05378 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1); 05379 05380 build_ecx_key((unsigned char *) key, pvt); 05381 05382 ast_mutex_unlock(&iaxsl[pvt->callno]); 05383 05384 return res; 05385 }
static void iax2_lock_owner | ( | int | callno | ) | [static] |
Definition at line 1258 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().
01259 { 01260 for (;;) { 01261 if (!iaxs[callno] || !iaxs[callno]->owner) { 01262 /* There is no owner lock to get. */ 01263 break; 01264 } 01265 if (!ast_channel_trylock(iaxs[callno]->owner)) { 01266 /* We got the lock */ 01267 break; 01268 } 01269 /* Avoid deadlock by pausing and trying again */ 01270 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01271 } 01272 }
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 13702 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.
13703 { 13704 int res = 0; 13705 struct iax2_dpcache *dp = NULL; 13706 #if 0 13707 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13708 #endif 13709 if ((priority != 1) && (priority != 2)) 13710 return 0; 13711 13712 AST_LIST_LOCK(&dpcache); 13713 if ((dp = find_cache(chan, data, context, exten, priority))) { 13714 if (dp->flags & CACHE_FLAG_MATCHMORE) 13715 res = 1; 13716 } else { 13717 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13718 } 13719 AST_LIST_UNLOCK(&dpcache); 13720 13721 return res; 13722 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 11897 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
11898 { 11899 struct iax2_peer *peer = (struct iax2_peer *)data; 11900 peer->pokeexpire = -1; 11901 #ifdef SCHED_MULTITHREADED 11902 if (schedule_action(__iax2_poke_noanswer, data)) 11903 #endif 11904 __iax2_poke_noanswer(data); 11905 peer_unref(peer); 11906 return 0; 11907 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 11918 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().
11919 { 11920 int callno; 11921 struct sockaddr_in peer_addr; 11922 11923 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) { 11924 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 11925 immediately after clearing things out */ 11926 peer->lastms = 0; 11927 peer->historicms = 0; 11928 peer->pokeexpire = -1; 11929 peer->callno = 0; 11930 return 0; 11931 } 11932 11933 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 11934 11935 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 11936 if ((callno = peer->callno) > 0) { 11937 ast_log(LOG_NOTICE, "Still have a callno...\n"); 11938 ast_mutex_lock(&iaxsl[callno]); 11939 iax2_destroy(callno); 11940 ast_mutex_unlock(&iaxsl[callno]); 11941 } 11942 if (heldcall) 11943 ast_mutex_unlock(&iaxsl[heldcall]); 11944 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0); 11945 if (heldcall) 11946 ast_mutex_lock(&iaxsl[heldcall]); 11947 if (peer->callno < 1) { 11948 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 11949 return -1; 11950 } 11951 11952 /* Speed up retransmission times for this qualify call */ 11953 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 11954 iaxs[peer->callno]->peerpoke = peer; 11955 11956 if (peer->pokeexpire > -1) { 11957 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 11958 peer->pokeexpire = -1; 11959 peer_unref(peer); 11960 } 11961 } 11962 11963 /* Queue up a new task to handle no reply */ 11964 /* If the host is already unreachable then use the unreachable interval instead */ 11965 if (peer->lastms < 0) 11966 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 11967 else 11968 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 11969 11970 if (peer->pokeexpire == -1) 11971 peer_unref(peer); 11972 11973 /* And send the poke */ 11974 ast_mutex_lock(&iaxsl[callno]); 11975 if (iaxs[callno]) { 11976 struct iax_ie_data ied = { 11977 .buf = { 0 }, 11978 .pos = 0, 11979 }; 11980 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 11981 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1); 11982 } 11983 ast_mutex_unlock(&iaxsl[callno]); 11984 11985 return 0; 11986 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11909 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
11910 { 11911 struct iax2_peer *peer = obj; 11912 11913 iax2_poke_peer(peer, 0); 11914 11915 return 0; 11916 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9057 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
09058 { 09059 struct iax2_peer *peer = (struct iax2_peer *)data; 09060 peer->pokeexpire = -1; 09061 #ifdef SCHED_MULTITHREADED 09062 if (schedule_action(__iax2_poke_peer_s, data)) 09063 #endif 09064 __iax2_poke_peer_s(data); 09065 return 0; 09066 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 3349 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().
03350 { 03351 struct ast_channel *c = NULL; 03352 struct chan_iax2_pvt *pvt = iaxs[callno]; 03353 03354 if (!pvt) 03355 return -1; 03356 03357 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) { 03358 iax2_destroy_helper(pvt); 03359 ast_set_flag64(pvt, IAX_ALREADYGONE); 03360 } 03361 03362 if ((c = pvt->owner)) { 03363 c->tech_pvt = NULL; 03364 iax2_queue_hangup(callno); 03365 pvt->owner = NULL; 03366 ast_module_unref(ast_module_info->self); 03367 } 03368 03369 return 0; 03370 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 11554 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().
11555 { 11556 struct iax2_thread *thread = data; 11557 struct timeval wait; 11558 struct timespec ts; 11559 int put_into_idle = 0; 11560 int first_time = 1; 11561 int old_state; 11562 11563 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1); 11564 11565 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state); 11566 pthread_cleanup_push(iax2_process_thread_cleanup, data); 11567 11568 for (;;) { 11569 /* Wait for something to signal us to be awake */ 11570 ast_mutex_lock(&thread->lock); 11571 11572 if (thread->stop) { 11573 ast_mutex_unlock(&thread->lock); 11574 break; 11575 } 11576 11577 /* Flag that we're ready to accept signals */ 11578 if (first_time) { 11579 signal_condition(&thread->init_lock, &thread->init_cond); 11580 first_time = 0; 11581 } 11582 11583 /* Put into idle list if applicable */ 11584 if (put_into_idle) { 11585 insert_idle_thread(thread); 11586 } 11587 11588 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 11589 struct iax2_thread *t = NULL; 11590 /* Wait to be signalled or time out */ 11591 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11592 ts.tv_sec = wait.tv_sec; 11593 ts.tv_nsec = wait.tv_usec * 1000; 11594 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11595 /* This thread was never put back into the available dynamic 11596 * thread list, so just go away. */ 11597 if (!put_into_idle || thread->stop) { 11598 ast_mutex_unlock(&thread->lock); 11599 break; 11600 } 11601 AST_LIST_LOCK(&dynamic_list); 11602 /* Account for the case where this thread is acquired *right* after a timeout */ 11603 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 11604 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1); 11605 AST_LIST_UNLOCK(&dynamic_list); 11606 if (t) { 11607 /* This dynamic thread timed out waiting for a task and was 11608 * not acquired immediately after the timeout, 11609 * so it's time to go away. */ 11610 ast_mutex_unlock(&thread->lock); 11611 break; 11612 } 11613 /* Someone grabbed our thread *right* after we timed out. 11614 * Wait for them to set us up with something to do and signal 11615 * us to continue. */ 11616 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11617 ts.tv_sec = wait.tv_sec; 11618 ts.tv_nsec = wait.tv_usec * 1000; 11619 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11620 ast_mutex_unlock(&thread->lock); 11621 break; 11622 } 11623 } 11624 } else { 11625 ast_cond_wait(&thread->cond, &thread->lock); 11626 } 11627 11628 /* Go back into our respective list */ 11629 put_into_idle = 1; 11630 11631 ast_mutex_unlock(&thread->lock); 11632 11633 if (thread->stop) { 11634 break; 11635 } 11636 11637 if (thread->iostate == IAX_IOSTATE_IDLE) 11638 continue; 11639 11640 /* See what we need to do */ 11641 switch (thread->iostate) { 11642 case IAX_IOSTATE_READY: 11643 thread->actions++; 11644 thread->iostate = IAX_IOSTATE_PROCESSING; 11645 socket_process(thread); 11646 handle_deferred_full_frames(thread); 11647 break; 11648 case IAX_IOSTATE_SCHEDREADY: 11649 thread->actions++; 11650 thread->iostate = IAX_IOSTATE_PROCESSING; 11651 #ifdef SCHED_MULTITHREADED 11652 thread->schedfunc(thread->scheddata); 11653 #endif 11654 default: 11655 break; 11656 } 11657 time(&thread->checktime); 11658 thread->iostate = IAX_IOSTATE_IDLE; 11659 #ifdef DEBUG_SCHED_MULTITHREAD 11660 thread->curfunc[0]='\0'; 11661 #endif 11662 11663 /* The network thread added us to the active_thread list when we were given 11664 * frames to process, Now that we are done, we must remove ourselves from 11665 * the active list, and return to the idle list */ 11666 AST_LIST_LOCK(&active_list); 11667 AST_LIST_REMOVE(&active_list, thread, list); 11668 AST_LIST_UNLOCK(&active_list); 11669 11670 /* Make sure another frame didn't sneak in there after we thought we were done. */ 11671 handle_deferred_full_frames(thread); 11672 } 11673 11674 /*!\note For some reason, idle threads are exiting without being removed 11675 * from an idle list, which is causing memory corruption. Forcibly remove 11676 * it from the list, if it's there. 11677 */ 11678 AST_LIST_LOCK(&idle_list); 11679 AST_LIST_REMOVE(&idle_list, thread, list); 11680 AST_LIST_UNLOCK(&idle_list); 11681 11682 AST_LIST_LOCK(&dynamic_list); 11683 AST_LIST_REMOVE(&dynamic_list, thread, list); 11684 AST_LIST_UNLOCK(&dynamic_list); 11685 11686 /* I am exiting here on my own volition, I need to clean up my own data structures 11687 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 11688 */ 11689 pthread_cleanup_pop(1); 11690 return NULL; 11691 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 11543 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().
11544 { 11545 struct iax2_thread *thread = data; 11546 ast_mutex_destroy(&thread->lock); 11547 ast_cond_destroy(&thread->cond); 11548 ast_mutex_destroy(&thread->init_lock); 11549 ast_cond_destroy(&thread->init_cond); 11550 ast_free(thread); 11551 ast_atomic_dec_and_test(&iaxactivethreadcount); 11552 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
const char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 11754 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().
11755 { 11756 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 11757 is found for template */ 11758 struct iax_ie_data provdata; 11759 struct iax_ie_data ied; 11760 unsigned int sig; 11761 struct sockaddr_in sin; 11762 int callno; 11763 struct create_addr_info cai; 11764 11765 memset(&cai, 0, sizeof(cai)); 11766 11767 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template); 11768 11769 if (iax_provision_build(&provdata, &sig, template, force)) { 11770 ast_debug(1, "No provisioning found for template '%s'\n", template); 11771 return 0; 11772 } 11773 11774 if (end) { 11775 memcpy(&sin, end, sizeof(sin)); 11776 cai.sockfd = sockfd; 11777 } else if (create_addr(dest, NULL, &sin, &cai)) 11778 return -1; 11779 11780 /* Build the rest of the message */ 11781 memset(&ied, 0, sizeof(ied)); 11782 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 11783 11784 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 11785 if (!callno) 11786 return -1; 11787 11788 if (iaxs[callno]) { 11789 /* Schedule autodestruct in case they don't ever give us anything back */ 11790 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 11791 sched, 15000, auto_hangup, (void *)(long)callno); 11792 ast_set_flag64(iaxs[callno], IAX_PROVISION); 11793 /* Got a call number now, so go ahead and send the provisioning information */ 11794 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 11795 } 11796 ast_mutex_unlock(&iaxsl[callno]); 11797 11798 return 1; 11799 }
static int iax2_queryoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int * | datalen | |||
) | [static] |
Definition at line 5331 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.
05332 { 05333 switch (option) { 05334 case AST_OPTION_SECURE_SIGNALING: 05335 case AST_OPTION_SECURE_MEDIA: 05336 { 05337 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05338 ast_mutex_lock(&iaxsl[callno]); 05339 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0; 05340 ast_mutex_unlock(&iaxsl[callno]); 05341 return 0; 05342 } 05343 default: 05344 return -1; 05345 } 05346 }
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 2982 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().
02984 { 02985 iax2_lock_owner(callno); 02986 if (iaxs[callno] && iaxs[callno]->owner) { 02987 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 02988 ast_channel_unlock(iaxs[callno]->owner); 02989 } 02990 return 0; 02991 }
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 2936 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().
02937 { 02938 iax2_lock_owner(callno); 02939 if (iaxs[callno] && iaxs[callno]->owner) { 02940 ast_queue_frame(iaxs[callno]->owner, f); 02941 ast_channel_unlock(iaxs[callno]->owner); 02942 } 02943 return 0; 02944 }
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 2959 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().
02960 { 02961 iax2_lock_owner(callno); 02962 if (iaxs[callno] && iaxs[callno]->owner) { 02963 ast_queue_hangup(iaxs[callno]->owner); 02964 ast_channel_unlock(iaxs[callno]->owner); 02965 } 02966 return 0; 02967 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5348 of file chan_iax2.c.
References ast_log(), ast_null_frame, and LOG_NOTICE.
05349 { 05350 ast_log(LOG_NOTICE, "I should never be called!\n"); 05351 return &ast_null_frame; 05352 }
static int iax2_register | ( | const char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 8498 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().
08499 { 08500 char copy[256]; 08501 char *username, *hostname, *secret; 08502 char *porta; 08503 char *stringp=NULL; 08504 08505 if (!value) 08506 return -1; 08507 08508 ast_copy_string(copy, value, sizeof(copy)); 08509 stringp = copy; 08510 username = strsep(&stringp, "@"); 08511 hostname = strsep(&stringp, "@"); 08512 08513 if (!hostname) { 08514 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 08515 return -1; 08516 } 08517 08518 stringp = username; 08519 username = strsep(&stringp, ":"); 08520 secret = strsep(&stringp, ":"); 08521 stringp = hostname; 08522 hostname = strsep(&stringp, ":"); 08523 porta = strsep(&stringp, ":"); 08524 08525 if (porta && !atoi(porta)) { 08526 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 08527 return -1; 08528 } 08529 08530 return iax2_append_register(hostname, username, secret, porta); 08531 }
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 11998 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.
11999 { 12000 int callno; 12001 int res; 12002 format_t fmt, native; 12003 struct sockaddr_in sin; 12004 struct ast_channel *c; 12005 struct parsed_dial_string pds; 12006 struct create_addr_info cai; 12007 char *tmpstr; 12008 12009 memset(&pds, 0, sizeof(pds)); 12010 tmpstr = ast_strdupa(data); 12011 parse_dial_string(tmpstr, &pds); 12012 12013 if (ast_strlen_zero(pds.peer)) { 12014 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 12015 return NULL; 12016 } 12017 12018 memset(&cai, 0, sizeof(cai)); 12019 cai.capability = iax2_capability; 12020 12021 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12022 12023 /* Populate our address from the given */ 12024 if (create_addr(pds.peer, NULL, &sin, &cai)) { 12025 *cause = AST_CAUSE_UNREGISTERED; 12026 return NULL; 12027 } 12028 12029 if (pds.port) 12030 sin.sin_port = htons(atoi(pds.port)); 12031 12032 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 12033 if (callno < 1) { 12034 ast_log(LOG_WARNING, "Unable to create call\n"); 12035 *cause = AST_CAUSE_CONGESTION; 12036 return NULL; 12037 } 12038 12039 /* If this is a trunk, update it now */ 12040 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12041 if (ast_test_flag64(&cai, IAX_TRUNK)) { 12042 int new_callno; 12043 if ((new_callno = make_trunk(callno, 1)) != -1) 12044 callno = new_callno; 12045 } 12046 iaxs[callno]->maxtime = cai.maxtime; 12047 if (cai.found) 12048 ast_string_field_set(iaxs[callno], host, pds.peer); 12049 12050 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL); 12051 12052 ast_mutex_unlock(&iaxsl[callno]); 12053 12054 if (c) { 12055 /* Choose a format we can live with */ 12056 if (c->nativeformats & format) 12057 c->nativeformats &= format; 12058 else { 12059 native = c->nativeformats; 12060 fmt = format; 12061 res = ast_translator_best_choice(&fmt, &native); 12062 if (res < 0) { 12063 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 12064 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 12065 ast_hangup(c); 12066 return NULL; 12067 } 12068 c->nativeformats = native; 12069 } 12070 c->readformat = ast_best_codec(c->nativeformats); 12071 c->writeformat = c->readformat; 12072 } 12073 12074 return c; 12075 }
static int iax2_sched_add | ( | struct ast_sched_thread * | st, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 1498 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().
01500 { 01501 return ast_sched_thread_add(st, when, callback, data); 01502 }
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 1490 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().
01492 { 01493 ast_sched_thread_del(st, id); 01494 01495 return ast_sched_thread_add(st, when, callback, data); 01496 }
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 6329 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().
06330 { 06331 /* Queue a packet for delivery on a given private structure. Use "ts" for 06332 timestamp, or calculate if ts is 0. Send immediately without retransmission 06333 or delayed, with retransmission */ 06334 struct ast_iax2_full_hdr *fh; 06335 struct ast_iax2_mini_hdr *mh; 06336 struct ast_iax2_video_hdr *vh; 06337 struct { 06338 struct iax_frame fr2; 06339 unsigned char buffer[4096]; 06340 } frb; 06341 struct iax_frame *fr; 06342 int res; 06343 int sendmini=0; 06344 unsigned int lastsent; 06345 unsigned int fts; 06346 06347 frb.fr2.afdatalen = sizeof(frb.buffer); 06348 06349 if (!pvt) { 06350 ast_log(LOG_WARNING, "No private structure for packet?\n"); 06351 return -1; 06352 } 06353 06354 lastsent = pvt->lastsent; 06355 06356 /* Calculate actual timestamp */ 06357 fts = calc_timestamp(pvt, ts, f); 06358 06359 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 06360 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 06361 * increment the "predicted timestamps" for voice, if we're predicting */ 06362 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 06363 return 0; 06364 #if 0 06365 ast_log(LOG_NOTICE, 06366 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n", 06367 *("=!" + (f->frametype == AST_FRAME_VOICE)), 06368 IAX_CALLENCRYPTED(pvt) ? "" : "not ", 06369 pvt->keyrotateid != -1 ? "" : "no " 06370 ); 06371 #endif 06372 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) { 06373 iax2_key_rotate(pvt); 06374 } 06375 06376 if ((ast_test_flag64(pvt, IAX_TRUNK) || 06377 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 06378 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 06379 /* High two bytes are the same on timestamp, or sending on a trunk */ && 06380 (f->frametype == AST_FRAME_VOICE) 06381 /* is a voice frame */ && 06382 (f->subclass.codec == pvt->svoiceformat) 06383 /* is the same type */ ) { 06384 /* Force immediate rather than delayed transmission */ 06385 now = 1; 06386 /* Mark that mini-style frame is appropriate */ 06387 sendmini = 1; 06388 } 06389 if ( f->frametype == AST_FRAME_VIDEO ) { 06390 /* 06391 * If the lower 15 bits of the timestamp roll over, or if 06392 * the video format changed then send a full frame. 06393 * Otherwise send a mini video frame 06394 */ 06395 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 06396 ((f->subclass.codec & ~0x1LL) == pvt->svideoformat) 06397 ) { 06398 now = 1; 06399 sendmini = 1; 06400 } else { 06401 now = 0; 06402 sendmini = 0; 06403 } 06404 pvt->lastvsent = fts; 06405 } 06406 if (f->frametype == AST_FRAME_IAX) { 06407 /* 0x8000 marks this message as TX:, this bit will be stripped later */ 06408 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX; 06409 if (!pvt->first_iax_message) { 06410 pvt->first_iax_message = pvt->last_iax_message; 06411 } 06412 } 06413 /* Allocate an iax_frame */ 06414 if (now) { 06415 fr = &frb.fr2; 06416 } else 06417 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)); 06418 if (!fr) { 06419 ast_log(LOG_WARNING, "Out of memory\n"); 06420 return -1; 06421 } 06422 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 06423 iax_frame_wrap(fr, f); 06424 06425 fr->ts = fts; 06426 fr->callno = pvt->callno; 06427 fr->transfer = transfer; 06428 fr->final = final; 06429 fr->encmethods = 0; 06430 if (!sendmini) { 06431 /* We need a full frame */ 06432 if (seqno > -1) 06433 fr->oseqno = seqno; 06434 else 06435 fr->oseqno = pvt->oseqno++; 06436 fr->iseqno = pvt->iseqno; 06437 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr)); 06438 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 06439 fh->ts = htonl(fr->ts); 06440 fh->oseqno = fr->oseqno; 06441 if (transfer) { 06442 fh->iseqno = 0; 06443 } else 06444 fh->iseqno = fr->iseqno; 06445 /* Keep track of the last thing we've acknowledged */ 06446 if (!transfer) 06447 pvt->aseqno = fr->iseqno; 06448 fh->type = fr->af.frametype & 0xFF; 06449 06450 if (fr->af.frametype == AST_FRAME_VIDEO) { 06451 fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6); 06452 } else if (fr->af.frametype == AST_FRAME_VOICE) { 06453 fh->csub = compress_subclass(fr->af.subclass.codec); 06454 } else { 06455 fh->csub = compress_subclass(fr->af.subclass.integer); 06456 } 06457 06458 if (transfer) { 06459 fr->dcallno = pvt->transfercallno; 06460 } else 06461 fr->dcallno = pvt->peercallno; 06462 fh->dcallno = htons(fr->dcallno); 06463 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 06464 fr->data = fh; 06465 fr->retries = 0; 06466 /* Retry after 2x the ping time has passed */ 06467 fr->retrytime = pvt->pingtime * 2; 06468 if (fr->retrytime < MIN_RETRY_TIME) 06469 fr->retrytime = MIN_RETRY_TIME; 06470 if (fr->retrytime > MAX_RETRY_TIME) 06471 fr->retrytime = MAX_RETRY_TIME; 06472 /* Acks' don't get retried */ 06473 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK)) 06474 fr->retries = -1; 06475 else if (f->frametype == AST_FRAME_VOICE) 06476 pvt->svoiceformat = f->subclass.codec; 06477 else if (f->frametype == AST_FRAME_VIDEO) 06478 pvt->svideoformat = f->subclass.codec & ~0x1LL; 06479 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06480 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06481 if (fr->transfer) 06482 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06483 else 06484 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06485 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 06486 fr->encmethods = pvt->encmethods; 06487 fr->ecx = pvt->ecx; 06488 fr->mydcx = pvt->mydcx; 06489 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand)); 06490 } else 06491 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06492 } 06493 06494 if (now) { 06495 res = send_packet(fr); 06496 } else 06497 res = iax2_transmit(fr); 06498 } else { 06499 if (ast_test_flag64(pvt, IAX_TRUNK)) { 06500 iax2_trunk_queue(pvt, fr); 06501 res = 0; 06502 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 06503 /* Video frame have no sequence number */ 06504 fr->oseqno = -1; 06505 fr->iseqno = -1; 06506 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr)); 06507 vh->zeros = 0; 06508 vh->callno = htons(0x8000 | fr->callno); 06509 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0)); 06510 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 06511 fr->data = vh; 06512 fr->retries = -1; 06513 res = send_packet(fr); 06514 } else { 06515 /* Mini-frames have no sequence number */ 06516 fr->oseqno = -1; 06517 fr->iseqno = -1; 06518 /* Mini frame will do */ 06519 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr)); 06520 mh->callno = htons(fr->callno); 06521 mh->ts = htons(fr->ts & 0xFFFF); 06522 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 06523 fr->data = mh; 06524 fr->retries = -1; 06525 if (pvt->transferring == TRANSFER_MEDIAPASS) 06526 fr->transfer = 1; 06527 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06528 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06529 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 06530 } else 06531 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06532 } 06533 res = send_packet(fr); 06534 } 06535 } 06536 return res; 06537 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 4284 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04285 { 04286 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 04287 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 4279 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.
04280 { 04281 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1); 04282 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 4272 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04273 { 04274 04275 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 04276 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 04277 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 5259 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().
05260 { 05261 struct ast_option_header *h; 05262 int res; 05263 05264 switch (option) { 05265 case AST_OPTION_TXGAIN: 05266 case AST_OPTION_RXGAIN: 05267 /* these two cannot be sent, because they require a result */ 05268 errno = ENOSYS; 05269 return -1; 05270 case AST_OPTION_OPRMODE: 05271 errno = EINVAL; 05272 return -1; 05273 case AST_OPTION_SECURE_SIGNALING: 05274 case AST_OPTION_SECURE_MEDIA: 05275 { 05276 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05277 ast_mutex_lock(&iaxsl[callno]); 05278 if ((*(int *) data)) { 05279 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05280 } else { 05281 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05282 } 05283 ast_mutex_unlock(&iaxsl[callno]); 05284 return 0; 05285 } 05286 /* These options are sent to the other side across the network where 05287 * they will be passed to whatever channel is bridged there. Don't 05288 * do anything silly like pass an option that transmits pointers to 05289 * memory on this machine to a remote machine to use */ 05290 case AST_OPTION_TONE_VERIFY: 05291 case AST_OPTION_TDD: 05292 case AST_OPTION_RELAXDTMF: 05293 case AST_OPTION_AUDIO_MODE: 05294 case AST_OPTION_DIGIT_DETECT: 05295 case AST_OPTION_FAX_DETECT: 05296 { 05297 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05298 struct chan_iax2_pvt *pvt; 05299 05300 ast_mutex_lock(&iaxsl[callno]); 05301 pvt = iaxs[callno]; 05302 05303 if (wait_for_peercallno(pvt)) { 05304 ast_mutex_unlock(&iaxsl[callno]); 05305 return -1; 05306 } 05307 05308 ast_mutex_unlock(&iaxsl[callno]); 05309 05310 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 05311 return -1; 05312 } 05313 05314 h->flag = AST_OPTION_FLAG_REQUEST; 05315 h->option = htons(option); 05316 memcpy(h->data, data, datalen); 05317 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 05318 AST_CONTROL_OPTION, 0, (unsigned char *) h, 05319 datalen + sizeof(*h), -1); 05320 ast_free(h); 05321 return res; 05322 } 05323 default: 05324 return -1; 05325 } 05326 05327 /* Just in case someone does a break instead of a return */ 05328 return -1; 05329 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 5387 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.
05388 { 05389 int res; 05390 struct iax_ie_data ied0; 05391 struct iax_ie_data ied1; 05392 unsigned int transferid = (unsigned int)ast_random(); 05393 05394 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) { 05395 ast_debug(1, "transfers are not supported for encrypted calls at this time"); 05396 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER); 05397 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER); 05398 return 0; 05399 } 05400 05401 memset(&ied0, 0, sizeof(ied0)); 05402 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 05403 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 05404 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 05405 05406 memset(&ied1, 0, sizeof(ied1)); 05407 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 05408 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 05409 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 05410 05411 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 05412 if (res) 05413 return -1; 05414 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 05415 if (res) 05416 return -1; 05417 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05418 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05419 return 0; 05420 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 5646 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.
05647 { 05648 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05649 struct iax_ie_data ied = { "", }; 05650 char tmp[256], *context; 05651 enum ast_control_transfer message = AST_TRANSFER_SUCCESS; 05652 ast_copy_string(tmp, dest, sizeof(tmp)); 05653 context = strchr(tmp, '@'); 05654 if (context) { 05655 *context = '\0'; 05656 context++; 05657 } 05658 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 05659 if (context) 05660 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 05661 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest); 05662 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message)); 05663 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 05664 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 4255 of file chan_iax2.c.
References ast_taskprocessor_push(), iax_frame::sentyet, and transmit_frame().
Referenced by iax2_send().
04256 { 04257 fr->sentyet = 0; 04258 04259 return ast_taskprocessor_push(transmit_processor, transmit_frame, fr); 04260 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 9111 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
09112 { 09113 /* Drop when trunk is about 5 seconds idle */ 09114 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 09115 return 1; 09116 return 0; 09117 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 6066 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().
06067 { 06068 struct ast_frame *f; 06069 struct iax2_trunk_peer *tpeer; 06070 void *tmp, *ptr; 06071 struct timeval now; 06072 int res; 06073 struct ast_iax2_meta_trunk_entry *met; 06074 struct ast_iax2_meta_trunk_mini *mtm; 06075 06076 f = &fr->af; 06077 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 06078 if (tpeer) { 06079 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 06080 /* Need to reallocate space */ 06081 if (tpeer->trunkdataalloc < trunkmaxsize) { 06082 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 06083 ast_mutex_unlock(&tpeer->lock); 06084 return -1; 06085 } 06086 06087 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 06088 tpeer->trunkdata = tmp; 06089 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); 06090 } else { 06091 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)); 06092 ast_mutex_unlock(&tpeer->lock); 06093 return -1; 06094 } 06095 } 06096 06097 /* Append to meta frame */ 06098 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 06099 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) { 06100 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06101 mtm->len = htons(f->datalen); 06102 mtm->mini.callno = htons(pvt->callno); 06103 mtm->mini.ts = htons(0xffff & fr->ts); 06104 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 06105 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 06106 } else { 06107 met = (struct ast_iax2_meta_trunk_entry *)ptr; 06108 /* Store call number and length in meta header */ 06109 met->callno = htons(pvt->callno); 06110 met->len = htons(f->datalen); 06111 /* Advance pointers/decrease length past trunk entry header */ 06112 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 06113 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 06114 } 06115 /* Copy actual trunk data */ 06116 memcpy(ptr, f->data.ptr, f->datalen); 06117 tpeer->trunkdatalen += f->datalen; 06118 06119 tpeer->calls++; 06120 06121 /* track the largest mtu we actually have sent */ 06122 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 06123 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 06124 06125 /* if we have enough for a full MTU, ship it now without waiting */ 06126 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) { 06127 now = ast_tvnow(); 06128 res = send_trunk(tpeer, &now); 06129 trunk_untimed ++; 06130 } 06131 06132 ast_mutex_unlock(&tpeer->lock); 06133 } 06134 return 0; 06135 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 9032 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().
09033 { 09034 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 09035 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 7411 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.
07412 { 07413 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 07414 int res = -1; 07415 ast_mutex_lock(&iaxsl[callno]); 07416 if (iaxs[callno]) { 07417 /* If there's an outstanding error, return failure now */ 07418 if (!iaxs[callno]->error) { 07419 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) 07420 res = 0; 07421 /* Don't waste bandwidth sending null frames */ 07422 else if (f->frametype == AST_FRAME_NULL) 07423 res = 0; 07424 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH)) 07425 res = 0; 07426 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 07427 res = 0; 07428 else 07429 /* Simple, just queue for transmission */ 07430 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 07431 } else { 07432 ast_debug(1, "Write error: %s\n", strerror(errno)); 07433 } 07434 } 07435 /* If it's already gone, just return */ 07436 ast_mutex_unlock(&iaxsl[callno]); 07437 return res; 07438 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 3141 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().
03142 { 03143 int res = 0; 03144 struct iax_firmware *cur = NULL; 03145 03146 if (ast_strlen_zero(dev)) 03147 return 0; 03148 03149 AST_LIST_LOCK(&firmwares); 03150 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03151 if (!strcmp(dev, (char *)cur->fwh->devname)) { 03152 res = ntohs(cur->fwh->version); 03153 break; 03154 } 03155 } 03156 AST_LIST_UNLOCK(&firmwares); 03157 03158 return res; 03159 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 1115 of file chan_iax2.c.
References ast_verbose.
Referenced by load_module().
01116 { 01117 if (iaxdebug) 01118 ast_verbose("%s", data); 01119 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 1121 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
01122 { 01123 ast_log(LOG_WARNING, "%s", data); 01124 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 3161 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().
03162 { 03163 int res = -1; 03164 unsigned int bs = desc & 0xff; 03165 unsigned int start = (desc >> 8) & 0xffffff; 03166 unsigned int bytes; 03167 struct iax_firmware *cur; 03168 03169 if (ast_strlen_zero((char *)dev) || !bs) 03170 return -1; 03171 03172 start *= bs; 03173 03174 AST_LIST_LOCK(&firmwares); 03175 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03176 if (strcmp((char *)dev, (char *)cur->fwh->devname)) 03177 continue; 03178 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 03179 if (start < ntohl(cur->fwh->datalen)) { 03180 bytes = ntohl(cur->fwh->datalen) - start; 03181 if (bytes > bs) 03182 bytes = bs; 03183 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 03184 } else { 03185 bytes = 0; 03186 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 03187 } 03188 if (bytes == bs) 03189 res = 0; 03190 else 03191 res = 1; 03192 break; 03193 } 03194 AST_LIST_UNLOCK(&firmwares); 03195 03196 return res; 03197 }
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 1098 of file chan_iax2.c.
References debugaddr, f, and iax_showframe().
Referenced by iax2_send(), raw_hangup(), and socket_process().
01099 { 01100 if (iaxdebug || 01101 (sin && debugaddr.sin_addr.s_addr && 01102 (!ntohs(debugaddr.sin_port) || 01103 debugaddr.sin_port == sin->sin_port) && 01104 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) { 01105 if (iaxdebug) { 01106 iax_showframe(f, fhi, rx, sin, datalen); 01107 } else { 01108 iaxdebug = 1; 01109 iax_showframe(f, fhi, rx, sin, datalen); 01110 iaxdebug = 0; 01111 } 01112 } 01113 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2, | |||
const char * | parkexten | |||
) | [static] |
Definition at line 9274 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_log(), ast_pthread_create_detached_background, AST_STATE_DOWN, ast_channel::context, ast_channel::exten, iax_park_thread(), ast_channel::linkedid, LOG_WARNING, ast_channel::name, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_process().
09275 { 09276 struct iax_dual *d; 09277 struct ast_channel *chan1m, *chan2m; 09278 pthread_t th; 09279 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name); 09280 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name); 09281 if (chan2m && chan1m) { 09282 /* Make formats okay */ 09283 chan1m->readformat = chan1->readformat; 09284 chan1m->writeformat = chan1->writeformat; 09285 ast_channel_masquerade(chan1m, chan1); 09286 /* Setup the extensions and such */ 09287 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 09288 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 09289 chan1m->priority = chan1->priority; 09290 09291 /* We make a clone of the peer channel too, so we can play 09292 back the announcement */ 09293 /* Make formats okay */ 09294 chan2m->readformat = chan2->readformat; 09295 chan2m->writeformat = chan2->writeformat; 09296 ast_channel_masquerade(chan2m, chan2); 09297 /* Setup the extensions and such */ 09298 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 09299 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 09300 chan2m->priority = chan2->priority; 09301 if (ast_do_masquerade(chan2m)) { 09302 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 09303 ast_hangup(chan2m); 09304 return -1; 09305 } 09306 } else { 09307 if (chan1m) 09308 ast_hangup(chan1m); 09309 if (chan2m) 09310 ast_hangup(chan2m); 09311 return -1; 09312 } 09313 if ((d = ast_calloc(1, sizeof(*d)))) { 09314 d->chan1 = chan1m; 09315 d->chan2 = chan2m; 09316 d->parkexten = parkexten; 09317 if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) { 09318 return 0; 09319 } 09320 ast_free(d); 09321 } 09322 return -1; 09323 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 9254 of file chan_iax2.c.
References ast_free, ast_frfree, ast_hangup(), ast_log(), ast_park_call(), ast_read(), iax_dual::chan1, iax_dual::chan2, ext, f, LOG_NOTICE, and iax_dual::parkexten.
Referenced by iax_park().
09255 { 09256 struct ast_channel *chan1, *chan2; 09257 struct iax_dual *d; 09258 struct ast_frame *f; 09259 int ext; 09260 int res; 09261 d = stuff; 09262 chan1 = d->chan1; 09263 chan2 = d->chan2; 09264 ast_free(d); 09265 f = ast_read(chan1); 09266 if (f) 09267 ast_frfree(f); 09268 res = ast_park_call(chan1, chan2, 0, d->parkexten, &ext); 09269 ast_hangup(chan2); 09270 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 09271 return NULL; 09272 }
Definition at line 1955 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().
01956 { 01957 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01958 if (new) { 01959 size_t afdatalen = new->afdatalen; 01960 memcpy(new, fr, sizeof(*new)); 01961 iax_frame_wrap(new, &fr->af); 01962 new->afdatalen = afdatalen; 01963 new->data = NULL; 01964 new->datalen = 0; 01965 new->direction = DIRECTION_INGRESS; 01966 new->retrans = -1; 01967 } 01968 return new; 01969 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 1380 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().
01381 { 01382 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 01383 AST_LIST_LOCK(&dynamic_list); 01384 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 01385 AST_LIST_UNLOCK(&dynamic_list); 01386 } else { 01387 AST_LIST_LOCK(&idle_list); 01388 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 01389 AST_LIST_UNLOCK(&idle_list); 01390 } 01391 01392 return; 01393 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 1150 of file chan_iax2.c.
References args, and ast_verbose.
Referenced by handle_cli_iax2_set_debug_jb().
01151 { 01152 va_list args; 01153 char buf[1024]; 01154 01155 va_start(args, fmt); 01156 vsnprintf(buf, sizeof(buf), fmt, args); 01157 va_end(args); 01158 01159 ast_verbose("%s", buf); 01160 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 1126 of file chan_iax2.c.
References args, ast_log(), and LOG_ERROR.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
01127 { 01128 va_list args; 01129 char buf[1024]; 01130 01131 va_start(args, fmt); 01132 vsnprintf(buf, sizeof(buf), fmt, args); 01133 va_end(args); 01134 01135 ast_log(LOG_ERROR, "%s", buf); 01136 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 1138 of file chan_iax2.c.
References args, ast_log(), and LOG_WARNING.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
01139 { 01140 va_list args; 01141 char buf[1024]; 01142 01143 va_start(args, fmt); 01144 vsnprintf(buf, sizeof(buf), fmt, args); 01145 va_end(args); 01146 01147 ast_log(LOG_WARNING, "%s", buf); 01148 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 14585 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, papp, peer_set_sock_cb(), peers, reload_firmware(), RQ_CHAR, RQ_UINTEGER2, sched, SENTINEL, set_config(), start_network_thread(), and timer.
14586 { 14587 static const char config[] = "iax.conf"; 14588 int x = 0; 14589 struct iax2_registry *reg = NULL; 14590 14591 if (load_objects()) { 14592 return AST_MODULE_LOAD_FAILURE; 14593 } 14594 14595 memset(iaxs, 0, sizeof(iaxs)); 14596 14597 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14598 ast_mutex_init(&iaxsl[x]); 14599 } 14600 14601 if (!(sched = ast_sched_thread_create())) { 14602 ast_log(LOG_ERROR, "Failed to create scheduler thread\n"); 14603 return AST_MODULE_LOAD_FAILURE; 14604 } 14605 14606 if (!(io = io_context_create())) { 14607 ast_log(LOG_ERROR, "Failed to create I/O context\n"); 14608 sched = ast_sched_thread_destroy(sched); 14609 return AST_MODULE_LOAD_FAILURE; 14610 } 14611 14612 if (!(netsock = ast_netsock_list_alloc())) { 14613 ast_log(LOG_ERROR, "Failed to create netsock list\n"); 14614 io_context_destroy(io); 14615 sched = ast_sched_thread_destroy(sched); 14616 return AST_MODULE_LOAD_FAILURE; 14617 } 14618 ast_netsock_init(netsock); 14619 14620 outsock = ast_netsock_list_alloc(); 14621 if (!outsock) { 14622 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 14623 io_context_destroy(io); 14624 sched = ast_sched_thread_destroy(sched); 14625 return AST_MODULE_LOAD_FAILURE; 14626 } 14627 ast_netsock_init(outsock); 14628 14629 randomcalltokendata = ast_random(); 14630 14631 iax_set_output(iax_debug_output); 14632 iax_set_error(iax_error_output); 14633 jb_setoutput(jb_error_output, jb_warning_output, NULL); 14634 14635 if ((timer = ast_timer_open())) { 14636 ast_timer_set_rate(timer, trunkfreq); 14637 } 14638 14639 if (set_config(config, 0) == -1) { 14640 if (timer) { 14641 ast_timer_close(timer); 14642 } 14643 return AST_MODULE_LOAD_DECLINE; 14644 } 14645 14646 #ifdef TEST_FRAMEWORK 14647 AST_TEST_REGISTER(test_iax2_peers_get); 14648 AST_TEST_REGISTER(test_iax2_users_get); 14649 #endif 14650 14651 /* Register AstData providers */ 14652 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers)); 14653 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14654 14655 ast_register_application_xml(papp, iax2_prov_app); 14656 14657 ast_custom_function_register(&iaxpeer_function); 14658 ast_custom_function_register(&iaxvar_function); 14659 14660 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers); 14661 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list); 14662 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats); 14663 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry); 14664 14665 if (ast_channel_register(&iax2_tech)) { 14666 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 14667 __unload_module(); 14668 return AST_MODULE_LOAD_FAILURE; 14669 } 14670 14671 if (ast_register_switch(&iax2_switch)) { 14672 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 14673 } 14674 14675 if (start_network_thread()) { 14676 ast_log(LOG_ERROR, "Unable to start network thread\n"); 14677 __unload_module(); 14678 return AST_MODULE_LOAD_FAILURE; 14679 } else { 14680 ast_verb(2, "IAX Ready and Listening\n"); 14681 } 14682 14683 AST_LIST_LOCK(®istrations); 14684 AST_LIST_TRAVERSE(®istrations, reg, entry) 14685 iax2_do_register(reg); 14686 AST_LIST_UNLOCK(®istrations); 14687 14688 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 14689 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 14690 14691 14692 reload_firmware(0); 14693 iax_provision_reload(0); 14694 14695 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL); 14696 14697 network_change_event_subscribe(); 14698 14699 return AST_MODULE_LOAD_SUCCESS; 14700 }
static int load_objects | ( | void | ) | [static] |
Definition at line 14344 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().
14345 { 14346 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL; 14347 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL; 14348 14349 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) { 14350 goto container_fail; 14351 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) { 14352 goto container_fail; 14353 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) { 14354 goto container_fail; 14355 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) { 14356 goto container_fail; 14357 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) { 14358 goto container_fail; 14359 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14360 goto container_fail; 14361 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14362 goto container_fail; 14363 } else if (create_callno_pools()) { 14364 goto container_fail; 14365 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) { 14366 goto container_fail; 14367 } 14368 14369 return 0; 14370 14371 container_fail: 14372 if (peers) { 14373 ao2_ref(peers, -1); 14374 } 14375 if (users) { 14376 ao2_ref(users, -1); 14377 } 14378 if (iax_peercallno_pvts) { 14379 ao2_ref(iax_peercallno_pvts, -1); 14380 } 14381 if (iax_transfercallno_pvts) { 14382 ao2_ref(iax_transfercallno_pvts, -1); 14383 } 14384 if (peercnts) { 14385 ao2_ref(peercnts, -1); 14386 } 14387 if (callno_limits) { 14388 ao2_ref(callno_limits, -1); 14389 } 14390 if (calltoken_ignores) { 14391 ao2_ref(calltoken_ignores, -1); 14392 } 14393 if (callno_pool) { 14394 ao2_ref(callno_pool, -1); 14395 } 14396 if (callno_pool_trunk) { 14397 ao2_ref(callno_pool_trunk, -1); 14398 } 14399 return AST_MODULE_LOAD_FAILURE; 14400 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 5422 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_trylock, DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
05423 { 05424 ast_mutex_lock(&iaxsl[callno0]); 05425 while (ast_mutex_trylock(&iaxsl[callno1])) { 05426 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 05427 } 05428 }
static void log_jitterstats | ( | unsigned short | callno | ) | [static] |
Definition at line 9395 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().
09396 { 09397 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1; 09398 jb_info jbinfo; 09399 09400 ast_mutex_lock(&iaxsl[callno]); 09401 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) { 09402 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) { 09403 jb_getinfo(iaxs[callno]->jb, &jbinfo); 09404 localjitter = jbinfo.jitter; 09405 localdelay = jbinfo.current - jbinfo.min; 09406 locallost = jbinfo.frames_lost; 09407 locallosspct = jbinfo.losspct/1000; 09408 localdropped = jbinfo.frames_dropped; 09409 localooo = jbinfo.frames_ooo; 09410 localpackets = jbinfo.frames_in; 09411 } 09412 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", 09413 iaxs[callno]->owner->name, 09414 iaxs[callno]->pingtime, 09415 localjitter, 09416 localdelay, 09417 locallost, 09418 locallosspct, 09419 localdropped, 09420 localooo, 09421 localpackets, 09422 iaxs[callno]->remote_rr.jitter, 09423 iaxs[callno]->remote_rr.delay, 09424 iaxs[callno]->remote_rr.losscnt, 09425 iaxs[callno]->remote_rr.losspct/1000, 09426 iaxs[callno]->remote_rr.dropped, 09427 iaxs[callno]->remote_rr.ooo, 09428 iaxs[callno]->remote_rr.packets); 09429 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", 09430 iaxs[callno]->owner->name, 09431 iaxs[callno]->pingtime, 09432 localjitter, 09433 localdelay, 09434 locallost, 09435 locallosspct, 09436 localdropped, 09437 localooo, 09438 localpackets, 09439 iaxs[callno]->remote_rr.jitter, 09440 iaxs[callno]->remote_rr.delay, 09441 iaxs[callno]->remote_rr.losscnt, 09442 iaxs[callno]->remote_rr.losspct/1000, 09443 iaxs[callno]->remote_rr.dropped, 09444 iaxs[callno]->remote_rr.ooo, 09445 iaxs[callno]->remote_rr.packets); 09446 } 09447 ast_mutex_unlock(&iaxsl[callno]); 09448 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 2035 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(), TRUNK_CALL_START, update_max_nontrunk(), update_max_trunk(), and callno_entry::validated.
Referenced by iax2_request(), and socket_process().
02036 { 02037 int x; 02038 int res= 0; 02039 struct callno_entry *callno_entry; 02040 if (iaxs[callno]->oseqno) { 02041 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 02042 return -1; 02043 } 02044 if (callno & TRUNK_CALL_START) { 02045 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 02046 return -1; 02047 } 02048 02049 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) { 02050 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 02051 return -1; 02052 } 02053 02054 x = callno_entry->callno; 02055 ast_mutex_lock(&iaxsl[x]); 02056 02057 /*! 02058 * \note We delete these before switching the slot, because if 02059 * they fire in the meantime, they will generate a warning. 02060 */ 02061 ast_sched_thread_del(sched, iaxs[callno]->pingid); 02062 ast_sched_thread_del(sched, iaxs[callno]->lagid); 02063 iaxs[callno]->lagid = iaxs[callno]->pingid = -1; 02064 iaxs[x] = iaxs[callno]; 02065 iaxs[x]->callno = x; 02066 02067 /* since we copied over the pvt from a different callno, make sure the old entry is replaced 02068 * before assigning the new one */ 02069 if (iaxs[x]->callno_entry) { 02070 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry); 02071 } 02072 iaxs[x]->callno_entry = callno_entry; 02073 02074 iaxs[callno] = NULL; 02075 /* Update the two timers that should have been started */ 02076 iaxs[x]->pingid = iax2_sched_add(sched, 02077 ping_time * 1000, send_ping, (void *)(long)x); 02078 iaxs[x]->lagid = iax2_sched_add(sched, 02079 lagrq_time * 1000, send_lagrq, (void *)(long)x); 02080 02081 if (locked) 02082 ast_mutex_unlock(&iaxsl[callno]); 02083 res = x; 02084 if (!locked) 02085 ast_mutex_unlock(&iaxsl[x]); 02086 02087 ast_debug(1, "Made call %d into trunk call %d\n", callno, x); 02088 /* We move this call from a non-trunked to a trunked call */ 02089 update_max_trunk(); 02090 update_max_nontrunk(); 02091 return res; 02092 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 6912 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), and RESULT_SUCCESS.
Referenced by load_module().
06913 { 06914 ast_cli_netstats(s, -1, 0); 06915 astman_append(s, "\r\n"); 06916 return RESULT_SUCCESS; 06917 }
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 6975 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().
06976 { 06977 struct iax2_peer *peer = NULL; 06978 int peer_count = 0; 06979 char nm[20]; 06980 char status[20]; 06981 const char *id = astman_get_header(m,"ActionID"); 06982 char idtext[256] = ""; 06983 struct ast_str *encmethods = ast_str_alloca(256); 06984 struct ao2_iterator i; 06985 06986 if (!ast_strlen_zero(id)) 06987 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 06988 06989 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext); 06990 06991 06992 i = ao2_iterator_init(peers, 0); 06993 for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) { 06994 encmethods_to_str(peer->encmethods, encmethods); 06995 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext); 06996 if (!ast_strlen_zero(peer->username)) { 06997 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username); 06998 } else { 06999 astman_append(s, "ObjectName: %s\r\n", peer->name); 07000 } 07001 astman_append(s, "ChanObjectType: peer\r\n"); 07002 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr)); 07003 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 07004 astman_append(s, "Mask: %s\r\n", nm); 07005 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr)); 07006 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 07007 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 07008 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 07009 peer_status(peer, status, sizeof(status)); 07010 astman_append(s, "Status: %s\r\n\r\n", status); 07011 peer_count++; 07012 } 07013 ao2_iterator_destroy(&i); 07014 07015 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count); 07016 return RESULT_SUCCESS; 07017 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
callback to display iax peers in manager
Definition at line 6951 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().
06952 { 06953 static const char * const a[] = { "iax2", "show", "peers" }; 06954 const char *id = astman_get_header(m,"ActionID"); 06955 char idtext[256] = ""; 06956 int total = 0; 06957 06958 if (!ast_strlen_zero(id)) 06959 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 06960 06961 astman_send_listack(s, m, "Peer status list will follow", "start"); 06962 /* List the peers in separate manager events */ 06963 __iax2_show_peers(-1, &total, s, 3, a); 06964 /* Send final confirmation */ 06965 astman_append(s, 06966 "Event: PeerlistComplete\r\n" 06967 "EventList: Complete\r\n" 06968 "ListItems: %d\r\n" 06969 "%s" 06970 "\r\n", total, idtext); 06971 return 0; 06972 }
static int manager_iax2_show_registry | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 7083 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().
07084 { 07085 const char *id = astman_get_header(m, "ActionID"); 07086 struct iax2_registry *reg = NULL; 07087 char idtext[256] = ""; 07088 char host[80] = ""; 07089 char perceived[80] = ""; 07090 int total = 0; 07091 07092 if (!ast_strlen_zero(id)) 07093 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07094 07095 astman_send_listack(s, m, "Registrations will follow", "start"); 07096 07097 AST_LIST_LOCK(®istrations); 07098 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07099 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07100 07101 if (reg->us.sin_addr.s_addr) { 07102 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07103 } else { 07104 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07105 } 07106 07107 astman_append(s, 07108 "Event: RegistryEntry\r\n" 07109 "%s" 07110 "Host: %s\r\n" 07111 "DNSmanager: %s\r\n" 07112 "Username: %s\r\n" 07113 "Perceived: %s\r\n" 07114 "Refresh: %d\r\n" 07115 "State: %s\r\n" 07116 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, 07117 reg->refresh, regstate2str(reg->regstate)); 07118 07119 total++; 07120 } 07121 AST_LIST_UNLOCK(®istrations); 07122 07123 astman_append(s, 07124 "Event: RegistrationsComplete\r\n" 07125 "EventList: Complete\r\n" 07126 "ListItems: %d\r\n" 07127 "%s" 07128 "\r\n", total, idtext); 07129 07130 return 0; 07131 }
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 1984 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(), 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(), and transfercallno_pvt_cmp_cb().
01985 { 01986 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01987 (cur->addr.sin_port == sin->sin_port)) { 01988 /* This is the main host */ 01989 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01990 (check_dcallno ? dcallno == cur->callno : 1) ) { 01991 /* That's us. Be sure we keep track of the peer call number */ 01992 return 1; 01993 } 01994 } 01995 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01996 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01997 /* We're transferring */ 01998 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01999 return 1; 02000 } 02001 return 0; 02002 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
ast_aes_decrypt_key * | dcx | |||
) | [static] |
Definition at line 6165 of file chan_iax2.c.
References ast_aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
06166 { 06167 #if 0 06168 /* Debug with "fake encryption" */ 06169 int x; 06170 if (len % 16) 06171 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06172 for (x=0;x<len;x++) 06173 dst[x] = src[x] ^ 0xff; 06174 #else 06175 unsigned char lastblock[16] = { 0 }; 06176 int x; 06177 while(len > 0) { 06178 ast_aes_decrypt(src, dst, dcx); 06179 for (x=0;x<16;x++) 06180 dst[x] ^= lastblock[x]; 06181 memcpy(lastblock, src, sizeof(lastblock)); 06182 dst += 16; 06183 src += 16; 06184 len -= 16; 06185 } 06186 #endif 06187 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
ast_aes_encrypt_key * | ecx | |||
) | [static] |
Definition at line 6189 of file chan_iax2.c.
References ast_aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
06190 { 06191 #if 0 06192 /* Debug with "fake encryption" */ 06193 int x; 06194 if (len % 16) 06195 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06196 for (x=0;x<len;x++) 06197 dst[x] = src[x] ^ 0xff; 06198 #else 06199 unsigned char curblock[16] = { 0 }; 06200 int x; 06201 while(len > 0) { 06202 for (x=0;x<16;x++) 06203 curblock[x] ^= src[x]; 06204 ast_aes_encrypt(curblock, dst, ecx); 06205 memcpy(curblock, dst, sizeof(curblock)); 06206 dst += 16; 06207 src += 16; 06208 len -= 16; 06209 } 06210 #endif 06211 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 7755 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().
07756 { 07757 /* Select exactly one common encryption if there are any */ 07758 p->encmethods &= enc; 07759 if (p->encmethods) { 07760 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */ 07761 p->keyrotateid = -2; 07762 } 07763 if (p->encmethods & IAX_ENCRYPT_AES128) 07764 p->encmethods = IAX_ENCRYPT_AES128; 07765 else 07766 p->encmethods = 0; 07767 } 07768 }
static void mwi_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 1274 of file chan_iax2.c.
01275 { 01276 /* The MWI subscriptions exist just so the core knows we care about those 01277 * mailboxes. However, we just grab the events out of the cache when it 01278 * is time to send MWI, since it is only sent with a REGACK. */ 01279 }
static void network_change_event_cb | ( | const struct ast_event * | , | |
void * | ||||
) | [static] |
Definition at line 1312 of file chan_iax2.c.
References ast_debug, iax2_sched_add(), network_change_event_sched_cb(), and sched.
Referenced by network_change_event_subscribe().
01313 { 01314 ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n"); 01315 if (network_change_event_sched_id == -1) { 01316 network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL); 01317 } 01318 01319 }
static int network_change_event_sched_cb | ( | const void * | data | ) | [static] |
Definition at line 1299 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().
01300 { 01301 struct iax2_registry *reg; 01302 network_change_event_sched_id = -1; 01303 AST_LIST_LOCK(®istrations); 01304 AST_LIST_TRAVERSE(®istrations, reg, entry) { 01305 iax2_do_register(reg); 01306 } 01307 AST_LIST_UNLOCK(®istrations); 01308 01309 return 0; 01310 }
static void network_change_event_subscribe | ( | void | ) | [static] |
Definition at line 1281 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().
01282 { 01283 if (!network_change_event_subscription) { 01284 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE, 01285 network_change_event_cb, 01286 "SIP Network Change ", 01287 NULL, 01288 AST_EVENT_IE_END); 01289 } 01290 }
static void network_change_event_unsubscribe | ( | void | ) | [static] |
Definition at line 1292 of file chan_iax2.c.
References ast_event_unsubscribe(), and network_change_event_subscription.
Referenced by __unload_module(), set_config(), and unload_module().
01293 { 01294 if (network_change_event_subscription) { 01295 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription); 01296 } 01297 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 12077 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().
12078 { 12079 if (timer) { 12080 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL); 12081 } 12082 12083 for (;;) { 12084 pthread_testcancel(); 12085 /* Wake up once a second just in case SIGURG was sent while 12086 * we weren't in poll(), to make sure we don't hang when trying 12087 * to unload. */ 12088 ast_io_wait(io, 1000); 12089 } 12090 12091 return NULL; 12092 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static] |
Definition at line 1913 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().
01914 { 01915 struct chan_iax2_pvt *tmp; 01916 jb_conf jbconf; 01917 01918 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01919 return NULL; 01920 } 01921 01922 if (ast_string_field_init(tmp, 32)) { 01923 ao2_ref(tmp, -1); 01924 tmp = NULL; 01925 return NULL; 01926 } 01927 01928 tmp->prefs = prefs; 01929 tmp->pingid = -1; 01930 tmp->lagid = -1; 01931 tmp->autoid = -1; 01932 tmp->authid = -1; 01933 tmp->initid = -1; 01934 tmp->keyrotateid = -1; 01935 01936 ast_string_field_set(tmp,exten, "s"); 01937 ast_string_field_set(tmp,host, host); 01938 01939 tmp->jb = jb_new(); 01940 tmp->jbid = -1; 01941 jbconf.max_jitterbuf = maxjitterbuffer; 01942 jbconf.resync_threshold = resyncthreshold; 01943 jbconf.max_contig_interp = maxjitterinterps; 01944 jbconf.target_extra = jittertargetextra; 01945 jb_setconf(tmp->jb,&jbconf); 01946 01947 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries); 01948 01949 tmp->hold_signaling = 1; 01950 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue); 01951 01952 return tmp; 01953 }
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 4944 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().
04945 { 04946 if (ast_strlen_zero(data)) 04947 return; 04948 04949 pds->peer = strsep(&data, "/"); 04950 pds->exten = strsep(&data, "/"); 04951 pds->options = data; 04952 04953 if (pds->exten) { 04954 data = pds->exten; 04955 pds->exten = strsep(&data, "@"); 04956 pds->context = data; 04957 } 04958 04959 if (strchr(pds->peer, '@')) { 04960 data = pds->peer; 04961 pds->username = strsep(&data, "@"); 04962 pds->peer = data; 04963 } 04964 04965 if (pds->username) { 04966 data = pds->username; 04967 pds->username = strsep(&data, ":"); 04968 pds->password = data; 04969 } 04970 04971 data = pds->peer; 04972 pds->peer = strsep(&data, ":"); 04973 pds->port = data; 04974 04975 /* check for a key name wrapped in [] in the secret position, if found, 04976 move it to the key field instead 04977 */ 04978 if (pds->password && (pds->password[0] == '[')) { 04979 pds->key = ast_strip_quoted(pds->password, "[", "]"); 04980 pds->password = NULL; 04981 } 04982 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1656 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and iax2_peer::name.
Referenced by load_module(), and load_objects().
01657 { 01658 struct iax2_peer *peer = obj, *peer2 = arg; 01659 01660 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0; 01661 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12821 of file chan_iax2.c.
References ast_set_flag64, and IAX_DELME.
Referenced by delete_users().
12822 { 12823 struct iax2_peer *peer = obj; 12824 12825 ast_set_flag64(peer, IAX_DELME); 12826 12827 return 0; 12828 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 12253 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().
12254 { 12255 struct iax2_peer *peer = obj; 12256 int callno = peer->callno; 12257 12258 ast_free_ha(peer->ha); 12259 12260 if (callno > 0) { 12261 ast_mutex_lock(&iaxsl[callno]); 12262 iax2_destroy(callno); 12263 ast_mutex_unlock(&iaxsl[callno]); 12264 } 12265 12266 register_peer_exten(peer, 0); 12267 12268 if (peer->dnsmgr) 12269 ast_dnsmgr_release(peer->dnsmgr); 12270 12271 if (peer->mwi_event_sub) 12272 ast_event_unsubscribe(peer->mwi_event_sub); 12273 12274 ast_string_field_free_memory(peer); 12275 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1646 of file chan_iax2.c.
References ast_str_hash(), and iax2_peer::name.
Referenced by load_module(), and load_objects().
01647 { 01648 const struct iax2_peer *peer = obj; 01649 01650 return ast_str_hash(peer->name); 01651 }
Definition at line 1703 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().
01704 { 01705 ao2_ref(peer, +1); 01706 return peer; 01707 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 14298 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
14299 { 14300 struct iax2_peer *peer = obj; 14301 14302 if (peer->sockfd < 0) 14303 peer->sockfd = defaultsockfd; 14304 14305 return 0; 14306 }
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 12179 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, and strsep().
Referenced by build_peer().
12180 { 12181 struct sockaddr_in sin; 12182 struct ast_sockaddr sin_tmp; 12183 int nonlocal = 1; 12184 int port = IAX_DEFAULT_PORTNO; 12185 int sockfd = defaultsockfd; 12186 char *tmp; 12187 char *addr; 12188 char *portstr; 12189 12190 if (!(tmp = ast_strdupa(srcaddr))) 12191 return -1; 12192 12193 addr = strsep(&tmp, ":"); 12194 portstr = tmp; 12195 12196 if (portstr) { 12197 port = atoi(portstr); 12198 if (port < 1) 12199 port = IAX_DEFAULT_PORTNO; 12200 } 12201 12202 if (!ast_get_ip(&sin_tmp, addr)) { 12203 struct ast_netsock *sock; 12204 int res; 12205 12206 ast_sockaddr_to_sin(&sin_tmp, &sin); 12207 sin.sin_port = 0; 12208 sin.sin_family = AF_INET; 12209 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 12210 if (res == 0) { 12211 /* ip address valid. */ 12212 sin.sin_port = htons(port); 12213 if (!(sock = ast_netsock_find(netsock, &sin))) 12214 sock = ast_netsock_find(outsock, &sin); 12215 if (sock) { 12216 sockfd = ast_netsock_sockfd(sock); 12217 nonlocal = 0; 12218 } else { 12219 unsigned int orig_saddr = sin.sin_addr.s_addr; 12220 /* INADDR_ANY matches anyway! */ 12221 sin.sin_addr.s_addr = INADDR_ANY; 12222 if (ast_netsock_find(netsock, &sin)) { 12223 sin.sin_addr.s_addr = orig_saddr; 12224 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL); 12225 if (sock) { 12226 sockfd = ast_netsock_sockfd(sock); 12227 ast_netsock_unref(sock); 12228 nonlocal = 0; 12229 } else { 12230 nonlocal = 2; 12231 } 12232 } 12233 } 12234 } 12235 } 12236 12237 peer->sockfd = sockfd; 12238 12239 if (nonlocal == 1) { 12240 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 12241 srcaddr, peer->name); 12242 return -1; 12243 } else if (nonlocal == 2) { 12244 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 12245 srcaddr, peer->name); 12246 return -1; 12247 } else { 12248 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 12249 return 0; 12250 } 12251 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 3702 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().
03703 { 03704 int res = 0; 03705 if (peer->maxms) { 03706 if (peer->lastms < 0) { 03707 ast_copy_string(status, "UNREACHABLE", statuslen); 03708 } else if (peer->lastms > peer->maxms) { 03709 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 03710 res = 1; 03711 } else if (peer->lastms) { 03712 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 03713 res = 1; 03714 } else { 03715 ast_copy_string(status, "UNKNOWN", statuslen); 03716 } 03717 } else { 03718 ast_copy_string(status, "Unmonitored", statuslen); 03719 res = -1; 03720 } 03721 return res; 03722 }
Definition at line 1709 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().
01710 { 01711 ao2_ref(peer, -1); 01712 return NULL; 01713 }
static int peercnt_add | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2332 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().
02333 { 02334 struct peercnt *peercnt; 02335 unsigned long addr = sin->sin_addr.s_addr; 02336 int res = 0; 02337 struct peercnt tmp = { 02338 .addr = addr, 02339 }; 02340 02341 /* Reasoning for peercnts container lock: Two identical ip addresses 02342 * could be added by different threads at the "same time". Without the container 02343 * lock, both threads could alloc space for the same object and attempt 02344 * to link to table. With the lock, one would create the object and link 02345 * to table while the other would find the already created peercnt object 02346 * rather than creating a new one. */ 02347 ao2_lock(peercnts); 02348 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02349 ao2_lock(peercnt); 02350 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) { 02351 ao2_lock(peercnt); 02352 /* create and set defaults */ 02353 peercnt->addr = addr; 02354 set_peercnt_limit(peercnt); 02355 /* guarantees it does not go away after unlocking table 02356 * ao2_find automatically adds this */ 02357 ao2_link(peercnts, peercnt); 02358 } else { 02359 ao2_unlock(peercnts); 02360 return -1; 02361 } 02362 02363 /* check to see if the address has hit its callno limit. If not increment cur. */ 02364 if (peercnt->limit > peercnt->cur) { 02365 peercnt->cur++; 02366 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr)); 02367 } else { /* max num call numbers for this peer has been reached! */ 02368 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr)); 02369 res = -1; 02370 } 02371 02372 /* clean up locks and ref count */ 02373 ao2_unlock(peercnt); 02374 ao2_unlock(peercnts); 02375 ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */ 02376 02377 return res; 02378 }
static int peercnt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2162 of file chan_iax2.c.
References peercnt::addr, CMP_MATCH, and CMP_STOP.
Referenced by load_objects().
02163 { 02164 struct peercnt *peercnt1 = obj, *peercnt2 = arg; 02165 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0; 02166 }
static int peercnt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 2156 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 2299 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().
02300 { 02301 /* this function turns off and on custom callno limits set by peer registration */ 02302 struct peercnt *peercnt; 02303 struct peercnt tmp = { 02304 .addr = 0, 02305 }; 02306 struct sockaddr_in sin; 02307 02308 ast_sockaddr_to_sin(sockaddr, &sin); 02309 02310 tmp.addr = sin.sin_addr.s_addr; 02311 02312 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02313 peercnt->reg = reg; 02314 if (limit) { 02315 peercnt->limit = limit; 02316 } else { 02317 set_peercnt_limit(peercnt); 02318 } 02319 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg); 02320 ao2_ref(peercnt, -1); /* decrement ref from find */ 02321 } 02322 }
static void peercnt_remove | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2384 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().
02385 { 02386 struct sockaddr_in sin = { 02387 .sin_addr.s_addr = peercnt->addr, 02388 }; 02389 02390 if (peercnt) { 02391 /* Container locked here since peercnt may be unlinked from list. If left unlocked, 02392 * peercnt_add could try and grab this entry from the table and modify it at the 02393 * "same time" this thread attemps to unlink it.*/ 02394 ao2_lock(peercnts); 02395 peercnt->cur--; 02396 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr)); 02397 /* if this was the last connection from the peer remove it from table */ 02398 if (peercnt->cur == 0) { 02399 ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */ 02400 } 02401 ao2_unlock(peercnts); 02402 } 02403 }
static int peercnt_remove_by_addr | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2423 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().
02424 { 02425 struct peercnt *peercnt; 02426 struct peercnt tmp = { 02427 .addr = sin->sin_addr.s_addr, 02428 }; 02429 02430 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02431 peercnt_remove(peercnt); 02432 ao2_ref(peercnt, -1); /* decrement ref from find */ 02433 } 02434 return 0; 02435 }
static int peercnt_remove_cb | ( | const void * | obj | ) | [static] |
Definition at line 2409 of file chan_iax2.c.
References ao2_ref, and peercnt_remove().
Referenced by sched_delay_remove().
02410 { 02411 struct peercnt *peercnt = (struct peercnt *) obj; 02412 02413 peercnt_remove(peercnt); 02414 ao2_ref(peercnt, -1); /* decrement ref from scheduler */ 02415 02416 return 0; 02417 }
static int peers_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 14432 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.
14434 { 14435 struct ast_data *data_peer; 14436 struct iax2_peer *peer; 14437 struct ao2_iterator i; 14438 char status[20]; 14439 struct ast_str *encmethods = ast_str_alloca(256); 14440 14441 i = ao2_iterator_init(peers, 0); 14442 while ((peer = ao2_iterator_next(&i))) { 14443 data_peer = ast_data_add_node(data_root, "peer"); 14444 if (!data_peer) { 14445 peer_unref(peer); 14446 continue; 14447 } 14448 14449 ast_data_add_structure(iax2_peer, data_peer, peer); 14450 14451 ast_data_add_codecs(data_peer, "codecs", peer->capability); 14452 14453 peer_status(peer, status, sizeof(status)); 14454 ast_data_add_str(data_peer, "status", status); 14455 14456 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr)); 14457 14458 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask)); 14459 14460 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr)); 14461 14462 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK)); 14463 14464 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC)); 14465 14466 encmethods_to_str(peer->encmethods, encmethods); 14467 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no"); 14468 14469 peer_unref(peer); 14470 14471 if (!ast_data_search_match(search, data_peer)) { 14472 ast_data_remove_node(data_root, data_peer); 14473 } 14474 } 14475 ao2_iterator_destroy(&i); 14476 14477 return 0; 14478 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 13387 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().
13388 { 13389 struct ao2_iterator i; 13390 struct iax2_peer *peer; 13391 13392 i = ao2_iterator_init(peers, 0); 13393 while ((peer = ao2_iterator_next(&i))) { 13394 iax2_poke_peer(peer, 0); 13395 peer_unref(peer); 13396 } 13397 ao2_iterator_destroy(&i); 13398 }
static int prune_addr_range_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2288 of file chan_iax2.c.
References CMP_MATCH, and addr_range::delme.
Referenced by reload_config().
02289 { 02290 struct addr_range *addr_range = obj; 02291 02292 return addr_range->delme ? CMP_MATCH : 0; 02293 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 12884 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().
12885 { 12886 struct iax2_peer *peer; 12887 struct ao2_iterator i; 12888 12889 i = ao2_iterator_init(peers, 0); 12890 while ((peer = ao2_iterator_next(&i))) { 12891 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 12892 unlink_peer(peer); 12893 } 12894 peer_unref(peer); 12895 } 12896 ao2_iterator_destroy(&i); 12897 }
static void prune_users | ( | void | ) | [static] |
Definition at line 12868 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().
12869 { 12870 struct iax2_user *user; 12871 struct ao2_iterator i; 12872 12873 i = ao2_iterator_init(users, 0); 12874 while ((user = ao2_iterator_next(&i))) { 12875 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 12876 ao2_unlink(users, user); 12877 } 12878 user_unref(user); 12879 } 12880 ao2_iterator_destroy(&i); 12881 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 14315 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().
14316 { 14317 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14318 14319 /* The frames_received field is used to hold whether we're matching 14320 * against a full frame or not ... */ 14321 14322 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 14323 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14324 }
static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1866 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.
01867 { 01868 struct chan_iax2_pvt *pvt = obj; 01869 struct iax_frame *cur = NULL; 01870 struct signaling_queue_entry *s = NULL; 01871 01872 ast_mutex_lock(&iaxsl[pvt->callno]); 01873 01874 iax2_destroy_helper(pvt); 01875 01876 sched_delay_remove(&pvt->addr, pvt->callno_entry); 01877 pvt->callno_entry = NULL; 01878 01879 /* Already gone */ 01880 ast_set_flag64(pvt, IAX_ALREADYGONE); 01881 01882 AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) { 01883 /* Cancel any pending transmissions */ 01884 cur->retries = -1; 01885 } 01886 01887 ast_mutex_unlock(&iaxsl[pvt->callno]); 01888 01889 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01890 free_signaling_queue_entry(s); 01891 } 01892 01893 if (pvt->reg) { 01894 pvt->reg->callno = 0; 01895 } 01896 01897 if (!pvt->owner) { 01898 jb_frame frame; 01899 if (pvt->vars) { 01900 ast_variables_destroy(pvt->vars); 01901 pvt->vars = NULL; 01902 } 01903 01904 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01905 iax2_frame_free(frame.data); 01906 } 01907 01908 jb_destroy(pvt->jb); 01909 ast_string_field_free_memory(pvt); 01910 } 01911 }
static int pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 14308 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
14309 { 14310 const struct chan_iax2_pvt *pvt = obj; 14311 14312 return pvt->peercallno; 14313 }
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 1842 of file chan_iax2.c.
References ast_calloc, AST_FRAME_IAX, AST_LIST_INSERT_TAIL, f, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, iax2_trunk_peer::next, and chan_iax2_pvt::signaling_queue.
Referenced by __send_command().
01843 { 01844 struct signaling_queue_entry *new; 01845 01846 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) { 01847 return 1; /* do not queue this frame */ 01848 } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) { 01849 return -1; /* out of memory */ 01850 } 01851 01852 memcpy(&new->f, f, sizeof(new->f)); /* copy ast_frame into our queue entry */ 01853 01854 if (new->f.datalen) { /* if there is data in this frame copy it over as well */ 01855 if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) { 01856 free_signaling_queue_entry(new); 01857 return -1; 01858 } 01859 memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr)); 01860 } 01861 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next); 01862 01863 return 0; 01864 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 7736 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().
07737 { 07738 struct ast_iax2_full_hdr fh; 07739 fh.scallno = htons(src | IAX_FLAG_FULL); 07740 fh.dcallno = htons(dst); 07741 fh.ts = 0; 07742 fh.oseqno = 0; 07743 fh.iseqno = 0; 07744 fh.type = AST_FRAME_IAX; 07745 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 07746 iax_outputframe(NULL, &fh, 0, sin, 0); 07747 #if 0 07748 if (option_debug) 07749 #endif 07750 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n", 07751 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 07752 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 07753 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 4305 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.
04306 { 04307 struct ast_variable *var = NULL; 04308 struct ast_variable *tmp; 04309 struct iax2_peer *peer=NULL; 04310 time_t regseconds = 0, nowtime; 04311 int dynamic=0; 04312 04313 if (peername) { 04314 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL); 04315 if (!var && sin) 04316 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04317 } else if (sin) { 04318 char porta[25]; 04319 sprintf(porta, "%d", ntohs(sin->sin_port)); 04320 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04321 if (var) { 04322 /* We'll need the peer name in order to build the structure! */ 04323 for (tmp = var; tmp; tmp = tmp->next) { 04324 if (!strcasecmp(tmp->name, "name")) 04325 peername = tmp->value; 04326 } 04327 } 04328 } 04329 if (!var && peername) { /* Last ditch effort */ 04330 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL); 04331 /*!\note 04332 * If this one loaded something, then we need to ensure that the host 04333 * field matched. The only reason why we can't have this as a criteria 04334 * is because we only have the IP address and the host field might be 04335 * set as a name (and the reverse PTR might not match). 04336 */ 04337 if (var && sin) { 04338 for (tmp = var; tmp; tmp = tmp->next) { 04339 if (!strcasecmp(tmp->name, "host")) { 04340 struct ast_hostent ahp; 04341 struct hostent *hp; 04342 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 04343 /* No match */ 04344 ast_variables_destroy(var); 04345 var = NULL; 04346 } 04347 break; 04348 } 04349 } 04350 } 04351 } 04352 if (!var) 04353 return NULL; 04354 04355 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 04356 04357 if (!peer) { 04358 ast_variables_destroy(var); 04359 return NULL; 04360 } 04361 04362 for (tmp = var; tmp; tmp = tmp->next) { 04363 /* Make sure it's not a user only... */ 04364 if (!strcasecmp(tmp->name, "type")) { 04365 if (strcasecmp(tmp->value, "friend") && 04366 strcasecmp(tmp->value, "peer")) { 04367 /* Whoops, we weren't supposed to exist! */ 04368 peer = peer_unref(peer); 04369 break; 04370 } 04371 } else if (!strcasecmp(tmp->name, "regseconds")) { 04372 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 04373 } else if (!strcasecmp(tmp->name, "ipaddr")) { 04374 ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE); 04375 } else if (!strcasecmp(tmp->name, "port")) { 04376 ast_sockaddr_set_port(&peer->addr, atoi(tmp->value)); 04377 } else if (!strcasecmp(tmp->name, "host")) { 04378 if (!strcasecmp(tmp->value, "dynamic")) 04379 dynamic = 1; 04380 } 04381 } 04382 04383 ast_variables_destroy(var); 04384 04385 if (!peer) 04386 return NULL; 04387 04388 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04389 ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 04390 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) { 04391 if (peer->expire > -1) { 04392 if (!ast_sched_thread_del(sched, peer->expire)) { 04393 peer->expire = -1; 04394 peer_unref(peer); 04395 } 04396 } 04397 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 04398 if (peer->expire == -1) 04399 peer_unref(peer); 04400 } 04401 ao2_link(peers, peer); 04402 if (ast_test_flag64(peer, IAX_DYNAMIC)) 04403 reg_source_db(peer); 04404 } else { 04405 ast_set_flag64(peer, IAX_TEMPONLY); 04406 } 04407 04408 if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 04409 time(&nowtime); 04410 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 04411 memset(&peer->addr, 0, sizeof(peer->addr)); 04412 realtime_update_peer(peer->name, &peer->addr, 0); 04413 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 04414 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04415 } 04416 else { 04417 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 04418 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04419 } 04420 } 04421 04422 return peer; 04423 }
static void realtime_update_peer | ( | const char * | peername, | |
struct ast_sockaddr * | sockaddr, | |||
time_t | regtime | |||
) | [static] |
Definition at line 4496 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().
04497 { 04498 char port[10]; 04499 char regseconds[20]; 04500 const char *sysname = ast_config_AST_SYSTEM_NAME; 04501 char *syslabel = NULL; 04502 04503 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 04504 sysname = NULL; 04505 else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME)) 04506 syslabel = "regserver"; 04507 04508 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 04509 snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr)); 04510 ast_update_realtime("iaxpeers", "name", peername, 04511 "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port, 04512 "regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslable can be NULL */ 04513 }
static struct iax2_user * realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 4425 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.
04426 { 04427 struct ast_variable *var; 04428 struct ast_variable *tmp; 04429 struct iax2_user *user=NULL; 04430 04431 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL); 04432 if (!var) 04433 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04434 if (!var && sin) { 04435 char porta[6]; 04436 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 04437 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04438 if (!var) 04439 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04440 } 04441 if (!var) { /* Last ditch effort */ 04442 var = ast_load_realtime("iaxusers", "name", username, SENTINEL); 04443 /*!\note 04444 * If this one loaded something, then we need to ensure that the host 04445 * field matched. The only reason why we can't have this as a criteria 04446 * is because we only have the IP address and the host field might be 04447 * set as a name (and the reverse PTR might not match). 04448 */ 04449 if (var) { 04450 for (tmp = var; tmp; tmp = tmp->next) { 04451 if (!strcasecmp(tmp->name, "host")) { 04452 struct ast_hostent ahp; 04453 struct hostent *hp; 04454 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 04455 /* No match */ 04456 ast_variables_destroy(var); 04457 var = NULL; 04458 } 04459 break; 04460 } 04461 } 04462 } 04463 } 04464 if (!var) 04465 return NULL; 04466 04467 tmp = var; 04468 while(tmp) { 04469 /* Make sure it's not a peer only... */ 04470 if (!strcasecmp(tmp->name, "type")) { 04471 if (strcasecmp(tmp->value, "friend") && 04472 strcasecmp(tmp->value, "user")) { 04473 return NULL; 04474 } 04475 } 04476 tmp = tmp->next; 04477 } 04478 04479 user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)); 04480 04481 ast_variables_destroy(var); 04482 04483 if (!user) 04484 return NULL; 04485 04486 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04487 ast_set_flag64(user, IAX_RTCACHEFRIENDS); 04488 ao2_link(users, user); 04489 } else { 04490 ast_set_flag64(user, IAX_TEMPONLY); 04491 } 04492 04493 return user; 04494 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 8615 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().
08616 { 08617 char data[80]; 08618 char *expiry; 08619 08620 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) { 08621 return; 08622 } 08623 08624 expiry = strrchr(data, ':'); 08625 if (!expiry) { 08626 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data); 08627 } 08628 *expiry++ = '\0'; 08629 08630 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) { 08631 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data); 08632 return; 08633 } 08634 08635 p->expiry = atoi(expiry); 08636 08637 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name, 08638 ast_sockaddr_stringify(&p->addr), p->expiry); 08639 08640 iax2_poke_peer(p, 0); 08641 if (p->expire > -1) { 08642 if (!ast_sched_thread_del(sched, p->expire)) { 08643 p->expire = -1; 08644 peer_unref(p); 08645 } 08646 } 08647 08648 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08649 08650 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08651 if (p->expire == -1) { 08652 peer_unref(p); 08653 } 08654 08655 if (iax2_regfunk) { 08656 iax2_regfunk(p->name, 1); 08657 } 08658 08659 register_peer_exten(p, 1); 08660 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 8534 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().
08535 { 08536 char multi[256]; 08537 char *stringp, *ext; 08538 if (!ast_strlen_zero(regcontext)) { 08539 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 08540 stringp = multi; 08541 while((ext = strsep(&stringp, "&"))) { 08542 if (onoff) { 08543 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 08544 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 08545 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2"); 08546 } else 08547 ast_context_remove_extension(regcontext, ext, 1, NULL); 08548 } 08549 } 08550 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 7910 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().
07911 { 07912 char requeststr[256] = ""; 07913 char peer[256] = ""; 07914 char md5secret[256] = ""; 07915 char rsasecret[256] = ""; 07916 char secret[256] = ""; 07917 struct iax2_peer *p = NULL; 07918 struct ast_key *key; 07919 char *keyn; 07920 int x; 07921 int expire = 0; 07922 int res = -1; 07923 struct ast_sockaddr addr; 07924 07925 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07926 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 07927 if (ies->username) 07928 ast_copy_string(peer, ies->username, sizeof(peer)); 07929 if (ies->password) 07930 ast_copy_string(secret, ies->password, sizeof(secret)); 07931 if (ies->md5_result) 07932 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07933 if (ies->rsa_result) 07934 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07935 if (ies->refresh) 07936 expire = ies->refresh; 07937 07938 if (ast_strlen_zero(peer)) { 07939 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 07940 return -1; 07941 } 07942 07943 /* SLD: first call to lookup peer during registration */ 07944 ast_mutex_unlock(&iaxsl[callno]); 07945 p = find_peer(peer, 1); 07946 ast_mutex_lock(&iaxsl[callno]); 07947 if (!p || !iaxs[callno]) { 07948 if (iaxs[callno]) { 07949 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 07950 /* Anything, as long as it's non-blank */ 07951 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07952 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 07953 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 07954 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 07955 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 07956 * to be plaintext, indicating it is an authmethod used by other peers on the system. 07957 * 07958 * If none of these cases exist, res will be returned as 0 without authentication indicating 07959 * an AUTHREQ needs to be sent out. */ 07960 07961 if (ast_strlen_zero(iaxs[callno]->challenge) && 07962 !(!ast_strlen_zero(secret) && plaintext)) { 07963 /* by setting res to 0, an REGAUTH will be sent */ 07964 res = 0; 07965 } 07966 } 07967 if (authdebug && !p) 07968 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 07969 goto return_unref; 07970 } 07971 07972 if (!ast_test_flag64(p, IAX_DYNAMIC)) { 07973 if (authdebug) 07974 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 07975 goto return_unref; 07976 } 07977 07978 ast_sockaddr_from_sin(&addr, sin); 07979 if (!ast_apply_ha(p->ha, &addr)) { 07980 if (authdebug) 07981 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 07982 goto return_unref; 07983 } 07984 ast_string_field_set(iaxs[callno], secret, p->secret); 07985 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 07986 /* Check secret against what we have on file */ 07987 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 07988 if (!ast_strlen_zero(p->inkeys)) { 07989 char tmpkeys[256]; 07990 char *stringp=NULL; 07991 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 07992 stringp=tmpkeys; 07993 keyn = strsep(&stringp, ":"); 07994 while(keyn) { 07995 key = ast_key_get(keyn, AST_KEY_PUBLIC); 07996 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 07997 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07998 break; 07999 } else if (!key) 08000 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 08001 keyn = strsep(&stringp, ":"); 08002 } 08003 if (!keyn) { 08004 if (authdebug) 08005 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 08006 goto return_unref; 08007 } 08008 } else { 08009 if (authdebug) 08010 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 08011 goto return_unref; 08012 } 08013 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 08014 struct MD5Context md5; 08015 unsigned char digest[16]; 08016 char *tmppw, *stringp; 08017 08018 tmppw = ast_strdupa(p->secret); 08019 stringp = tmppw; 08020 while((tmppw = strsep(&stringp, ";"))) { 08021 MD5Init(&md5); 08022 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 08023 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 08024 MD5Final(digest, &md5); 08025 for (x=0;x<16;x++) 08026 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 08027 if (!strcasecmp(requeststr, md5secret)) 08028 break; 08029 } 08030 if (tmppw) { 08031 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08032 } else { 08033 if (authdebug) 08034 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 08035 goto return_unref; 08036 } 08037 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 08038 /* They've provided a plain text password and we support that */ 08039 if (strcmp(secret, p->secret)) { 08040 if (authdebug) 08041 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 08042 goto return_unref; 08043 } else 08044 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08045 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 08046 /* if challenge has been sent, but no challenge response if given, reject. */ 08047 goto return_unref; 08048 } 08049 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08050 08051 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 08052 res = 0; 08053 08054 return_unref: 08055 if (iaxs[callno]) { 08056 ast_string_field_set(iaxs[callno], peer, peer); 08057 08058 /* Choose lowest expiry number */ 08059 if (expire && (expire < iaxs[callno]->expiry)) { 08060 iaxs[callno]->expiry = expire; 08061 } 08062 } 08063 08064 if (p) { 08065 peer_unref(p); 08066 } 08067 return res; 08068 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 8836 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().
08837 { 08838 struct iax_ie_data ied; 08839 struct iax2_peer *p; 08840 char challenge[10]; 08841 const char *peer_name; 08842 int sentauthmethod; 08843 08844 peer_name = ast_strdupa(iaxs[callno]->peer); 08845 08846 /* SLD: third call to find_peer in registration */ 08847 ast_mutex_unlock(&iaxsl[callno]); 08848 if ((p = find_peer(peer_name, 1))) { 08849 last_authmethod = p->authmethods; 08850 } 08851 08852 ast_mutex_lock(&iaxsl[callno]); 08853 if (!iaxs[callno]) 08854 goto return_unref; 08855 08856 memset(&ied, 0, sizeof(ied)); 08857 /* The selection of which delayed reject is sent may leak information, 08858 * if it sets a static response. For example, if a host is known to only 08859 * use MD5 authentication, then an RSA response would indicate that the 08860 * peer does not exist, and vice-versa. 08861 * Therefore, we use whatever the last peer used (which may vary over the 08862 * course of a server, which should leak minimal information). */ 08863 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 08864 if (!p) { 08865 iaxs[callno]->authmethods = sentauthmethod; 08866 } 08867 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 08868 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 08869 /* Build the challenge */ 08870 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 08871 ast_string_field_set(iaxs[callno], challenge, challenge); 08872 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 08873 } 08874 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 08875 08876 return_unref: 08877 if (p) { 08878 peer_unref(p); 08879 } 08880 08881 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 08882 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 8884 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().
08885 { 08886 struct iax2_registry *reg; 08887 /* Start pessimistic */ 08888 struct iax_ie_data ied; 08889 char peer[256] = ""; 08890 char challenge[256] = ""; 08891 int res; 08892 int authmethods = 0; 08893 if (ies->authmethods) 08894 authmethods = ies->authmethods; 08895 if (ies->username) 08896 ast_copy_string(peer, ies->username, sizeof(peer)); 08897 if (ies->challenge) 08898 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 08899 memset(&ied, 0, sizeof(ied)); 08900 reg = iaxs[callno]->reg; 08901 if (reg) { 08902 struct sockaddr_in reg_addr; 08903 08904 ast_sockaddr_to_sin(®->addr, ®_addr); 08905 08906 if (inaddrcmp(®_addr, sin)) { 08907 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08908 return -1; 08909 } 08910 if (ast_strlen_zero(reg->secret)) { 08911 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 08912 reg->regstate = REG_STATE_NOAUTH; 08913 return -1; 08914 } 08915 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08916 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08917 if (reg->secret[0] == '[') { 08918 char tmpkey[256]; 08919 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 08920 tmpkey[strlen(tmpkey) - 1] = '\0'; 08921 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL); 08922 } else 08923 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL); 08924 if (!res) { 08925 reg->regstate = REG_STATE_AUTHSENT; 08926 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 08927 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08928 } else 08929 return -1; 08930 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 08931 } else 08932 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 08933 return -1; 08934 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 7020 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().
07021 { 07022 switch(regstate) { 07023 case REG_STATE_UNREGISTERED: 07024 return "Unregistered"; 07025 case REG_STATE_REGSENT: 07026 return "Request Sent"; 07027 case REG_STATE_AUTHSENT: 07028 return "Auth. Sent"; 07029 case REG_STATE_REGISTERED: 07030 return "Registered"; 07031 case REG_STATE_REJECTED: 07032 return "Rejected"; 07033 case REG_STATE_TIMEOUT: 07034 return "Timeout"; 07035 case REG_STATE_NOAUTH: 07036 return "No Authentication"; 07037 default: 07038 return "Unknown"; 07039 } 07040 }
static int reload | ( | void | ) | [static] |
Definition at line 13448 of file chan_iax2.c.
References reload_config().
13449 { 13450 return reload_config(); 13451 }
static int reload_config | ( | void | ) | [static] |
Definition at line 13399 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().
13400 { 13401 static const char config[] = "iax.conf"; 13402 struct iax2_registry *reg; 13403 13404 if (set_config(config, 1) > 0) { 13405 prune_peers(); 13406 prune_users(); 13407 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13408 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13409 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL); 13410 trunk_timed = trunk_untimed = 0; 13411 trunk_nmaxmtu = trunk_maxmtu = 0; 13412 memset(&debugaddr, '\0', sizeof(debugaddr)); 13413 13414 AST_LIST_LOCK(®istrations); 13415 AST_LIST_TRAVERSE(®istrations, reg, entry) 13416 iax2_do_register(reg); 13417 AST_LIST_UNLOCK(®istrations); 13418 13419 /* Qualify hosts, too */ 13420 poke_all_peers(); 13421 } 13422 13423 reload_firmware(0); 13424 iax_provision_reload(1); 13425 ast_unload_realtime("iaxpeers"); 13426 13427 return 0; 13428 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 3200 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().
03201 { 03202 struct iax_firmware *cur = NULL; 03203 DIR *fwd; 03204 struct dirent *de; 03205 char dir[256], fn[256]; 03206 03207 AST_LIST_LOCK(&firmwares); 03208 03209 /* Mark all as dead */ 03210 AST_LIST_TRAVERSE(&firmwares, cur, list) 03211 cur->dead = 1; 03212 03213 /* Now that we have marked them dead... load new ones */ 03214 if (!unload) { 03215 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR); 03216 fwd = opendir(dir); 03217 if (fwd) { 03218 while((de = readdir(fwd))) { 03219 if (de->d_name[0] != '.') { 03220 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 03221 if (!try_firmware(fn)) { 03222 ast_verb(2, "Loaded firmware '%s'\n", de->d_name); 03223 } 03224 } 03225 } 03226 closedir(fwd); 03227 } else 03228 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 03229 } 03230 03231 /* Clean up leftovers */ 03232 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) { 03233 if (!cur->dead) 03234 continue; 03235 AST_LIST_REMOVE_CURRENT(list); 03236 destroy_firmware(cur); 03237 } 03238 AST_LIST_TRAVERSE_SAFE_END; 03239 03240 AST_LIST_UNLOCK(&firmwares); 03241 }
static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2123 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().
02124 { 02125 if (!pvt->peercallno) { 02126 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 02127 return; 02128 } 02129 02130 ao2_unlink(iax_peercallno_pvts, pvt); 02131 }
static void remove_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2104 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().
02105 { 02106 if (!pvt->transfercallno) { 02107 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 02108 return; 02109 } 02110 02111 ao2_unlink(iax_transfercallno_pvts, pvt); 02112 }
static int replace_callno | ( | const void * | obj | ) | [static] |
Definition at line 2632 of file chan_iax2.c.
References ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_log(), callno_entry::callno, LOG_ERROR, TRUNK_CALL_START, and callno_entry::validated.
Referenced by __find_callno(), make_trunk(), and sched_delay_remove().
02633 { 02634 struct callno_entry *callno_entry = (struct callno_entry *) obj; 02635 02636 /* the callno_pool container is locked here primarily to ensure thread 02637 * safety of the total_nonval_callno_used check and decrement */ 02638 ao2_lock(callno_pool); 02639 02640 if (!callno_entry->validated && (total_nonval_callno_used != 0)) { 02641 total_nonval_callno_used--; 02642 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) { 02643 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno); 02644 } 02645 02646 if (callno_entry->callno < TRUNK_CALL_START) { 02647 ao2_link(callno_pool, callno_entry); 02648 } else { 02649 ao2_link(callno_pool_trunk, callno_entry); 02650 } 02651 ao2_ref(callno_entry, -1); /* only container ref remains */ 02652 02653 ao2_unlock(callno_pool); 02654 return 0; 02655 }
static void requirecalltoken_mark_auto | ( | const char * | name, | |
int | subclass | |||
) | [static] |
Definition at line 4801 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().
04802 { 04803 struct iax2_user *user = NULL; 04804 struct iax2_peer *peer = NULL; 04805 04806 if (ast_strlen_zero(name)) { 04807 return; /* no username given */ 04808 } 04809 04810 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) { 04811 user->calltoken_required = CALLTOKEN_YES; 04812 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) { 04813 peer->calltoken_required = CALLTOKEN_YES; 04814 } 04815 04816 if (peer) { 04817 peer_unref(peer); 04818 } 04819 if (user) { 04820 user_unref(user); 04821 } 04822 }
static void resend_with_token | ( | int | callno, | |
struct iax_frame * | f, | |||
const char * | newtoken | |||
) | [static] |
Definition at line 4719 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().
04720 { 04721 struct chan_iax2_pvt *pvt = iaxs[callno]; 04722 int frametype = f->af.frametype; 04723 int subclass = f->af.subclass.integer; 04724 struct { 04725 struct ast_iax2_full_hdr fh; 04726 struct iax_ie_data ied; 04727 } data = { 04728 .ied.buf = { 0 }, 04729 .ied.pos = 0, 04730 }; 04731 /* total len - header len gives us the frame's IE len */ 04732 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr); 04733 04734 if (!pvt) { 04735 return; /* this should not be possible if called from socket_process() */ 04736 } 04737 04738 /* 04739 * Check to make sure last frame sent is valid for call token resend 04740 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 04741 * 2. Frame should _NOT_ already have a destination callno 04742 * 3. Frame must be a valid iax_frame subclass capable of starting dialog 04743 * 4. Pvt must have a calltoken_ie_len which represents the number of 04744 * bytes at the end of the frame used for the previous calltoken ie. 04745 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length 04746 * 6. Total length of f->data must be _LESS_ than size of our data struct 04747 * because f->data must be able to fit within data. 04748 */ 04749 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0) 04750 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) || 04751 (f->datalen > sizeof(data))) { 04752 04753 return; /* ignore resend, token was not valid for the dialog */ 04754 } 04755 04756 /* token is valid 04757 * 1. Copy frame data over 04758 * 2. Redo calltoken IE, it will always be the last ie in the frame. 04759 * NOTE: Having the ie always be last is not protocol specified, 04760 * it is only an implementation choice. Since we only expect the ie to 04761 * be last for frames we have sent, this can no way be affected by 04762 * another end point. 04763 * 3. Remove frame from queue 04764 * 4. Free old frame 04765 * 5. Clear previous seqnos 04766 * 6. Resend with CALLTOKEN ie. 04767 */ 04768 04769 /* ---1.--- */ 04770 memcpy(&data, f->data, f->datalen); 04771 data.ied.pos = ie_data_pos; 04772 04773 /* ---2.--- */ 04774 /* move to the beginning of the calltoken ie so we can write over it */ 04775 data.ied.pos -= pvt->calltoken_ie_len; 04776 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken); 04777 04778 /* make sure to update token length incase it ever has to be stripped off again */ 04779 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */ 04780 04781 /* ---3.--- */ 04782 AST_LIST_REMOVE(&frame_queue[callno], f, list); 04783 04784 /* ---4.--- */ 04785 iax2_frame_free(f); 04786 04787 /* ---5.--- */ 04788 pvt->oseqno = 0; 04789 pvt->rseqno = 0; 04790 pvt->iseqno = 0; 04791 pvt->aseqno = 0; 04792 if (pvt->peercallno) { 04793 remove_by_peercallno(pvt); 04794 pvt->peercallno = 0; 04795 } 04796 04797 /* ---6.--- */ 04798 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1); 04799 }
Definition at line 9365 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().
09366 { 09367 int i; 09368 unsigned int length, offset = 0; 09369 char full_osptoken[IAX_MAX_OSPBUFF_SIZE]; 09370 09371 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) { 09372 length = ies->ospblocklength[i]; 09373 if (length != 0) { 09374 if (length > IAX_MAX_OSPBLOCK_SIZE) { 09375 /* OSP token block length wrong, clear buffer */ 09376 offset = 0; 09377 break; 09378 } else { 09379 memcpy(full_osptoken + offset, ies->osptokenblock[i], length); 09380 offset += length; 09381 } 09382 } else { 09383 break; 09384 } 09385 } 09386 *(full_osptoken + offset) = '\0'; 09387 if (strlen(full_osptoken) != offset) { 09388 /* OSP token length wrong, clear buffer */ 09389 *full_osptoken = '\0'; 09390 } 09391 09392 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken); 09393 }
Definition at line 9354 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().
09355 { 09356 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 09357 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 09358 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 09359 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 09360 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 09361 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 09362 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 09363 }
static void sched_delay_remove | ( | struct sockaddr_in * | sin, | |
struct callno_entry * | callno_entry | |||
) | [static] |
Definition at line 2704 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().
02705 { 02706 int i; 02707 struct peercnt *peercnt; 02708 struct peercnt tmp = { 02709 .addr = sin->sin_addr.s_addr, 02710 }; 02711 02712 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02713 /* refcount is incremented with ao2_find. keep that ref for the scheduler */ 02714 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME); 02715 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt); 02716 if (i == -1) { 02717 ao2_ref(peercnt, -1); 02718 } 02719 } 02720 02721 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry); 02722 }
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 4133 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::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().
04134 { 04135 int type, len; 04136 int ret; 04137 int needfree = 0; 04138 struct ast_channel *owner = NULL; 04139 struct ast_channel *bridge = NULL; 04140 04141 /* Attempt to recover wrapped timestamps */ 04142 unwrap_timestamp(fr); 04143 04144 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 04145 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 04146 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 04147 else { 04148 #if 0 04149 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 04150 #endif 04151 fr->af.delivery = ast_tv(0,0); 04152 } 04153 04154 type = JB_TYPE_CONTROL; 04155 len = 0; 04156 04157 if(fr->af.frametype == AST_FRAME_VOICE) { 04158 type = JB_TYPE_VOICE; 04159 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000); 04160 } else if(fr->af.frametype == AST_FRAME_CNG) { 04161 type = JB_TYPE_SILENCE; 04162 } 04163 04164 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 04165 if (tsout) 04166 *tsout = fr->ts; 04167 __do_deliver(fr); 04168 return -1; 04169 } 04170 04171 iax2_lock_owner(fr->callno); 04172 if (!iaxs[fr->callno]) { 04173 /* The call dissappeared so discard this frame that we could not send. */ 04174 iax2_frame_free(fr); 04175 return -1; 04176 } 04177 if ((owner = iaxs[fr->callno]->owner)) 04178 bridge = ast_bridged_channel(owner); 04179 04180 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 04181 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 04182 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 04183 jb_frame frame; 04184 04185 ast_channel_unlock(owner); 04186 04187 /* deliver any frames in the jb */ 04188 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 04189 __do_deliver(frame.data); 04190 /* __do_deliver() can make the call disappear */ 04191 if (!iaxs[fr->callno]) 04192 return -1; 04193 } 04194 04195 jb_reset(iaxs[fr->callno]->jb); 04196 04197 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid); 04198 04199 /* deliver this frame now */ 04200 if (tsout) 04201 *tsout = fr->ts; 04202 __do_deliver(fr); 04203 return -1; 04204 } 04205 if (owner) { 04206 ast_channel_unlock(owner); 04207 } 04208 04209 /* insert into jitterbuffer */ 04210 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 04211 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 04212 calc_rxstamp(iaxs[fr->callno],fr->ts)); 04213 if (ret == JB_DROP) { 04214 needfree++; 04215 } else if (ret == JB_SCHED) { 04216 update_jbsched(iaxs[fr->callno]); 04217 } 04218 if (tsout) 04219 *tsout = fr->ts; 04220 if (needfree) { 04221 /* Free our iax frame */ 04222 iax2_frame_free(fr); 04223 return -1; 04224 } 04225 return 0; 04226 }
static int scheduled_destroy | ( | const void * | vid | ) | [static] |
Definition at line 1807 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().
01808 { 01809 unsigned short callno = PTR_TO_CALLNO(vid); 01810 ast_mutex_lock(&iaxsl[callno]); 01811 if (iaxs[callno]) { 01812 if (option_debug) { 01813 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno); 01814 } 01815 iax2_destroy(callno); 01816 } 01817 ast_mutex_unlock(&iaxsl[callno]); 01818 return 0; 01819 }
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 4683 of file chan_iax2.c.
References AST_FRAME_IAX, iax_ie_data::buf, compress_subclass(), f, and iax_ie_data::pos.
Referenced by handle_call_token(), and socket_process().
04686 { 04687 struct { 04688 struct ast_iax2_full_hdr f; 04689 struct iax_ie_data ied; 04690 } data; 04691 size_t size = sizeof(struct ast_iax2_full_hdr); 04692 04693 if (ied) { 04694 size += ied->pos; 04695 memcpy(&data.ied, ied->buf, ied->pos); 04696 } 04697 04698 data.f.scallno = htons(0x8000 | callno); 04699 data.f.dcallno = htons(dcallno); 04700 data.f.ts = htonl(ts); 04701 data.f.iseqno = seqno; 04702 data.f.oseqno = 0; 04703 data.f.type = AST_FRAME_IAX; 04704 data.f.csub = compress_subclass(command); 04705 04706 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin)); 04707 }
static int send_command | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 7459 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().
07460 { 07461 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 07462 }
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 7478 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().
07479 { 07480 int call_num = i->callno; 07481 /* It is assumed that the callno has already been locked */ 07482 iax2_predestroy(i->callno); 07483 if (!iaxs[call_num]) 07484 return -1; 07485 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 07486 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 7488 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
07489 { 07490 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 07491 }
static int send_command_locked | ( | unsigned short | callno, | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 7464 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().
07465 { 07466 int res; 07467 ast_mutex_lock(&iaxsl[callno]); 07468 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 07469 ast_mutex_unlock(&iaxsl[callno]); 07470 return res; 07471 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | ||||
) | [static] |
Definition at line 7493 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
07494 { 07495 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 07496 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1593 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().
01594 { 01595 int callno = (long) data; 01596 ast_mutex_lock(&iaxsl[callno]); 01597 if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) { 01598 iaxs[callno]->lagid = -1; 01599 } 01600 ast_mutex_unlock(&iaxsl[callno]); 01601 01602 #ifdef SCHED_MULTITHREADED 01603 if (schedule_action(__send_lagrq, data)) 01604 #endif 01605 __send_lagrq(data); 01606 return 0; 01607 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3313 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().
03314 { 03315 int res; 03316 int callno = f->callno; 03317 03318 /* Don't send if there was an error, but return error instead */ 03319 if (!callno || !iaxs[callno] || iaxs[callno]->error) 03320 return -1; 03321 03322 /* Called with iaxsl held */ 03323 if (iaxdebug) 03324 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)); 03325 03326 if (f->transfer) { 03327 if (iaxdebug) 03328 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03329 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer)); 03330 } else { 03331 if (iaxdebug) 03332 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03333 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr)); 03334 } 03335 if (res < 0) { 03336 if (iaxdebug) 03337 ast_debug(1, "Received error: %s\n", strerror(errno)); 03338 handle_error(); 03339 } else 03340 res = 0; 03341 03342 return res; 03343 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1526 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().
01527 { 01528 int callno = (long) data; 01529 ast_mutex_lock(&iaxsl[callno]); 01530 if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) { 01531 iaxs[callno]->pingid = -1; 01532 } 01533 ast_mutex_unlock(&iaxsl[callno]); 01534 01535 #ifdef SCHED_MULTITHREADED 01536 if (schedule_action(__send_ping, data)) 01537 #endif 01538 __send_ping(data); 01539 01540 return 0; 01541 }
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 1829 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().
01830 { 01831 struct signaling_queue_entry *s = NULL; 01832 01833 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01834 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0); 01835 free_signaling_queue_entry(s); 01836 } 01837 pvt->hold_signaling = 0; 01838 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 9068 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().
09069 { 09070 int res = 0; 09071 struct iax_frame *fr; 09072 struct ast_iax2_meta_hdr *meta; 09073 struct ast_iax2_meta_trunk_hdr *mth; 09074 int calls = 0; 09075 09076 /* Point to frame */ 09077 fr = (struct iax_frame *)tpeer->trunkdata; 09078 /* Point to meta data */ 09079 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 09080 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 09081 if (tpeer->trunkdatalen) { 09082 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 09083 meta->zeros = 0; 09084 meta->metacmd = IAX_META_TRUNK; 09085 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) 09086 meta->cmddata = IAX_META_TRUNK_MINI; 09087 else 09088 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 09089 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 09090 /* And the rest of the ast_iax2 header */ 09091 fr->direction = DIRECTION_OUTGRESS; 09092 fr->retrans = -1; 09093 fr->transfer = 0; 09094 /* Any appropriate call will do */ 09095 fr->data = fr->afdata; 09096 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 09097 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 09098 calls = tpeer->calls; 09099 #if 0 09100 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)); 09101 #endif 09102 /* Reset transmit trunk side data */ 09103 tpeer->trunkdatalen = 0; 09104 tpeer->calls = 0; 09105 } 09106 if (res < 0) 09107 return res; 09108 return calls; 09109 }
static int set_config | ( | const char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 12916 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_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, build_callno_limits(), build_peer(), build_user(), capability, CONFIG_FLAG_FILEUNCHANGED, config_flags, 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(), user, user_unref(), users, and ast_variable::value.
Referenced by load_module(), reload(), and reload_config().
12917 { 12918 struct ast_config *cfg, *ucfg; 12919 format_t capability = iax2_capability; 12920 struct ast_variable *v; 12921 char *cat; 12922 const char *utype; 12923 const char *tosval; 12924 int format; 12925 int portno = IAX_DEFAULT_PORTNO; 12926 int x; 12927 int mtuv; 12928 int subscribe_network_change = 1; 12929 struct iax2_user *user; 12930 struct iax2_peer *peer; 12931 struct ast_netsock *ns; 12932 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 12933 #if 0 12934 static unsigned short int last_port=0; 12935 #endif 12936 12937 cfg = ast_config_load(config_file, config_flags); 12938 12939 if (!cfg) { 12940 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 12941 return -1; 12942 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 12943 ucfg = ast_config_load("users.conf", config_flags); 12944 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) 12945 return 0; 12946 /* Otherwise we need to reread both files */ 12947 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 12948 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) { 12949 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 12950 ast_config_destroy(ucfg); 12951 return 0; 12952 } 12953 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 12954 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 12955 return 0; 12956 } else { /* iax.conf changed, gotta reread users.conf, too */ 12957 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 12958 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 12959 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n"); 12960 ast_config_destroy(cfg); 12961 return 0; 12962 } 12963 } 12964 12965 if (reload) { 12966 set_config_destroy(); 12967 } 12968 12969 /* Reset global codec prefs */ 12970 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 12971 12972 /* Reset Global Flags */ 12973 memset(&globalflags, 0, sizeof(globalflags)); 12974 ast_set_flag64(&globalflags, IAX_RTUPDATE); 12975 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 12976 12977 #ifdef SO_NO_CHECK 12978 nochecksums = 0; 12979 #endif 12980 /* Reset default parking lot */ 12981 default_parkinglot[0] = '\0'; 12982 12983 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 12984 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 12985 global_max_trunk_mtu = MAX_TRUNK_MTU; 12986 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT; 12987 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL; 12988 12989 maxauthreq = 3; 12990 12991 srvlookup = 0; 12992 12993 v = ast_variable_browse(cfg, "general"); 12994 12995 /* Seed initial tos value */ 12996 tosval = ast_variable_retrieve(cfg, "general", "tos"); 12997 if (tosval) { 12998 if (ast_str2tos(tosval, &qos.tos)) 12999 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n"); 13000 } 13001 /* Seed initial cos value */ 13002 tosval = ast_variable_retrieve(cfg, "general", "cos"); 13003 if (tosval) { 13004 if (ast_str2cos(tosval, &qos.cos)) 13005 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n"); 13006 } 13007 while(v) { 13008 if (!strcasecmp(v->name, "bindport")){ 13009 if (reload) 13010 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 13011 else 13012 portno = atoi(v->value); 13013 } else if (!strcasecmp(v->name, "pingtime")) 13014 ping_time = atoi(v->value); 13015 else if (!strcasecmp(v->name, "iaxthreadcount")) { 13016 if (reload) { 13017 if (atoi(v->value) != iaxthreadcount) 13018 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 13019 } else { 13020 iaxthreadcount = atoi(v->value); 13021 if (iaxthreadcount < 1) { 13022 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 13023 iaxthreadcount = 1; 13024 } else if (iaxthreadcount > 256) { 13025 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 13026 iaxthreadcount = 256; 13027 } 13028 } 13029 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 13030 if (reload) { 13031 AST_LIST_LOCK(&dynamic_list); 13032 iaxmaxthreadcount = atoi(v->value); 13033 AST_LIST_UNLOCK(&dynamic_list); 13034 } else { 13035 iaxmaxthreadcount = atoi(v->value); 13036 if (iaxmaxthreadcount < 0) { 13037 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 13038 iaxmaxthreadcount = 0; 13039 } else if (iaxmaxthreadcount > 256) { 13040 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 13041 iaxmaxthreadcount = 256; 13042 } 13043 } 13044 } else if (!strcasecmp(v->name, "nochecksums")) { 13045 #ifdef SO_NO_CHECK 13046 if (ast_true(v->value)) 13047 nochecksums = 1; 13048 else 13049 nochecksums = 0; 13050 #else 13051 if (ast_true(v->value)) 13052 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 13053 #endif 13054 } 13055 else if (!strcasecmp(v->name, "maxjitterbuffer")) 13056 maxjitterbuffer = atoi(v->value); 13057 else if (!strcasecmp(v->name, "resyncthreshold")) 13058 resyncthreshold = atoi(v->value); 13059 else if (!strcasecmp(v->name, "maxjitterinterps")) 13060 maxjitterinterps = atoi(v->value); 13061 else if (!strcasecmp(v->name, "jittertargetextra")) 13062 jittertargetextra = atoi(v->value); 13063 else if (!strcasecmp(v->name, "lagrqtime")) 13064 lagrq_time = atoi(v->value); 13065 else if (!strcasecmp(v->name, "maxregexpire")) 13066 max_reg_expire = atoi(v->value); 13067 else if (!strcasecmp(v->name, "minregexpire")) 13068 min_reg_expire = atoi(v->value); 13069 else if (!strcasecmp(v->name, "bindaddr")) { 13070 if (reload) { 13071 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 13072 } else { 13073 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) { 13074 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 13075 } else { 13076 if (strchr(v->value, ':')) 13077 ast_verb(2, "Binding IAX2 to '%s'\n", v->value); 13078 else 13079 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno); 13080 if (defaultsockfd < 0) 13081 defaultsockfd = ast_netsock_sockfd(ns); 13082 ast_netsock_unref(ns); 13083 } 13084 } 13085 } else if (!strcasecmp(v->name, "authdebug")) { 13086 authdebug = ast_true(v->value); 13087 } else if (!strcasecmp(v->name, "encryption")) { 13088 iax2_encryption |= get_encrypt_methods(v->value); 13089 if (!iax2_encryption) { 13090 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13091 } 13092 } else if (!strcasecmp(v->name, "forceencryption")) { 13093 if (ast_false(v->value)) { 13094 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13095 } else { 13096 iax2_encryption |= get_encrypt_methods(v->value); 13097 if (iax2_encryption) { 13098 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13099 } 13100 } 13101 } else if (!strcasecmp(v->name, "transfer")) { 13102 if (!strcasecmp(v->value, "mediaonly")) { 13103 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 13104 } else if (ast_true(v->value)) { 13105 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 13106 } else 13107 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 13108 } else if (!strcasecmp(v->name, "codecpriority")) { 13109 if(!strcasecmp(v->value, "caller")) 13110 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST); 13111 else if(!strcasecmp(v->value, "disabled")) 13112 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13113 else if(!strcasecmp(v->value, "reqonly")) { 13114 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP); 13115 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13116 } 13117 } else if (!strcasecmp(v->name, "jitterbuffer")) 13118 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 13119 else if (!strcasecmp(v->name, "forcejitterbuffer")) 13120 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 13121 else if (!strcasecmp(v->name, "delayreject")) 13122 delayreject = ast_true(v->value); 13123 else if (!strcasecmp(v->name, "allowfwdownload")) 13124 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 13125 else if (!strcasecmp(v->name, "rtcachefriends")) 13126 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 13127 else if (!strcasecmp(v->name, "rtignoreregexpire")) 13128 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 13129 else if (!strcasecmp(v->name, "rtupdate")) 13130 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE); 13131 else if (!strcasecmp(v->name, "rtsavesysname")) 13132 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME); 13133 else if (!strcasecmp(v->name, "trunktimestamps")) 13134 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 13135 else if (!strcasecmp(v->name, "rtautoclear")) { 13136 int i = atoi(v->value); 13137 if(i > 0) 13138 global_rtautoclear = i; 13139 else 13140 i = 0; 13141 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 13142 } else if (!strcasecmp(v->name, "trunkfreq")) { 13143 trunkfreq = atoi(v->value); 13144 if (trunkfreq < 10) 13145 trunkfreq = 10; 13146 } else if (!strcasecmp(v->name, "trunkmtu")) { 13147 mtuv = atoi(v->value); 13148 if (mtuv == 0 ) 13149 global_max_trunk_mtu = 0; 13150 else if (mtuv >= 172 && mtuv < 4000) 13151 global_max_trunk_mtu = mtuv; 13152 else 13153 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n", 13154 mtuv, v->lineno); 13155 } else if (!strcasecmp(v->name, "trunkmaxsize")) { 13156 trunkmaxsize = atoi(v->value); 13157 if (trunkmaxsize == 0) 13158 trunkmaxsize = MAX_TRUNKDATA; 13159 } else if (!strcasecmp(v->name, "autokill")) { 13160 if (sscanf(v->value, "%30d", &x) == 1) { 13161 if (x >= 0) 13162 autokill = x; 13163 else 13164 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 13165 } else if (ast_true(v->value)) { 13166 autokill = DEFAULT_MAXMS; 13167 } else { 13168 autokill = 0; 13169 } 13170 } else if (!strcasecmp(v->name, "bandwidth")) { 13171 if (!strcasecmp(v->value, "low")) { 13172 capability = IAX_CAPABILITY_LOWBANDWIDTH; 13173 } else if (!strcasecmp(v->value, "medium")) { 13174 capability = IAX_CAPABILITY_MEDBANDWIDTH; 13175 } else if (!strcasecmp(v->value, "high")) { 13176 capability = IAX_CAPABILITY_FULLBANDWIDTH; 13177 } else 13178 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 13179 } else if (!strcasecmp(v->name, "allow")) { 13180 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 13181 } else if (!strcasecmp(v->name, "disallow")) { 13182 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 13183 } else if (!strcasecmp(v->name, "register")) { 13184 iax2_register(v->value, v->lineno); 13185 } else if (!strcasecmp(v->name, "iaxcompat")) { 13186 iaxcompat = ast_true(v->value); 13187 } else if (!strcasecmp(v->name, "regcontext")) { 13188 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 13189 /* Create context if it doesn't exist already */ 13190 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2"); 13191 } else if (!strcasecmp(v->name, "tos")) { 13192 if (ast_str2tos(v->value, &qos.tos)) 13193 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno); 13194 } else if (!strcasecmp(v->name, "cos")) { 13195 if (ast_str2cos(v->value, &qos.cos)) 13196 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno); 13197 } else if (!strcasecmp(v->name, "parkinglot")) { 13198 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot)); 13199 } else if (!strcasecmp(v->name, "accountcode")) { 13200 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 13201 } else if (!strcasecmp(v->name, "mohinterpret")) { 13202 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 13203 } else if (!strcasecmp(v->name, "mohsuggest")) { 13204 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 13205 } else if (!strcasecmp(v->name, "amaflags")) { 13206 format = ast_cdr_amaflags2int(v->value); 13207 if (format < 0) { 13208 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 13209 } else { 13210 amaflags = format; 13211 } 13212 } else if (!strcasecmp(v->name, "language")) { 13213 ast_copy_string(language, v->value, sizeof(language)); 13214 } else if (!strcasecmp(v->name, "maxauthreq")) { 13215 maxauthreq = atoi(v->value); 13216 if (maxauthreq < 0) 13217 maxauthreq = 0; 13218 } else if (!strcasecmp(v->name, "adsi")) { 13219 adsi = ast_true(v->value); 13220 } else if (!strcasecmp(v->name, "srvlookup")) { 13221 srvlookup = ast_true(v->value); 13222 } else if (!strcasecmp(v->name, "connectedline")) { 13223 if (ast_true(v->value)) { 13224 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13225 } else if (!strcasecmp(v->value, "send")) { 13226 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13227 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13228 } else if (!strcasecmp(v->value, "receive")) { 13229 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13230 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13231 } else { 13232 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13233 } 13234 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 13235 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) { 13236 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno); 13237 } 13238 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) { 13239 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) { 13240 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); 13241 } 13242 } else if (!strcasecmp(v->name, "calltokenoptional")) { 13243 if (add_calltoken_ignore(v->value)) { 13244 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno); 13245 } 13246 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) { 13247 if (ast_true(v->value)) { 13248 subscribe_network_change = 1; 13249 } else if (ast_false(v->value)) { 13250 subscribe_network_change = 0; 13251 } else { 13252 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno); 13253 } 13254 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 13255 if (ast_true(v->value)) { 13256 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 13257 } else if (ast_false(v->value)) { 13258 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID); 13259 } else { 13260 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 13261 } 13262 }/*else if (strcasecmp(v->name,"type")) */ 13263 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 13264 v = v->next; 13265 } 13266 13267 if (subscribe_network_change) { 13268 network_change_event_subscribe(); 13269 } else { 13270 network_change_event_unsubscribe(); 13271 } 13272 13273 if (defaultsockfd < 0) { 13274 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) { 13275 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 13276 } else { 13277 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 13278 defaultsockfd = ast_netsock_sockfd(ns); 13279 ast_netsock_unref(ns); 13280 } 13281 } 13282 if (reload) { 13283 ast_netsock_release(outsock); 13284 outsock = ast_netsock_list_alloc(); 13285 if (!outsock) { 13286 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 13287 return -1; 13288 } 13289 ast_netsock_init(outsock); 13290 } 13291 13292 if (min_reg_expire > max_reg_expire) { 13293 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 13294 min_reg_expire, max_reg_expire, max_reg_expire); 13295 min_reg_expire = max_reg_expire; 13296 } 13297 iax2_capability = capability; 13298 13299 if (ucfg) { 13300 struct ast_variable *gen; 13301 int genhasiax; 13302 int genregisteriax; 13303 const char *hasiax, *registeriax; 13304 13305 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 13306 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 13307 gen = ast_variable_browse(ucfg, "general"); 13308 cat = ast_category_browse(ucfg, NULL); 13309 while (cat) { 13310 if (strcasecmp(cat, "general")) { 13311 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 13312 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 13313 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 13314 /* Start with general parameters, then specific parameters, user and peer */ 13315 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 13316 if (user) { 13317 ao2_link(users, user); 13318 user = user_unref(user); 13319 } 13320 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 13321 if (peer) { 13322 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13323 reg_source_db(peer); 13324 ao2_link(peers, peer); 13325 peer = peer_unref(peer); 13326 } 13327 } 13328 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 13329 char tmp[256]; 13330 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 13331 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 13332 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 13333 if (!host) 13334 host = ast_variable_retrieve(ucfg, "general", "host"); 13335 if (!username) 13336 username = ast_variable_retrieve(ucfg, "general", "username"); 13337 if (!secret) 13338 secret = ast_variable_retrieve(ucfg, "general", "secret"); 13339 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 13340 if (!ast_strlen_zero(secret)) 13341 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 13342 else 13343 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 13344 iax2_register(tmp, 0); 13345 } 13346 } 13347 } 13348 cat = ast_category_browse(ucfg, cat); 13349 } 13350 ast_config_destroy(ucfg); 13351 } 13352 13353 cat = ast_category_browse(cfg, NULL); 13354 while(cat) { 13355 if (strcasecmp(cat, "general")) { 13356 utype = ast_variable_retrieve(cfg, cat, "type"); 13357 if (!strcasecmp(cat, "callnumberlimits")) { 13358 build_callno_limits(ast_variable_browse(cfg, cat)); 13359 } else if (utype) { 13360 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 13361 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 13362 if (user) { 13363 ao2_link(users, user); 13364 user = user_unref(user); 13365 } 13366 } 13367 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 13368 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 13369 if (peer) { 13370 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13371 reg_source_db(peer); 13372 ao2_link(peers, peer); 13373 peer = peer_unref(peer); 13374 } 13375 } else if (strcasecmp(utype, "user")) { 13376 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 13377 } 13378 } else 13379 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 13380 } 13381 cat = ast_category_browse(cfg, cat); 13382 } 13383 ast_config_destroy(cfg); 13384 return 1; 13385 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 12899 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().
12900 { 12901 strcpy(accountcode, ""); 12902 strcpy(language, ""); 12903 strcpy(mohinterpret, "default"); 12904 strcpy(mohsuggest, ""); 12905 trunkmaxsize = MAX_TRUNKDATA; 12906 amaflags = 0; 12907 delayreject = 0; 12908 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | 12909 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12910 delete_users(); 12911 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL); 12912 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL); 12913 }
static void set_hangup_source_and_cause | ( | int | callno, | |
unsigned char | causecode | |||
) | [static] |
Definition at line 9790 of file chan_iax2.c.
References ast_channel_unlock, ast_set_hangupsource(), ast_channel::hangupcause, iax2_lock_owner(), iaxs, and chan_iax2_pvt::owner.
Referenced by socket_process().
09791 { 09792 iax2_lock_owner(callno); 09793 if (iaxs[callno] && iaxs[callno]->owner) { 09794 if (causecode) { 09795 iaxs[callno]->owner->hangupcause = causecode; 09796 } 09797 ast_set_hangupsource(iaxs[callno]->owner, iaxs[callno]->owner->name, 0); 09798 ast_channel_unlock(iaxs[callno]->owner); 09799 } 09800 }
static void set_peercnt_limit | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2248 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().
02249 { 02250 uint16_t limit = global_maxcallno; 02251 struct addr_range *addr_range; 02252 struct sockaddr_in sin = { 02253 .sin_addr.s_addr = peercnt->addr, 02254 }; 02255 02256 02257 if (peercnt->reg && peercnt->limit) { 02258 return; /* this peercnt has a custom limit set by a registration */ 02259 } 02260 02261 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) { 02262 limit = addr_range->limit; 02263 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr)); 02264 ao2_ref(addr_range, -1); 02265 } 02266 02267 peercnt->limit = limit; 02268 }
static int set_peercnt_limit_all_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2274 of file chan_iax2.c.
References ast_debug, and set_peercnt_limit().
Referenced by reload_config().
02275 { 02276 struct peercnt *peercnt = obj; 02277 02278 set_peercnt_limit(peercnt); 02279 ast_debug(1, "Reset limits for peercnts table\n"); 02280 02281 return 0; 02282 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 1047 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().
01048 { 01049 ast_mutex_lock(lock); 01050 ast_cond_signal(cond); 01051 ast_mutex_unlock(lock); 01052 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 9802 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_unlock, 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(), ast_channel::context, 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().
09803 { 09804 struct sockaddr_in sin; 09805 int res; 09806 int updatehistory=1; 09807 int new = NEW_PREVENT; 09808 int dcallno = 0; 09809 char decrypted = 0; 09810 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 09811 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 09812 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 09813 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 09814 struct iax_frame *fr; 09815 struct iax_frame *cur; 09816 struct ast_frame f = { 0, }; 09817 struct ast_channel *c = NULL; 09818 struct iax2_dpcache *dp; 09819 struct iax2_peer *peer; 09820 struct iax_ies ies; 09821 struct iax_ie_data ied0, ied1; 09822 format_t format; 09823 int fd; 09824 int exists; 09825 int minivid = 0; 09826 char empty[32]=""; /* Safety measure */ 09827 struct iax_frame *duped_fr; 09828 char host_pref_buf[128]; 09829 char caller_pref_buf[128]; 09830 struct ast_codec_pref pref; 09831 char *using_prefs = "mine"; 09832 09833 /* allocate an iax_frame with 4096 bytes of data buffer */ 09834 fr = alloca(sizeof(*fr) + 4096); 09835 memset(fr, 0, sizeof(*fr)); 09836 fr->afdatalen = 4096; /* From alloca() above */ 09837 09838 /* Copy frequently used parameters to the stack */ 09839 res = thread->buf_len; 09840 fd = thread->iofd; 09841 memcpy(&sin, &thread->iosin, sizeof(sin)); 09842 09843 if (res < sizeof(*mh)) { 09844 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh)); 09845 return 1; 09846 } 09847 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 09848 if (res < sizeof(*vh)) { 09849 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)); 09850 return 1; 09851 } 09852 09853 /* This is a video frame, get call number */ 09854 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 09855 minivid = 1; 09856 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) 09857 return socket_process_meta(res, meta, &sin, fd, fr); 09858 09859 #ifdef DEBUG_SUPPORT 09860 if (res >= sizeof(*fh)) 09861 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 09862 #endif 09863 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 09864 if (res < sizeof(*fh)) { 09865 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)); 09866 return 1; 09867 } 09868 09869 /* Get the destination call number */ 09870 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 09871 09872 09873 /* check to make sure this full frame isn't encrypted before we attempt 09874 * to look inside of it. If it is encrypted, decrypt it first. Its ok if the 09875 * callno is not found here, that just means one hasn't been allocated for 09876 * this connection yet. */ 09877 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) { 09878 ast_mutex_lock(&iaxsl[fr->callno]); 09879 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) { 09880 if (decrypt_frame(fr->callno, fh, &f, &res)) { 09881 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 09882 ast_mutex_unlock(&iaxsl[fr->callno]); 09883 return 1; 09884 } 09885 decrypted = 1; 09886 } 09887 ast_mutex_unlock(&iaxsl[fr->callno]); 09888 } 09889 09890 /* Retrieve the type and subclass */ 09891 f.frametype = fh->type; 09892 if (f.frametype == AST_FRAME_VIDEO) { 09893 f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 09894 } else if (f.frametype == AST_FRAME_VOICE) { 09895 f.subclass.codec = uncompress_subclass(fh->csub); 09896 } else { 09897 f.subclass.integer = uncompress_subclass(fh->csub); 09898 } 09899 09900 /* Deal with POKE/PONG without allocating a callno */ 09901 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) { 09902 /* Reply back with a PONG, but don't care about the result. */ 09903 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 09904 return 1; 09905 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) { 09906 /* Ignore */ 09907 return 1; 09908 } 09909 09910 f.datalen = res - sizeof(*fh); 09911 if (f.datalen) { 09912 if (f.frametype == AST_FRAME_IAX) { 09913 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) { 09914 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 09915 ast_variables_destroy(ies.vars); 09916 return 1; 09917 } 09918 f.data.ptr = NULL; 09919 f.datalen = 0; 09920 } else { 09921 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr); 09922 memset(&ies, 0, sizeof(ies)); 09923 } 09924 } else { 09925 if (f.frametype == AST_FRAME_IAX) 09926 f.data.ptr = NULL; 09927 else 09928 f.data.ptr = empty; 09929 memset(&ies, 0, sizeof(ies)); 09930 } 09931 09932 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) { 09933 /* only set NEW_ALLOW if calltoken checks out */ 09934 if (handle_call_token(fh, &ies, &sin, fd)) { 09935 ast_variables_destroy(ies.vars); 09936 return 1; 09937 } 09938 09939 if (ies.calltoken && ies.calltokendata) { 09940 /* if we've gotten this far, and the calltoken ie data exists, 09941 * then calltoken validation _MUST_ have taken place. If calltoken 09942 * data is provided, it is always validated reguardless of any 09943 * calltokenoptional or requirecalltoken options */ 09944 new = NEW_ALLOW_CALLTOKEN_VALIDATED; 09945 } else { 09946 new = NEW_ALLOW; 09947 } 09948 } 09949 } else { 09950 /* Don't know anything about it yet */ 09951 f.frametype = AST_FRAME_NULL; 09952 f.subclass.integer = 0; 09953 memset(&ies, 0, sizeof(ies)); 09954 } 09955 09956 if (!fr->callno) { 09957 int check_dcallno = 0; 09958 09959 /* 09960 * We enforce accurate destination call numbers for ACKs. This forces the other 09961 * end to know the destination call number before call setup can complete. 09962 * 09963 * Discussed in the following thread: 09964 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 09965 */ 09966 09967 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) { 09968 check_dcallno = 1; 09969 } 09970 09971 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) { 09972 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) { 09973 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 09974 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) { 09975 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 09976 } 09977 ast_variables_destroy(ies.vars); 09978 return 1; 09979 } 09980 } 09981 09982 if (fr->callno > 0) 09983 ast_mutex_lock(&iaxsl[fr->callno]); 09984 09985 if (!fr->callno || !iaxs[fr->callno]) { 09986 /* A call arrived for a nonexistent destination. Unless it's an "inval" 09987 frame, reply with an inval */ 09988 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 09989 /* We can only raw hangup control frames */ 09990 if (((f.subclass.integer != IAX_COMMAND_INVAL) && 09991 (f.subclass.integer != IAX_COMMAND_TXCNT) && 09992 (f.subclass.integer != IAX_COMMAND_TXACC) && 09993 (f.subclass.integer != IAX_COMMAND_FWDOWNL))|| 09994 (f.frametype != AST_FRAME_IAX)) 09995 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 09996 fd); 09997 } 09998 if (fr->callno > 0) 09999 ast_mutex_unlock(&iaxsl[fr->callno]); 10000 ast_variables_destroy(ies.vars); 10001 return 1; 10002 } 10003 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) { 10004 if (decrypt_frame(fr->callno, fh, &f, &res)) { 10005 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 10006 ast_variables_destroy(ies.vars); 10007 ast_mutex_unlock(&iaxsl[fr->callno]); 10008 return 1; 10009 } 10010 decrypted = 1; 10011 } 10012 10013 #ifdef DEBUG_SUPPORT 10014 if (decrypted) { 10015 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 10016 } 10017 #endif 10018 10019 10020 /* count this frame */ 10021 iaxs[fr->callno]->frames_received++; 10022 10023 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 10024 f.subclass.integer != IAX_COMMAND_TXCNT && /* for attended transfer */ 10025 f.subclass.integer != IAX_COMMAND_TXACC) { /* for attended transfer */ 10026 unsigned short new_peercallno; 10027 10028 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 10029 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 10030 if (iaxs[fr->callno]->peercallno) { 10031 remove_by_peercallno(iaxs[fr->callno]); 10032 } 10033 iaxs[fr->callno]->peercallno = new_peercallno; 10034 store_by_peercallno(iaxs[fr->callno]); 10035 } 10036 } 10037 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10038 if (iaxdebug) 10039 ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer); 10040 /* Check if it's out of order (and not an ACK or INVAL) */ 10041 fr->oseqno = fh->oseqno; 10042 fr->iseqno = fh->iseqno; 10043 fr->ts = ntohl(fh->ts); 10044 #ifdef IAXTESTS 10045 if (test_resync) { 10046 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 10047 fr->ts += test_resync; 10048 } 10049 #endif /* IAXTESTS */ 10050 #if 0 10051 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 10052 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 10053 (f.subclass == IAX_COMMAND_NEW || 10054 f.subclass == IAX_COMMAND_AUTHREQ || 10055 f.subclass == IAX_COMMAND_ACCEPT || 10056 f.subclass == IAX_COMMAND_REJECT)) ) ) 10057 #endif 10058 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 10059 updatehistory = 0; 10060 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 10061 (iaxs[fr->callno]->iseqno || 10062 ((f.subclass.integer != IAX_COMMAND_TXCNT) && 10063 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10064 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10065 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10066 (f.subclass.integer != IAX_COMMAND_TXACC)) || 10067 (f.frametype != AST_FRAME_IAX))) { 10068 if ( 10069 ((f.subclass.integer != IAX_COMMAND_ACK) && 10070 (f.subclass.integer != IAX_COMMAND_INVAL) && 10071 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10072 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10073 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10074 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10075 (f.subclass.integer != IAX_COMMAND_TXACC) && 10076 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10077 (f.frametype != AST_FRAME_IAX)) { 10078 /* If it's not an ACK packet, it's out of order. */ 10079 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 10080 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer); 10081 /* Check to see if we need to request retransmission, 10082 * and take sequence number wraparound into account */ 10083 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 10084 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 10085 if ((f.frametype != AST_FRAME_IAX) || 10086 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) { 10087 ast_debug(1, "Acking anyway\n"); 10088 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 10089 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 10090 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10091 } 10092 } else { 10093 /* Send a VNAK requesting retransmission */ 10094 iax2_vnak(fr->callno); 10095 } 10096 ast_variables_destroy(ies.vars); 10097 ast_mutex_unlock(&iaxsl[fr->callno]); 10098 return 1; 10099 } 10100 } else { 10101 /* Increment unless it's an ACK or VNAK */ 10102 if (((f.subclass.integer != IAX_COMMAND_ACK) && 10103 (f.subclass.integer != IAX_COMMAND_INVAL) && 10104 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10105 (f.subclass.integer != IAX_COMMAND_TXACC) && 10106 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10107 (f.frametype != AST_FRAME_IAX)) 10108 iaxs[fr->callno]->iseqno++; 10109 } 10110 /* Ensure text frames are NULL-terminated */ 10111 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 10112 if (res < thread->buf_size) 10113 thread->buf[res++] = '\0'; 10114 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 10115 thread->buf[res - 1] = '\0'; 10116 } 10117 10118 /* Handle implicit ACKing unless this is an INVAL, and only if this is 10119 from the real peer, not the transfer peer */ 10120 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10121 ((f.subclass.integer != IAX_COMMAND_INVAL) || 10122 (f.frametype != AST_FRAME_IAX))) { 10123 unsigned char x; 10124 int call_to_destroy; 10125 /* First we have to qualify that the ACKed value is within our window */ 10126 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno)) 10127 x = fr->iseqno; 10128 else 10129 x = iaxs[fr->callno]->oseqno; 10130 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 10131 /* The acknowledgement is within our window. Time to acknowledge everything 10132 that it says to */ 10133 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 10134 /* Ack the packet with the given timestamp */ 10135 if (iaxdebug) 10136 ast_debug(1, "Cancelling transmission of packet %d\n", x); 10137 call_to_destroy = 0; 10138 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10139 /* If it's our call, and our timestamp, mark -1 retries */ 10140 if (x == cur->oseqno) { 10141 cur->retries = -1; 10142 /* Destroy call if this is the end */ 10143 if (cur->final) 10144 call_to_destroy = fr->callno; 10145 } 10146 } 10147 if (call_to_destroy) { 10148 if (iaxdebug) 10149 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy); 10150 ast_mutex_lock(&iaxsl[call_to_destroy]); 10151 iax2_destroy(call_to_destroy); 10152 ast_mutex_unlock(&iaxsl[call_to_destroy]); 10153 } 10154 } 10155 /* Note how much we've received acknowledgement for */ 10156 if (iaxs[fr->callno]) 10157 iaxs[fr->callno]->rseqno = fr->iseqno; 10158 else { 10159 /* Stop processing now */ 10160 ast_variables_destroy(ies.vars); 10161 ast_mutex_unlock(&iaxsl[fr->callno]); 10162 return 1; 10163 } 10164 } else { 10165 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 10166 } 10167 } 10168 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10169 ((f.frametype != AST_FRAME_IAX) || 10170 ((f.subclass.integer != IAX_COMMAND_TXACC) && 10171 (f.subclass.integer != IAX_COMMAND_TXCNT)))) { 10172 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 10173 ast_variables_destroy(ies.vars); 10174 ast_mutex_unlock(&iaxsl[fr->callno]); 10175 return 1; 10176 } 10177 10178 /* when we receive the first full frame for a new incoming channel, 10179 it is safe to start the PBX on the channel because we have now 10180 completed a 3-way handshake with the peer */ 10181 if ((f.frametype == AST_FRAME_VOICE) || 10182 (f.frametype == AST_FRAME_VIDEO) || 10183 (f.frametype == AST_FRAME_IAX)) { 10184 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 10185 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10186 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) { 10187 ast_variables_destroy(ies.vars); 10188 ast_mutex_unlock(&iaxsl[fr->callno]); 10189 return 1; 10190 } 10191 } 10192 10193 if (ies.vars) { 10194 struct ast_datastore *variablestore = NULL; 10195 struct ast_variable *var, *prev = NULL; 10196 AST_LIST_HEAD(, ast_var_t) *varlist; 10197 10198 iax2_lock_owner(fr->callno); 10199 if (!iaxs[fr->callno]) { 10200 ast_variables_destroy(ies.vars); 10201 ast_mutex_unlock(&iaxsl[fr->callno]); 10202 return 1; 10203 } 10204 if ((c = iaxs[fr->callno]->owner)) { 10205 varlist = ast_calloc(1, sizeof(*varlist)); 10206 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 10207 10208 if (variablestore && varlist) { 10209 variablestore->data = varlist; 10210 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 10211 AST_LIST_HEAD_INIT(varlist); 10212 ast_debug(1, "I can haz IAX vars?\n"); 10213 for (var = ies.vars; var; var = var->next) { 10214 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 10215 if (prev) { 10216 ast_free(prev); 10217 } 10218 prev = var; 10219 if (!newvar) { 10220 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 10221 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10222 } else { 10223 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 10224 } 10225 } 10226 if (prev) { 10227 ast_free(prev); 10228 } 10229 ies.vars = NULL; 10230 ast_channel_datastore_add(c, variablestore); 10231 } else { 10232 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10233 if (variablestore) { 10234 ast_datastore_free(variablestore); 10235 } 10236 if (varlist) { 10237 ast_free(varlist); 10238 } 10239 } 10240 ast_channel_unlock(c); 10241 } else { 10242 /* No channel yet, so transfer the variables directly over to the pvt, 10243 * for later inheritance. */ 10244 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n"); 10245 for (var = ies.vars; var && var->next; var = var->next); 10246 if (var) { 10247 var->next = iaxs[fr->callno]->iaxvars; 10248 iaxs[fr->callno]->iaxvars = ies.vars; 10249 ies.vars = NULL; 10250 } 10251 } 10252 } 10253 10254 if (ies.vars) { 10255 ast_debug(1, "I have IAX variables, but they were not processed\n"); 10256 } 10257 } 10258 10259 /* once we receive our first IAX Full Frame that is not CallToken related, send all 10260 * queued signaling frames that were being held. */ 10261 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) { 10262 send_signaling(iaxs[fr->callno]); 10263 } 10264 10265 if (f.frametype == AST_FRAME_VOICE) { 10266 if (f.subclass.codec != iaxs[fr->callno]->voiceformat) { 10267 iaxs[fr->callno]->voiceformat = f.subclass.codec; 10268 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec)); 10269 if (iaxs[fr->callno]->owner) { 10270 iax2_lock_owner(fr->callno); 10271 if (iaxs[fr->callno]) { 10272 if (iaxs[fr->callno]->owner) { 10273 format_t orignative; 10274 10275 orignative = iaxs[fr->callno]->owner->nativeformats; 10276 iaxs[fr->callno]->owner->nativeformats = f.subclass.codec; 10277 if (iaxs[fr->callno]->owner->readformat) 10278 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 10279 iaxs[fr->callno]->owner->nativeformats = orignative; 10280 ast_channel_unlock(iaxs[fr->callno]->owner); 10281 } 10282 } else { 10283 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n"); 10284 /* Free remote variables (if any) */ 10285 if (ies.vars) { 10286 ast_variables_destroy(ies.vars); 10287 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n"); 10288 ies.vars = NULL; 10289 } 10290 ast_mutex_unlock(&iaxsl[fr->callno]); 10291 return 1; 10292 } 10293 } 10294 } 10295 } 10296 if (f.frametype == AST_FRAME_VIDEO) { 10297 if (f.subclass.codec != iaxs[fr->callno]->videoformat) { 10298 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL)); 10299 iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL; 10300 } 10301 } 10302 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) { 10303 if (f.subclass.integer == AST_CONTROL_BUSY) { 10304 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 10305 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) { 10306 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 10307 } 10308 } 10309 if (f.frametype == AST_FRAME_IAX) { 10310 ast_sched_thread_del(sched, iaxs[fr->callno]->initid); 10311 /* Handle the IAX pseudo frame itself */ 10312 if (iaxdebug) 10313 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer); 10314 10315 /* Update last ts unless the frame's timestamp originated with us. */ 10316 if (iaxs[fr->callno]->last < fr->ts && 10317 f.subclass.integer != IAX_COMMAND_ACK && 10318 f.subclass.integer != IAX_COMMAND_PONG && 10319 f.subclass.integer != IAX_COMMAND_LAGRP) { 10320 iaxs[fr->callno]->last = fr->ts; 10321 if (iaxdebug) 10322 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 10323 } 10324 iaxs[fr->callno]->last_iax_message = f.subclass.integer; 10325 if (!iaxs[fr->callno]->first_iax_message) { 10326 iaxs[fr->callno]->first_iax_message = f.subclass.integer; 10327 } 10328 switch(f.subclass.integer) { 10329 case IAX_COMMAND_ACK: 10330 /* Do nothing */ 10331 break; 10332 case IAX_COMMAND_QUELCH: 10333 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10334 /* Generate Manager Hold event, if necessary*/ 10335 if (iaxs[fr->callno]->owner) { 10336 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10337 "Status: On\r\n" 10338 "Channel: %s\r\n" 10339 "Uniqueid: %s\r\n", 10340 iaxs[fr->callno]->owner->name, 10341 iaxs[fr->callno]->owner->uniqueid); 10342 } 10343 10344 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH); 10345 if (ies.musiconhold) { 10346 iax2_lock_owner(fr->callno); 10347 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) { 10348 break; 10349 } 10350 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10351 const char *moh_suggest = iaxs[fr->callno]->mohsuggest; 10352 10353 /* 10354 * We already hold the owner lock so we do not 10355 * need to check iaxs[fr->callno] after it returns. 10356 */ 10357 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 10358 S_OR(moh_suggest, NULL), 10359 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0); 10360 } 10361 ast_channel_unlock(iaxs[fr->callno]->owner); 10362 } 10363 } 10364 break; 10365 case IAX_COMMAND_UNQUELCH: 10366 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10367 iax2_lock_owner(fr->callno); 10368 if (!iaxs[fr->callno]) { 10369 break; 10370 } 10371 /* Generate Manager Unhold event, if necessary */ 10372 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) { 10373 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10374 "Status: Off\r\n" 10375 "Channel: %s\r\n" 10376 "Uniqueid: %s\r\n", 10377 iaxs[fr->callno]->owner->name, 10378 iaxs[fr->callno]->owner->uniqueid); 10379 } 10380 10381 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH); 10382 if (!iaxs[fr->callno]->owner) { 10383 break; 10384 } 10385 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10386 /* 10387 * We already hold the owner lock so we do not 10388 * need to check iaxs[fr->callno] after it returns. 10389 */ 10390 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 10391 } 10392 ast_channel_unlock(iaxs[fr->callno]->owner); 10393 } 10394 break; 10395 case IAX_COMMAND_TXACC: 10396 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 10397 /* Ack the packet with the given timestamp */ 10398 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10399 /* Cancel any outstanding txcnt's */ 10400 if (cur->transfer) { 10401 cur->retries = -1; 10402 } 10403 } 10404 memset(&ied1, 0, sizeof(ied1)); 10405 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 10406 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 10407 iaxs[fr->callno]->transferring = TRANSFER_READY; 10408 } 10409 break; 10410 case IAX_COMMAND_NEW: 10411 /* Ignore if it's already up */ 10412 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 10413 break; 10414 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 10415 ast_mutex_unlock(&iaxsl[fr->callno]); 10416 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 10417 ast_mutex_lock(&iaxsl[fr->callno]); 10418 if (!iaxs[fr->callno]) { 10419 break; 10420 } 10421 } 10422 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 10423 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) { 10424 int new_callno; 10425 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 10426 fr->callno = new_callno; 10427 } 10428 /* For security, always ack immediately */ 10429 if (delayreject) 10430 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10431 if (check_access(fr->callno, &sin, &ies)) { 10432 /* They're not allowed on */ 10433 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10434 if (authdebug) 10435 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); 10436 break; 10437 } 10438 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) { 10439 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10440 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n"); 10441 break; 10442 } 10443 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 10444 const char *context, *exten, *cid_num; 10445 10446 context = ast_strdupa(iaxs[fr->callno]->context); 10447 exten = ast_strdupa(iaxs[fr->callno]->exten); 10448 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 10449 10450 /* This might re-enter the IAX code and need the lock */ 10451 ast_mutex_unlock(&iaxsl[fr->callno]); 10452 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 10453 ast_mutex_lock(&iaxsl[fr->callno]); 10454 10455 if (!iaxs[fr->callno]) { 10456 break; 10457 } 10458 } else 10459 exists = 0; 10460 /* Get OSP token if it does exist */ 10461 save_osptoken(fr, &ies); 10462 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 10463 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 10464 memset(&ied0, 0, sizeof(ied0)); 10465 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10466 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10467 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10468 if (!iaxs[fr->callno]) { 10469 break; 10470 } 10471 if (authdebug) 10472 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); 10473 } else { 10474 /* Select an appropriate format */ 10475 10476 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10477 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10478 using_prefs = "reqonly"; 10479 } else { 10480 using_prefs = "disabled"; 10481 } 10482 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 10483 memset(&pref, 0, sizeof(pref)); 10484 strcpy(caller_pref_buf, "disabled"); 10485 strcpy(host_pref_buf, "disabled"); 10486 } else { 10487 using_prefs = "mine"; 10488 /* If the information elements are in here... use them */ 10489 if (ies.codec_prefs) 10490 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 10491 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10492 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 10493 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10494 pref = iaxs[fr->callno]->rprefs; 10495 using_prefs = "caller"; 10496 } else { 10497 pref = iaxs[fr->callno]->prefs; 10498 } 10499 } else 10500 pref = iaxs[fr->callno]->prefs; 10501 10502 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 10503 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 10504 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 10505 } 10506 if (!format) { 10507 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) 10508 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 10509 if (!format) { 10510 memset(&ied0, 0, sizeof(ied0)); 10511 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10512 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10513 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10514 if (!iaxs[fr->callno]) { 10515 break; 10516 } 10517 if (authdebug) { 10518 char tmp[256], tmp2[256], tmp3[256]; 10519 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10520 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", 10521 ast_inet_ntoa(sin.sin_addr), 10522 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10523 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10524 } else { 10525 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10526 ast_inet_ntoa(sin.sin_addr), 10527 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10528 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10529 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10530 } 10531 } 10532 } else { 10533 /* Pick one... */ 10534 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10535 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 10536 format = 0; 10537 } else { 10538 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10539 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 10540 memset(&pref, 0, sizeof(pref)); 10541 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10542 strcpy(caller_pref_buf,"disabled"); 10543 strcpy(host_pref_buf,"disabled"); 10544 } else { 10545 using_prefs = "mine"; 10546 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10547 /* Do the opposite of what we tried above. */ 10548 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10549 pref = iaxs[fr->callno]->prefs; 10550 } else { 10551 pref = iaxs[fr->callno]->rprefs; 10552 using_prefs = "caller"; 10553 } 10554 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 10555 } else /* if no codec_prefs IE do it the old way */ 10556 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10557 } 10558 } 10559 10560 if (!format) { 10561 char tmp[256], tmp2[256], tmp3[256]; 10562 memset(&ied0, 0, sizeof(ied0)); 10563 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10564 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10565 ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 10566 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10567 if (!iaxs[fr->callno]) { 10568 break; 10569 } 10570 if (authdebug) { 10571 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10572 ast_inet_ntoa(sin.sin_addr), 10573 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10574 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10575 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10576 } 10577 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10578 break; 10579 } 10580 } 10581 } 10582 if (format) { 10583 /* No authentication required, let them in */ 10584 memset(&ied1, 0, sizeof(ied1)); 10585 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 10586 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 10587 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 10588 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 10589 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10590 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n" 10591 "%srequested format = %s,\n" 10592 "%srequested prefs = %s,\n" 10593 "%sactual format = %s,\n" 10594 "%shost prefs = %s,\n" 10595 "%spriority = %s\n", 10596 ast_inet_ntoa(sin.sin_addr), 10597 VERBOSE_PREFIX_4, 10598 ast_getformatname(iaxs[fr->callno]->peerformat), 10599 VERBOSE_PREFIX_4, 10600 caller_pref_buf, 10601 VERBOSE_PREFIX_4, 10602 ast_getformatname(format), 10603 VERBOSE_PREFIX_4, 10604 host_pref_buf, 10605 VERBOSE_PREFIX_4, 10606 using_prefs); 10607 10608 iaxs[fr->callno]->chosenformat = format; 10609 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10610 } else { 10611 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10612 /* If this is a TBD call, we're ready but now what... */ 10613 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 10614 } 10615 } 10616 } 10617 break; 10618 } 10619 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 10620 merge_encryption(iaxs[fr->callno],ies.encmethods); 10621 else 10622 iaxs[fr->callno]->encmethods = 0; 10623 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 10624 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 10625 break; 10626 case IAX_COMMAND_DPREQ: 10627 /* Request status in the dialplan */ 10628 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 10629 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 10630 if (iaxcompat) { 10631 /* Spawn a thread for the lookup */ 10632 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 10633 } else { 10634 /* Just look it up */ 10635 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 10636 } 10637 } 10638 break; 10639 case IAX_COMMAND_HANGUP: 10640 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10641 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno); 10642 /* Set hangup cause according to remote and hangupsource */ 10643 if (iaxs[fr->callno]->owner) { 10644 set_hangup_source_and_cause(fr->callno, ies.causecode); 10645 if (!iaxs[fr->callno]) { 10646 break; 10647 } 10648 } 10649 10650 /* Send ack immediately, before we destroy */ 10651 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10652 iax2_destroy(fr->callno); 10653 break; 10654 case IAX_COMMAND_REJECT: 10655 /* Set hangup cause according to remote and hangup source */ 10656 if (iaxs[fr->callno]->owner) { 10657 set_hangup_source_and_cause(fr->callno, ies.causecode); 10658 if (!iaxs[fr->callno]) { 10659 break; 10660 } 10661 } 10662 10663 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10664 if (iaxs[fr->callno]->owner && authdebug) 10665 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 10666 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 10667 ies.cause ? ies.cause : "<Unknown>"); 10668 ast_debug(1, "Immediately destroying %d, having received reject\n", 10669 fr->callno); 10670 } 10671 /* Send ack immediately, before we destroy */ 10672 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 10673 fr->ts, NULL, 0, fr->iseqno); 10674 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) 10675 iaxs[fr->callno]->error = EPERM; 10676 iax2_destroy(fr->callno); 10677 break; 10678 case IAX_COMMAND_TRANSFER: 10679 { 10680 struct ast_channel *bridged_chan; 10681 struct ast_channel *owner; 10682 10683 iax2_lock_owner(fr->callno); 10684 if (!iaxs[fr->callno]) { 10685 /* Initiating call went away before we could transfer. */ 10686 break; 10687 } 10688 owner = iaxs[fr->callno]->owner; 10689 bridged_chan = owner ? ast_bridged_channel(owner) : NULL; 10690 if (bridged_chan && ies.called_number) { 10691 ast_mutex_unlock(&iaxsl[fr->callno]); 10692 10693 /* Set BLINDTRANSFER channel variables */ 10694 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name); 10695 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name); 10696 10697 if (ast_parking_ext_valid(ies.called_number, c, iaxs[fr->callno]->context)) { 10698 ast_debug(1, "Parking call '%s'\n", bridged_chan->name); 10699 if (iax_park(bridged_chan, owner, ies.called_number)) { 10700 ast_log(LOG_WARNING, "Failed to park call '%s'\n", 10701 bridged_chan->name); 10702 } 10703 ast_mutex_lock(&iaxsl[fr->callno]); 10704 } else { 10705 ast_mutex_lock(&iaxsl[fr->callno]); 10706 10707 if (iaxs[fr->callno]) { 10708 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, 10709 ies.called_number, 1)) { 10710 ast_log(LOG_WARNING, 10711 "Async goto of '%s' to '%s@%s' failed\n", 10712 bridged_chan->name, ies.called_number, 10713 iaxs[fr->callno]->context); 10714 } else { 10715 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", 10716 bridged_chan->name, ies.called_number, 10717 iaxs[fr->callno]->context); 10718 } 10719 } else { 10720 /* Initiating call went away before we could transfer. */ 10721 } 10722 } 10723 } else { 10724 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno); 10725 } 10726 if (owner) { 10727 ast_channel_unlock(owner); 10728 } 10729 10730 break; 10731 } 10732 case IAX_COMMAND_ACCEPT: 10733 /* Ignore if call is already up or needs authentication or is a TBD */ 10734 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 10735 break; 10736 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10737 /* Send ack immediately, before we destroy */ 10738 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10739 iax2_destroy(fr->callno); 10740 break; 10741 } 10742 if (ies.format) { 10743 iaxs[fr->callno]->peerformat = ies.format; 10744 } else { 10745 if (iaxs[fr->callno]->owner) 10746 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 10747 else 10748 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 10749 } 10750 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)); 10751 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 10752 memset(&ied0, 0, sizeof(ied0)); 10753 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10754 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10755 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10756 if (!iaxs[fr->callno]) { 10757 break; 10758 } 10759 if (authdebug) { 10760 char tmp1[256], tmp2[256]; 10761 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n", 10762 ast_inet_ntoa(sin.sin_addr), 10763 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 10764 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10765 } 10766 } else { 10767 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10768 iax2_lock_owner(fr->callno); 10769 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 10770 /* Switch us to use a compatible format */ 10771 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 10772 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 10773 10774 /* Setup read/write formats properly. */ 10775 if (iaxs[fr->callno]->owner->writeformat) 10776 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 10777 if (iaxs[fr->callno]->owner->readformat) 10778 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 10779 ast_channel_unlock(iaxs[fr->callno]->owner); 10780 } 10781 } 10782 if (iaxs[fr->callno]) { 10783 AST_LIST_LOCK(&dpcache); 10784 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list) 10785 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) 10786 iax2_dprequest(dp, fr->callno); 10787 AST_LIST_UNLOCK(&dpcache); 10788 } 10789 break; 10790 case IAX_COMMAND_POKE: 10791 /* Send back a pong packet with the original timestamp */ 10792 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 10793 break; 10794 case IAX_COMMAND_PING: 10795 { 10796 struct iax_ie_data pingied; 10797 construct_rr(iaxs[fr->callno], &pingied); 10798 /* Send back a pong packet with the original timestamp */ 10799 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 10800 } 10801 break; 10802 case IAX_COMMAND_PONG: 10803 /* Calculate ping time */ 10804 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 10805 /* save RR info */ 10806 save_rr(fr, &ies); 10807 10808 /* Good time to write jb stats for this call */ 10809 log_jitterstats(fr->callno); 10810 10811 if (iaxs[fr->callno]->peerpoke) { 10812 peer = iaxs[fr->callno]->peerpoke; 10813 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 10814 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 10815 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 10816 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); 10817 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name); /* Activate notification */ 10818 } 10819 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 10820 if (iaxs[fr->callno]->pingtime > peer->maxms) { 10821 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 10822 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); 10823 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 10824 } 10825 } 10826 peer->lastms = iaxs[fr->callno]->pingtime; 10827 if (peer->smoothing && (peer->lastms > -1)) 10828 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 10829 else if (peer->smoothing && peer->lastms < 0) 10830 peer->historicms = (0 + peer->historicms) / 2; 10831 else 10832 peer->historicms = iaxs[fr->callno]->pingtime; 10833 10834 /* Remove scheduled iax2_poke_noanswer */ 10835 if (peer->pokeexpire > -1) { 10836 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 10837 peer_unref(peer); 10838 peer->pokeexpire = -1; 10839 } 10840 } 10841 /* Schedule the next cycle */ 10842 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 10843 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 10844 else 10845 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 10846 if (peer->pokeexpire == -1) 10847 peer_unref(peer); 10848 /* and finally send the ack */ 10849 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10850 /* And wrap up the qualify call */ 10851 iax2_destroy(fr->callno); 10852 peer->callno = 0; 10853 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 10854 } 10855 break; 10856 case IAX_COMMAND_LAGRQ: 10857 case IAX_COMMAND_LAGRP: 10858 f.src = "LAGRQ"; 10859 f.mallocd = 0; 10860 f.offset = 0; 10861 f.samples = 0; 10862 iax_frame_wrap(fr, &f); 10863 if (f.subclass.integer == IAX_COMMAND_LAGRQ) { 10864 /* Received a LAGRQ - echo back a LAGRP */ 10865 fr->af.subclass.integer = IAX_COMMAND_LAGRP; 10866 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 10867 } else { 10868 /* Received LAGRP in response to our LAGRQ */ 10869 unsigned int ts; 10870 /* This is a reply we've been given, actually measure the difference */ 10871 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 10872 iaxs[fr->callno]->lag = ts - fr->ts; 10873 if (iaxdebug) 10874 ast_debug(1, "Peer %s lag measured as %dms\n", 10875 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 10876 } 10877 break; 10878 case IAX_COMMAND_AUTHREQ: 10879 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 10880 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>"); 10881 break; 10882 } 10883 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 10884 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 10885 .subclass.integer = AST_CONTROL_HANGUP, 10886 }; 10887 ast_log(LOG_WARNING, 10888 "I don't know how to authenticate %s to %s\n", 10889 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 10890 iax2_queue_frame(fr->callno, &hangup_fr); 10891 } 10892 break; 10893 case IAX_COMMAND_AUTHREP: 10894 /* For security, always ack immediately */ 10895 if (delayreject) 10896 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10897 /* Ignore once we've started */ 10898 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 10899 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>"); 10900 break; 10901 } 10902 if (authenticate_verify(iaxs[fr->callno], &ies)) { 10903 if (authdebug) 10904 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); 10905 memset(&ied0, 0, sizeof(ied0)); 10906 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10907 break; 10908 } 10909 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 10910 /* This might re-enter the IAX code and need the lock */ 10911 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 10912 } else 10913 exists = 0; 10914 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 10915 if (authdebug) 10916 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); 10917 memset(&ied0, 0, sizeof(ied0)); 10918 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10919 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10920 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10921 if (!iaxs[fr->callno]) { 10922 break; 10923 } 10924 } else { 10925 /* Select an appropriate format */ 10926 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10927 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10928 using_prefs = "reqonly"; 10929 } else { 10930 using_prefs = "disabled"; 10931 } 10932 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 10933 memset(&pref, 0, sizeof(pref)); 10934 strcpy(caller_pref_buf, "disabled"); 10935 strcpy(host_pref_buf, "disabled"); 10936 } else { 10937 using_prefs = "mine"; 10938 if (ies.codec_prefs) 10939 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 10940 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10941 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10942 pref = iaxs[fr->callno]->rprefs; 10943 using_prefs = "caller"; 10944 } else { 10945 pref = iaxs[fr->callno]->prefs; 10946 } 10947 } else /* if no codec_prefs IE do it the old way */ 10948 pref = iaxs[fr->callno]->prefs; 10949 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 10950 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 10951 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 10952 } 10953 if (!format) { 10954 char tmp1[256], tmp2[256], tmp3[256]; 10955 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10956 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n", 10957 ast_getformatname(iaxs[fr->callno]->peerformat), 10958 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability)); 10959 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 10960 } 10961 if (!format) { 10962 if (authdebug) { 10963 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10964 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr), 10965 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 10966 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10967 } else { 10968 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10969 ast_inet_ntoa(sin.sin_addr), 10970 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 10971 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10972 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10973 } 10974 } 10975 memset(&ied0, 0, sizeof(ied0)); 10976 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10977 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10978 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10979 if (!iaxs[fr->callno]) { 10980 break; 10981 } 10982 } else { 10983 /* Pick one... */ 10984 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10985 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 10986 format = 0; 10987 } else { 10988 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10989 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 10990 memset(&pref, 0, sizeof(pref)); 10991 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 10992 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10993 strcpy(caller_pref_buf,"disabled"); 10994 strcpy(host_pref_buf,"disabled"); 10995 } else { 10996 using_prefs = "mine"; 10997 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10998 /* Do the opposite of what we tried above. */ 10999 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 11000 pref = iaxs[fr->callno]->prefs; 11001 } else { 11002 pref = iaxs[fr->callno]->rprefs; 11003 using_prefs = "caller"; 11004 } 11005 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 11006 } else /* if no codec_prefs IE do it the old way */ 11007 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 11008 } 11009 } 11010 if (!format) { 11011 char tmp1[256], tmp2[256], tmp3[256]; 11012 ast_log(LOG_ERROR, "No best format in %s???\n", 11013 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 11014 if (authdebug) { 11015 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11016 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", 11017 ast_inet_ntoa(sin.sin_addr), 11018 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11019 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 11020 } else { 11021 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 11022 ast_inet_ntoa(sin.sin_addr), 11023 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11024 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 11025 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 11026 } 11027 } 11028 memset(&ied0, 0, sizeof(ied0)); 11029 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 11030 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 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 } 11036 } 11037 } 11038 if (format) { 11039 /* Authentication received */ 11040 memset(&ied1, 0, sizeof(ied1)); 11041 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 11042 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 11043 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 11044 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 11045 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11046 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n" 11047 "%srequested format = %s,\n" 11048 "%srequested prefs = %s,\n" 11049 "%sactual format = %s,\n" 11050 "%shost prefs = %s,\n" 11051 "%spriority = %s\n", 11052 ast_inet_ntoa(sin.sin_addr), 11053 VERBOSE_PREFIX_4, 11054 ast_getformatname(iaxs[fr->callno]->peerformat), 11055 VERBOSE_PREFIX_4, 11056 caller_pref_buf, 11057 VERBOSE_PREFIX_4, 11058 ast_getformatname(format), 11059 VERBOSE_PREFIX_4, 11060 host_pref_buf, 11061 VERBOSE_PREFIX_4, 11062 using_prefs); 11063 11064 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11065 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL))) 11066 iax2_destroy(fr->callno); 11067 else if (ies.vars) { 11068 struct ast_datastore *variablestore; 11069 struct ast_variable *var, *prev = NULL; 11070 AST_LIST_HEAD(, ast_var_t) *varlist; 11071 varlist = ast_calloc(1, sizeof(*varlist)); 11072 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 11073 if (variablestore && varlist) { 11074 variablestore->data = varlist; 11075 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11076 AST_LIST_HEAD_INIT(varlist); 11077 ast_debug(1, "I can haz IAX vars? w00t\n"); 11078 for (var = ies.vars; var; var = var->next) { 11079 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 11080 if (prev) 11081 ast_free(prev); 11082 prev = var; 11083 if (!newvar) { 11084 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 11085 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11086 } else { 11087 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 11088 } 11089 } 11090 if (prev) 11091 ast_free(prev); 11092 ies.vars = NULL; 11093 ast_channel_datastore_add(c, variablestore); 11094 } else { 11095 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11096 if (variablestore) 11097 ast_datastore_free(variablestore); 11098 if (varlist) 11099 ast_free(varlist); 11100 } 11101 } 11102 } else { 11103 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11104 /* If this is a TBD call, we're ready but now what... */ 11105 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 11106 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) { 11107 goto immediatedial; 11108 } 11109 } 11110 } 11111 } 11112 break; 11113 case IAX_COMMAND_DIAL: 11114 immediatedial: 11115 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 11116 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11117 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 11118 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 11119 if (authdebug) 11120 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); 11121 memset(&ied0, 0, sizeof(ied0)); 11122 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 11123 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 11124 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11125 if (!iaxs[fr->callno]) { 11126 break; 11127 } 11128 } else { 11129 char tmp[256]; 11130 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11131 ast_verb(3, "Accepting DIAL from %s, formats = %s\n", 11132 ast_inet_ntoa(sin.sin_addr), 11133 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat)); 11134 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11135 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 11136 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL))) 11137 iax2_destroy(fr->callno); 11138 else if (ies.vars) { 11139 struct ast_datastore *variablestore; 11140 struct ast_variable *var, *prev = NULL; 11141 AST_LIST_HEAD(, ast_var_t) *varlist; 11142 varlist = ast_calloc(1, sizeof(*varlist)); 11143 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 11144 ast_debug(1, "I can haz IAX vars? w00t\n"); 11145 if (variablestore && varlist) { 11146 variablestore->data = varlist; 11147 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11148 AST_LIST_HEAD_INIT(varlist); 11149 for (var = ies.vars; var; var = var->next) { 11150 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 11151 if (prev) 11152 ast_free(prev); 11153 prev = var; 11154 if (!newvar) { 11155 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 11156 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11157 } else { 11158 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 11159 } 11160 } 11161 if (prev) 11162 ast_free(prev); 11163 ies.vars = NULL; 11164 ast_channel_datastore_add(c, variablestore); 11165 } else { 11166 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11167 if (variablestore) 11168 ast_datastore_free(variablestore); 11169 if (varlist) 11170 ast_free(varlist); 11171 } 11172 } 11173 } 11174 } 11175 break; 11176 case IAX_COMMAND_INVAL: 11177 iaxs[fr->callno]->error = ENOTCONN; 11178 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno); 11179 iax2_destroy(fr->callno); 11180 ast_debug(1, "Destroying call %d\n", fr->callno); 11181 break; 11182 case IAX_COMMAND_VNAK: 11183 ast_debug(1, "Received VNAK: resending outstanding frames\n"); 11184 /* Force retransmission */ 11185 vnak_retransmit(fr->callno, fr->iseqno); 11186 break; 11187 case IAX_COMMAND_REGREQ: 11188 case IAX_COMMAND_REGREL: 11189 /* For security, always ack immediately */ 11190 if (delayreject) 11191 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11192 if (register_verify(fr->callno, &sin, &ies)) { 11193 if (!iaxs[fr->callno]) { 11194 break; 11195 } 11196 /* Send delayed failure */ 11197 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 11198 break; 11199 } 11200 if (!iaxs[fr->callno]) { 11201 break; 11202 } 11203 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 11204 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 11205 11206 if (f.subclass.integer == IAX_COMMAND_REGREL) { 11207 memset(&sin, 0, sizeof(sin)); 11208 sin.sin_family = AF_INET; 11209 } 11210 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) { 11211 ast_log(LOG_WARNING, "Registry error\n"); 11212 } 11213 if (!iaxs[fr->callno]) { 11214 break; 11215 } 11216 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 11217 ast_mutex_unlock(&iaxsl[fr->callno]); 11218 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 11219 ast_mutex_lock(&iaxsl[fr->callno]); 11220 } 11221 break; 11222 } 11223 registry_authrequest(fr->callno); 11224 break; 11225 case IAX_COMMAND_REGACK: 11226 if (iax2_ack_registry(&ies, &sin, fr->callno)) 11227 ast_log(LOG_WARNING, "Registration failure\n"); 11228 /* Send ack immediately, before we destroy */ 11229 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11230 iax2_destroy(fr->callno); 11231 break; 11232 case IAX_COMMAND_REGREJ: 11233 if (iaxs[fr->callno]->reg) { 11234 if (authdebug) { 11235 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)); 11236 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>"); 11237 } 11238 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 11239 } 11240 /* Send ack immediately, before we destroy */ 11241 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11242 iax2_destroy(fr->callno); 11243 break; 11244 case IAX_COMMAND_REGAUTH: 11245 /* Authentication request */ 11246 if (registry_rerequest(&ies, fr->callno, &sin)) { 11247 memset(&ied0, 0, sizeof(ied0)); 11248 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 11249 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 11250 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11251 } 11252 break; 11253 case IAX_COMMAND_TXREJ: 11254 iaxs[fr->callno]->transferring = 0; 11255 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 11256 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 11257 if (iaxs[fr->callno]->bridgecallno) { 11258 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 11259 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 11260 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 11261 } 11262 } 11263 break; 11264 case IAX_COMMAND_TXREADY: 11265 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 11266 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 11267 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 11268 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 11269 else 11270 iaxs[fr->callno]->transferring = TRANSFER_READY; 11271 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 11272 if (iaxs[fr->callno]->bridgecallno) { 11273 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 11274 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 11275 /* They're both ready, now release them. */ 11276 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 11277 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 11278 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 11279 11280 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 11281 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 11282 11283 memset(&ied0, 0, sizeof(ied0)); 11284 memset(&ied1, 0, sizeof(ied1)); 11285 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11286 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11287 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 11288 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 11289 } else { 11290 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 11291 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 11292 11293 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 11294 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 11295 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 11296 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 11297 11298 /* Stop doing lag & ping requests */ 11299 stop_stuff(fr->callno); 11300 stop_stuff(iaxs[fr->callno]->bridgecallno); 11301 11302 memset(&ied0, 0, sizeof(ied0)); 11303 memset(&ied1, 0, sizeof(ied1)); 11304 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11305 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11306 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 11307 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 11308 } 11309 11310 } 11311 } 11312 } 11313 break; 11314 case IAX_COMMAND_TXREQ: 11315 try_transfer(iaxs[fr->callno], &ies); 11316 break; 11317 case IAX_COMMAND_TXCNT: 11318 if (iaxs[fr->callno]->transferring) 11319 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 11320 break; 11321 case IAX_COMMAND_TXREL: 11322 /* Send ack immediately, rather than waiting until we've changed addresses */ 11323 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11324 complete_transfer(fr->callno, &ies); 11325 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 11326 break; 11327 case IAX_COMMAND_TXMEDIA: 11328 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 11329 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 11330 /* Cancel any outstanding frames and start anew */ 11331 if (cur->transfer) { 11332 cur->retries = -1; 11333 } 11334 } 11335 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 11336 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 11337 } 11338 break; 11339 case IAX_COMMAND_RTKEY: 11340 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) { 11341 ast_log(LOG_WARNING, 11342 "we've been told to rotate our encryption key, " 11343 "but this isn't an encrypted call. bad things will happen.\n" 11344 ); 11345 break; 11346 } 11347 11348 IAX_DEBUGDIGEST("Receiving", ies.challenge); 11349 11350 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx); 11351 break; 11352 case IAX_COMMAND_DPREP: 11353 complete_dpreply(iaxs[fr->callno], &ies); 11354 break; 11355 case IAX_COMMAND_UNSUPPORT: 11356 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 11357 break; 11358 case IAX_COMMAND_FWDOWNL: 11359 /* Firmware download */ 11360 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 11361 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 11362 break; 11363 } 11364 memset(&ied0, 0, sizeof(ied0)); 11365 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 11366 if (res < 0) 11367 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11368 else if (res > 0) 11369 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11370 else 11371 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11372 break; 11373 case IAX_COMMAND_CALLTOKEN: 11374 { 11375 struct iax_frame *cur; 11376 /* find last sent frame */ 11377 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) { 11378 resend_with_token(fr->callno, cur, (char *) ies.calltokendata); 11379 } 11380 break; 11381 } 11382 default: 11383 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno); 11384 memset(&ied0, 0, sizeof(ied0)); 11385 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer); 11386 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 11387 } 11388 /* Free remote variables (if any) */ 11389 if (ies.vars) { 11390 ast_variables_destroy(ies.vars); 11391 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n"); 11392 ies.vars = NULL; 11393 } 11394 11395 /* Don't actually pass these frames along */ 11396 if ((f.subclass.integer != IAX_COMMAND_ACK) && 11397 (f.subclass.integer != IAX_COMMAND_TXCNT) && 11398 (f.subclass.integer != IAX_COMMAND_TXACC) && 11399 (f.subclass.integer != IAX_COMMAND_INVAL) && 11400 (f.subclass.integer != IAX_COMMAND_VNAK)) { 11401 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 11402 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11403 } 11404 ast_mutex_unlock(&iaxsl[fr->callno]); 11405 return 1; 11406 } 11407 /* Unless this is an ACK or INVAL frame, ack it */ 11408 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 11409 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11410 } else if (minivid) { 11411 f.frametype = AST_FRAME_VIDEO; 11412 if (iaxs[fr->callno]->videoformat > 0) 11413 f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0); 11414 else { 11415 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 11416 iax2_vnak(fr->callno); 11417 ast_variables_destroy(ies.vars); 11418 ast_mutex_unlock(&iaxsl[fr->callno]); 11419 return 1; 11420 } 11421 f.datalen = res - sizeof(*vh); 11422 if (f.datalen) 11423 f.data.ptr = thread->buf + sizeof(*vh); 11424 else 11425 f.data.ptr = NULL; 11426 #ifdef IAXTESTS 11427 if (test_resync) { 11428 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 11429 } else 11430 #endif /* IAXTESTS */ 11431 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 11432 } else { 11433 /* A mini frame */ 11434 f.frametype = AST_FRAME_VOICE; 11435 if (iaxs[fr->callno]->voiceformat > 0) 11436 f.subclass.codec = iaxs[fr->callno]->voiceformat; 11437 else { 11438 ast_debug(1, "Received mini frame before first full voice frame\n"); 11439 iax2_vnak(fr->callno); 11440 ast_variables_destroy(ies.vars); 11441 ast_mutex_unlock(&iaxsl[fr->callno]); 11442 return 1; 11443 } 11444 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 11445 if (f.datalen < 0) { 11446 ast_log(LOG_WARNING, "Datalen < 0?\n"); 11447 ast_variables_destroy(ies.vars); 11448 ast_mutex_unlock(&iaxsl[fr->callno]); 11449 return 1; 11450 } 11451 if (f.datalen) 11452 f.data.ptr = thread->buf + sizeof(*mh); 11453 else 11454 f.data.ptr = NULL; 11455 #ifdef IAXTESTS 11456 if (test_resync) { 11457 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 11458 } else 11459 #endif /* IAXTESTS */ 11460 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 11461 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 11462 } 11463 /* Don't pass any packets until we're started */ 11464 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 11465 ast_variables_destroy(ies.vars); 11466 ast_mutex_unlock(&iaxsl[fr->callno]); 11467 return 1; 11468 } 11469 /* Don't allow connected line updates unless we are configured to */ 11470 if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) { 11471 struct ast_party_connected_line connected; 11472 11473 if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) { 11474 ast_variables_destroy(ies.vars); 11475 ast_mutex_unlock(&iaxsl[fr->callno]); 11476 return 1; 11477 } 11478 11479 /* Initialize defaults */ 11480 ast_party_connected_line_init(&connected); 11481 connected.id.number.presentation = iaxs[fr->callno]->calling_pres; 11482 connected.id.name.presentation = iaxs[fr->callno]->calling_pres; 11483 11484 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) { 11485 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str); 11486 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str); 11487 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id); 11488 11489 if (iaxs[fr->callno]->owner) { 11490 ast_set_callerid(iaxs[fr->callno]->owner, 11491 S_COR(connected.id.number.valid, connected.id.number.str, ""), 11492 S_COR(connected.id.name.valid, connected.id.name.str, ""), 11493 NULL); 11494 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation; 11495 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation; 11496 } 11497 } 11498 ast_party_connected_line_free(&connected); 11499 } 11500 /* Common things */ 11501 f.src = "IAX2"; 11502 f.mallocd = 0; 11503 f.offset = 0; 11504 f.len = 0; 11505 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 11506 f.samples = ast_codec_get_samples(&f); 11507 /* We need to byteswap incoming slinear samples from network byte order */ 11508 if (f.subclass.codec == AST_FORMAT_SLINEAR) 11509 ast_frame_byteswap_be(&f); 11510 } else 11511 f.samples = 0; 11512 iax_frame_wrap(fr, &f); 11513 11514 /* If this is our most recent packet, use it as our basis for timestamping */ 11515 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11516 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 11517 fr->outoforder = 0; 11518 } else { 11519 if (iaxdebug && iaxs[fr->callno]) 11520 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); 11521 fr->outoforder = -1; 11522 } 11523 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 11524 duped_fr = iaxfrdup2(fr); 11525 if (duped_fr) { 11526 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 11527 } 11528 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11529 iaxs[fr->callno]->last = fr->ts; 11530 #if 1 11531 if (iaxdebug) 11532 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 11533 #endif 11534 } 11535 11536 /* Always run again */ 11537 ast_variables_destroy(ies.vars); 11538 ast_mutex_unlock(&iaxsl[fr->callno]); 11539 return 1; 11540 }
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 9592 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().
09594 { 09595 unsigned char metatype; 09596 struct ast_iax2_meta_trunk_mini *mtm; 09597 struct ast_iax2_meta_trunk_hdr *mth; 09598 struct ast_iax2_meta_trunk_entry *mte; 09599 struct iax2_trunk_peer *tpeer; 09600 unsigned int ts; 09601 void *ptr; 09602 struct timeval rxtrunktime; 09603 struct ast_frame f = { 0, }; 09604 09605 if (packet_len < sizeof(*meta)) { 09606 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 09607 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09608 return 1; 09609 } 09610 09611 if (meta->metacmd != IAX_META_TRUNK) 09612 return 1; 09613 09614 if (packet_len < (sizeof(*meta) + sizeof(*mth))) { 09615 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len, 09616 (int) (sizeof(*meta) + sizeof(*mth))); 09617 return 1; 09618 } 09619 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 09620 ts = ntohl(mth->ts); 09621 metatype = meta->cmddata; 09622 packet_len -= (sizeof(*meta) + sizeof(*mth)); 09623 ptr = mth->data; 09624 tpeer = find_tpeer(sin, sockfd); 09625 if (!tpeer) { 09626 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 09627 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09628 return 1; 09629 } 09630 tpeer->trunkact = ast_tvnow(); 09631 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 09632 tpeer->rxtrunktime = tpeer->trunkact; 09633 rxtrunktime = tpeer->rxtrunktime; 09634 ast_mutex_unlock(&tpeer->lock); 09635 while (packet_len >= sizeof(*mte)) { 09636 /* Process channels */ 09637 unsigned short callno, trunked_ts, len; 09638 09639 if (metatype == IAX_META_TRUNK_MINI) { 09640 mtm = (struct ast_iax2_meta_trunk_mini *) ptr; 09641 ptr += sizeof(*mtm); 09642 packet_len -= sizeof(*mtm); 09643 len = ntohs(mtm->len); 09644 callno = ntohs(mtm->mini.callno); 09645 trunked_ts = ntohs(mtm->mini.ts); 09646 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 09647 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 09648 ptr += sizeof(*mte); 09649 packet_len -= sizeof(*mte); 09650 len = ntohs(mte->len); 09651 callno = ntohs(mte->callno); 09652 trunked_ts = 0; 09653 } else { 09654 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09655 break; 09656 } 09657 /* Stop if we don't have enough data */ 09658 if (len > packet_len) 09659 break; 09660 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0); 09661 if (!fr->callno) 09662 continue; 09663 09664 /* If it's a valid call, deliver the contents. If not, we 09665 drop it, since we don't have a scallno to use for an INVAL */ 09666 /* Process as a mini frame */ 09667 memset(&f, 0, sizeof(f)); 09668 f.frametype = AST_FRAME_VOICE; 09669 if (!iaxs[fr->callno]) { 09670 /* drop it */ 09671 } else if (iaxs[fr->callno]->voiceformat == 0) { 09672 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 09673 iax2_vnak(fr->callno); 09674 } else { 09675 f.subclass.codec = iaxs[fr->callno]->voiceformat; 09676 f.datalen = len; 09677 if (f.datalen >= 0) { 09678 if (f.datalen) 09679 f.data.ptr = ptr; 09680 else 09681 f.data.ptr = NULL; 09682 if (trunked_ts) 09683 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 09684 else 09685 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 09686 /* Don't pass any packets until we're started */ 09687 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09688 struct iax_frame *duped_fr; 09689 09690 /* Common things */ 09691 f.src = "IAX2"; 09692 f.mallocd = 0; 09693 f.offset = 0; 09694 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 09695 f.samples = ast_codec_get_samples(&f); 09696 else 09697 f.samples = 0; 09698 fr->outoforder = 0; 09699 iax_frame_wrap(fr, &f); 09700 duped_fr = iaxfrdup2(fr); 09701 if (duped_fr) 09702 schedule_delivery(duped_fr, 1, 1, &fr->ts); 09703 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) 09704 iaxs[fr->callno]->last = fr->ts; 09705 } 09706 } else { 09707 ast_log(LOG_WARNING, "Datalen < 0?\n"); 09708 } 09709 } 09710 ast_mutex_unlock(&iaxsl[fr->callno]); 09711 ptr += len; 09712 packet_len -= len; 09713 } 09714 09715 return 1; 09716 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 9513 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().
09514 { 09515 struct iax2_thread *thread; 09516 socklen_t len; 09517 time_t t; 09518 static time_t last_errtime = 0; 09519 struct ast_iax2_full_hdr *fh; 09520 09521 if (!(thread = find_idle_thread())) { 09522 time(&t); 09523 if (t != last_errtime) 09524 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n"); 09525 last_errtime = t; 09526 usleep(1); 09527 return 1; 09528 } 09529 09530 len = sizeof(thread->iosin); 09531 thread->iofd = fd; 09532 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 09533 thread->buf_size = sizeof(thread->readbuf); 09534 thread->buf = thread->readbuf; 09535 if (thread->buf_len < 0) { 09536 if (errno != ECONNREFUSED && errno != EAGAIN) 09537 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 09538 handle_error(); 09539 thread->iostate = IAX_IOSTATE_IDLE; 09540 signal_condition(&thread->lock, &thread->cond); 09541 return 1; 09542 } 09543 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 09544 thread->iostate = IAX_IOSTATE_IDLE; 09545 signal_condition(&thread->lock, &thread->cond); 09546 return 1; 09547 } 09548 09549 /* Determine if this frame is a full frame; if so, and any thread is currently 09550 processing a full frame for the same callno from this peer, then drop this 09551 frame (and the peer will retransmit it) */ 09552 fh = (struct ast_iax2_full_hdr *) thread->buf; 09553 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 09554 struct iax2_thread *cur = NULL; 09555 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 09556 09557 AST_LIST_LOCK(&active_list); 09558 AST_LIST_TRAVERSE(&active_list, cur, list) { 09559 if ((cur->ffinfo.callno == callno) && 09560 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 09561 break; 09562 } 09563 if (cur) { 09564 /* we found another thread processing a full frame for this call, 09565 so queue it up for processing later. */ 09566 defer_full_frame(thread, cur); 09567 AST_LIST_UNLOCK(&active_list); 09568 thread->iostate = IAX_IOSTATE_IDLE; 09569 signal_condition(&thread->lock, &thread->cond); 09570 return 1; 09571 } else { 09572 /* this thread is going to process this frame, so mark it */ 09573 thread->ffinfo.callno = callno; 09574 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 09575 thread->ffinfo.type = fh->type; 09576 thread->ffinfo.csub = fh->csub; 09577 AST_LIST_INSERT_HEAD(&active_list, thread, list); 09578 } 09579 AST_LIST_UNLOCK(&active_list); 09580 } 09581 09582 /* Mark as ready and send on its way */ 09583 thread->iostate = IAX_IOSTATE_READY; 09584 #ifdef DEBUG_SCHED_MULTITHREAD 09585 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 09586 #endif 09587 signal_condition(&thread->lock, &thread->cond); 09588 09589 return 1; 09590 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 9230 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().
09231 { 09232 pthread_t newthread; 09233 struct dpreq_data *dpr; 09234 09235 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 09236 return; 09237 09238 dpr->callno = callno; 09239 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 09240 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 09241 if (callerid) 09242 dpr->callerid = ast_strdup(callerid); 09243 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) { 09244 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 09245 } 09246 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 12094 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().
12095 { 12096 struct iax2_thread *thread; 12097 int threadcount = 0; 12098 int x; 12099 for (x = 0; x < iaxthreadcount; x++) { 12100 thread = ast_calloc(1, sizeof(*thread)); 12101 if (thread) { 12102 thread->type = IAX_THREAD_TYPE_POOL; 12103 thread->threadnum = ++threadcount; 12104 ast_mutex_init(&thread->lock); 12105 ast_cond_init(&thread->cond, NULL); 12106 ast_mutex_init(&thread->init_lock); 12107 ast_cond_init(&thread->init_cond, NULL); 12108 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 12109 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 12110 ast_mutex_destroy(&thread->lock); 12111 ast_cond_destroy(&thread->cond); 12112 ast_mutex_destroy(&thread->init_lock); 12113 ast_cond_destroy(&thread->init_cond); 12114 ast_free(thread); 12115 thread = NULL; 12116 continue; 12117 } 12118 AST_LIST_LOCK(&idle_list); 12119 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 12120 AST_LIST_UNLOCK(&idle_list); 12121 } 12122 } 12123 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 12124 ast_verb(2, "%d helper threads started\n", threadcount); 12125 return 0; 12126 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 8936 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
08937 { 08938 iax2_destroy_helper(iaxs[callno]); 08939 }
static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2113 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().
02114 { 02115 if (!pvt->peercallno) { 02116 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 02117 return; 02118 } 02119 02120 ao2_link(iax_peercallno_pvts, pvt); 02121 }
static void store_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2094 of file chan_iax2.c.
References ao2_link, ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by try_transfer().
02095 { 02096 if (!pvt->transfercallno) { 02097 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 02098 return; 02099 } 02100 02101 ao2_link(iax_transfercallno_pvts, pvt); 02102 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 9119 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().
09120 { 09121 int res, processed = 0, totalcalls = 0; 09122 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL; 09123 struct timeval now = ast_tvnow(); 09124 09125 if (iaxtrunkdebug) 09126 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize); 09127 09128 if (timer) { 09129 ast_timer_ack(timer, 1); 09130 } 09131 09132 /* For each peer that supports trunking... */ 09133 AST_LIST_LOCK(&tpeers); 09134 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) { 09135 processed++; 09136 res = 0; 09137 ast_mutex_lock(&tpeer->lock); 09138 /* We can drop a single tpeer per pass. That makes all this logic 09139 substantially easier */ 09140 if (!drop && iax2_trunk_expired(tpeer, &now)) { 09141 /* Take it out of the list, but don't free it yet, because it 09142 could be in use */ 09143 AST_LIST_REMOVE_CURRENT(list); 09144 drop = tpeer; 09145 } else { 09146 res = send_trunk(tpeer, &now); 09147 trunk_timed++; 09148 if (iaxtrunkdebug) 09149 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); 09150 } 09151 totalcalls += res; 09152 res = 0; 09153 ast_mutex_unlock(&tpeer->lock); 09154 } 09155 AST_LIST_TRAVERSE_SAFE_END; 09156 AST_LIST_UNLOCK(&tpeers); 09157 09158 if (drop) { 09159 ast_mutex_lock(&drop->lock); 09160 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 09161 because by the time they could get tpeerlock, we've already grabbed it */ 09162 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 09163 if (drop->trunkdata) { 09164 ast_free(drop->trunkdata); 09165 drop->trunkdata = NULL; 09166 } 09167 ast_mutex_unlock(&drop->lock); 09168 ast_mutex_destroy(&drop->lock); 09169 ast_free(drop); 09170 09171 } 09172 09173 if (iaxtrunkdebug) 09174 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 09175 iaxtrunkdebug = 0; 09176 09177 return 1; 09178 }
static int transfercallno_pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 14333 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().
Referenced by load_objects().
14334 { 14335 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14336 14337 /* The frames_received field is used to hold whether we're matching 14338 * against a full frame or not ... */ 14339 14340 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 14341 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14342 }
static int transfercallno_pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 14326 of file chan_iax2.c.
References chan_iax2_pvt::transfercallno.
Referenced by load_objects().
14327 { 14328 const struct chan_iax2_pvt *pvt = obj; 14329 14330 return pvt->transfercallno; 14331 }
static int transmit_frame | ( | void * | data | ) | [static] |
Definition at line 4228 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().
04229 { 04230 struct iax_frame *fr = data; 04231 04232 ast_mutex_lock(&iaxsl[fr->callno]); 04233 04234 fr->sentyet = 1; 04235 04236 if (iaxs[fr->callno]) { 04237 send_packet(fr); 04238 } 04239 04240 if (fr->retries < 0) { 04241 ast_mutex_unlock(&iaxsl[fr->callno]); 04242 /* No retransmit requested */ 04243 iax_frame_free(fr); 04244 } else { 04245 /* We need reliable delivery. Schedule a retransmission */ 04246 AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list); 04247 fr->retries++; 04248 fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr); 04249 ast_mutex_unlock(&iaxsl[fr->callno]); 04250 } 04251 04252 return 0; 04253 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 3300 of file chan_iax2.c.
References ast_debug, errno, f, and handle_error().
Referenced by send_trunk().
03301 { 03302 int res; 03303 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 03304 sizeof(*sin)); 03305 if (res < 0) { 03306 ast_debug(1, "Received error: %s\n", strerror(errno)); 03307 handle_error(); 03308 } else 03309 res = 0; 03310 return res; 03311 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 3002 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().
03003 { 03004 struct stat stbuf; 03005 struct iax_firmware *cur = NULL; 03006 int ifd, fd, res, len, chunk; 03007 struct ast_iax2_firmware_header *fwh, fwh2; 03008 struct MD5Context md5; 03009 unsigned char sum[16], buf[1024]; 03010 char *s2, *last; 03011 03012 if (!(s2 = alloca(strlen(s) + 100))) { 03013 ast_log(LOG_WARNING, "Alloca failed!\n"); 03014 return -1; 03015 } 03016 03017 last = strrchr(s, '/'); 03018 if (last) 03019 last++; 03020 else 03021 last = s; 03022 03023 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 03024 03025 if ((res = stat(s, &stbuf) < 0)) { 03026 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 03027 return -1; 03028 } 03029 03030 /* Make sure it's not a directory */ 03031 if (S_ISDIR(stbuf.st_mode)) 03032 return -1; 03033 ifd = open(s, O_RDONLY); 03034 if (ifd < 0) { 03035 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 03036 return -1; 03037 } 03038 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE); 03039 if (fd < 0) { 03040 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 03041 close(ifd); 03042 return -1; 03043 } 03044 /* Unlink our newly created file */ 03045 unlink(s2); 03046 03047 /* Now copy the firmware into it */ 03048 len = stbuf.st_size; 03049 while(len) { 03050 chunk = len; 03051 if (chunk > sizeof(buf)) 03052 chunk = sizeof(buf); 03053 res = read(ifd, buf, chunk); 03054 if (res != chunk) { 03055 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 03056 close(ifd); 03057 close(fd); 03058 return -1; 03059 } 03060 res = write(fd, buf, chunk); 03061 if (res != chunk) { 03062 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 03063 close(ifd); 03064 close(fd); 03065 return -1; 03066 } 03067 len -= chunk; 03068 } 03069 close(ifd); 03070 /* Return to the beginning */ 03071 lseek(fd, 0, SEEK_SET); 03072 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 03073 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 03074 close(fd); 03075 return -1; 03076 } 03077 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 03078 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 03079 close(fd); 03080 return -1; 03081 } 03082 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 03083 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 03084 close(fd); 03085 return -1; 03086 } 03087 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 03088 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 03089 close(fd); 03090 return -1; 03091 } 03092 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 03093 if (fwh == MAP_FAILED) { 03094 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 03095 close(fd); 03096 return -1; 03097 } 03098 MD5Init(&md5); 03099 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 03100 MD5Final(sum, &md5); 03101 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 03102 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 03103 munmap((void*)fwh, stbuf.st_size); 03104 close(fd); 03105 return -1; 03106 } 03107 03108 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03109 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 03110 /* Found a candidate */ 03111 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 03112 /* The version we have on loaded is older, load this one instead */ 03113 break; 03114 /* This version is no newer than what we have. Don't worry about it. 03115 We'll consider it a proper load anyhow though */ 03116 munmap((void*)fwh, stbuf.st_size); 03117 close(fd); 03118 return 0; 03119 } 03120 } 03121 03122 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) { 03123 cur->fd = -1; 03124 AST_LIST_INSERT_TAIL(&firmwares, cur, list); 03125 } 03126 03127 if (cur) { 03128 if (cur->fwh) 03129 munmap((void*)cur->fwh, cur->mmaplen); 03130 if (cur->fd > -1) 03131 close(cur->fd); 03132 cur->fwh = fwh; 03133 cur->fd = fd; 03134 cur->mmaplen = stbuf.st_size; 03135 cur->dead = 0; 03136 } 03137 03138 return 0; 03139 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 8264 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().
08265 { 08266 int newcall = 0; 08267 char newip[256]; 08268 struct iax_ie_data ied; 08269 struct sockaddr_in new; 08270 08271 08272 memset(&ied, 0, sizeof(ied)); 08273 if (ies->apparent_addr) 08274 memmove(&new, ies->apparent_addr, sizeof(new)); 08275 if (ies->callno) 08276 newcall = ies->callno; 08277 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 08278 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08279 return -1; 08280 } 08281 pvt->transfercallno = newcall; 08282 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 08283 inet_aton(newip, &pvt->transfer.sin_addr); 08284 pvt->transfer.sin_family = AF_INET; 08285 pvt->transferid = ies->transferid; 08286 /* only store by transfercallno if this is a new transfer, 08287 * just in case we get a duplicate TXREQ */ 08288 if (pvt->transferring == TRANSFER_NONE) { 08289 store_by_transfercallno(pvt); 08290 } 08291 pvt->transferring = TRANSFER_BEGIN; 08292 08293 if (ies->transferid) 08294 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 08295 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 08296 return 0; 08297 }
static format_t uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1629 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), handle_call_token(), and socket_process().
01630 { 01631 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01632 if (csub & IAX_FLAG_SC_LOG) { 01633 /* special case for 'compressed' -1 */ 01634 if (csub == 0xff) 01635 return -1; 01636 else 01637 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01638 } 01639 else 01640 return csub; 01641 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 8553 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().
08554 { 08555 if (peer->expire > -1) { 08556 if (!ast_sched_thread_del(sched, peer->expire)) { 08557 peer->expire = -1; 08558 peer_unref(peer); 08559 } 08560 } 08561 08562 if (peer->pokeexpire > -1) { 08563 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 08564 peer->pokeexpire = -1; 08565 peer_unref(peer); 08566 } 08567 } 08568 08569 ao2_unlink(peers, peer); 08570 }
static int unload_module | ( | void | ) | [static] |
Definition at line 14291 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), iaxpeer_function, and iaxvar_function.
14292 { 14293 ast_custom_function_unregister(&iaxpeer_function); 14294 ast_custom_function_unregister(&iaxvar_function); 14295 return __unload_module(); 14296 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 5430 of file chan_iax2.c.
References ast_mutex_unlock, and iaxsl.
Referenced by iax2_bridge().
05431 { 05432 ast_mutex_unlock(&iaxsl[callno1]); 05433 ast_mutex_unlock(&iaxsl[callno0]); 05434 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 3990 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().
03991 { 03992 /* Video mini frames only encode the lower 15 bits of the session 03993 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 03994 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 03995 const int lower_mask = (1 << ts_shift) - 1; 03996 const int upper_mask = ~lower_mask; 03997 const int last_upper = iaxs[fr->callno]->last & upper_mask; 03998 03999 if ( (fr->ts & upper_mask) == last_upper ) { 04000 const int x = fr->ts - iaxs[fr->callno]->last; 04001 const int threshold = (ts_shift == 15) ? 25000 : 50000; 04002 04003 if (x < -threshold) { 04004 /* Sudden big jump backwards in timestamp: 04005 What likely happened here is that miniframe timestamp has circled but we haven't 04006 gotten the update from the main packet. We'll just pretend that we did, and 04007 update the timestamp appropriately. */ 04008 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 04009 if (iaxdebug) 04010 ast_debug(1, "schedule_delivery: pushed forward timestamp\n"); 04011 } else if (x > threshold) { 04012 /* Sudden apparent big jump forwards in timestamp: 04013 What's likely happened is this is an old miniframe belonging to the previous 04014 top 15 or 16-bit timestamp that has turned up out of order. 04015 Adjust the timestamp appropriately. */ 04016 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 04017 if (iaxdebug) 04018 ast_debug(1, "schedule_delivery: pushed back timestamp\n"); 04019 } 04020 } 04021 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 4025 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().
04026 { 04027 int when; 04028 04029 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 04030 04031 when = jb_next(pvt->jb) - when; 04032 04033 if (when <= 0) { 04034 /* XXX should really just empty until when > 0.. */ 04035 when = 1; 04036 } 04037 04038 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 04039 CALLNO_TO_PTR(pvt->callno)); 04040 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 2021 of file chan_iax2.c.
References ast_debug, iaxs, and TRUNK_CALL_START.
Referenced by __find_callno(), and make_trunk().
02022 { 02023 int max = 1; 02024 int x; 02025 /* XXX Prolly don't need locks here XXX */ 02026 for (x=1;x<TRUNK_CALL_START - 1; x++) { 02027 if (iaxs[x]) 02028 max = x + 1; 02029 } 02030 maxnontrunkcall = max; 02031 if (iaxdebug) 02032 ast_debug(1, "New max nontrunk callno is %d\n", max); 02033 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 2004 of file chan_iax2.c.
References ARRAY_LEN, ast_debug, iaxs, and TRUNK_CALL_START.
Referenced by iax2_destroy(), and make_trunk().
02005 { 02006 int max = TRUNK_CALL_START; 02007 int x; 02008 02009 /* XXX Prolly don't need locks here XXX */ 02010 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 02011 if (iaxs[x]) { 02012 max = x + 1; 02013 } 02014 } 02015 02016 maxtrunkcall = max; 02017 if (iaxdebug) 02018 ast_debug(1, "New max trunk callno is %d\n", max); 02019 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3438 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().
03439 { 03440 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 03441 struct ast_iax2_full_hdr *fh = f->data; 03442 struct ast_frame af; 03443 03444 /* if frame is encrypted. decrypt before updating it. */ 03445 if (f->encmethods) { 03446 decode_frame(&f->mydcx, fh, &af, &f->datalen); 03447 } 03448 /* Mark this as a retransmission */ 03449 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 03450 /* Update iseqno */ 03451 f->iseqno = iaxs[f->callno]->iseqno; 03452 fh->iseqno = f->iseqno; 03453 03454 /* Now re-encrypt the frame */ 03455 if (f->encmethods) { 03456 /* since this is a retransmit frame, create a new random padding 03457 * before re-encrypting. */ 03458 build_rand_pad(f->semirand, sizeof(f->semirand)); 03459 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen); 03460 } 03461 return 0; 03462 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 8668 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().
08669 { 08670 /* Called from IAX thread only, with proper iaxsl lock */ 08671 struct iax_ie_data ied = { 08672 .pos = 0, 08673 }; 08674 struct iax2_peer *p; 08675 int msgcount; 08676 char data[80]; 08677 int version; 08678 const char *peer_name; 08679 int res = -1; 08680 struct ast_sockaddr sockaddr; 08681 08682 ast_sockaddr_from_sin(&sockaddr, sin); 08683 08684 peer_name = ast_strdupa(iaxs[callno]->peer); 08685 08686 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 08687 ast_mutex_unlock(&iaxsl[callno]); 08688 if (!(p = find_peer(peer_name, 1))) { 08689 ast_mutex_lock(&iaxsl[callno]); 08690 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 08691 return -1; 08692 } 08693 ast_mutex_lock(&iaxsl[callno]); 08694 if (!iaxs[callno]) 08695 goto return_unref; 08696 08697 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 08698 if (sin->sin_addr.s_addr) { 08699 time_t nowtime; 08700 time(&nowtime); 08701 realtime_update_peer(peer_name, &sockaddr, nowtime); 08702 } else { 08703 realtime_update_peer(peer_name, &sockaddr, 0); 08704 } 08705 } 08706 08707 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) { 08708 if (iax2_regfunk) { 08709 iax2_regfunk(p->name, 1); 08710 } 08711 08712 /* modify entry in peercnts table as _not_ registered */ 08713 peercnt_modify(0, 0, &p->addr); 08714 08715 /* Stash the IP address from which they registered */ 08716 ast_sockaddr_from_sin(&p->addr, sin); 08717 08718 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 08719 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 08720 ast_db_put("IAX/Registry", p->name, data); 08721 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 08722 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 08723 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 08724 register_peer_exten(p, 1); 08725 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08726 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) { 08727 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name, 08728 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 08729 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 08730 register_peer_exten(p, 0); 08731 ast_db_del("IAX/Registry", p->name); 08732 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */ 08733 } 08734 /* Update the host */ 08735 /* Verify that the host is really there */ 08736 iax2_poke_peer(p, callno); 08737 } 08738 08739 /* modify entry in peercnts table as registered */ 08740 if (p->maxcallno) { 08741 peercnt_modify(1, p->maxcallno, &p->addr); 08742 } 08743 08744 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 08745 if (!iaxs[callno]) { 08746 res = -1; 08747 goto return_unref; 08748 } 08749 08750 /* Store socket fd */ 08751 p->sockfd = fd; 08752 /* Setup the expiry */ 08753 if (p->expire > -1) { 08754 if (!ast_sched_thread_del(sched, p->expire)) { 08755 p->expire = -1; 08756 peer_unref(p); 08757 } 08758 } 08759 /* treat an unspecified refresh interval as the minimum */ 08760 if (!refresh) 08761 refresh = min_reg_expire; 08762 if (refresh > max_reg_expire) { 08763 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08764 p->name, max_reg_expire, refresh); 08765 p->expiry = max_reg_expire; 08766 } else if (refresh < min_reg_expire) { 08767 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08768 p->name, min_reg_expire, refresh); 08769 p->expiry = min_reg_expire; 08770 } else { 08771 p->expiry = refresh; 08772 } 08773 if (p->expiry && sin->sin_addr.s_addr) { 08774 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08775 if (p->expire == -1) 08776 peer_unref(p); 08777 } 08778 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 08779 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 08780 if (sin->sin_addr.s_addr) { 08781 struct sockaddr_in peer_addr; 08782 08783 ast_sockaddr_to_sin(&p->addr, &peer_addr); 08784 08785 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 08786 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr); 08787 if (!ast_strlen_zero(p->mailbox)) { 08788 struct ast_event *event; 08789 int new, old; 08790 char *mailbox, *context; 08791 08792 context = mailbox = ast_strdupa(p->mailbox); 08793 strsep(&context, "@"); 08794 if (ast_strlen_zero(context)) 08795 context = "default"; 08796 08797 event = ast_event_get_cached(AST_EVENT_MWI, 08798 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 08799 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 08800 AST_EVENT_IE_END); 08801 if (event) { 08802 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 08803 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 08804 ast_event_destroy(event); 08805 } else { /* Fall back on checking the mailbox directly */ 08806 ast_app_inboxcount(p->mailbox, &new, &old); 08807 } 08808 08809 if (new > 255) { 08810 new = 255; 08811 } 08812 if (old > 255) { 08813 old = 255; 08814 } 08815 msgcount = (old << 8) | new; 08816 08817 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 08818 } 08819 if (ast_test_flag64(p, IAX_HASCALLERID)) { 08820 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 08821 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 08822 } 08823 } 08824 version = iax_check_version(devtype); 08825 if (version) 08826 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 08827 08828 res = 0; 08829 08830 return_unref: 08831 peer_unref(p); 08832 08833 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 08834 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1676 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and user.
Referenced by load_objects().
01677 { 01678 struct iax2_user *user = obj, *user2 = arg; 01679 01680 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0; 01681 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12830 of file chan_iax2.c.
References ast_set_flag64, IAX_DELME, and user.
Referenced by delete_users().
12831 { 12832 struct iax2_user *user = obj; 12833 12834 ast_set_flag64(user, IAX_DELME); 12835 12836 return 0; 12837 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 12555 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().
12556 { 12557 struct iax2_user *user = obj; 12558 12559 ast_free_ha(user->ha); 12560 free_context(user->contexts); 12561 if(user->vars) { 12562 ast_variables_destroy(user->vars); 12563 user->vars = NULL; 12564 } 12565 ast_string_field_free_memory(user); 12566 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1666 of file chan_iax2.c.
References ast_str_hash(), and user.
Referenced by load_objects().
01667 { 01668 const struct iax2_user *user = obj; 01669 01670 return ast_str_hash(user->name); 01671 }
Definition at line 1729 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 14496 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.
14498 { 14499 struct ast_data *data_user, *data_authmethods, *data_enum_node; 14500 struct iax2_user *user; 14501 struct ao2_iterator i; 14502 char auth[90]; 14503 char *pstr = ""; 14504 14505 i = ao2_iterator_init(users, 0); 14506 while ((user = ao2_iterator_next(&i))) { 14507 data_user = ast_data_add_node(data_root, "user"); 14508 if (!data_user) { 14509 user_unref(user); 14510 continue; 14511 } 14512 14513 ast_data_add_structure(iax2_user, data_user, user); 14514 14515 ast_data_add_codecs(data_user, "codecs", user->capability); 14516 14517 if (!ast_strlen_zero(user->secret)) { 14518 ast_copy_string(auth, user->secret, sizeof(auth)); 14519 } else if (!ast_strlen_zero(user->inkeys)) { 14520 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys); 14521 } else { 14522 ast_copy_string(auth, "no secret", sizeof(auth)); 14523 } 14524 ast_data_add_password(data_user, "secret", auth); 14525 14526 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT); 14527 14528 /* authmethods */ 14529 data_authmethods = ast_data_add_node(data_user, "authmethods"); 14530 if (!data_authmethods) { 14531 ast_data_remove_node(data_root, data_user); 14532 continue; 14533 } 14534 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA); 14535 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5); 14536 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT); 14537 14538 /* amaflags */ 14539 data_enum_node = ast_data_add_node(data_user, "amaflags"); 14540 if (!data_enum_node) { 14541 ast_data_remove_node(data_root, data_user); 14542 continue; 14543 } 14544 ast_data_add_int(data_enum_node, "value", user->amaflags); 14545 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags)); 14546 14547 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0); 14548 14549 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) { 14550 pstr = "REQ only"; 14551 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) { 14552 pstr = "disabled"; 14553 } else { 14554 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host"; 14555 } 14556 ast_data_add_str(data_user, "codec-preferences", pstr); 14557 14558 user_unref(user); 14559 14560 if (!ast_data_search_match(search, data_user)) { 14561 ast_data_remove_node(data_root, data_user); 14562 } 14563 } 14564 ao2_iterator_destroy(&i); 14565 14566 return 0; 14567 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 9037 of file chan_iax2.c.
References AST_LIST_TRAVERSE, f, frame_queue, iax_frame::list, and send_packet().
Referenced by socket_process().
09038 { 09039 struct iax_frame *f; 09040 09041 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) { 09042 /* Send a copy immediately */ 09043 if (((unsigned char) (f->oseqno - last) < 128) && 09044 (f->retries >= 0)) { 09045 send_packet(f); 09046 } 09047 } 09048 }
static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 5240 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().
05241 { 05242 unsigned short callno = pvt->callno; 05243 05244 if (!pvt->peercallno) { 05245 /* We don't know the remote side's call number, yet. :( */ 05246 int count = 10; 05247 while (count-- && pvt && !pvt->peercallno) { 05248 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 05249 pvt = iaxs[callno]; 05250 } 05251 if (!pvt->peercallno) { 05252 return -1; 05253 } 05254 } 05255 05256 return 0; 05257 }
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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto", } [static] |
Definition at line 14708 of file chan_iax2.c.
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 378 of file chan_iax2.c.
Referenced by __ast_channel_alloc_ap(), __oh323_new(), 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(), 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 382 of file chan_iax2.c.
int amaflags = 0 [static] |
Definition at line 381 of file chan_iax2.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 14708 of file chan_iax2.c.
int authdebug = 1 [static] |
Definition at line 289 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 290 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 889 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 844 of file chan_iax2.c.
const unsigned int CALLNO_POOL_BUCKETS = 2699 [static] |
Definition at line 849 of file chan_iax2.c.
struct ao2_container* callno_pool_trunk [static] |
table of available trunk call numbers
Definition at line 847 of file chan_iax2.c.
struct ao2_container* calltoken_ignores [static] |
Table containing ip addresses not requiring calltoken validation
Definition at line 892 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 300 of file chan_iax2.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1096 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 894 of file chan_iax2.c.
uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static] |
Definition at line 896 of file chan_iax2.c.
char default_parkinglot[AST_MAX_CONTEXT] [static] |
Definition at line 267 of file chan_iax2.c.
Referenced by load_config(), park_exec_full(), park_space_reserve(), and sip_alloc().
int defaultsockfd = -1 [static] |
Definition at line 312 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 383 of file chan_iax2.c.
Definition at line 860 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 262 of file chan_iax2.c.
uint16_t global_maxcallno [static] |
Definition at line 898 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 901 of file chan_iax2.c.
int global_rtautoclear = 120 [static] |
Definition at line 434 of file chan_iax2.c.
struct ast_flags64 globalflags = { 0 } [static] |
Definition at line 386 of file chan_iax2.c.
format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 364 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 14579 of file chan_iax2.c.
Referenced by load_module().
int iax2_encryption = 0 [static] |
Definition at line 384 of file chan_iax2.c.
int(*) iax2_regfunk(const char *username, int onoff) = NULL [static] |
Definition at line 314 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 1214 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 1332 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 1073 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 1089 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 633 of file chan_iax2.c.
Referenced by iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 291 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 366 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 294 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 296 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 13843 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 1062 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_max_nontrunk(), update_max_trunk(), 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 1082 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(), socket_process(), socket_process_meta(), transmit_frame(), unlock_both(), update_registry(), and wait_for_peercallno().
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 629 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 368 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 9784 of file chan_iax2.c.
Referenced by load_module(), and unload_module().
struct io_context* io [static] |
Definition at line 359 of file chan_iax2.c.
int jittertargetextra = 40 [static] |
Definition at line 282 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 278 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 269 of file chan_iax2.c.
Definition at line 860 of file chan_iax2.c.
int last_authmethod = 0 [static] |
Definition at line 292 of file chan_iax2.c.
const time_t MAX_CALLTOKEN_DELAY = 10 [static] |
Definition at line 866 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 304 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 276 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 275 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 279 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 281 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 1163 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 1162 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 303 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 379 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 380 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 310 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 388 of file chan_iax2.c.
int network_change_event_sched_id = -1 [static] |
Definition at line 273 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 272 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 311 of file chan_iax2.c.
Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().
char* papp = "IAX2Provision" [static] |
struct ao2_container* peercnts [static] |
Table containing peercnt objects for every ip address consuming a callno
Definition at line 886 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 880 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(), 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 14569 of file chan_iax2.c.
int ping_time = 21 [static] |
Definition at line 277 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 253 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 864 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 270 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 280 of file chan_iax2.c.
struct ast_sched_thread* sched [static] |
Definition at line 360 of file chan_iax2.c.
int srvlookup = 0 [static] |
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 255 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 370 of file chan_iax2.c.
Definition at line 308 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(), 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 299 of file chan_iax2.c.
uint16_t total_nonval_callno_used = 0 [static] |
Definition at line 903 of file chan_iax2.c.
struct ast_taskprocessor* transmit_processor [static] |
Definition at line 862 of file chan_iax2.c.
int trunk_maxmtu [static] |
Definition at line 263 of file chan_iax2.c.
int trunk_nmaxmtu [static] |
Trunk MTU statistics
Definition at line 263 of file chan_iax2.c.
int trunk_timed [static] |
Definition at line 263 of file chan_iax2.c.
int trunk_untimed [static] |
Definition at line 263 of file chan_iax2.c.
int trunkfreq = 20 [static] |
Definition at line 286 of file chan_iax2.c.
int trunkmaxsize = MAX_TRUNKDATA [static] |
Definition at line 287 of file chan_iax2.c.
struct ao2_container* users [static] |
Definition at line 883 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 14574 of file chan_iax2.c.