#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/aes.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 "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 | 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 | 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%s" |
| #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%s" |
| #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 ARRAY_LEN(iaxs) / 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 manager, int fd, 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_channel_write (struct ast_channel *chan, const char *function, char *data, const char *value) |
| 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) |
| static struct ast_channel * | ast_iax2_new (int callno, int state, int 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 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 (int 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 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_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, int 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) |
| 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_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 sockaddr_in *sin) |
| 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 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 sockaddr_in *sin, 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 int | 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 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_DEFAULT , .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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } |
| 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 { | |
| struct iax_frame * first | |
| struct iax_frame * last | |
| } | frame_queue [IAX_MAX_CALLS] |
| 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 int | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH |
| 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] |
| 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 struct ast_netsock_list * | outsock |
| static char * | papp = "IAX2Provision" |
| static struct ao2_container * | peercnts |
| static struct ao2_container * | peers |
| 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 |
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 235 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 DEBUG_SCHED_MULTITHREAD |
Definition at line 227 of file chan_iax2.c.
| #define DEBUG_SUPPORT |
Definition at line 243 of file chan_iax2.c.
| #define DEFAULT_CONTEXT "default" |
Definition at line 262 of file chan_iax2.c.
Referenced by check_access(), handle_cli_iax2_show_users(), and reload_config().
| #define DEFAULT_DROP 3 |
Definition at line 241 of file chan_iax2.c.
| #define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 333 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 238 of file chan_iax2.c.
| #define DEFAULT_MAXMS 2000 |
Definition at line 331 of file chan_iax2.c.
Referenced by build_peer(), iax2_poke_peer(), reload_config(), and set_config().
| #define DEFAULT_RETRY_TIME 1000 |
| #define DEFAULT_THREAD_COUNT 10 |
Definition at line 237 of file chan_iax2.c.
| #define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 610 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
| #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%s" |
| #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%s" |
| #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 248 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 419 of file chan_iax2.c.
Referenced by set_config(), and socket_process().
| #define IAX_ALREADYGONE (uint64_t)(1 << 9) |
Already disconnected
Definition at line 402 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 336 of file chan_iax2.c.
Referenced by iax2_send(), iax2_start_transfer(), and socket_process().
| #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
Definition at line 311 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 322 of file chan_iax2.c.
Referenced by set_config().
| #define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 327 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 409 of file chan_iax2.c.
Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), and socket_process().
| #define IAX_CODEC_NOPREFS (uint64_t)(1 << 15) |
Force old behaviour by turning off prefs
Definition at line 408 of file chan_iax2.c.
Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), and socket_process().
| #define IAX_CODEC_USER_FIRST (uint64_t)(1 << 14) |
are we willing to let the other guy choose the codec?
Definition at line 407 of file chan_iax2.c.
Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), and socket_process().
| #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 418 of file chan_iax2.c.
Referenced by socket_process().
| #define IAX_DELME (uint64_t)(1 << 1) |
Needs to be deleted
Definition at line 394 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 399 of file chan_iax2.c.
Referenced by __iax2_show_peers(), build_peer(), function_iaxpeer(), handle_cli_iax2_show_peer(), manager_iax2_show_peer_list(), realtime_peer(), register_verify(), and set_config().
| #define IAX_ENCRYPTED (uint64_t)(1 << 12) |
Whether we should assume encrypted tx/rx
Definition at line 405 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 423 of file chan_iax2.c.
Referenced by __find_callno(), authenticate_reply(), authenticate_verify(), build_peer(), build_user(), check_access(), create_addr(), iax2_call(), 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 413 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 393 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 420 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 406 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 417 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 397 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_bridge(), 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 403 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 404 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 422 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 412 of file chan_iax2.c.
Referenced by __expire_registry(), handle_cli_iax2_prune_realtime(), realtime_peer(), and set_config().
| #define IAX_RTCACHEFRIENDS (uint64_t)(1 << 17) |
let realtime stay till your reload
Definition at line 410 of file chan_iax2.c.
Referenced by __expire_registry(), handle_cli_iax2_prune_realtime(), prune_peers(), prune_users(), realtime_peer(), realtime_user(), set_config(), and update_registry().
| #define IAX_RTIGNOREREGEXPIRE (uint64_t)(1 << 21) |
When using realtime, ignore registration expiration
Definition at line 414 of file chan_iax2.c.
Referenced by realtime_peer(), and set_config().
| #define IAX_RTSAVE_SYSNAME (uint64_t)(1 << 8) |
Save Systname on Realtime Updates
Definition at line 401 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 411 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 400 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 421 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 424 of file chan_iax2.c.
Referenced by check_access(), and set_config().
| #define IAX_TEMPONLY (uint64_t)(1 << 2) |
Temporary (realtime)
Definition at line 395 of file chan_iax2.c.
Referenced by __expire_registry(), realtime_peer(), realtime_user(), reg_source_db(), and update_registry().
| #define IAX_TRANSFERMEDIA (uint64_t)(1 << 23) |
When doing IAX2 transfers, transfer media only
Definition at line 416 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_bridge(), iax2_request(), set_config(), and set_config_destroy().
| #define IAX_TRUNK (uint64_t)(1 << 3) |
Treat as a trunk
Definition at line 396 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(), and socket_process().
| #define IAX_TRUNKTIMESTAMPS (uint64_t)(1 << 22) |
Send trunk timestamps
Definition at line 415 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 398 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 618 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 607 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 869 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 612 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 257 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 278 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 240 of file chan_iax2.c.
| #define MIN_JITTER_BUFFER 10 |
Definition at line 608 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 234 of file chan_iax2.c.
Referenced by __auto_congest(), __get_from_jb(), acf_channel_read(), acf_channel_write(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit_begin(), iax2_digit_end(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), iax2_write(), and scheduled_destroy().
| #define SCHED_MULTITHREADED |
Definition at line 223 of file chan_iax2.c.
| #define schedule_action | ( | func, | |||
| data | ) | __schedule_action(func, data, __PRETTY_FUNCTION__) |
Definition at line 1398 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 ARRAY_LEN(iaxs) / 2 |
Definition at line 1083 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 615 of file chan_iax2.c.
| anonymous enum |
Definition at line 929 of file chan_iax2.c.
00929 { 00930 /*! Extension exists */ 00931 CACHE_FLAG_EXISTS = (1 << 0), 00932 /*! Extension is nonexistent */ 00933 CACHE_FLAG_NONEXISTENT = (1 << 1), 00934 /*! Extension can exist */ 00935 CACHE_FLAG_CANEXIST = (1 << 2), 00936 /*! Waiting to hear back response */ 00937 CACHE_FLAG_PENDING = (1 << 3), 00938 /*! Timed out */ 00939 CACHE_FLAG_TIMEOUT = (1 << 4), 00940 /*! Request transmitted */ 00941 CACHE_FLAG_TRANSMITTED = (1 << 5), 00942 /*! Timeout */ 00943 CACHE_FLAG_UNKNOWN = (1 << 6), 00944 /*! Matchmore */ 00945 CACHE_FLAG_MATCHMORE = (1 << 7), 00946 };
| anonymous enum |
Definition at line 1866 of file chan_iax2.c.
01866 { 01867 /* do not allow a new call number, only search ones in use for match */ 01868 NEW_PREVENT = 0, 01869 /* search for match first, then allow a new one to be allocated */ 01870 NEW_ALLOW = 1, 01871 /* do not search for match, force a new call number */ 01872 NEW_FORCE = 2, 01873 /* do not search for match, force a new call number. Signifies call number 01874 * has been calltoken validated */ 01875 NEW_ALLOW_CALLTOKEN_VALIDATED = 3, 01876 };
| enum calltoken_peer_enum |
Call token validation settings.
Definition at line 432 of file chan_iax2.c.
00432 { 00433 /*! \brief Default calltoken required unless the ip is in the ignorelist */ 00434 CALLTOKEN_DEFAULT = 0, 00435 /*! \brief Require call token validation. */ 00436 CALLTOKEN_YES = 1, 00437 /*! \brief Require call token validation after a successful registration 00438 * using call token validation occurs. */ 00439 CALLTOKEN_AUTO = 2, 00440 /*! \brief Do not require call token validation. */ 00441 CALLTOKEN_NO = 3, 00442 };
| enum iax2_state |
Definition at line 381 of file chan_iax2.c.
00381 { 00382 IAX_STATE_STARTED = (1 << 0), 00383 IAX_STATE_AUTHENTICATED = (1 << 1), 00384 IAX_STATE_TBD = (1 << 2), 00385 };
| enum iax2_thread_iostate |
Definition at line 970 of file chan_iax2.c.
00970 { 00971 IAX_IOSTATE_IDLE, 00972 IAX_IOSTATE_READY, 00973 IAX_IOSTATE_PROCESSING, 00974 IAX_IOSTATE_SCHEDREADY, 00975 };
| enum iax2_thread_type |
Definition at line 977 of file chan_iax2.c.
00977 { 00978 IAX_THREAD_TYPE_POOL, 00979 IAX_THREAD_TYPE_DYNAMIC, 00980 };
| 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 563 of file chan_iax2.c.
00563 { 00564 REG_STATE_UNREGISTERED = 0, 00565 REG_STATE_REGSENT, 00566 REG_STATE_AUTHSENT, 00567 REG_STATE_REGISTERED, 00568 REG_STATE_REJECTED, 00569 REG_STATE_TIMEOUT, 00570 REG_STATE_NOAUTH 00571 };
| 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 573 of file chan_iax2.c.
00573 { 00574 TRANSFER_NONE = 0, 00575 TRANSFER_BEGIN, 00576 TRANSFER_READY, 00577 TRANSFER_RELEASED, 00578 TRANSFER_PASSTHROUGH, 00579 TRANSFER_MBEGIN, 00580 TRANSFER_MREADY, 00581 TRANSFER_MRELEASED, 00582 TRANSFER_MPASSTHROUGH, 00583 TRANSFER_MEDIA, 00584 TRANSFER_MEDIAPASS 00585 };
| static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3351 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, 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, iax_frame::final, frame_queue, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, LOG_WARNING, MAX_RETRY_TIME, ast_channel::name, iax_frame::oseqno, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_command(), send_packet(), ast_frame::subclass, iax_frame::transfer, iax_frame::ts, update_packet(), and iax2_registry::us.
Referenced by attempt_transmit().
03352 { 03353 /* Attempt to transmit the frame to the remote peer... 03354 Called without iaxsl held. */ 03355 struct iax_frame *f = (struct iax_frame *)data; 03356 int freeme = 0; 03357 int callno = f->callno; 03358 /* Make sure this call is still active */ 03359 if (callno) 03360 ast_mutex_lock(&iaxsl[callno]); 03361 if (callno && iaxs[callno]) { 03362 if ((f->retries < 0) /* Already ACK'd */ || 03363 (f->retries >= max_retries) /* Too many attempts */) { 03364 /* Record an error if we've transmitted too many times */ 03365 if (f->retries >= max_retries) { 03366 if (f->transfer) { 03367 /* Transfer timeout */ 03368 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 03369 } else if (f->final) { 03370 iax2_destroy(callno); 03371 } else { 03372 if (iaxs[callno]->owner) 03373 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, 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, f->ts, f->oseqno); 03374 iaxs[callno]->error = ETIMEDOUT; 03375 if (iaxs[callno]->owner) { 03376 struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER }; 03377 /* Hangup the fd */ 03378 iax2_queue_frame(callno, &fr); /* XXX */ 03379 /* Remember, owner could disappear */ 03380 if (iaxs[callno] && iaxs[callno]->owner) 03381 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03382 } else { 03383 if (iaxs[callno]->reg) { 03384 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 03385 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 03386 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 03387 } 03388 iax2_destroy(callno); 03389 } 03390 } 03391 03392 } 03393 freeme = 1; 03394 } else { 03395 /* Update it if it needs it */ 03396 update_packet(f); 03397 /* Attempt transmission */ 03398 send_packet(f); 03399 f->retries++; 03400 /* Try again later after 10 times as long */ 03401 f->retrytime *= 10; 03402 if (f->retrytime > MAX_RETRY_TIME) 03403 f->retrytime = MAX_RETRY_TIME; 03404 /* Transfer messages max out at one second */ 03405 if (f->transfer && (f->retrytime > 1000)) 03406 f->retrytime = 1000; 03407 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 03408 } 03409 } else { 03410 /* Make sure it gets freed */ 03411 f->retries = -1; 03412 freeme = 1; 03413 } 03414 03415 if (freeme) { 03416 /* Don't attempt delivery, just remove it from the queue */ 03417 AST_LIST_REMOVE(&frame_queue[callno], f, list); 03418 ast_mutex_unlock(&iaxsl[callno]); 03419 f->retrans = -1; /* this is safe because this is the scheduled function */ 03420 /* Free the IAX frame */ 03421 iax2_frame_free(f); 03422 } else if (callno) { 03423 ast_mutex_unlock(&iaxsl[callno]); 03424 } 03425 }
| static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 8679 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_ie_data::buf, IAX_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iax_ie_data::pos, and send_command_final().
Referenced by auth_reject().
08680 { 08681 /* Called from IAX thread only, without iaxs lock */ 08682 int callno = (int)(long)(nothing); 08683 struct iax_ie_data ied; 08684 ast_mutex_lock(&iaxsl[callno]); 08685 if (iaxs[callno]) { 08686 memset(&ied, 0, sizeof(ied)); 08687 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 08688 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 08689 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 08690 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 08691 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 08692 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08693 } 08694 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 08695 } 08696 ast_mutex_unlock(&iaxsl[callno]); 08697 }
| static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 4498 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_queue_frame(), chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
04499 { 04500 int callno = PTR_TO_CALLNO(nothing); 04501 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 04502 ast_mutex_lock(&iaxsl[callno]); 04503 if (iaxs[callno]) { 04504 iaxs[callno]->initid = -1; 04505 iax2_queue_frame(callno, &f); 04506 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 04507 } 04508 ast_mutex_unlock(&iaxsl[callno]); 04509 }
| static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 8728 of file chan_iax2.c.
References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax_ie_data::buf, IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iax_ie_data::pos, and send_command_final().
Referenced by auto_hangup().
08729 { 08730 /* Called from IAX thread only, without iaxs lock */ 08731 int callno = (int)(long)(nothing); 08732 struct iax_ie_data ied; 08733 ast_mutex_lock(&iaxsl[callno]); 08734 if (iaxs[callno]) { 08735 memset(&ied, 0, sizeof(ied)); 08736 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 08737 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 08738 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 08739 } 08740 ast_mutex_unlock(&iaxsl[callno]); 08741 }
| 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 3146 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, and iax_frame::retrans.
Referenced by __get_from_jb(), and schedule_delivery().
03147 { 03148 /* Just deliver the packet by using queueing. This is called by 03149 the IAX thread with the iaxsl lock held. */ 03150 struct iax_frame *fr = data; 03151 fr->retrans = -1; 03152 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 03153 if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE)) 03154 iax2_queue_frame(fr->callno, &fr->af); 03155 /* Free our iax frame */ 03156 iax2_frame_free(fr); 03157 /* And don't run again */ 03158 return 0; 03159 }
| static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8327 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, 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().
08328 { 08329 struct iax2_peer *peer = (struct iax2_peer *) data; 08330 08331 if (!peer) 08332 return; 08333 08334 peer->expire = -1; 08335 08336 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name); 08337 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 08338 realtime_update_peer(peer->name, &peer->addr, 0); 08339 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08340 /* modify entry in peercnts table as _not_ registered */ 08341 peercnt_modify(0, 0, &peer->addr); 08342 /* Reset the address */ 08343 memset(&peer->addr, 0, sizeof(peer->addr)); 08344 /* Reset expiry value */ 08345 peer->expiry = min_reg_expire; 08346 if (!ast_test_flag64(peer, IAX_TEMPONLY)) 08347 ast_db_del("IAX/Registry", peer->name); 08348 register_peer_exten(peer, 0); 08349 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 08350 if (iax2_regfunk) 08351 iax2_regfunk(peer->name, 0); 08352 08353 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) 08354 unlink_peer(peer); 08355 08356 peer_unref(peer); 08357 }
| 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 2624 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, callno_entry::callno, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, get_unused_callno(), iax2_getpeername(), iax2_sched_add(), IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, 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(), 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().
02625 { 02626 int res = 0; 02627 int x; 02628 /* this call is calltoken validated as long as it is either NEW_FORCE 02629 * or NEW_ALLOW_CALLTOKEN_VALIDATED */ 02630 int validated = (new > NEW_ALLOW) ? 1 : 0; 02631 char host[80]; 02632 02633 if (new <= NEW_ALLOW) { 02634 if (callno) { 02635 struct chan_iax2_pvt *pvt; 02636 struct chan_iax2_pvt tmp_pvt = { 02637 .callno = dcallno, 02638 .peercallno = callno, 02639 .transfercallno = callno, 02640 /* hack!! */ 02641 .frames_received = check_dcallno, 02642 }; 02643 02644 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 02645 /* this works for finding normal call numbers not involving transfering */ 02646 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02647 if (return_locked) { 02648 ast_mutex_lock(&iaxsl[pvt->callno]); 02649 } 02650 res = pvt->callno; 02651 ao2_ref(pvt, -1); 02652 pvt = NULL; 02653 return res; 02654 } 02655 /* this searches for transfer call numbers that might not get caught otherwise */ 02656 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr)); 02657 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer)); 02658 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02659 if (return_locked) { 02660 ast_mutex_lock(&iaxsl[pvt->callno]); 02661 } 02662 res = pvt->callno; 02663 ao2_ref(pvt, -1); 02664 pvt = NULL; 02665 return res; 02666 } 02667 } 02668 /* This will occur on the first response to a message that we initiated, 02669 * such as a PING. */ 02670 if (dcallno) { 02671 ast_mutex_lock(&iaxsl[dcallno]); 02672 } 02673 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 02674 iaxs[dcallno]->peercallno = callno; 02675 res = dcallno; 02676 store_by_peercallno(iaxs[dcallno]); 02677 if (!res || !return_locked) { 02678 ast_mutex_unlock(&iaxsl[dcallno]); 02679 } 02680 return res; 02681 } 02682 if (dcallno) { 02683 ast_mutex_unlock(&iaxsl[dcallno]); 02684 } 02685 #ifdef IAX_OLD_FIND 02686 /* If we get here, we SHOULD NOT find a call structure for this 02687 callno; if we do, it means that there is a call structure that 02688 has a peer callno but did NOT get entered into the hash table, 02689 which is bad. 02690 02691 If we find a call structure using this old, slow method, output a log 02692 message so we'll know about it. After a few months of leaving this in 02693 place, if we don't hear about people seeing these messages, we can 02694 remove this code for good. 02695 */ 02696 02697 for (x = 1; !res && x < maxnontrunkcall; x++) { 02698 ast_mutex_lock(&iaxsl[x]); 02699 if (iaxs[x]) { 02700 /* Look for an exact match */ 02701 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02702 res = x; 02703 } 02704 } 02705 if (!res || !return_locked) 02706 ast_mutex_unlock(&iaxsl[x]); 02707 } 02708 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 02709 ast_mutex_lock(&iaxsl[x]); 02710 if (iaxs[x]) { 02711 /* Look for an exact match */ 02712 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02713 res = x; 02714 } 02715 } 02716 if (!res || !return_locked) 02717 ast_mutex_unlock(&iaxsl[x]); 02718 } 02719 #endif 02720 } 02721 if (!res && (new >= NEW_ALLOW)) { 02722 struct callno_entry *callno_entry; 02723 /* It may seem odd that we look through the peer list for a name for 02724 * this *incoming* call. Well, it is weird. However, users don't 02725 * have an IP address/port number that we can match against. So, 02726 * this is just checking for a peer that has that IP/port and 02727 * assuming that we have a user of the same name. This isn't always 02728 * correct, but it will be changed if needed after authentication. */ 02729 if (!iax2_getpeername(*sin, host, sizeof(host))) 02730 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 02731 02732 if (peercnt_add(sin)) { 02733 /* This address has hit its callnumber limit. When the limit 02734 * is reached, the connection is not added to the peercnts table.*/ 02735 return 0; 02736 } 02737 02738 if (!(callno_entry = get_unused_callno(0, validated))) { 02739 /* since we ran out of space, remove the peercnt 02740 * entry we added earlier */ 02741 peercnt_remove_by_addr(sin); 02742 ast_log(LOG_WARNING, "No more space\n"); 02743 return 0; 02744 } 02745 x = callno_entry->callno; 02746 ast_mutex_lock(&iaxsl[x]); 02747 02748 iaxs[x] = new_iax(sin, host); 02749 update_max_nontrunk(); 02750 if (iaxs[x]) { 02751 if (iaxdebug) 02752 ast_debug(1, "Creating new call structure %d\n", x); 02753 iaxs[x]->callno_entry = callno_entry; 02754 iaxs[x]->sockfd = sockfd; 02755 iaxs[x]->addr.sin_port = sin->sin_port; 02756 iaxs[x]->addr.sin_family = sin->sin_family; 02757 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 02758 iaxs[x]->peercallno = callno; 02759 iaxs[x]->callno = x; 02760 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 02761 iaxs[x]->expiry = min_reg_expire; 02762 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 02763 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 02764 iaxs[x]->amaflags = amaflags; 02765 ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 02766 ast_string_field_set(iaxs[x], accountcode, accountcode); 02767 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 02768 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 02769 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot); 02770 02771 if (iaxs[x]->peercallno) { 02772 store_by_peercallno(iaxs[x]); 02773 } 02774 } else { 02775 ast_log(LOG_WARNING, "Out of resources\n"); 02776 ast_mutex_unlock(&iaxsl[x]); 02777 replace_callno(callno_entry); 02778 return 0; 02779 } 02780 if (!return_locked) 02781 ast_mutex_unlock(&iaxsl[x]); 02782 res = x; 02783 } 02784 return res; 02785 }
| static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 3924 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(), jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, 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, 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().
03925 { 03926 int callno = PTR_TO_CALLNO(p); 03927 struct chan_iax2_pvt *pvt = NULL; 03928 struct iax_frame *fr; 03929 jb_frame frame; 03930 int ret; 03931 long ms; 03932 long next; 03933 struct timeval now = ast_tvnow(); 03934 03935 /* Make sure we have a valid private structure before going on */ 03936 ast_mutex_lock(&iaxsl[callno]); 03937 pvt = iaxs[callno]; 03938 if (!pvt) { 03939 /* No go! */ 03940 ast_mutex_unlock(&iaxsl[callno]); 03941 return; 03942 } 03943 03944 pvt->jbid = -1; 03945 03946 /* round up a millisecond since ast_sched_runq does; */ 03947 /* prevents us from spinning while waiting for our now */ 03948 /* to catch up with runq's now */ 03949 now.tv_usec += 1000; 03950 03951 ms = ast_tvdiff_ms(now, pvt->rxcore); 03952 03953 if(ms >= (next = jb_next(pvt->jb))) { 03954 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat)); 03955 switch(ret) { 03956 case JB_OK: 03957 fr = frame.data; 03958 __do_deliver(fr); 03959 /* __do_deliver() can cause the call to disappear */ 03960 pvt = iaxs[callno]; 03961 break; 03962 case JB_INTERP: 03963 { 03964 struct ast_frame af = { 0, }; 03965 03966 /* create an interpolation frame */ 03967 af.frametype = AST_FRAME_VOICE; 03968 af.subclass = pvt->voiceformat; 03969 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000); 03970 af.src = "IAX2 JB interpolation"; 03971 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 03972 af.offset = AST_FRIENDLY_OFFSET; 03973 03974 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 03975 * which we'd need to malloc, and then it would free it. That seems like a drag */ 03976 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) { 03977 iax2_queue_frame(callno, &af); 03978 /* iax2_queue_frame() could cause the call to disappear */ 03979 pvt = iaxs[callno]; 03980 } 03981 } 03982 break; 03983 case JB_DROP: 03984 iax2_frame_free(frame.data); 03985 break; 03986 case JB_NOFRAME: 03987 case JB_EMPTY: 03988 /* do nothing */ 03989 break; 03990 default: 03991 /* shouldn't happen */ 03992 break; 03993 } 03994 } 03995 if (pvt) 03996 update_jbsched(pvt); 03997 ast_mutex_unlock(&iaxsl[callno]); 03998 }
| static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8009 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
08010 { 08011 struct iax2_registry *reg = (struct iax2_registry *)data; 08012 reg->expire = -1; 08013 iax2_do_register(reg); 08014 }
| static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 11553 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(), iax2_peer::lastms, LOG_NOTICE, manager_event, iax2_peer::name, peer_ref(), peer_unref(), iax2_peer::pokeexpire, and iax2_peer::pokefreqnotok.
Referenced by iax2_poke_noanswer().
11554 { 11555 struct iax2_peer *peer = (struct iax2_peer *)data; 11556 int callno; 11557 11558 if (peer->lastms > -1) { 11559 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 11560 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 11561 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 11562 } 11563 if ((callno = peer->callno) > 0) { 11564 ast_mutex_lock(&iaxsl[callno]); 11565 iax2_destroy(callno); 11566 ast_mutex_unlock(&iaxsl[callno]); 11567 } 11568 peer->callno = 0; 11569 peer->lastms = -1; 11570 /* Try again quickly */ 11571 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 11572 if (peer->pokeexpire == -1) 11573 peer_unref(peer); 11574 }
| static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 8788 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
08789 { 08790 struct iax2_peer *peer = (struct iax2_peer *)data; 08791 iax2_poke_peer(peer, 0); 08792 peer_unref(peer); 08793 }
| static int __iax2_show_peers | ( | int | manager, | |
| int | fd, | |||
| struct mansession * | s, | |||
| const int | argc, | |||
| const char *const | argv[] | |||
| ) | [static] |
Definition at line 6405 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_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(), RESULT_SHOWUSAGE, RESULT_SUCCESS, status, and iax2_peer::username.
Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().
06406 { 06407 regex_t regexbuf; 06408 int havepattern = 0; 06409 int total_peers = 0; 06410 int online_peers = 0; 06411 int offline_peers = 0; 06412 int unmonitored_peers = 0; 06413 struct ao2_iterator i; 06414 06415 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 06416 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 06417 06418 struct iax2_peer *peer = NULL; 06419 char name[256]; 06420 struct ast_str *encmethods = ast_str_alloca(256); 06421 int registeredonly=0; 06422 char *term = manager ? "\r\n" : "\n"; 06423 char idtext[256] = ""; 06424 switch (argc) { 06425 case 6: 06426 if (!strcasecmp(argv[3], "registered")) 06427 registeredonly = 1; 06428 else 06429 return RESULT_SHOWUSAGE; 06430 if (!strcasecmp(argv[4], "like")) { 06431 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 06432 return RESULT_SHOWUSAGE; 06433 havepattern = 1; 06434 } else 06435 return RESULT_SHOWUSAGE; 06436 break; 06437 case 5: 06438 if (!strcasecmp(argv[3], "like")) { 06439 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 06440 return RESULT_SHOWUSAGE; 06441 havepattern = 1; 06442 } else 06443 return RESULT_SHOWUSAGE; 06444 break; 06445 case 4: 06446 if (!strcasecmp(argv[3], "registered")) 06447 registeredonly = 1; 06448 else 06449 return RESULT_SHOWUSAGE; 06450 break; 06451 case 3: 06452 break; 06453 default: 06454 return RESULT_SHOWUSAGE; 06455 } 06456 06457 06458 if (!s) 06459 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 06460 06461 i = ao2_iterator_init(peers, 0); 06462 for (peer = ao2_iterator_next(&i); peer; 06463 peer_unref(peer), peer = ao2_iterator_next(&i)) { 06464 char nm[20]; 06465 char status[20]; 06466 int retstatus; 06467 06468 if (registeredonly && !peer->addr.sin_addr.s_addr) 06469 continue; 06470 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 06471 continue; 06472 06473 if (!ast_strlen_zero(peer->username)) 06474 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 06475 else 06476 ast_copy_string(name, peer->name, sizeof(name)); 06477 06478 encmethods_to_str(peer->encmethods, encmethods); 06479 retstatus = peer_status(peer, status, sizeof(status)); 06480 if (retstatus > 0) 06481 online_peers++; 06482 else if (!retstatus) 06483 offline_peers++; 06484 else 06485 unmonitored_peers++; 06486 06487 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 06488 06489 if (s) { 06490 astman_append(s, 06491 "Event: PeerEntry\r\n%s" 06492 "Channeltype: IAX2\r\n" 06493 "ChanObjectType: peer\r\n" 06494 "ObjectName: %s\r\n" 06495 "IPaddress: %s\r\n" 06496 "IPport: %d\r\n" 06497 "Dynamic: %s\r\n" 06498 "Trunk: %s\r\n" 06499 "Encryption: %s\r\n" 06500 "Status: %s\r\n\r\n", 06501 idtext, 06502 name, 06503 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-", 06504 ntohs(peer->addr.sin_port), 06505 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no", 06506 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no", 06507 peer->encmethods ? ast_str_buffer(encmethods) : "no", 06508 status); 06509 } else { 06510 ast_cli(fd, FORMAT, name, 06511 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 06512 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 06513 nm, 06514 ntohs(peer->addr.sin_port), 06515 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ", 06516 peer->encmethods ? "(E)" : " ", 06517 status, 06518 term); 06519 } 06520 total_peers++; 06521 } 06522 ao2_iterator_destroy(&i); 06523 06524 if (!s) 06525 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 06526 06527 if (havepattern) 06528 regfree(®exbuf); 06529 06530 return RESULT_SUCCESS; 06531 #undef FORMAT 06532 #undef FORMAT2 06533 }
| static void __reg_module | ( | void | ) | [static] |
Definition at line 14038 of file chan_iax2.c.
| static int __schedule_action | ( | void(*)(const void *data) | func, | |
| const void * | data, | |||
| const char * | funcname | |||
| ) | [static] |
Definition at line 1373 of file chan_iax2.c.
References ast_copy_string(), ast_debug, iax2_thread::cond, iax2_thread::curfunc, find_idle_thread(), IAX_IOSTATE_SCHEDREADY, iax2_thread::iostate, iax2_thread::lock, iax2_thread::scheddata, iax2_thread::schedfunc, signal_condition(), and thread.
01374 { 01375 struct iax2_thread *thread = NULL; 01376 static time_t lasterror; 01377 static time_t t; 01378 01379 thread = find_idle_thread(); 01380 01381 if (thread != NULL) { 01382 thread->schedfunc = func; 01383 thread->scheddata = data; 01384 thread->iostate = IAX_IOSTATE_SCHEDREADY; 01385 #ifdef DEBUG_SCHED_MULTITHREAD 01386 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 01387 #endif 01388 signal_condition(&thread->lock, &thread->cond); 01389 return 0; 01390 } 01391 time(&t); 01392 if (t != lasterror) 01393 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n"); 01394 lasterror = t; 01395 01396 return -1; 01397 }
| 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 7209 of file chan_iax2.c.
References ast_frame::data, ast_frame::datalen, ast_frame::frametype, iax2_send(), ast_frame::ptr, queue_signalling(), ast_frame::src, and ast_frame::subclass.
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
07211 { 07212 struct ast_frame f = { 0, }; 07213 int res = 0; 07214 07215 f.frametype = type; 07216 f.subclass = command; 07217 f.datalen = datalen; 07218 f.src = __FUNCTION__; 07219 f.data.ptr = (void *) data; 07220 07221 if ((res = queue_signalling(i, &f)) <= 0) { 07222 return res; 07223 } 07224 07225 return iax2_send(i, &f, ts, seqno, now, transfer, final); 07226 }
| static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1478 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax2_thread::callno, iax2_sched_add(), IAX_COMMAND_LAGRQ, chan_iax2_pvt::lagid, send_command(), and send_lagrq().
Referenced by send_lagrq().
01479 { 01480 int callno = (long) data; 01481 01482 ast_mutex_lock(&iaxsl[callno]); 01483 01484 if (iaxs[callno]) { 01485 if (iaxs[callno]->peercallno) { 01486 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01487 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01488 } else { 01489 /* I am the schedule, so I'm allowed to do this */ 01490 iaxs[callno]->lagid = -1; 01491 } 01492 } else { 01493 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno); 01494 } 01495 01496 ast_mutex_unlock(&iaxsl[callno]); 01497 }
| static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1417 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax2_thread::callno, iax2_sched_add(), IAX_COMMAND_PING, chan_iax2_pvt::pingid, send_command(), and send_ping().
Referenced by send_ping().
01418 { 01419 int callno = (long) data; 01420 01421 ast_mutex_lock(&iaxsl[callno]); 01422 01423 if (iaxs[callno]) { 01424 if (iaxs[callno]->peercallno) { 01425 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01426 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01427 } else { 01428 /* I am the schedule, so I'm allowed to do this */ 01429 iaxs[callno]->pingid = -1; 01430 } 01431 } else { 01432 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno); 01433 } 01434 01435 ast_mutex_unlock(&iaxsl[callno]); 01436 }
| static int __unload_module | ( | void | ) | [static] |
Definition at line 13739 of file chan_iax2.c.
References ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_context_find(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_manager_unregister(), ast_mutex_destroy(), ast_netsock_release(), AST_PTHREADT_NULL, ast_sched_thread_destroy(), ast_taskprocessor_unreference(), ast_timer_close(), ast_unload_realtime(), ast_unregister_application(), ast_unregister_switch(), delete_users(), iax2_destroy(), iax_provision_unload(), iaxactivethreadcount, reload_firmware(), thread, and iax2_thread::threadid.
13740 { 13741 struct iax2_thread *thread = NULL; 13742 struct ast_context *con; 13743 int x; 13744 13745 if (netthreadid != AST_PTHREADT_NULL) { 13746 pthread_cancel(netthreadid); 13747 pthread_kill(netthreadid, SIGURG); 13748 pthread_join(netthreadid, NULL); 13749 } 13750 13751 sched = ast_sched_thread_destroy(sched); 13752 13753 /* Call for all threads to halt */ 13754 AST_LIST_LOCK(&idle_list); 13755 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) 13756 pthread_cancel(thread->threadid); 13757 AST_LIST_UNLOCK(&idle_list); 13758 13759 AST_LIST_LOCK(&active_list); 13760 while ((thread = AST_LIST_REMOVE_HEAD(&active_list, list))) 13761 pthread_cancel(thread->threadid); 13762 AST_LIST_UNLOCK(&active_list); 13763 13764 AST_LIST_LOCK(&dynamic_list); 13765 while ((thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list))) 13766 pthread_cancel(thread->threadid); 13767 AST_LIST_UNLOCK(&dynamic_list); 13768 13769 /* Wait for threads to exit */ 13770 while(0 < iaxactivethreadcount) 13771 usleep(10000); 13772 13773 ast_netsock_release(netsock); 13774 ast_netsock_release(outsock); 13775 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 13776 if (iaxs[x]) { 13777 iax2_destroy(x); 13778 } 13779 } 13780 ast_manager_unregister( "IAXpeers" ); 13781 ast_manager_unregister( "IAXpeerlist" ); 13782 ast_manager_unregister( "IAXnetstats" ); 13783 ast_manager_unregister( "IAXregistry" ); 13784 ast_unregister_application(papp); 13785 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 13786 ast_unregister_switch(&iax2_switch); 13787 ast_channel_unregister(&iax2_tech); 13788 delete_users(); 13789 iax_provision_unload(); 13790 reload_firmware(1); 13791 13792 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 13793 ast_mutex_destroy(&iaxsl[x]); 13794 } 13795 13796 ao2_ref(peers, -1); 13797 ao2_ref(users, -1); 13798 ao2_ref(iax_peercallno_pvts, -1); 13799 ao2_ref(iax_transfercallno_pvts, -1); 13800 ao2_ref(peercnts, -1); 13801 ao2_ref(callno_limits, -1); 13802 ao2_ref(calltoken_ignores, -1); 13803 ao2_ref(callno_pool, -1); 13804 ao2_ref(callno_pool_trunk, -1); 13805 if (timer) { 13806 ast_timer_close(timer); 13807 } 13808 transmit_processor = ast_taskprocessor_unreference(transmit_processor); 13809 13810 con = ast_context_find(regcontext); 13811 if (con) 13812 ast_context_destroy(con, "IAX2"); 13813 ast_unload_realtime("iaxpeers"); 13814 return 0; 13815 }
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 14038 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 13524 of file chan_iax2.c.
References chan_iax2_pvt::addr, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::callno, LOG_ERROR, chan_iax2_pvt::osptoken, PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, and chan_iax2_pvt::username.
13525 { 13526 struct chan_iax2_pvt *pvt; 13527 unsigned int callno; 13528 int res = 0; 13529 13530 if (!chan || chan->tech != &iax2_tech) { 13531 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n"); 13532 return -1; 13533 } 13534 13535 callno = PTR_TO_CALLNO(chan->tech_pvt); 13536 ast_mutex_lock(&iaxsl[callno]); 13537 if (!(pvt = iaxs[callno])) { 13538 ast_mutex_unlock(&iaxsl[callno]); 13539 return -1; 13540 } 13541 13542 if (!strcasecmp(args, "osptoken")) { 13543 ast_copy_string(buf, pvt->osptoken, buflen); 13544 } else if (!strcasecmp(args, "peerip")) { 13545 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen); 13546 } else if (!strcasecmp(args, "peername")) { 13547 ast_copy_string(buf, pvt->username, buflen); 13548 } else { 13549 res = -1; 13550 } 13551 13552 ast_mutex_unlock(&iaxsl[callno]); 13553 13554 return res; 13555 }
| static int acf_channel_write | ( | struct ast_channel * | chan, | |
| const char * | function, | |||
| char * | data, | |||
| const char * | value | |||
| ) | [static] |
Definition at line 13496 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_string_field_set, chan_iax2_pvt::callno, LOG_ERROR, chan_iax2_pvt::osptoken, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.
13497 { 13498 struct chan_iax2_pvt *pvt; 13499 unsigned int callno; 13500 int res = 0; 13501 13502 if (!chan || chan->tech != &iax2_tech) { 13503 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n"); 13504 return -1; 13505 } 13506 13507 callno = PTR_TO_CALLNO(chan->tech_pvt); 13508 ast_mutex_lock(&iaxsl[callno]); 13509 if (!(pvt = iaxs[callno])) { 13510 ast_mutex_unlock(&iaxsl[callno]); 13511 return -1; 13512 } 13513 13514 if (!strcasecmp(args, "osptoken")) 13515 ast_string_field_set(pvt, osptoken, value); 13516 else 13517 res = -1; 13518 13519 ast_mutex_unlock(&iaxsl[callno]); 13520 13521 return res; 13522 }
| static int acf_iaxvar_read | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 9453 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, ast_var_t::name, ast_var_t::value, and var.
09454 { 09455 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09456 AST_LIST_HEAD(, ast_var_t) *varlist; 09457 struct ast_var_t *var; 09458 09459 if (!variablestore) { 09460 *buf = '\0'; 09461 return 0; 09462 } 09463 varlist = variablestore->data; 09464 09465 AST_LIST_LOCK(varlist); 09466 AST_LIST_TRAVERSE(varlist, var, entries) { 09467 if (strcmp(var->name, data) == 0) { 09468 ast_copy_string(buf, var->value, len); 09469 break; 09470 } 09471 } 09472 AST_LIST_UNLOCK(varlist); 09473 return 0; 09474 }
| static int acf_iaxvar_write | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| const char * | value | |||
| ) | [static] |
Definition at line 9476 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, ast_datastore::inheritance, LOG_ERROR, ast_var_t::name, and var.
09477 { 09478 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09479 AST_LIST_HEAD(, ast_var_t) *varlist; 09480 struct ast_var_t *var; 09481 09482 if (!variablestore) { 09483 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 09484 if (!variablestore) { 09485 ast_log(LOG_ERROR, "Memory allocation error\n"); 09486 return -1; 09487 } 09488 varlist = ast_calloc(1, sizeof(*varlist)); 09489 if (!varlist) { 09490 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09491 return -1; 09492 } 09493 09494 AST_LIST_HEAD_INIT(varlist); 09495 variablestore->data = varlist; 09496 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 09497 ast_channel_datastore_add(chan, variablestore); 09498 } else 09499 varlist = variablestore->data; 09500 09501 AST_LIST_LOCK(varlist); 09502 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) { 09503 if (strcmp(var->name, data) == 0) { 09504 AST_LIST_REMOVE_CURRENT(entries); 09505 ast_var_delete(var); 09506 break; 09507 } 09508 } 09509 AST_LIST_TRAVERSE_SAFE_END; 09510 var = ast_var_assign(data, value); 09511 if (var) 09512 AST_LIST_INSERT_TAIL(varlist, var, entries); 09513 else 09514 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09515 AST_LIST_UNLOCK(varlist); 09516 return 0; 09517 }
| static int add_calltoken_ignore | ( | const char * | addr | ) | [static] |
Definition at line 2377 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(), addr_range::delme, addr_range::ha, LOG_WARNING, and OBJ_POINTER.
Referenced by set_config().
02378 { 02379 struct addr_range tmp; 02380 struct addr_range *addr_range = NULL; 02381 struct ast_ha *ha = NULL; 02382 int error = 0; 02383 02384 if (ast_strlen_zero(addr)) { 02385 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr); 02386 return -1; 02387 } 02388 02389 ha = ast_append_ha("permit", addr, NULL, &error); 02390 02391 /* check for valid config information */ 02392 if (error) { 02393 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr); 02394 return -1; 02395 } 02396 02397 ast_copy_ha(ha, &tmp.ha); 02398 /* find or create the addr_range */ 02399 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) { 02400 ao2_lock(addr_range); 02401 addr_range->delme = 0; 02402 ao2_unlock(addr_range); 02403 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02404 /* copy over config data into addr_range object */ 02405 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */ 02406 ao2_link(calltoken_ignores, addr_range); 02407 } else { 02408 ast_free_ha(ha); 02409 return -1; 02410 } 02411 02412 ast_free_ha(ha); 02413 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02414 02415 return 0; 02416 }
| static void add_empty_calltoken_ie | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ie_data * | ied | |||
| ) | [static] |
Definition at line 4572 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().
04573 { 04574 /* first make sure their are two empty bytes left in ied->buf */ 04575 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) { 04576 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */ 04577 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */ 04578 pvt->calltoken_ie_len = 2; 04579 } 04580 }
| static int addr_range_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2039 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, addr_range::ha, ast_ha::netaddr, and ast_ha::netmask.
Referenced by load_objects().
02040 { 02041 struct addr_range *lim1 = obj, *lim2 = arg; 02042 return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) && 02043 (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ? 02044 CMP_MATCH | CMP_STOP : 0; 02045 }
| static int addr_range_delme_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2026 of file chan_iax2.c.
References addr_range::delme.
Referenced by set_config_destroy().
02027 { 02028 struct addr_range *lim = obj; 02029 lim->delme = 1; 02030 return 0; 02031 }
| static int addr_range_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 2033 of file chan_iax2.c.
References addr_range::ha, and ast_ha::netaddr.
Referenced by load_objects().
02034 { 02035 const struct addr_range *lim = obj; 02036 return abs((int) lim->ha.netaddr.s_addr); 02037 }
| static int addr_range_match_address_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2059 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, addr_range::ha, ast_ha::netaddr, and ast_ha::netmask.
Referenced by calltoken_required(), and set_peercnt_limit().
02060 { 02061 struct addr_range *addr_range = obj; 02062 struct sockaddr_in *sin = arg; 02063 02064 if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) { 02065 return CMP_MATCH | CMP_STOP; 02066 } 02067 return 0; 02068 }
| static int apply_context | ( | struct iax2_context * | con, | |
| const char * | context | |||
| ) | [static] |
Definition at line 7267 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
07268 { 07269 while(con) { 07270 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 07271 return -1; 07272 con = con->next; 07273 } 07274 return 0; 07275 }
| static int ast_cli_netstats | ( | struct mansession * | s, | |
| int | fd, | |||
| int | limit_fmt | |||
| ) | [static] |
Definition at line 6972 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, 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().
06973 { 06974 int x; 06975 int numchans = 0; 06976 char first_message[10] = { 0, }; 06977 char last_message[10] = { 0, }; 06978 #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" 06979 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" 06980 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 06981 ast_mutex_lock(&iaxsl[x]); 06982 if (iaxs[x]) { 06983 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 06984 jb_info jbinfo; 06985 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 06986 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 06987 06988 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 06989 jb_getinfo(iaxs[x]->jb, &jbinfo); 06990 localjitter = jbinfo.jitter; 06991 localdelay = jbinfo.current - jbinfo.min; 06992 locallost = jbinfo.frames_lost; 06993 locallosspct = jbinfo.losspct/1000; 06994 localdropped = jbinfo.frames_dropped; 06995 localooo = jbinfo.frames_ooo; 06996 } else { 06997 localjitter = -1; 06998 localdelay = 0; 06999 locallost = -1; 07000 locallosspct = -1; 07001 localdropped = 0; 07002 localooo = -1; 07003 } 07004 if (s) 07005 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07006 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07007 iaxs[x]->pingtime, 07008 localjitter, 07009 localdelay, 07010 locallost, 07011 locallosspct, 07012 localdropped, 07013 localooo, 07014 iaxs[x]->frames_received/1000, 07015 iaxs[x]->remote_rr.jitter, 07016 iaxs[x]->remote_rr.delay, 07017 iaxs[x]->remote_rr.losscnt, 07018 iaxs[x]->remote_rr.losspct, 07019 iaxs[x]->remote_rr.dropped, 07020 iaxs[x]->remote_rr.ooo, 07021 iaxs[x]->remote_rr.packets/1000, 07022 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07023 first_message, 07024 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07025 last_message); 07026 else 07027 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07028 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07029 iaxs[x]->pingtime, 07030 localjitter, 07031 localdelay, 07032 locallost, 07033 locallosspct, 07034 localdropped, 07035 localooo, 07036 iaxs[x]->frames_received/1000, 07037 iaxs[x]->remote_rr.jitter, 07038 iaxs[x]->remote_rr.delay, 07039 iaxs[x]->remote_rr.losscnt, 07040 iaxs[x]->remote_rr.losspct, 07041 iaxs[x]->remote_rr.dropped, 07042 iaxs[x]->remote_rr.ooo, 07043 iaxs[x]->remote_rr.packets/1000, 07044 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07045 first_message, 07046 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07047 last_message); 07048 numchans++; 07049 } 07050 ast_mutex_unlock(&iaxsl[x]); 07051 } 07052 07053 return numchans; 07054 }
| static struct ast_channel* ast_iax2_new | ( | int | callno, | |
| int | state, | |||
| int | capability, | |||
| const char * | linkedid | |||
| ) | [static, read] |
Create new call, interface with the PBX core.
Definition at line 5496 of file chan_iax2.c.
References chan_iax2_pvt::accountcode, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, 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(), 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, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, chan_iax2_pvt::cid_name, chan_iax2_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, chan_iax2_pvt::context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, chan_iax2_pvt::dnid, ast_var_t::entries, ast_channel::exten, chan_iax2_pvt::exten, chan_iax2_pvt::host, iax2_ami_channelupdate(), chan_iax2_pvt::iaxvars, ast_datastore::inheritance, chan_iax2_pvt::language, LOG_ERROR, LOG_WARNING, ast_channel::name, ast_variable::name, ast_channel::nativeformats, ast_variable::next, chan_iax2_pvt::owner, parkinglot, chan_iax2_pvt::parkinglot, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_channel::rawreadformat, ast_channel::rawwriteformat, chan_iax2_pvt::rdnis, ast_channel::readformat, ast_channel::tech, ast_channel::tech_pvt, ast_variable::value, var, chan_iax2_pvt::vars, and ast_channel::writeformat.
Referenced by iax2_request(), and socket_process().
05497 { 05498 struct ast_channel *tmp; 05499 struct chan_iax2_pvt *i; 05500 struct ast_variable *v = NULL; 05501 05502 if (!(i = iaxs[callno])) { 05503 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 05504 return NULL; 05505 } 05506 05507 /* Don't hold call lock */ 05508 ast_mutex_unlock(&iaxsl[callno]); 05509 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); 05510 ast_mutex_lock(&iaxsl[callno]); 05511 if (i != iaxs[callno]) { 05512 if (tmp) { 05513 /* unlock and relock iaxsl[callno] to preserve locking order */ 05514 ast_mutex_unlock(&iaxsl[callno]); 05515 tmp = ast_channel_release(tmp); 05516 ast_mutex_lock(&iaxsl[callno]); 05517 } 05518 return NULL; 05519 } 05520 iax2_ami_channelupdate(i); 05521 if (!tmp) 05522 return NULL; 05523 tmp->tech = &iax2_tech; 05524 /* We can support any format by default, until we get restricted */ 05525 tmp->nativeformats = capability; 05526 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 05527 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 05528 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 05529 05530 if (!ast_strlen_zero(i->parkinglot)) 05531 ast_string_field_set(tmp, parkinglot, i->parkinglot); 05532 /* Don't use ast_set_callerid() here because it will 05533 * generate a NewCallerID event before the NewChannel event */ 05534 if (!ast_strlen_zero(i->ani)) 05535 tmp->cid.cid_ani = ast_strdup(i->ani); 05536 else 05537 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05538 tmp->cid.cid_dnid = ast_strdup(i->dnid); 05539 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 05540 tmp->cid.cid_pres = i->calling_pres; 05541 tmp->cid.cid_ton = i->calling_ton; 05542 tmp->cid.cid_tns = i->calling_tns; 05543 if (!ast_strlen_zero(i->language)) 05544 ast_string_field_set(tmp, language, i->language); 05545 if (!ast_strlen_zero(i->accountcode)) 05546 ast_string_field_set(tmp, accountcode, i->accountcode); 05547 if (i->amaflags) 05548 tmp->amaflags = i->amaflags; 05549 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05550 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05551 if (i->adsi) 05552 tmp->adsicpe = i->peeradsicpe; 05553 else 05554 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05555 i->owner = tmp; 05556 i->capability = capability; 05557 05558 /* Set inherited variables */ 05559 if (i->vars) { 05560 for (v = i->vars ; v ; v = v->next) 05561 pbx_builtin_setvar_helper(tmp, v->name, v->value); 05562 } 05563 if (i->iaxvars) { 05564 struct ast_datastore *variablestore; 05565 struct ast_variable *var, *prev = NULL; 05566 AST_LIST_HEAD(, ast_var_t) *varlist; 05567 ast_debug(1, "Loading up the channel with IAXVARs\n"); 05568 varlist = ast_calloc(1, sizeof(*varlist)); 05569 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 05570 if (variablestore && varlist) { 05571 variablestore->data = varlist; 05572 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 05573 AST_LIST_HEAD_INIT(varlist); 05574 for (var = i->iaxvars; var; var = var->next) { 05575 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 05576 if (prev) 05577 ast_free(prev); 05578 prev = var; 05579 if (!newvar) { 05580 /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */ 05581 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 05582 } else { 05583 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 05584 } 05585 } 05586 if (prev) 05587 ast_free(prev); 05588 i->iaxvars = NULL; 05589 ast_channel_datastore_add(i->owner, variablestore); 05590 } else { 05591 if (variablestore) { 05592 ast_datastore_free(variablestore); 05593 } 05594 if (varlist) { 05595 ast_free(varlist); 05596 } 05597 } 05598 } 05599 05600 if (state != AST_STATE_DOWN) { 05601 if (ast_pbx_start(tmp)) { 05602 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05603 ast_hangup(tmp); 05604 i->owner = NULL; 05605 return NULL; 05606 } 05607 } 05608 05609 ast_module_ref(ast_module_info->self); 05610 return tmp; 05611 }
| static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3427 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and transmit_frame().
03428 { 03429 #ifdef SCHED_MULTITHREADED 03430 if (schedule_action(__attempt_transmit, data)) 03431 #endif 03432 __attempt_transmit(data); 03433 return 0; 03434 }
| static int auth_fail | ( | int | callno, | |
| int | failcode | |||
| ) | [static] |
Definition at line 8713 of file chan_iax2.c.
References auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, and iax2_sched_replace().
Referenced by socket_process().
08714 { 08715 /* Schedule sending the authentication failure in one second, to prevent 08716 guessing */ 08717 if (iaxs[callno]) { 08718 iaxs[callno]->authfail = failcode; 08719 if (delayreject) { 08720 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 08721 sched, 1000, auth_reject, (void *)(long)callno); 08722 } else 08723 auth_reject((void *)(long)callno); 08724 } 08725 return 0; 08726 }
| static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 8699 of file chan_iax2.c.
References __auth_reject(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::authid, and schedule_action.
Referenced by auth_fail().
08700 { 08701 int callno = (int)(long)(data); 08702 ast_mutex_lock(&iaxsl[callno]); 08703 if (iaxs[callno]) 08704 iaxs[callno]->authid = -1; 08705 ast_mutex_unlock(&iaxsl[callno]); 08706 #ifdef SCHED_MULTITHREADED 08707 if (schedule_action(__auth_reject, data)) 08708 #endif 08709 __auth_reject(data); 08710 return 0; 08711 }
| 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 7835 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, MD5Final(), MD5Init(), and MD5Update().
Referenced by action_login(), authenticate_reply(), and registry_rerequest().
07836 { 07837 int res = -1; 07838 int x; 07839 if (!ast_strlen_zero(keyn)) { 07840 if (!(authmethods & IAX_AUTH_RSA)) { 07841 if (ast_strlen_zero(secret)) 07842 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)); 07843 } else if (ast_strlen_zero(challenge)) { 07844 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 07845 } else { 07846 char sig[256]; 07847 struct ast_key *key; 07848 key = ast_key_get(keyn, AST_KEY_PRIVATE); 07849 if (!key) { 07850 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 07851 } else { 07852 if (ast_sign(key, (char*)challenge, sig)) { 07853 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 07854 res = -1; 07855 } else { 07856 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 07857 res = 0; 07858 } 07859 } 07860 } 07861 } 07862 /* Fall back */ 07863 if (res && !ast_strlen_zero(secret)) { 07864 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 07865 struct MD5Context md5; 07866 unsigned char digest[16]; 07867 char digres[128]; 07868 MD5Init(&md5); 07869 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 07870 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 07871 MD5Final(digest, &md5); 07872 /* If they support md5, authenticate with it. */ 07873 for (x=0;x<16;x++) 07874 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 07875 if (pvt) { 07876 build_encryption_keys(digest, pvt); 07877 } 07878 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 07879 res = 0; 07880 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 07881 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 07882 res = 0; 07883 } else 07884 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 07885 } 07886 return res; 07887 }
| 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 7893 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_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_var_assign(), authenticate(), iax_ies::authmethods, iax2_peer::authmethods, iax_ie_data::buf, chan_iax2_pvt::callno, chan_iax2_pvt::challenge, iax_ies::challenge, ast_datastore::data, DATASTORE_INHERIT_FOREVER, chan_iax2_pvt::encmethods, iax_ies::encmethods, ast_var_t::entries, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_FORCE_ENCRYPT, IAX_KEYPOPULATED, ast_datastore::inheritance, LOG_ERROR, LOG_NOTICE, iax2_peer::mask, merge_encryption(), ast_variable::name, iax2_peer::name, ast_variable::next, iax2_peer::outkey, chan_iax2_pvt::owner, chan_iax2_pvt::peer, peer_unref(), iax_ie_data::pos, realtime_peer(), iax2_peer::secret, send_command(), chan_iax2_pvt::username, iax2_peer::username, iax_ies::username, ast_variable::value, var, and iax_ies::vars.
Referenced by socket_process().
07894 { 07895 struct iax2_peer *peer = NULL; 07896 /* Start pessimistic */ 07897 int res = -1; 07898 int authmethods = 0; 07899 struct iax_ie_data ied; 07900 uint16_t callno = p->callno; 07901 07902 memset(&ied, 0, sizeof(ied)); 07903 07904 if (ies->username) 07905 ast_string_field_set(p, username, ies->username); 07906 if (ies->challenge) 07907 ast_string_field_set(p, challenge, ies->challenge); 07908 if (ies->authmethods) 07909 authmethods = ies->authmethods; 07910 if (authmethods & IAX_AUTH_MD5) 07911 merge_encryption(p, ies->encmethods); 07912 else 07913 p->encmethods = 0; 07914 07915 /* Check for override RSA authentication first */ 07916 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 07917 /* Normal password authentication */ 07918 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 07919 } else { 07920 struct ao2_iterator i = ao2_iterator_init(peers, 0); 07921 while ((peer = ao2_iterator_next(&i))) { 07922 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 07923 /* No peer specified at our end, or this is the peer */ 07924 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 07925 /* No username specified in peer rule, or this is the right username */ 07926 && (!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))) 07927 /* No specified host, or this is our host */ 07928 ) { 07929 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 07930 if (!res) { 07931 peer_unref(peer); 07932 break; 07933 } 07934 } 07935 peer_unref(peer); 07936 } 07937 ao2_iterator_destroy(&i); 07938 if (!peer) { 07939 /* We checked our list and didn't find one. It's unlikely, but possible, 07940 that we're trying to authenticate *to* a realtime peer */ 07941 const char *peer_name = ast_strdupa(p->peer); 07942 ast_mutex_unlock(&iaxsl[callno]); 07943 if ((peer = realtime_peer(peer_name, NULL))) { 07944 ast_mutex_lock(&iaxsl[callno]); 07945 if (!(p = iaxs[callno])) { 07946 peer_unref(peer); 07947 return -1; 07948 } 07949 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 07950 peer_unref(peer); 07951 } 07952 if (!peer) { 07953 ast_mutex_lock(&iaxsl[callno]); 07954 if (!(p = iaxs[callno])) 07955 return -1; 07956 } 07957 } 07958 } 07959 07960 if (ies->encmethods) { 07961 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 07962 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 07963 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set"); 07964 return -1; /* if force encryption is yes, and no encryption methods, then return -1 to hangup */ 07965 } 07966 if (!res) { 07967 struct ast_datastore *variablestore; 07968 struct ast_variable *var, *prev = NULL; 07969 AST_LIST_HEAD(, ast_var_t) *varlist; 07970 varlist = ast_calloc(1, sizeof(*varlist)); 07971 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 07972 if (variablestore && varlist && p->owner) { 07973 variablestore->data = varlist; 07974 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 07975 AST_LIST_HEAD_INIT(varlist); 07976 for (var = ies->vars; var; var = var->next) { 07977 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 07978 if (prev) 07979 ast_free(prev); 07980 prev = var; 07981 if (!newvar) { 07982 /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */ 07983 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 07984 } else { 07985 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 07986 } 07987 } 07988 if (prev) 07989 ast_free(prev); 07990 ies->vars = NULL; 07991 ast_channel_datastore_add(p->owner, variablestore); 07992 } else { 07993 if (p->owner) 07994 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 07995 if (variablestore) 07996 ast_datastore_free(variablestore); 07997 if (varlist) 07998 ast_free(varlist); 07999 } 08000 } 08001 08002 if (!res) 08003 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 08004 return res; 08005 }
| static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 7543 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, iax_ie_data::buf, chan_iax2_pvt::challenge, iax2_user::curauthreq, 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, iax2_user::maxauthreq, OBJ_POINTER, iax_ie_data::pos, send_command(), send_command_final(), user_unref(), and chan_iax2_pvt::username.
Referenced by socket_process().
07544 { 07545 struct iax_ie_data ied; 07546 int res = -1, authreq_restrict = 0; 07547 char challenge[10]; 07548 struct chan_iax2_pvt *p = iaxs[call_num]; 07549 07550 memset(&ied, 0, sizeof(ied)); 07551 07552 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 07553 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07554 struct iax2_user *user, tmp_user = { 07555 .name = p->username, 07556 }; 07557 07558 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07559 if (user) { 07560 if (user->curauthreq == user->maxauthreq) 07561 authreq_restrict = 1; 07562 else 07563 user->curauthreq++; 07564 user = user_unref(user); 07565 } 07566 } 07567 07568 /* If the AUTHREQ limit test failed, send back an error */ 07569 if (authreq_restrict) { 07570 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 07571 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 07572 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 07573 return 0; 07574 } 07575 07576 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 07577 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 07578 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 07579 ast_string_field_set(p, challenge, challenge); 07580 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 07581 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 07582 } 07583 if (p->encmethods) 07584 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 07585 07586 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 07587 07588 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 07589 07590 if (p->encmethods) 07591 ast_set_flag64(p, IAX_ENCRYPTED); 07592 07593 return res; 07594 }
| static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 7596 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, iax2_user::curauthreq, 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, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_user::name, OBJ_POINTER, iax_ies::password, iax_ies::rsa_result, chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, strsep(), user_unref(), and chan_iax2_pvt::username.
Referenced by socket_process().
07597 { 07598 char requeststr[256]; 07599 char md5secret[256] = ""; 07600 char secret[256] = ""; 07601 char rsasecret[256] = ""; 07602 int res = -1; 07603 int x; 07604 struct iax2_user *user, tmp_user = { 07605 .name = p->username, 07606 }; 07607 07608 if (p->authrej) { 07609 return res; 07610 } 07611 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07612 if (user) { 07613 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07614 ast_atomic_fetchadd_int(&user->curauthreq, -1); 07615 ast_clear_flag64(p, IAX_MAXAUTHREQ); 07616 } 07617 ast_string_field_set(p, host, user->name); 07618 user = user_unref(user); 07619 } 07620 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) { 07621 ast_log(LOG_NOTICE, "Call Terminated, Incomming call is unencrypted while force encrypt is enabled."); 07622 return res; 07623 } 07624 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 07625 return res; 07626 if (ies->password) 07627 ast_copy_string(secret, ies->password, sizeof(secret)); 07628 if (ies->md5_result) 07629 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07630 if (ies->rsa_result) 07631 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07632 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 07633 struct ast_key *key; 07634 char *keyn; 07635 char tmpkey[256]; 07636 char *stringp=NULL; 07637 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 07638 stringp=tmpkey; 07639 keyn = strsep(&stringp, ":"); 07640 while(keyn) { 07641 key = ast_key_get(keyn, AST_KEY_PUBLIC); 07642 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 07643 res = 0; 07644 break; 07645 } else if (!key) 07646 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 07647 keyn = strsep(&stringp, ":"); 07648 } 07649 } else if (p->authmethods & IAX_AUTH_MD5) { 07650 struct MD5Context md5; 07651 unsigned char digest[16]; 07652 char *tmppw, *stringp; 07653 07654 tmppw = ast_strdupa(p->secret); 07655 stringp = tmppw; 07656 while((tmppw = strsep(&stringp, ";"))) { 07657 MD5Init(&md5); 07658 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 07659 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 07660 MD5Final(digest, &md5); 07661 /* If they support md5, authenticate with it. */ 07662 for (x=0;x<16;x++) 07663 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 07664 if (!strcasecmp(requeststr, md5secret)) { 07665 res = 0; 07666 break; 07667 } 07668 } 07669 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 07670 if (!strcmp(secret, p->secret)) 07671 res = 0; 07672 } 07673 return res; 07674 }
| static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 4511 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), sip_call(), and sip_show_sched().
04512 { 04513 #ifdef SCHED_MULTITHREADED 04514 if (schedule_action(__auto_congest, data)) 04515 #endif 04516 __auto_congest(data); 04517 return 0; 04518 }
| static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 8743 of file chan_iax2.c.
References __auto_hangup(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::autoid, and schedule_action.
Referenced by iax2_dprequest(), and iax2_provision().
08744 { 08745 int callno = (int)(long)(data); 08746 ast_mutex_lock(&iaxsl[callno]); 08747 if (iaxs[callno]) { 08748 iaxs[callno]->autoid = -1; 08749 } 08750 ast_mutex_unlock(&iaxsl[callno]); 08751 #ifdef SCHED_MULTITHREADED 08752 if (schedule_action(__auto_hangup, data)) 08753 #endif 08754 __auto_hangup(data); 08755 return 0; 08756 }
| static void build_callno_limits | ( | struct ast_variable * | v | ) | [static] |
Definition at line 2322 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(), addr_range::delme, addr_range::ha, addr_range::limit, LOG_ERROR, ast_variable::name, ast_variable::next, OBJ_POINTER, and ast_variable::value.
Referenced by set_config().
02323 { 02324 struct addr_range *addr_range = NULL; 02325 struct addr_range tmp; 02326 struct ast_ha *ha; 02327 int limit; 02328 int error; 02329 int found; 02330 02331 for (; v; v = v->next) { 02332 limit = -1; 02333 error = 0; 02334 found = 0; 02335 ha = ast_append_ha("permit", v->name, NULL, &error); 02336 02337 /* check for valid config information */ 02338 if (error) { 02339 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name); 02340 continue; 02341 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) { 02342 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value); 02343 ast_free_ha(ha); 02344 continue; 02345 } 02346 02347 ast_copy_ha(ha, &tmp.ha); 02348 /* find or create the addr_range */ 02349 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) { 02350 ao2_lock(addr_range); 02351 found = 1; 02352 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02353 ast_free_ha(ha); 02354 return; /* out of memory */ 02355 } 02356 02357 /* copy over config data into addr_range object */ 02358 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */ 02359 ast_free_ha(ha); /* cleanup the tmp ha */ 02360 addr_range->limit = limit; 02361 addr_range->delme = 0; 02362 02363 /* cleanup */ 02364 if (found) { 02365 ao2_unlock(addr_range); 02366 } else { 02367 ao2_link(callno_limits, addr_range); 02368 } 02369 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02370 } 02371 }
| static struct iax2_context* build_context | ( | const char * | context | ) | [static, read] |
Definition at line 11796 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), and iax2_context::context.
Referenced by build_user().
11797 { 11798 struct iax2_context *con; 11799 11800 if ((con = ast_calloc(1, sizeof(*con)))) 11801 ast_copy_string(con->context, context, sizeof(con->context)); 11802 11803 return con; 11804 }
| static void build_ecx_key | ( | const unsigned char * | digest, | |
| struct chan_iax2_pvt * | pvt | |||
| ) | [static] |
Definition at line 5954 of file chan_iax2.c.
References ast_aes_decrypt_key, ast_aes_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().
05955 { 05956 /* it is required to hold the corresponding decrypt key to our encrypt key 05957 * in the pvt struct because queued frames occasionally need to be decrypted and 05958 * re-encrypted when updated for a retransmission */ 05959 build_rand_pad(pvt->semirand, sizeof(pvt->semirand)); 05960 ast_aes_encrypt_key(digest, &pvt->ecx); 05961 ast_aes_decrypt_key(digest, &pvt->mydcx); 05962 }
| static void build_encryption_keys | ( | const unsigned char * | digest, | |
| struct chan_iax2_pvt * | pvt | |||
| ) | [static] |
Definition at line 5948 of file chan_iax2.c.
References ast_aes_decrypt_key, build_ecx_key(), and chan_iax2_pvt::dcx.
Referenced by authenticate(), and decrypt_frame().
05949 { 05950 build_ecx_key(digest, pvt); 05951 ast_aes_decrypt_key(digest, &pvt->dcx); 05952 }
| static struct iax2_peer * build_peer | ( | const char * | name, | |
| struct ast_variable * | v, | |||
| struct ast_variable * | alt, | |||
| int | temponly | |||
| ) | [static, read] |
Create peer structure based on configuration.
Definition at line 11944 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, 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_strdupa, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_true(), iax2_peer::authmethods, CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_peer::calltoken_required, CALLTOKEN_YES, iax2_peer::capability, cid_name, cid_num, context, iax2_peer::dbsecret, iax2_peer::defaddr, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, iax2_peer::dnsmgr, iax2_peer::encmethods, iax2_peer::expire, iax2_peer::expiry, get_auth_methods(), get_encrypt_methods(), 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(), iax2_peer::inkeys, ast_variable::lineno, LOG_WARNING, iax2_peer::mailbox, mailbox, iax2_peer::mask, iax2_peer::maxcallno, iax2_peer::maxms, mwi_event_cb(), iax2_peer::mwi_event_sub, ast_variable::name, iax2_peer::name, ast_variable::next, OBJ_POINTER, iax2_peer::outkey, peer_destructor(), peer_set_srcaddr(), peer_unref(), peercnt_modify(), iax2_peer::peercontext, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, prefs, iax2_peer::prefs, iax2_peer::regexten, S_OR, secret, iax2_peer::smoothing, iax2_peer::sockfd, strsep(), unlink_peer(), ast_variable::value, and zonetag.
11945 { 11946 struct iax2_peer *peer = NULL; 11947 struct ast_ha *oldha = NULL; 11948 int maskfound = 0; 11949 int found = 0; 11950 int firstpass = 1; 11951 struct iax2_peer tmp_peer = { 11952 .name = name, 11953 }; 11954 11955 if (!temponly) { 11956 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 11957 if (peer && !ast_test_flag64(peer, IAX_DELME)) 11958 firstpass = 0; 11959 } 11960 11961 if (peer) { 11962 found++; 11963 if (firstpass) { 11964 oldha = peer->ha; 11965 peer->ha = NULL; 11966 } 11967 unlink_peer(peer); 11968 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 11969 peer->expire = -1; 11970 peer->pokeexpire = -1; 11971 peer->sockfd = defaultsockfd; 11972 if (ast_string_field_init(peer, 32)) 11973 peer = peer_unref(peer); 11974 } 11975 11976 if (peer) { 11977 if (firstpass) { 11978 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 11979 peer->encmethods = iax2_encryption; 11980 peer->adsi = adsi; 11981 ast_string_field_set(peer,secret,""); 11982 if (!found) { 11983 ast_string_field_set(peer, name, name); 11984 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 11985 peer->expiry = min_reg_expire; 11986 } 11987 peer->prefs = prefs; 11988 peer->capability = iax2_capability; 11989 peer->smoothing = 0; 11990 peer->pokefreqok = DEFAULT_FREQ_OK; 11991 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 11992 peer->maxcallno = 0; 11993 peercnt_modify(0, 0, &peer->addr); 11994 peer->calltoken_required = CALLTOKEN_DEFAULT; 11995 ast_string_field_set(peer,context,""); 11996 ast_string_field_set(peer,peercontext,""); 11997 ast_clear_flag64(peer, IAX_HASCALLERID); 11998 ast_string_field_set(peer, cid_name, ""); 11999 ast_string_field_set(peer, cid_num, ""); 12000 ast_string_field_set(peer, mohinterpret, mohinterpret); 12001 ast_string_field_set(peer, mohsuggest, mohsuggest); 12002 } 12003 12004 if (!v) { 12005 v = alt; 12006 alt = NULL; 12007 } 12008 while(v) { 12009 if (!strcasecmp(v->name, "secret")) { 12010 ast_string_field_set(peer, secret, v->value); 12011 } else if (!strcasecmp(v->name, "mailbox")) { 12012 ast_string_field_set(peer, mailbox, v->value); 12013 } else if (!strcasecmp(v->name, "hasvoicemail")) { 12014 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 12015 ast_string_field_set(peer, mailbox, name); 12016 } 12017 } else if (!strcasecmp(v->name, "mohinterpret")) { 12018 ast_string_field_set(peer, mohinterpret, v->value); 12019 } else if (!strcasecmp(v->name, "mohsuggest")) { 12020 ast_string_field_set(peer, mohsuggest, v->value); 12021 } else if (!strcasecmp(v->name, "dbsecret")) { 12022 ast_string_field_set(peer, dbsecret, v->value); 12023 } else if (!strcasecmp(v->name, "trunk")) { 12024 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK); 12025 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) { 12026 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name); 12027 ast_clear_flag64(peer, IAX_TRUNK); 12028 } 12029 } else if (!strcasecmp(v->name, "auth")) { 12030 peer->authmethods = get_auth_methods(v->value); 12031 } else if (!strcasecmp(v->name, "encryption")) { 12032 peer->encmethods |= get_encrypt_methods(v->value); 12033 if (!peer->encmethods) { 12034 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12035 } 12036 } else if (!strcasecmp(v->name, "forceencryption")) { 12037 if (ast_false(v->value)) { 12038 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12039 } else { 12040 peer->encmethods |= get_encrypt_methods(v->value); 12041 if (peer->encmethods) { 12042 ast_set_flag64(peer, IAX_FORCE_ENCRYPT); 12043 } 12044 } 12045 } else if (!strcasecmp(v->name, "transfer")) { 12046 if (!strcasecmp(v->value, "mediaonly")) { 12047 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12048 } else if (ast_true(v->value)) { 12049 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12050 } else 12051 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12052 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12053 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF); 12054 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12055 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 12056 } else if (!strcasecmp(v->name, "host")) { 12057 if (!strcasecmp(v->value, "dynamic")) { 12058 /* They'll register with us */ 12059 ast_set_flag64(peer, IAX_DYNAMIC); 12060 if (!found) { 12061 /* Initialize stuff iff we're not found, otherwise 12062 we keep going with what we had */ 12063 memset(&peer->addr.sin_addr, 0, 4); 12064 if (peer->addr.sin_port) { 12065 /* If we've already got a port, make it the default rather than absolute */ 12066 peer->defaddr.sin_port = peer->addr.sin_port; 12067 peer->addr.sin_port = 0; 12068 } 12069 } 12070 } else { 12071 /* Non-dynamic. Make sure we become that way if we're not */ 12072 ast_sched_thread_del(sched, peer->expire); 12073 ast_clear_flag64(peer, IAX_DYNAMIC); 12074 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) 12075 return peer_unref(peer); 12076 if (!peer->addr.sin_port) 12077 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 12078 } 12079 if (!maskfound) 12080 inet_aton("255.255.255.255", &peer->mask); 12081 } else if (!strcasecmp(v->name, "defaultip")) { 12082 if (ast_get_ip(&peer->defaddr, v->value)) 12083 return peer_unref(peer); 12084 } else if (!strcasecmp(v->name, "sourceaddress")) { 12085 peer_set_srcaddr(peer, v->value); 12086 } else if (!strcasecmp(v->name, "permit") || 12087 !strcasecmp(v->name, "deny")) { 12088 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL); 12089 } else if (!strcasecmp(v->name, "mask")) { 12090 maskfound++; 12091 inet_aton(v->value, &peer->mask); 12092 } else if (!strcasecmp(v->name, "context")) { 12093 ast_string_field_set(peer, context, v->value); 12094 } else if (!strcasecmp(v->name, "regexten")) { 12095 ast_string_field_set(peer, regexten, v->value); 12096 } else if (!strcasecmp(v->name, "peercontext")) { 12097 ast_string_field_set(peer, peercontext, v->value); 12098 } else if (!strcasecmp(v->name, "port")) { 12099 if (ast_test_flag64(peer, IAX_DYNAMIC)) 12100 peer->defaddr.sin_port = htons(atoi(v->value)); 12101 else 12102 peer->addr.sin_port = htons(atoi(v->value)); 12103 } else if (!strcasecmp(v->name, "username")) { 12104 ast_string_field_set(peer, username, v->value); 12105 } else if (!strcasecmp(v->name, "allow")) { 12106 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 12107 } else if (!strcasecmp(v->name, "disallow")) { 12108 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 12109 } else if (!strcasecmp(v->name, "callerid")) { 12110 if (!ast_strlen_zero(v->value)) { 12111 char name2[80]; 12112 char num2[80]; 12113 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12114 ast_string_field_set(peer, cid_name, name2); 12115 ast_string_field_set(peer, cid_num, num2); 12116 } else { 12117 ast_string_field_set(peer, cid_name, ""); 12118 ast_string_field_set(peer, cid_num, ""); 12119 } 12120 ast_set_flag64(peer, IAX_HASCALLERID); 12121 } else if (!strcasecmp(v->name, "fullname")) { 12122 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 12123 ast_set_flag64(peer, IAX_HASCALLERID); 12124 } else if (!strcasecmp(v->name, "cid_number")) { 12125 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 12126 ast_set_flag64(peer, IAX_HASCALLERID); 12127 } else if (!strcasecmp(v->name, "sendani")) { 12128 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI); 12129 } else if (!strcasecmp(v->name, "inkeys")) { 12130 ast_string_field_set(peer, inkeys, v->value); 12131 } else if (!strcasecmp(v->name, "outkey")) { 12132 ast_string_field_set(peer, outkey, v->value); 12133 } else if (!strcasecmp(v->name, "qualify")) { 12134 if (!strcasecmp(v->value, "no")) { 12135 peer->maxms = 0; 12136 } else if (!strcasecmp(v->value, "yes")) { 12137 peer->maxms = DEFAULT_MAXMS; 12138 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 12139 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); 12140 peer->maxms = 0; 12141 } 12142 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 12143 peer->smoothing = ast_true(v->value); 12144 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 12145 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) { 12146 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); 12147 } 12148 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 12149 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) { 12150 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); 12151 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 12152 } else if (!strcasecmp(v->name, "timezone")) { 12153 ast_string_field_set(peer, zonetag, v->value); 12154 } else if (!strcasecmp(v->name, "adsi")) { 12155 peer->adsi = ast_true(v->value); 12156 } else if (!strcasecmp(v->name, "connectedline")) { 12157 if (ast_true(v->value)) { 12158 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12159 } else if (!strcasecmp(v->value, "send")) { 12160 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE); 12161 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE); 12162 } else if (!strcasecmp(v->value, "receive")) { 12163 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE); 12164 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE); 12165 } else { 12166 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12167 } 12168 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 12169 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) { 12170 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 12171 } else { 12172 peercnt_modify(1, peer->maxcallno, &peer->addr); 12173 } 12174 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12175 /* default is required unless in optional ip list */ 12176 if (ast_false(v->value)) { 12177 peer->calltoken_required = CALLTOKEN_NO; 12178 } else if (!strcasecmp(v->value, "auto")) { 12179 peer->calltoken_required = CALLTOKEN_AUTO; 12180 } else if (ast_true(v->value)) { 12181 peer->calltoken_required = CALLTOKEN_YES; 12182 } else { 12183 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12184 } 12185 } /* else if (strcasecmp(v->name,"type")) */ 12186 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12187 v = v->next; 12188 if (!v) { 12189 v = alt; 12190 alt = NULL; 12191 } 12192 } 12193 if (!peer->authmethods) 12194 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12195 ast_clear_flag64(peer, IAX_DELME); 12196 /* Make sure these are IPv4 addresses */ 12197 peer->addr.sin_family = AF_INET; 12198 } 12199 12200 if (oldha) 12201 ast_free_ha(oldha); 12202 12203 if (!ast_strlen_zero(peer->mailbox)) { 12204 char *mailbox, *context; 12205 context = mailbox = ast_strdupa(peer->mailbox); 12206 strsep(&context, "@"); 12207 if (ast_strlen_zero(context)) 12208 context = "default"; 12209 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL, 12210 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 12211 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 12212 AST_EVENT_IE_END); 12213 } 12214 12215 return peer; 12216 }
| static void build_rand_pad | ( | unsigned char * | buf, | |
| ssize_t | len | |||
| ) | [static] |
Definition at line 5938 of file chan_iax2.c.
References ast_random().
Referenced by build_ecx_key(), and update_packet().
05939 { 05940 long tmp; 05941 for (tmp = ast_random(); len > 0; tmp = ast_random()) { 05942 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len); 05943 buf += sizeof(tmp); 05944 len -= sizeof(tmp); 05945 } 05946 }
| static struct iax2_user * build_user | ( | const char * | name, | |
| struct ast_variable * | v, | |||
| struct ast_variable * | alt, | |||
| int | temponly | |||
| ) | [static, read] |
Create in-memory user structure from configuration.
Definition at line 12232 of file chan_iax2.c.
References iax2_user::adsi, iax2_user::amaflags, 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(), iax2_user::authmethods, build_context(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_user::calltoken_required, CALLTOKEN_YES, iax2_user::capability, iax2_user::cid_name, cid_name, iax2_user::cid_num, cid_num, cleanup(), iax2_user::contexts, iax2_user::curauthreq, iax2_user::dbsecret, iax2_user::encmethods, format, free_context(), get_auth_methods(), get_encrypt_methods(), iax2_user::ha, 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, iax2_user::maxauthreq, ast_variable::name, iax2_user::name, ast_variable::next, iax2_context::next, OBJ_POINTER, parkinglot, prefs, iax2_user::prefs, secret, iax2_user::secret, user_destructor(), user_unref(), ast_variable::value, and iax2_user::vars.
12233 { 12234 struct iax2_user *user = NULL; 12235 struct iax2_context *con, *conl = NULL; 12236 struct ast_ha *oldha = NULL; 12237 struct iax2_context *oldcon = NULL; 12238 int format; 12239 int firstpass=1; 12240 int oldcurauthreq = 0; 12241 char *varname = NULL, *varval = NULL; 12242 struct ast_variable *tmpvar = NULL; 12243 struct iax2_user tmp_user = { 12244 .name = name, 12245 }; 12246 12247 if (!temponly) { 12248 user = ao2_find(users, &tmp_user, OBJ_POINTER); 12249 if (user && !ast_test_flag64(user, IAX_DELME)) 12250 firstpass = 0; 12251 } 12252 12253 if (user) { 12254 if (firstpass) { 12255 oldcurauthreq = user->curauthreq; 12256 oldha = user->ha; 12257 oldcon = user->contexts; 12258 user->ha = NULL; 12259 user->contexts = NULL; 12260 } 12261 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12262 ao2_unlink(users, user); 12263 } else { 12264 user = ao2_alloc(sizeof(*user), user_destructor); 12265 } 12266 12267 if (user) { 12268 if (firstpass) { 12269 ast_string_field_free_memory(user); 12270 memset(user, 0, sizeof(struct iax2_user)); 12271 if (ast_string_field_init(user, 32)) { 12272 user = user_unref(user); 12273 goto cleanup; 12274 } 12275 user->maxauthreq = maxauthreq; 12276 user->curauthreq = oldcurauthreq; 12277 user->prefs = prefs; 12278 user->capability = iax2_capability; 12279 user->encmethods = iax2_encryption; 12280 user->adsi = adsi; 12281 user->calltoken_required = CALLTOKEN_DEFAULT; 12282 ast_string_field_set(user, name, name); 12283 ast_string_field_set(user, language, language); 12284 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); 12285 ast_clear_flag64(user, IAX_HASCALLERID); 12286 ast_string_field_set(user, cid_name, ""); 12287 ast_string_field_set(user, cid_num, ""); 12288 ast_string_field_set(user, accountcode, accountcode); 12289 ast_string_field_set(user, mohinterpret, mohinterpret); 12290 ast_string_field_set(user, mohsuggest, mohsuggest); 12291 } 12292 if (!v) { 12293 v = alt; 12294 alt = NULL; 12295 } 12296 while(v) { 12297 if (!strcasecmp(v->name, "context")) { 12298 con = build_context(v->value); 12299 if (con) { 12300 if (conl) 12301 conl->next = con; 12302 else 12303 user->contexts = con; 12304 conl = con; 12305 } 12306 } else if (!strcasecmp(v->name, "permit") || 12307 !strcasecmp(v->name, "deny")) { 12308 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL); 12309 } else if (!strcasecmp(v->name, "setvar")) { 12310 varname = ast_strdupa(v->value); 12311 if (varname && (varval = strchr(varname,'='))) { 12312 *varval = '\0'; 12313 varval++; 12314 if((tmpvar = ast_variable_new(varname, varval, ""))) { 12315 tmpvar->next = user->vars; 12316 user->vars = tmpvar; 12317 } 12318 } 12319 } else if (!strcasecmp(v->name, "allow")) { 12320 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 12321 } else if (!strcasecmp(v->name, "disallow")) { 12322 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 12323 } else if (!strcasecmp(v->name, "trunk")) { 12324 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK); 12325 if (ast_test_flag64(user, IAX_TRUNK) && !timer) { 12326 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name); 12327 ast_clear_flag64(user, IAX_TRUNK); 12328 } 12329 } else if (!strcasecmp(v->name, "auth")) { 12330 user->authmethods = get_auth_methods(v->value); 12331 } else if (!strcasecmp(v->name, "encryption")) { 12332 user->encmethods |= get_encrypt_methods(v->value); 12333 if (!user->encmethods) { 12334 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 12335 } 12336 } else if (!strcasecmp(v->name, "forceencryption")) { 12337 if (ast_false(v->value)) { 12338 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 12339 } else { 12340 user->encmethods |= get_encrypt_methods(v->value); 12341 if (user->encmethods) { 12342 ast_set_flag64(user, IAX_FORCE_ENCRYPT); 12343 } 12344 } 12345 } else if (!strcasecmp(v->name, "transfer")) { 12346 if (!strcasecmp(v->value, "mediaonly")) { 12347 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12348 } else if (ast_true(v->value)) { 12349 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12350 } else 12351 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12352 } else if (!strcasecmp(v->name, "codecpriority")) { 12353 if(!strcasecmp(v->value, "caller")) 12354 ast_set_flag64(user, IAX_CODEC_USER_FIRST); 12355 else if(!strcasecmp(v->value, "disabled")) 12356 ast_set_flag64(user, IAX_CODEC_NOPREFS); 12357 else if(!strcasecmp(v->value, "reqonly")) { 12358 ast_set_flag64(user, IAX_CODEC_NOCAP); 12359 ast_set_flag64(user, IAX_CODEC_NOPREFS); 12360 } 12361 } else if (!strcasecmp(v->name, "immediate")) { 12362 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE); 12363 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12364 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF); 12365 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12366 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF); 12367 } else if (!strcasecmp(v->name, "dbsecret")) { 12368 ast_string_field_set(user, dbsecret, v->value); 12369 } else if (!strcasecmp(v->name, "secret")) { 12370 if (!ast_strlen_zero(user->secret)) { 12371 char *old = ast_strdupa(user->secret); 12372 12373 ast_string_field_build(user, secret, "%s;%s", old, v->value); 12374 } else 12375 ast_string_field_set(user, secret, v->value); 12376 } else if (!strcasecmp(v->name, "callerid")) { 12377 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 12378 char name2[80]; 12379 char num2[80]; 12380 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12381 ast_string_field_set(user, cid_name, name2); 12382 ast_string_field_set(user, cid_num, num2); 12383 ast_set_flag64(user, IAX_HASCALLERID); 12384 } else { 12385 ast_clear_flag64(user, IAX_HASCALLERID); 12386 ast_string_field_set(user, cid_name, ""); 12387 ast_string_field_set(user, cid_num, ""); 12388 } 12389 } else if (!strcasecmp(v->name, "fullname")) { 12390 if (!ast_strlen_zero(v->value)) { 12391 ast_string_field_set(user, cid_name, v->value); 12392 ast_set_flag64(user, IAX_HASCALLERID); 12393 } else { 12394 ast_string_field_set(user, cid_name, ""); 12395 if (ast_strlen_zero(user->cid_num)) 12396 ast_clear_flag64(user, IAX_HASCALLERID); 12397 } 12398 } else if (!strcasecmp(v->name, "cid_number")) { 12399 if (!ast_strlen_zero(v->value)) { 12400 ast_string_field_set(user, cid_num, v->value); 12401 ast_set_flag64(user, IAX_HASCALLERID); 12402 } else { 12403 ast_string_field_set(user, cid_num, ""); 12404 if (ast_strlen_zero(user->cid_name)) 12405 ast_clear_flag64(user, IAX_HASCALLERID); 12406 } 12407 } else if (!strcasecmp(v->name, "accountcode")) { 12408 ast_string_field_set(user, accountcode, v->value); 12409 } else if (!strcasecmp(v->name, "mohinterpret")) { 12410 ast_string_field_set(user, mohinterpret, v->value); 12411 } else if (!strcasecmp(v->name, "mohsuggest")) { 12412 ast_string_field_set(user, mohsuggest, v->value); 12413 } else if (!strcasecmp(v->name, "parkinglot")) { 12414 ast_string_field_set(user, parkinglot, v->value); 12415 } else if (!strcasecmp(v->name, "language")) { 12416 ast_string_field_set(user, language, v->value); 12417 } else if (!strcasecmp(v->name, "amaflags")) { 12418 format = ast_cdr_amaflags2int(v->value); 12419 if (format < 0) { 12420 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 12421 } else { 12422 user->amaflags = format; 12423 } 12424 } else if (!strcasecmp(v->name, "inkeys")) { 12425 ast_string_field_set(user, inkeys, v->value); 12426 } else if (!strcasecmp(v->name, "maxauthreq")) { 12427 user->maxauthreq = atoi(v->value); 12428 if (user->maxauthreq < 0) 12429 user->maxauthreq = 0; 12430 } else if (!strcasecmp(v->name, "adsi")) { 12431 user->adsi = ast_true(v->value); 12432 } else if (!strcasecmp(v->name, "connectedline")) { 12433 if (ast_true(v->value)) { 12434 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12435 } else if (!strcasecmp(v->value, "send")) { 12436 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE); 12437 ast_set_flag64(user, IAX_SENDCONNECTEDLINE); 12438 } else if (!strcasecmp(v->value, "receive")) { 12439 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE); 12440 ast_set_flag64(user, IAX_RECVCONNECTEDLINE); 12441 } else { 12442 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12443 } 12444 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12445 /* default is required unless in optional ip list */ 12446 if (ast_false(v->value)) { 12447 user->calltoken_required = CALLTOKEN_NO; 12448 } else if (!strcasecmp(v->value, "auto")) { 12449 user->calltoken_required = CALLTOKEN_AUTO; 12450 } else if (ast_true(v->value)) { 12451 user->calltoken_required = CALLTOKEN_YES; 12452 } else { 12453 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12454 } 12455 } /* else if (strcasecmp(v->name,"type")) */ 12456 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12457 v = v->next; 12458 if (!v) { 12459 v = alt; 12460 alt = NULL; 12461 } 12462 } 12463 if (!user->authmethods) { 12464 if (!ast_strlen_zero(user->secret)) { 12465 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12466 if (!ast_strlen_zero(user->inkeys)) 12467 user->authmethods |= IAX_AUTH_RSA; 12468 } else if (!ast_strlen_zero(user->inkeys)) { 12469 user->authmethods = IAX_AUTH_RSA; 12470 } else { 12471 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12472 } 12473 } 12474 ast_clear_flag64(user, IAX_DELME); 12475 } 12476 cleanup: 12477 if (oldha) 12478 ast_free_ha(oldha); 12479 if (oldcon) 12480 free_context(oldcon); 12481 return user; 12482 }
| static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 13101 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(), iax_ie_data::buf, chan_iax2_pvt::capability, parsed_dial_string::context, create_addr(), parsed_dial_string::exten, 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, parsed_dial_string::key, LOG_WARNING, NEW_FORCE, parse_dial_string(), parsed_dial_string::password, parsed_dial_string::peer, iax_ie_data::pos, secret, send_command(), create_addr_info::sockfd, and parsed_dial_string::username.
Referenced by find_cache().
13102 { 13103 struct sockaddr_in sin; 13104 int x; 13105 int callno; 13106 struct iax_ie_data ied; 13107 struct create_addr_info cai; 13108 struct parsed_dial_string pds; 13109 char *tmpstr; 13110 13111 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 13112 /* Look for an *exact match* call. Once a call is negotiated, it can only 13113 look up entries for a single context */ 13114 if (!ast_mutex_trylock(&iaxsl[x])) { 13115 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 13116 return x; 13117 ast_mutex_unlock(&iaxsl[x]); 13118 } 13119 } 13120 13121 /* No match found, we need to create a new one */ 13122 13123 memset(&cai, 0, sizeof(cai)); 13124 memset(&ied, 0, sizeof(ied)); 13125 memset(&pds, 0, sizeof(pds)); 13126 13127 tmpstr = ast_strdupa(data); 13128 parse_dial_string(tmpstr, &pds); 13129 13130 if (ast_strlen_zero(pds.peer)) { 13131 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 13132 return -1; 13133 } 13134 13135 /* Populate our address from the given */ 13136 if (create_addr(pds.peer, NULL, &sin, &cai)) 13137 return -1; 13138 13139 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n", 13140 pds.peer, pds.username, pds.password, pds.context); 13141 13142 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 13143 if (callno < 1) { 13144 ast_log(LOG_WARNING, "Unable to create call\n"); 13145 return -1; 13146 } 13147 13148 ast_string_field_set(iaxs[callno], dproot, data); 13149 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 13150 13151 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 13152 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 13153 /* the string format is slightly different from a standard dial string, 13154 because the context appears in the 'exten' position 13155 */ 13156 if (pds.exten) 13157 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 13158 if (pds.username) 13159 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 13160 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 13161 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 13162 /* Keep password handy */ 13163 if (pds.password) 13164 ast_string_field_set(iaxs[callno], secret, pds.password); 13165 if (pds.key) 13166 ast_string_field_set(iaxs[callno], outkey, pds.key); 13167 /* Start the call going */ 13168 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 13169 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 13170 13171 return callno; 13172 }
| static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | offset | |||
| ) | [static] |
Definition at line 5790 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 ast_rtp_read(), and schedule_delivery().
05791 { 05792 /* Returns where in "receive time" we are. That is, how many ms 05793 since we received (or would have received) the frame with timestamp 0 */ 05794 int ms; 05795 #ifdef IAXTESTS 05796 int jit; 05797 #endif /* IAXTESTS */ 05798 /* Setup rxcore if necessary */ 05799 if (ast_tvzero(p->rxcore)) { 05800 p->rxcore = ast_tvnow(); 05801 if (iaxdebug) 05802 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 05803 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 05804 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 05805 #if 1 05806 if (iaxdebug) 05807 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 05808 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 05809 #endif 05810 } 05811 05812 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 05813 #ifdef IAXTESTS 05814 if (test_jit) { 05815 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 05816 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 05817 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 05818 jit = -jit; 05819 ms += jit; 05820 } 05821 } 05822 if (test_late) { 05823 ms += test_late; 05824 test_late = 0; 05825 } 05826 #endif /* IAXTESTS */ 05827 return ms; 05828 }
| static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | ts, | |||
| struct ast_frame * | f | |||
| ) | [static] |
Definition at line 5657 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, ast_frame::delivery, ast_frame::frametype, iax2_trunk_peer::lastsent, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, chan_iax2_pvt::peercallno, ast_frame::samples, and ast_frame::subclass.
Referenced by iax2_send(), and socket_process().
05658 { 05659 int ms; 05660 int voice = 0; 05661 int genuine = 0; 05662 int adjust; 05663 int rate = ast_format_rate(f->subclass) / 1000; 05664 struct timeval *delivery = NULL; 05665 05666 05667 /* What sort of frame do we have?: voice is self-explanatory 05668 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 05669 non-genuine frames are CONTROL frames [ringing etc], DTMF 05670 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 05671 the others need a timestamp slaved to the voice frames so that they go in sequence 05672 */ 05673 if (f) { 05674 if (f->frametype == AST_FRAME_VOICE) { 05675 voice = 1; 05676 delivery = &f->delivery; 05677 } else if (f->frametype == AST_FRAME_IAX) { 05678 genuine = 1; 05679 } else if (f->frametype == AST_FRAME_CNG) { 05680 p->notsilenttx = 0; 05681 } 05682 } 05683 if (ast_tvzero(p->offset)) { 05684 p->offset = ast_tvnow(); 05685 /* Round to nearest 20ms for nice looking traces */ 05686 p->offset.tv_usec -= p->offset.tv_usec % 20000; 05687 } 05688 /* If the timestamp is specified, just send it as is */ 05689 if (ts) 05690 return ts; 05691 /* If we have a time that the frame arrived, always use it to make our timestamp */ 05692 if (delivery && !ast_tvzero(*delivery)) { 05693 ms = ast_tvdiff_ms(*delivery, p->offset); 05694 if (ms < 0) { 05695 ms = 0; 05696 } 05697 if (iaxdebug) 05698 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 05699 } else { 05700 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 05701 if (ms < 0) 05702 ms = 0; 05703 if (voice) { 05704 /* On a voice frame, use predicted values if appropriate */ 05705 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 05706 /* Adjust our txcore, keeping voice and non-voice synchronized */ 05707 /* AN EXPLANATION: 05708 When we send voice, we usually send "calculated" timestamps worked out 05709 on the basis of the number of samples sent. When we send other frames, 05710 we usually send timestamps worked out from the real clock. 05711 The problem is that they can tend to drift out of step because the 05712 source channel's clock and our clock may not be exactly at the same rate. 05713 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 05714 for this call. Moving it adjusts timestamps for non-voice frames. 05715 We make the adjustment in the style of a moving average. Each time we 05716 adjust p->offset by 10% of the difference between our clock-derived 05717 timestamp and the predicted timestamp. That's why you see "10000" 05718 below even though IAX2 timestamps are in milliseconds. 05719 The use of a moving average avoids offset moving too radically. 05720 Generally, "adjust" roams back and forth around 0, with offset hardly 05721 changing at all. But if a consistent different starts to develop it 05722 will be eliminated over the course of 10 frames (200-300msecs) 05723 */ 05724 adjust = (ms - p->nextpred); 05725 if (adjust < 0) 05726 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 05727 else if (adjust > 0) 05728 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 05729 05730 if (!p->nextpred) { 05731 p->nextpred = ms; /*f->samples / rate;*/ 05732 if (p->nextpred <= p->lastsent) 05733 p->nextpred = p->lastsent + 3; 05734 } 05735 ms = p->nextpred; 05736 } else { 05737 /* in this case, just use the actual 05738 * time, since we're either way off 05739 * (shouldn't happen), or we're ending a 05740 * silent period -- and seed the next 05741 * predicted time. Also, round ms to the 05742 * next multiple of frame size (so our 05743 * silent periods are multiples of 05744 * frame size too) */ 05745 05746 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 05747 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 05748 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 05749 05750 if (f->samples >= rate) /* check to make sure we dont core dump */ 05751 { 05752 int diff = ms % (f->samples / rate); 05753 if (diff) 05754 ms += f->samples/rate - diff; 05755 } 05756 05757 p->nextpred = ms; 05758 p->notsilenttx = 1; 05759 } 05760 } else if ( f->frametype == AST_FRAME_VIDEO ) { 05761 /* 05762 * IAX2 draft 03 says that timestamps MUST be in order. 05763 * It does not say anything about several frames having the same timestamp 05764 * When transporting video, we can have a frame that spans multiple iax packets 05765 * (so called slices), so it would make sense to use the same timestamp for all of 05766 * them 05767 * We do want to make sure that frames don't go backwards though 05768 */ 05769 if ( (unsigned int)ms < p->lastsent ) 05770 ms = p->lastsent; 05771 } else { 05772 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 05773 it's a genuine frame */ 05774 if (genuine) { 05775 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 05776 if (ms <= p->lastsent) 05777 ms = p->lastsent + 3; 05778 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 05779 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 05780 ms = p->lastsent + 3; 05781 } 05782 } 05783 } 05784 p->lastsent = ms; 05785 if (voice) 05786 p->nextpred = p->nextpred + f->samples / rate; 05787 return ms; 05788 }
| static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
| int | sampms, | |||
| struct timeval * | now | |||
| ) | [static] |
Definition at line 5613 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().
05614 { 05615 unsigned long int mssincetx; /* unsigned to handle overflows */ 05616 long int ms, pred; 05617 05618 tpeer->trunkact = *now; 05619 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime); 05620 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 05621 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 05622 tpeer->txtrunktime = *now; 05623 tpeer->lastsent = 999999; 05624 } 05625 /* Update last transmit time now */ 05626 tpeer->lasttxtime = *now; 05627 05628 /* Calculate ms offset */ 05629 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime); 05630 /* Predict from last value */ 05631 pred = tpeer->lastsent + sampms; 05632 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 05633 ms = pred; 05634 05635 /* We never send the same timestamp twice, so fudge a little if we must */ 05636 if (ms == tpeer->lastsent) 05637 ms = tpeer->lastsent + 1; 05638 tpeer->lastsent = ms; 05639 return ms; 05640 }
| static int callno_hash | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 2527 of file chan_iax2.c.
References ast_random().
Referenced by create_callno_pools().
02528 { 02529 return abs(ast_random()); 02530 }
| static int calltoken_required | ( | struct sockaddr_in * | sin, | |
| const char * | name, | |||
| int | subclass | |||
| ) | [static] |
Definition at line 2075 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_NO, iax2_peer::calltoken_required, iax2_user::calltoken_required, find_peer(), find_user(), IAX_COMMAND_NEW, peer_unref(), realtime_peer(), realtime_user(), S_OR, and user_unref().
Referenced by handle_call_token().
02076 { 02077 struct addr_range *addr_range; 02078 struct iax2_peer *peer = NULL; 02079 struct iax2_user *user = NULL; 02080 /* if no username is given, check for guest accounts */ 02081 const char *find = S_OR(name, "guest"); 02082 int res = 1; /* required by default */ 02083 int optional = 0; 02084 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT; 02085 /* There are only two cases in which calltoken validation is not required. 02086 * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and 02087 * the peer definition has not set the requirecalltoken option. 02088 * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no. 02089 */ 02090 02091 /* ----- Case 1 ----- */ 02092 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) { 02093 ao2_ref(addr_range, -1); 02094 optional = 1; 02095 } 02096 02097 /* ----- Case 2 ----- */ 02098 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) { 02099 calltoken_required = user->calltoken_required; 02100 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) { 02101 calltoken_required = user->calltoken_required; 02102 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) { 02103 calltoken_required = peer->calltoken_required; 02104 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) { 02105 calltoken_required = peer->calltoken_required; 02106 } 02107 02108 if (peer) { 02109 peer_unref(peer); 02110 } 02111 if (user) { 02112 user_unref(user); 02113 } 02114 02115 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); 02116 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) || 02117 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) { 02118 res = 0; 02119 } 02120 02121 return res; 02122 }
| static int check_access | ( | int | callno, | |
| struct sockaddr_in * | sin, | |||
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 7278 of file chan_iax2.c.
References iax2_user::accountcode, iax2_user::adsi, chan_iax2_pvt::adsi, iax_ies::adsicpe, chan_iax2_pvt::amaflags, iax2_user::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_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_variable_new(), iax2_user::authmethods, 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, iax2_user::capability, chan_iax2_pvt::capability, iax_ies::capability, iax2_user::cid_name, cid_name, iax2_user::cid_num, cid_num, iax_ies::codec_prefs, iax2_context::context, chan_iax2_pvt::context, context, iax2_user::contexts, iax2_user::dbsecret, DEFAULT_CONTEXT, iax_ies::dnid, iax2_user::encmethods, chan_iax2_pvt::encmethods, exten, ast_variable::file, iax_ies::format, iax2_user::ha, 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, iax2_user::inkeys, iax2_user::language, iax_ies::language, LOG_WARNING, iax2_user::maxauthreq, iax2_user::mohinterpret, iax2_user::mohsuggest, ast_variable::name, iax2_user::name, ast_variable::next, parkinglot, iax2_user::parkinglot, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_user::prefs, chan_iax2_pvt::prefs, prefs, iax_ies::rdnis, realtime_user(), secret, iax2_user::secret, user_unref(), iax_ies::username, ast_variable::value, chan_iax2_pvt::vars, iax2_user::vars, iax_ies::version, and version.
Referenced by socket_process().
07279 { 07280 /* Start pessimistic */ 07281 int res = -1; 07282 int version = 2; 07283 struct iax2_user *user = NULL, *best = NULL; 07284 int bestscore = 0; 07285 int gotcapability = 0; 07286 struct ast_variable *v = NULL, *tmpvar = NULL; 07287 struct ao2_iterator i; 07288 07289 if (!iaxs[callno]) 07290 return res; 07291 if (ies->called_number) 07292 ast_string_field_set(iaxs[callno], exten, ies->called_number); 07293 if (ies->calling_number) { 07294 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) { 07295 ast_shrink_phone_number(ies->calling_number); 07296 } 07297 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 07298 } 07299 if (ies->calling_name) 07300 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 07301 if (ies->calling_ani) 07302 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 07303 if (ies->dnid) 07304 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 07305 if (ies->rdnis) 07306 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 07307 if (ies->called_context) 07308 ast_string_field_set(iaxs[callno], context, ies->called_context); 07309 if (ies->language) 07310 ast_string_field_set(iaxs[callno], language, ies->language); 07311 if (ies->username) 07312 ast_string_field_set(iaxs[callno], username, ies->username); 07313 if (ies->calling_ton > -1) 07314 iaxs[callno]->calling_ton = ies->calling_ton; 07315 if (ies->calling_tns > -1) 07316 iaxs[callno]->calling_tns = ies->calling_tns; 07317 if (ies->calling_pres > -1) 07318 iaxs[callno]->calling_pres = ies->calling_pres; 07319 if (ies->format) 07320 iaxs[callno]->peerformat = ies->format; 07321 if (ies->adsicpe) 07322 iaxs[callno]->peeradsicpe = ies->adsicpe; 07323 if (ies->capability) { 07324 gotcapability = 1; 07325 iaxs[callno]->peercapability = ies->capability; 07326 } 07327 if (ies->version) 07328 version = ies->version; 07329 07330 /* Use provided preferences until told otherwise for actual preferences */ 07331 if(ies->codec_prefs) { 07332 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 07333 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 07334 } 07335 07336 if (!gotcapability) 07337 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 07338 if (version > IAX_PROTO_VERSION) { 07339 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 07340 ast_inet_ntoa(sin->sin_addr), version); 07341 return res; 07342 } 07343 /* Search the userlist for a compatible entry, and fill in the rest */ 07344 i = ao2_iterator_init(users, 0); 07345 while ((user = ao2_iterator_next(&i))) { 07346 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 07347 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 07348 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 07349 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 07350 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 07351 if (!ast_strlen_zero(iaxs[callno]->username)) { 07352 /* Exact match, stop right now. */ 07353 if (best) 07354 user_unref(best); 07355 best = user; 07356 break; 07357 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 07358 /* No required authentication */ 07359 if (user->ha) { 07360 /* There was host authentication and we passed, bonus! */ 07361 if (bestscore < 4) { 07362 bestscore = 4; 07363 if (best) 07364 user_unref(best); 07365 best = user; 07366 continue; 07367 } 07368 } else { 07369 /* No host access, but no secret, either, not bad */ 07370 if (bestscore < 3) { 07371 bestscore = 3; 07372 if (best) 07373 user_unref(best); 07374 best = user; 07375 continue; 07376 } 07377 } 07378 } else { 07379 if (user->ha) { 07380 /* Authentication, but host access too, eh, it's something.. */ 07381 if (bestscore < 2) { 07382 bestscore = 2; 07383 if (best) 07384 user_unref(best); 07385 best = user; 07386 continue; 07387 } 07388 } else { 07389 /* Authentication and no host access... This is our baseline */ 07390 if (bestscore < 1) { 07391 bestscore = 1; 07392 if (best) 07393 user_unref(best); 07394 best = user; 07395 continue; 07396 } 07397 } 07398 } 07399 } 07400 user_unref(user); 07401 } 07402 ao2_iterator_destroy(&i); 07403 user = best; 07404 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 07405 user = realtime_user(iaxs[callno]->username, sin); 07406 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 07407 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 07408 user = user_unref(user); 07409 } 07410 } 07411 if (user) { 07412 /* We found our match (use the first) */ 07413 /* copy vars */ 07414 for (v = user->vars ; v ; v = v->next) { 07415 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) { 07416 tmpvar->next = iaxs[callno]->vars; 07417 iaxs[callno]->vars = tmpvar; 07418 } 07419 } 07420 /* If a max AUTHREQ restriction is in place, activate it */ 07421 if (user->maxauthreq > 0) 07422 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ); 07423 iaxs[callno]->prefs = user->prefs; 07424 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT); 07425 iaxs[callno]->encmethods = user->encmethods; 07426 /* Store the requested username if not specified */ 07427 if (ast_strlen_zero(iaxs[callno]->username)) 07428 ast_string_field_set(iaxs[callno], username, user->name); 07429 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 07430 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK); 07431 iaxs[callno]->capability = user->capability; 07432 /* And use the default context */ 07433 if (ast_strlen_zero(iaxs[callno]->context)) { 07434 if (user->contexts) 07435 ast_string_field_set(iaxs[callno], context, user->contexts->context); 07436 else 07437 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT); 07438 } 07439 /* And any input keys */ 07440 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 07441 /* And the permitted authentication methods */ 07442 iaxs[callno]->authmethods = user->authmethods; 07443 iaxs[callno]->adsi = user->adsi; 07444 /* If the user has callerid, override the remote caller id. */ 07445 if (ast_test_flag64(user, IAX_HASCALLERID)) { 07446 iaxs[callno]->calling_tns = 0; 07447 iaxs[callno]->calling_ton = 0; 07448 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 07449 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 07450 ast_string_field_set(iaxs[callno], ani, user->cid_num); 07451 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 07452 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 07453 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 07454 } /* else user is allowed to set their own CID settings */ 07455 if (!ast_strlen_zero(user->accountcode)) 07456 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 07457 if (!ast_strlen_zero(user->mohinterpret)) 07458 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 07459 if (!ast_strlen_zero(user->mohsuggest)) 07460 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 07461 if (!ast_strlen_zero(user->parkinglot)) 07462 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot); 07463 if (user->amaflags) 07464 iaxs[callno]->amaflags = user->amaflags; 07465 if (!ast_strlen_zero(user->language)) 07466 ast_string_field_set(iaxs[callno], language, user->language); 07467 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 07468 /* Keep this check last */ 07469 if (!ast_strlen_zero(user->dbsecret)) { 07470 char *family, *key=NULL; 07471 char buf[80]; 07472 family = ast_strdupa(user->dbsecret); 07473 key = strchr(family, '/'); 07474 if (key) { 07475 *key = '\0'; 07476 key++; 07477 } 07478 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 07479 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 07480 else 07481 ast_string_field_set(iaxs[callno], secret, buf); 07482 } else 07483 ast_string_field_set(iaxs[callno], secret, user->secret); 07484 res = 0; 07485 user = user_unref(user); 07486 } else { 07487 /* user was not found, but we should still fake an AUTHREQ. 07488 * Set authmethods to the last known authmethod used by the system 07489 * Set a fake secret, it's not looked at, just required to attempt authentication. 07490 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 07491 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 07492 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07493 iaxs[callno]->authrej = 1; 07494 if (!ast_strlen_zero(iaxs[callno]->username)) { 07495 /* only send the AUTHREQ if a username was specified. */ 07496 res = 0; 07497 } 07498 } 07499 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 07500 return res; 07501 }
| static int check_provisioning | ( | struct sockaddr_in * | sin, | |
| int | sockfd, | |||
| char * | si, | |||
| unsigned int | ver | |||
| ) | [static] |
Definition at line 9061 of file chan_iax2.c.
References ast_debug, iax2_provision(), and iax_provision_version().
Referenced by socket_process().
09062 { 09063 unsigned int ourver; 09064 char rsi[80]; 09065 snprintf(rsi, sizeof(rsi), "si-%s", si); 09066 if (iax_provision_version(&ourver, rsi, 1)) 09067 return 0; 09068 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 09069 if (ourver != ver) 09070 iax2_provision(sin, sockfd, NULL, rsi, 1); 09071 return 0; 09072 }
| static int check_srcaddr | ( | struct sockaddr * | sa, | |
| socklen_t | salen | |||
| ) | [static] |
Check if address can be used as packet source.
Definition at line 11822 of file chan_iax2.c.
References ast_debug, ast_log(), errno, and LOG_ERROR.
Referenced by peer_set_srcaddr().
11823 { 11824 int sd; 11825 int res; 11826 11827 sd = socket(AF_INET, SOCK_DGRAM, 0); 11828 if (sd < 0) { 11829 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 11830 return -1; 11831 } 11832 11833 res = bind(sd, sa, salen); 11834 if (res < 0) { 11835 ast_debug(1, "Can't bind: %s\n", strerror(errno)); 11836 close(sd); 11837 return 1; 11838 } 11839 11840 close(sd); 11841 return 0; 11842 }
| static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 8055 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().
08056 { 08057 char exten[256] = ""; 08058 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0; 08059 struct iax2_dpcache *dp = NULL; 08060 08061 if (ies->called_number) 08062 ast_copy_string(exten, ies->called_number, sizeof(exten)); 08063 08064 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 08065 status = CACHE_FLAG_EXISTS; 08066 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 08067 status = CACHE_FLAG_CANEXIST; 08068 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 08069 status = CACHE_FLAG_NONEXISTENT; 08070 08071 if (ies->refresh) 08072 expiry = ies->refresh; 08073 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 08074 matchmore = CACHE_FLAG_MATCHMORE; 08075 08076 AST_LIST_LOCK(&dpcache); 08077 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) { 08078 if (strcmp(dp->exten, exten)) 08079 continue; 08080 AST_LIST_REMOVE_CURRENT(peer_list); 08081 dp->callno = 0; 08082 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 08083 if (dp->flags & CACHE_FLAG_PENDING) { 08084 dp->flags &= ~CACHE_FLAG_PENDING; 08085 dp->flags |= status; 08086 dp->flags |= matchmore; 08087 } 08088 /* Wake up waiters */ 08089 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 08090 if (dp->waiters[x] > -1) { 08091 if (write(dp->waiters[x], "asdf", 4) < 0) { 08092 } 08093 } 08094 } 08095 } 08096 AST_LIST_TRAVERSE_SAFE_END; 08097 AST_LIST_UNLOCK(&dpcache); 08098 08099 return 0; 08100 }
| static char * complete_iax2_peers | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state, | |||
| uint64_t | flags | |||
| ) | [static] |
Definition at line 3690 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, ast_test_flag64, iax2_peer::name, and peer_unref().
Referenced by handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), and handle_cli_iax2_show_peer().
03691 { 03692 int which = 0; 03693 struct iax2_peer *peer; 03694 char *res = NULL; 03695 int wordlen = strlen(word); 03696 struct ao2_iterator i; 03697 03698 i = ao2_iterator_init(peers, 0); 03699 while ((peer = ao2_iterator_next(&i))) { 03700 if (!strncasecmp(peer->name, word, wordlen) && ++which > state 03701 && (!flags || ast_test_flag64(peer, flags))) { 03702 res = ast_strdup(peer->name); 03703 peer_unref(peer); 03704 break; 03705 } 03706 peer_unref(peer); 03707 } 03708 ao2_iterator_destroy(&i); 03709 03710 return res; 03711 }
| static char * complete_iax2_unregister | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 6647 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, iax2_peer::expire, iax2_peer::name, and peer_unref().
Referenced by handle_cli_iax2_unregister().
06648 { 06649 int which = 0; 06650 struct iax2_peer *p = NULL; 06651 char *res = NULL; 06652 int wordlen = strlen(word); 06653 06654 /* 0 - iax2; 1 - unregister; 2 - <peername> */ 06655 if (pos == 2) { 06656 struct ao2_iterator i = ao2_iterator_init(peers, 0); 06657 while ((p = ao2_iterator_next(&i))) { 06658 if (!strncasecmp(p->name, word, wordlen) && 06659 ++which > state && p->expire > 0) { 06660 res = ast_strdup(p->name); 06661 peer_unref(p); 06662 break; 06663 } 06664 peer_unref(p); 06665 } 06666 ao2_iterator_destroy(&i); 06667 } 06668 06669 return res; 06670 }
| static int complete_transfer | ( | int | callno, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 8102 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(), 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, 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().
08103 { 08104 int peercallno = 0; 08105 struct chan_iax2_pvt *pvt = iaxs[callno]; 08106 struct iax_frame *cur; 08107 jb_frame frame; 08108 08109 if (ies->callno) 08110 peercallno = ies->callno; 08111 08112 if (peercallno < 1) { 08113 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08114 return -1; 08115 } 08116 remove_by_transfercallno(pvt); 08117 /* since a transfer has taken place, the address will change. 08118 * This must be accounted for in the peercnts table. Remove 08119 * the old address and add the new one */ 08120 peercnt_remove_by_addr(&pvt->addr); 08121 peercnt_add(&pvt->transfer); 08122 /* now copy over the new address */ 08123 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 08124 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 08125 /* Reset sequence numbers */ 08126 pvt->oseqno = 0; 08127 pvt->rseqno = 0; 08128 pvt->iseqno = 0; 08129 pvt->aseqno = 0; 08130 08131 if (pvt->peercallno) { 08132 remove_by_peercallno(pvt); 08133 } 08134 pvt->peercallno = peercallno; 08135 /*this is where the transfering call swiches hash tables */ 08136 store_by_peercallno(pvt); 08137 pvt->transferring = TRANSFER_NONE; 08138 pvt->svoiceformat = -1; 08139 pvt->voiceformat = 0; 08140 pvt->svideoformat = -1; 08141 pvt->videoformat = 0; 08142 pvt->transfercallno = -1; 08143 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 08144 memset(&pvt->offset, 0, sizeof(pvt->offset)); 08145 /* reset jitterbuffer */ 08146 while(jb_getall(pvt->jb,&frame) == JB_OK) 08147 iax2_frame_free(frame.data); 08148 jb_reset(pvt->jb); 08149 pvt->lag = 0; 08150 pvt->last = 0; 08151 pvt->lastsent = 0; 08152 pvt->nextpred = 0; 08153 pvt->pingtime = DEFAULT_RETRY_TIME; 08154 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) { 08155 /* We must cancel any packets that would have been transmitted 08156 because now we're talking to someone new. It's okay, they 08157 were transmitted to someone that didn't care anyway. */ 08158 cur->retries = -1; 08159 } 08160 return 0; 08161 }
| static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1509 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().
01510 { 01511 int x; 01512 int power=-1; 01513 /* If it's 128 or smaller, just return it */ 01514 if (subclass < IAX_FLAG_SC_LOG) 01515 return subclass; 01516 /* Otherwise find its power */ 01517 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01518 if (subclass & (1 << x)) { 01519 if (power > -1) { 01520 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01521 return 0; 01522 } else 01523 power = x; 01524 } 01525 } 01526 return power | IAX_FLAG_SC_LOG; 01527 }
| static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ie_data * | iep | |||
| ) | [static] |
Definition at line 9074 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().
09075 { 09076 jb_info stats; 09077 jb_getinfo(pvt->jb, &stats); 09078 09079 memset(iep, 0, sizeof(*iep)); 09080 09081 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 09082 if(stats.frames_in == 0) stats.frames_in = 1; 09083 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 09084 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 09085 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 09086 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 09087 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 09088 }
| static int create_addr | ( | const char * | peername, | |
| struct ast_channel * | c, | |||
| struct sockaddr_in * | sin, | |||
| struct create_addr_info * | cai | |||
| ) | [static] |
Definition at line 4407 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_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, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag.
04408 { 04409 struct iax2_peer *peer; 04410 int res = -1; 04411 struct ast_codec_pref ourprefs; 04412 04413 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK); 04414 cai->sockfd = defaultsockfd; 04415 cai->maxtime = 0; 04416 sin->sin_family = AF_INET; 04417 04418 if (!(peer = find_peer(peername, 1))) { 04419 cai->found = 0; 04420 if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) { 04421 ast_log(LOG_WARNING, "No such host: %s\n", peername); 04422 return -1; 04423 } 04424 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 04425 /* use global iax prefs for unknown peer/user */ 04426 /* But move the calling channel's native codec to the top of the preference list */ 04427 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 04428 if (c) 04429 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04430 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04431 return 0; 04432 } 04433 04434 cai->found = 1; 04435 04436 /* if the peer has no address (current or default), return failure */ 04437 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 04438 goto return_unref; 04439 04440 /* if the peer is being monitored and is currently unreachable, return failure */ 04441 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 04442 goto return_unref; 04443 04444 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 04445 cai->maxtime = peer->maxms; 04446 cai->capability = peer->capability; 04447 cai->encmethods = peer->encmethods; 04448 cai->sockfd = peer->sockfd; 04449 cai->adsi = peer->adsi; 04450 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 04451 /* Move the calling channel's native codec to the top of the preference list */ 04452 if (c) { 04453 ast_debug(1, "prepending %x to prefs\n", c->nativeformats); 04454 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04455 } 04456 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04457 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 04458 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 04459 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 04460 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 04461 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 04462 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num)); 04463 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name)); 04464 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 04465 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 04466 if (ast_strlen_zero(peer->dbsecret)) { 04467 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 04468 } else { 04469 char *family; 04470 char *key = NULL; 04471 04472 family = ast_strdupa(peer->dbsecret); 04473 key = strchr(family, '/'); 04474 if (key) 04475 *key++ = '\0'; 04476 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 04477 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 04478 goto return_unref; 04479 } 04480 } 04481 04482 if (peer->addr.sin_addr.s_addr) { 04483 sin->sin_addr = peer->addr.sin_addr; 04484 sin->sin_port = peer->addr.sin_port; 04485 } else { 04486 sin->sin_addr = peer->defaddr.sin_addr; 04487 sin->sin_port = peer->defaddr.sin_port; 04488 } 04489 04490 res = 0; 04491 04492 return_unref: 04493 peer_unref(peer); 04494 04495 return res; 04496 }
| static int create_callno_pools | ( | void | ) | [static] |
Definition at line 2532 of file chan_iax2.c.
References ao2_alloc, ao2_container_alloc, ao2_link, ao2_ref, callno_entry::callno, callno_hash(), and TRUNK_CALL_START.
Referenced by load_objects().
02533 { 02534 uint16_t i; 02535 02536 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02537 return -1; 02538 } 02539 02540 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02541 return -1; 02542 } 02543 02544 /* start at 2, 0 and 1 are reserved */ 02545 for (i = 2; i <= IAX_MAX_CALLS; i++) { 02546 struct callno_entry *callno_entry; 02547 02548 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) { 02549 return -1; 02550 } 02551 02552 callno_entry->callno = i; 02553 02554 if (i < TRUNK_CALL_START) { 02555 ao2_link(callno_pool, callno_entry); 02556 } else { 02557 ao2_link(callno_pool_trunk, callno_entry); 02558 } 02559 02560 ao2_ref(callno_entry, -1); 02561 } 02562 02563 return 0; 02564 }
| 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 6012 of file chan_iax2.c.
References ast_debug, AST_FRAME_VIDEO, ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, ast_frame::frametype, IAX_FLAG_FULL, memcpy_decrypt(), ast_iax2_full_hdr::scallno, ast_frame::subclass, ast_iax2_full_hdr::type, and uncompress_subclass().
Referenced by decrypt_frame(), and update_packet().
06013 { 06014 int padding; 06015 unsigned char *workspace; 06016 06017 workspace = alloca(*datalen); 06018 memset(f, 0, sizeof(*f)); 06019 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06020 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06021 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 06022 return -1; 06023 /* Decrypt */ 06024 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 06025 06026 padding = 16 + (workspace[15] & 0x0f); 06027 if (iaxdebug) 06028 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 06029 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 06030 return -1; 06031 06032 *datalen -= padding; 06033 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06034 f->frametype = fh->type; 06035 if (f->frametype == AST_FRAME_VIDEO) { 06036 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06037 } else { 06038 f->subclass = uncompress_subclass(fh->csub); 06039 } 06040 } else { 06041 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06042 if (iaxdebug) 06043 ast_debug(1, "Decoding mini with length %d\n", *datalen); 06044 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 06045 return -1; 06046 /* Decrypt */ 06047 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 06048 padding = 16 + (workspace[15] & 0x0f); 06049 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 06050 return -1; 06051 *datalen -= padding; 06052 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06053 } 06054 return 0; 06055 }
| static int decrypt_frame | ( | int | callno, | |
| struct ast_iax2_full_hdr * | fh, | |||
| struct ast_frame * | f, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 6098 of file chan_iax2.c.
References ast_set_flag64, ast_strdupa, ast_test_flag64, build_encryption_keys(), decode_frame(), IAX_KEYPOPULATED, MD5Final(), MD5Init(), MD5Update(), secret, and strsep().
Referenced by socket_process().
06099 { 06100 int res=-1; 06101 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) { 06102 /* Search for possible keys, given secrets */ 06103 struct MD5Context md5; 06104 unsigned char digest[16]; 06105 char *tmppw, *stringp; 06106 06107 tmppw = ast_strdupa(iaxs[callno]->secret); 06108 stringp = tmppw; 06109 while ((tmppw = strsep(&stringp, ";"))) { 06110 MD5Init(&md5); 06111 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 06112 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 06113 MD5Final(digest, &md5); 06114 build_encryption_keys(digest, iaxs[callno]); 06115 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06116 if (!res) { 06117 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED); 06118 break; 06119 } 06120 } 06121 } else 06122 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06123 return res; 06124 }
| 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 9221 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_thread::buf, iax2_pkt_buf::buf, iax2_thread::buf_len, iax2_thread::full_frames, iax2_pkt_buf::len, iax2_thread::lock, and ast_iax2_full_hdr::oseqno.
Referenced by socket_read().
09222 { 09223 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 09224 struct ast_iax2_full_hdr *fh, *cur_fh; 09225 09226 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 09227 return; 09228 09229 pkt_buf->len = from_here->buf_len; 09230 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 09231 09232 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 09233 ast_mutex_lock(&to_here->lock); 09234 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 09235 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 09236 if (fh->oseqno < cur_fh->oseqno) { 09237 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry); 09238 break; 09239 } 09240 } 09241 AST_LIST_TRAVERSE_SAFE_END 09242 09243 if (!cur_pkt_buf) 09244 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 09245 09246 ast_mutex_unlock(&to_here->lock); 09247 }
| static void delete_users | ( | void | ) | [static] |
Definition at line 12502 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::expire, iax2_destroy(), peer_delme_cb(), chan_iax2_pvt::reg, and user_delme_cb().
12503 { 12504 struct iax2_registry *reg; 12505 12506 ao2_callback(users, 0, user_delme_cb, NULL); 12507 12508 AST_LIST_LOCK(®istrations); 12509 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 12510 if (sched) { 12511 ast_sched_thread_del(sched, reg->expire); 12512 } 12513 if (reg->callno) { 12514 int callno = reg->callno; 12515 ast_mutex_lock(&iaxsl[callno]); 12516 if (iaxs[callno]) { 12517 iaxs[callno]->reg = NULL; 12518 iax2_destroy(callno); 12519 } 12520 ast_mutex_unlock(&iaxsl[callno]); 12521 } 12522 if (reg->dnsmgr) 12523 ast_dnsmgr_release(reg->dnsmgr); 12524 ast_free(reg); 12525 } 12526 AST_LIST_UNLOCK(®istrations); 12527 12528 ao2_callback(peers, 0, peer_delme_cb, NULL); 12529 }
| static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 2887 of file chan_iax2.c.
References ast_free, ast_iax2_firmware_header::datalen, iax_firmware::fd, and iax_firmware::fwh.
Referenced by reload_firmware().
02888 { 02889 /* Close firmware */ 02890 if (cur->fwh) { 02891 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 02892 } 02893 close(cur->fd); 02894 ast_free(cur); 02895 }
| static void dp_lookup | ( | int | callno, | |
| const char * | context, | |||
| const char * | callednum, | |||
| const char * | callerid, | |||
| int | skiplock | |||
| ) | [static] |
Definition at line 8925 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(), iax_ie_data::buf, 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, iax_ie_data::pos, and send_command().
Referenced by dp_lookup_thread(), and socket_process().
08926 { 08927 unsigned short dpstatus = 0; 08928 struct iax_ie_data ied1; 08929 int mm; 08930 08931 memset(&ied1, 0, sizeof(ied1)); 08932 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 08933 /* Must be started */ 08934 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 08935 dpstatus = IAX_DPSTATUS_EXISTS; 08936 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 08937 dpstatus = IAX_DPSTATUS_CANEXIST; 08938 } else { 08939 dpstatus = IAX_DPSTATUS_NONEXISTENT; 08940 } 08941 if (ast_ignore_pattern(context, callednum)) 08942 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 08943 if (mm) 08944 dpstatus |= IAX_DPSTATUS_MATCHMORE; 08945 if (!skiplock) 08946 ast_mutex_lock(&iaxsl[callno]); 08947 if (iaxs[callno]) { 08948 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 08949 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 08950 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 08951 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 08952 } 08953 if (!skiplock) 08954 ast_mutex_unlock(&iaxsl[callno]); 08955 }
| static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 8957 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().
08958 { 08959 /* Look up for dpreq */ 08960 struct dpreq_data *dpr = data; 08961 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 08962 if (dpr->callerid) 08963 ast_free(dpr->callerid); 08964 ast_free(dpr); 08965 return NULL; 08966 }
| static void encmethods_to_str | ( | int | e, | |
| struct ast_str * | buf | |||
| ) | [static] |
Definition at line 1448 of file chan_iax2.c.
References ast_str_append(), ast_str_set(), ast_str_strlen(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.
Referenced by __iax2_show_peers(), handle_cli_iax2_show_peer(), and manager_iax2_show_peer_list().
01449 { 01450 ast_str_set(&buf, 0, "("); 01451 if (e & IAX_ENCRYPT_AES128) { 01452 ast_str_append(&buf, 0, "aes128"); 01453 } 01454 if (e & IAX_ENCRYPT_KEYROTATE) { 01455 ast_str_append(&buf, 0, ",keyrotate"); 01456 } 01457 if (ast_str_strlen(buf) > 1) { 01458 ast_str_append(&buf, 0, ")"); 01459 } else { 01460 ast_str_set(&buf, 0, "No"); 01461 } 01462 }
| static int encrypt_frame | ( | ast_aes_encrypt_key * | ecx, | |
| struct ast_iax2_full_hdr * | fh, | |||
| unsigned char * | poo, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 6057 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().
06058 { 06059 int padding; 06060 unsigned char *workspace; 06061 workspace = alloca(*datalen + 32); 06062 if (!workspace) 06063 return -1; 06064 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06065 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06066 if (iaxdebug) 06067 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 06068 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 06069 padding = 16 + (padding & 0xf); 06070 memcpy(workspace, poo, padding); 06071 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06072 workspace[15] &= 0xf0; 06073 workspace[15] |= (padding & 0xf); 06074 if (iaxdebug) 06075 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]); 06076 *datalen += padding; 06077 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 06078 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 06079 memcpy(poo, workspace + *datalen - 32, 32); 06080 } else { 06081 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06082 if (iaxdebug) 06083 ast_debug(1, "Encoding mini frame with length %d\n", *datalen); 06084 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 06085 padding = 16 + (padding & 0xf); 06086 memcpy(workspace, poo, padding); 06087 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06088 workspace[15] &= 0xf0; 06089 workspace[15] |= (padding & 0x0f); 06090 *datalen += padding; 06091 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 06092 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 06093 memcpy(poo, workspace + *datalen - 32, 32); 06094 } 06095 return 0; 06096 }
| static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8359 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by handle_cli_iax2_prune_realtime(), handle_cli_iax2_unregister(), realtime_peer(), reg_source_db(), and update_registry().
08360 { 08361 #ifdef SCHED_MULTITHREADED 08362 if (schedule_action(__expire_registry, data)) 08363 #endif 08364 __expire_registry(data); 08365 return 0; 08366 }
| static struct iax2_dpcache* find_cache | ( | struct ast_channel * | chan, | |
| const char * | data, | |||
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) | [static, read] |
Definition at line 13174 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, LOG_WARNING,