#include "asterisk.h"
#include <sys/mman.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <signal.h>
#include <strings.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <regex.h>
#include "asterisk/paths.h"
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/md5.h"
#include "asterisk/cdr.h"
#include "asterisk/crypto.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/app.h"
#include "asterisk/astdb.h"
#include "asterisk/musiconhold.h"
#include "asterisk/features.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/localtime.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/netsock.h"
#include "asterisk/stringfields.h"
#include "asterisk/linkedlists.h"
#include "asterisk/event.h"
#include "asterisk/astobj2.h"
#include "asterisk/timing.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/test.h"
#include "asterisk/data.h"
#include "asterisk/netsock2.h"
#include "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"
#include "jitterbuf.h"
Go to the source code of this file.
Data Structures | |
| struct | active_list |
| struct | addr_range |
| struct | callno_entry |
| struct | chan_iax2_pvt |
| struct | chan_iax2_pvt::signaling_queue |
| struct | create_addr_info |
| struct | dpcache |
| struct | dpreq_data |
| struct | dynamic_list |
| struct | firmwares |
| struct | iax2_context |
| struct | iax2_dpcache |
| struct | iax2_peer |
| struct | iax2_pkt_buf |
| struct | iax2_registry |
| struct | iax2_thread |
| struct | iax2_trunk_peer |
| struct | iax2_user |
| struct | iax_dual |
| struct | iax_firmware |
| struct | iax_rr |
| struct | idle_list |
| struct | parsed_dial_string |
| struct | peercnt |
| struct | registrations |
| struct | signaling_queue_entry |
| struct | tpeers |
Defines | |
| #define | ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" |
| #define | ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" |
| #define | CALLNO_TO_PTR(a) ((void *)(unsigned long)(a)) |
| #define | CALLTOKEN_HASH_FORMAT "%s%d%u%d" |
| #define | CALLTOKEN_IE_FORMAT "%u?%s" |
| #define | DATA_EXPORT_IAX2_PEER(MEMBER) |
| #define | DATA_EXPORT_IAX2_USER(MEMBER) |
| #define | DEBUG_SCHED_MULTITHREAD |
| #define | DEBUG_SUPPORT |
| #define | DEFAULT_CONTEXT "default" |
| #define | DEFAULT_DROP 3 |
| #define | DEFAULT_FREQ_NOTOK 10 * 1000 |
| #define | DEFAULT_FREQ_OK 60 * 1000 |
| #define | DEFAULT_MAX_THREAD_COUNT 100 |
| #define | DEFAULT_MAXMS 2000 |
| #define | DEFAULT_RETRY_TIME 1000 |
| #define | DEFAULT_THREAD_COUNT 10 |
| #define | DEFAULT_TRUNKDATA 640 * 10 |
| #define | DONT_RESCHEDULE -2 |
| #define | FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n" |
| #define | FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
| #define | FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-11s %-32.32s\n" |
| #define | FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
| #define | FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" |
| #define | FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
| #define | FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-11s %-32.32s\n" |
| #define | FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
| #define | FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
| #define | GAMMA (0.01) |
| #define | IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
| #define | IAX_ALLOWFWDOWNLOAD (uint64_t)(1 << 26) |
| #define | IAX_ALREADYGONE (uint64_t)(1 << 9) |
| #define | IAX_CALLENCRYPTED(pvt) (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED)) |
| #define | IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
| #define | IAX_CAPABILITY_LOWBANDWIDTH |
| #define | IAX_CAPABILITY_LOWFREE |
| #define | IAX_CAPABILITY_MEDBANDWIDTH |
| #define | IAX_CODEC_NOCAP (uint64_t)(1 << 16) |
| #define | IAX_CODEC_NOPREFS (uint64_t)(1 << 15) |
| #define | IAX_CODEC_USER_FIRST (uint64_t)(1 << 14) |
| #define | IAX_DEBUGDIGEST(msg, key) |
| #define | IAX_DELAYPBXSTART (uint64_t)(1 << 25) |
| #define | IAX_DELME (uint64_t)(1 << 1) |
| #define | IAX_DYNAMIC (uint64_t)(1 << 6) |
| #define | IAX_ENCRYPTED (uint64_t)(1 << 12) |
| #define | IAX_FORCE_ENCRYPT (uint64_t)(1 << 30) |
| #define | IAX_FORCEJITTERBUF (uint64_t)(1 << 20) |
| #define | IAX_HASCALLERID (uint64_t)(1 << 0) |
| #define | IAX_IMMEDIATE (uint64_t)(1 << 27) |
| #define | IAX_KEYPOPULATED (uint64_t)(1 << 13) |
| #define | IAX_MAXAUTHREQ (uint64_t)(1 << 24) |
| #define | IAX_NOTRANSFER (uint64_t)(1 << 4) |
| #define | IAX_PROVISION (uint64_t)(1 << 10) |
| #define | IAX_QUELCH (uint64_t)(1 << 11) |
| #define | IAX_RECVCONNECTEDLINE (uint64_t)(1 << 29) |
| #define | IAX_RTAUTOCLEAR (uint64_t)(1 << 19) |
| #define | IAX_RTCACHEFRIENDS (uint64_t)(1 << 17) |
| #define | IAX_RTIGNOREREGEXPIRE (uint64_t)(1 << 21) |
| #define | IAX_RTSAVE_SYSNAME (uint64_t)(1 << 8) |
| #define | IAX_RTUPDATE (uint64_t)(1 << 18) |
| #define | IAX_SENDANI (uint64_t)(1 << 7) |
| #define | IAX_SENDCONNECTEDLINE (uint64_t)(1 << 28) |
| #define | IAX_SHRINKCALLERID (uint64_t)(1 << 31) |
| #define | IAX_TEMPONLY (uint64_t)(1 << 2) |
| #define | IAX_TRANSFERMEDIA (uint64_t)(1 << 23) |
| #define | IAX_TRUNK (uint64_t)(1 << 3) |
| #define | IAX_TRUNKTIMESTAMPS (uint64_t)(1 << 22) |
| #define | IAX_USEJITTERBUF (uint64_t)(1 << 5) |
| #define | MARK_IAX_SUBCLASS_TX 0x8000 |
| #define | MAX_JITTER_BUFFER 50 |
| #define | MAX_PEER_BUCKETS 563 |
| #define | MAX_RETRY_TIME 10000 |
| #define | MAX_TIMESTAMP_SKEW 160 |
| #define | MAX_TRUNK_MTU 1240 |
| Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240. | |
| #define | MAX_TRUNKDATA 640 * 200 |
| #define | MAX_USER_BUCKETS MAX_PEER_BUCKETS |
| #define | MEMORY_SIZE 100 |
| #define | MIN_JITTER_BUFFER 10 |
| #define | MIN_RETRY_TIME 100 |
| #define | MIN_REUSE_TIME 60 |
| #define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
| #define | SCHED_MULTITHREADED |
| #define | schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__) |
| #define | TRUNK_CALL_START IAX_MAX_CALLS / 2 |
| #define | TS_GAP_FOR_JB_RESYNC 5000 |
Enumerations | |
| enum | { NEW_PREVENT = 0, NEW_ALLOW = 1, NEW_FORCE = 2, NEW_ALLOW_CALLTOKEN_VALIDATED = 3 } |
| 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 | calltoken_peer_enum { CALLTOKEN_DEFAULT = 0, CALLTOKEN_YES = 1, CALLTOKEN_AUTO = 2, CALLTOKEN_NO = 3 } |
| Call token validation settings. More... | |
| enum | iax2_state { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2) } |
| enum | iax2_thread_iostate { IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_SCHEDREADY } |
| enum | iax2_thread_type { IAX_THREAD_TYPE_POOL, IAX_THREAD_TYPE_DYNAMIC } |
| enum | iax_reg_state { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH } |
| enum | iax_transfer_state { TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED, TRANSFER_PASSTHROUGH, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED, TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS } |
Functions | |
| static void | __attempt_transmit (const void *data) |
| static void | __auth_reject (const void *nothing) |
| static void | __auto_congest (const void *nothing) |
| static void | __auto_hangup (const void *nothing) |
| static int | __do_deliver (void *data) |
| static void | __expire_registry (const void *data) |
| static int | __find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno) |
| static void | __get_from_jb (const void *p) |
| static void | __iax2_do_register_s (const void *data) |
| static void | __iax2_poke_noanswer (const void *data) |
| static void | __iax2_poke_peer_s (const void *data) |
| static int | __iax2_show_peers (int fd, int *total, struct mansession *s, const int argc, const char *const argv[]) |
| static void | __reg_module (void) |
| static int | __schedule_action (void(*func)(const void *data), const void *data, const char *funcname) |
| static int | __send_command (struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, int now, int transfer, int final) |
| static void | __send_lagrq (const void *data) |
| static void | __send_ping (const void *data) |
| static int | __unload_module (void) |
| static void | __unreg_module (void) |
| static int | acf_channel_read (struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen) |
| static int | acf_iaxvar_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| static int | acf_iaxvar_write (struct ast_channel *chan, const char *cmd, char *data, const char *value) |
| static int | add_calltoken_ignore (const char *addr) |
| static void | add_empty_calltoken_ie (struct chan_iax2_pvt *pvt, struct iax_ie_data *ied) |
| static int | addr_range_cmp_cb (void *obj, void *arg, int flags) |
| static int | addr_range_delme_cb (void *obj, void *arg, int flags) |
| static int | addr_range_hash_cb (const void *obj, const int flags) |
| static int | addr_range_match_address_cb (void *obj, void *arg, int flags) |
| static int | apply_context (struct iax2_context *con, const char *context) |
| static int | ast_cli_netstats (struct mansession *s, int fd, int limit_fmt) |
| AST_DATA_STRUCTURE (iax2_user, DATA_EXPORT_IAX2_USER) | |
| AST_DATA_STRUCTURE (iax2_peer, DATA_EXPORT_IAX2_PEER) | |
| static struct ast_channel * | ast_iax2_new (int callno, int state, iax2_format capability, const char *linkedid) |
| Create new call, interface with the PBX core. | |
| static int | attempt_transmit (const void *data) |
| static int | auth_fail (int callno, int failcode) |
| static int | auth_reject (const void *data) |
| static int | authenticate (const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, struct chan_iax2_pvt *pvt) |
| static int | authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey) |
| static int | authenticate_request (int call_num) |
| static int | authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies) |
| static int | auto_congest (const void *data) |
| static int | auto_hangup (const void *data) |
| static void | build_callno_limits (struct ast_variable *v) |
| static struct iax2_context * | build_context (const char *context) |
| static void | build_ecx_key (const unsigned char *digest, struct chan_iax2_pvt *pvt) |
| static void | build_encryption_keys (const unsigned char *digest, struct chan_iax2_pvt *pvt) |
| static struct iax2_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
| Create peer structure based on configuration. | |
| static void | build_rand_pad (unsigned char *buf, ssize_t len) |
| static struct iax2_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
| Create in-memory user structure from configuration. | |
| static int | cache_get_callno_locked (const char *data) |
| static unsigned int | calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset) |
| static unsigned int | calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f) |
| static unsigned int | calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now) |
| static int | callno_hash (const void *obj, const int flags) |
| static int | calltoken_required (struct sockaddr_in *sin, const char *name, int subclass) |
| static int | check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
| static int | check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver) |
| static int | check_srcaddr (struct sockaddr *sa, socklen_t salen) |
| Check if address can be used as packet source. | |
| static void | cleanup_thread_list (void *head) |
| static int | complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
| static char * | complete_iax2_peers (const char *line, const char *word, int pos, int state, uint64_t flags) |
| static char * | complete_iax2_unregister (const char *line, const char *word, int pos, int state) |
| static int | complete_transfer (int callno, struct iax_ies *ies) |
| static unsigned char | compress_subclass (iax2_format 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 iax2_format | iax2_best_codec (iax2_format formats) |
| 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, const 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 iax2_format | iax2_codec_choose (struct ast_codec_pref *pref, iax2_format formats, int find_best) |
| static int | iax2_data_add_codecs (struct ast_data *root, const char *node_name, iax2_format formats) |
| 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 (const char *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 *) |
| const char * | iax2_getformatname (iax2_format format) |
| iax2 wrapper function for ast_getformatname | |
| static char * | iax2_getformatname_multiple (char *codec_buf, size_t len, iax2_format format) |
| static int | iax2_getpeername (struct sockaddr_in sin, char *host, int len) |
| static int | iax2_getpeertrunk (struct sockaddr_in sin) |
| static int | iax2_hangup (struct ast_channel *c) |
| static int | iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen) |
| static int | iax2_key_rotate (const void *vpvt) |
| static void | iax2_lock_owner (int callno) |
| static int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
| Part of the IAX2 Switch interface. | |
| static int | iax2_parse_allow_disallow (struct ast_codec_pref *pref, iax2_format *formats, const char *list, int allowing) |
| static int | iax2_poke_noanswer (const void *data) |
| static int | iax2_poke_peer (struct iax2_peer *peer, int heldcall) |
| static int | iax2_poke_peer_cb (void *obj, void *arg, int flags) |
| static int | iax2_poke_peer_s (const void *data) |
| static int | iax2_predestroy (int callno) |
| static void * | iax2_process_thread (void *data) |
| static void | iax2_process_thread_cleanup (void *data) |
| static int | iax2_prov_app (struct ast_channel *chan, const char *data) |
| static int | iax2_provision (struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force) |
| static int | iax2_queryoption (struct ast_channel *c, int option, void *data, int *datalen) |
| static int | iax2_queue_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen) |
| Queue a control frame on the ast_channel owner. | |
| static int | iax2_queue_frame (int callno, struct ast_frame *f) |
| Queue a frame to a call's owning asterisk channel. | |
| static int | iax2_queue_hangup (int callno) |
| Queue a hangup frame on the ast_channel owner. | |
| static struct ast_frame * | iax2_read (struct ast_channel *c) |
| static int | iax2_register (const char *value, int lineno) |
| static struct ast_channel * | iax2_request (const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause) |
| static int | iax2_sched_add (struct ast_sched_context *sched, int when, ast_sched_cb callback, const void *data) |
| static int | iax2_sched_replace (int id, struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) |
| static int | iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final) |
| static int | iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen) |
| static int | iax2_sendimage (struct ast_channel *c, struct ast_frame *img) |
| static int | iax2_sendtext (struct ast_channel *c, const char *text) |
| static int | iax2_setoption (struct ast_channel *c, int option, void *data, int datalen) |
| static int | iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly) |
| static int | iax2_transfer (struct ast_channel *c, const char *dest) |
| static int | iax2_transmit (struct iax_frame *fr) |
| static int | iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now) |
| static int | iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr) |
| static int | iax2_vnak (int callno) |
| static int | iax2_write (struct ast_channel *c, struct ast_frame *f) |
| static int | iax_check_version (char *dev) |
| static void | iax_debug_output (const char *data) |
| static void | iax_error_output (const char *data) |
| static int | iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc) |
| static void | iax_outputframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen) |
| static int | iax_park (struct ast_channel *chan1, struct ast_channel *chan2, const char *park_exten, const char *park_context) |
| static void * | iax_park_thread (void *stuff) |
| static struct iax_frame * | iaxfrdup2 (struct iax_frame *fr) |
| static void | insert_idle_thread (struct iax2_thread *thread) |
| static void | jb_debug_output (const char *fmt,...) |
| static void | jb_error_output (const char *fmt,...) |
| static void | jb_warning_output (const char *fmt,...) |
| static int | load_module (void) |
| Load IAX2 module, load configuraiton ---. | |
| static int | load_objects (void) |
| static void | lock_both (unsigned short callno0, unsigned short callno1) |
| static void | log_jitterstats (unsigned short callno) |
| static int | make_trunk (unsigned short callno, int locked) |
| static int | manager_iax2_show_netstats (struct mansession *s, const struct message *m) |
| static int | manager_iax2_show_peer_list (struct mansession *s, const struct message *m) |
| callback to display iax peers in manager format | |
| static int | manager_iax2_show_peers (struct mansession *s, const struct message *m) |
| callback to display iax peers in manager | |
| static int | manager_iax2_show_registry (struct mansession *s, const struct message *m) |
| static int | match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno) |
| static void | memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx) |
| static void | memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx) |
| static void | merge_encryption (struct chan_iax2_pvt *p, unsigned int enc) |
| static void | mwi_event_cb (const struct ast_event *event, void *userdata) |
| static void | network_change_event_cb (const struct ast_event *, void *) |
| static int | network_change_event_sched_cb (const void *data) |
| static void | network_change_event_subscribe (void) |
| static void | network_change_event_unsubscribe (void) |
| static void * | network_thread (void *ignore) |
| static struct chan_iax2_pvt * | new_iax (struct sockaddr_in *sin, const char *host) |
| static void | parse_dial_string (char *data, struct parsed_dial_string *pds) |
| Parses an IAX dial string into its component parts. | |
| static int | peer_cmp_cb (void *obj, void *arg, int flags) |
| static int | peer_delme_cb (void *obj, void *arg, int flags) |
| static void | peer_destructor (void *obj) |
| static int | peer_hash_cb (const void *obj, const int flags) |
| static struct iax2_peer * | peer_ref (struct iax2_peer *peer) |
| static int | peer_set_sock_cb (void *obj, void *arg, int flags) |
| static int | peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr) |
| Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found. | |
| static int | peer_status (struct iax2_peer *peer, char *status, int statuslen) |
| peer_status: Report Peer status in character string | |
| static struct iax2_peer * | peer_unref (struct iax2_peer *peer) |
| static int | peercnt_add (struct sockaddr_in *sin) |
| static int | peercnt_cmp_cb (void *obj, void *arg, int flags) |
| static int | peercnt_hash_cb (const void *obj, const int flags) |
| static void | peercnt_modify (unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr) |
| static void | peercnt_remove (struct peercnt *peercnt) |
| static int | peercnt_remove_by_addr (struct sockaddr_in *sin) |
| static int | peercnt_remove_cb (const void *obj) |
| static int | peers_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
| static void | poke_all_peers (void) |
| static int | prune_addr_range_cb (void *obj, void *arg, int flags) |
| static void | prune_peers (void) |
| static void | prune_users (void) |
| static int | pvt_cmp_cb (void *obj, void *arg, int flags) |
| static void | pvt_destructor (void *obj) |
| static int | pvt_hash_cb (const void *obj, const int flags) |
| static int | queue_signalling (struct chan_iax2_pvt *pvt, struct ast_frame *f) |
| All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number. | |
| static int | raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd) |
| static struct iax2_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
| static void | realtime_update_peer (const char *peername, struct ast_sockaddr *sockaddr, time_t regtime) |
| static struct iax2_user * | realtime_user (const char *username, struct sockaddr_in *sin) |
| static void | reg_source_db (struct iax2_peer *p) |
| static void | register_peer_exten (struct iax2_peer *peer, int onoff) |
| static int | register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
| Verify inbound registration. | |
| static int | registry_authrequest (int callno) |
| static int | registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin) |
| static char * | regstate2str (int regstate) |
| static int | reload (void) |
| static int | reload_config (void) |
| static void | reload_firmware (int unload) |
| static void | remove_by_peercallno (struct chan_iax2_pvt *pvt) |
| static void | remove_by_transfercallno (struct chan_iax2_pvt *pvt) |
| static int | replace_callno (const void *obj) |
| static void | requirecalltoken_mark_auto (const char *name, int subclass) |
| static void | resend_with_token (int callno, struct iax_frame *f, const char *newtoken) |
| static void | save_osptoken (struct iax_frame *fr, struct iax_ies *ies) |
| static void | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
| static void | sched_delay_remove (struct sockaddr_in *sin, struct callno_entry *callno_entry) |
| static int | schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout) |
| static int | scheduled_destroy (const void *vid) |
| static int | send_apathetic_reply (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno, int sockfd, struct iax_ie_data *ied) |
| static int | send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
| static int | send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
| static int | send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
| static int | send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int) |
| static int | send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int) |
| static int | send_lagrq (const void *data) |
| static int | send_packet (struct iax_frame *f) |
| static int | send_ping (const void *data) |
| static void | send_signaling (struct chan_iax2_pvt *pvt) |
| This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point. | |
| static int | send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now) |
| static int | set_config (const char *config_file, int reload) |
| Load configuration. | |
| static void | set_config_destroy (void) |
| static void | set_hangup_source_and_cause (int callno, unsigned char causecode) |
| static void | set_peercnt_limit (struct peercnt *peercnt) |
| static int | set_peercnt_limit_all_cb (void *obj, void *arg, int flags) |
| static void | signal_condition (ast_mutex_t *lock, ast_cond_t *cond) |
| static int | socket_process (struct iax2_thread *thread) |
| static int | socket_process_meta (int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd, struct iax_frame *fr) |
| static int | socket_read (int *id, int fd, short events, void *cbdata) |
| static void | spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid) |
| static int | start_network_thread (void) |
| static void | stop_stuff (int callno) |
| static void | store_by_peercallno (struct chan_iax2_pvt *pvt) |
| static void | store_by_transfercallno (struct chan_iax2_pvt *pvt) |
| static int | timing_read (int *id, int fd, short events, void *cbdata) |
| static int | transfercallno_pvt_cmp_cb (void *obj, void *arg, int flags) |
| static int | transfercallno_pvt_hash_cb (const void *obj, const int flags) |
| static int | transmit_frame (void *data) |
| static int | transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd) |
| static int | try_firmware (char *s) |
| static int | try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
| static iax2_format | uncompress_subclass (unsigned char csub) |
| static void | unlink_peer (struct iax2_peer *peer) |
| static int | unload_module (void) |
| static void | unlock_both (unsigned short callno0, unsigned short callno1) |
| static void | unwrap_timestamp (struct iax_frame *fr) |
| static void | update_jbsched (struct chan_iax2_pvt *pvt) |
| static void | update_max_nontrunk (void) |
| static void | update_max_trunk (void) |
| static int | update_packet (struct iax_frame *f) |
| static int | update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh) |
| static int | user_cmp_cb (void *obj, void *arg, int flags) |
| static int | user_delme_cb (void *obj, void *arg, int flags) |
| static void | user_destructor (void *obj) |
| static int | user_hash_cb (const void *obj, const int flags) |
| static struct iax2_user * | user_ref (struct iax2_user *user) |
| static struct iax2_user * | user_unref (struct iax2_user *user) |
| static int | users_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
| static void | vnak_retransmit (int callno, int last) |
| static int | wait_for_peercallno (struct chan_iax2_pvt *pvt) |
Variables | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto", } |
| static char | accountcode [AST_MAX_ACCOUNT_CODE] |
| static int | adsi = 0 |
| static int | amaflags = 0 |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static int | authdebug = 0 |
| 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+1] |
| a list of frames that may need to be retransmitted | |
| static int | global_max_trunk_mtu |
| static uint16_t | global_maxcallno |
| static uint16_t | global_maxcallno_nonval |
| static int | global_rtautoclear = 120 |
| static struct ast_flags64 | globalflags = { 0 } |
| static iax2_format | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH |
| static struct ast_data_entry | iax2_data_providers [] |
| static int | iax2_encryption = 0 |
| static int(* | iax2_regfunk )(const char *username, int onoff) = NULL |
| static struct ast_switch | iax2_switch |
| static struct ast_channel_tech | iax2_tech |
| static struct ast_datastore_info | iax2_variable_datastore_info |
| static struct ao2_container * | iax_peercallno_pvts |
| Another container of iax2_pvt structures. | |
| static struct ao2_container * | iax_transfercallno_pvts |
| Another container of iax2_pvt structures. | |
| static int | iaxactivethreadcount = 0 |
| static int | iaxcompat = 0 |
| static int | iaxdebug = 0 |
| static int | iaxdefaultdpcache = 10 * 60 |
| static int | iaxdefaulttimeout = 5 |
| static int | iaxdynamicthreadcount = 0 |
| static int | iaxdynamicthreadnum = 0 |
| static int | iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT |
| static struct ast_custom_function | iaxpeer_function |
| static struct chan_iax2_pvt * | iaxs [IAX_MAX_CALLS+1] |
| an array of iax2 pvt structures | |
| static ast_mutex_t | iaxsl [ARRAY_LEN(iaxs)] |
| chan_iax2_pvt structure locks | |
| static int | iaxthreadcount = DEFAULT_THREAD_COUNT |
| static int | iaxtrunkdebug = 0 |
| static struct ast_custom_function | iaxvar_function |
| static struct io_context * | io |
| static int | jittertargetextra = 40 |
| static int | lagrq_time = 10 |
| static char | language [MAX_LANGUAGE] = "" |
| static int | last_authmethod = 0 |
| static const time_t | MAX_CALLTOKEN_DELAY = 10 |
| static int | max_reg_expire |
| static int | max_retries = 4 |
| static int | maxauthreq = 3 |
| static int | maxjitterbuffer = 1000 |
| static int | maxjitterinterps = 10 |
| static int | maxnontrunkcall = 1 |
| static int | maxtrunkcall = TRUNK_CALL_START |
| static int | min_reg_expire |
| static char | mohinterpret [MAX_MUSICCLASS] |
| static char | mohsuggest [MAX_MUSICCLASS] |
| static struct ast_netsock_list * | netsock |
| static pthread_t | netthreadid = AST_PTHREADT_NULL |
| static int | network_change_event_sched_id = -1 |
| static struct ast_event_sub * | network_change_event_subscription |
| static struct ast_netsock_list * | outsock |
| static char * | papp = "IAX2Provision" |
| static struct ao2_container * | peercnts |
| static struct ao2_container * | peers |
| static struct ast_data_handler | peers_data_provider |
| static int | ping_time = 21 |
| static struct ast_codec_pref | prefs |
| struct { | |
| unsigned int cos | |
| unsigned int tos | |
| } | qos |
| static int | randomcalltokendata |
| static char | regcontext [AST_MAX_CONTEXT] = "" |
| static int | resyncthreshold = 1000 |
| static struct ast_sched_context * | sched |
| static int | srvlookup = 0 |
| static const char | tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)" |
| static int | test_losspct = 0 |
| static struct ast_timer * | timer |
| static uint16_t | total_nonval_callno_used = 0 |
| static struct ast_taskprocessor * | transmit_processor |
| static int | trunk_maxmtu |
| static int | trunk_nmaxmtu |
| static int | trunk_timed |
| static int | trunk_untimed |
| static int | trunkfreq = 20 |
| static int | trunkmaxsize = MAX_TRUNKDATA |
| static struct ao2_container * | users |
| static struct ast_data_handler | users_data_provider |
Definition in file chan_iax2.c.
| #define ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" |
Referenced by ast_cli_netstats().
| #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" |
Referenced by ast_cli_netstats().
| #define CALLNO_TO_PTR | ( | a | ) | ((void *)(unsigned long)(a)) |
Definition at line 239 of file chan_iax2.c.
Referenced by ast_iax2_new(), iax2_call(), iax2_hangup(), and update_jbsched().
| #define CALLTOKEN_HASH_FORMAT "%s%d%u%d" |
Referenced by handle_call_token().
| #define CALLTOKEN_IE_FORMAT "%u?%s" |
Referenced by handle_call_token().
| #define DATA_EXPORT_IAX2_PEER | ( | MEMBER | ) |
Definition at line 14580 of file chan_iax2.c.
| #define DATA_EXPORT_IAX2_USER | ( | MEMBER | ) |
Definition at line 14657 of file chan_iax2.c.
| #define DEBUG_SCHED_MULTITHREAD |
Definition at line 231 of file chan_iax2.c.
| #define DEBUG_SUPPORT |
Definition at line 247 of file chan_iax2.c.
| #define DEFAULT_CONTEXT "default" |
Definition at line 266 of file chan_iax2.c.
Referenced by check_access(), handle_cli_iax2_show_users(), reload_config(), and users_data_provider_get().
| #define DEFAULT_DROP 3 |
Definition at line 245 of file chan_iax2.c.
| #define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 341 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 242 of file chan_iax2.c.
| #define DEFAULT_MAXMS 2000 |
Definition at line 339 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 241 of file chan_iax2.c.
| #define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 621 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
| #define DONT_RESCHEDULE -2 |
Definition at line 363 of file chan_iax2.c.
Referenced by __send_lagrq(), __send_ping(), iax2_destroy_helper(), send_lagrq(), and send_ping().
| #define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n" |
| #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
| #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-11s %-32.32s\n" |
| #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
| #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" |
| #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
| #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-11s %-32.32s\n" |
| #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
| #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
| #define GAMMA (0.01) |
Definition at line 252 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 429 of file chan_iax2.c.
Referenced by set_config(), and socket_process().
| #define IAX_ALREADYGONE (uint64_t)(1 << 9) |
Already disconnected
Definition at line 412 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 344 of file chan_iax2.c.
Referenced by acf_channel_read(), iax2_send(), iax2_start_transfer(), and socket_process().
| #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
Definition at line 318 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), and set_config().
| #define IAX_CAPABILITY_LOWBANDWIDTH |
Value:
(IAX_CAPABILITY_MEDBANDWIDTH & \ ~ast_format_id_to_old_bitfield(AST_FORMAT_G726) & \ ~ast_format_id_to_old_bitfield(AST_FORMAT_G726_AAL2) & \ ~ast_format_id_to_old_bitfield(AST_FORMAT_ADPCM))
Definition at line 330 of file chan_iax2.c.
Referenced by set_config().
| #define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 335 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 419 of file chan_iax2.c.
Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), socket_process(), and users_data_provider_get().
| #define IAX_CODEC_NOPREFS (uint64_t)(1 << 15) |
Force old behaviour by turning off prefs
Definition at line 418 of file chan_iax2.c.
Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), socket_process(), and users_data_provider_get().
| #define IAX_CODEC_USER_FIRST (uint64_t)(1 << 14) |
are we willing to let the other guy choose the codec?
Definition at line 417 of file chan_iax2.c.
Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), socket_process(), and users_data_provider_get().
| #define IAX_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 428 of file chan_iax2.c.
Referenced by socket_process().
| #define IAX_DELME (uint64_t)(1 << 1) |
Needs to be deleted
Definition at line 404 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 409 of file chan_iax2.c.
Referenced by __iax2_show_peers(), build_peer(), function_iaxpeer(), handle_cli_iax2_show_peer(), manager_iax2_show_peer_list(), peers_data_provider_get(), realtime_peer(), register_verify(), and set_config().
| #define IAX_ENCRYPTED (uint64_t)(1 << 12) |
Whether we should assume encrypted tx/rx
Definition at line 415 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 433 of file chan_iax2.c.
Referenced by __find_callno(), authenticate_reply(), authenticate_verify(), build_peer(), build_user(), check_access(), create_addr(), iax2_call(), iax2_queryoption(), iax2_setoption(), set_config(), and socket_process().
| #define IAX_FORCEJITTERBUF (uint64_t)(1 << 20) |
Force jitterbuffer, even when bridged to a channel that can take jitter
Definition at line 423 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 403 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 430 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 416 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 427 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 407 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 413 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 414 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 432 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 422 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 420 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 424 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 411 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 421 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 410 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 431 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 434 of file chan_iax2.c.
Referenced by check_access(), and set_config().
| #define IAX_TEMPONLY (uint64_t)(1 << 2) |
Temporary (realtime)
Definition at line 405 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 426 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 406 of file chan_iax2.c.
Referenced by __iax2_show_peers(), build_peer(), build_user(), check_access(), create_addr(), handle_cli_iax2_show_peer(), iax2_getpeertrunk(), iax2_request(), iax2_send(), manager_iax2_show_peer_list(), peers_data_provider_get(), and socket_process().
| #define IAX_TRUNKTIMESTAMPS (uint64_t)(1 << 22) |
Send trunk timestamps
Definition at line 425 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 408 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 629 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 618 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 880 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 623 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 261 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 285 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 244 of file chan_iax2.c.
| #define MIN_JITTER_BUFFER 10 |
Definition at line 619 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 238 of file chan_iax2.c.
Referenced by __auto_congest(), __get_from_jb(), acf_channel_read(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit_begin(), iax2_digit_end(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_queryoption(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), iax2_write(), and scheduled_destroy().
| #define SCHED_MULTITHREADED |
Definition at line 227 of file chan_iax2.c.
| #define schedule_action | ( | func, | |||
| data | ) | __schedule_action(func, data, __PRETTY_FUNCTION__) |
Definition at line 1485 of file chan_iax2.c.
Referenced by attempt_transmit(), auth_reject(), auto_congest(), auto_hangup(), expire_registry(), get_from_jb(), iax2_do_register_s(), iax2_poke_noanswer(), iax2_poke_peer_s(), send_lagrq(), and send_ping().
| #define TRUNK_CALL_START IAX_MAX_CALLS / 2 |
Definition at line 1095 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 626 of file chan_iax2.c.
| anonymous enum |
Definition at line 2048 of file chan_iax2.c.
02048 { 02049 /* do not allow a new call number, only search ones in use for match */ 02050 NEW_PREVENT = 0, 02051 /* search for match first, then allow a new one to be allocated */ 02052 NEW_ALLOW = 1, 02053 /* do not search for match, force a new call number */ 02054 NEW_FORCE = 2, 02055 /* do not search for match, force a new call number. Signifies call number 02056 * has been calltoken validated */ 02057 NEW_ALLOW_CALLTOKEN_VALIDATED = 3, 02058 };
| anonymous enum |
Definition at line 940 of file chan_iax2.c.
00940 { 00941 /*! Extension exists */ 00942 CACHE_FLAG_EXISTS = (1 << 0), 00943 /*! Extension is nonexistent */ 00944 CACHE_FLAG_NONEXISTENT = (1 << 1), 00945 /*! Extension can exist */ 00946 CACHE_FLAG_CANEXIST = (1 << 2), 00947 /*! Waiting to hear back response */ 00948 CACHE_FLAG_PENDING = (1 << 3), 00949 /*! Timed out */ 00950 CACHE_FLAG_TIMEOUT = (1 << 4), 00951 /*! Request transmitted */ 00952 CACHE_FLAG_TRANSMITTED = (1 << 5), 00953 /*! Timeout */ 00954 CACHE_FLAG_UNKNOWN = (1 << 6), 00955 /*! Matchmore */ 00956 CACHE_FLAG_MATCHMORE = (1 << 7), 00957 };
| enum calltoken_peer_enum |
Call token validation settings.
Definition at line 442 of file chan_iax2.c.
00442 { 00443 /*! \brief Default calltoken required unless the ip is in the ignorelist */ 00444 CALLTOKEN_DEFAULT = 0, 00445 /*! \brief Require call token validation. */ 00446 CALLTOKEN_YES = 1, 00447 /*! \brief Require call token validation after a successful registration 00448 * using call token validation occurs. */ 00449 CALLTOKEN_AUTO = 2, 00450 /*! \brief Do not require call token validation. */ 00451 CALLTOKEN_NO = 3, 00452 };
| enum iax2_state |
Definition at line 391 of file chan_iax2.c.
00391 { 00392 IAX_STATE_STARTED = (1 << 0), 00393 IAX_STATE_AUTHENTICATED = (1 << 1), 00394 IAX_STATE_TBD = (1 << 2), 00395 };
| enum iax2_thread_iostate |
Definition at line 981 of file chan_iax2.c.
00981 { 00982 IAX_IOSTATE_IDLE, 00983 IAX_IOSTATE_READY, 00984 IAX_IOSTATE_PROCESSING, 00985 IAX_IOSTATE_SCHEDREADY, 00986 };
| enum iax2_thread_type |
Definition at line 988 of file chan_iax2.c.
00988 { 00989 IAX_THREAD_TYPE_POOL, 00990 IAX_THREAD_TYPE_DYNAMIC, 00991 };
| 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 574 of file chan_iax2.c.
00574 { 00575 REG_STATE_UNREGISTERED = 0, 00576 REG_STATE_REGSENT, 00577 REG_STATE_AUTHSENT, 00578 REG_STATE_REGISTERED, 00579 REG_STATE_REJECTED, 00580 REG_STATE_TIMEOUT, 00581 REG_STATE_NOAUTH 00582 };
| 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 584 of file chan_iax2.c.
00584 { 00585 TRANSFER_NONE = 0, 00586 TRANSFER_BEGIN, 00587 TRANSFER_READY, 00588 TRANSFER_RELEASED, 00589 TRANSFER_PASSTHROUGH, 00590 TRANSFER_MBEGIN, 00591 TRANSFER_MREADY, 00592 TRANSFER_MRELEASED, 00593 TRANSFER_MPASSTHROUGH, 00594 TRANSFER_MEDIA, 00595 TRANSFER_MEDIAPASS 00596 };
| static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3542 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, AST_CAUSE_DESTINATION_OUT_OF_ORDER, ast_channel_name(), 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, ast_frame_subclass::integer, LOG_WARNING, MAX_RETRY_TIME, 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().
03543 { 03544 /* Attempt to transmit the frame to the remote peer... 03545 Called without iaxsl held. */ 03546 struct iax_frame *f = (struct iax_frame *)data; 03547 int freeme = 0; 03548 int callno = f->callno; 03549 /* Make sure this call is still active */ 03550 if (callno) 03551 ast_mutex_lock(&iaxsl[callno]); 03552 if (callno && iaxs[callno]) { 03553 if ((f->retries < 0) /* Already ACK'd */ || 03554 (f->retries >= max_retries) /* Too many attempts */) { 03555 /* Record an error if we've transmitted too many times */ 03556 if (f->retries >= max_retries) { 03557 if (f->transfer) { 03558 /* Transfer timeout */ 03559 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 03560 } else if (f->final) { 03561 iax2_destroy(callno); 03562 } else { 03563 if (iaxs[callno]->owner) 03564 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %u, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),ast_channel_name(iaxs[f->callno]->owner), f->af.frametype, f->af.subclass.integer, f->ts, f->oseqno); 03565 iaxs[callno]->error = ETIMEDOUT; 03566 if (iaxs[callno]->owner) { 03567 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER }; 03568 /* Hangup the fd */ 03569 iax2_queue_frame(callno, &fr); /* XXX */ 03570 /* Remember, owner could disappear */ 03571 if (iaxs[callno] && iaxs[callno]->owner) 03572 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03573 } else { 03574 if (iaxs[callno]->reg) { 03575 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 03576 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 03577 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 03578 } 03579 iax2_destroy(callno); 03580 } 03581 } 03582 03583 } 03584 freeme = 1; 03585 } else { 03586 /* Update it if it needs it */ 03587 update_packet(f); 03588 /* Attempt transmission */ 03589 send_packet(f); 03590 f->retries++; 03591 /* Try again later after 10 times as long */ 03592 f->retrytime *= 10; 03593 if (f->retrytime > MAX_RETRY_TIME) 03594 f->retrytime = MAX_RETRY_TIME; 03595 /* Transfer messages max out at one second */ 03596 if (f->transfer && (f->retrytime > 1000)) 03597 f->retrytime = 1000; 03598 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 03599 } 03600 } else { 03601 /* Make sure it gets freed */ 03602 f->retries = -1; 03603 freeme = 1; 03604 } 03605 03606 if (freeme) { 03607 /* Don't attempt delivery, just remove it from the queue */ 03608 AST_LIST_REMOVE(&frame_queue[callno], f, list); 03609 ast_mutex_unlock(&iaxsl[callno]); 03610 f->retrans = -1; /* this is safe because this is the scheduled function */ 03611 /* Free the IAX frame */ 03612 iax2_frame_free(f); 03613 } else if (callno) { 03614 ast_mutex_unlock(&iaxsl[callno]); 03615 } 03616 }
| static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 9046 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().
09047 { 09048 /* Called from IAX thread only, without iaxs lock */ 09049 int callno = (int)(long)(nothing); 09050 struct iax_ie_data ied; 09051 ast_mutex_lock(&iaxsl[callno]); 09052 if (iaxs[callno]) { 09053 memset(&ied, 0, sizeof(ied)); 09054 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 09055 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 09056 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 09057 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 09058 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 09059 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 09060 } 09061 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 09062 } 09063 ast_mutex_unlock(&iaxsl[callno]); 09064 }
| static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 4728 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().
04729 { 04730 int callno = PTR_TO_CALLNO(nothing); 04731 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } }; 04732 ast_mutex_lock(&iaxsl[callno]); 04733 if (iaxs[callno]) { 04734 iaxs[callno]->initid = -1; 04735 iax2_queue_frame(callno, &f); 04736 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 04737 } 04738 ast_mutex_unlock(&iaxsl[callno]); 04739 }
| static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 9095 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().
09096 { 09097 /* Called from IAX thread only, without iaxs lock */ 09098 int callno = (int)(long)(nothing); 09099 struct iax_ie_data ied; 09100 ast_mutex_lock(&iaxsl[callno]); 09101 if (iaxs[callno]) { 09102 memset(&ied, 0, sizeof(ied)); 09103 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 09104 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 09105 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 09106 } 09107 ast_mutex_unlock(&iaxsl[callno]); 09108 }
| 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 3328 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().
03329 { 03330 /* Just deliver the packet by using queueing. This is called by 03331 the IAX thread with the iaxsl lock held. */ 03332 struct iax_frame *fr = data; 03333 fr->retrans = -1; 03334 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 03335 if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE)) 03336 iax2_queue_frame(fr->callno, &fr->af); 03337 /* Free our iax frame */ 03338 iax2_frame_free(fr); 03339 /* And don't run again */ 03340 return 0; 03341 }
| static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8673 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().
08674 { 08675 struct iax2_peer *peer = (struct iax2_peer *) data; 08676 08677 if (!peer) 08678 return; 08679 if (peer->expire == -1) { 08680 /* Removed already (possibly through CLI), ignore */ 08681 return; 08682 } 08683 08684 peer->expire = -1; 08685 08686 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name); 08687 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 08688 realtime_update_peer(peer->name, &peer->addr, 0); 08689 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08690 /* modify entry in peercnts table as _not_ registered */ 08691 peercnt_modify(0, 0, &peer->addr); 08692 /* Reset the address */ 08693 memset(&peer->addr, 0, sizeof(peer->addr)); 08694 /* Reset expiry value */ 08695 peer->expiry = min_reg_expire; 08696 if (!ast_test_flag64(peer, IAX_TEMPONLY)) 08697 ast_db_del("IAX/Registry", peer->name); 08698 register_peer_exten(peer, 0); 08699 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 08700 if (iax2_regfunk) 08701 iax2_regfunk(peer->name, 0); 08702 08703 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) 08704 unlink_peer(peer); 08705 08706 peer_unref(peer); 08707 }
| 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 2831 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().
02832 { 02833 int res = 0; 02834 int x; 02835 /* this call is calltoken validated as long as it is either NEW_FORCE 02836 * or NEW_ALLOW_CALLTOKEN_VALIDATED */ 02837 int validated = (new > NEW_ALLOW) ? 1 : 0; 02838 char host[80]; 02839 02840 if (new <= NEW_ALLOW) { 02841 if (callno) { 02842 struct chan_iax2_pvt *pvt; 02843 struct chan_iax2_pvt tmp_pvt = { 02844 .callno = dcallno, 02845 .peercallno = callno, 02846 .transfercallno = callno, 02847 /* hack!! */ 02848 .frames_received = check_dcallno, 02849 }; 02850 02851 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 02852 /* this works for finding normal call numbers not involving transfering */ 02853 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02854 if (return_locked) { 02855 ast_mutex_lock(&iaxsl[pvt->callno]); 02856 } 02857 res = pvt->callno; 02858 ao2_ref(pvt, -1); 02859 pvt = NULL; 02860 return res; 02861 } 02862 /* this searches for transfer call numbers that might not get caught otherwise */ 02863 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr)); 02864 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer)); 02865 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02866 if (return_locked) { 02867 ast_mutex_lock(&iaxsl[pvt->callno]); 02868 } 02869 res = pvt->callno; 02870 ao2_ref(pvt, -1); 02871 pvt = NULL; 02872 return res; 02873 } 02874 } 02875 /* This will occur on the first response to a message that we initiated, 02876 * such as a PING. */ 02877 if (dcallno) { 02878 ast_mutex_lock(&iaxsl[dcallno]); 02879 } 02880 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 02881 iaxs[dcallno]->peercallno = callno; 02882 res = dcallno; 02883 store_by_peercallno(iaxs[dcallno]); 02884 if (!res || !return_locked) { 02885 ast_mutex_unlock(&iaxsl[dcallno]); 02886 } 02887 return res; 02888 } 02889 if (dcallno) { 02890 ast_mutex_unlock(&iaxsl[dcallno]); 02891 } 02892 #ifdef IAX_OLD_FIND 02893 /* If we get here, we SHOULD NOT find a call structure for this 02894 callno; if we do, it means that there is a call structure that 02895 has a peer callno but did NOT get entered into the hash table, 02896 which is bad. 02897 02898 If we find a call structure using this old, slow method, output a log 02899 message so we'll know about it. After a few months of leaving this in 02900 place, if we don't hear about people seeing these messages, we can 02901 remove this code for good. 02902 */ 02903 02904 for (x = 1; !res && x < maxnontrunkcall; x++) { 02905 ast_mutex_lock(&iaxsl[x]); 02906 if (iaxs[x]) { 02907 /* Look for an exact match */ 02908 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02909 res = x; 02910 } 02911 } 02912 if (!res || !return_locked) 02913 ast_mutex_unlock(&iaxsl[x]); 02914 } 02915 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 02916 ast_mutex_lock(&iaxsl[x]); 02917 if (iaxs[x]) { 02918 /* Look for an exact match */ 02919 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02920 res = x; 02921 } 02922 } 02923 if (!res || !return_locked) 02924 ast_mutex_unlock(&iaxsl[x]); 02925 } 02926 #endif 02927 } 02928 if (!res && (new >= NEW_ALLOW)) { 02929 struct callno_entry *callno_entry; 02930 /* It may seem odd that we look through the peer list for a name for 02931 * this *incoming* call. Well, it is weird. However, users don't 02932 * have an IP address/port number that we can match against. So, 02933 * this is just checking for a peer that has that IP/port and 02934 * assuming that we have a user of the same name. This isn't always 02935 * correct, but it will be changed if needed after authentication. */ 02936 if (!iax2_getpeername(*sin, host, sizeof(host))) 02937 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 02938 02939 if (peercnt_add(sin)) { 02940 /* This address has hit its callnumber limit. When the limit 02941 * is reached, the connection is not added to the peercnts table.*/ 02942 return 0; 02943 } 02944 02945 if (!(callno_entry = get_unused_callno(0, validated))) { 02946 /* since we ran out of space, remove the peercnt 02947 * entry we added earlier */ 02948 peercnt_remove_by_addr(sin); 02949 ast_log(LOG_WARNING, "No more space\n"); 02950 return 0; 02951 } 02952 x = callno_entry->callno; 02953 ast_mutex_lock(&iaxsl[x]); 02954 02955 iaxs[x] = new_iax(sin, host); 02956 update_max_nontrunk(); 02957 if (iaxs[x]) { 02958 if (iaxdebug) 02959 ast_debug(1, "Creating new call structure %d\n", x); 02960 iaxs[x]->callno_entry = callno_entry; 02961 iaxs[x]->sockfd = sockfd; 02962 iaxs[x]->addr.sin_port = sin->sin_port; 02963 iaxs[x]->addr.sin_family = sin->sin_family; 02964 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 02965 iaxs[x]->peercallno = callno; 02966 iaxs[x]->callno = x; 02967 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 02968 iaxs[x]->expiry = min_reg_expire; 02969 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 02970 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 02971 iaxs[x]->amaflags = amaflags; 02972 ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 02973 ast_string_field_set(iaxs[x], accountcode, accountcode); 02974 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 02975 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 02976 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot); 02977 02978 if (iaxs[x]->peercallno) { 02979 store_by_peercallno(iaxs[x]); 02980 } 02981 } else { 02982 ast_log(LOG_WARNING, "Out of resources\n"); 02983 ast_mutex_unlock(&iaxsl[x]); 02984 replace_callno(callno_entry); 02985 return 0; 02986 } 02987 if (!return_locked) 02988 ast_mutex_unlock(&iaxsl[x]); 02989 res = x; 02990 } 02991 return res; 02992 }
| static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 4120 of file chan_iax2.c.
References __do_deliver(), ast_codec_interp_len(), ast_format_copy(), ast_format_from_old_bitfield(), 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_subclass::format, 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().
04121 { 04122 int callno = PTR_TO_CALLNO(p); 04123 struct chan_iax2_pvt *pvt = NULL; 04124 struct iax_frame *fr; 04125 jb_frame frame; 04126 int ret; 04127 long ms; 04128 long next; 04129 struct timeval now = ast_tvnow(); 04130 04131 /* Make sure we have a valid private structure before going on */ 04132 ast_mutex_lock(&iaxsl[callno]); 04133 pvt = iaxs[callno]; 04134 if (!pvt) { 04135 /* No go! */ 04136 ast_mutex_unlock(&iaxsl[callno]); 04137 return; 04138 } 04139 04140 pvt->jbid = -1; 04141 04142 /* round up a millisecond since ast_sched_runq does; */ 04143 /* prevents us from spinning while waiting for our now */ 04144 /* to catch up with runq's now */ 04145 now.tv_usec += 1000; 04146 04147 ms = ast_tvdiff_ms(now, pvt->rxcore); 04148 04149 if(ms >= (next = jb_next(pvt->jb))) { 04150 struct ast_format voicefmt; 04151 ast_format_from_old_bitfield(&voicefmt, pvt->voiceformat); 04152 ret = jb_get(pvt->jb, &frame, ms, ast_codec_interp_len(&voicefmt)); 04153 switch(ret) { 04154 case JB_OK: 04155 fr = frame.data; 04156 __do_deliver(fr); 04157 /* __do_deliver() can cause the call to disappear */ 04158 pvt = iaxs[callno]; 04159 break; 04160 case JB_INTERP: 04161 { 04162 struct ast_frame af = { 0, }; 04163 04164 /* create an interpolation frame */ 04165 af.frametype = AST_FRAME_VOICE; 04166 ast_format_copy(&af.subclass.format, &voicefmt); 04167 af.samples = frame.ms * (ast_format_rate(&voicefmt) / 1000); 04168 af.src = "IAX2 JB interpolation"; 04169 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 04170 af.offset = AST_FRIENDLY_OFFSET; 04171 04172 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 04173 * which we'd need to malloc, and then it would free it. That seems like a drag */ 04174 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) { 04175 iax2_queue_frame(callno, &af); 04176 /* iax2_queue_frame() could cause the call to disappear */ 04177 pvt = iaxs[callno]; 04178 } 04179 } 04180 break; 04181 case JB_DROP: 04182 iax2_frame_free(frame.data); 04183 break; 04184 case JB_NOFRAME: 04185 case JB_EMPTY: 04186 /* do nothing */ 04187 break; 04188 default: 04189 /* shouldn't happen */ 04190 break; 04191 } 04192 } 04193 if (pvt) 04194 update_jbsched(pvt); 04195 ast_mutex_unlock(&iaxsl[callno]); 04196 }
| static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8343 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
08344 { 08345 struct iax2_registry *reg = (struct iax2_registry *)data; 08346 reg->expire = -1; 08347 iax2_do_register(reg); 08348 }
| static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 12047 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().
12048 { 12049 struct iax2_peer *peer = (struct iax2_peer *)data; 12050 int callno; 12051 12052 if (peer->lastms > -1) { 12053 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 12054 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 12055 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 12056 } 12057 if ((callno = peer->callno) > 0) { 12058 ast_mutex_lock(&iaxsl[callno]); 12059 iax2_destroy(callno); 12060 ast_mutex_unlock(&iaxsl[callno]); 12061 } 12062 peer->callno = 0; 12063 peer->lastms = -1; 12064 /* Try again quickly */ 12065 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 12066 if (peer->pokeexpire == -1) 12067 peer_unref(peer); 12068 }
| static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9155 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
09156 { 09157 struct iax2_peer *peer = (struct iax2_peer *)data; 09158 iax2_poke_peer(peer, 0); 09159 peer_unref(peer); 09160 }
| static int __iax2_show_peers | ( | int | fd, | |
| int * | total, | |||
| struct mansession * | s, | |||
| const int | argc, | |||
| const char *const | argv[] | |||
| ) | [static] |
Definition at line 6716 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli(), ast_copy_string(), ast_inet_ntoa(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_sockaddr_to_sin, ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag64, astman_append(), iax2_peer::description, 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().
06717 { 06718 regex_t regexbuf; 06719 int havepattern = 0; 06720 int total_peers = 0; 06721 int online_peers = 0; 06722 int offline_peers = 0; 06723 int unmonitored_peers = 0; 06724 struct ao2_iterator i; 06725 06726 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-11s %-32.32s\n" 06727 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-11s %-32.32s\n" 06728 06729 struct iax2_peer *peer = NULL; 06730 char name[256]; 06731 struct ast_str *encmethods = ast_str_alloca(256); 06732 int registeredonly=0; 06733 char idtext[256] = ""; 06734 switch (argc) { 06735 case 6: 06736 if (!strcasecmp(argv[3], "registered")) 06737 registeredonly = 1; 06738 else 06739 return RESULT_SHOWUSAGE; 06740 if (!strcasecmp(argv[4], "like")) { 06741 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 06742 return RESULT_SHOWUSAGE; 06743 havepattern = 1; 06744 } else 06745 return RESULT_SHOWUSAGE; 06746 break; 06747 case 5: 06748 if (!strcasecmp(argv[3], "like")) { 06749 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 06750 return RESULT_SHOWUSAGE; 06751 havepattern = 1; 06752 } else 06753 return RESULT_SHOWUSAGE; 06754 break; 06755 case 4: 06756 if (!strcasecmp(argv[3], "registered")) 06757 registeredonly = 1; 06758 else 06759 return RESULT_SHOWUSAGE; 06760 break; 06761 case 3: 06762 break; 06763 default: 06764 return RESULT_SHOWUSAGE; 06765 } 06766 06767 06768 if (!s) 06769 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", "Description"); 06770 06771 i = ao2_iterator_init(peers, 0); 06772 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) { 06773 char nm[20]; 06774 char status[20]; 06775 int retstatus; 06776 struct sockaddr_in peer_addr; 06777 06778 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 06779 06780 if (registeredonly && !peer_addr.sin_addr.s_addr) { 06781 continue; 06782 } 06783 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) { 06784 continue; 06785 } 06786 06787 if (!ast_strlen_zero(peer->username)) 06788 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 06789 else 06790 ast_copy_string(name, peer->name, sizeof(name)); 06791 06792 encmethods_to_str(peer->encmethods, encmethods); 06793 retstatus = peer_status(peer, status, sizeof(status)); 06794 if (retstatus > 0) 06795 online_peers++; 06796 else if (!retstatus) 06797 offline_peers++; 06798 else 06799 unmonitored_peers++; 06800 06801 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 06802 06803 if (s) { 06804 astman_append(s, 06805 "Event: PeerEntry\r\n%s" 06806 "Channeltype: IAX2\r\n" 06807 "ObjectName: %s\r\n" 06808 "ChanObjectType: peer\r\n" 06809 "IPaddress: %s\r\n" 06810 "IPport: %d\r\n" 06811 "Dynamic: %s\r\n" 06812 "Trunk: %s\r\n" 06813 "Encryption: %s\r\n" 06814 "Status: %s\r\n" 06815 "Description: %s\r\n\r\n", 06816 idtext, 06817 name, 06818 ast_sockaddr_stringify_addr(&peer->addr), 06819 ast_sockaddr_port(&peer->addr), 06820 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no", 06821 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no", 06822 peer->encmethods ? ast_str_buffer(encmethods) : "no", 06823 status, 06824 peer->description); 06825 } else { 06826 ast_cli(fd, FORMAT, name, 06827 ast_sockaddr_stringify_addr(&peer->addr), 06828 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 06829 nm, 06830 ast_sockaddr_port(&peer->addr), 06831 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ", 06832 peer->encmethods ? "(E)" : " ", 06833 status, 06834 peer->description); 06835 } 06836 total_peers++; 06837 } 06838 ao2_iterator_destroy(&i); 06839 06840 if (!s) 06841 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n", 06842 total_peers, online_peers, offline_peers, unmonitored_peers); 06843 06844 if (havepattern) 06845 regfree(®exbuf); 06846 06847 if (total) 06848 *total = total_peers; 06849 06850 return RESULT_SUCCESS; 06851 #undef FORMAT 06852 #undef FORMAT2 06853 }
| static void __reg_module | ( | void | ) | [static] |
Definition at line 14896 of file chan_iax2.c.
| static int __schedule_action | ( | void(*)(const void *data) | func, | |
| const void * | data, | |||
| const char * | funcname | |||
| ) | [static] |
Definition at line 1460 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.
01461 { 01462 struct iax2_thread *thread = NULL; 01463 static time_t lasterror; 01464 static time_t t; 01465 01466 thread = find_idle_thread(); 01467 01468 if (thread != NULL) { 01469 thread->schedfunc = func; 01470 thread->scheddata = data; 01471 thread->iostate = IAX_IOSTATE_SCHEDREADY; 01472 #ifdef DEBUG_SCHED_MULTITHREAD 01473 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 01474 #endif 01475 signal_condition(&thread->lock, &thread->cond); 01476 return 0; 01477 } 01478 time(&t); 01479 if (t != lasterror) 01480 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n"); 01481 lasterror = t; 01482 01483 return -1; 01484 }
| 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 7542 of file chan_iax2.c.
References ast_frame::data, ast_frame::datalen, ast_frame::frametype, iax2_send(), ast_frame_subclass::integer, 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().
07544 { 07545 struct ast_frame f = { 0, }; 07546 int res = 0; 07547 07548 f.frametype = type; 07549 f.subclass.integer = command; 07550 f.datalen = datalen; 07551 f.src = __FUNCTION__; 07552 f.data.ptr = (void *) data; 07553 07554 if ((res = queue_signalling(i, &f)) <= 0) { 07555 return res; 07556 } 07557 07558 return iax2_send(i, &f, ts, seqno, now, transfer, final); 07559 }
| static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1569 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, iax2_thread::callno, DONT_RESCHEDULE, iax2_sched_add(), IAX_COMMAND_LAGRQ, chan_iax2_pvt::lagid, send_command(), and send_lagrq().
Referenced by send_lagrq().
01570 { 01571 int callno = (long) data; 01572 01573 ast_mutex_lock(&iaxsl[callno]); 01574 01575 if (iaxs[callno]) { 01576 if (iaxs[callno]->peercallno) { 01577 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01578 if (iaxs[callno]->lagid != DONT_RESCHEDULE) { 01579 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01580 } 01581 } 01582 } else { 01583 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno); 01584 } 01585 01586 ast_mutex_unlock(&iaxsl[callno]); 01587 }
| static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1502 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, iax2_thread::callno, DONT_RESCHEDULE, iax2_sched_add(), IAX_COMMAND_PING, chan_iax2_pvt::pingid, send_command(), and send_ping().
Referenced by send_ping().
01503 { 01504 int callno = (long) data; 01505 01506 ast_mutex_lock(&iaxsl[callno]); 01507 01508 if (iaxs[callno]) { 01509 if (iaxs[callno]->peercallno) { 01510 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01511 if (iaxs[callno]->pingid != DONT_RESCHEDULE) { 01512 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01513 } 01514 } 01515 } else { 01516 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno); 01517 } 01518 01519 ast_mutex_unlock(&iaxsl[callno]); 01520 }
| static int __unload_module | ( | void | ) | [static] |
Definition at line 14382 of file chan_iax2.c.
References ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_context_find(), ast_data_unregister, ast_format_cap_destroy(), ast_manager_unregister(), ast_mutex_destroy, ast_netsock_release(), AST_PTHREADT_NULL, ast_sched_context_destroy(), ast_taskprocessor_unreference(), AST_TEST_UNREGISTER, ast_timer_close(), ast_unload_realtime(), ast_unregister_application(), ast_unregister_switch(), ast_channel_tech::capabilities, cleanup_thread_list(), delete_users(), iax2_destroy(), iax_provision_unload(), network_change_event_unsubscribe(), and reload_firmware().
14383 { 14384 struct ast_context *con; 14385 int x; 14386 14387 network_change_event_unsubscribe(); 14388 14389 ast_manager_unregister("IAXpeers"); 14390 ast_manager_unregister("IAXpeerlist"); 14391 ast_manager_unregister("IAXnetstats"); 14392 ast_manager_unregister("IAXregistry"); 14393 ast_unregister_application(papp); 14394 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14395 ast_unregister_switch(&iax2_switch); 14396 ast_channel_unregister(&iax2_tech); 14397 14398 if (netthreadid != AST_PTHREADT_NULL) { 14399 pthread_cancel(netthreadid); 14400 pthread_kill(netthreadid, SIGURG); 14401 pthread_join(netthreadid, NULL); 14402 } 14403 14404 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14405 if (iaxs[x]) { 14406 iax2_destroy(x); 14407 } 14408 } 14409 14410 /* Call for all threads to halt */ 14411 cleanup_thread_list(&idle_list); 14412 cleanup_thread_list(&active_list); 14413 cleanup_thread_list(&dynamic_list); 14414 14415 ast_netsock_release(netsock); 14416 ast_netsock_release(outsock); 14417 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14418 if (iaxs[x]) { 14419 iax2_destroy(x); 14420 } 14421 } 14422 ast_manager_unregister( "IAXpeers" ); 14423 ast_manager_unregister( "IAXpeerlist" ); 14424 ast_manager_unregister( "IAXnetstats" ); 14425 ast_manager_unregister( "IAXregistry" ); 14426 ast_unregister_application(papp); 14427 #ifdef TEST_FRAMEWORK 14428 AST_TEST_UNREGISTER(test_iax2_peers_get); 14429 AST_TEST_UNREGISTER(test_iax2_users_get); 14430 #endif 14431 ast_data_unregister(NULL); 14432 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14433 ast_unregister_switch(&iax2_switch); 14434 ast_channel_unregister(&iax2_tech); 14435 delete_users(); 14436 iax_provision_unload(); 14437 reload_firmware(1); 14438 14439 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14440 ast_mutex_destroy(&iaxsl[x]); 14441 } 14442 14443 ao2_ref(peers, -1); 14444 ao2_ref(users, -1); 14445 ao2_ref(iax_peercallno_pvts, -1); 14446 ao2_ref(iax_transfercallno_pvts, -1); 14447 ao2_ref(peercnts, -1); 14448 ao2_ref(callno_limits, -1); 14449 ao2_ref(calltoken_ignores, -1); 14450 ao2_ref(callno_pool, -1); 14451 ao2_ref(callno_pool_trunk, -1); 14452 if (timer) { 14453 ast_timer_close(timer); 14454 } 14455 transmit_processor = ast_taskprocessor_unreference(transmit_processor); 14456 ast_sched_context_destroy(sched); 14457 sched = NULL; 14458 14459 con = ast_context_find(regcontext); 14460 if (con) 14461 ast_context_destroy(con, "IAX2"); 14462 ast_unload_realtime("iaxpeers"); 14463 14464 iax2_tech.capabilities = ast_format_cap_destroy(iax2_tech.capabilities); 14465 return 0; 14466 }
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 14896 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 14022 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, IAX_CALLENCRYPTED, LOG_ERROR, chan_iax2_pvt::osptoken, PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, and chan_iax2_pvt::username.
14023 { 14024 struct chan_iax2_pvt *pvt; 14025 unsigned int callno; 14026 int res = 0; 14027 14028 if (!chan || chan->tech != &iax2_tech) { 14029 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n"); 14030 return -1; 14031 } 14032 14033 callno = PTR_TO_CALLNO(chan->tech_pvt); 14034 ast_mutex_lock(&iaxsl[callno]); 14035 if (!(pvt = iaxs[callno])) { 14036 ast_mutex_unlock(&iaxsl[callno]); 14037 return -1; 14038 } 14039 14040 if (!strcasecmp(args, "osptoken")) { 14041 ast_copy_string(buf, pvt->osptoken, buflen); 14042 } else if (!strcasecmp(args, "peerip")) { 14043 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen); 14044 } else if (!strcasecmp(args, "peername")) { 14045 ast_copy_string(buf, pvt->username, buflen); 14046 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) { 14047 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : ""); 14048 } else { 14049 res = -1; 14050 } 14051 14052 ast_mutex_unlock(&iaxsl[callno]); 14053 14054 return res; 14055 }
| static int acf_iaxvar_read | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 9869 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.
09870 { 09871 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09872 AST_LIST_HEAD(, ast_var_t) *varlist; 09873 struct ast_var_t *var; 09874 09875 if (!variablestore) { 09876 *buf = '\0'; 09877 return 0; 09878 } 09879 varlist = variablestore->data; 09880 09881 AST_LIST_LOCK(varlist); 09882 AST_LIST_TRAVERSE(varlist, var, entries) { 09883 if (strcmp(var->name, data) == 0) { 09884 ast_copy_string(buf, var->value, len); 09885 break; 09886 } 09887 } 09888 AST_LIST_UNLOCK(varlist); 09889 return 0; 09890 }
| static int acf_iaxvar_write | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| const char * | value | |||
| ) | [static] |
Definition at line 9892 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.
09893 { 09894 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09895 AST_LIST_HEAD(, ast_var_t) *varlist; 09896 struct ast_var_t *var; 09897 09898 if (!variablestore) { 09899 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 09900 if (!variablestore) { 09901 ast_log(LOG_ERROR, "Memory allocation error\n"); 09902 return -1; 09903 } 09904 varlist = ast_calloc(1, sizeof(*varlist)); 09905 if (!varlist) { 09906 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09907 return -1; 09908 } 09909 09910 AST_LIST_HEAD_INIT(varlist); 09911 variablestore->data = varlist; 09912 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 09913 ast_channel_datastore_add(chan, variablestore); 09914 } else 09915 varlist = variablestore->data; 09916 09917 AST_LIST_LOCK(varlist); 09918 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) { 09919 if (strcmp(var->name, data) == 0) { 09920 AST_LIST_REMOVE_CURRENT(entries); 09921 ast_var_delete(var); 09922 break; 09923 } 09924 } 09925 AST_LIST_TRAVERSE_SAFE_END; 09926 var = ast_var_assign(data, value); 09927 if (var) 09928 AST_LIST_INSERT_TAIL(varlist, var, entries); 09929 else 09930 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09931 AST_LIST_UNLOCK(varlist); 09932 return 0; 09933 }
| static int add_calltoken_ignore | ( | const char * | addr | ) | [static] |
Definition at line 2572 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().
02573 { 02574 struct addr_range tmp; 02575 struct addr_range *addr_range = NULL; 02576 struct ast_ha *ha = NULL; 02577 int error = 0; 02578 02579 if (ast_strlen_zero(addr)) { 02580 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr); 02581 return -1; 02582 } 02583 02584 ha = ast_append_ha("permit", addr, NULL, &error); 02585 02586 /* check for valid config information */ 02587 if (error) { 02588 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr); 02589 return -1; 02590 } 02591 02592 ast_copy_ha(ha, &tmp.ha); 02593 /* find or create the addr_range */ 02594 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) { 02595 ao2_lock(addr_range); 02596 addr_range->delme = 0; 02597 ao2_unlock(addr_range); 02598 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02599 /* copy over config data into addr_range object */ 02600 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */ 02601 ao2_link(calltoken_ignores, addr_range); 02602 } else { 02603 ast_free_ha(ha); 02604 return -1; 02605 } 02606 02607 ast_free_ha(ha); 02608 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02609 02610 return 0; 02611 }
| static void add_empty_calltoken_ie | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ie_data * | ied | |||
| ) | [static] |
Definition at line 4802 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().
04803 { 04804 /* first make sure their are two empty bytes left in ied->buf */ 04805 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) { 04806 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */ 04807 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */ 04808 pvt->calltoken_ie_len = 2; 04809 } 04810 }
| static int addr_range_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2224 of file chan_iax2.c.
References ast_ha::addr, ast_sockaddr_cmp_addr(), CMP_MATCH, CMP_STOP, addr_range::ha, and ast_ha::netmask.
Referenced by load_objects().
02225 { 02226 struct addr_range *lim1 = obj, *lim2 = arg; 02227 return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) && 02228 !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ? 02229 CMP_MATCH | CMP_STOP : 0; 02230 }
| static int addr_range_delme_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2209 of file chan_iax2.c.
References addr_range::delme.
Referenced by set_config_destroy().
02210 { 02211 struct addr_range *lim = obj; 02212 lim->delme = 1; 02213 return 0; 02214 }
| static int addr_range_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 2216 of file chan_iax2.c.
References ast_ha::addr, ast_sockaddr_to_sin, and addr_range::ha.
Referenced by load_objects().
02217 { 02218 const struct addr_range *lim = obj; 02219 struct sockaddr_in sin; 02220 ast_sockaddr_to_sin(&lim->ha.addr, &sin); 02221 return abs((int) sin.sin_addr.s_addr); 02222 }
| static int addr_range_match_address_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2244 of file chan_iax2.c.
References ast_ha::addr, ast_sockaddr_to_sin, CMP_MATCH, CMP_STOP, addr_range::ha, and ast_ha::netmask.
Referenced by calltoken_required(), and set_peercnt_limit().
02245 { 02246 struct addr_range *addr_range = obj; 02247 struct sockaddr_in *sin = arg; 02248 struct sockaddr_in ha_netmask_sin; 02249 struct sockaddr_in ha_addr_sin; 02250 02251 ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin); 02252 ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin); 02253 02254 if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) { 02255 return CMP_MATCH | CMP_STOP; 02256 } 02257 return 0; 02258 }
| static int apply_context | ( | struct iax2_context * | con, | |
| const char * | context | |||
| ) | [static] |
Definition at line 7600 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
07601 { 07602 while(con) { 07603 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 07604 return -1; 07605 con = con->next; 07606 } 07607 return 0; 07608 }
| static int ast_cli_netstats | ( | struct mansession * | s, | |
| int | fd, | |||
| int | limit_fmt | |||
| ) | [static] |
Definition at line 7301 of file chan_iax2.c.
References ACN_FORMAT1, ACN_FORMAT2, ARRAY_LEN, ast_channel_name(), 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, 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, and chan_iax2_pvt::remote_rr.
Referenced by handle_cli_iax2_show_netstats(), and manager_iax2_show_netstats().
07302 { 07303 int x; 07304 int numchans = 0; 07305 char first_message[10] = { 0, }; 07306 char last_message[10] = { 0, }; 07307 #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" 07308 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" 07309 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07310 ast_mutex_lock(&iaxsl[x]); 07311 if (iaxs[x]) { 07312 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 07313 jb_info jbinfo; 07314 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 07315 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 07316 07317 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07318 jb_getinfo(iaxs[x]->jb, &jbinfo); 07319 localjitter = jbinfo.jitter; 07320 localdelay = jbinfo.current - jbinfo.min; 07321 locallost = jbinfo.frames_lost; 07322 locallosspct = jbinfo.losspct/1000; 07323 localdropped = jbinfo.frames_dropped; 07324 localooo = jbinfo.frames_ooo; 07325 } else { 07326 localjitter = -1; 07327 localdelay = 0; 07328 locallost = -1; 07329 locallosspct = -1; 07330 localdropped = 0; 07331 localooo = -1; 07332 } 07333 if (s) 07334 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07335 iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)", 07336 iaxs[x]->pingtime, 07337 localjitter, 07338 localdelay, 07339 locallost, 07340 locallosspct, 07341 localdropped, 07342 localooo, 07343 iaxs[x]->frames_received/1000, 07344 iaxs[x]->remote_rr.jitter, 07345 iaxs[x]->remote_rr.delay, 07346 iaxs[x]->remote_rr.losscnt, 07347 iaxs[x]->remote_rr.losspct, 07348 iaxs[x]->remote_rr.dropped, 07349 iaxs[x]->remote_rr.ooo, 07350 iaxs[x]->remote_rr.packets/1000, 07351 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07352 first_message, 07353 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07354 last_message); 07355 else 07356 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07357 iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)", 07358 iaxs[x]->pingtime, 07359 localjitter, 07360 localdelay, 07361 locallost, 07362 locallosspct, 07363 localdropped, 07364 localooo, 07365 iaxs[x]->frames_received/1000, 07366 iaxs[x]->remote_rr.jitter, 07367 iaxs[x]->remote_rr.delay, 07368 iaxs[x]->remote_rr.losscnt, 07369 iaxs[x]->remote_rr.losspct, 07370 iaxs[x]->remote_rr.dropped, 07371 iaxs[x]->remote_rr.ooo, 07372 iaxs[x]->remote_rr.packets/1000, 07373 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07374 first_message, 07375 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07376 last_message); 07377 numchans++; 07378 } 07379 ast_mutex_unlock(&iaxsl[x]); 07380 } 07381 07382 return numchans; 07383 }
| AST_DATA_STRUCTURE | ( | iax2_user | , | |
| DATA_EXPORT_IAX2_USER | ||||
| ) |
| AST_DATA_STRUCTURE | ( | iax2_peer | , | |
| DATA_EXPORT_IAX2_PEER | ||||
| ) |
| static struct ast_channel* ast_iax2_new | ( | int | callno, | |
| int | state, | |||
| iax2_format | capability, | |||
| const char * | linkedid | |||
| ) | [static, read] |
Create new call, interface with the PBX core.
Definition at line 5787 of file chan_iax2.c.
References chan_iax2_pvt::accountcode, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, ast_party_caller::ani, chan_iax2_pvt::ani, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_calloc, ast_channel_alloc, ast_channel_datastore_add(), ast_channel_name(), ast_channel_release(), ast_copy_string(), ast_datastore_alloc, ast_datastore_free(), ast_debug, ast_format_cap_from_old_bitfield(), ast_format_copy(), 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_strlen_zero(), ast_var_assign(), ast_channel::caller, chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, chan_iax2_pvt::callno, CALLNO_TO_PTR, chan_iax2_pvt::capability, chan_iax2_pvt::cid_name, chan_iax2_pvt::cid_num, ast_channel::context, chan_iax2_pvt::context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_channel::dialed, chan_iax2_pvt::dnid, ast_var_t::entries, ast_channel::exten, chan_iax2_pvt::exten, ast_party_redirecting::from, chan_iax2_pvt::host, iax2_ami_channelupdate(), chan_iax2_pvt::iaxvars, ast_party_caller::id, ast_datastore::inheritance, chan_iax2_pvt::language, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_party_id::name, ast_channel::nativeformats, ast_variable::next, ast_party_dialed::number, ast_party_id::number, chan_iax2_pvt::owner, chan_iax2_pvt::parkinglot, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_party_number::plan, ast_party_number::presentation, ast_party_name::presentation, ast_channel::rawreadformat, ast_channel::rawwriteformat, chan_iax2_pvt::rdnis, ast_channel::readformat, ast_channel::redirecting, ast_party_dialed::str, ast_party_number::str, ast_channel::tech, ast_channel::tech_pvt, ast_party_dialed::transit_network_select, ast_party_number::valid, ast_variable::value, var, chan_iax2_pvt::vars, and ast_channel::writeformat.
Referenced by iax2_request(), and socket_process().
05788 { 05789 struct ast_channel *tmp; 05790 struct chan_iax2_pvt *i; 05791 struct ast_variable *v = NULL; 05792 struct ast_format tmpfmt; 05793 05794 if (!(i = iaxs[callno])) { 05795 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 05796 return NULL; 05797 } 05798 05799 /* Don't hold call lock */ 05800 ast_mutex_unlock(&iaxsl[callno]); 05801 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); 05802 ast_mutex_lock(&iaxsl[callno]); 05803 if (i != iaxs[callno]) { 05804 if (tmp) { 05805 /* unlock and relock iaxsl[callno] to preserve locking order */ 05806 ast_mutex_unlock(&iaxsl[callno]); 05807 tmp = ast_channel_release(tmp); 05808 ast_mutex_lock(&iaxsl[callno]); 05809 } 05810 return NULL; 05811 } 05812 iax2_ami_channelupdate(i); 05813 if (!tmp) 05814 return NULL; 05815 tmp->tech = &iax2_tech; 05816 /* We can support any format by default, until we get restricted */ 05817 ast_format_cap_from_old_bitfield(tmp->nativeformats, capability); 05818 ast_best_codec(tmp->nativeformats, &tmpfmt); 05819 05820 ast_format_copy(&tmp->readformat, &tmpfmt); 05821 ast_format_copy(&tmp->rawreadformat, &tmpfmt); 05822 ast_format_copy(&tmp->writeformat, &tmpfmt); 05823 ast_format_copy(&tmp->rawwriteformat, &tmpfmt); 05824 05825 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 05826 05827 if (!ast_strlen_zero(i->parkinglot)) 05828 ast_channel_parkinglot_set(tmp, i->parkinglot); 05829 /* Don't use ast_set_callerid() here because it will 05830 * generate a NewCallerID event before the NewChannel event */ 05831 if (!ast_strlen_zero(i->ani)) { 05832 tmp->caller.ani.number.valid = 1; 05833 tmp->caller.ani.number.str = ast_strdup(i->ani); 05834 } else if (!ast_strlen_zero(i->cid_num)) { 05835 tmp->caller.ani.number.valid = 1; 05836 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 05837 } 05838 tmp->dialed.number.str = ast_strdup(i->dnid); 05839 if (!ast_strlen_zero(i->rdnis)) { 05840 tmp->redirecting.from.number.valid = 1; 05841 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 05842 } 05843 tmp->caller.id.name.presentation = i->calling_pres; 05844 tmp->caller.id.number.presentation = i->calling_pres; 05845 tmp->caller.id.number.plan = i->calling_ton; 05846 tmp->dialed.transit_network_select = i->calling_tns; 05847 if (!ast_strlen_zero(i->language)) 05848 ast_channel_language_set(tmp, i->language); 05849 if (!ast_strlen_zero(i->accountcode)) 05850 ast_channel_accountcode_set(tmp, i->accountcode); 05851 if (i->amaflags) 05852 tmp->amaflags = i->amaflags; 05853 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05854 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05855 if (i->adsi) 05856 tmp->adsicpe = i->peeradsicpe; 05857 else 05858 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05859 i->owner = tmp; 05860 i->capability = capability; 05861 05862 /* Set inherited variables */ 05863 if (i->vars) { 05864 for (v = i->vars ; v ; v = v->next) 05865 pbx_builtin_setvar_helper(tmp, v->name, v->value); 05866 } 05867 if (i->iaxvars) { 05868 struct ast_datastore *variablestore; 05869 struct ast_variable *var, *prev = NULL; 05870 AST_LIST_HEAD(, ast_var_t) *varlist; 05871 ast_debug(1, "Loading up the channel with IAXVARs\n"); 05872 varlist = ast_calloc(1, sizeof(*varlist)); 05873 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 05874 if (variablestore && varlist) { 05875 variablestore->data = varlist; 05876 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 05877 AST_LIST_HEAD_INIT(varlist); 05878 for (var = i->iaxvars; var; var = var->next) { 05879 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 05880 if (prev) 05881 ast_free(prev); 05882 prev = var; 05883 if (!newvar) { 05884 /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */ 05885 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 05886 } else { 05887 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 05888 } 05889 } 05890 if (prev) 05891 ast_free(prev); 05892 i->iaxvars = NULL; 05893 ast_channel_datastore_add(i->owner, variablestore); 05894 } else { 05895 if (variablestore) { 05896 ast_datastore_free(variablestore); 05897 } 05898 if (varlist) { 05899 ast_free(varlist); 05900 } 05901 } 05902 } 05903 05904 if (state != AST_STATE_DOWN) { 05905 if (ast_pbx_start(tmp)) { 05906 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp)); 05907 ast_hangup(tmp); 05908 i->owner = NULL; 05909 return NULL; 05910 } 05911 } 05912 05913 ast_module_ref(ast_module_info->self); 05914 return tmp; 05915 }
| static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3618 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and transmit_frame().
03619 { 03620 #ifdef SCHED_MULTITHREADED 03621 if (schedule_action(__attempt_transmit, data)) 03622 #endif 03623 __attempt_transmit(data); 03624 return 0; 03625 }
| static int auth_fail | ( | int | callno, | |
| int | failcode | |||
| ) | [static] |
Definition at line 9080 of file chan_iax2.c.
References auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, and iax2_sched_replace().
Referenced by socket_process().
09081 { 09082 /* Schedule sending the authentication failure in one second, to prevent 09083 guessing */ 09084 if (iaxs[callno]) { 09085 iaxs[callno]->authfail = failcode; 09086 if (delayreject) { 09087 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 09088 sched, 1000, auth_reject, (void *)(long)callno); 09089 } else 09090 auth_reject((void *)(long)callno); 09091 } 09092 return 0; 09093 }
| static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 9066 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().
09067 { 09068 int callno = (int)(long)(data); 09069 ast_mutex_lock(&iaxsl[callno]); 09070 if (iaxs[callno]) 09071 iaxs[callno]->authid = -1; 09072 ast_mutex_unlock(&iaxsl[callno]); 09073 #ifdef SCHED_MULTITHREADED 09074 if (schedule_action(__auth_reject, data)) 09075 #endif 09076 __auth_reject(data); 09077 return 0; 09078 }
| 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 8165 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().
08166 { 08167 int res = -1; 08168 int x; 08169 if (!ast_strlen_zero(keyn)) { 08170 if (!(authmethods & IAX_AUTH_RSA)) { 08171 if (ast_strlen_zero(secret)) 08172 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)); 08173 } else if (ast_strlen_zero(challenge)) { 08174 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 08175 } else { 08176 char sig[256]; 08177 struct ast_key *key; 08178 key = ast_key_get(keyn, AST_KEY_PRIVATE); 08179 if (!key) { 08180 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 08181 } else { 08182 if (ast_sign(key, (char*)challenge, sig)) { 08183 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 08184 res = -1; 08185 } else { 08186 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 08187 res = 0; 08188 } 08189 } 08190 } 08191 } 08192 /* Fall back */ 08193 if (res && !ast_strlen_zero(secret)) { 08194 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 08195 struct MD5Context md5; 08196 unsigned char digest[16]; 08197 char digres[128]; 08198 MD5Init(&md5); 08199 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 08200 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 08201 MD5Final(digest, &md5); 08202 /* If they support md5, authenticate with it. */ 08203 for (x=0;x<16;x++) 08204 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 08205 if (pvt) { 08206 build_encryption_keys(digest, pvt); 08207 } 08208 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 08209 res = 0; 08210 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 08211 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 08212 res = 0; 08213 } else 08214 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 08215 } 08216 return res; 08217 }
| 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 8223 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_calloc, ast_channel_datastore_add(), ast_datastore_alloc, ast_datastore_free(), AST_FRAME_IAX, ast_free, AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set_flag64, ast_sockaddr_to_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_var_assign(), authenticate(), iax_ies::authmethods, iax2_peer::authmethods, 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().
08224 { 08225 struct iax2_peer *peer = NULL; 08226 /* Start pessimistic */ 08227 int res = -1; 08228 int authmethods = 0; 08229 struct iax_ie_data ied; 08230 uint16_t callno = p->callno; 08231 08232 memset(&ied, 0, sizeof(ied)); 08233 08234 if (ies->username) 08235 ast_string_field_set(p, username, ies->username); 08236 if (ies->challenge) 08237 ast_string_field_set(p, challenge, ies->challenge); 08238 if (ies->authmethods) 08239 authmethods = ies->authmethods; 08240 if (authmethods & IAX_AUTH_MD5) 08241 merge_encryption(p, ies->encmethods); 08242 else 08243 p->encmethods = 0; 08244 08245 /* Check for override RSA authentication first */ 08246 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 08247 /* Normal password authentication */ 08248 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 08249 } else { 08250 struct ao2_iterator i = ao2_iterator_init(peers, 0); 08251 while ((peer = ao2_iterator_next(&i))) { 08252 struct sockaddr_in peer_addr; 08253 08254 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 08255 08256 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 08257 /* No peer specified at our end, or this is the peer */ 08258 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 08259 /* No username specified in peer rule, or this is the right username */ 08260 && (!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))) 08261 /* No specified host, or this is our host */ 08262 ) { 08263 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 08264 if (!res) { 08265 peer_unref(peer); 08266 break; 08267 } 08268 } 08269 peer_unref(peer); 08270 } 08271 ao2_iterator_destroy(&i); 08272 if (!peer) { 08273 /* We checked our list and didn't find one. It's unlikely, but possible, 08274 that we're trying to authenticate *to* a realtime peer */ 08275 const char *peer_name = ast_strdupa(p->peer); 08276 ast_mutex_unlock(&iaxsl[callno]); 08277 if ((peer = realtime_peer(peer_name, NULL))) { 08278 ast_mutex_lock(&iaxsl[callno]); 08279 if (!(p = iaxs[callno])) { 08280 peer_unref(peer); 08281 return -1; 08282 } 08283 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 08284 peer_unref(peer); 08285 } 08286 if (!peer) { 08287 ast_mutex_lock(&iaxsl[callno]); 08288 if (!(p = iaxs[callno])) 08289 return -1; 08290 } 08291 } 08292 } 08293 08294 if (ies->encmethods) { 08295 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 08296 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 08297 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set"); 08298 return -1; /* if force encryption is yes, and no encryption methods, then return -1 to hangup */ 08299 } 08300 if (!res) { 08301 struct ast_datastore *variablestore; 08302 struct ast_variable *var, *prev = NULL; 08303 AST_LIST_HEAD(, ast_var_t) *varlist; 08304 varlist = ast_calloc(1, sizeof(*varlist)); 08305 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 08306 if (variablestore && varlist && p->owner) { 08307 variablestore->data = varlist; 08308 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 08309 AST_LIST_HEAD_INIT(varlist); 08310 for (var = ies->vars; var; var = var->next) { 08311 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 08312 if (prev) 08313 ast_free(prev); 08314 prev = var; 08315 if (!newvar) { 08316 /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */ 08317 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08318 } else { 08319 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 08320 } 08321 } 08322 if (prev) 08323 ast_free(prev); 08324 ies->vars = NULL; 08325 ast_channel_datastore_add(p->owner, variablestore); 08326 } else { 08327 if (p->owner) 08328 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08329 if (variablestore) 08330 ast_datastore_free(variablestore); 08331 if (varlist) 08332 ast_free(varlist); 08333 } 08334 } 08335 08336 if (!res) 08337 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 08338 return res; 08339 }
| static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 7875 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_KEY, iax_ie_data::pos, send_command(), send_command_final(), user_unref(), and chan_iax2_pvt::username.
Referenced by socket_process().
07876 { 07877 struct iax_ie_data ied; 07878 int res = -1, authreq_restrict = 0; 07879 char challenge[10]; 07880 struct chan_iax2_pvt *p = iaxs[call_num]; 07881 07882 memset(&ied, 0, sizeof(ied)); 07883 07884 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 07885 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07886 struct iax2_user *user; 07887 07888 user = ao2_find(users, p->username, OBJ_KEY); 07889 if (user) { 07890 if (user->curauthreq == user->maxauthreq) 07891 authreq_restrict = 1; 07892 else 07893 user->curauthreq++; 07894 user = user_unref(user); 07895 } 07896 } 07897 07898 /* If the AUTHREQ limit test failed, send back an error */ 07899 if (authreq_restrict) { 07900 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 07901 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 07902 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 07903 return 0; 07904 } 07905 07906 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 07907 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 07908 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 07909 ast_string_field_set(p, challenge, challenge); 07910 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 07911 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 07912 } 07913 if (p->encmethods) 07914 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 07915 07916 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 07917 07918 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 07919 07920 if (p->encmethods) 07921 ast_set_flag64(p, IAX_ENCRYPTED); 07922 07923 return res; 07924 }
| static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 7926 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_KEY, 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().
07927 { 07928 char requeststr[256]; 07929 char md5secret[256] = ""; 07930 char secret[256] = ""; 07931 char rsasecret[256] = ""; 07932 int res = -1; 07933 int x; 07934 struct iax2_user *user; 07935 07936 if (p->authrej) { 07937 return res; 07938 } 07939 user = ao2_find(users, p->username, OBJ_KEY); 07940 if (user) { 07941 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07942 ast_atomic_fetchadd_int(&user->curauthreq, -1); 07943 ast_clear_flag64(p, IAX_MAXAUTHREQ); 07944 } 07945 ast_string_field_set(p, host, user->name); 07946 user = user_unref(user); 07947 } 07948 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) { 07949 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled."); 07950 return res; 07951 } 07952 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 07953 return res; 07954 if (ies->password) 07955 ast_copy_string(secret, ies->password, sizeof(secret)); 07956 if (ies->md5_result) 07957 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07958 if (ies->rsa_result) 07959 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07960 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 07961 struct ast_key *key; 07962 char *keyn; 07963 char tmpkey[256]; 07964 char *stringp=NULL; 07965 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 07966 stringp=tmpkey; 07967 keyn = strsep(&stringp, ":"); 07968 while(keyn) { 07969 key = ast_key_get(keyn, AST_KEY_PUBLIC); 07970 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 07971 res = 0; 07972 break; 07973 } else if (!key) 07974 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 07975 keyn = strsep(&stringp, ":"); 07976 } 07977 } else if (p->authmethods & IAX_AUTH_MD5) { 07978 struct MD5Context md5; 07979 unsigned char digest[16]; 07980 char *tmppw, *stringp; 07981 07982 tmppw = ast_strdupa(p->secret); 07983 stringp = tmppw; 07984 while((tmppw = strsep(&stringp, ";"))) { 07985 MD5Init(&md5); 07986 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 07987 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 07988 MD5Final(digest, &md5); 07989 /* If they support md5, authenticate with it. */ 07990 for (x=0;x<16;x++) 07991 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 07992 if (!strcasecmp(requeststr, md5secret)) { 07993 res = 0; 07994 break; 07995 } 07996 } 07997 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 07998 if (!strcmp(secret, p->secret)) 07999 res = 0; 08000 } 08001 return res; 08002 }
| static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 4741 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), sip_call(), and sip_show_sched().
04742 { 04743 #ifdef SCHED_MULTITHREADED 04744 if (schedule_action(__auto_congest, data)) 04745 #endif 04746 __auto_congest(data); 04747 return 0; 04748 }
| static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 9110 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().
09111 { 09112 int callno = (int)(long)(data); 09113 ast_mutex_lock(&iaxsl[callno]); 09114 if (iaxs[callno]) { 09115 iaxs[callno]->autoid = -1; 09116 } 09117 ast_mutex_unlock(&iaxsl[callno]); 09118 #ifdef SCHED_MULTITHREADED 09119 if (schedule_action(__auto_hangup, data)) 09120 #endif 09121 __auto_hangup(data); 09122 return 0; 09123 }
| static void build_callno_limits | ( | struct ast_variable * | v | ) | [static] |
Definition at line 2517 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().
02518 { 02519 struct addr_range *addr_range = NULL; 02520 struct addr_range tmp; 02521 struct ast_ha *ha; 02522 int limit; 02523 int error; 02524 int found; 02525 02526 for (; v; v = v->next) { 02527 limit = -1; 02528 error = 0; 02529 found = 0; 02530 ha = ast_append_ha("permit", v->name, NULL, &error); 02531 02532 /* check for valid config information */ 02533 if (error) { 02534 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name); 02535 continue; 02536 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) { 02537 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value); 02538 ast_free_ha(ha); 02539 continue; 02540 } 02541 02542 ast_copy_ha(ha, &tmp.ha); 02543 /* find or create the addr_range */ 02544 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) { 02545 ao2_lock(addr_range); 02546 found = 1; 02547 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02548 ast_free_ha(ha); 02549 return; /* out of memory */ 02550 } 02551 02552 /* copy over config data into addr_range object */ 02553 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */ 02554 ast_free_ha(ha); /* cleanup the tmp ha */ 02555 addr_range->limit = limit; 02556 addr_range->delme = 0; 02557 02558 /* cleanup */ 02559 if (found) { 02560 ao2_unlock(addr_range); 02561 } else { 02562 ao2_link(callno_limits, addr_range); 02563 } 02564 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02565 } 02566 }
| static struct iax2_context* build_context | ( | const char * | context | ) | [static, read] |
Definition at line 12304 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), and iax2_context::context.
Referenced by build_user().
12305 { 12306 struct iax2_context *con; 12307 12308 if ((con = ast_calloc(1, sizeof(*con)))) 12309 ast_copy_string(con->context, context, sizeof(con->context)); 12310 12311 return con; 12312 }
| static void build_ecx_key | ( | const unsigned char * | digest, | |
| struct chan_iax2_pvt * | pvt | |||
| ) | [static] |
Definition at line 6257 of file chan_iax2.c.
References ast_aes_set_decrypt_key(), ast_aes_set_encrypt_key(), build_rand_pad(), chan_iax2_pvt::ecx, chan_iax2_pvt::mydcx, and chan_iax2_pvt::semirand.
Referenced by build_encryption_keys(), and iax2_key_rotate().
06258 { 06259 /* it is required to hold the corresponding decrypt key to our encrypt key 06260 * in the pvt struct because queued frames occasionally need to be decrypted and 06261 * re-encrypted when updated for a retransmission */ 06262 build_rand_pad(pvt->semirand, sizeof(pvt->semirand)); 06263 ast_aes_set_encrypt_key(digest, &pvt->ecx); 06264 ast_aes_set_decrypt_key(digest, &pvt->mydcx); 06265 }
| static void build_encryption_keys | ( | const unsigned char * | digest, | |
| struct chan_iax2_pvt * | pvt | |||
| ) | [static] |
Definition at line 6251 of file chan_iax2.c.
References ast_aes_set_decrypt_key(), build_ecx_key(), and chan_iax2_pvt::dcx.
Referenced by authenticate(), and decrypt_frame().
06252 { 06253 build_ecx_key(digest, pvt); 06254 ast_aes_set_decrypt_key(digest, &pvt->dcx); 06255 }
| 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 12455 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_SCHED_DEL, ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_setnull(), ast_sockaddr_to_sin, ast_strdupa, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_true(), 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::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, iax2_parse_allow_disallow(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, inet_aton(), ast_variable::lineno, LOG_WARNING, iax2_peer::mailbox, mailbox, iax2_peer::mask, iax2_peer::maxcallno, iax2_peer::maxms, mwi_event_cb(), iax2_peer::mwi_event_sub, iax2_peer::name, ast_variable::name, ast_variable::next, OBJ_KEY, peer_destructor(), peer_set_srcaddr(), peer_unref(), peercnt_modify(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, prefs, iax2_peer::prefs, S_OR, secret, iax2_peer::smoothing, iax2_peer::sockfd, ast_sockaddr::ss, strsep(), unlink_peer(), ast_variable::value, and zonetag.
12456 { 12457 struct iax2_peer *peer = NULL; 12458 struct ast_ha *oldha = NULL; 12459 int maskfound = 0; 12460 int found = 0; 12461 int firstpass = 1; 12462 12463 if (!temponly) { 12464 peer = ao2_find(peers, name, OBJ_KEY); 12465 if (peer && !ast_test_flag64(peer, IAX_DELME)) 12466 firstpass = 0; 12467 } 12468 12469 if (peer) { 12470 found++; 12471 if (firstpass) { 12472 oldha = peer->ha; 12473 peer->ha = NULL; 12474 } 12475 unlink_peer(peer); 12476 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 12477 peer->expire = -1; 12478 peer->pokeexpire = -1; 12479 peer->sockfd = defaultsockfd; 12480 peer->addr.ss.ss_family = AF_INET; 12481 if (ast_string_field_init(peer, 32)) 12482 peer = peer_unref(peer); 12483 } 12484 12485 if (peer) { 12486 if (firstpass) { 12487 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 12488 peer->encmethods = iax2_encryption; 12489 peer->adsi = adsi; 12490 ast_string_field_set(peer,secret,""); 12491 if (!found) { 12492 ast_string_field_set(peer, name, name); 12493 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12494 peer->expiry = min_reg_expire; 12495 } 12496 peer->prefs = prefs; 12497 peer->capability = iax2_capability; 12498 peer->smoothing = 0; 12499 peer->pokefreqok = DEFAULT_FREQ_OK; 12500 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 12501 peer->maxcallno = 0; 12502 peercnt_modify(0, 0, &peer->addr); 12503 peer->calltoken_required = CALLTOKEN_DEFAULT; 12504 ast_string_field_set(peer,context,""); 12505 ast_string_field_set(peer,peercontext,""); 12506 ast_clear_flag64(peer, IAX_HASCALLERID); 12507 ast_string_field_set(peer, cid_name, ""); 12508 ast_string_field_set(peer, cid_num, ""); 12509 ast_string_field_set(peer, mohinterpret, mohinterpret); 12510 ast_string_field_set(peer, mohsuggest, mohsuggest); 12511 } 12512 12513 if (!v) { 12514 v = alt; 12515 alt = NULL; 12516 } 12517 while(v) { 12518 if (!strcasecmp(v->name, "secret")) { 12519 ast_string_field_set(peer, secret, v->value); 12520 } else if (!strcasecmp(v->name, "mailbox")) { 12521 ast_string_field_set(peer, mailbox, v->value); 12522 } else if (!strcasecmp(v->name, "hasvoicemail")) { 12523 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 12524 ast_string_field_set(peer, mailbox, name); 12525 } 12526 } else if (!strcasecmp(v->name, "mohinterpret")) { 12527 ast_string_field_set(peer, mohinterpret, v->value); 12528 } else if (!strcasecmp(v->name, "mohsuggest")) { 12529 ast_string_field_set(peer, mohsuggest, v->value); 12530 } else if (!strcasecmp(v->name, "dbsecret")) { 12531 ast_string_field_set(peer, dbsecret, v->value); 12532 } else if (!strcasecmp(v->name, "description")) { 12533 ast_string_field_set(peer, description, v->value); 12534 } else if (!strcasecmp(v->name, "trunk")) { 12535 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK); 12536 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) { 12537 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name); 12538 ast_clear_flag64(peer, IAX_TRUNK); 12539 } 12540 } else if (!strcasecmp(v->name, "auth")) { 12541 peer->authmethods = get_auth_methods(v->value); 12542 } else if (!strcasecmp(v->name, "encryption")) { 12543 peer->encmethods |= get_encrypt_methods(v->value); 12544 if (!peer->encmethods) { 12545 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12546 } 12547 } else if (!strcasecmp(v->name, "forceencryption")) { 12548 if (ast_false(v->value)) { 12549 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12550 } else { 12551 peer->encmethods |= get_encrypt_methods(v->value); 12552 if (peer->encmethods) { 12553 ast_set_flag64(peer, IAX_FORCE_ENCRYPT); 12554 } 12555 } 12556 } else if (!strcasecmp(v->name, "transfer")) { 12557 if (!strcasecmp(v->value, "mediaonly")) { 12558 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12559 } else if (ast_true(v->value)) { 12560 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12561 } else 12562 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12563 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12564 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF); 12565 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12566 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 12567 } else if (!strcasecmp(v->name, "host")) { 12568 if (!strcasecmp(v->value, "dynamic")) { 12569 /* They'll register with us */ 12570 ast_set_flag64(peer, IAX_DYNAMIC); 12571 if (!found) { 12572 /* Initialize stuff iff we're not found, otherwise 12573 we keep going with what we had */ 12574 if (ast_sockaddr_port(&peer->addr)) { 12575 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr)); 12576 } 12577 ast_sockaddr_setnull(&peer->addr); 12578 } 12579 } else { 12580 /* Non-dynamic. Make sure we become that way if we're not */ 12581 AST_SCHED_DEL(sched, peer->expire); 12582 ast_clear_flag64(peer, IAX_DYNAMIC); 12583 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) 12584 return peer_unref(peer); 12585 if (!ast_sockaddr_port(&peer->addr)) { 12586 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12587 } 12588 } 12589 if (!maskfound) 12590 inet_aton("255.255.255.255", &peer->mask); 12591 } else if (!strcasecmp(v->name, "defaultip")) { 12592 struct ast_sockaddr peer_defaddr_tmp; 12593 12594 peer_defaddr_tmp.ss.ss_family = AF_INET; 12595 if (ast_get_ip(&peer_defaddr_tmp, v->value)) { 12596 return peer_unref(peer); 12597 } 12598 ast_sockaddr_to_sin(&peer_defaddr_tmp, 12599 &peer->defaddr); 12600 } else if (!strcasecmp(v->name, "sourceaddress")) { 12601 peer_set_srcaddr(peer, v->value); 12602 } else if (!strcasecmp(v->name, "permit") || 12603 !strcasecmp(v->name, "deny")) { 12604 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL); 12605 } else if (!strcasecmp(v->name, "mask")) { 12606 maskfound++; 12607 inet_aton(v->value, &peer->mask); 12608 } else if (!strcasecmp(v->name, "context")) { 12609 ast_string_field_set(peer, context, v->value); 12610 } else if (!strcasecmp(v->name, "regexten")) { 12611 ast_string_field_set(peer, regexten, v->value); 12612 } else if (!strcasecmp(v->name, "peercontext")) { 12613 ast_string_field_set(peer, peercontext, v->value); 12614 } else if (!strcasecmp(v->name, "port")) { 12615 if (ast_test_flag64(peer, IAX_DYNAMIC)) { 12616 peer->defaddr.sin_port = htons(atoi(v->value)); 12617 } else { 12618 ast_sockaddr_set_port(&peer->addr, atoi(v->value)); 12619 } 12620 } else if (!strcasecmp(v->name, "username")) { 12621 ast_string_field_set(peer, username, v->value); 12622 } else if (!strcasecmp(v->name, "allow")) { 12623 iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 12624 } else if (!strcasecmp(v->name, "disallow")) { 12625 iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 12626 } else if (!strcasecmp(v->name, "callerid")) { 12627 if (!ast_strlen_zero(v->value)) { 12628 char name2[80]; 12629 char num2[80]; 12630 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12631 ast_string_field_set(peer, cid_name, name2); 12632 ast_string_field_set(peer, cid_num, num2); 12633 } else { 12634 ast_string_field_set(peer, cid_name, ""); 12635 ast_string_field_set(peer, cid_num, ""); 12636 } 12637 ast_set_flag64(peer, IAX_HASCALLERID); 12638 } else if (!strcasecmp(v->name, "fullname")) { 12639 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 12640 ast_set_flag64(peer, IAX_HASCALLERID); 12641 } else if (!strcasecmp(v->name, "cid_number")) { 12642 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 12643 ast_set_flag64(peer, IAX_HASCALLERID); 12644 } else if (!strcasecmp(v->name, "sendani")) { 12645 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI); 12646 } else if (!strcasecmp(v->name, "inkeys")) { 12647 ast_string_field_set(peer, inkeys, v->value); 12648 } else if (!strcasecmp(v->name, "outkey")) { 12649 ast_string_field_set(peer, outkey, v->value); 12650 } else if (!strcasecmp(v->name, "qualify")) { 12651 if (!strcasecmp(v->value, "no")) { 12652 peer->maxms = 0; 12653 } else if (!strcasecmp(v->value, "yes")) { 12654 peer->maxms = DEFAULT_MAXMS; 12655 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 12656 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); 12657 peer->maxms = 0; 12658 } 12659 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 12660 peer->smoothing = ast_true(v->value); 12661 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 12662 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) { 12663 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); 12664 } 12665 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 12666 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) { 12667 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); 12668 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 12669 } else if (!strcasecmp(v->name, "timezone")) { 12670 ast_string_field_set(peer, zonetag, v->value); 12671 } else if (!strcasecmp(v->name, "adsi")) { 12672 peer->adsi = ast_true(v->value); 12673 } else if (!strcasecmp(v->name, "connectedline")) { 12674 if (ast_true(v->value)) { 12675 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12676 } else if (!strcasecmp(v->value, "send")) { 12677 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE); 12678 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE); 12679 } else if (!strcasecmp(v->value, "receive")) { 12680 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE); 12681 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE); 12682 } else { 12683 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12684 } 12685 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 12686 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) { 12687 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 12688 } else { 12689 peercnt_modify(1, peer->maxcallno, &peer->addr); 12690 } 12691 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12692 /* default is required unless in optional ip list */ 12693 if (ast_false(v->value)) { 12694 peer->calltoken_required = CALLTOKEN_NO; 12695 } else if (!strcasecmp(v->value, "auto")) { 12696 peer->calltoken_required = CALLTOKEN_AUTO; 12697 } else if (ast_true(v->value)) { 12698 peer->calltoken_required = CALLTOKEN_YES; 12699 } else { 12700 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12701 } 12702 } /* else if (strcasecmp(v->name,"type")) */ 12703 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12704 v = v->next; 12705 if (!v) { 12706 v = alt; 12707 alt = NULL; 12708 } 12709 } 12710 if (!peer->authmethods) 12711 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12712 ast_clear_flag64(peer, IAX_DELME); 12713 } 12714 12715 if (oldha) 12716 ast_free_ha(oldha); 12717 12718 if (!ast_strlen_zero(peer->mailbox)) { 12719 char *mailbox, *context; 12720 context = mailbox = ast_strdupa(peer->mailbox); 12721 strsep(&context, "@"); 12722 if (ast_strlen_zero(context)) 12723 context = "default"; 12724 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL, 12725 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 12726 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 12727 AST_EVENT_IE_END); 12728 } 12729 12730 return peer; 12731 }
| static void build_rand_pad | ( | unsigned char * | buf, | |
| ssize_t | len | |||
| ) | [static] |
Definition at line 6241 of file chan_iax2.c.
References ast_random().
Referenced by build_ecx_key(), and update_packet().
06242 { 06243 long tmp; 06244 for (tmp = ast_random(); len > 0; tmp = ast_random()) { 06245 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len); 06246 buf += sizeof(tmp); 06247 len -= sizeof(tmp); 06248 } 06249 }
| 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 12747 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_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::encmethods, format, free_context(), get_auth_methods(), get_encrypt_methods(), iax2_user::ha, iax2_parse_allow_disallow(), 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, iax2_user::name, ast_variable::name, ast_variable::next, iax2_context::next, OBJ_KEY, parkinglot, prefs, iax2_user::prefs, secret, iax2_user::secret, user_destructor(), user_unref(), ast_variable::value, and iax2_user::vars.
12748 { 12749 struct iax2_user *user = NULL; 12750 struct iax2_context *con, *conl = NULL; 12751 struct ast_ha *oldha = NULL; 12752 struct iax2_context *oldcon = NULL; 12753 int format; 12754 int firstpass=1; 12755 int oldcurauthreq = 0; 12756 char *varname = NULL, *varval = NULL; 12757 struct ast_variable *tmpvar = NULL; 12758 12759 if (!temponly) { 12760 user = ao2_find(users, name, OBJ_KEY); 12761 if (user && !ast_test_flag64(user, IAX_DELME)) 12762 firstpass = 0; 12763 } 12764 12765 if (user) { 12766 if (firstpass) { 12767 oldcurauthreq = user->curauthreq; 12768 oldha = user->ha; 12769 oldcon = user->contexts; 12770 user->ha = NULL; 12771 user->contexts = NULL; 12772 } 12773 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12774 ao2_unlink(users, user); 12775 } else { 12776 user = ao2_alloc(sizeof(*user), user_destructor); 12777 } 12778 12779 if (user) { 12780 if (firstpass) { 12781 ast_string_field_free_memory(user); 12782 memset(user, 0, sizeof(struct iax2_user)); 12783 if (ast_string_field_init(user, 32)) { 12784 user = user_unref(user); 12785 goto cleanup; 12786 } 12787 user->maxauthreq = maxauthreq; 12788 user->curauthreq = oldcurauthreq; 12789 user->prefs = prefs; 12790 user->capability = iax2_capability; 12791 user->encmethods = iax2_encryption; 12792 user->adsi = adsi; 12793 user->calltoken_required = CALLTOKEN_DEFAULT; 12794 ast_string_field_set(user, name, name); 12795 ast_string_field_set(user, language, language); 12796 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); 12797 ast_clear_flag64(user, IAX_HASCALLERID); 12798 ast_string_field_set(user, cid_name, ""); 12799 ast_string_field_set(user, cid_num, ""); 12800 ast_string_field_set(user, accountcode, accountcode); 12801 ast_string_field_set(user, mohinterpret, mohinterpret); 12802 ast_string_field_set(user, mohsuggest, mohsuggest); 12803 } 12804 if (!v) { 12805 v = alt; 12806 alt = NULL; 12807 } 12808 while(v) { 12809 if (!strcasecmp(v->name, "context")) { 12810 con = build_context(v->value); 12811 if (con) { 12812 if (conl) 12813 conl->next = con; 12814 else 12815 user->contexts = con; 12816 conl = con; 12817 } 12818 } else if (!strcasecmp(v->name, "permit") || 12819 !strcasecmp(v->name, "deny")) { 12820 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL); 12821 } else if (!strcasecmp(v->name, "setvar")) { 12822 varname = ast_strdupa(v->value); 12823 if (varname && (varval = strchr(varname,'='))) { 12824 *varval = '\0'; 12825 varval++; 12826 if((tmpvar = ast_variable_new(varname, varval, ""))) { 12827 tmpvar->next = user->vars; 12828 user->vars = tmpvar; 12829 } 12830 } 12831 } else if (!strcasecmp(v->name, "allow")) { 12832 iax2_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 12833 } else if (!strcasecmp(v->name, "disallow")) { 12834 iax2_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 12835 } else if (!strcasecmp(v->name, "trunk")) { 12836 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK); 12837 if (ast_test_flag64(user, IAX_TRUNK) && !timer) { 12838 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name); 12839 ast_clear_flag64(user, IAX_TRUNK); 12840 } 12841 } else if (!strcasecmp(v->name, "auth")) { 12842 user->authmethods = get_auth_methods(v->value); 12843 } else if (!strcasecmp(v->name, "encryption")) { 12844 user->encmethods |= get_encrypt_methods(v->value); 12845 if (!user->encmethods) { 12846 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 12847 } 12848 } else if (!strcasecmp(v->name, "forceencryption")) { 12849 if (ast_false(v->value)) { 12850 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 12851 } else { 12852 user->encmethods |= get_encrypt_methods(v->value); 12853 if (user->encmethods) { 12854 ast_set_flag64(user, IAX_FORCE_ENCRYPT); 12855 } 12856 } 12857 } else if (!strcasecmp(v->name, "transfer")) { 12858 if (!strcasecmp(v->value, "mediaonly")) { 12859 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12860 } else if (ast_true(v->value)) { 12861 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12862 } else 12863 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12864 } else if (!strcasecmp(v->name, "codecpriority")) { 12865 if(!strcasecmp(v->value, "caller")) 12866 ast_set_flag64(user, IAX_CODEC_USER_FIRST); 12867 else if(!strcasecmp(v->value, "disabled")) 12868 ast_set_flag64(user, IAX_CODEC_NOPREFS); 12869 else if(!strcasecmp(v->value, "reqonly")) { 12870 ast_set_flag64(user, IAX_CODEC_NOCAP); 12871 ast_set_flag64(user, IAX_CODEC_NOPREFS); 12872 } 12873 } else if (!strcasecmp(v->name, "immediate")) { 12874 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE); 12875 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12876 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF); 12877 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12878 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF); 12879 } else if (!strcasecmp(v->name, "dbsecret")) { 12880 ast_string_field_set(user, dbsecret, v->value); 12881 } else if (!strcasecmp(v->name, "secret")) { 12882 if (!ast_strlen_zero(user->secret)) { 12883 char *old = ast_strdupa(user->secret); 12884 12885 ast_string_field_build(user, secret, "%s;%s", old, v->value); 12886 } else 12887 ast_string_field_set(user, secret, v->value); 12888 } else if (!strcasecmp(v->name, "callerid")) { 12889 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 12890 char name2[80]; 12891 char num2[80]; 12892 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12893 ast_string_field_set(user, cid_name, name2); 12894 ast_string_field_set(user, cid_num, num2); 12895 ast_set_flag64(user, IAX_HASCALLERID); 12896 } else { 12897 ast_clear_flag64(user, IAX_HASCALLERID); 12898 ast_string_field_set(user, cid_name, ""); 12899 ast_string_field_set(user, cid_num, ""); 12900 } 12901 } else if (!strcasecmp(v->name, "fullname")) { 12902 if (!ast_strlen_zero(v->value)) { 12903 ast_string_field_set(user, cid_name, v->value); 12904 ast_set_flag64(user, IAX_HASCALLERID); 12905 } else { 12906 ast_string_field_set(user, cid_name, ""); 12907 if (ast_strlen_zero(user->cid_num)) 12908 ast_clear_flag64(user, IAX_HASCALLERID); 12909 } 12910 } else if (!strcasecmp(v->name, "cid_number")) { 12911 if (!ast_strlen_zero(v->value)) { 12912 ast_string_field_set(user, cid_num, v->value); 12913 ast_set_flag64(user, IAX_HASCALLERID); 12914 } else { 12915 ast_string_field_set(user, cid_num, ""); 12916 if (ast_strlen_zero(user->cid_name)) 12917 ast_clear_flag64(user, IAX_HASCALLERID); 12918 } 12919 } else if (!strcasecmp(v->name, "accountcode")) { 12920 ast_string_field_set(user, accountcode, v->value); 12921 } else if (!strcasecmp(v->name, "mohinterpret")) { 12922 ast_string_field_set(user, mohinterpret, v->value); 12923 } else if (!strcasecmp(v->name, "mohsuggest")) { 12924 ast_string_field_set(user, mohsuggest, v->value); 12925 } else if (!strcasecmp(v->name, "parkinglot")) { 12926 ast_string_field_set(user, parkinglot, v->value); 12927 } else if (!strcasecmp(v->name, "language")) { 12928 ast_string_field_set(user, language, v->value); 12929 } else if (!strcasecmp(v->name, "amaflags")) { 12930 format = ast_cdr_amaflags2int(v->value); 12931 if (format < 0) { 12932 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 12933 } else { 12934 user->amaflags = format; 12935 } 12936 } else if (!strcasecmp(v->name, "inkeys")) { 12937 ast_string_field_set(user, inkeys, v->value); 12938 } else if (!strcasecmp(v->name, "maxauthreq")) { 12939 user->maxauthreq = atoi(v->value); 12940 if (user->maxauthreq < 0) 12941 user->maxauthreq = 0; 12942 } else if (!strcasecmp(v->name, "adsi")) { 12943 user->adsi = ast_true(v->value); 12944 } else if (!strcasecmp(v->name, "connectedline")) { 12945 if (ast_true(v->value)) { 12946 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12947 } else if (!strcasecmp(v->value, "send")) { 12948 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE); 12949 ast_set_flag64(user, IAX_SENDCONNECTEDLINE); 12950 } else if (!strcasecmp(v->value, "receive")) { 12951 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE); 12952 ast_set_flag64(user, IAX_RECVCONNECTEDLINE); 12953 } else { 12954 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12955 } 12956 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12957 /* default is required unless in optional ip list */ 12958 if (ast_false(v->value)) { 12959 user->calltoken_required = CALLTOKEN_NO; 12960 } else if (!strcasecmp(v->value, "auto")) { 12961 user->calltoken_required = CALLTOKEN_AUTO; 12962 } else if (ast_true(v->value)) { 12963 user->calltoken_required = CALLTOKEN_YES; 12964 } else { 12965 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12966 } 12967 } /* else if (strcasecmp(v->name,"type")) */ 12968 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12969 v = v->next; 12970 if (!v) { 12971 v = alt; 12972 alt = NULL; 12973 } 12974 } 12975 if (!user->authmethods) { 12976 if (!ast_strlen_zero(user->secret)) { 12977 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12978 if (!ast_strlen_zero(user->inkeys)) 12979 user->authmethods |= IAX_AUTH_RSA; 12980 } else if (!ast_strlen_zero(user->inkeys)) { 12981 user->authmethods = IAX_AUTH_RSA; 12982 } else { 12983 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12984 } 12985 } 12986 ast_clear_flag64(user, IAX_DELME); 12987 } 12988 cleanup: 12989 if (oldha) 12990 ast_free_ha(oldha); 12991 if (oldcon) 12992 free_context(oldcon); 12993 return user; 12994 }
| static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 13628 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().
13629 { 13630 struct sockaddr_in sin; 13631 int x; 13632 int callno; 13633 struct iax_ie_data ied; 13634 struct create_addr_info cai; 13635 struct parsed_dial_string pds; 13636 char *tmpstr; 13637 13638 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 13639 /* Look for an *exact match* call. Once a call is negotiated, it can only 13640 look up entries for a single context */ 13641 if (!ast_mutex_trylock(&iaxsl[x])) { 13642 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 13643 return x; 13644 ast_mutex_unlock(&iaxsl[x]); 13645 } 13646 } 13647 13648 /* No match found, we need to create a new one */ 13649 13650 memset(&cai, 0, sizeof(cai)); 13651 memset(&ied, 0, sizeof(ied)); 13652 memset(&pds, 0, sizeof(pds)); 13653 13654 tmpstr = ast_strdupa(data); 13655 parse_dial_string(tmpstr, &pds); 13656 13657 if (ast_strlen_zero(pds.peer)) { 13658 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 13659 return -1; 13660 } 13661 13662 /* Populate our address from the given */ 13663 if (create_addr(pds.peer, NULL, &sin, &cai)) 13664 return -1; 13665 13666 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n", 13667 pds.peer, pds.username, pds.password, pds.context); 13668 13669 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 13670 if (callno < 1) { 13671 ast_log(LOG_WARNING, "Unable to create call\n"); 13672 return -1; 13673 } 13674 13675 ast_string_field_set(iaxs[callno], dproot, data); 13676 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 13677 13678 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 13679 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 13680 /* the string format is slightly different from a standard dial string, 13681 because the context appears in the 'exten' position 13682 */ 13683 if (pds.exten) 13684 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 13685 if (pds.username) 13686 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 13687 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 13688 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 13689 /* Keep password handy */ 13690 if (pds.password) 13691 ast_string_field_set(iaxs[callno], secret, pds.password); 13692 if (pds.key) 13693 ast_string_field_set(iaxs[callno], outkey, pds.key); 13694 /* Start the call going */ 13695 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 13696 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 13697 13698 return callno; 13699 }
| static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | offset | |||
| ) | [static] |
Definition at line 6094 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().
06095 { 06096 /* Returns where in "receive time" we are. That is, how many ms 06097 since we received (or would have received) the frame with timestamp 0 */ 06098 int ms; 06099 #ifdef IAXTESTS 06100 int jit; 06101 #endif /* IAXTESTS */ 06102 /* Setup rxcore if necessary */ 06103 if (ast_tvzero(p->rxcore)) { 06104 p->rxcore = ast_tvnow(); 06105 if (iaxdebug) 06106 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 06107 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 06108 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 06109 #if 1 06110 if (iaxdebug) 06111 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 06112 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 06113 #endif 06114 } 06115 06116 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 06117 #ifdef IAXTESTS 06118 if (test_jit) { 06119 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 06120 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 06121 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 06122 jit = -jit; 06123 ms += jit; 06124 } 06125 } 06126 if (test_late) { 06127 ms += test_late; 06128 test_late = 0; 06129 } 06130 #endif /* IAXTESTS */ 06131 return ms; 06132 }
| static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | ts, | |||
| struct ast_frame * | f | |||
| ) | [static] |
Definition at line 5961 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_subclass::format, 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().
05962 { 05963 int ms; 05964 int voice = 0; 05965 int genuine = 0; 05966 int adjust; 05967 int rate = ast_format_rate(&f->subclass.format) / 1000; 05968 struct timeval *delivery = NULL; 05969 05970 05971 /* What sort of frame do we have?: voice is self-explanatory 05972 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 05973 non-genuine frames are CONTROL frames [ringing etc], DTMF 05974 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 05975 the others need a timestamp slaved to the voice frames so that they go in sequence 05976 */ 05977 if (f) { 05978 if (f->frametype == AST_FRAME_VOICE) { 05979 voice = 1; 05980 delivery = &f->delivery; 05981 } else if (f->frametype == AST_FRAME_IAX) { 05982 genuine = 1; 05983 } else if (f->frametype == AST_FRAME_CNG) { 05984 p->notsilenttx = 0; 05985 } 05986 } 05987 if (ast_tvzero(p->offset)) { 05988 p->offset = ast_tvnow(); 05989 /* Round to nearest 20ms for nice looking traces */ 05990 p->offset.tv_usec -= p->offset.tv_usec % 20000; 05991 } 05992 /* If the timestamp is specified, just send it as is */ 05993 if (ts) 05994 return ts; 05995 /* If we have a time that the frame arrived, always use it to make our timestamp */ 05996 if (delivery && !ast_tvzero(*delivery)) { 05997 ms = ast_tvdiff_ms(*delivery, p->offset); 05998 if (ms < 0) { 05999 ms = 0; 06000 } 06001 if (iaxdebug) 06002 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 06003 } else { 06004 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 06005 if (ms < 0) 06006 ms = 0; 06007 if (voice) { 06008 /* On a voice frame, use predicted values if appropriate */ 06009 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 06010 /* Adjust our txcore, keeping voice and non-voice synchronized */ 06011 /* AN EXPLANATION: 06012 When we send voice, we usually send "calculated" timestamps worked out 06013 on the basis of the number of samples sent. When we send other frames, 06014 we usually send timestamps worked out from the real clock. 06015 The problem is that they can tend to drift out of step because the 06016 source channel's clock and our clock may not be exactly at the same rate. 06017 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 06018 for this call. Moving it adjusts timestamps for non-voice frames. 06019 We make the adjustment in the style of a moving average. Each time we 06020 adjust p->offset by 10% of the difference between our clock-derived 06021 timestamp and the predicted timestamp. That's why you see "10000" 06022 below even though IAX2 timestamps are in milliseconds. 06023 The use of a moving average avoids offset moving too radically. 06024 Generally, "adjust" roams back and forth around 0, with offset hardly 06025 changing at all. But if a consistent different starts to develop it 06026 will be eliminated over the course of 10 frames (200-300msecs) 06027 */ 06028 adjust = (ms - p->nextpred); 06029 if (adjust < 0) 06030 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 06031 else if (adjust > 0) 06032 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 06033 06034 if (!p->nextpred) { 06035 p->nextpred = ms; /*f->samples / rate;*/ 06036 if (p->nextpred <= p->lastsent) 06037 p->nextpred = p->lastsent + 3; 06038 } 06039 ms = p->nextpred; 06040 } else { 06041 /* in this case, just use the actual 06042 * time, since we're either way off 06043 * (shouldn't happen), or we're ending a 06044 * silent period -- and seed the next 06045 * predicted time. Also, round ms to the 06046 * next multiple of frame size (so our 06047 * silent periods are multiples of 06048 * frame size too) */ 06049 06050 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 06051 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 06052 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 06053 06054 if (f->samples >= rate) /* check to make sure we don't core dump */ 06055 { 06056 int diff = ms % (f->samples / rate); 06057 if (diff) 06058 ms += f->samples/rate - diff; 06059 } 06060 06061 p->nextpred = ms; 06062 p->notsilenttx = 1; 06063 } 06064 } else if ( f->frametype == AST_FRAME_VIDEO ) { 06065 /* 06066 * IAX2 draft 03 says that timestamps MUST be in order. 06067 * It does not say anything about several frames having the same timestamp 06068 * When transporting video, we can have a frame that spans multiple iax packets 06069 * (so called slices), so it would make sense to use the same timestamp for all of 06070 * them 06071 * We do want to make sure that frames don't go backwards though 06072 */ 06073 if ( (unsigned int)ms < p->lastsent ) 06074 ms = p->lastsent; 06075 } else { 06076 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 06077 it's a genuine frame */ 06078 if (genuine) { 06079 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 06080 if (ms <= p->lastsent) 06081 ms = p->lastsent + 3; 06082 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 06083 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 06084 ms = p->lastsent + 3; 06085 } 06086 } 06087 } 06088 p->lastsent = ms; 06089 if (voice) 06090 p->nextpred = p->nextpred + f->samples / rate; 06091 return ms; 06092 }
| static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
| int | sampms, | |||
| struct timeval * | now | |||
| ) | [static] |
Definition at line 5917 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().
05918 { 05919 unsigned long int mssincetx; /* unsigned to handle overflows */ 05920 long int ms, pred; 05921 05922 tpeer->trunkact = *now; 05923 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime); 05924 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 05925 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 05926 tpeer->txtrunktime = *now; 05927 tpeer->lastsent = 999999; 05928 } 05929 /* Update last transmit time now */ 05930 tpeer->lasttxtime = *now; 05931 05932 /* Calculate ms offset */ 05933 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime); 05934 /* Predict from last value */ 05935 pred = tpeer->lastsent + sampms; 05936 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 05937 ms = pred; 05938 05939 /* We never send the same timestamp twice, so fudge a little if we must */ 05940 if (ms == tpeer->lastsent) 05941 ms = tpeer->lastsent + 1; 05942 tpeer->lastsent = ms; 05943 return ms; 05944 }
| static int callno_hash | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 2734 of file chan_iax2.c.
References ast_random().
Referenced by create_callno_pools().
02735 { 02736 return abs(ast_random()); 02737 }
| static int calltoken_required | ( | struct sockaddr_in * | sin, | |
| const char * | name, | |||
| int | subclass | |||
| ) | [static] |
Definition at line 2265 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().
02266 { 02267 struct addr_range *addr_range; 02268 struct iax2_peer *peer = NULL; 02269 struct iax2_user *user = NULL; 02270 /* if no username is given, check for guest accounts */ 02271 const char *find = S_OR(name, "guest"); 02272 int res = 1; /* required by default */ 02273 int optional = 0; 02274 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT; 02275 /* There are only two cases in which calltoken validation is not required. 02276 * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and 02277 * the peer definition has not set the requirecalltoken option. 02278 * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no. 02279 */ 02280 02281 /* ----- Case 1 ----- */ 02282 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) { 02283 ao2_ref(addr_range, -1); 02284 optional = 1; 02285 } 02286 02287 /* ----- Case 2 ----- */ 02288 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) { 02289 calltoken_required = user->calltoken_required; 02290 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) { 02291 calltoken_required = user->calltoken_required; 02292 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) { 02293 calltoken_required = peer->calltoken_required; 02294 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) { 02295 calltoken_required = peer->calltoken_required; 02296 } 02297 02298 if (peer) { 02299 peer_unref(peer); 02300 } 02301 if (user) { 02302 user_unref(user); 02303 } 02304 02305 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); 02306 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) || 02307 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) { 02308 res = 0; 02309 } 02310 02311 return res; 02312 }
| static int check_access | ( | int | callno, | |
| struct sockaddr_in * | sin, | |||
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 7611 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_sockaddr_from_sin, 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().
07612 { 07613 /* Start pessimistic */ 07614 int res = -1; 07615 int version = 2; 07616 struct iax2_user *user = NULL, *best = NULL; 07617 int bestscore = 0; 07618 int gotcapability = 0; 07619 struct ast_variable *v = NULL, *tmpvar = NULL; 07620 struct ao2_iterator i; 07621 struct ast_sockaddr addr; 07622 07623 if (!iaxs[callno]) 07624 return res; 07625 if (ies->called_number) 07626 ast_string_field_set(iaxs[callno], exten, ies->called_number); 07627 if (ies->calling_number) { 07628 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) { 07629 ast_shrink_phone_number(ies->calling_number); 07630 } 07631 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 07632 } 07633 if (ies->calling_name) 07634 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 07635 if (ies->calling_ani) 07636 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 07637 if (ies->dnid) 07638 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 07639 if (ies->rdnis) 07640 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 07641 if (ies->called_context) 07642 ast_string_field_set(iaxs[callno], context, ies->called_context); 07643 if (ies->language) 07644 ast_string_field_set(iaxs[callno], language, ies->language); 07645 if (ies->username) 07646 ast_string_field_set(iaxs[callno], username, ies->username); 07647 if (ies->calling_ton > -1) 07648 iaxs[callno]->calling_ton = ies->calling_ton; 07649 if (ies->calling_tns > -1) 07650 iaxs[callno]->calling_tns = ies->calling_tns; 07651 if (ies->calling_pres > -1) 07652 iaxs[callno]->calling_pres = ies->calling_pres; 07653 if (ies->format) 07654 iaxs[callno]->peerformat = ies->format; 07655 if (ies->adsicpe) 07656 iaxs[callno]->peeradsicpe = ies->adsicpe; 07657 if (ies->capability) { 07658 gotcapability = 1; 07659 iaxs[callno]->peercapability = ies->capability; 07660 } 07661 if (ies->version) 07662 version = ies->version; 07663 07664 /* Use provided preferences until told otherwise for actual preferences */ 07665 if (ies->codec_prefs) { 07666 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 07667 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 07668 } 07669 07670 if (!gotcapability) 07671 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 07672 if (version > IAX_PROTO_VERSION) { 07673 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 07674 ast_inet_ntoa(sin->sin_addr), version); 07675 return res; 07676 } 07677 /* Search the userlist for a compatible entry, and fill in the rest */ 07678 ast_sockaddr_from_sin(&addr, sin); 07679 i = ao2_iterator_init(users, 0); 07680 while ((user = ao2_iterator_next(&i))) { 07681 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 07682 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 07683 && ast_apply_ha(user->ha, &addr) /* Access is permitted from this IP */ 07684 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 07685 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 07686 if (!ast_strlen_zero(iaxs[callno]->username)) { 07687 /* Exact match, stop right now. */ 07688 if (best) 07689 user_unref(best); 07690 best = user; 07691 break; 07692 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 07693 /* No required authentication */ 07694 if (user->ha) { 07695 /* There was host authentication and we passed, bonus! */ 07696 if (bestscore < 4) { 07697 bestscore = 4; 07698 if (best) 07699 user_unref(best); 07700 best = user; 07701 continue; 07702 } 07703 } else { 07704 /* No host access, but no secret, either, not bad */ 07705 if (bestscore < 3) { 07706 bestscore = 3; 07707 if (best) 07708 user_unref(best); 07709 best = user; 07710 continue; 07711 } 07712 } 07713 } else { 07714 if (user->ha) { 07715 /* Authentication, but host access too, eh, it's something.. */ 07716 if (bestscore < 2) { 07717 bestscore = 2; 07718 if (best) 07719 user_unref(best); 07720 best = user; 07721 continue; 07722 } 07723 } else { 07724 /* Authentication and no host access... This is our baseline */ 07725 if (bestscore < 1) { 07726 bestscore = 1; 07727 if (best) 07728 user_unref(best); 07729 best = user; 07730 continue; 07731 } 07732 } 07733 } 07734 } 07735 user_unref(user); 07736 } 07737 ao2_iterator_destroy(&i); 07738 user = best; 07739 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 07740 user = realtime_user(iaxs[callno]->username, sin); 07741 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 07742 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 07743 user = user_unref(user); 07744 } 07745 } 07746 if (user) { 07747 /* We found our match (use the first) */ 07748 /* copy vars */ 07749 for (v = user->vars ; v ; v = v->next) { 07750 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) { 07751 tmpvar->next = iaxs[callno]->vars; 07752 iaxs[callno]->vars = tmpvar; 07753 } 07754 } 07755 /* If a max AUTHREQ restriction is in place, activate it */ 07756 if (user->maxauthreq > 0) 07757 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ); 07758 iaxs[callno]->prefs = user->prefs; 07759 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT); 07760 iaxs[callno]->encmethods = user->encmethods; 07761 /* Store the requested username if not specified */ 07762 if (ast_strlen_zero(iaxs[callno]->username)) 07763 ast_string_field_set(iaxs[callno], username, user->name); 07764 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 07765 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK); 07766 iaxs[callno]->capability = user->capability; 07767 /* And use the default context */ 07768 if (ast_strlen_zero(iaxs[callno]->context)) { 07769 if (user->contexts) 07770 ast_string_field_set(iaxs[callno], context, user->contexts->context); 07771 else 07772 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT); 07773 } 07774 /* And any input keys */ 07775 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 07776 /* And the permitted authentication methods */ 07777 iaxs[callno]->authmethods = user->authmethods; 07778 iaxs[callno]->adsi = user->adsi; 07779 /* If the user has callerid, override the remote caller id. */ 07780 if (ast_test_flag64(user, IAX_HASCALLERID)) { 07781 iaxs[callno]->calling_tns = 0; 07782 iaxs[callno]->calling_ton = 0; 07783 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 07784 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 07785 ast_string_field_set(iaxs[callno], ani, user->cid_num); 07786 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 07787 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 07788 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 07789 } /* else user is allowed to set their own CID settings */ 07790 if (!ast_strlen_zero(user->accountcode)) 07791 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 07792 if (!ast_strlen_zero(user->mohinterpret)) 07793 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 07794 if (!ast_strlen_zero(user->mohsuggest)) 07795 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 07796 if (!ast_strlen_zero(user->parkinglot)) 07797 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot); 07798 if (user->amaflags) 07799 iaxs[callno]->amaflags = user->amaflags; 07800 if (!ast_strlen_zero(user->language)) 07801 ast_string_field_set(iaxs[callno], language, user->language); 07802 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 07803 /* Keep this check last */ 07804 if (!ast_strlen_zero(user->dbsecret)) { 07805 char *family, *key=NULL; 07806 char buf[80]; 07807 family = ast_strdupa(user->dbsecret); 07808 key = strchr(family, '/'); 07809 if (key) { 07810 *key = '\0'; 07811 key++; 07812 } 07813 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 07814 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 07815 else 07816 ast_string_field_set(iaxs[callno], secret, buf); 07817 } else 07818 ast_string_field_set(iaxs[callno], secret, user->secret); 07819 res = 0; 07820 user = user_unref(user); 07821 } else { 07822 /* user was not found, but we should still fake an AUTHREQ. 07823 * Set authmethods to the last known authmethod used by the system 07824 * Set a fake secret, it's not looked at, just required to attempt authentication. 07825 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 07826 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 07827 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07828 iaxs[callno]->authrej = 1; 07829 if (!ast_strlen_zero(iaxs[callno]->username)) { 07830 /* only send the AUTHREQ if a username was specified. */ 07831 res = 0; 07832 } 07833 } 07834 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 07835 return res; 07836 }
| static int check_provisioning | ( | struct sockaddr_in * | sin, | |
| int | sockfd, | |||
| char * | si, | |||
| unsigned int | ver | |||
| ) | [static] |
Definition at line 9476 of file chan_iax2.c.
References ast_debug, iax2_provision(), and iax_provision_version().
Referenced by socket_process().
09477 { 09478 unsigned int ourver; 09479 char rsi[80]; 09480 snprintf(rsi, sizeof(rsi), "si-%s", si); 09481 if (iax_provision_version(&ourver, rsi, 1)) 09482 return 0; 09483 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 09484 if (ourver != ver) 09485 iax2_provision(sin, sockfd, NULL, rsi, 1); 09486 return 0; 09487 }
| static int check_srcaddr | ( | struct sockaddr * | sa, | |
| socklen_t | salen | |||
| ) | [static] |
Check if address can be used as packet source.
Definition at line 12330 of file chan_iax2.c.
References ast_debug, ast_log(), errno, and LOG_ERROR.
Referenced by peer_set_srcaddr().
12331 { 12332 int sd; 12333 int res; 12334 12335 sd = socket(AF_INET, SOCK_DGRAM, 0); 12336 if (sd < 0) { 12337 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 12338 return -1; 12339 } 12340 12341 res = bind(sd, sa, salen); 12342 if (res < 0) { 12343 ast_debug(1, "Can't bind: %s\n", strerror(errno)); 12344 close(sd); 12345 return 1; 12346 } 12347 12348 close(sd); 12349 return 0; 12350 }
| static void cleanup_thread_list | ( | void * | head | ) | [static] |
Definition at line 14362 of file chan_iax2.c.
References AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, iax2_thread::cond, iax2_thread::lock, signal_condition(), iax2_thread::stop, thread, and iax2_thread::threadid.
Referenced by __unload_module().
14363 { 14364 AST_LIST_HEAD(iax2_thread_list, iax2_thread); 14365 struct iax2_thread_list *list_head = head; 14366 struct iax2_thread *thread; 14367 14368 AST_LIST_LOCK(list_head); 14369 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) { 14370 pthread_t thread_id = thread->threadid; 14371 14372 thread->stop = 1; 14373 signal_condition(&thread->lock, &thread->cond); 14374 14375 AST_LIST_UNLOCK(list_head); 14376 pthread_join(thread_id, NULL); 14377 AST_LIST_LOCK(list_head); 14378 } 14379 AST_LIST_UNLOCK(list_head); 14380 }
| static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 8394 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().
08395 { 08396 char exten[256] = ""; 08397 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0; 08398 struct iax2_dpcache *dp = NULL; 08399 08400 if (ies->called_number) 08401 ast_copy_string(exten, ies->called_number, sizeof(exten)); 08402 08403 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 08404 status = CACHE_FLAG_EXISTS; 08405 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 08406 status = CACHE_FLAG_CANEXIST; 08407 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 08408 status = CACHE_FLAG_NONEXISTENT; 08409 08410 if (ies->refresh) 08411 expiry = ies->refresh; 08412 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 08413 matchmore = CACHE_FLAG_MATCHMORE; 08414 08415 AST_LIST_LOCK(&dpcache); 08416 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) { 08417 if (strcmp(dp->exten, exten)) 08418 continue; 08419 AST_LIST_REMOVE_CURRENT(peer_list); 08420 dp->callno = 0; 08421 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 08422 if (dp->flags & CACHE_FLAG_PENDING) { 08423 dp->flags &= ~CACHE_FLAG_PENDING; 08424 dp->flags |= status; 08425 dp->flags |= matchmore; 08426 } 08427 /* Wake up waiters */ 08428 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 08429 if (dp->waiters[x] > -1) { 08430 if (write(dp->waiters[x], "asdf", 4) < 0) { 08431 } 08432 } 08433 } 08434 } 08435 AST_LIST_TRAVERSE_SAFE_END; 08436 AST_LIST_UNLOCK(&dpcache); 08437 08438 return 0; 08439 }
| static char * complete_iax2_peers | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state, | |||
| uint64_t | flags | |||
| ) | [static] |
Definition at line 3886 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().
03887 { 03888 int which = 0; 03889 struct iax2_peer *peer; 03890 char *res = NULL; 03891 int wordlen = strlen(word); 03892 struct ao2_iterator i; 03893 03894 i = ao2_iterator_init(peers, 0); 03895 while ((peer = ao2_iterator_next(&i))) { 03896 if (!strncasecmp(peer->name, word, wordlen) && ++which > state 03897 && (!flags || ast_test_flag64(peer, flags))) { 03898 res = ast_strdup(peer->name); 03899 peer_unref(peer); 03900 break; 03901 } 03902 peer_unref(peer); 03903 } 03904 ao2_iterator_destroy(&i); 03905 03906 return res; 03907 }
| static char * complete_iax2_unregister | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 6964 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().
06965 { 06966 int which = 0; 06967 struct iax2_peer *p = NULL; 06968 char *res = NULL; 06969 int wordlen = strlen(word); 06970 06971 /* 0 - iax2; 1 - unregister; 2 - <peername> */ 06972 if (pos == 2) { 06973 struct ao2_iterator i = ao2_iterator_init(peers, 0); 06974 while ((p = ao2_iterator_next(&i))) { 06975 if (!strncasecmp(p->name, word, wordlen) && 06976 ++which > state && p->expire > 0) { 06977 res = ast_strdup(p->name); 06978 peer_unref(p); 06979 break; 06980 } 06981 peer_unref(p); 06982 } 06983 ao2_iterator_destroy(&i); 06984 } 06985 06986 return res; 06987 }
| static int complete_transfer | ( | int | callno, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 8441 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().
08442 { 08443 int peercallno = 0; 08444 struct chan_iax2_pvt *pvt = iaxs[callno]; 08445 struct iax_frame *cur; 08446 jb_frame frame; 08447 08448 if (ies->callno) 08449 peercallno = ies->callno; 08450 08451 if (peercallno < 1) { 08452 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08453 return -1; 08454 } 08455 remove_by_transfercallno(pvt); 08456 /* since a transfer has taken place, the address will change. 08457 * This must be accounted for in the peercnts table. Remove 08458 * the old address and add the new one */ 08459 peercnt_remove_by_addr(&pvt->addr); 08460 peercnt_add(&pvt->transfer); 08461 /* now copy over the new address */ 08462 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 08463 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 08464 /* Reset sequence numbers */ 08465 pvt->oseqno = 0; 08466 pvt->rseqno = 0; 08467 pvt->iseqno = 0; 08468 pvt->aseqno = 0; 08469 08470 if (pvt->peercallno) { 08471 remove_by_peercallno(pvt); 08472 } 08473 pvt->peercallno = peercallno; 08474 /*this is where the transfering call swiches hash tables */ 08475 store_by_peercallno(pvt); 08476 pvt->transferring = TRANSFER_NONE; 08477 pvt->svoiceformat = -1; 08478 pvt->voiceformat = 0; 08479 pvt->svideoformat = -1; 08480 pvt->videoformat = 0; 08481 pvt->transfercallno = 0; 08482 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 08483 memset(&pvt->offset, 0, sizeof(pvt->offset)); 08484 /* reset jitterbuffer */ 08485 while(jb_getall(pvt->jb,&frame) == JB_OK) 08486 iax2_frame_free(frame.data); 08487 jb_reset(pvt->jb); 08488 pvt->lag = 0; 08489 pvt->last = 0; 08490 pvt->lastsent = 0; 08491 pvt->nextpred = 0; 08492 pvt->pingtime = DEFAULT_RETRY_TIME; 08493 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) { 08494 /* We must cancel any packets that would have been transmitted 08495 because now we're talking to someone new. It's okay, they 08496 were transmitted to someone that didn't care anyway. */ 08497 cur->retries = -1; 08498 } 08499 return 0; 08500 }
| static unsigned char compress_subclass | ( | iax2_format | subclass | ) | [static] |
Definition at line 1605 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().
01606 { 01607 int x; 01608 int power=-1; 01609 /* If it's 64 or smaller, just return it */ 01610 if (subclass < IAX_FLAG_SC_LOG) 01611 return subclass; 01612 /* Otherwise find its power */ 01613 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01614 if (subclass & (1LL << x)) { 01615 if (power > -1) { 01616 ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass); 01617 return 0; 01618 } else 01619 power = x; 01620 } 01621 } 01622 return power | IAX_FLAG_SC_LOG; 01623 }
| static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ie_data * | iep | |||
| ) | [static] |
Definition at line 9489 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().
09490 { 09491 jb_info stats; 09492 jb_getinfo(pvt->jb, &stats); 09493 09494 memset(iep, 0, sizeof(*iep)); 09495 09496 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 09497 if(stats.frames_in == 0) stats.frames_in = 1; 09498 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 09499 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 09500 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 09501 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 09502 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 09503 }
| static int create_addr | ( | const char * | peername, | |
| struct ast_channel * | c, | |||
| struct sockaddr_in * | sin, | |||
| struct create_addr_info * | cai | |||
| ) | [static] |
Definition at line 4616 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_format_cap_iter_end(), ast_format_cap_iter_next(), ast_format_cap_iter_start(), ast_get_ip_or_srv(), ast_getformatname(), ast_log(), ast_sockaddr_to_sin, ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, iax2_peer::cid_name, create_addr_info::cid_name, iax2_peer::cid_num, create_addr_info::cid_num, iax2_peer::context, create_addr_info::context, iax2_peer::dbsecret, iax2_peer::defaddr, iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, IAX_DEFAULT_PORTNO, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, iax2_peer::mohinterpret, create_addr_info::mohinterpret, iax2_peer::mohsuggest, create_addr_info::mohsuggest, ast_channel::nativeformats, iax2_peer::outkey, create_addr_info::outkey, peer_unref(), iax2_peer::peercontext, create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, iax2_peer::secret, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, ast_sockaddr::ss, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag.
04617 { 04618 struct iax2_peer *peer; 04619 int res = -1; 04620 struct ast_codec_pref ourprefs; 04621 struct sockaddr_in peer_addr; 04622 04623 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK); 04624 cai->sockfd = defaultsockfd; 04625 cai->maxtime = 0; 04626 sin->sin_family = AF_INET; 04627 04628 if (!(peer = find_peer(peername, 1))) { 04629 struct ast_sockaddr sin_tmp; 04630 04631 cai->found = 0; 04632 sin_tmp.ss.ss_family = AF_INET; 04633 if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) { 04634 ast_log(LOG_WARNING, "No such host: %s\n", peername); 04635 return -1; 04636 } 04637 ast_sockaddr_to_sin(&sin_tmp, sin); 04638 if (sin->sin_port == 0) { 04639 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 04640 } 04641 /* use global iax prefs for unknown peer/user */ 04642 /* But move the calling channel's native codec to the top of the preference list */ 04643 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 04644 if (c) { 04645 struct ast_format tmpfmt; 04646 ast_format_cap_iter_start(c->nativeformats); 04647 while (!(ast_format_cap_iter_next(c->nativeformats, &tmpfmt))) { 04648 ast_codec_pref_prepend(&ourprefs, &tmpfmt, 1); 04649 } 04650 ast_format_cap_iter_end(c->nativeformats); 04651 } 04652 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04653 return 0; 04654 } 04655 04656 cai->found = 1; 04657 04658 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 04659 04660 /* if the peer has no address (current or default), return failure */ 04661 if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) { 04662 goto return_unref; 04663 } 04664 04665 /* if the peer is being monitored and is currently unreachable, return failure */ 04666 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 04667 goto return_unref; 04668 04669 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 04670 cai->maxtime = peer->maxms; 04671 cai->capability = peer->capability; 04672 cai->encmethods = peer->encmethods; 04673 cai->sockfd = peer->sockfd; 04674 cai->adsi = peer->adsi; 04675 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 04676 /* Move the calling channel's native codec to the top of the preference list */ 04677 if (c) { 04678 struct ast_format tmpfmt; 04679 ast_format_cap_iter_start(c->nativeformats); 04680 while (!(ast_format_cap_iter_next(c->nativeformats, &tmpfmt))) { 04681 ast_debug(1, "prepending %s to prefs\n", ast_getformatname(&tmpfmt)); 04682 ast_codec_pref_prepend(&ourprefs, &tmpfmt, 1); 04683 } 04684 ast_format_cap_iter_end(c->nativeformats); 04685 } 04686 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04687 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 04688 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 04689 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 04690 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 04691 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 04692 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num)); 04693 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name)); 04694 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 04695 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 04696 if (ast_strlen_zero(peer->dbsecret)) { 04697 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 04698 } else { 04699 char *family; 04700 char *key = NULL; 04701 04702 family = ast_strdupa(peer->dbsecret); 04703 key = strchr(family, '/'); 04704 if (key) 04705 *key++ = '\0'; 04706 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 04707 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 04708 goto return_unref; 04709 } 04710 } 04711 04712 if (peer_addr.sin_addr.s_addr) { 04713 sin->sin_addr = peer_addr.sin_addr; 04714 sin->sin_port = peer_addr.sin_port; 04715 } else { 04716 sin->sin_addr = peer->defaddr.sin_addr; 04717 sin->sin_port = peer->defaddr.sin_port; 04718 } 04719 04720 res = 0; 04721 04722 return_unref: 04723 peer_unref(peer); 04724 04725 return res; 04726 }
| static int create_callno_pools | ( | void | ) | [static] |
Definition at line 2739 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().
02740 { 02741 uint16_t i; 02742 02743 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02744 return -1; 02745 } 02746 02747 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02748 return -1; 02749 } 02750 02751 /* start at 2, 0 and 1 are reserved */ 02752 for (i = 2; i <= IAX_MAX_CALLS; i++) { 02753 struct callno_entry *callno_entry; 02754 02755 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) { 02756 return -1; 02757 } 02758 02759 callno_entry->callno = i; 02760 02761 if (i < TRUNK_CALL_START) { 02762 ao2_link(callno_pool, callno_entry); 02763 } else { 02764 ao2_link(callno_pool_trunk, callno_entry); 02765 } 02766 02767 ao2_ref(callno_entry, -1); 02768 } 02769 02770 return 0; 02771 }
| 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 6315 of file chan_iax2.c.
References ast_debug, ast_format_from_old_bitfield(), AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, ast_frame_subclass::format, ast_frame::frametype, IAX_FLAG_FULL, ast_frame_subclass::integer, 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().
06316 { 06317 int padding; 06318 unsigned char *workspace; 06319 06320 workspace = alloca(*datalen); 06321 memset(f, 0, sizeof(*f)); 06322 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06323 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06324 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 06325 return -1; 06326 /* Decrypt */ 06327 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 06328 06329 padding = 16 + (workspace[15] & 0x0f); 06330 if (iaxdebug) 06331 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 06332 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 06333 return -1; 06334 06335 *datalen -= padding; 06336 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06337 f->frametype = fh->type; 06338 if (f->frametype == AST_FRAME_VIDEO) { 06339 ast_format_from_old_bitfield(&f->subclass.format, (uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1))); 06340 } else if (f->frametype == AST_FRAME_VOICE) { 06341 ast_format_from_old_bitfield(&f->subclass.format, uncompress_subclass(fh->csub)); 06342 } else { 06343 f->subclass.integer = uncompress_subclass(fh->csub); 06344 } 06345 } else { 06346 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06347 if (iaxdebug) 06348 ast_debug(1, "Decoding mini with length %d\n", *datalen); 06349 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 06350 return -1; 06351 /* Decrypt */ 06352 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 06353 padding = 16 + (workspace[15] & 0x0f); 06354 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 06355 return -1; 06356 *datalen -= padding; 06357 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06358 } 06359 return 0; 06360 }
| static int decrypt_frame | ( | int | callno, | |
| struct ast_iax2_full_hdr * | fh, | |||
| struct ast_frame * | f, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 6403 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().
06404 { 06405 int res=-1; 06406 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) { 06407 /* Search for possible keys, given secrets */ 06408 struct MD5Context md5; 06409 unsigned char digest[16]; 06410 char *tmppw, *stringp; 06411 06412 tmppw = ast_strdupa(iaxs[callno]->secret); 06413 stringp = tmppw; 06414 while ((tmppw = strsep(&stringp, ";"))) { 06415 MD5Init(&md5); 06416 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 06417 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 06418 MD5Final(digest, &md5); 06419 build_encryption_keys(digest, iaxs[callno]); 06420 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06421 if (!res) { 06422 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED); 06423 break; 06424 } 06425 } 06426 } else 06427 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06428 return res; 06429 }
| 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 9636 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().
09637 { 09638 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 09639 struct ast_iax2_full_hdr *fh, *cur_fh; 09640 09641 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 09642 return; 09643 09644 pkt_buf->len = from_here->buf_len; 09645 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 09646 09647 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 09648 ast_mutex_lock(&to_here->lock); 09649 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 09650 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 09651 if (fh->oseqno < cur_fh->oseqno) { 09652 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry); 09653 break; 09654 } 09655 } 09656 AST_LIST_TRAVERSE_SAFE_END 09657 09658 if (!cur_pkt_buf) 09659 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 09660 09661 ast_mutex_unlock(&to_here->lock); 09662 }
| static void delete_users | ( | void | ) | [static] |
Definition at line 13014 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_DEL, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, iax2_destroy(), peer_delme_cb(), chan_iax2_pvt::reg, and user_delme_cb().
13015 { 13016 struct iax2_registry *reg; 13017 13018 ao2_callback(users, 0, user_delme_cb, NULL); 13019 13020 AST_LIST_LOCK(®istrations); 13021 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 13022 if (sched) { 13023 AST_SCHED_DEL(sched, reg->expire); 13024 } 13025 if (reg->callno) { 13026 int callno = reg->callno; 13027 ast_mutex_lock(&iaxsl[callno]); 13028 if (iaxs[callno]) { 13029 iaxs[callno]->reg = NULL; 13030 iax2_destroy(callno); 13031 } 13032 ast_mutex_unlock(&iaxsl[callno]); 13033 } 13034 if (reg->dnsmgr) 13035 ast_dnsmgr_release(reg->dnsmgr); 13036 ast_free(reg); 13037 } 13038 AST_LIST_UNLOCK(®istrations); 13039 13040 ao2_callback(peers, 0, peer_delme_cb, NULL); 13041 }
| static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 3069 of file chan_iax2.c.
References ast_free, ast_iax2_firmware_header::datalen, iax_firmware::fd, and iax_firmware::fwh.
Referenced by reload_firmware().
03070 { 03071 /* Close firmware */ 03072 if (cur->fwh) { 03073 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 03074 } 03075 close(cur->fd); 03076 ast_free(cur); 03077 }
| static void dp_lookup | ( | int | callno, | |
| const char * | context, | |||
| const char * | callednum, | |||
| const char * | callerid, | |||
| int | skiplock | |||
| ) | [static] |
Definition at line 9291 of file chan_iax2.c.
References ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_IAX, ast_ignore_pattern(), ast_matchmore_extension(), ast_mutex_lock, ast_mutex_unlock, ast_parking_ext_valid(), iax_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().
09292 { 09293 unsigned short dpstatus = 0; 09294 struct iax_ie_data ied1; 09295 int mm; 09296 09297 memset(&ied1, 0, sizeof(ied1)); 09298 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 09299 /* Must be started */ 09300 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 09301 dpstatus = IAX_DPSTATUS_EXISTS; 09302 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 09303 dpstatus = IAX_DPSTATUS_CANEXIST; 09304 } else { 09305 dpstatus = IAX_DPSTATUS_NONEXISTENT; 09306 } 09307 if (ast_ignore_pattern(context, callednum)) 09308 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 09309 if (mm) 09310 dpstatus |= IAX_DPSTATUS_MATCHMORE; 09311 if (!skiplock) 09312 ast_mutex_lock(&iaxsl[callno]); 09313 if (iaxs[callno]) { 09314 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 09315 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 09316 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 09317 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 09318 } 09319 if (!skiplock) 09320 ast_mutex_unlock(&iaxsl[callno]); 09321 }
| static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 9323 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().
09324 { 09325 /* Look up for dpreq */ 09326 struct dpreq_data *dpr = data; 09327 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 09328 if (dpr->callerid) 09329 ast_free(dpr->callerid); 09330 ast_free(dpr); 09331 return NULL; 09332 }
| static void encmethods_to_str | ( | int | e, | |
| struct ast_str * | buf | |||
| ) | [static] |
Definition at line 1539 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(), manager_iax2_show_peer_list(), and peers_data_provider_get().
01540 { 01541 ast_str_set(&buf, 0, "("); 01542 if (e & IAX_ENCRYPT_AES128) { 01543 ast_str_append(&buf, 0, "aes128"); 01544 } 01545 if (e & IAX_ENCRYPT_KEYROTATE) { 01546 ast_str_append(&buf, 0, ",keyrotate"); 01547 } 01548 if (ast_str_strlen(buf) > 1) { 01549 ast_str_append(&buf, 0, ")"); 01550 } else { 01551 ast_str_set(&buf, 0, "No"); 01552 } 01553 }
| static int encrypt_frame | ( | ast_aes_encrypt_key * | ecx, | |
| struct ast_iax2_full_hdr * | fh, | |||
| unsigned char * | poo, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 6362 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().
06363 { 06364 int padding; 06365 unsigned char *workspace; 06366 workspace = alloca(*datalen + 32); 06367 if (!workspace) 06368 return -1; 06369 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06370 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06371 if (iaxdebug) 06372 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 06373 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 06374 padding = 16 + (padding & 0xf); 06375 memcpy(workspace, poo, padding); 06376 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06377 workspace[15] &= 0xf0; 06378 workspace[15] |= (padding & 0xf); 06379 if (iaxdebug) 06380 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]); 06381 *datalen += padding; 06382 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 06383 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 06384 memcpy(poo, workspace + *datalen - 32, 32); 06385 } else { 06386 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06387 if (iaxdebug) 06388 ast_debug(1, "Encoding mini frame with length %d\n", *datalen); 06389 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 06390 padding = 16 + (padding & 0xf); 06391 memcpy(workspace, poo, padding); 06392 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06393 workspace[15] &= 0xf0; 06394 workspace[15] |= (padding & 0x0f); 06395 *datalen += padding; 06396 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 06397 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 06398 memcpy(poo, workspace + *datalen - 32, 32); 06399 } 06400 return 0; 06401 }
| static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8709 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().
08710 { 08711 #ifdef SCHED_MULTITHREADED 08712 if (schedule_action(__expire_registry, data)) 08713 #endif 08714 __expire_registry(data); 08715 return 0; 08716 }
| 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 13701 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, iax2_dpcache::orig, iax2_dpcache::peercontext, and iax2_dpcache::waiters.
Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore().
13702 { 13703 struct iax2_dpcache *dp = NULL; 13704 struct timeval now = ast_tvnow(); 13705 int x, com[2], timeout, old = 0, outfd, doabort, callno; 13706 struct ast_channel *c = NULL; 13707 struct ast_frame *f = NULL; 13708 13709 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) { 13710 if (ast_tvcmp(now, dp->expiry) > 0) { 13711 AST_LIST_REMOVE_CURRENT(cache_list); 13712 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno) 13713 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno); 13714 else 13715 ast_free(dp); 13716 continue; 13717 } 13718 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 13719 break; 13720 } 13721 AST_LIST_TRAVERSE_SAFE_END; 13722 13723 if (!dp) { 13724 /* No matching entry. Create a new one. */ 13725 /* First, can we make a callno? */ 13726 if ((callno = cache_get_callno_locked(data)) < 0) { 13727 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 13728 return NULL; 13729 } 13730 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 13731 ast_mutex_unlock(&iaxsl[callno]); 13732 return NULL; 13733 } 13734 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 13735 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 13736 dp->expiry = ast_tvnow(); 13737 dp->orig = dp->expiry; 13738 /* Expires in 30 mins by default */ 13739 dp->expiry.tv_sec += iaxdefaultdpcache; 13740 dp->flags = CACHE_FLAG_PENDING; 13741 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) 13742 dp->waiters[x] = -1; 13743 /* Insert into the lists */ 13744 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list); 13745 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list); 13746 /* Send the request if we're already up */ 13747 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 13748 iax2_dprequest(dp, callno); 13749 ast_mutex_unlock(&iaxsl[callno]); 13750 } 13751 13752 /* By here we must have a dp */ 13753 if (dp->flags & CACHE_FLAG_PENDING) { 13754 /* Okay, here it starts to get nasty. We need a pipe now to wait 13755 for a reply to come back so long as it's pending */ 13756 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13757 /* Find an empty slot */ 13758 if (dp->waiters[x] < 0) 13759 break; 13760 } 13761 if (x >= ARRAY_LEN(dp->waiters)) { 13762 ast_log(LOG_WARNING, "No more waiter positions available\n"); 13763 return NULL; 13764 } 13765 if (pipe(com)) { 13766 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 13767 return NULL; 13768 } 13769 dp->waiters[x] = com[1]; 13770 /* Okay, now we wait */ 13771 timeout = iaxdefaulttimeout * 1000; 13772 /* Temporarily unlock */ 13773 AST_LIST_UNLOCK(&dpcache); 13774 /* Defer any dtmf */ 13775 if (chan) 13776 old = ast_channel_defer_dtmf(chan); 13777 doabort = 0; 13778 while(timeout) { 13779 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 13780 if (outfd > -1) 13781 break; 13782 if (!c) 13783 continue; 13784 if (!(f = ast_read(c))) { 13785 doabort = 1; 13786 break; 13787 } 13788 ast_frfree(f); 13789 } 13790 if (!timeout) { 13791 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 13792 } 13793 AST_LIST_LOCK(&dpcache); 13794 dp->waiters[x] = -1; 13795 close(com[1]); 13796 close(com[0]); 13797 if (doabort) { 13798 /* Don't interpret anything, just abort. Not sure what th epoint 13799 of undeferring dtmf on a hung up channel is but hey whatever */ 13800 if (!old && chan) 13801 ast_channel_undefer_dtmf(chan); 13802 return NULL; 13803 } 13804 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 13805 /* Now to do non-independent analysis the results of our wait */ 13806 if (dp->flags & CACHE_FLAG_PENDING) { 13807 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 13808 pending. Don't let it take as long to timeout. */ 13809 dp->flags &= ~CACHE_FLAG_PENDING; 13810 dp->flags |= CACHE_FLAG_TIMEOUT; 13811 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 13812 systems without leaving it unavailable once the server comes back online */ 13813 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 13814 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13815 if (dp->waiters[x] > -1) { 13816 if (write(dp->waiters[x], "asdf", 4) < 0) { 13817 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 13818 } 13819 } 13820 } 13821 } 13822 } 13823 /* Our caller will obtain the rest */ 13824 if (!old && chan) 13825 ast_channel_undefer_dtmf(chan); 13826 } 13827 return dp; 13828 }
| static int find_callno | ( | unsigned short | callno, | |
| unsigned short | dcallno, | |||
| struct sockaddr_in * | sin, | |||
| int | new, | |||
| int | sockfd, | |||
| int | full_frame | |||
| ) | [static] |
Definition at line 2994 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
02994 { 02995 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 02996 }
| static int find_callno_locked | ( | unsigned short | callno, | |
| unsigned short | dcallno, | |||
| struct sockaddr_in * | sin, | |||
| int | new, | |||
| int | sockfd, | |||
| int | full_frame | |||
| ) | [static] |
Definition at line 2998 of file chan_iax2.c.
References __find_callno().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_provision(), iax2_request(), and socket_process_meta().
02998 { 02999 03000 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 03001 }
| static struct iax2_thread* find_idle_thread | ( | void | ) | [static, read] |
Definition at line 1393 of file chan_iax2.c.
References ast_atomic_fetchadd_int(), ast_calloc, ast_cond_destroy, ast_cond_init, ast_cond_wait, ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, iax2_thread::cond, iax2_thread::ffinfo, iax2_process_thread(), IAX_THREAD_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxdynamicthreadnum, iaxmaxthreadcount, iax2_thread::init_cond, iax2_thread::init_lock, iax2_thread::lock, thread, iax2_thread::threadid, iax2_thread::threadnum, and iax2_thread::type.
Referenced by __schedule_action(), and socket_read().
01394 { 01395 struct iax2_thread *thread = NULL; 01396 01397 /* Pop the head of the idle list off */ 01398 AST_LIST_LOCK(&idle_list); 01399 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 01400 AST_LIST_UNLOCK(&idle_list); 01401 01402 /* If we popped a thread off the idle list, just return it */ 01403 if (thread) { 01404 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01405 return thread; 01406 } 01407 01408 /* Pop the head of the dynamic list off */ 01409 AST_LIST_LOCK(&dynamic_list); 01410 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 01411 AST_LIST_UNLOCK(&dynamic_list); 01412 01413 /* If we popped a thread off the dynamic list, just return it */ 01414 if (thread) { 01415 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01416 return thread; 01417 } 01418 01419 /* If we can't create a new dynamic thread for any reason, return no thread at all */ 01420 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread)))) 01421 return NULL; 01422 01423 /* Set default values */ 01424 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1); 01425 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1); 01426 thread->type = IAX_THREAD_TYPE_DYNAMIC; 01427 01428 /* Initialize lock and condition */ 01429 ast_mutex_init(&thread->lock); 01430 ast_cond_init(&thread->cond, NULL); 01431 ast_mutex_init(&thread->init_lock); 01432 ast_cond_init(&thread->init_cond, NULL); 01433 ast_mutex_lock(&thread->init_lock); 01434 01435 /* Create thread and send it on it's way */ 01436 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 01437 ast_cond_destroy(&thread->cond); 01438 ast_mutex_destroy(&thread->lock); 01439 ast_mutex_unlock(&thread->init_lock); 01440 ast_cond_destroy(&thread->init_cond); 01441 ast_mutex_destroy(&thread->init_lock); 01442 ast_free(thread); 01443 return NULL; 01444 } 01445 01446 /* this thread is not processing a full frame (since it is idle), 01447 so ensure that the field for the full frame call number is empty */ 01448 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01449 01450 /* Wait for the thread to be ready before returning it to the caller */ 01451 ast_cond_wait(&thread->init_cond, &thread->init_lock); 01452 01453 /* Done with init_lock */ 01454 ast_mutex_unlock(&thread->init_lock); 01455 01456 return thread; 01457 }
| static struct iax2_peer* find_peer | ( | const char * | name, | |
| int | realtime | |||
| ) | [static, read] |
Definition at line 1773 of file chan_iax2.c.
References ao2_find, OBJ_KEY, and realtime_peer().
01774 { 01775 struct iax2_peer *peer = NULL; 01776 01777 peer = ao2_find(peers, name, OBJ_KEY); 01778 01779 /* Now go for realtime if applicable */ 01780 if(!peer && realtime) 01781 peer = realtime_peer(name, NULL); 01782 01783 return peer; 01784 }
| static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
| int | fd | |||
| ) | [static, read] |
Definition at line 6134 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_calloc, ast_debug, ast_inet_ntoa(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_init, ast_mutex_lock, ast_tvnow(), inaddrcmp(), iax2_trunk_peer::lastsent, iax2_trunk_peer::lock, iax2_trunk_peer::sockfd, and iax2_trunk_peer::trunkact.
Referenced by iax2_trunk_queue(), and socket_process_meta().
06135 { 06136 struct iax2_trunk_peer *tpeer = NULL; 06137 06138 /* Finds and locks trunk peer */ 06139 AST_LIST_LOCK(&tpeers); 06140 06141 AST_LIST_TRAVERSE(&tpeers, tpeer, list) { 06142 if (!inaddrcmp(&tpeer->addr, sin)) { 06143 ast_mutex_lock(&tpeer->lock); 06144 break; 06145 } 06146 } 06147 06148 if (!tpeer) { 06149 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 06150 ast_mutex_init(&tpeer->lock); 06151 tpeer->lastsent = 9999; 06152 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 06153 tpeer->trunkact = ast_tvnow(); 06154 ast_mutex_lock(&tpeer->lock); 06155 tpeer->sockfd = fd; 06156 #ifdef SO_NO_CHECK 06157 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 06158 #endif 06159 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 06160 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list); 06161 } 06162 } 06163 06164 AST_LIST_UNLOCK(&tpeers); 06165 06166 return tpeer; 06167 }
| static struct iax2_user* find_user | ( | const char * | name | ) | [static, read] |
| static unsigned int fix_peerts | ( | struct timeval * | rxtrunktime, | |
| int | callno, | |||
| unsigned int | ts | |||
| ) | [static] |
Definition at line 5946 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), and chan_iax2_pvt::rxcore.
Referenced by socket_process_meta().
05947 { 05948 long ms; /* NOT unsigned */ 05949 if (ast_tvzero(iaxs[callno]->rxcore)) { 05950 /* Initialize rxcore time if appropriate */ 05951 iaxs[callno]->rxcore = ast_tvnow(); 05952 /* Round to nearest 20ms so traces look pretty */ 05953 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 05954 } 05955 /* Calculate difference between trunk and channel */ 05956 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore); 05957 /* Return as the sum of trunk time and the difference between trunk and real time */ 05958 return ms + ts; 05959 }
| static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 12161 of file chan_iax2.c.
References ast_free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
12162 { 12163 struct iax2_context *conl; 12164 while(con) { 12165 conl = con; 12166 con = con->next; 12167 ast_free(conl); 12168 } 12169 }
| static void free_signaling_queue_entry | ( | struct signaling_queue_entry * | s | ) | [static] |
Definition at line 1895 of file chan_iax2.c.
References ast_free, ast_frame::data, ast_frame::datalen, signaling_queue_entry::f, and ast_frame::ptr.
Referenced by pvt_destructor(), queue_signalling(), and send_signaling().
| static int function_iaxpeer | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 13951 of file chan_iax2.c.
References iax2_peer::addr, iax2_trunk_peer::addr, ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_inet_ntoa(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_test_flag64, iax2_peer::callno, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::expire, find_peer(), iax2_getformatname_multiple(), IAX_DYNAMIC, iax2_peer::mailbox, peer_status(), peer_unref(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.
13952 { 13953 struct iax2_peer *peer; 13954 char *peername, *colname; 13955 13956 peername = ast_strdupa(data); 13957 13958 /* if our channel, return the IP address of the endpoint of current channel */ 13959 if (!strcmp(peername,"CURRENTCHANNEL")) { 13960 unsigned short callno; 13961 if (chan->tech != &iax2_tech) 13962 return -1; 13963 callno = PTR_TO_CALLNO(chan->tech_pvt); 13964 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 13965 return 0; 13966 } 13967 13968 if ((colname = strchr(peername, ','))) 13969 *colname++ = '\0'; 13970 else 13971 colname = "ip"; 13972 13973 if (!(peer = find_peer(peername, 1))) 13974 return -1; 13975 13976 if (!strcasecmp(colname, "ip")) { 13977 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len); 13978 } else if (!strcasecmp(colname, "status")) { 13979 peer_status(peer, buf, len); 13980 } else if (!strcasecmp(colname, "mailbox")) { 13981 ast_copy_string(buf, peer->mailbox, len); 13982 } else if (!strcasecmp(colname, "context")) { 13983 ast_copy_string(buf, peer->context, len); 13984 } else if (!strcasecmp(colname, "expire")) { 13985 snprintf(buf, len, "%d", peer->expire); 13986 } else if (!strcasecmp(colname, "dynamic")) { 13987 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 13988 } else if (!strcasecmp(colname, "callerid_name")) { 13989 ast_copy_string(buf, peer->cid_name, len); 13990 } else if (!strcasecmp(colname, "callerid_num")) { 13991 ast_copy_string(buf, peer->cid_num, len); 13992 } else if (!strcasecmp(colname, "codecs")) { 13993 iax2_getformatname_multiple(buf, len -1, peer->capability); 13994 } else if (!strncasecmp(colname, "codec[", 6)) { 13995 char *codecnum, *ptr; 13996 struct ast_format tmpfmt; 13997 codecnum = strchr(colname, '['); 13998 *codecnum = '\0'; 13999 codecnum++; 14000 if ((ptr = strchr(codecnum, ']'))) { 14001 *ptr = '\0'; 14002 } 14003 if((ast_codec_pref_index(&peer->prefs, atoi(codecnum), &tmpfmt))) { 14004 ast_copy_string(buf, ast_getformatname(&tmpfmt), len); 14005 } else { 14006 buf[0] = '\0'; 14007 } 14008 } else { 14009 buf[0] = '\0'; 14010 } 14011 14012 peer_unref(peer); 14013 14014 return 0; 14015 }
| static int get_auth_methods | ( | const char * | value | ) | [static] |
Definition at line 12314 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
12315 { 12316 int methods = 0; 12317 if (strstr(value, "rsa")) 12318 methods |= IAX_AUTH_RSA; 12319 if (strstr(value, "md5")) 12320 methods |= IAX_AUTH_MD5; 12321 if (strstr(value, "plaintext")) 12322 methods |= IAX_AUTH_PLAINTEXT; 12323 return methods; 12324 }
| static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1555 of file chan_iax2.c.
References ast_true(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.
Referenced by build_peer(), build_user(), and set_config().
01556 { 01557 int e; 01558 if (!strcasecmp(s, "aes128")) 01559 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01560 else if (ast_true(s)) 01561 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01562 else 01563 e = 0; 01564 return e; 01565 }
| static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 4198 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
04199 { 04200 #ifdef SCHED_MULTITHREADED 04201 if (schedule_action(__get_from_jb, data)) 04202 #endif 04203 __get_from_jb(data); 04204 return 0; 04205 }
| static struct callno_entry * get_unused_callno | ( | int | trunk, | |
| int | validated | |||
| ) | [static, read] |
Definition at line 2672 of file chan_iax2.c.
References ao2_container_count(), ao2_find, ao2_lock, ao2_unlock, ast_log(), LOG_WARNING, OBJ_CONTINUE, OBJ_POINTER, OBJ_UNLINK, and callno_entry::validated.
Referenced by __find_callno(), and make_trunk().
02673 { 02674 struct callno_entry *callno_entry = NULL; 02675 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) { 02676 ast_log(LOG_WARNING, "Out of CallNumbers\n"); 02677 /* Minor optimization for the extreme case. */ 02678 return NULL; 02679 } 02680 02681 /* the callno_pool container is locked here primarily to ensure thread 02682 * safety of the total_nonval_callno_used check and increment */ 02683 ao2_lock(callno_pool); 02684 02685 /* only a certain number of nonvalidated call numbers should be allocated. 02686 * If there ever is an attack, this separates the calltoken validating 02687 * users from the non calltoken validating users. */ 02688 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) { 02689 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval); 02690 ao2_unlock(callno_pool); 02691 return NULL; 02692 } 02693 02694 /* unlink the object from the container, taking over ownership 02695 * of the reference the container had to the object */ 02696 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE); 02697 02698 if (callno_entry) { 02699 callno_entry->validated = validated; 02700 if (!validated) { 02701 total_nonval_callno_used++; 02702 } 02703 } 02704 02705 ao2_unlock(callno_pool); 02706 return callno_entry; 02707 }
| static int handle_call_token | ( | struct ast_iax2_full_hdr * | fh, | |
| struct iax_ies * | ies, | |||
| struct sockaddr_in * | sin, | |||
| int | fd | |||
| ) | [static] |
Definition at line 4934 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), ast_sha1_hash(), ast_str_alloca, ast_str_buffer(), ast_str_set(), iax_ie_data::buf, iax_ies::calltoken, CALLTOKEN_HASH_FORMAT, CALLTOKEN_IE_FORMAT, calltoken_required(), iax_ies::calltokendata, ast_iax2_full_hdr::csub, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, iax_ie_append_str(), IAX_IE_CALLTOKEN, ast_iax2_full_hdr::iseqno, LOG_ERROR, LOG_WARNING, requirecalltoken_mark_auto(), S_OR, ast_iax2_full_hdr::scallno, send_apathetic_reply(), ast_iax2_full_hdr::ts, uncompress_subclass(), and iax_ies::username.
Referenced by socket_process().
04936 { 04937 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d" /* address + port + ts + randomcalldata */ 04938 #define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */ 04939 struct ast_str *buf = ast_str_alloca(256); 04940 time_t t = time(NULL); 04941 char hash[41]; /* 40 char sha1 hash */ 04942 int subclass = uncompress_subclass(fh->csub); 04943 04944 /* ----- Case 1 ----- */ 04945 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */ 04946 struct iax_ie_data ied = { 04947 .buf = { 0 }, 04948 .pos = 0, 04949 }; 04950 04951 /* create the hash with their address data and our timestamp */ 04952 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata); 04953 ast_sha1_hash(hash, ast_str_buffer(buf)); 04954 04955 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash); 04956 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf)); 04957 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied); 04958 04959 return 1; 04960 04961 /* ----- Case 2 ----- */ 04962 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */ 04963 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */ 04964 char *rec_ts = NULL; /* received timestamp */ 04965 unsigned int rec_time; /* received time_t */ 04966 04967 /* split the timestamp from the hash data */ 04968 rec_hash = strchr((char *) ies->calltokendata, '?'); 04969 if (rec_hash) { 04970 *rec_hash++ = '\0'; 04971 rec_ts = (char *) ies->calltokendata; 04972 } 04973 04974 /* check that we have valid data before we do any comparisons */ 04975 if (!rec_hash || !rec_ts) { 04976 goto reject; 04977 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) { 04978 goto reject; 04979 } 04980 04981 /* create a hash with their address and the _TOKEN'S_ timestamp */ 04982 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata); 04983 ast_sha1_hash(hash, ast_str_buffer(buf)); 04984 04985 /* compare hashes and then check timestamp delay */ 04986 if (strcmp(hash, rec_hash)) { 04987 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr)); 04988 goto reject; /* received hash does not match ours, reject */ 04989 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) { 04990 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr)); 04991 goto reject; /* too much delay, reject */ 04992 } 04993 04994 /* at this point the call token is valid, returning 0 04995 * will allow socket_process to continue as usual */ 04996 requirecalltoken_mark_auto(ies->username, subclass); 04997 return 0; 04998 04999 /* ----- Case 3 ----- */ 05000 } else { /* calltokens are not supported for this client, how do we respond? */ 05001 if (calltoken_required(sin, ies->username, subclass)) { 05002 ast_log(LOG_ERROR, "Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenoptional list or setting user %s requirecalltoken=no\n", ast_inet_ntoa(sin->sin_addr), S_OR(ies->username, "guest")); 05003 goto reject; 05004 } 05005 return 0; /* calltoken is not required for this addr, so permit it. */ 05006 } 05007 05008 reject: 05009 /* received frame has failed calltoken inspection, send apathetic reject messages */ 05010 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) { 05011 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 05012 } else { 05013 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 05014 } 05015 05016 return 1; 05017 }
| static char* handle_cli_iax2_provision | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 12008 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, iax2_provision(), iax_prov_complete_template(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
12009 { 12010 int force = 0; 12011 int res; 12012 12013 switch (cmd) { 12014 case CLI_INIT: 12015 e->command = "iax2 provision"; 12016 e->usage = 12017 "Usage: iax2 provision <host> <template> [forced]\n" 12018 " Provisions the given peer or IP address using a template\n" 12019 " matching either 'template' or '*' if the template is not\n" 12020 " found. If 'forced' is specified, even empty provisioning\n" 12021 " fields will be provisioned as empty fields.\n"; 12022 return NULL; 12023 case CLI_GENERATE: 12024 if (a->pos == 3) 12025 return iax_prov_complete_template(a->line, a->word, a->pos, a->n); 12026 return NULL; 12027 } 12028 12029 if (a->argc < 4) 12030 return CLI_SHOWUSAGE; 12031 if (a->argc > 4) { 12032 if (!strcasecmp(a->argv[4], "forced")) 12033 force = 1; 12034 else 12035 return CLI_SHOWUSAGE; 12036 } 12037 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force); 12038 if (res < 0) 12039 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]); 12040 else if (res < 1) 12041 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]); 12042 else 12043 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : ""); 12044 return CLI_SUCCESS; 12045 }
| static char* handle_cli_iax2_prune_realtime | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3627 of file chan_iax2.c.
References ao2_unlink, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_complete(), ast_set_flag64, ast_test_flag64, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), expire_registry(), ast_cli_args::fd, find_peer(), find_user(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, ast_cli_args::line, ast_cli_args::n, peer_ref(), peer_unref(), ast_cli_args::pos, prune_peers(), prune_users(), ast_cli_entry::usage, user_unref(), and ast_cli_args::word.
03628 { 03629 struct iax2_peer *peer = NULL; 03630 struct iax2_user *user = NULL; 03631 static const char * const choices[] = { "all", NULL }; 03632 char *cmplt; 03633 03634 switch (cmd) { 03635 case CLI_INIT: 03636 e->command = "iax2 prune realtime"; 03637 e->usage = 03638 "Usage: iax2 prune realtime [<peername>|all]\n" 03639 " Prunes object(s) from the cache\n"; 03640 return NULL; 03641 case CLI_GENERATE: 03642 if (a->pos == 3) { 03643 cmplt = ast_cli_complete(a->word, choices, a->n); 03644 if (!cmplt) 03645 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS); 03646 return cmplt; 03647 } 03648 return NULL; 03649 } 03650 if (a->argc != 4) 03651 return CLI_SHOWUSAGE; 03652 if (!strcmp(a->argv[3], "all")) { 03653 prune_users(); 03654 prune_peers(); 03655 ast_cli(a->fd, "Cache flushed successfully.\n"); 03656 return CLI_SUCCESS; 03657 } 03658 peer = find_peer(a->argv[3], 0); 03659 user = find_user(a->argv[3]); 03660 if (peer || user) { 03661 if (peer) { 03662 if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 03663 ast_set_flag64(peer, IAX_RTAUTOCLEAR); 03664 expire_registry(peer_ref(peer)); 03665 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]); 03666 } else { 03667 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]); 03668 } 03669 peer_unref(peer); 03670 } 03671 if (user) { 03672 if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 03673 ast_set_flag64(user, IAX_RTAUTOCLEAR); 03674 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]); 03675 } else { 03676 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]); 03677 } 03678 ao2_unlink(users,user); 03679 user_unref(user); 03680 } 03681 } else { 03682 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]); 03683 } 03684 03685 return CLI_SUCCESS; 03686 }
| static char* handle_cli_iax2_reload | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 13605 of file chan_iax2.c.
References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, reload_config(), and ast_cli_entry::usage.
13606 { 13607 switch (cmd) { 13608 case CLI_INIT: 13609 e->command = "iax2 reload"; 13610 e->usage = 13611 "Usage: iax2 reload\n" 13612 " Reloads IAX configuration from iax.conf\n"; 13613 return NULL; 13614 case CLI_GENERATE: 13615 return NULL; 13616 } 13617 13618 reload_config(); 13619 13620 return CLI_SUCCESS; 13621 }
| static char* handle_cli_iax2_set_debug | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7408 of file chan_iax2.c.
References iax2_peer::addr, ao2_ref, ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_inet_ntoa(), ast_sockaddr_to_sin, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), debugaddr, ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
07409 { 07410 switch (cmd) { 07411 case CLI_INIT: 07412 e->command = "iax2 set debug {on|off|peer}"; 07413 e->usage = 07414 "Usage: iax2 set debug {on|off|peer peername}\n" 07415 " Enables/Disables dumping of IAX packets for debugging purposes.\n"; 07416 return NULL; 07417 case CLI_GENERATE: 07418 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) 07419 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 07420 return NULL; 07421 } 07422 07423 if (a->argc < e->args || a->argc > e->args + 1) 07424 return CLI_SHOWUSAGE; 07425 07426 if (!strcasecmp(a->argv[3], "peer")) { 07427 struct iax2_peer *peer; 07428 struct sockaddr_in peer_addr; 07429 07430 07431 if (a->argc != e->args + 1) 07432 return CLI_SHOWUSAGE; 07433 07434 peer = find_peer(a->argv[4], 1); 07435 07436 if (!peer) { 07437 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]); 07438 return CLI_FAILURE; 07439 } 07440 07441 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 07442 07443 debugaddr.sin_addr = peer_addr.sin_addr; 07444 debugaddr.sin_port = peer_addr.sin_port; 07445 07446 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n", 07447 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 07448 07449 ao2_ref(peer, -1); 07450 } else if (!strncasecmp(a->argv[3], "on", 2)) { 07451 iaxdebug = 1; 07452 ast_cli(a->fd, "IAX2 Debugging Enabled\n"); 07453 } else { 07454 iaxdebug = 0; 07455 memset(&debugaddr, 0, sizeof(debugaddr)); 07456 ast_cli(a->fd, "IAX2 Debugging Disabled\n"); 07457 } 07458 return CLI_SUCCESS; 07459 }
| static char* handle_cli_iax2_set_debug_jb | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7487 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), and ast_cli_entry::usage.
07488 { 07489 switch (cmd) { 07490 case CLI_INIT: 07491 e->command = "iax2 set debug jb {on|off}"; 07492 e->usage = 07493 "Usage: iax2 set debug jb {on|off}\n" 07494 " Enables/Disables jitterbuffer debugging information\n"; 07495 return NULL; 07496 case CLI_GENERATE: 07497 return NULL; 07498 } 07499 07500 if (a->argc != e->args) 07501 return CLI_SHOWUSAGE; 07502 07503 if (!strncasecmp(a->argv[e->args -1], "on", 2)) { 07504 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 07505 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 07506 } else { 07507 jb_setoutput(jb_error_output, jb_warning_output, NULL); 07508 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 07509 } 07510 return CLI_SUCCESS; 07511 }
| static char* handle_cli_iax2_set_debug_trunk | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7461 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
07462 { 07463 switch (cmd) { 07464 case CLI_INIT: 07465 e->command = "iax2 set debug trunk {on|off}"; 07466 e->usage = 07467 "Usage: iax2 set debug trunk {on|off}\n" 07468 " Enables/Disables debugging of IAX trunking\n"; 07469 return NULL; 07470 case CLI_GENERATE: 07471 return NULL; 07472 } 07473 07474 if (a->argc != e->args) 07475 return CLI_SHOWUSAGE; 07476 07477 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 07478 iaxtrunkdebug = 1; 07479 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n"); 07480 } else { 07481 iaxtrunkdebug = 0; 07482 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n"); 07483 } 07484 return CLI_SUCCESS; 07485 }
| static char* handle_cli_iax2_set_mtu | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Set trunk MTU from CLI.
Definition at line 3955 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, MAX_TRUNK_MTU, and ast_cli_entry::usage.
03956 { 03957 int mtuv; 03958 03959 switch (cmd) { 03960 case CLI_INIT: 03961 e->command = "iax2 set mtu"; 03962 e->usage = 03963 "Usage: iax2 set mtu <value>\n" 03964 " Set the system-wide IAX IP mtu to <value> bytes net or\n" 03965 " zero to disable. Disabling means that the operating system\n" 03966 " must handle fragmentation of UDP packets when the IAX2 trunk\n" 03967 " packet exceeds the UDP payload size. This is substantially\n" 03968 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n" 03969 " greater for G.711 samples.\n"; 03970 return NULL; 03971 case CLI_GENERATE: 03972 return NULL; 03973 } 03974 03975 if (a->argc != 4) 03976 return CLI_SHOWUSAGE; 03977 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0) 03978 mtuv = MAX_TRUNK_MTU; 03979 else 03980 mtuv = atoi(a->argv[3]); 03981 03982 if (mtuv == 0) { 03983 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 03984 global_max_trunk_mtu = 0; 03985 return CLI_SUCCESS; 03986 } 03987 if (mtuv < 172 || mtuv > 4000) { 03988 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 03989 return CLI_SHOWUSAGE; 03990 } 03991 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 03992 global_max_trunk_mtu = mtuv; 03993 return CLI_SUCCESS; 03994 }
| static char* handle_cli_iax2_show_cache | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3996 of file chan_iax2.c.
References ARRAY_LEN, ast_cli(), ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_tvnow(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, CACHE_FLAG_TRANSMITTED, CACHE_FLAG_UNKNOWN, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, iax2_dpcache::expiry, iax2_dpcache::exten, ast_cli_args::fd, iax2_dpcache::flags, iax2_dpcache::peercontext, ast_cli_entry::usage, and iax2_dpcache::waiters.
03997 { 03998 struct iax2_dpcache *dp = NULL; 03999 char tmp[1024], *pc = NULL; 04000 int s, x, y; 04001 struct timeval now = ast_tvnow(); 04002 04003 switch (cmd) { 04004 case CLI_INIT: 04005 e->command = "iax2 show cache"; 04006 e->usage = 04007 "Usage: iax2 show cache\n" 04008 " Display currently cached IAX Dialplan results.\n"; 04009 return NULL; 04010 case CLI_GENERATE: 04011 return NULL; 04012 } 04013 04014 AST_LIST_LOCK(&dpcache); 04015 04016 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 04017 04018 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) { 04019 s = dp->expiry.tv_sec - now.tv_sec; 04020 tmp[0] = '\0'; 04021 if (dp->flags & CACHE_FLAG_EXISTS) 04022 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 04023 if (dp->flags & CACHE_FLAG_NONEXISTENT) 04024 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 04025 if (dp->flags & CACHE_FLAG_CANEXIST) 04026 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 04027 if (dp->flags & CACHE_FLAG_PENDING) 04028 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 04029 if (dp->flags & CACHE_FLAG_TIMEOUT) 04030 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 04031 if (dp->flags & CACHE_FLAG_TRANSMITTED) 04032 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 04033 if (dp->flags & CACHE_FLAG_MATCHMORE) 04034 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 04035 if (dp->flags & CACHE_FLAG_UNKNOWN) 04036 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 04037 /* Trim trailing pipe */ 04038 if (!ast_strlen_zero(tmp)) { 04039 tmp[strlen(tmp) - 1] = '\0'; 04040 } else { 04041 ast_copy_string(tmp, "(none)", sizeof(tmp)); 04042 } 04043 y = 0; 04044 pc = strchr(dp->peercontext, '@'); 04045 if (!pc) { 04046 pc = dp->peercontext; 04047 } else { 04048 pc++; 04049 } 04050 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 04051 if (dp->waiters[x] > -1) 04052 y++; 04053 } 04054 if (s > 0) { 04055 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 04056 } else { 04057 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 04058 } 04059 } 04060 04061 AST_LIST_UNLOCK(&dpcache); 04062 04063 return CLI_SUCCESS; 04064 }
| static char* handle_cli_iax2_show_callno_limits | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 2613 of file chan_iax2.c.
References peercnt::addr, ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_inet_ntoa(), CLI_GENERATE, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, peercnt::cur, ast_cli_args::fd, peercnt::limit, and ast_cli_entry::usage.
02614 { 02615 struct ao2_iterator i; 02616 struct peercnt *peercnt; 02617 struct sockaddr_in sin; 02618 int found = 0; 02619 02620 switch (cmd) { 02621 case CLI_INIT: 02622 e->command = "iax2 show callnumber usage"; 02623 e->usage = 02624 "Usage: iax2 show callnumber usage [IP address]\n" 02625 " Shows current IP addresses which are consuming iax2 call numbers\n"; 02626 return NULL; 02627 case CLI_GENERATE: 02628 return NULL; 02629 case CLI_HANDLER: 02630 if (a->argc < 4 || a->argc > 5) 02631 return CLI_SHOWUSAGE; 02632 02633 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit"); 02634 i = ao2_iterator_init(peercnts, 0); 02635 while ((peercnt = ao2_iterator_next(&i))) { 02636 sin.sin_addr.s_addr = peercnt->addr; 02637 if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) { 02638 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02639 ao2_ref(peercnt, -1); 02640 found = 1; 02641 break; 02642 } else { 02643 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02644 } 02645 ao2_ref(peercnt, -1); 02646 } 02647 ao2_iterator_destroy(&i); 02648 02649 if (a->argc == 4) { 02650 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n" 02651 "Non-CallToken Validated Callno Used: %d\n", 02652 global_maxcallno_nonval, 02653 total_nonval_callno_used); 02654 02655 ast_cli(a->fd, "Total Available Callno: %d\n" 02656 "Regular Callno Available: %d\n" 02657 "Trunk Callno Available: %d\n", 02658 ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk), 02659 ao2_container_count(callno_pool), 02660 ao2_container_count(callno_pool_trunk)); 02661 } else if (a->argc == 5 && !found) { 02662 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] ); 02663 } 02664 02665 02666 return CLI_SUCCESS; 02667 default: 02668 return NULL; 02669 } 02670 }
| static char* handle_cli_iax2_show_channels | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7235 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_cli_args::argc, ARRAY_LEN, ast_channel_name(), ast_cli(), ast_inet_ntoa(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, iax2_registry::callno, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, jb_info::current, iax_rr::delay, ast_cli_args::fd, FORMAT, FORMAT2, iax2_getformatname(), iax_frame_subclass2str(), IAX_USEJITTERBUF, jb_getinfo(), jb_info::jitter, MARK_IAX_SUBCLASS_TX, jb_info::min, chan_iax2_pvt::owner, chan_iax2_pvt::remote_rr, S_OR, and ast_cli_entry::usage.
07236 { 07237 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" 07238 #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" 07239 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 07240 int x; 07241 int numchans = 0; 07242 char first_message[10] = { 0, }; 07243 char last_message[10] = { 0, }; 07244 07245 switch (cmd) { 07246 case CLI_INIT: 07247 e->command = "iax2 show channels"; 07248 e->usage = 07249 "Usage: iax2 show channels\n" 07250 " Lists all currently active IAX channels.\n"; 07251 return NULL; 07252 case CLI_GENERATE: 07253 return NULL; 07254 } 07255 07256 if (a->argc != 3) 07257 return CLI_SHOWUSAGE; 07258 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg"); 07259 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07260 ast_mutex_lock(&iaxsl[x]); 07261 if (iaxs[x]) { 07262 int lag, jitter, localdelay; 07263 jb_info jbinfo; 07264 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07265 jb_getinfo(iaxs[x]->jb, &jbinfo); 07266 jitter = jbinfo.jitter; 07267 localdelay = jbinfo.current - jbinfo.min; 07268 } else { 07269 jitter = -1; 07270 localdelay = 0; 07271 } 07272 07273 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 07274 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 07275 lag = iaxs[x]->remote_rr.delay; 07276 ast_cli(a->fd, FORMAT, 07277 iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)", 07278 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 07279 S_OR(iaxs[x]->username, "(None)"), 07280 iaxs[x]->callno, iaxs[x]->peercallno, 07281 iaxs[x]->oseqno, iaxs[x]->iseqno, 07282 lag, 07283 jitter, 07284 localdelay, 07285 iax2_getformatname(iaxs[x]->voiceformat), 07286 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07287 first_message, 07288 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07289 last_message); 07290 numchans++; 07291 } 07292 ast_mutex_unlock(&iaxsl[x]); 07293 } 07294 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 07295 return CLI_SUCCESS; 07296 #undef FORMAT 07297 #undef FORMAT2 07298 #undef FORMATB 07299 }
| static char* handle_cli_iax2_show_firmware | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7021 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, ast_cli_args::fd, iax_firmware::fwh, ast_cli_entry::usage, and ast_iax2_firmware_header::version.
07022 { 07023 struct iax_firmware *cur = NULL; 07024 07025 switch (cmd) { 07026 case CLI_INIT: 07027 e->command = "iax2 show firmware"; 07028 e->usage = 07029 "Usage: iax2 show firmware\n" 07030 " Lists all known IAX firmware images.\n"; 07031 return NULL; 07032 case CLI_GENERATE: 07033 return NULL; 07034 } 07035 07036 if (a->argc != 3 && a->argc != 4) 07037 return CLI_SHOWUSAGE; 07038 07039 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size"); 07040 AST_LIST_LOCK(&firmwares); 07041 AST_LIST_TRAVERSE(&firmwares, cur, list) { 07042 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) { 07043 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname, 07044 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen)); 07045 } 07046 } 07047 AST_LIST_UNLOCK(&firmwares); 07048 07049 return CLI_SUCCESS; 07050 }
| static char* handle_cli_iax2_show_netstats | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7385 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli(), ast_cli_netstats(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
07386 { 07387 int numchans = 0; 07388 07389 switch (cmd) { 07390 case CLI_INIT: 07391 e->command = "iax2 show netstats"; 07392 e->usage = 07393 "Usage: iax2 show netstats\n" 07394 " Lists network status for all currently active IAX channels.\n"; 07395 return NULL; 07396 case CLI_GENERATE: 07397 return NULL; 07398 } 07399 if (a->argc != 3) 07400 return CLI_SHOWUSAGE; 07401 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 07402 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n"); 07403 numchans = ast_cli_netstats(NULL, a->fd, 1); 07404 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 07405 return CLI_SUCCESS; 07406 }
| static char* handle_cli_iax2_show_peer | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show one peer in detail.
Definition at line 3802 of file chan_iax2.c.
References iax2_peer::addr, ast_cli_args::argc, ast_cli_args::argv, ast_callerid_merge(), ast_cli(), ast_codec_pref_index(), AST_CODEC_PREF_SIZE, ast_getformatname(), ast_inet_ntoa(), ast_sockaddr_to_sin, ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag64, CALLTOKEN_AUTO, iax2_peer::calltoken_required, CALLTOKEN_YES, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), iax2_peer::context, iax2_peer::defaddr, iax2_peer::description, iax2_peer::encmethods, encmethods_to_str(), iax2_peer::expire, ast_cli_args::fd, find_peer(), iax2_peer::ha, iax2_getformatname_multiple(), IAX_DYNAMIC, IAX_TRUNK, ast_cli_args::line, iax2_peer::mailbox, iax2_peer::maxcallno, ast_cli_args::n, iax2_peer::name, iax2_peer::parkinglot, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, ast_cli_args::pos, iax2_peer::prefs, iax2_peer::secret, iax2_peer::smoothing, status, ast_cli_entry::usage, iax2_peer::username, and ast_cli_args::word.
03803 { 03804 char status[30]; 03805 char cbuf[256]; 03806 struct iax2_peer *peer; 03807 char codec_buf[512]; 03808 struct ast_str *encmethods = ast_str_alloca(256); 03809 int x = 0, load_realtime = 0; 03810 03811 switch (cmd) { 03812 case CLI_INIT: 03813 e->command = "iax2 show peer"; 03814 e->usage = 03815 "Usage: iax2 show peer <name>\n" 03816 " Display details on specific IAX peer\n"; 03817 return NULL; 03818 case CLI_GENERATE: 03819 if (a->pos == 3) 03820 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 03821 return NULL; 03822 } 03823 03824 if (a->argc < 4) 03825 return CLI_SHOWUSAGE; 03826 03827 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0; 03828 03829 peer = find_peer(a->argv[3], load_realtime); 03830 if (peer) { 03831 struct sockaddr_in peer_addr; 03832 03833 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 03834 03835 encmethods_to_str(peer->encmethods, encmethods); 03836 ast_cli(a->fd, "\n\n"); 03837 ast_cli(a->fd, " * Name : %s\n", peer->name); 03838 ast_cli(a->fd, " Description : %s\n", peer->description); 03839 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>"); 03840 ast_cli(a->fd, " Context : %s\n", peer->context); 03841 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot); 03842 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox); 03843 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 03844 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno); 03845 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No")); 03846 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 03847 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 03848 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 03849 ast_cli(a->fd, " Expire : %d\n", peer->expire); 03850 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No")); 03851 ast_cli(a->fd, " Addr->IP : %s Port %d\n", peer_addr.sin_addr.s_addr ? ast_inet_ntoa(peer_addr.sin_addr) : "(Unspecified)", ntohs(peer_addr.sin_port)); 03852 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 03853 ast_cli(a->fd, " Username : %s\n", peer->username); 03854 ast_cli(a->fd, " Codecs : "); 03855 iax2_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 03856 ast_cli(a->fd, "%s\n", codec_buf); 03857 03858 ast_cli(a->fd, " Codec Order : ("); 03859 for(x = 0; x < AST_CODEC_PREF_SIZE; x++) { 03860 struct ast_format tmpfmt; 03861 if(!(ast_codec_pref_index(&peer->prefs, x, &tmpfmt))) 03862 break; 03863 ast_cli(a->fd, "%s", ast_getformatname(&tmpfmt)); 03864 if(x < 31 && ast_codec_pref_index(&peer->prefs, x+1, &tmpfmt)) 03865 ast_cli(a->fd, "|"); 03866 } 03867 03868 if (!x) 03869 ast_cli(a->fd, "none"); 03870 ast_cli(a->fd, ")\n"); 03871 03872 ast_cli(a->fd, " Status : "); 03873 peer_status(peer, status, sizeof(status)); 03874 ast_cli(a->fd, "%s\n",status); 03875 ast_cli(a->fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 03876 ast_cli(a->fd, "\n"); 03877 peer_unref(peer); 03878 } else { 03879 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]); 03880 ast_cli(a->fd, "\n"); 03881 } 03882 03883 return CLI_SUCCESS; 03884 }
| static char* handle_cli_iax2_show_peers | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6989 of file chan_iax2.c.
References __iax2_show_peers(), ast_cli_args::argc, ast_cli_args::argv, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, RESULT_FAILURE, RESULT_SHOWUSAGE, and ast_cli_entry::usage.
06990 { 06991 switch (cmd) { 06992 case CLI_INIT: 06993 e->command = "iax2 show peers"; 06994 e->usage = 06995 "Usage: iax2 show peers [registered] [like <pattern>]\n" 06996 " Lists all known IAX2 peers.\n" 06997 " Optional 'registered' argument lists only peers with known addresses.\n" 06998 " Optional regular expression pattern is used to filter the peer list.\n"; 06999 return NULL; 07000 case CLI_GENERATE: 07001 return NULL; 07002 } 07003 07004 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) { 07005 case RESULT_SHOWUSAGE: 07006 return CLI_SHOWUSAGE; 07007 case RESULT_FAILURE: 07008 return CLI_FAILURE; 07009 default: 07010 return CLI_SUCCESS; 07011 } 07012 }
| static char* handle_cli_iax2_show_registry | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7144 of file chan_iax2.c.
References iax2_registry::addr, ast_cli_args::argc, ast_cli(), ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sockaddr_stringify(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_registry::dnsmgr, ast_cli_args::fd, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), iax2_registry::us, ast_cli_entry::usage, and iax2_registry::username.
07145 { 07146 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 07147 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 07148 struct iax2_registry *reg = NULL; 07149 char host[80]; 07150 char perceived[80]; 07151 int counter = 0; 07152 07153 switch (cmd) { 07154 case CLI_INIT: 07155 e->command = "iax2 show registry"; 07156 e->usage = 07157 "Usage: iax2 show registry\n" 07158 " Lists all registration requests and status.\n"; 07159 return NULL; 07160 case CLI_GENERATE: 07161 return NULL; 07162 } 07163 if (a->argc != 3) 07164 return CLI_SHOWUSAGE; 07165 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 07166 AST_LIST_LOCK(®istrations); 07167 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07168 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07169 if (reg->us.sin_addr.s_addr) 07170 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07171 else 07172 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07173 ast_cli(a->fd, FORMAT, host, 07174 (reg->dnsmgr) ? "Y" : "N", 07175 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 07176 counter++; 07177 } 07178 AST_LIST_UNLOCK(®istrations); 07179 ast_cli(a->fd, "%d IAX2 registrations.\n", counter); 07180 return CLI_SUCCESS; 07181 #undef FORMAT 07182 #undef FORMAT2 07183 }
| static char* handle_cli_iax2_show_stats | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3909 of file chan_iax2.c.
References ast_cli_args::argc, ARRAY_LEN, ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, iax_frame::final, frame_queue, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iax_frame::retries, and ast_cli_entry::usage.
03910 { 03911 struct iax_frame *cur; 03912 int cnt = 0, dead = 0, final = 0, i = 0; 03913 03914 switch (cmd) { 03915 case CLI_INIT: 03916 e->command = "iax2 show stats"; 03917 e->usage = 03918 "Usage: iax2 show stats\n" 03919 " Display statistics on IAX channel driver.\n"; 03920 return NULL; 03921 case CLI_GENERATE: 03922 return NULL; 03923 } 03924 03925 if (a->argc != 3) 03926 return CLI_SHOWUSAGE; 03927 03928 for (i = 0; i < ARRAY_LEN(frame_queue); i++) { 03929 ast_mutex_lock(&iaxsl[i]); 03930 AST_LIST_TRAVERSE(&frame_queue[i], cur, list) { 03931 if (cur->retries < 0) 03932 dead++; 03933 if (cur->final) 03934 final++; 03935 cnt++; 03936 } 03937 ast_mutex_unlock(&iaxsl[i]); 03938 } 03939 03940 ast_cli(a->fd, " IAX Statistics\n"); 03941 ast_cli(a->fd, "---------------------\n"); 03942 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 03943 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed, 03944 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu); 03945 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 03946 03947 trunk_timed = trunk_untimed = 0; 03948 if (trunk_maxmtu > trunk_nmaxmtu) 03949 trunk_nmaxmtu = trunk_maxmtu; 03950 03951 return CLI_SUCCESS; 03952 }
| static char* handle_cli_iax2_show_threads | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6855 of file chan_iax2.c.
References iax2_thread::actions, ast_cli_args::argc, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax2_thread::checktime, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_thread::curfunc, ast_cli_args::fd, IAX_THREAD_TYPE_DYNAMIC, iaxthreadcount, iax2_thread::iostate, thread, iax2_thread::threadnum, iax2_thread::type, and ast_cli_entry::usage.
06856 { 06857 struct iax2_thread *thread = NULL; 06858 time_t t; 06859 int threadcount = 0, dynamiccount = 0; 06860 char type; 06861 06862 switch (cmd) { 06863 case CLI_INIT: 06864 e->command = "iax2 show threads"; 06865 e->usage = 06866 "Usage: iax2 show threads\n" 06867 " Lists status of IAX helper threads\n"; 06868 return NULL; 06869 case CLI_GENERATE: 06870 return NULL; 06871 } 06872 if (a->argc != 3) 06873 return CLI_SHOWUSAGE; 06874 06875 ast_cli(a->fd, "IAX2 Thread Information\n"); 06876 time(&t); 06877 ast_cli(a->fd, "Idle Threads:\n"); 06878 AST_LIST_LOCK(&idle_list); 06879 AST_LIST_TRAVERSE(&idle_list, thread, list) { 06880 #ifdef DEBUG_SCHED_MULTITHREAD 06881 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06882 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06883 #else 06884 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06885 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06886 #endif 06887 threadcount++; 06888 } 06889 AST_LIST_UNLOCK(&idle_list); 06890 ast_cli(a->fd, "Active Threads:\n"); 06891 AST_LIST_LOCK(&active_list); 06892 AST_LIST_TRAVERSE(&active_list, thread, list) { 06893 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) 06894 type = 'D'; 06895 else 06896 type = 'P'; 06897 #ifdef DEBUG_SCHED_MULTITHREAD 06898 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 06899 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06900 #else 06901 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 06902 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06903 #endif 06904 threadcount++; 06905 } 06906 AST_LIST_UNLOCK(&active_list); 06907 ast_cli(a->fd, "Dynamic Threads:\n"); 06908 AST_LIST_LOCK(&dynamic_list); 06909 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 06910 #ifdef DEBUG_SCHED_MULTITHREAD 06911 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06912 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06913 #else 06914 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06915 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06916 #endif 06917 dynamiccount++; 06918 } 06919 AST_LIST_UNLOCK(&dynamic_list); 06920 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 06921 return CLI_SUCCESS; 06922 }
| static char* handle_cli_iax2_show_users | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6643 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_strlen_zero(), ast_test_flag64, iax2_user::authmethods, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_context::context, iax2_user::contexts, DEFAULT_CONTEXT, ast_cli_args::fd, FORMAT, FORMAT2, iax2_user::ha, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, iax2_user::inkeys, iax2_user::name, iax2_user::secret, ast_cli_entry::usage, and user_unref().
06644 { 06645 regex_t regexbuf; 06646 int havepattern = 0; 06647 06648 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 06649 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 06650 06651 struct iax2_user *user = NULL; 06652 char auth[90]; 06653 char *pstr = ""; 06654 struct ao2_iterator i; 06655 06656 switch (cmd) { 06657 case CLI_INIT: 06658 e->command = "iax2 show users [like]"; 06659 e->usage = 06660 "Usage: iax2 show users [like <pattern>]\n" 06661 " Lists all known IAX2 users.\n" 06662 " Optional regular expression pattern is used to filter the user list.\n"; 06663 return NULL; 06664 case CLI_GENERATE: 06665 return NULL; 06666 } 06667 06668 switch (a->argc) { 06669 case 5: 06670 if (!strcasecmp(a->argv[3], "like")) { 06671 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 06672 return CLI_SHOWUSAGE; 06673 havepattern = 1; 06674 } else 06675 return CLI_SHOWUSAGE; 06676 case 3: 06677 break; 06678 default: 06679 return CLI_SHOWUSAGE; 06680 } 06681 06682 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 06683 i = ao2_iterator_init(users, 0); 06684 for (; (user = ao2_iterator_next(&i)); user_unref(user)) { 06685 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 06686 continue; 06687 06688 if (!ast_strlen_zero(user->secret)) { 06689 ast_copy_string(auth,user->secret, sizeof(auth)); 06690 } else if (!ast_strlen_zero(user->inkeys)) { 06691 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 06692 } else 06693 ast_copy_string(auth, "-no secret-", sizeof(auth)); 06694 06695 if(ast_test_flag64(user, IAX_CODEC_NOCAP)) 06696 pstr = "REQ Only"; 06697 else if(ast_test_flag64(user, IAX_CODEC_NOPREFS)) 06698 pstr = "Disabled"; 06699 else 06700 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 06701 06702 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 06703 user->contexts ? user->contexts->context : DEFAULT_CONTEXT, 06704 user->ha ? "Yes" : "No", pstr); 06705 } 06706 ao2_iterator_destroy(&i); 06707 06708 if (havepattern) 06709 regfree(®exbuf); 06710 06711 return CLI_SUCCESS; 06712 #undef FORMAT 06713 #undef FORMAT2 06714 }
| static char* handle_cli_iax2_test_losspct | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3688 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.
03689 { 03690 switch (cmd) { 03691 case CLI_INIT: 03692 e->command = "iax2 test losspct"; 03693 e->usage = 03694 "Usage: iax2 test losspct <percentage>\n" 03695 " For testing, throws away <percentage> percent of incoming packets\n"; 03696 return NULL; 03697 case CLI_GENERATE: 03698 return NULL; 03699 } 03700 if (a->argc != 4) 03701 return CLI_SHOWUSAGE; 03702 03703 test_losspct = atoi(a->argv[3]); 03704 03705 return CLI_SUCCESS; 03706 }
| static char* handle_cli_iax2_unregister | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6924 of file chan_iax2.c.
References ao2_find, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_unregister(), iax2_peer::expire, expire_registry(), ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, OBJ_KEY, peer_ref(), peer_unref(), ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
06925 { 06926 struct iax2_peer *p; 06927 06928 switch (cmd) { 06929 case CLI_INIT: 06930 e->command = "iax2 unregister"; 06931 e->usage = 06932 "Usage: iax2 unregister <peername>\n" 06933 " Unregister (force expiration) an IAX2 peer from the registry.\n"; 06934 return NULL; 06935 case CLI_GENERATE: 06936 return complete_iax2_unregister(a->line, a->word, a->pos, a->n); 06937 } 06938 06939 if (a->argc != 3) 06940 return CLI_SHOWUSAGE; 06941 06942 p = find_peer(a->argv[2], 1); 06943 if (p) { 06944 if (p->expire > 0) { 06945 struct iax2_peer *peer; 06946 06947 peer = ao2_find(peers, a->argv[2], OBJ_KEY); 06948 if (peer) { 06949 expire_registry(peer_ref(peer)); /* will release its own reference when done */ 06950 peer_unref(peer); /* ref from ao2_find() */ 06951 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]); 06952 } else { 06953 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]); 06954 } 06955 } else { 06956 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 06957 } 06958 } else { 06959 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]); 06960 } 06961 return CLI_SUCCESS; 06962 }
| static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 9606 of file chan_iax2.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock, ast_mutex_unlock, iax2_pkt_buf::buf, iax2_thread::buf, iax2_thread::buf_len, iax2_thread::buf_size, iax2_thread::full_frames, iax2_pkt_buf::len, iax2_thread::lock, and socket_process().
Referenced by iax2_process_thread().
09607 { 09608 struct iax2_pkt_buf *pkt_buf; 09609 09610 ast_mutex_lock(&thread->lock); 09611 09612 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 09613 ast_mutex_unlock(&thread->lock); 09614 09615 thread->buf = pkt_buf->buf; 09616 thread->buf_len = pkt_buf->len; 09617 thread->buf_size = pkt_buf->len + 1; 09618 09619 socket_process(thread); 09620 09621 thread->buf = NULL; 09622 ast_free(pkt_buf); 09623 09624 ast_mutex_lock(&thread->lock); 09625 } 09626 09627 ast_mutex_unlock(&thread->lock); 09628 }
| static int handle_error | ( | void | ) | [static] |
Definition at line 3343 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), errno, LOG_WARNING, and netsocket.
Referenced by send_packet(), socket_read(), and transmit_trunk().
03344 { 03345 /* XXX Ideally we should figure out why an error occurred and then abort those 03346 rather than continuing to try. Unfortunately, the published interface does 03347 not seem to work XXX */ 03348 #if 0 03349 struct sockaddr_in *sin; 03350 int res; 03351 struct msghdr m; 03352 struct sock_extended_err e; 03353 m.msg_name = NULL; 03354 m.msg_namelen = 0; 03355 m.msg_iov = NULL; 03356 m.msg_control = &e; 03357 m.msg_controllen = sizeof(e); 03358 m.msg_flags = 0; 03359 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 03360 if (res < 0) 03361 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 03362 else { 03363 if (m.msg_controllen) { 03364 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 03365 if (sin) 03366 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 03367 else 03368 ast_log(LOG_WARNING, "No address detected??\n"); 03369 } else { 03370 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 03371 } 03372 } 03373 #endif 03374 return 0; 03375 }
| static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
| struct sockaddr_in * | sin, | |||
| int | callno | |||
| ) | [static] |
Acknowledgment received for OUR registration.
Definition at line 8503 of file chan_iax2.c.
References iax2_registry::addr, iax_ies::apparent_addr, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_sockaddr_to_sin, ast_verb, iax_ies::calling_number, EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), iax2_sched_replace(), inaddrcmp(), LOG_WARNING, manager_event, iax2_registry::messages, iax_ies::msgcount, iax2_registry::refresh, iax_ies::refresh, refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, iax2_registry::us, and iax_ies::username.
Referenced by socket_process().
08504 { 08505 struct iax2_registry *reg; 08506 /* Start pessimistic */ 08507 char peer[256] = ""; 08508 char msgstatus[60]; 08509 int refresh = 60; 08510 char ourip[256] = "<Unspecified>"; 08511 struct sockaddr_in oldus; 08512 struct sockaddr_in us; 08513 int oldmsgs; 08514 struct sockaddr_in reg_addr; 08515 08516 memset(&us, 0, sizeof(us)); 08517 if (ies->apparent_addr) { 08518 memmove(&us, ies->apparent_addr, sizeof(us)); 08519 } 08520 if (ies->username) { 08521 ast_copy_string(peer, ies->username, sizeof(peer)); 08522 } 08523 if (ies->refresh) { 08524 refresh = ies->refresh; 08525 } 08526 if (ies->calling_number) { 08527 /* We don't do anything with it really, but maybe we should */ 08528 } 08529 reg = iaxs[callno]->reg; 08530 if (!reg) { 08531 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 08532 return -1; 08533 } 08534 memcpy(&oldus, ®->us, sizeof(oldus)); 08535 oldmsgs = reg->messages; 08536 ast_sockaddr_to_sin(®->addr, ®_addr); 08537 if (inaddrcmp(®_addr, sin)) { 08538 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08539 return -1; 08540 } 08541 memcpy(®->us, &us, sizeof(reg->us)); 08542 if (ies->msgcount >= 0) { 08543 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 08544 } 08545 /* always refresh the registration at the interval requested by the server 08546 we are registering to 08547 */ 08548 reg->refresh = refresh; 08549 reg->expire = iax2_sched_replace(reg->expire, sched, 08550 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08551 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 08552 if (reg->messages > 255) { 08553 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 08554 } else if (reg->messages > 1) { 08555 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages); 08556 } else if (reg->messages > 0) { 08557 ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus)); 08558 } else { 08559 ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus)); 08560 } 08561 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 08562 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 08563 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 08564 } 08565 reg->regstate = REG_STATE_REGISTERED; 08566 return 0; 08567 }
| static int attribute_pure iax2_allow_new | ( | int | frametype, | |
| int | subclass, | |||
| int | inbound | |||
| ) | [inline, static] |
Definition at line 2808 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_FWDOWNL, IAX_COMMAND_NEW, IAX_COMMAND_POKE, IAX_COMMAND_REGREL, and IAX_COMMAND_REGREQ.
Referenced by resend_with_token(), and socket_process().
02809 { 02810 if (frametype != AST_FRAME_IAX) { 02811 return 0; 02812 } 02813 switch (subclass) { 02814 case IAX_COMMAND_NEW: 02815 case IAX_COMMAND_REGREQ: 02816 case IAX_COMMAND_FWDOWNL: 02817 case IAX_COMMAND_REGREL: 02818 return 1; 02819 case IAX_COMMAND_POKE: 02820 if (!inbound) { 02821 return 1; 02822 } 02823 break; 02824 } 02825 return 0; 02826 }
| static void iax2_ami_channelupdate | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Send manager event at call setup to link between Asterisk channel name and IAX2 call identifiers.
Definition at line 1322 of file chan_iax2.c.
References ast_channel_name(), chan_iax2_pvt::callno, EVENT_FLAG_SYSTEM, manager_event, chan_iax2_pvt::owner, chan_iax2_pvt::peer, and chan_iax2_pvt::peercallno.
Referenced by ast_iax2_new(), and iax2_answer().
01323 { 01324 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 01325 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n", 01326 pvt->owner ? ast_channel_name(pvt->owner) : "", 01327 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : ""); 01328 }
| static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5686 of file chan_iax2.c.
References AST_CONTROL_ANSWER, ast_debug, AST_FRAME_CONTROL, ast_mutex_lock, ast_mutex_unlock, iax2_ami_channelupdate(), PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
05687 { 05688 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05689 ast_debug(1, "Answering IAX2 call\n"); 05690 ast_mutex_lock(&iaxsl[callno]); 05691 if (iaxs[callno]) 05692 iax2_ami_channelupdate(iaxs[callno]); 05693 ast_mutex_unlock(&iaxsl[callno]); 05694 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 05695 }
| static int iax2_append_register | ( | const char * | hostname, | |
| const char * | username, | |||
| const char * | secret, | |||
| const char * | porta | |||
| ) | [static] |
Definition at line 8569 of file chan_iax2.c.
References iax2_registry::addr, ast_calloc, ast_copy_string(), ast_dnsmgr_lookup(), ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_sockaddr_set_port, iax2_registry::dnsmgr, iax2_registry::expire, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, iax2_registry::refresh, iax2_registry::secret, ast_sockaddr::ss, and iax2_registry::username.
Referenced by iax2_register().
08571 { 08572 struct iax2_registry *reg; 08573 08574 if (!(reg = ast_calloc(1, sizeof(*reg)))) 08575 return -1; 08576 08577 reg->addr.ss.ss_family = AF_INET; 08578 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) { 08579 ast_free(reg); 08580 return -1; 08581 } 08582 08583 ast_copy_string(reg->username, username, sizeof(reg->username)); 08584 08585 if (secret) 08586 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 08587 08588 reg->expire = -1; 08589 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 08590 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO); 08591 08592 AST_LIST_LOCK(®istrations); 08593 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 08594 AST_LIST_UNLOCK(®istrations); 08595 08596 return 0; 08597 }
| static iax2_format iax2_best_codec | ( | iax2_format | formats | ) | [static] |
Definition at line 1655 of file chan_iax2.c.
References ast_best_codec(), ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_format_cap_from_old_bitfield(), ast_format_clear(), and ast_format_to_old_bitfield().
Referenced by socket_process().
01656 { 01657 struct ast_format_cap *cap = ast_format_cap_alloc_nolock(); 01658 struct ast_format tmpfmt; 01659 if (!cap) { 01660 return 0; 01661 } 01662 01663 ast_format_clear(&tmpfmt); 01664 ast_format_cap_from_old_bitfield(cap, formats); 01665 ast_best_codec(cap, &tmpfmt); 01666 cap = ast_format_cap_destroy(cap); 01667 return ast_format_to_old_bitfield(&tmpfmt); 01668 }
| static enum ast_bridge_result iax2_bridge | ( | struct ast_channel * | c0, | |
| struct ast_channel * | c1, | |||
| int | flags, | |||
| struct ast_frame ** | fo, | |||
| struct ast_channel ** | rc, | |||
| int | timeoutms | |||
| ) | [static] |
Definition at line 5531 of file chan_iax2.c.
References ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_check_hangup(), AST_CONTROL_SRCUPDATE, ast_format_cap_identical(), AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_getformatname_multiple(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_read(), AST_SOFTHANGUP_DEV, ast_test_flag64, ast_tvnow(), ast_tvzero(), ast_verb, ast_waitfor_n(), ast_write(), chan_iax2_pvt::bridgecallno, buf1, f, ast_frame::frametype, iax2_start_transfer(), IAX_LINGER_TIMEOUT, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, ast_frame_subclass::integer, lock_both(), LOG_WARNING, ast_channel::nativeformats, PTR_TO_CALLNO, ast_frame::subclass, ast_channel::tech, ast_channel::tech_pvt, TRANSFER_RELEASED, and unlock_both().
05532 { 05533 struct ast_channel *cs[3]; 05534 struct ast_channel *who, *other; 05535 int to = -1; 05536 int res = -1; 05537 int transferstarted=0; 05538 struct ast_frame *f; 05539 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 05540 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 05541 struct timeval waittimer = {0, 0}; 05542 05543 /* We currently do not support native bridging if a timeoutms value has been provided */ 05544 if (timeoutms > 0) { 05545 return AST_BRIDGE_FAILED; 05546 } 05547 05548 timeoutms = -1; 05549 05550 lock_both(callno0, callno1); 05551 if (!iaxs[callno0] || !iaxs[callno1]) { 05552 unlock_both(callno0, callno1); 05553 return AST_BRIDGE_FAILED; 05554 } 05555 /* Put them in native bridge mode */ 05556 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 05557 iaxs[callno0]->bridgecallno = callno1; 05558 iaxs[callno1]->bridgecallno = callno0; 05559 } 05560 unlock_both(callno0, callno1); 05561 05562 /* If not, try to bridge until we can execute a transfer, if we can */ 05563 cs[0] = c0; 05564 cs[1] = c1; 05565 for (/* ever */;;) { 05566 /* Check in case we got masqueraded into */ 05567 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 05568 ast_verb(3, "Can't masquerade, we're different...\n"); 05569 /* Remove from native mode */ 05570 if (c0->tech == &iax2_tech) { 05571 ast_mutex_lock(&iaxsl[callno0]); 05572 iaxs[callno0]->bridgecallno = 0; 05573 ast_mutex_unlock(&iaxsl[callno0]); 05574 } 05575 if (c1->tech == &iax2_tech) { 05576 ast_mutex_lock(&iaxsl[callno1]); 05577 iaxs[callno1]->bridgecallno = 0; 05578 ast_mutex_unlock(&iaxsl[callno1]); 05579 } 05580 return AST_BRIDGE_FAILED_NOWARN; 05581 } 05582 if (!(ast_format_cap_identical(c0->nativeformats, c1->nativeformats))) { 05583 char buf0[256]; 05584 char buf1[256]; 05585 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats); 05586 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats); 05587 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1); 05588 /* Remove from native mode */ 05589 lock_both(callno0, callno1); 05590 if (iaxs[callno0]) 05591 iaxs[callno0]->bridgecallno = 0; 05592 if (iaxs[callno1]) 05593 iaxs[callno1]->bridgecallno = 0; 05594 unlock_both(callno0, callno1); 05595 return AST_BRIDGE_FAILED_NOWARN; 05596 } 05597 /* check if transfered and if we really want native bridging */ 05598 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) { 05599 /* Try the transfer */ 05600 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 05601 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA))) 05602 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 05603 transferstarted = 1; 05604 } 05605 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 05606 /* Call has been transferred. We're no longer involved */ 05607 struct timeval now = ast_tvnow(); 05608 if (ast_tvzero(waittimer)) { 05609 waittimer = now; 05610 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 05611 c0->_softhangup |= AST_SOFTHANGUP_DEV; 05612 c1->_softhangup |= AST_SOFTHANGUP_DEV; 05613 *fo = NULL; 05614 *rc = c0; 05615 res = AST_BRIDGE_COMPLETE; 05616 break; 05617 } 05618 } 05619 to = 1000; 05620 who = ast_waitfor_n(cs, 2, &to); 05621 if (timeoutms > -1) { 05622 timeoutms -= (1000 - to); 05623 if (timeoutms < 0) 05624 timeoutms = 0; 05625 } 05626 if (!who) { 05627 if (!timeoutms) { 05628 res = AST_BRIDGE_RETRY; 05629 break; 05630 } 05631 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 05632 res = AST_BRIDGE_FAILED; 05633 break; 05634 } 05635 continue; 05636 } 05637 f = ast_read(who); 05638 if (!f) { 05639 *fo = NULL; 05640 *rc = who; 05641 res = AST_BRIDGE_COMPLETE; 05642 break; 05643 } 05644 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass.integer != AST_CONTROL_SRCUPDATE)) { 05645 *fo = f; 05646 *rc = who; 05647 res = AST_BRIDGE_COMPLETE; 05648 break; 05649 } 05650 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 05651 if ((f->frametype == AST_FRAME_VOICE) || 05652 (f->frametype == AST_FRAME_TEXT) || 05653 (f->frametype == AST_FRAME_VIDEO) || 05654 (f->frametype == AST_FRAME_IMAGE) || 05655 (f->frametype == AST_FRAME_DTMF) || 05656 (f->frametype == AST_FRAME_CONTROL)) { 05657 /* monitored dtmf take out of the bridge. 05658 * check if we monitor the specific source. 05659 */ 05660 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 05661 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 05662 *rc = who; 05663 *fo = f; 05664 res = AST_BRIDGE_COMPLETE; 05665 /* Remove from native mode */ 05666 break; 05667 } 05668 /* everything else goes to the other side */ 05669 ast_write(other, f); 05670 } 05671 ast_frfree(f); 05672 /* Swap who gets priority */ 05673 cs[2] = cs[0]; 05674 cs[0] = cs[1]; 05675 cs[1] = cs[2]; 05676 } 05677 lock_both(callno0, callno1); 05678 if(iaxs[callno0]) 05679 iaxs[callno0]->bridgecallno = 0; 05680 if(iaxs[callno1]) 05681 iaxs[callno1]->bridgecallno = 0; 05682 unlock_both(callno0, callno1); 05683 return res; 05684 }
| static int iax2_call | ( | struct ast_channel * | c, | |
| const char * | dest, | |||
| int | timeout | |||
| ) | [static] |
Definition at line 5077 of file chan_iax2.c.
References ast_channel::_state, add_empty_calltoken_ie(), create_addr_info::adsi, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_party_connected_line::ani, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, ast_channel_datastore_find(), ast_channel_language(), ast_channel_name(), ast_copy_string(), ast_debug, ast_format_cap_to_old_bitfield(), AST_FRAME_IAX, AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_party_id_presentation(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_var_name(), ast_var_value(), auto_congest(), iax_ie_data::buf, CALLNO_TO_PTR, ast_channel::connected, context, create_addr_info::context, ast_channel::context, parsed_dial_string::context, create_addr(), ast_datastore::data, ast_channel::dialed, chan_iax2_pvt::encmethods, create_addr_info::encmethods, parsed_dial_string::exten, ast_party_redirecting::from, ast_channel::hangupcause, iax2_datetime(), iax2_sched_add(), IAX_COMMAND_NEW, IAX_FORCE_ENCRYPT, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_raw(), iax_ie_append_short(), iax_ie_append_str(), iax_ie_append_versioned_uint64(), IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CAPABILITY, IAX_IE_CAPABILITY2, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_FORMAT2, IAX_IE_LANGUAGE, IAX_IE_OSPTOKEN, IAX_IE_RDNIS, IAX_IE_USERNAME, IAX_IE_VARIABLE, IAX_IE_VERSION, IAX_MAX_OSPBLOCK_SIZE, IAX_MAX_OSPTOKEN_SIZE, IAX_PROTO_VERSION, IAX_SENDANI, ast_party_connected_line::id, chan_iax2_pvt::initid, parsed_dial_string::key, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_party_id::name, ast_channel::nativeformats, ast_party_dialed::number, ast_party_id::number, parsed_dial_string::options, create_addr_info::outkey, parse_dial_string(), parsed_dial_string::password, pbx_builtin_getvar_helper(), parsed_dial_string::peer, create_addr_info::peercontext, chan_iax2_pvt::pingtime, ast_party_number::plan, parsed_dial_string::port, iax_ie_data::pos, create_addr_info::prefs, PTR_TO_CALLNO, ast_channel::redirecting, secret, create_addr_info::secret, send_command(), create_addr_info::sockfd, chan_iax2_pvt::sockfd, ast_party_dialed::str, ast_party_name::str, ast_party_number::str, ast_channel::tech_pvt, create_addr_info::timezone, ast_party_dialed::transit_network_select, create_addr_info::username, parsed_dial_string::username, ast_party_name::valid, ast_party_number::valid, and var.
05078 { 05079 struct sockaddr_in sin; 05080 char *l=NULL, *n=NULL, *tmpstr; 05081 struct iax_ie_data ied; 05082 char *defaultrdest = "s"; 05083 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05084 struct parsed_dial_string pds; 05085 struct create_addr_info cai; 05086 struct ast_var_t *var; 05087 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL); 05088 const char* osp_token_ptr; 05089 unsigned int osp_token_length; 05090 unsigned char osp_block_index; 05091 unsigned int osp_block_length; 05092 unsigned char osp_buffer[256]; 05093 iax2_format iax2_tmpfmt; 05094 05095 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 05096 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", ast_channel_name(c)); 05097 return -1; 05098 } 05099 05100 memset(&cai, 0, sizeof(cai)); 05101 cai.encmethods = iax2_encryption; 05102 05103 memset(&pds, 0, sizeof(pds)); 05104 tmpstr = ast_strdupa(dest); 05105 parse_dial_string(tmpstr, &pds); 05106 05107 if (ast_strlen_zero(pds.peer)) { 05108 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 05109 return -1; 05110 } 05111 if (!pds.exten) { 05112 pds.exten = defaultrdest; 05113 } 05114 if (create_addr(pds.peer, c, &sin, &cai)) { 05115 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 05116 return -1; 05117 } 05118 if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) { 05119 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n"); 05120 c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05121 return -1; 05122 } 05123 if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 05124 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n"); 05125 return -1; 05126 } 05127 if (!pds.username && !ast_strlen_zero(cai.username)) 05128 pds.username = cai.username; 05129 if (!pds.password && !ast_strlen_zero(cai.secret)) 05130 pds.password = cai.secret; 05131 if (!pds.key && !ast_strlen_zero(cai.outkey)) 05132 pds.key = cai.outkey; 05133 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 05134 pds.context = cai.peercontext; 05135 05136 /* Keep track of the context for outgoing calls too */ 05137 ast_copy_string(c->context, cai.context, sizeof(c->context)); 05138 05139 if (pds.port) 05140 sin.sin_port = htons(atoi(pds.port)); 05141 05142 l = c->connected.id.number.valid ? c->connected.id.number.str : NULL; 05143 n = c->connected.id.name.valid ? c->connected.id.name.str : NULL; 05144 05145 /* Now build request */ 05146 memset(&ied, 0, sizeof(ied)); 05147 05148 /* On new call, first IE MUST be IAX version of caller */ 05149 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 05150 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 05151 if (pds.options && strchr(pds.options, 'a')) { 05152 /* Request auto answer */ 05153 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 05154 } 05155 05156 /* WARNING: this breaks down at 190 bits! */ 05157 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 05158 05159 if (l) { 05160 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 05161 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05162 ast_party_id_presentation(&c->connected.id)); 05163 } else if (n) { 05164 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05165 ast_party_id_presentation(&c->connected.id)); 05166 } else { 05167 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 05168 } 05169 05170 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan); 05171 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select); 05172 05173 if (n) 05174 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 05175 if (ast_test_flag64(iaxs[callno], IAX_SENDANI) 05176 && c->connected.ani.number.valid 05177 && c->connected.ani.number.str) { 05178 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str); 05179 } 05180 05181 if (!ast_strlen_zero(ast_channel_language(c))) 05182 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, ast_channel_language(c)); 05183 if (!ast_strlen_zero(c->dialed.number.str)) { 05184 iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str); 05185 } 05186 if (c->redirecting.from.number.valid 05187 && !ast_strlen_zero(c->redirecting.from.number.str)) { 05188 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str); 05189 } 05190 05191 if (pds.context) 05192 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 05193 05194 if (pds.username) 05195 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 05196 05197 if (cai.encmethods) 05198 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 05199 05200 ast_mutex_lock(&iaxsl[callno]); 05201 05202 if (!ast_strlen_zero(c->context)) 05203 ast_string_field_set(iaxs[callno], context, c->context); 05204 05205 if (pds.username) 05206 ast_string_field_set(iaxs[callno], username, pds.username); 05207 05208 iaxs[callno]->encmethods = cai.encmethods; 05209 05210 iaxs[callno]->adsi = cai.adsi; 05211 05212 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 05213 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 05214 05215 if (pds.key) 05216 ast_string_field_set(iaxs[callno], outkey, pds.key); 05217 if (pds.password) 05218 ast_string_field_set(iaxs[callno], secret, pds.password); 05219 05220 iax2_tmpfmt = ast_format_cap_to_old_bitfield(c->nativeformats); 05221 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) iax2_tmpfmt); 05222 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, iax2_tmpfmt); 05223 05224 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability); 05225 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability); 05226 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 05227 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 05228 05229 if (iaxs[callno]->maxtime) { 05230 /* Initialize pingtime and auto-congest time */ 05231 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 05232 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 05233 } else if (autokill) { 05234 iaxs[callno]->pingtime = autokill / 2; 05235 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 05236 } 05237 05238 /* Check if there is an OSP token */ 05239 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN"); 05240 if (!ast_strlen_zero(osp_token_ptr)) { 05241 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) { 05242 osp_block_index = 0; 05243 while (osp_token_length > 0) { 05244 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length; 05245 osp_buffer[0] = osp_block_index; 05246 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length); 05247 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1); 05248 osp_block_index++; 05249 osp_token_ptr += osp_block_length; 05250 osp_token_length -= osp_block_length; 05251 } 05252 } else 05253 ast_log(LOG_WARNING, "OSP token is too long\n"); 05254 } else if (iaxdebug) 05255 ast_debug(1, "OSP token is undefined\n"); 05256 05257 /* send the command using the appropriate socket for this peer */ 05258 iaxs[callno]->sockfd = cai.sockfd; 05259 05260 /* Add remote vars */ 05261 if (variablestore) { 05262 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data; 05263 ast_debug(1, "Found an IAX variable store on this channel\n"); 05264 AST_LIST_LOCK(variablelist); 05265 AST_LIST_TRAVERSE(variablelist, var, entries) { 05266 char tmp[256]; 05267 int i; 05268 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var)); 05269 /* Automatically divide the value up into sized chunks */ 05270 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) { 05271 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i); 05272 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp); 05273 } 05274 } 05275 AST_LIST_UNLOCK(variablelist); 05276 } 05277 05278 /* Transmit the string in a "NEW" request */ 05279 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 05280 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 05281 05282 ast_mutex_unlock(&iaxsl[callno]); 05283 ast_setstate(c, AST_STATE_RINGING); 05284 05285 return 0; 05286 }
| static int iax2_canmatch | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority, | |||
| const char * | callerid, | |||
| const char * | data | |||
| ) | [static] |
part of the IAX2 dial plan switch interface
Definition at line 13854 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_CANEXIST, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
13855 { 13856 int res = 0; 13857 struct iax2_dpcache *dp = NULL; 13858 #if 0 13859 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13860 #endif 13861 if ((priority != 1) && (priority != 2)) 13862 return 0; 13863 13864 AST_LIST_LOCK(&dpcache); 13865 if ((dp = find_cache(chan, data, context, exten, priority))) { 13866 if (dp->flags & CACHE_FLAG_CANEXIST) 13867 res = 1; 13868 } else { 13869 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13870 } 13871 AST_LIST_UNLOCK(&dpcache); 13872 13873 return res; 13874 }
| static iax2_format iax2_codec_choose | ( | struct ast_codec_pref * | pref, | |
| iax2_format | formats, | |||
| int | find_best | |||
| ) | [static] |
Definition at line 1639 of file chan_iax2.c.
References ast_codec_choose(), ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_format_cap_from_old_bitfield(), ast_format_clear(), ast_format_to_old_bitfield(), and format.
Referenced by socket_process().
01640 { 01641 struct ast_format_cap *cap; 01642 struct ast_format tmpfmt; 01643 iax2_format format = 0; 01644 if ((cap = ast_format_cap_alloc_nolock())) { 01645 ast_format_clear(&tmpfmt); 01646 ast_format_cap_from_old_bitfield(cap, formats); 01647 ast_codec_choose(pref, cap, find_best, &tmpfmt); 01648 format = ast_format_to_old_bitfield(&tmpfmt); 01649 cap = ast_format_cap_destroy(cap); 01650 } 01651 01652 return format; 01653 }
| static int iax2_data_add_codecs | ( | struct ast_data * | root, | |
| const char * | node_name, | |||
| iax2_format | formats | |||
| ) | [static] |
Definition at line 1710 of file chan_iax2.c.
References ast_data_add_codecs(), ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), and ast_format_cap_from_old_bitfield().
Referenced by peers_data_provider_get(), and users_data_provider_get().
01711 { 01712 int res; 01713 struct ast_format_cap *cap = ast_format_cap_alloc_nolock(); 01714 if (!cap) { 01715 return -1; 01716 } 01717 ast_format_cap_from_old_bitfield(cap, formats); 01718 res = ast_data_add_codecs(root, node_name, cap); 01719 cap = ast_format_cap_destroy(cap); 01720 return res; 01721 }
| static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 4750 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), ast_tvnow(), ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, and ast_tm::tm_year.
Referenced by iax2_call(), and update_registry().
04751 { 04752 struct timeval t = ast_tvnow(); 04753 struct ast_tm tm; 04754 unsigned int tmp; 04755 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz); 04756 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 04757 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 04758 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 04759 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 04760 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 04761 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 04762 return tmp; 04763 }
| static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 3449 of file chan_iax2.c.
References ao2_ref, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_queue_hangup(), DEADLOCK_AVOIDANCE, iax2_destroy_helper(), chan_iax2_pvt::owner, chan_iax2_pvt::peercallno, remove_by_peercallno(), remove_by_transfercallno(), chan_iax2_pvt::transfercallno, and update_max_trunk().
Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __unload_module(), delete_users(), iax2_do_register(), iax2_hangup(), iax2_poke_peer(), peer_destructor(), scheduled_destroy(), and socket_process().
03450 { 03451 struct chan_iax2_pvt *pvt = NULL; 03452 struct ast_channel *owner = NULL; 03453 03454 retry: 03455 if ((pvt = iaxs[callno])) { 03456 #if 0 03457 /* iax2_destroy_helper gets called from this function later on. When 03458 * called twice, we get the (previously) familiar FRACK! errors in 03459 * devmode, from the scheduler. An alternative to this approach is to 03460 * reset the scheduler entries to -1 when they're deleted in 03461 * iax2_destroy_helper(). That approach was previously decided to be 03462 * "wrong" because "the memory is going to be deallocated anyway. Why 03463 * should we be resetting those values?" */ 03464 iax2_destroy_helper(pvt); 03465 #endif 03466 } 03467 03468 owner = pvt ? pvt->owner : NULL; 03469 03470 if (owner) { 03471 if (ast_channel_trylock(owner)) { 03472 ast_debug(3, "Avoiding IAX destroy deadlock\n"); 03473 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03474 goto retry; 03475 } 03476 } 03477 03478 if (!owner) { 03479 iaxs[callno] = NULL; 03480 } 03481 03482 if (pvt) { 03483 if (!owner) { 03484 pvt->owner = NULL; 03485 } else { 03486 /* If there's an owner, prod it to give up */ 03487 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 03488 * because we already hold the owner channel lock. */ 03489 ast_queue_hangup(owner); 03490 } 03491 03492 if (pvt->peercallno) { 03493 remove_by_peercallno(pvt); 03494 } 03495 03496 if (pvt->transfercallno) { 03497 remove_by_transfercallno(pvt); 03498 } 03499 03500 if (!owner) { 03501 ao2_ref(pvt, -1); 03502 pvt = NULL; 03503 } 03504 } 03505 03506 if (owner) { 03507 ast_channel_unlock(owner); 03508 } 03509 03510 if (callno & 0x4000) { 03511 update_max_trunk(); 03512 } 03513 }
| static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1851 of file chan_iax2.c.
References ao2_find, ast_atomic_fetchadd_int(), ast_clear_flag64, AST_SCHED_DEL, AST_SCHED_DEL_SPINLOCK, ast_test_flag64, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::callno, iax2_user::curauthreq, DONT_RESCHEDULE, IAX_MAXAUTHREQ, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::lagid, OBJ_KEY, chan_iax2_pvt::pingid, user_unref(), and chan_iax2_pvt::username.
Referenced by iax2_destroy(), iax2_predestroy(), pvt_destructor(), and stop_stuff().
01852 { 01853 /* Decrement AUTHREQ count if needed */ 01854 if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) { 01855 struct iax2_user *user; 01856 01857 user = ao2_find(users, pvt->username, OBJ_KEY); 01858 if (user) { 01859 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01860 user_unref(user); 01861 } 01862 01863 ast_clear_flag64(pvt, IAX_MAXAUTHREQ); 01864 } 01865 /* No more pings or lagrq's */ 01866 AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]); 01867 pvt->pingid = DONT_RESCHEDULE; 01868 AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]); 01869 pvt->lagid = DONT_RESCHEDULE; 01870 AST_SCHED_DEL(sched, pvt->autoid); 01871 AST_SCHED_DEL(sched, pvt->authid); 01872 AST_SCHED_DEL(sched, pvt->initid); 01873 AST_SCHED_DEL(sched, pvt->jbid); 01874 AST_SCHED_DEL(sched, pvt->keyrotateid); 01875 }
| static int iax2_devicestate | ( | const char * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 14058 of file chan_iax2.c.
References iax2_peer::addr, ast_debug, AST_DEVICE_INVALID, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_log(), ast_sockaddr_ipv4(), ast_strdupa, ast_strlen_zero(), iax2_peer::defaddr, find_peer(), iax2_peer::historicms, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, parse_dial_string(), parsed_dial_string::peer, and peer_unref().
14059 { 14060 struct parsed_dial_string pds; 14061 char *tmp = ast_strdupa(data); 14062 struct iax2_peer *p; 14063 int res = AST_DEVICE_INVALID; 14064 14065 memset(&pds, 0, sizeof(pds)); 14066 parse_dial_string(tmp, &pds); 14067 14068 if (ast_strlen_zero(pds.peer)) { 14069 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 14070 return res; 14071 } 14072 14073 ast_debug(3, "Checking device state for device %s\n", pds.peer); 14074 14075 /* SLD: FIXME: second call to find_peer during registration */ 14076 if (!(p = find_peer(pds.peer, 1))) 14077 return res; 14078 14079 res = AST_DEVICE_UNAVAILABLE; 14080 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 14081 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 14082 14083 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) && 14084 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 14085 /* Peer is registered, or have default IP address 14086 and a valid registration */ 14087 if (p->historicms == 0 || p->historicms <= p->maxms) 14088 /* let the core figure out whether it is in use or not */ 14089 res = AST_DEVICE_UNKNOWN; 14090 } 14091 14092 peer_unref(p); 14093 14094 return res; 14095 }
| static int iax2_digit_begin | ( | struct ast_channel * | c, | |
| char | digit | |||
| ) | [static] |
Definition at line 4342 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04343 { 04344 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 04345 }
| static int iax2_digit_end | ( | struct ast_channel * | c, | |
| char | digit, | |||
| unsigned int | duration | |||
| ) | [static] |
Definition at line 4347 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04348 { 04349 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 04350 }
| static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 11866 of file chan_iax2.c.
References add_empty_calltoken_ie(), iax2_registry::addr, ast_debug, ast_dnsmgr_changed(), ast_dnsmgr_refresh(), AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_ipv4(), ast_sockaddr_to_sin, iax_ie_data::buf, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno_locked(), iax2_destroy(), iax2_do_register_s(), iax2_sched_replace(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, LOG_WARNING, NEW_FORCE, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, send_command(), and iax2_registry::username.
Referenced by __iax2_do_register_s(), load_module(), network_change_event_sched_cb(), and reload_config().
11867 { 11868 struct iax_ie_data ied; 11869 if (iaxdebug) 11870 ast_debug(1, "Sending registration request for '%s'\n", reg->username); 11871 11872 if (reg->dnsmgr && 11873 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) { 11874 /* Maybe the IP has changed, force DNS refresh */ 11875 ast_dnsmgr_refresh(reg->dnsmgr); 11876 } 11877 11878 /* 11879 * if IP has Changed, free allocated call to create a new one with new IP 11880 * call has the pointer to IP and must be updated to the new one 11881 */ 11882 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 11883 int callno = reg->callno; 11884 ast_mutex_lock(&iaxsl[callno]); 11885 iax2_destroy(callno); 11886 ast_mutex_unlock(&iaxsl[callno]); 11887 reg->callno = 0; 11888 } 11889 if (!ast_sockaddr_ipv4(®->addr)) { 11890 if (iaxdebug) 11891 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username); 11892 /* Setup the next registration attempt */ 11893 reg->expire = iax2_sched_replace(reg->expire, sched, 11894 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11895 return -1; 11896 } 11897 11898 if (!reg->callno) { 11899 struct sockaddr_in reg_addr; 11900 11901 ast_debug(3, "Allocate call number\n"); 11902 11903 ast_sockaddr_to_sin(®->addr, ®_addr); 11904 11905 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0); 11906 if (reg->callno < 1) { 11907 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 11908 return -1; 11909 } else 11910 ast_debug(3, "Registration created on call %d\n", reg->callno); 11911 iaxs[reg->callno]->reg = reg; 11912 ast_mutex_unlock(&iaxsl[reg->callno]); 11913 } 11914 /* Setup the next registration a little early */ 11915 reg->expire = iax2_sched_replace(reg->expire, sched, 11916 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11917 /* Send the request */ 11918 memset(&ied, 0, sizeof(ied)); 11919 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 11920 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 11921 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */ 11922 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 11923 reg->regstate = REG_STATE_REGSENT; 11924 return 0; 11925 }
| static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8350 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
08351 { 08352 #ifdef SCHED_MULTITHREADED 08353 if (schedule_action(__iax2_do_register_s, data)) 08354 #endif 08355 __iax2_do_register_s(data); 08356 return 0; 08357 }
| static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
| int | callno | |||
| ) | [static] |
Definition at line 9125 of file chan_iax2.c.
References AST_FRAME_IAX, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, iax2_sched_replace(), IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iax_ie_data::pos, and send_command().
Referenced by find_cache(), and socket_process().
09126 { 09127 struct iax_ie_data ied; 09128 /* Auto-hangup with 30 seconds of inactivity */ 09129 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 09130 sched, 30000, auto_hangup, (void *)(long)callno); 09131 memset(&ied, 0, sizeof(ied)); 09132 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 09133 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 09134 dp->flags |= CACHE_FLAG_TRANSMITTED; 09135 }
| static void * iax2_dup_variable_datastore | ( | void * | old | ) | [static] |
Definition at line 1336 of file chan_iax2.c.
References ast_calloc, AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_var_assign(), ast_var_name(), ast_var_value(), ast_var_t::entries, and LOG_ERROR.
01337 { 01338 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist; 01339 struct ast_var_t *oldvar, *newvar; 01340 01341 newlist = ast_calloc(sizeof(*newlist), 1); 01342 if (!newlist) { 01343 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n"); 01344 return NULL; 01345 } 01346 01347 AST_LIST_HEAD_INIT(newlist); 01348 AST_LIST_LOCK(oldlist); 01349 AST_LIST_TRAVERSE(oldlist, oldvar, entries) { 01350 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar)); 01351 if (newvar) 01352 AST_LIST_INSERT_TAIL(newlist, newvar, entries); 01353 else 01354 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar)); 01355 } 01356 AST_LIST_UNLOCK(oldlist); 01357 return newlist; 01358 }
| static int iax2_exec | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority, | |||
| const char * | callerid, | |||
| const char * | data | |||
| ) | [static] |
Execute IAX2 dialplan switch.
Definition at line 13900 of file chan_iax2.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_verb, CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_exec(), and pbx_findapp().
13901 { 13902 char odata[256]; 13903 char req[256]; 13904 char *ncontext; 13905 struct iax2_dpcache *dp = NULL; 13906 struct ast_app *dial = NULL; 13907 #if 0 13908 ast_log(LOG_NOTICE, "iax2_exec: con: %s, exten: %s, pri: %d, cid: %s, data: %s, newstack: %d\n", context, exten, priority, callerid ? callerid : "<unknown>", data, newstack); 13909 #endif 13910 if (priority == 2) { 13911 /* Indicate status, can be overridden in dialplan */ 13912 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 13913 if (dialstatus) { 13914 dial = pbx_findapp(dialstatus); 13915 if (dial) 13916 pbx_exec(chan, dial, ""); 13917 } 13918 return -1; 13919 } else if (priority != 1) 13920 return -1; 13921 13922 AST_LIST_LOCK(&dpcache); 13923 if ((dp = find_cache(chan, data, context, exten, priority))) { 13924 if (dp->flags & CACHE_FLAG_EXISTS) { 13925 ast_copy_string(odata, data, sizeof(odata)); 13926 ncontext = strchr(odata, '/'); 13927 if (ncontext) { 13928 *ncontext = '\0'; 13929 ncontext++; 13930 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 13931 } else { 13932 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 13933 } 13934 ast_verb(3, "Executing Dial('%s')\n", req); 13935 } else { 13936 AST_LIST_UNLOCK(&dpcache); 13937 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 13938 return -1; 13939 } 13940 } 13941 AST_LIST_UNLOCK(&dpcache); 13942 13943 if ((dial = pbx_findapp("Dial"))) 13944 return pbx_exec(chan, dial, req); 13945 else 13946 ast_log(LOG_WARNING, "No dial application registered\n"); 13947 13948 return -1; 13949 }
| static int iax2_exists | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority, | |||
| const char * | callerid, | |||
| const char * | data | |||
| ) | [static] |
Part of the IAX2 switch interface.
Definition at line 13831 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
13832 { 13833 int res = 0; 13834 struct iax2_dpcache *dp = NULL; 13835 #if 0 13836 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13837 #endif 13838 if ((priority != 1) && (priority != 2)) 13839 return 0; 13840 13841 AST_LIST_LOCK(&dpcache); 13842 if ((dp = find_cache(chan, data, context, exten, priority))) { 13843 if (dp->flags & CACHE_FLAG_EXISTS) 13844 res = 1; 13845 } else { 13846 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13847 } 13848 AST_LIST_UNLOCK(&dpcache); 13849 13850 return res; 13851 }
| static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
| struct ast_channel * | newchan | |||
| ) | [static] |
Definition at line 4369 of file chan_iax2.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, iax_frame::callno, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt.
04370 { 04371 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 04372 ast_mutex_lock(&iaxsl[callno]); 04373 if (iaxs[callno]) 04374 iaxs[callno]->owner = newchan; 04375 else 04376 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 04377 ast_mutex_unlock(&iaxsl[callno]); 04378 return 0; 04379 }
| static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1877 of file chan_iax2.c.
References AST_SCHED_DEL, iax_frame_free(), and iax_frame::retrans.
Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), pvt_destructor(), resend_with_token(), and schedule_delivery().
01878 { 01879 AST_SCHED_DEL(sched, fr->retrans); 01880 iax_frame_free(fr); 01881 }
| static void iax2_free_variable_datastore | ( | void * | old | ) | [static] |
Definition at line 1360 of file chan_iax2.c.
References ast_free, AST_LIST_HEAD, AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and ast_var_t::entries.
01361 { 01362 AST_LIST_HEAD(, ast_var_t) *oldlist = old; 01363 struct ast_var_t *oldvar; 01364 01365 AST_LIST_LOCK(oldlist); 01366 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) { 01367 ast_free(oldvar); 01368 } 01369 AST_LIST_UNLOCK(oldlist); 01370 AST_LIST_HEAD_DESTROY(oldlist); 01371 ast_free(oldlist); 01372 }
| const char* iax2_getformatname | ( | iax2_format | format | ) |
iax2 wrapper function for ast_getformatname
Definition at line 1670 of file chan_iax2.c.
References ast_format_from_old_bitfield(), and ast_getformatname().
Referenced by dump_versioned_codec(), handle_cli_iax2_show_channels(), iax_show_provisioning(), and socket_process().
01671 { 01672 struct ast_format tmpfmt; 01673 if (!(ast_format_from_old_bitfield(&tmpfmt, format))) { 01674 return "Unknown"; 01675 } 01676 01677 return ast_getformatname(&tmpfmt); 01678 }
| static char* iax2_getformatname_multiple | ( | char * | codec_buf, | |
| size_t | len, | |||
| iax2_format | format | |||
| ) | [static] |
Definition at line 1680 of file chan_iax2.c.
References ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_format_cap_from_old_bitfield(), and ast_getformatname_multiple().
Referenced by function_iaxpeer(), handle_cli_iax2_show_peer(), and socket_process().
01681 { 01682 struct ast_format_cap *cap = ast_format_cap_alloc_nolock(); 01683 01684 if (!cap) { 01685 return "(Nothing)"; 01686 } 01687 ast_format_cap_from_old_bitfield(cap, format); 01688 ast_getformatname_multiple(codec_buf, len, cap); 01689 cap = ast_format_cap_destroy(cap); 01690 01691 return codec_buf; 01692 }
| static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
| char * | host, | |||
| int | len | |||
| ) | [static] |
Definition at line 1814 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_copy_string(), ast_sockaddr_to_sin, iax2_peer::name, peer_unref(), and realtime_peer().
Referenced by __find_callno().
01815 { 01816 struct iax2_peer *peer = NULL; 01817 int res = 0; 01818 struct ao2_iterator i; 01819 01820 i = ao2_iterator_init(peers, 0); 01821 while ((peer = ao2_iterator_next(&i))) { 01822 struct sockaddr_in peer_addr; 01823 01824 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 01825 01826 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01827 (peer_addr.sin_port == sin.sin_port)) { 01828 ast_copy_string(host, peer->name, len); 01829 peer_unref(peer); 01830 res = 1; 01831 break; 01832 } 01833 peer_unref(peer); 01834 } 01835 ao2_iterator_destroy(&i); 01836 01837 if (!peer) { 01838 peer = realtime_peer(NULL, &sin); 01839 if (peer) { 01840 ast_copy_string(host, peer->name, len); 01841 peer_unref(peer); 01842 res = 1; 01843 } 01844 } 01845 01846 return res; 01847 }
| static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 5761 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_sockaddr_to_sin, ast_test_flag64, IAX_TRUNK, and peer_unref().
Referenced by check_access().
05762 { 05763 struct iax2_peer *peer; 05764 int res = 0; 05765 struct ao2_iterator i; 05766 05767 i = ao2_iterator_init(peers, 0); 05768 while ((peer = ao2_iterator_next(&i))) { 05769 struct sockaddr_in peer_addr; 05770 05771 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 05772 05773 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 05774 (peer_addr.sin_port == sin.sin_port)) { 05775 res = ast_test_flag64(peer, IAX_TRUNK); 05776 peer_unref(peer); 05777 break; 05778 } 05779 peer_unref(peer); 05780 } 05781 ao2_iterator_destroy(&i); 05782 05783 return res; 05784 }
| static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5288 of file chan_iax2.c.
References ast_channel_name(), ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_add(), ast_test_flag64, ast_verb, iax_ie_data::buf, CALLNO_TO_PTR, ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, LOG_ERROR, LOG_WARNING, iax_ie_data::pos, PTR_TO_CALLNO, scheduled_destroy(), send_command_final(), and ast_channel::tech_pvt.
05289 { 05290 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05291 struct iax_ie_data ied; 05292 int alreadygone; 05293 memset(&ied, 0, sizeof(ied)); 05294 ast_mutex_lock(&iaxsl[callno]); 05295 if (callno && iaxs[callno]) { 05296 ast_debug(1, "We're hanging up %s now...\n", ast_channel_name(c)); 05297 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE); 05298 /* Send the hangup unless we have had a transmission error or are already gone */ 05299 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 05300 if (!iaxs[callno]->error && !alreadygone) { 05301 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 05302 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 05303 } 05304 if (!iaxs[callno]) { 05305 ast_mutex_unlock(&iaxsl[callno]); 05306 return 0; 05307 } 05308 } 05309 /* Explicitly predestroy it */ 05310 iax2_predestroy(callno); 05311 /* If we were already gone to begin with, destroy us now */ 05312 if (iaxs[callno] && alreadygone) { 05313 ast_debug(1, "Really destroying %s now...\n", ast_channel_name(c)); 05314 iax2_destroy(callno); 05315 } else if (iaxs[callno]) { 05316 if (ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) { 05317 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno); 05318 iax2_destroy(callno); 05319 } 05320 } 05321 } else if (c->tech_pvt) { 05322 /* If this call no longer exists, but the channel still 05323 * references it we need to set the channel's tech_pvt to null 05324 * to avoid ast_channel_free() trying to free it. 05325 */ 05326 c->tech_pvt = NULL; 05327 } 05328 ast_mutex_unlock(&iaxsl[callno]); 05329 ast_verb(3, "Hungup '%s'\n", ast_channel_name(c)); 05330 return 0; 05331 }
| static int iax2_indicate | ( | struct ast_channel * | c, | |
| int | condition, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Definition at line 5697 of file chan_iax2.c.
References AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_CONTROL, ast_moh_start(), ast_moh_stop(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, IAX_SENDCONNECTEDLINE, chan_iax2_pvt::mohinterpret, PTR_TO_CALLNO, send_command(), ast_channel::tech_pvt, and wait_for_peercallno().
05698 { 05699 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05700 struct chan_iax2_pvt *pvt; 05701 int res = 0; 05702 05703 if (iaxdebug) 05704 ast_debug(1, "Indicating condition %d\n", condition); 05705 05706 ast_mutex_lock(&iaxsl[callno]); 05707 pvt = iaxs[callno]; 05708 05709 if (wait_for_peercallno(pvt)) { 05710 res = -1; 05711 goto done; 05712 } 05713 05714 switch (condition) { 05715 case AST_CONTROL_HOLD: 05716 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05717 ast_moh_start(c, data, pvt->mohinterpret); 05718 goto done; 05719 } 05720 break; 05721 case AST_CONTROL_UNHOLD: 05722 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05723 ast_moh_stop(c); 05724 goto done; 05725 } 05726 break; 05727 case AST_CONTROL_CONNECTED_LINE: 05728 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE)) 05729 goto done; 05730 break; 05731 } 05732 05733 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 05734 05735 done: 05736 ast_mutex_unlock(&iaxsl[callno]); 05737 05738 return res; 05739 }
| static int iax2_key_rotate | ( | const void * | vpvt | ) | [static] |
Definition at line 5450 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_sched_add(), iax_ie_data::buf, build_ecx_key(), chan_iax2_pvt::callno, IAX_COMMAND_RTKEY, IAX_DEBUGDIGEST, iax_ie_append_raw(), IAX_IE_CHALLENGE, chan_iax2_pvt::keyrotateid, MD5Final(), MD5Init(), MD5Update(), iax_ie_data::pos, and send_command().
Referenced by iax2_send().
05451 { 05452 int res = 0; 05453 struct chan_iax2_pvt *pvt = (void *) vpvt; 05454 struct MD5Context md5; 05455 char key[17] = ""; 05456 struct iax_ie_data ied = { 05457 .pos = 0, 05458 }; 05459 05460 ast_mutex_lock(&iaxsl[pvt->callno]); 05461 pvt->keyrotateid = ast_sched_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt); 05462 05463 snprintf(key, sizeof(key), "%lX", ast_random()); 05464 05465 MD5Init(&md5); 05466 MD5Update(&md5, (unsigned char *) key, strlen(key)); 05467 MD5Final((unsigned char *) key, &md5); 05468 05469 IAX_DEBUGDIGEST("Sending", key); 05470 05471 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16); 05472 05473 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1); 05474 05475 build_ecx_key((unsigned char *) key, pvt); 05476 05477 ast_mutex_unlock(&iaxsl[pvt->callno]); 05478 05479 return res; 05480 }
| static void iax2_lock_owner | ( | int | callno | ) | [static] |
Definition at line 1259 of file chan_iax2.c.
References ast_channel_trylock, and DEADLOCK_AVOIDANCE.
Referenced by iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), schedule_delivery(), set_hangup_source_and_cause(), and socket_process().
01260 { 01261 for (;;) { 01262 if (!iaxs[callno] || !iaxs[callno]->owner) { 01263 /* There is no owner lock to get. */ 01264 break; 01265 } 01266 if (!ast_channel_trylock(iaxs[callno]->owner)) { 01267 /* We got the lock */ 01268 break; 01269 } 01270 /* Avoid deadlock by pausing and trying again */ 01271 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01272 } 01273 }
| static int iax2_matchmore | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority, | |||
| const char * | callerid, | |||
| const char * | data | |||
| ) | [static] |
Part of the IAX2 Switch interface.
Definition at line 13877 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_MATCHMORE, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
13878 { 13879 int res = 0; 13880 struct iax2_dpcache *dp = NULL; 13881 #if 0 13882 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13883 #endif 13884 if ((priority != 1) && (priority != 2)) 13885 return 0; 13886 13887 AST_LIST_LOCK(&dpcache); 13888 if ((dp = find_cache(chan, data, context, exten, priority))) { 13889 if (dp->flags & CACHE_FLAG_MATCHMORE) 13890 res = 1; 13891 } else { 13892 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13893 } 13894 AST_LIST_UNLOCK(&dpcache); 13895 13896 return res; 13897 }
| static int iax2_parse_allow_disallow | ( | struct ast_codec_pref * | pref, | |
| iax2_format * | formats, | |||
| const char * | list, | |||
| int | allowing | |||
| ) | [static] |
Definition at line 1694 of file chan_iax2.c.
References ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_format_cap_from_old_bitfield(), ast_format_cap_to_old_bitfield(), and ast_parse_allow_disallow().
Referenced by build_peer(), build_user(), and set_config().
01695 { 01696 int res; 01697 struct ast_format_cap *cap = ast_format_cap_alloc_nolock(); 01698 if (!cap) { 01699 return 1; 01700 } 01701 01702 ast_format_cap_from_old_bitfield(cap, *formats); 01703 res = ast_parse_allow_disallow(pref, cap, list, allowing); 01704 *formats = ast_format_cap_to_old_bitfield(cap); 01705 cap = ast_format_cap_destroy(cap); 01706 01707 return res; 01708 }
| static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 12070 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
12071 { 12072 struct iax2_peer *peer = (struct iax2_peer *)data; 12073 peer->pokeexpire = -1; 12074 #ifdef SCHED_MULTITHREADED 12075 if (schedule_action(__iax2_poke_noanswer, data)) 12076 #endif 12077 __iax2_poke_noanswer(data); 12078 peer_unref(peer); 12079 return 0; 12080 }
| static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
| int | heldcall | |||
| ) | [static] |
Definition at line 12091 of file chan_iax2.c.
References add_empty_calltoken_ie(), iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_SCHED_DEL, ast_sockaddr_ipv4(), ast_sockaddr_to_sin, iax_ie_data::buf, iax2_peer::callno, DEFAULT_MAXMS, iax2_peer::dnsmgr, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), iax2_sched_add(), IAX_COMMAND_POKE, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, iax2_peer::name, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax_ie_data::pos, send_command(), and iax2_peer::sockfd.
Referenced by __iax2_poke_peer_s(), iax2_poke_peer_cb(), poke_all_peers(), reg_source_db(), and update_registry().
12092 { 12093 int callno; 12094 struct sockaddr_in peer_addr; 12095 12096 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) { 12097 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 12098 immediately after clearing things out */ 12099 peer->lastms = 0; 12100 peer->historicms = 0; 12101 peer->pokeexpire = -1; 12102 peer->callno = 0; 12103 return 0; 12104 } 12105 12106 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 12107 12108 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 12109 if ((callno = peer->callno) > 0) { 12110 ast_log(LOG_NOTICE, "Still have a callno...\n"); 12111 ast_mutex_lock(&iaxsl[callno]); 12112 iax2_destroy(callno); 12113 ast_mutex_unlock(&iaxsl[callno]); 12114 } 12115 if (heldcall) 12116 ast_mutex_unlock(&iaxsl[heldcall]); 12117 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0); 12118 if (heldcall) 12119 ast_mutex_lock(&iaxsl[heldcall]); 12120 if (peer->callno < 1) { 12121 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 12122 return -1; 12123 } 12124 12125 /* Speed up retransmission times for this qualify call */ 12126 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 12127 iaxs[peer->callno]->peerpoke = peer; 12128 12129 if (peer->pokeexpire > -1) { 12130 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 12131 peer->pokeexpire = -1; 12132 peer_unref(peer); 12133 } 12134 } 12135 12136 /* Queue up a new task to handle no reply */ 12137 /* If the host is already unreachable then use the unreachable interval instead */ 12138 if (peer->lastms < 0) 12139 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 12140 else 12141 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 12142 12143 if (peer->pokeexpire == -1) 12144 peer_unref(peer); 12145 12146 /* And send the poke */ 12147 ast_mutex_lock(&iaxsl[callno]); 12148 if (iaxs[callno]) { 12149 struct iax_ie_data ied = { 12150 .buf = { 0 }, 12151 .pos = 0, 12152 }; 12153 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 12154 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1); 12155 } 12156 ast_mutex_unlock(&iaxsl[callno]); 12157 12158 return 0; 12159 }
| static int iax2_poke_peer_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 12082 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
12083 { 12084 struct iax2_peer *peer = obj; 12085 12086 iax2_poke_peer(peer, 0); 12087 12088 return 0; 12089 }
| static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9162 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
09163 { 09164 struct iax2_peer *peer = (struct iax2_peer *)data; 09165 peer->pokeexpire = -1; 09166 #ifdef SCHED_MULTITHREADED 09167 if (schedule_action(__iax2_poke_peer_s, data)) 09168 #endif 09169 __iax2_poke_peer_s(data); 09170 return 0; 09171 }
| static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 3426 of file chan_iax2.c.
References ast_module_unref(), ast_set_flag64, ast_test_flag64, iax2_destroy_helper(), iax2_queue_hangup(), IAX_ALREADYGONE, chan_iax2_pvt::owner, and ast_channel::tech_pvt.
Referenced by iax2_hangup(), and send_command_final().
03427 { 03428 struct ast_channel *c = NULL; 03429 struct chan_iax2_pvt *pvt = iaxs[callno]; 03430 03431 if (!pvt) 03432 return -1; 03433 03434 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) { 03435 iax2_destroy_helper(pvt); 03436 ast_set_flag64(pvt, IAX_ALREADYGONE); 03437 } 03438 03439 if ((c = pvt->owner)) { 03440 c->tech_pvt = NULL; 03441 iax2_queue_hangup(callno); 03442 pvt->owner = NULL; 03443 ast_module_unref(ast_module_info->self); 03444 } 03445 03446 return 0; 03447 }
| static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 11721 of file chan_iax2.c.
References iax2_thread::actions, ast_atomic_fetchadd_int(), ast_cond_timedwait, ast_cond_wait, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), iax2_thread::checktime, iax2_thread::cond, iax2_thread::curfunc, handle_deferred_full_frames(), iax2_process_thread_cleanup(), IAX_IOSTATE_IDLE, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_READY, IAX_IOSTATE_SCHEDREADY, IAX_THREAD_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, iax2_thread::init_cond, iax2_thread::init_lock, insert_idle_thread(), iax2_thread::iostate, iax2_thread::lock, iax2_thread::scheddata, iax2_thread::schedfunc, signal_condition(), socket_process(), iax2_thread::stop, thread, and iax2_thread::type.
Referenced by find_idle_thread(), and start_network_thread().
11722 { 11723 struct iax2_thread *thread = data; 11724 struct timeval wait; 11725 struct timespec ts; 11726 int put_into_idle = 0; 11727 int first_time = 1; 11728 int old_state; 11729 11730 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1); 11731 11732 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state); 11733 pthread_cleanup_push(iax2_process_thread_cleanup, data); 11734 11735 for (;;) { 11736 /* Wait for something to signal us to be awake */ 11737 ast_mutex_lock(&thread->lock); 11738 11739 if (thread->stop) { 11740 ast_mutex_unlock(&thread->lock); 11741 break; 11742 } 11743 11744 /* Flag that we're ready to accept signals */ 11745 if (first_time) { 11746 signal_condition(&thread->init_lock, &thread->init_cond); 11747 first_time = 0; 11748 } 11749 11750 /* Put into idle list if applicable */ 11751 if (put_into_idle) { 11752 insert_idle_thread(thread); 11753 } 11754 11755 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 11756 struct iax2_thread *t = NULL; 11757 /* Wait to be signalled or time out */ 11758 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11759 ts.tv_sec = wait.tv_sec; 11760 ts.tv_nsec = wait.tv_usec * 1000; 11761 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11762 /* This thread was never put back into the available dynamic 11763 * thread list, so just go away. */ 11764 if (!put_into_idle || thread->stop) { 11765 ast_mutex_unlock(&thread->lock); 11766 break; 11767 } 11768 AST_LIST_LOCK(&dynamic_list); 11769 /* Account for the case where this thread is acquired *right* after a timeout */ 11770 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 11771 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1); 11772 AST_LIST_UNLOCK(&dynamic_list); 11773 if (t) { 11774 /* This dynamic thread timed out waiting for a task and was 11775 * not acquired immediately after the timeout, 11776 * so it's time to go away. */ 11777 ast_mutex_unlock(&thread->lock); 11778 break; 11779 } 11780 /* Someone grabbed our thread *right* after we timed out. 11781 * Wait for them to set us up with something to do and signal 11782 * us to continue. */ 11783 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11784 ts.tv_sec = wait.tv_sec; 11785 ts.tv_nsec = wait.tv_usec * 1000; 11786 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11787 ast_mutex_unlock(&thread->lock); 11788 break; 11789 } 11790 } 11791 } else { 11792 ast_cond_wait(&thread->cond, &thread->lock); 11793 } 11794 11795 /* Go back into our respective list */ 11796 put_into_idle = 1; 11797 11798 ast_mutex_unlock(&thread->lock); 11799 11800 if (thread->stop) { 11801 break; 11802 } 11803 11804 if (thread->iostate == IAX_IOSTATE_IDLE) 11805 continue; 11806 11807 /* See what we need to do */ 11808 switch (thread->iostate) { 11809 case IAX_IOSTATE_READY: 11810 thread->actions++; 11811 thread->iostate = IAX_IOSTATE_PROCESSING; 11812 socket_process(thread); 11813 handle_deferred_full_frames(thread); 11814 break; 11815 case IAX_IOSTATE_SCHEDREADY: 11816 thread->actions++; 11817 thread->iostate = IAX_IOSTATE_PROCESSING; 11818 #ifdef SCHED_MULTITHREADED 11819 thread->schedfunc(thread->scheddata); 11820 #endif 11821 default: 11822 break; 11823 } 11824 time(&thread->checktime); 11825 thread->iostate = IAX_IOSTATE_IDLE; 11826 #ifdef DEBUG_SCHED_MULTITHREAD 11827 thread->curfunc[0]='\0'; 11828 #endif 11829 11830 /* The network thread added us to the active_thread list when we were given 11831 * frames to process, Now that we are done, we must remove ourselves from 11832 * the active list, and return to the idle list */ 11833 AST_LIST_LOCK(&active_list); 11834 AST_LIST_REMOVE(&active_list, thread, list); 11835 AST_LIST_UNLOCK(&active_list); 11836 11837 /* Make sure another frame didn't sneak in there after we thought we were done. */ 11838 handle_deferred_full_frames(thread); 11839 } 11840 11841 /*! 11842 * \note For some reason, idle threads are exiting without being removed 11843 * from an idle list, which is causing memory corruption. Forcibly remove 11844 * it from the list, if it's there. 11845 */ 11846 AST_LIST_LOCK(&idle_list); 11847 AST_LIST_REMOVE(&idle_list, thread, list); 11848 AST_LIST_UNLOCK(&idle_list); 11849 11850 AST_LIST_LOCK(&dynamic_list); 11851 AST_LIST_REMOVE(&dynamic_list, thread, list); 11852 AST_LIST_UNLOCK(&dynamic_list); 11853 11854 if (!thread->stop) { 11855 /* Nobody asked me to stop so nobody is waiting to join me. */ 11856 pthread_detach(pthread_self()); 11857 } 11858 11859 /* I am exiting here on my own volition, I need to clean up my own data structures 11860 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 11861 */ 11862 pthread_cleanup_pop(1); 11863 return NULL; 11864 }
| static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 11710 of file chan_iax2.c.
References ast_atomic_dec_and_test(), ast_cond_destroy, ast_free, ast_mutex_destroy, iax2_thread::cond, iaxactivethreadcount, iax2_thread::init_cond, iax2_thread::init_lock, iax2_thread::lock, and thread.
Referenced by iax2_process_thread().
11711 { 11712 struct iax2_thread *thread = data; 11713 ast_mutex_destroy(&thread->lock); 11714 ast_cond_destroy(&thread->cond); 11715 ast_mutex_destroy(&thread->init_lock); 11716 ast_cond_destroy(&thread->init_cond); 11717 ast_free(thread); 11718 ast_atomic_dec_and_test(&iaxactivethreadcount); 11719 }
| static int iax2_provision | ( | struct sockaddr_in * | end, | |
| int | sockfd, | |||
| const char * | dest, | |||
| const char * | template, | |||
| int | force | |||
| ) | [static] |
Definition at line 11927 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_unlock, ast_set_flag64, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, create_addr(), find_callno_locked(), iax2_sched_replace(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), NEW_FORCE, iax_ie_data::pos, send_command(), and create_addr_info::sockfd.
Referenced by check_provisioning(), handle_cli_iax2_provision(), and iax2_prov_app().
11928 { 11929 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 11930 is found for template */ 11931 struct iax_ie_data provdata; 11932 struct iax_ie_data ied; 11933 unsigned int sig; 11934 struct sockaddr_in sin; 11935 int callno; 11936 struct create_addr_info cai; 11937 11938 memset(&cai, 0, sizeof(cai)); 11939 11940 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template); 11941 11942 if (iax_provision_build(&provdata, &sig, template, force)) { 11943 ast_debug(1, "No provisioning found for template '%s'\n", template); 11944 return 0; 11945 } 11946 11947 if (end) { 11948 memcpy(&sin, end, sizeof(sin)); 11949 cai.sockfd = sockfd; 11950 } else if (create_addr(dest, NULL, &sin, &cai)) 11951 return -1; 11952 11953 /* Build the rest of the message */ 11954 memset(&ied, 0, sizeof(ied)); 11955 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 11956 11957 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 11958 if (!callno) 11959 return -1; 11960 11961 if (iaxs[callno]) { 11962 /* Schedule autodestruct in case they don't ever give us anything back */ 11963 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 11964 sched, 15000, auto_hangup, (void *)(long)callno); 11965 ast_set_flag64(iaxs[callno], IAX_PROVISION); 11966 /* Got a call number now, so go ahead and send the provisioning information */ 11967 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 11968 } 11969 ast_mutex_unlock(&iaxsl[callno]); 11970 11971 return 1; 11972 }
| static int iax2_queryoption | ( | struct ast_channel * | c, | |
| int | option, | |||
| void * | data, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 5427 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_unlock, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, ast_test_flag64, chan_iax2_pvt::callno, IAX_FORCE_ENCRYPT, PTR_TO_CALLNO, and ast_channel::tech_pvt.
05428 { 05429 switch (option) { 05430 case AST_OPTION_SECURE_SIGNALING: 05431 case AST_OPTION_SECURE_MEDIA: 05432 { 05433 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05434 ast_mutex_lock(&iaxsl[callno]); 05435 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0; 05436 ast_mutex_unlock(&iaxsl[callno]); 05437 return 0; 05438 } 05439 default: 05440 return -1; 05441 } 05442 }
| static int iax2_queue_control_data | ( | int | callno, | |
| enum ast_control_frame_type | control, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Queue a control frame on the ast_channel owner.
This function queues a control frame on the owner of the IAX2 pvt struct that is active for the given call number.
Definition at line 3059 of file chan_iax2.c.
References ast_channel_unlock, ast_queue_control_data(), and iax2_lock_owner().
Referenced by socket_process().
03061 { 03062 iax2_lock_owner(callno); 03063 if (iaxs[callno] && iaxs[callno]->owner) { 03064 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 03065 ast_channel_unlock(iaxs[callno]->owner); 03066 } 03067 return 0; 03068 }
| static int iax2_queue_frame | ( | int | callno, | |
| struct ast_frame * | f | |||
| ) | [static] |
Queue a frame to a call's owning asterisk channel.
Definition at line 3013 of file chan_iax2.c.
References ast_channel_unlock, ast_queue_frame(), and iax2_lock_owner().
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), __get_from_jb(), and socket_process().
03014 { 03015 iax2_lock_owner(callno); 03016 if (iaxs[callno] && iaxs[callno]->owner) { 03017 ast_queue_frame(iaxs[callno]->owner, f); 03018 ast_channel_unlock(iaxs[callno]->owner); 03019 } 03020 return 0; 03021 }
| static int iax2_queue_hangup | ( | int | callno | ) | [static] |
Queue a hangup frame on the ast_channel owner.
This function queues a hangup frame on the owner of the IAX2 pvt struct that is active for the given call number.
Definition at line 3036 of file chan_iax2.c.
References ast_channel_unlock, ast_queue_hangup(), and iax2_lock_owner().
Referenced by iax2_predestroy().
03037 { 03038 iax2_lock_owner(callno); 03039 if (iaxs[callno] && iaxs[callno]->owner) { 03040 ast_queue_hangup(iaxs[callno]->owner); 03041 ast_channel_unlock(iaxs[callno]->owner); 03042 } 03043 return 0; 03044 }
| static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static, read] |
Definition at line 5444 of file chan_iax2.c.
References ast_debug, and ast_null_frame.
05445 { 05446 ast_debug(1, "I should never be called!\n"); 05447 return &ast_null_frame; 05448 }
| static int iax2_register | ( | const char * | value, | |
| int | lineno | |||
| ) | [static] |
Definition at line 8599 of file chan_iax2.c.
References ast_copy_string(), ast_log(), copy(), hostname, iax2_append_register(), LOG_WARNING, secret, and strsep().
Referenced by set_config().
08600 { 08601 char copy[256]; 08602 char *username, *hostname, *secret; 08603 char *porta; 08604 char *stringp=NULL; 08605 08606 if (!value) 08607 return -1; 08608 08609 ast_copy_string(copy, value, sizeof(copy)); 08610 stringp = copy; 08611 username = strsep(&stringp, "@"); 08612 hostname = strsep(&stringp, "@"); 08613 08614 if (!hostname) { 08615 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 08616 return -1; 08617 } 08618 08619 stringp = username; 08620 username = strsep(&stringp, ":"); 08621 secret = strsep(&stringp, ":"); 08622 stringp = hostname; 08623 hostname = strsep(&stringp, ":"); 08624 porta = strsep(&stringp, ":"); 08625 08626 if (porta && !atoi(porta)) { 08627 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 08628 return -1; 08629 } 08630 08631 return iax2_append_register(hostname, username, secret, porta); 08632 }
| static struct ast_channel * iax2_request | ( | const char * | type, | |
| struct ast_format_cap * | cap, | |||
| const struct ast_channel * | requestor, | |||
| const char * | data, | |||
| int * | cause | |||
| ) | [static, read] |
Definition at line 12171 of file chan_iax2.c.
References ast_best_codec(), AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_channel_linkedid(), ast_channel_name(), ast_copy_flags64, ast_format_cap_copy(), ast_format_cap_destroy(), ast_format_cap_joint(), ast_format_cap_set(), ast_format_copy(), ast_getformatname_multiple(), ast_hangup(), ast_iax2_new(), ast_log(), ast_mutex_unlock, AST_STATE_DOWN, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_translator_best_choice(), create_addr_info::capability, create_addr(), find_callno_locked(), create_addr_info::found, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, LOG_WARNING, make_trunk(), create_addr_info::maxtime, chan_iax2_pvt::maxtime, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), parsed_dial_string::peer, parsed_dial_string::port, ast_channel::readformat, create_addr_info::sockfd, and ast_channel::writeformat.
12172 { 12173 int callno; 12174 int res; 12175 struct sockaddr_in sin; 12176 struct ast_channel *c; 12177 struct parsed_dial_string pds; 12178 struct create_addr_info cai; 12179 char *tmpstr; 12180 12181 memset(&pds, 0, sizeof(pds)); 12182 tmpstr = ast_strdupa(data); 12183 parse_dial_string(tmpstr, &pds); 12184 12185 if (ast_strlen_zero(pds.peer)) { 12186 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 12187 return NULL; 12188 } 12189 memset(&cai, 0, sizeof(cai)); 12190 cai.capability = iax2_capability; 12191 12192 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12193 12194 /* Populate our address from the given */ 12195 if (create_addr(pds.peer, NULL, &sin, &cai)) { 12196 *cause = AST_CAUSE_UNREGISTERED; 12197 return NULL; 12198 } 12199 12200 if (pds.port) 12201 sin.sin_port = htons(atoi(pds.port)); 12202 12203 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 12204 if (callno < 1) { 12205 ast_log(LOG_WARNING, "Unable to create call\n"); 12206 *cause = AST_CAUSE_CONGESTION; 12207 return NULL; 12208 } 12209 12210 /* If this is a trunk, update it now */ 12211 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12212 if (ast_test_flag64(&cai, IAX_TRUNK)) { 12213 int new_callno; 12214 if ((new_callno = make_trunk(callno, 1)) != -1) 12215 callno = new_callno; 12216 } 12217 iaxs[callno]->maxtime = cai.maxtime; 12218 if (cai.found) 12219 ast_string_field_set(iaxs[callno], host, pds.peer); 12220 12221 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? ast_channel_linkedid(requestor) : NULL); 12222 12223 ast_mutex_unlock(&iaxsl[callno]); 12224 12225 if (c) { 12226 struct ast_format_cap *joint; 12227 12228 /* Choose a format we can live with */ 12229 if ((joint = ast_format_cap_joint(c->nativeformats, cap))) { 12230 ast_format_cap_copy(c->nativeformats, joint); 12231 joint = ast_format_cap_destroy(joint); 12232 } else { 12233 struct ast_format best_fmt_cap; 12234 struct ast_format best_fmt_native; 12235 res = ast_translator_best_choice(cap, c->nativeformats, &best_fmt_cap, &best_fmt_native); 12236 if (res < 0) { 12237 char tmp[256]; 12238 char tmp2[256]; 12239 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 12240 ast_getformatname_multiple(tmp, sizeof(tmp), c->nativeformats), ast_getformatname_multiple(tmp2, sizeof(tmp2), cap), ast_channel_name(c)); 12241 ast_hangup(c); 12242 return NULL; 12243 } 12244 ast_format_cap_set(c->nativeformats, &best_fmt_native); 12245 } 12246 ast_best_codec(c->nativeformats, &c->readformat); 12247 ast_format_copy(&c->writeformat, &c->readformat); 12248 } 12249 12250 return c; 12251 }
| static int iax2_sched_add | ( | struct ast_sched_context * | sched, | |
| int | when, | |||
| ast_sched_cb | callback, | |||
| const void * | data | |||
| ) | [static] |
Definition at line 1494 of file chan_iax2.c.
References ast_sched_add().
Referenced by __attempt_transmit(), __find_callno(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), iax2_call(), iax2_poke_peer(), make_trunk(), network_change_event_cb(), realtime_peer(), reg_source_db(), sched_delay_remove(), socket_process(), transmit_frame(), and update_registry().
01496 { 01497 return ast_sched_add(con, when, callback, data); 01498 }
| static int iax2_sched_replace | ( | int | id, | |
| struct ast_sched_context * | con, | |||
| int | when, | |||
| ast_sched_cb | callback, | |||
| const void * | data | |||
| ) | [static] |
Definition at line 1488 of file chan_iax2.c.
References ast_sched_replace().
Referenced by auth_fail(), iax2_ack_registry(), iax2_do_register(), iax2_dprequest(), iax2_provision(), and update_jbsched().
01490 { 01491 return ast_sched_replace(id, con, when, callback, data); 01492 }
| static int iax2_send | ( | struct chan_iax2_pvt * | pvt, | |
| struct ast_frame * | f, | |||
| unsigned int | ts, | |||
| int | seqno, | |||
| int | now, | |||
| int | transfer, | |||
| int | final | |||
| ) | [static] |
Definition at line 6431 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, chan_iax2_pvt::aseqno, ast_format_get_video_mark(), ast_format_id_from_old_bitfield(), ast_format_to_old_bitfield(), AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag64, calc_timestamp(), ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, chan_iax2_pvt::callno, iax_frame::callno, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, iax_frame::datalen, ast_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, iax_frame::ecx, chan_iax2_pvt::ecx, chan_iax2_pvt::encmethods, iax_frame::encmethods, encrypt_frame(), iax_frame::final, chan_iax2_pvt::first_iax_message, ast_frame_subclass::format, ast_frame::frametype, iax2_key_rotate(), iax2_transmit(), iax2_trunk_queue(), IAX_CALLENCRYPTED, IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_outputframe(), IAX_TRUNK, ast_format::id, ast_frame_subclass::integer, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::last_iax_message, chan_iax2_pvt::lastsent, iax2_trunk_peer::lastsent, chan_iax2_pvt::lastvsent, LOG_NOTICE, LOG_WARNING, MARK_IAX_SUBCLASS_TX, MAX_RETRY_TIME, MIN_RETRY_TIME, chan_iax2_pvt::mydcx, iax_frame::mydcx, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, ast_frame::ptr, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, iax_frame::semirand, chan_iax2_pvt::semirand, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, iax_frame::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.
Referenced by __send_command(), iax2_write(), send_signaling(), and socket_process().
06432 { 06433 /* Queue a packet for delivery on a given private structure. Use "ts" for 06434 timestamp, or calculate if ts is 0. Send immediately without retransmission 06435 or delayed, with retransmission */ 06436 struct ast_iax2_full_hdr *fh; 06437 struct ast_iax2_mini_hdr *mh; 06438 struct ast_iax2_video_hdr *vh; 06439 struct { 06440 struct iax_frame fr2; 06441 unsigned char buffer[4096]; 06442 } frb; 06443 struct iax_frame *fr; 06444 int res; 06445 int sendmini=0; 06446 unsigned int lastsent; 06447 unsigned int fts; 06448 06449 frb.fr2.afdatalen = sizeof(frb.buffer); 06450 06451 if (!pvt) { 06452 ast_log(LOG_WARNING, "No private structure for packet?\n"); 06453 return -1; 06454 } 06455 06456 lastsent = pvt->lastsent; 06457 06458 /* Calculate actual timestamp */ 06459 fts = calc_timestamp(pvt, ts, f); 06460 06461 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 06462 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 06463 * increment the "predicted timestamps" for voice, if we're predicting */ 06464 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 06465 return 0; 06466 #if 0 06467 ast_log(LOG_NOTICE, 06468 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n", 06469 *("=!" + (f->frametype == AST_FRAME_VOICE)), 06470 IAX_CALLENCRYPTED(pvt) ? "" : "not ", 06471 pvt->keyrotateid != -1 ? "" : "no " 06472 ); 06473 #endif 06474 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) { 06475 iax2_key_rotate(pvt); 06476 } 06477 06478 if ((ast_test_flag64(pvt, IAX_TRUNK) || 06479 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 06480 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 06481 /* High two bytes are the same on timestamp, or sending on a trunk */ && 06482 (f->frametype == AST_FRAME_VOICE) 06483 /* is a voice frame */ && 06484 (f->subclass.format.id == ast_format_id_from_old_bitfield(pvt->svoiceformat)) 06485 /* is the same type */ ) { 06486 /* Force immediate rather than delayed transmission */ 06487 now = 1; 06488 /* Mark that mini-style frame is appropriate */ 06489 sendmini = 1; 06490 } 06491 if ( f->frametype == AST_FRAME_VIDEO ) { 06492 /* 06493 * If the lower 15 bits of the timestamp roll over, or if 06494 * the video format changed then send a full frame. 06495 * Otherwise send a mini video frame 06496 */ 06497 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 06498 ((f->subclass.format.id) == ast_format_id_from_old_bitfield(pvt->svideoformat)) 06499 ) { 06500 now = 1; 06501 sendmini = 1; 06502 } else { 06503 now = 0; 06504 sendmini = 0; 06505 } 06506 pvt->lastvsent = fts; 06507 } 06508 if (f->frametype == AST_FRAME_IAX) { 06509 /* 0x8000 marks this message as TX:, this bit will be stripped later */ 06510 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX; 06511 if (!pvt->first_iax_message) { 06512 pvt->first_iax_message = pvt->last_iax_message; 06513 } 06514 } 06515 /* Allocate an iax_frame */ 06516 if (now) { 06517 fr = &frb.fr2; 06518 } else 06519 fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag64(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO)); 06520 if (!fr) { 06521 ast_log(LOG_WARNING, "Out of memory\n"); 06522 return -1; 06523 } 06524 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 06525 iax_frame_wrap(fr, f); 06526 06527 fr->ts = fts; 06528 fr->callno = pvt->callno; 06529 fr->transfer = transfer; 06530 fr->final = final; 06531 fr->encmethods = 0; 06532 if (!sendmini) { 06533 /* We need a full frame */ 06534 if (seqno > -1) 06535 fr->oseqno = seqno; 06536 else 06537 fr->oseqno = pvt->oseqno++; 06538 fr->iseqno = pvt->iseqno; 06539 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr)); 06540 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 06541 fh->ts = htonl(fr->ts); 06542 fh->oseqno = fr->oseqno; 06543 if (transfer) { 06544 fh->iseqno = 0; 06545 } else 06546 fh->iseqno = fr->iseqno; 06547 /* Keep track of the last thing we've acknowledged */ 06548 if (!transfer) 06549 pvt->aseqno = fr->iseqno; 06550 fh->type = fr->af.frametype & 0xFF; 06551 06552 if (fr->af.frametype == AST_FRAME_VIDEO) { 06553 iax2_format tmpfmt = ast_format_to_old_bitfield(&fr->af.subclass.format); 06554 tmpfmt |= ast_format_get_video_mark(&fr->af.subclass.format) ? 0x1LL : 0; 06555 fh->csub = compress_subclass(tmpfmt | ((tmpfmt & 0x1LL) << 6)); 06556 } else if (fr->af.frametype == AST_FRAME_VOICE) { 06557 fh->csub = compress_subclass(ast_format_to_old_bitfield(&fr->af.subclass.format)); 06558 } else { 06559 fh->csub = compress_subclass(fr->af.subclass.integer); 06560 } 06561 06562 if (transfer) { 06563 fr->dcallno = pvt->transfercallno; 06564 } else 06565 fr->dcallno = pvt->peercallno; 06566 fh->dcallno = htons(fr->dcallno); 06567 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 06568 fr->data = fh; 06569 fr->retries = 0; 06570 /* Retry after 2x the ping time has passed */ 06571 fr->retrytime = pvt->pingtime * 2; 06572 if (fr->retrytime < MIN_RETRY_TIME) 06573 fr->retrytime = MIN_RETRY_TIME; 06574 if (fr->retrytime > MAX_RETRY_TIME) 06575 fr->retrytime = MAX_RETRY_TIME; 06576 /* Acks' don't get retried */ 06577 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK)) 06578 fr->retries = -1; 06579 else if (f->frametype == AST_FRAME_VOICE) 06580 pvt->svoiceformat = ast_format_to_old_bitfield(&f->subclass.format); 06581 else if (f->frametype == AST_FRAME_VIDEO) 06582 pvt->svideoformat = ast_format_to_old_bitfield(&f->subclass.format); 06583 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06584 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06585 if (fr->transfer) 06586 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06587 else 06588 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06589 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 06590 fr->encmethods = pvt->encmethods; 06591 fr->ecx = pvt->ecx; 06592 fr->mydcx = pvt->mydcx; 06593 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand)); 06594 } else 06595 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06596 } 06597 06598 if (now) { 06599 res = send_packet(fr); 06600 } else 06601 res = iax2_transmit(fr); 06602 } else { 06603 if (ast_test_flag64(pvt, IAX_TRUNK)) { 06604 iax2_trunk_queue(pvt, fr); 06605 res = 0; 06606 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 06607 /* Video frame have no sequence number */ 06608 fr->oseqno = -1; 06609 fr->iseqno = -1; 06610 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr)); 06611 vh->zeros = 0; 06612 vh->callno = htons(0x8000 | fr->callno); 06613 vh->ts = htons((fr->ts & 0x7FFF) | (ast_format_get_video_mark(&fr->af.subclass.format) ? 0x8000 : 0)); 06614 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 06615 fr->data = vh; 06616 fr->retries = -1; 06617 res = send_packet(fr); 06618 } else { 06619 /* Mini-frames have no sequence number */ 06620 fr->oseqno = -1; 06621 fr->iseqno = -1; 06622 /* Mini frame will do */ 06623 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr)); 06624 mh->callno = htons(fr->callno); 06625 mh->ts = htons(fr->ts & 0xFFFF); 06626 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 06627 fr->data = mh; 06628 fr->retries = -1; 06629 if (pvt->transferring == TRANSFER_MEDIAPASS) 06630 fr->transfer = 1; 06631 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06632 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06633 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 06634 } else 06635 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06636 } 06637 res = send_packet(fr); 06638 } 06639 } 06640 return res; 06641 }
| static int iax2_sendhtml | ( | struct ast_channel * | c, | |
| int | subclass, | |||
| const char * | data, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 4364 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04365 { 04366 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 04367 }
| static int iax2_sendimage | ( | struct ast_channel * | c, | |
| struct ast_frame * | img | |||
| ) | [static] |
Definition at line 4359 of file chan_iax2.c.
References AST_FRAME_IMAGE, ast_frame::data, ast_frame::datalen, ast_frame_subclass::integer, ast_frame::ptr, PTR_TO_CALLNO, send_command_locked(), ast_frame::subclass, and ast_channel::tech_pvt.
04360 { 04361 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1); 04362 }
| static int iax2_sendtext | ( | struct ast_channel * | c, | |
| const char * | text | |||
| ) | [static] |
Definition at line 4352 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04353 { 04354 04355 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 04356 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 04357 }
| static int iax2_setoption | ( | struct ast_channel * | c, | |
| int | option, | |||
| void * | data, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 5355 of file chan_iax2.c.
References ast_clear_flag64, AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_free, ast_malloc, ast_mutex_lock, ast_mutex_unlock, AST_OPTION_AUDIO_MODE, AST_OPTION_DIGIT_DETECT, AST_OPTION_FAX_DETECT, AST_OPTION_FLAG_REQUEST, AST_OPTION_OPRMODE, AST_OPTION_RELAXDTMF, AST_OPTION_RXGAIN, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_OPTION_TXGAIN, ast_set_flag64, ast_option_header::data, errno, IAX_FORCE_ENCRYPT, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().
05356 { 05357 struct ast_option_header *h; 05358 int res; 05359 05360 switch (option) { 05361 case AST_OPTION_TXGAIN: 05362 case AST_OPTION_RXGAIN: 05363 /* these two cannot be sent, because they require a result */ 05364 errno = ENOSYS; 05365 return -1; 05366 case AST_OPTION_OPRMODE: 05367 errno = EINVAL; 05368 return -1; 05369 case AST_OPTION_SECURE_SIGNALING: 05370 case AST_OPTION_SECURE_MEDIA: 05371 { 05372 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05373 ast_mutex_lock(&iaxsl[callno]); 05374 if ((*(int *) data)) { 05375 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05376 } else { 05377 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05378 } 05379 ast_mutex_unlock(&iaxsl[callno]); 05380 return 0; 05381 } 05382 /* These options are sent to the other side across the network where 05383 * they will be passed to whatever channel is bridged there. Don't 05384 * do anything silly like pass an option that transmits pointers to 05385 * memory on this machine to a remote machine to use */ 05386 case AST_OPTION_TONE_VERIFY: 05387 case AST_OPTION_TDD: 05388 case AST_OPTION_RELAXDTMF: 05389 case AST_OPTION_AUDIO_MODE: 05390 case AST_OPTION_DIGIT_DETECT: 05391 case AST_OPTION_FAX_DETECT: 05392 { 05393 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05394 struct chan_iax2_pvt *pvt; 05395 05396 ast_mutex_lock(&iaxsl[callno]); 05397 pvt = iaxs[callno]; 05398 05399 if (wait_for_peercallno(pvt)) { 05400 ast_mutex_unlock(&iaxsl[callno]); 05401 return -1; 05402 } 05403 05404 ast_mutex_unlock(&iaxsl[callno]); 05405 05406 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 05407 return -1; 05408 } 05409 05410 h->flag = AST_OPTION_FLAG_REQUEST; 05411 h->option = htons(option); 05412 memcpy(h->data, data, datalen); 05413 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 05414 AST_CONTROL_OPTION, 0, (unsigned char *) h, 05415 datalen + sizeof(*h), -1); 05416 ast_free(h); 05417 return res; 05418 } 05419 default: 05420 return -1; 05421 } 05422 05423 /* Just in case someone does a break instead of a return */ 05424 return -1; 05425 }
| static int iax2_start_transfer | ( | unsigned short | callno0, | |
| unsigned short | callno1, | |||
| int | mediaonly | |||
| ) | [static] |
Definition at line 5482 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_debug, AST_FRAME_IAX, ast_random(), ast_set_flag64, iax_ie_data::buf, IAX_CALLENCRYPTED, IAX_COMMAND_TXREQ, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), IAX_IE_CALLNO, IAX_IE_TRANSFERID, IAX_NOTRANSFER, iax_ie_data::pos, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.
Referenced by iax2_bridge().
05483 { 05484 int res; 05485 struct iax_ie_data ied0; 05486 struct iax_ie_data ied1; 05487 unsigned int transferid = (unsigned int)ast_random(); 05488 05489 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) { 05490 ast_debug(1, "transfers are not supported for encrypted calls at this time"); 05491 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER); 05492 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER); 05493 return 0; 05494 } 05495 05496 memset(&ied0, 0, sizeof(ied0)); 05497 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 05498 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 05499 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 05500 05501 memset(&ied1, 0, sizeof(ied1)); 05502 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 05503 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 05504 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 05505 05506 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 05507 if (res) 05508 return -1; 05509 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 05510 if (res) 05511 return -1; 05512 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05513 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05514 return 0; 05515 }
| static int iax2_transfer | ( | struct ast_channel * | c, | |
| const char * | dest | |||
| ) | [static] |
Definition at line 5741 of file chan_iax2.c.
References ast_channel_name(), AST_CONTROL_TRANSFER, ast_copy_string(), ast_debug, AST_FRAME_IAX, ast_queue_control_data(), AST_TRANSFER_SUCCESS, iax_ie_data::buf, chan_iax2_pvt::callno, context, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, iax_ie_data::pos, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
05742 { 05743 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05744 struct iax_ie_data ied = { "", }; 05745 char tmp[256], *context; 05746 enum ast_control_transfer message = AST_TRANSFER_SUCCESS; 05747 ast_copy_string(tmp, dest, sizeof(tmp)); 05748 context = strchr(tmp, '@'); 05749 if (context) { 05750 *context = '\0'; 05751 context++; 05752 } 05753 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 05754 if (context) 05755 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 05756 ast_debug(1, "Transferring '%s' to '%s'\n", ast_channel_name(c), dest); 05757 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message)); 05758 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 05759 }
| static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 4335 of file chan_iax2.c.
References ast_taskprocessor_push(), iax_frame::sentyet, and transmit_frame().
Referenced by iax2_send().
04336 { 04337 fr->sentyet = 0; 04338 04339 return ast_taskprocessor_push(transmit_processor, transmit_frame, fr); 04340 }
| static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
| struct timeval * | now | |||
| ) | [inline, static] |
Definition at line 9216 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
09217 { 09218 /* Drop when trunk is about 5 seconds idle */ 09219 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 09220 return 1; 09221 return 0; 09222 }
| static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_frame * | fr | |||
| ) | [static] |
Definition at line 6169 of file chan_iax2.c.
References iax2_trunk_peer::addr, chan_iax2_pvt::addr, iax_frame::af, ast_debug, ast_inet_ntoa(), ast_log(), ast_mutex_unlock, ast_realloc, ast_test_flag64, ast_tvnow(), ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, ast_frame::data, ast_frame::datalen, DEFAULT_TRUNKDATA, f, find_tpeer(), IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_iax2_meta_trunk_mini::mini, ast_frame::ptr, send_trunk(), chan_iax2_pvt::sockfd, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, iax_frame::ts, and ast_iax2_mini_hdr::ts.
Referenced by iax2_send().
06170 { 06171 struct ast_frame *f; 06172 struct iax2_trunk_peer *tpeer; 06173 void *tmp, *ptr; 06174 struct timeval now; 06175 struct ast_iax2_meta_trunk_entry *met; 06176 struct ast_iax2_meta_trunk_mini *mtm; 06177 06178 f = &fr->af; 06179 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 06180 if (tpeer) { 06181 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 06182 /* Need to reallocate space */ 06183 if (tpeer->trunkdataalloc < trunkmaxsize) { 06184 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 06185 ast_mutex_unlock(&tpeer->lock); 06186 return -1; 06187 } 06188 06189 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 06190 tpeer->trunkdata = tmp; 06191 ast_debug(1, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc); 06192 } else { 06193 ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s:%d\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 06194 ast_mutex_unlock(&tpeer->lock); 06195 return -1; 06196 } 06197 } 06198 06199 /* Append to meta frame */ 06200 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 06201 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) { 06202 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06203 mtm->len = htons(f->datalen); 06204 mtm->mini.callno = htons(pvt->callno); 06205 mtm->mini.ts = htons(0xffff & fr->ts); 06206 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 06207 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 06208 } else { 06209 met = (struct ast_iax2_meta_trunk_entry *)ptr; 06210 /* Store call number and length in meta header */ 06211 met->callno = htons(pvt->callno); 06212 met->len = htons(f->datalen); 06213 /* Advance pointers/decrease length past trunk entry header */ 06214 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 06215 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 06216 } 06217 /* Copy actual trunk data */ 06218 memcpy(ptr, f->data.ptr, f->datalen); 06219 tpeer->trunkdatalen += f->datalen; 06220 06221 tpeer->calls++; 06222 06223 /* track the largest mtu we actually have sent */ 06224 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 06225 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 06226 06227 /* if we have enough for a full MTU, ship it now without waiting */ 06228 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) { 06229 now = ast_tvnow(); 06230 send_trunk(tpeer, &now); 06231 trunk_untimed ++; 06232 } 06233 06234 ast_mutex_unlock(&tpeer->lock); 06235 } 06236 return 0; 06237 }
| static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 9137 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, and send_command_immediate().
Referenced by socket_process(), and socket_process_meta().
09138 { 09139 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 09140 }
| static int iax2_write | ( | struct ast_channel * | c, | |
| struct ast_frame * | f | |||
| ) | [static] |
Definition at line 7513 of file chan_iax2.c.
References ast_debug, AST_FRAME_NULL, AST_FRAME_VOICE, ast_mutex_lock, ast_mutex_unlock, ast_test_flag, ast_test_flag64, errno, ast_frame::frametype, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, PTR_TO_CALLNO, and ast_channel::tech_pvt.
07514 { 07515 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 07516 int res = -1; 07517 ast_mutex_lock(&iaxsl[callno]); 07518 if (iaxs[callno]) { 07519 /* If there's an outstanding error, return failure now */ 07520 if (!iaxs[callno]->error) { 07521 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) 07522 res = 0; 07523 /* Don't waste bandwidth sending null frames */ 07524 else if (f->frametype == AST_FRAME_NULL) 07525 res = 0; 07526 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH)) 07527 res = 0; 07528 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 07529 res = 0; 07530 else 07531 /* Simple, just queue for transmission */ 07532 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 07533 } else { 07534 ast_debug(1, "Write error: %s\n", strerror(errno)); 07535 } 07536 } 07537 /* If it's already gone, just return */ 07538 ast_mutex_unlock(&iaxsl[callno]); 07539 return res; 07540 }
| static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 3218 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_iax2_firmware_header::devname, iax_firmware::fwh, and ast_iax2_firmware_header::version.
Referenced by update_registry().
03219 { 03220 int res = 0; 03221 struct iax_firmware *cur = NULL; 03222 03223 if (ast_strlen_zero(dev)) 03224 return 0; 03225 03226 AST_LIST_LOCK(&firmwares); 03227 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03228 if (!strcmp(dev, (char *)cur->fwh->devname)) { 03229 res = ntohs(cur->fwh->version); 03230 break; 03231 } 03232 } 03233 AST_LIST_UNLOCK(&firmwares); 03234 03235 return res; 03236 }
| static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 1117 of file chan_iax2.c.
References ast_verbose.
Referenced by load_module().
01118 { 01119 if (iaxdebug) 01120 ast_verbose("%s", data); 01121 }
| static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 1123 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
01124 { 01125 ast_log(LOG_WARNING, "%s", data); 01126 }
| static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
| const unsigned char * | dev, | |||
| unsigned int | desc | |||
| ) | [static] |
Definition at line 3238 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, iax_firmware::fwh, iax_ie_append(), iax_ie_append_int(), iax_ie_append_raw(), IAX_IE_FWBLOCKDATA, and IAX_IE_FWBLOCKDESC.
Referenced by socket_process().
03239 { 03240 int res = -1; 03241 unsigned int bs = desc & 0xff; 03242 unsigned int start = (desc >> 8) & 0xffffff; 03243 unsigned int bytes; 03244 struct iax_firmware *cur; 03245 03246 if (ast_strlen_zero((char *)dev) || !bs) 03247 return -1; 03248 03249 start *= bs; 03250 03251 AST_LIST_LOCK(&firmwares); 03252 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03253 if (strcmp((char *)dev, (char *)cur->fwh->devname)) 03254 continue; 03255 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 03256 if (start < ntohl(cur->fwh->datalen)) { 03257 bytes = ntohl(cur->fwh->datalen) - start; 03258 if (bytes > bs) 03259 bytes = bs; 03260 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 03261 } else { 03262 bytes = 0; 03263 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 03264 } 03265 if (bytes == bs) 03266 res = 0; 03267 else 03268 res = 1; 03269 break; 03270 } 03271 AST_LIST_UNLOCK(&firmwares); 03272 03273 return res; 03274 }
| static void iax_outputframe | ( | struct iax_frame * | f, | |
| struct ast_iax2_full_hdr * | fhi, | |||
| int | rx, | |||
| struct sockaddr_in * | sin, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 1100 of file chan_iax2.c.
References debugaddr, and iax_showframe().
Referenced by iax2_send(), raw_hangup(), and socket_process().
01101 { 01102 if (iaxdebug || 01103 (sin && debugaddr.sin_addr.s_addr && 01104 (!ntohs(debugaddr.sin_port) || 01105 debugaddr.sin_port == sin->sin_port) && 01106 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) { 01107 if (iaxdebug) { 01108 iax_showframe(f, fhi, rx, sin, datalen); 01109 } else { 01110 iaxdebug = 1; 01111 iax_showframe(f, fhi, rx, sin, datalen); 01112 iaxdebug = 0; 01113 } 01114 } 01115 }
| static int iax_park | ( | struct ast_channel * | chan1, | |
| struct ast_channel * | chan2, | |||
| const char * | park_exten, | |||
| const char * | park_context | |||
| ) | [static] |
DO NOT hold any locks while calling iax_park
Definition at line 9386 of file chan_iax2.c.
References ast_channel::amaflags, ast_calloc, ast_channel_accountcode(), ast_channel_alloc, ast_channel_linkedid(), ast_channel_masquerade(), ast_channel_name(), ast_channel_parkinglot(), ast_copy_string(), ast_do_masquerade(), ast_free, ast_hangup(), ast_pthread_create_detached_background, AST_STATE_DOWN, ast_strdup, iax_dual::chan1, iax_dual::chan2, ast_channel::context, ast_channel::exten, iax_park_thread(), iax_dual::park_context, iax_dual::park_exten, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_process().
09387 { 09388 struct iax_dual *d; 09389 struct ast_channel *chan1m, *chan2m;/* Chan2m: The transferer, chan1m: The transferee */ 09390 pthread_t th; 09391 09392 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, ast_channel_accountcode(chan2), chan1->exten, chan1->context, ast_channel_linkedid(chan1), chan1->amaflags, "Parking/%s", ast_channel_name(chan1)); 09393 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, ast_channel_accountcode(chan2), chan2->exten, chan2->context, ast_channel_linkedid(chan2), chan2->amaflags, "IAXPeer/%s", ast_channel_name(chan2)); 09394 d = ast_calloc(1, sizeof(*d)); 09395 if (!chan1m || !chan2m || !d) { 09396 if (chan1m) { 09397 ast_hangup(chan1m); 09398 } 09399 if (chan2m) { 09400 ast_hangup(chan2m); 09401 } 09402 ast_free(d); 09403 return -1; 09404 } 09405 d->park_exten = ast_strdup(park_exten); 09406 d->park_context = ast_strdup(park_context); 09407 if (!d->park_exten || !d->park_context) { 09408 ast_hangup(chan1m); 09409 ast_hangup(chan2m); 09410 ast_free(d->park_exten); 09411 ast_free(d->park_context); 09412 ast_free(d); 09413 return -1; 09414 } 09415 09416 /* Make formats okay */ 09417 chan1m->readformat = chan1->readformat; 09418 chan1m->writeformat = chan1->writeformat; 09419 09420 /* Prepare for taking over the channel */ 09421 if (ast_channel_masquerade(chan1m, chan1)) { 09422 ast_hangup(chan1m); 09423 ast_hangup(chan2m); 09424 ast_free(d->park_exten); 09425 ast_free(d->park_context); 09426 ast_free(d); 09427 return -1; 09428 } 09429 09430 /* Setup the extensions and such */ 09431 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 09432 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 09433 chan1m->priority = chan1->priority; 09434 09435 ast_do_masquerade(chan1m); 09436 09437 /* We make a clone of the peer channel too, so we can play 09438 back the announcement */ 09439 09440 /* Make formats okay */ 09441 chan2m->readformat = chan2->readformat; 09442 chan2m->writeformat = chan2->writeformat; 09443 ast_channel_parkinglot_set(chan2m, ast_channel_parkinglot(chan2)); 09444 09445 /* Prepare for taking over the channel */ 09446 if (ast_channel_masquerade(chan2m, chan2)) { 09447 ast_hangup(chan1m); 09448 ast_hangup(chan2m); 09449 ast_free(d->park_exten); 09450 ast_free(d->park_context); 09451 ast_free(d); 09452 return -1; 09453 } 09454 09455 /* Setup the extensions and such */ 09456 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 09457 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 09458 chan2m->priority = chan2->priority; 09459 09460 ast_do_masquerade(chan2m); 09461 09462 d->chan1 = chan1m; /* Transferee */ 09463 d->chan2 = chan2m; /* Transferer */ 09464 if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) { 09465 /* Could not start thread */ 09466 ast_hangup(chan1m); 09467 ast_hangup(chan2m); 09468 ast_free(d->park_exten); 09469 ast_free(d->park_context); 09470 ast_free(d); 09471 return -1; 09472 } 09473 return 0; 09474 }
| static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 9359 of file chan_iax2.c.
References ast_channel_name(), ast_debug, ast_free, ast_hangup(), ast_log(), ast_park_call_exten(), iax_dual::chan1, iax_dual::chan2, ext, LOG_NOTICE, iax_dual::park_context, and iax_dual::park_exten.
Referenced by iax_park().
09360 { 09361 struct iax_dual *d; 09362 int res; 09363 int ext = 0; 09364 09365 d = stuff; 09366 09367 ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n", 09368 ast_channel_name(d->chan2), ast_channel_name(d->chan1)); 09369 09370 res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext); 09371 if (res) { 09372 /* Parking failed. */ 09373 ast_hangup(d->chan1); 09374 } else { 09375 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 09376 } 09377 ast_hangup(d->chan2); 09378 09379 ast_free(d->park_exten); 09380 ast_free(d->park_context); 09381 ast_free(d); 09382 return NULL; 09383 }
Definition at line 2031 of file chan_iax2.c.
References iax_frame::af, iax_frame::afdatalen, iax_frame::cacheable, ast_frame::datalen, DIRECTION_INGRESS, iax_frame_new(), and iax_frame_wrap().
Referenced by socket_process(), and socket_process_meta().
02032 { 02033 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 02034 if (new) { 02035 size_t afdatalen = new->afdatalen; 02036 memcpy(new, fr, sizeof(*new)); 02037 iax_frame_wrap(new, &fr->af); 02038 new->afdatalen = afdatalen; 02039 new->data = NULL; 02040 new->datalen = 0; 02041 new->direction = DIRECTION_INGRESS; 02042 new->retrans = -1; 02043 } 02044 return new; 02045 }
| static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 1378 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, IAX_THREAD_TYPE_DYNAMIC, and iax2_thread::type.
Referenced by iax2_process_thread().
01379 { 01380 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 01381 AST_LIST_LOCK(&dynamic_list); 01382 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 01383 AST_LIST_UNLOCK(&dynamic_list); 01384 } else { 01385 AST_LIST_LOCK(&idle_list); 01386 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 01387 AST_LIST_UNLOCK(&idle_list); 01388 } 01389 01390 return; 01391 }
| static void jb_debug_output | ( | const char * | fmt, | |
| ... | ||||
| ) | [static] |
Definition at line 1152 of file chan_iax2.c.
References args, and ast_verbose.
Referenced by handle_cli_iax2_set_debug_jb().
01153 { 01154 va_list args; 01155 char buf[1024]; 01156 01157 va_start(args, fmt); 01158 vsnprintf(buf, sizeof(buf), fmt, args); 01159 va_end(args); 01160 01161 ast_verbose("%s", buf); 01162 }
| static void jb_error_output | ( | const char * | fmt, | |
| ... | ||||
| ) | [static] |
Definition at line 1128 of file chan_iax2.c.
References args, ast_log(), and LOG_ERROR.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
01129 { 01130 va_list args; 01131 char buf[1024]; 01132 01133 va_start(args, fmt); 01134 vsnprintf(buf, sizeof(buf), fmt, args); 01135 va_end(args); 01136 01137 ast_log(LOG_ERROR, "%s", buf); 01138 }
| static void jb_warning_output | ( | const char * | fmt, | |
| ... | ||||
| ) | [static] |
Definition at line 1140 of file chan_iax2.c.
References args, ast_log(), and LOG_WARNING.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
01141 { 01142 va_list args; 01143 char buf[1024]; 01144 01145 va_start(args, fmt); 01146 vsnprintf(buf, sizeof(buf), fmt, args); 01147 va_end(args); 01148 01149 ast_log(LOG_WARNING, "%s", buf); 01150 }
| static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 14759 of file chan_iax2.c.
References __unload_module(), ao2_callback, ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register, ast_data_register_multiple, ast_format_cap_add_all(), ast_format_cap_alloc(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_mutex_init, ast_netsock_init(), ast_netsock_list_alloc(), ast_random(), ast_realtime_require_field(), ast_register_application_xml, ast_register_switch(), ast_sched_context_create(), ast_sched_context_destroy(), ast_sched_start_thread(), AST_TEST_REGISTER, ast_timer_close(), ast_timer_open(), ast_timer_set_rate(), ast_verb, ast_channel_tech::capabilities, config, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax_debug_output(), iax_error_output(), iax_provision_reload(), iax_set_error(), iax_set_output(), io_context_create(), io_context_destroy(), jb_error_output(), jb_setoutput(), jb_warning_output(), load_objects(), LOG_ERROR, manager_iax2_show_netstats(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_iax2_show_registry(), network_change_event_subscribe(), peer_set_sock_cb(), reload_firmware(), RQ_CHAR, RQ_UINTEGER2, SENTINEL, set_config(), and start_network_thread().
14760 { 14761 static const char config[] = "iax.conf"; 14762 int x = 0; 14763 struct iax2_registry *reg = NULL; 14764 14765 if (!(iax2_tech.capabilities = ast_format_cap_alloc())) { 14766 return AST_MODULE_LOAD_FAILURE; 14767 } 14768 ast_format_cap_add_all(iax2_tech.capabilities); 14769 14770 if (load_objects()) { 14771 return AST_MODULE_LOAD_FAILURE; 14772 } 14773 14774 memset(iaxs, 0, sizeof(iaxs)); 14775 14776 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14777 ast_mutex_init(&iaxsl[x]); 14778 } 14779 14780 if (!(sched = ast_sched_context_create())) { 14781 ast_log(LOG_ERROR, "Failed to create scheduler thread\n"); 14782 return AST_MODULE_LOAD_FAILURE; 14783 } 14784 14785 if (ast_sched_start_thread(sched)) { 14786 ast_sched_context_destroy(sched); 14787 sched = NULL; 14788 return AST_MODULE_LOAD_FAILURE; 14789 } 14790 14791 if (!(io = io_context_create())) { 14792 ast_log(LOG_ERROR, "Failed to create I/O context\n"); 14793 ast_sched_context_destroy(sched); 14794 sched = NULL; 14795 return AST_MODULE_LOAD_FAILURE; 14796 } 14797 14798 if (!(netsock = ast_netsock_list_alloc())) { 14799 ast_log(LOG_ERROR, "Failed to create netsock list\n"); 14800 io_context_destroy(io); 14801 ast_sched_context_destroy(sched); 14802 sched = NULL; 14803 return AST_MODULE_LOAD_FAILURE; 14804 } 14805 ast_netsock_init(netsock); 14806 14807 outsock = ast_netsock_list_alloc(); 14808 if (!outsock) { 14809 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 14810 io_context_destroy(io); 14811 ast_sched_context_destroy(sched); 14812 sched = NULL; 14813 return AST_MODULE_LOAD_FAILURE; 14814 } 14815 ast_netsock_init(outsock); 14816 14817 randomcalltokendata = ast_random(); 14818 14819 iax_set_output(iax_debug_output); 14820 iax_set_error(iax_error_output); 14821 jb_setoutput(jb_error_output, jb_warning_output, NULL); 14822 14823 if ((timer = ast_timer_open())) { 14824 ast_timer_set_rate(timer, trunkfreq); 14825 } 14826 14827 if (set_config(config, 0) == -1) { 14828 if (timer) { 14829 ast_timer_close(timer); 14830 } 14831 return AST_MODULE_LOAD_DECLINE; 14832 } 14833 14834 #ifdef TEST_FRAMEWORK 14835 AST_TEST_REGISTER(test_iax2_peers_get); 14836 AST_TEST_REGISTER(test_iax2_users_get); 14837 #endif 14838 14839 /* Register AstData providers */ 14840 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers)); 14841 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14842 14843 ast_register_application_xml(papp, iax2_prov_app); 14844 14845 ast_custom_function_register(&iaxpeer_function); 14846 ast_custom_function_register(&iaxvar_function); 14847 14848 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers); 14849 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list); 14850 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats); 14851 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry); 14852 14853 if (ast_channel_register(&iax2_tech)) { 14854 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 14855 __unload_module(); 14856 return AST_MODULE_LOAD_FAILURE; 14857 } 14858 14859 if (ast_register_switch(&iax2_switch)) { 14860 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 14861 } 14862 14863 if (start_network_thread()) { 14864 ast_log(LOG_ERROR, "Unable to start network thread\n"); 14865 __unload_module(); 14866 return AST_MODULE_LOAD_FAILURE; 14867 } else { 14868 ast_verb(2, "IAX Ready and Listening\n"); 14869 } 14870 14871 AST_LIST_LOCK(®istrations); 14872 AST_LIST_TRAVERSE(®istrations, reg, entry) 14873 iax2_do_register(reg); 14874 AST_LIST_UNLOCK(®istrations); 14875 14876 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 14877 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 14878 14879 14880 reload_firmware(0); 14881 iax_provision_reload(0); 14882 14883 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL); 14884 14885 network_change_event_subscribe(); 14886 14887 return AST_MODULE_LOAD_SUCCESS; 14888 }
| static int load_objects | ( | void | ) | [static] |
Definition at line 14521 of file chan_iax2.c.
References addr_range_cmp_cb(), addr_range_hash_cb(), ao2_container_alloc, ao2_ref, AST_MODULE_LOAD_FAILURE, ast_taskprocessor_get(), create_callno_pools(), MAX_PEER_BUCKETS, MAX_USER_BUCKETS, peer_cmp_cb(), peer_hash_cb(), peercnt_cmp_cb(), peercnt_hash_cb(), pvt_cmp_cb(), pvt_hash_cb(), TPS_REF_DEFAULT, transfercallno_pvt_cmp_cb(), transfercallno_pvt_hash_cb(), user_cmp_cb(), and user_hash_cb().
Referenced by load_module().
14522 { 14523 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL; 14524 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL; 14525 14526 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) { 14527 goto container_fail; 14528 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) { 14529 goto container_fail; 14530 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) { 14531 goto container_fail; 14532 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) { 14533 goto container_fail; 14534 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) { 14535 goto container_fail; 14536 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14537 goto container_fail; 14538 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14539 goto container_fail; 14540 } else if (create_callno_pools()) { 14541 goto container_fail; 14542 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) { 14543 goto container_fail; 14544 } 14545 14546 return 0; 14547 14548 container_fail: 14549 if (peers) { 14550 ao2_ref(peers, -1); 14551 } 14552 if (users) { 14553 ao2_ref(users, -1); 14554 } 14555 if (iax_peercallno_pvts) { 14556 ao2_ref(iax_peercallno_pvts, -1); 14557 } 14558 if (iax_transfercallno_pvts) { 14559 ao2_ref(iax_transfercallno_pvts, -1); 14560 } 14561 if (peercnts) { 14562 ao2_ref(peercnts, -1); 14563 } 14564 if (callno_limits) { 14565 ao2_ref(callno_limits, -1); 14566 } 14567 if (calltoken_ignores) { 14568 ao2_ref(calltoken_ignores, -1); 14569 } 14570 if (callno_pool) { 14571 ao2_ref(callno_pool, -1); 14572 } 14573 if (callno_pool_trunk) { 14574 ao2_ref(callno_pool_trunk, -1); 14575 } 14576 return AST_MODULE_LOAD_FAILURE; 14577 }
| static void lock_both | ( | unsigned short | callno0, | |
| unsigned short | callno1 | |||
| ) | [static] |
Definition at line 5517 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_trylock, and DEADLOCK_AVOIDANCE.
Referenced by iax2_bridge().
05518 { 05519 ast_mutex_lock(&iaxsl[callno0]); 05520 while (ast_mutex_trylock(&iaxsl[callno1])) { 05521 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 05522 } 05523 }
| static void log_jitterstats | ( | unsigned short | callno | ) | [static] |
Definition at line 9546 of file chan_iax2.c.
References ast_channel_name(), ast_debug, ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, jb_info::current, iax_rr::delay, iax_rr::dropped, EVENT_FLAG_REPORTING, jb_info::frames_dropped, jb_info::frames_in, jb_info::frames_lost, jb_info::frames_ooo, IAX_USEJITTERBUF, ast_channel::jb, jb_getinfo(), iax_rr::jitter, jb_info::jitter, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, manager_event, jb_info::min, iax_rr::ooo, iax_rr::packets, and chan_iax2_pvt::remote_rr.
Referenced by socket_process().
09547 { 09548 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1; 09549 jb_info jbinfo; 09550 09551 ast_mutex_lock(&iaxsl[callno]); 09552 if (iaxs[callno] && iaxs[callno]->owner && ast_channel_name(iaxs[callno]->owner)) { 09553 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) { 09554 jb_getinfo(iaxs[callno]->jb, &jbinfo); 09555 localjitter = jbinfo.jitter; 09556 localdelay = jbinfo.current - jbinfo.min; 09557 locallost = jbinfo.frames_lost; 09558 locallosspct = jbinfo.losspct/1000; 09559 localdropped = jbinfo.frames_dropped; 09560 localooo = jbinfo.frames_ooo; 09561 localpackets = jbinfo.frames_in; 09562 } 09563 ast_debug(3, "JB STATS:%s ping=%d ljitterms=%d ljbdelayms=%d ltotlost=%d lrecentlosspct=%d ldropped=%d looo=%d lrecvd=%d rjitterms=%d rjbdelayms=%d rtotlost=%d rrecentlosspct=%d rdropped=%d rooo=%d rrecvd=%d\n", 09564 ast_channel_name(iaxs[callno]->owner), 09565 iaxs[callno]->pingtime, 09566 localjitter, 09567 localdelay, 09568 locallost, 09569 locallosspct, 09570 localdropped, 09571 localooo, 09572 localpackets, 09573 iaxs[callno]->remote_rr.jitter, 09574 iaxs[callno]->remote_rr.delay, 09575 iaxs[callno]->remote_rr.losscnt, 09576 iaxs[callno]->remote_rr.losspct/1000, 09577 iaxs[callno]->remote_rr.dropped, 09578 iaxs[callno]->remote_rr.ooo, 09579 iaxs[callno]->remote_rr.packets); 09580 manager_event(EVENT_FLAG_REPORTING, "JitterBufStats", "Owner: %s\r\nPing: %d\r\nLocalJitter: %d\r\nLocalJBDelay: %d\r\nLocalTotalLost: %d\r\nLocalLossPercent: %d\r\nLocalDropped: %d\r\nLocalooo: %d\r\nLocalReceived: %d\r\nRemoteJitter: %d\r\nRemoteJBDelay: %d\r\nRemoteTotalLost: %d\r\nRemoteLossPercent: %d\r\nRemoteDropped: %d\r\nRemoteooo: %d\r\nRemoteReceived: %d\r\n", 09581 ast_channel_name(iaxs[callno]->owner), 09582 iaxs[callno]->pingtime, 09583 localjitter, 09584 localdelay, 09585 locallost, 09586 locallosspct, 09587 localdropped, 09588 localooo, 09589 localpackets, 09590 iaxs[callno]->remote_rr.jitter, 09591 iaxs[callno]->remote_rr.delay, 09592 iaxs[callno]->remote_rr.losscnt, 09593 iaxs[callno]->remote_rr.losspct/1000, 09594 iaxs[callno]->remote_rr.dropped, 09595 iaxs[callno]->remote_rr.ooo, 09596 iaxs[callno]->remote_rr.packets); 09597 } 09598 ast_mutex_unlock(&iaxsl[callno]); 09599 }
| static int make_trunk | ( | unsigned short | callno, | |
| int | locked | |||
| ) | [static] |
Definition at line 2111 of file chan_iax2.c.
References ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_SCHED_DEL, chan_iax2_pvt::callno, callno_entry::callno, chan_iax2_pvt::callno_entry, get_unused_callno(), iax2_sched_add(), chan_iax2_pvt::lagid, LOG_WARNING, MIN_REUSE_TIME, chan_iax2_pvt::pingid, replace_callno(), send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), update_max_trunk(), and callno_entry::validated.
Referenced by iax2_request(), and socket_process().
02112 { 02113 int x; 02114 int res= 0; 02115 struct callno_entry *callno_entry; 02116 if (iaxs[callno]->oseqno) { 02117 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 02118 return -1; 02119 } 02120 if (callno & TRUNK_CALL_START) { 02121 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 02122 return -1; 02123 } 02124 02125 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) { 02126 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 02127 return -1; 02128 } 02129 02130 x = callno_entry->callno; 02131 ast_mutex_lock(&iaxsl[x]); 02132 02133 /*! 02134 * \note We delete these before switching the slot, because if 02135 * they fire in the meantime, they will generate a warning. 02136 */ 02137 AST_SCHED_DEL(sched, iaxs[callno]->pingid); 02138 AST_SCHED_DEL(sched, iaxs[callno]->lagid); 02139 iaxs[callno]->lagid = iaxs[callno]->pingid = -1; 02140 iaxs[x] = iaxs[callno]; 02141 iaxs[x]->callno = x; 02142 02143 /* since we copied over the pvt from a different callno, make sure the old entry is replaced 02144 * before assigning the new one */ 02145 if (iaxs[x]->callno_entry) { 02146 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry); 02147 } 02148 iaxs[x]->callno_entry = callno_entry; 02149 02150 iaxs[callno] = NULL; 02151 /* Update the two timers that should have been started */ 02152 iaxs[x]->pingid = iax2_sched_add(sched, 02153 ping_time * 1000, send_ping, (void *)(long)x); 02154 iaxs[x]->lagid = iax2_sched_add(sched, 02155 lagrq_time * 1000, send_lagrq, (void *)(long)x); 02156 02157 if (locked) 02158 ast_mutex_unlock(&iaxsl[callno]); 02159 res = x; 02160 if (!locked) 02161 ast_mutex_unlock(&iaxsl[x]); 02162 02163 ast_debug(1, "Made call %d into trunk call %d\n", callno, x); 02164 /* We move this call from a non-trunked to a trunked call */ 02165 update_max_trunk(); 02166 update_max_nontrunk(); 02167 return res; 02168 }
| static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 7014 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), and RESULT_SUCCESS.
Referenced by load_module().
07015 { 07016 ast_cli_netstats(s, -1, 0); 07017 astman_append(s, "\r\n"); 07018 return RESULT_SUCCESS; 07019 }
| static int manager_iax2_show_peer_list | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
callback to display iax peers in manager format
Definition at line 7077 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_copy_string(), ast_inet_ntoa(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag64, astman_append(), astman_get_header(), iax2_peer::encmethods, encmethods_to_str(), IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, iax2_peer::name, peer_status(), peer_unref(), RESULT_SUCCESS, status, and iax2_peer::username.
Referenced by load_module().
07078 { 07079 struct iax2_peer *peer = NULL; 07080 int peer_count = 0; 07081 char nm[20]; 07082 char status[20]; 07083 const char *id = astman_get_header(m,"ActionID"); 07084 char idtext[256] = ""; 07085 struct ast_str *encmethods = ast_str_alloca(256); 07086 struct ao2_iterator i; 07087 07088 if (!ast_strlen_zero(id)) 07089 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07090 07091 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext); 07092 07093 07094 i = ao2_iterator_init(peers, 0); 07095 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) { 07096 encmethods_to_str(peer->encmethods, encmethods); 07097 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext); 07098 if (!ast_strlen_zero(peer->username)) { 07099 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username); 07100 } else { 07101 astman_append(s, "ObjectName: %s\r\n", peer->name); 07102 } 07103 astman_append(s, "ChanObjectType: peer\r\n"); 07104 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr)); 07105 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 07106 astman_append(s, "Mask: %s\r\n", nm); 07107 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr)); 07108 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 07109 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 07110 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 07111 peer_status(peer, status, sizeof(status)); 07112 astman_append(s, "Status: %s\r\n\r\n", status); 07113 peer_count++; 07114 } 07115 ao2_iterator_destroy(&i); 07116 07117 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count); 07118 return RESULT_SUCCESS; 07119 }
| static int manager_iax2_show_peers | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
callback to display iax peers in manager
Definition at line 7053 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), and total.
Referenced by load_module().
07054 { 07055 static const char * const a[] = { "iax2", "show", "peers" }; 07056 const char *id = astman_get_header(m,"ActionID"); 07057 char idtext[256] = ""; 07058 int total = 0; 07059 07060 if (!ast_strlen_zero(id)) 07061 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07062 07063 astman_send_listack(s, m, "Peer status list will follow", "start"); 07064 /* List the peers in separate manager events */ 07065 __iax2_show_peers(-1, &total, s, 3, a); 07066 /* Send final confirmation */ 07067 astman_append(s, 07068 "Event: PeerlistComplete\r\n" 07069 "EventList: Complete\r\n" 07070 "ListItems: %d\r\n" 07071 "%s" 07072 "\r\n", total, idtext); 07073 return 0; 07074 }
| static int manager_iax2_show_registry | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 7185 of file chan_iax2.c.
References iax2_registry::addr, ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sockaddr_stringify(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), iax2_registry::dnsmgr, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), total, iax2_registry::us, and iax2_registry::username.
Referenced by load_module().
07186 { 07187 const char *id = astman_get_header(m, "ActionID"); 07188 struct iax2_registry *reg = NULL; 07189 char idtext[256] = ""; 07190 char host[80] = ""; 07191 char perceived[80] = ""; 07192 int total = 0; 07193 07194 if (!ast_strlen_zero(id)) 07195 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07196 07197 astman_send_listack(s, m, "Registrations will follow", "start"); 07198 07199 AST_LIST_LOCK(®istrations); 07200 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07201 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07202 07203 if (reg->us.sin_addr.s_addr) { 07204 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07205 } else { 07206 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07207 } 07208 07209 astman_append(s, 07210 "Event: RegistryEntry\r\n" 07211 "%s" 07212 "Host: %s\r\n" 07213 "DNSmanager: %s\r\n" 07214 "Username: %s\r\n" 07215 "Perceived: %s\r\n" 07216 "Refresh: %d\r\n" 07217 "State: %s\r\n" 07218 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, 07219 reg->refresh, regstate2str(reg->regstate)); 07220 07221 total++; 07222 } 07223 AST_LIST_UNLOCK(®istrations); 07224 07225 astman_append(s, 07226 "Event: RegistrationsComplete\r\n" 07227 "EventList: Complete\r\n" 07228 "ListItems: %d\r\n" 07229 "%s" 07230 "\r\n", total, idtext); 07231 07232 return 0; 07233 }
| static int match | ( | struct sockaddr_in * | sin, | |
| unsigned short | callno, | |||
| unsigned short | dcallno, | |||
| const struct chan_iax2_pvt * | cur, | |||
| int | check_dcallno | |||
| ) | [static] |
Definition at line 2060 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.
Referenced by __find_callno(), __get_header(), ast_parse_device_state(), ast_srtp_add_stream(), ast_srtp_change_source(), check_blacklist(), find_by_name(), find_command(), handle_updates(), internal_ao2_callback(), lua_find_extension(), misdn_update_redirecting(), pbx_find_extension(), pvt_cmp_cb(), realtime_switch_common(), and transfercallno_pvt_cmp_cb().
02061 { 02062 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 02063 (cur->addr.sin_port == sin->sin_port)) { 02064 /* This is the main host */ 02065 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 02066 (check_dcallno ? dcallno == cur->callno : 1) ) { 02067 /* That's us. Be sure we keep track of the peer call number */ 02068 return 1; 02069 } 02070 } 02071 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 02072 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 02073 /* We're transferring */ 02074 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 02075 return 1; 02076 } 02077 return 0; 02078 }
| static void memcpy_decrypt | ( | unsigned char * | dst, | |
| const unsigned char * | src, | |||
| int | len, | |||
| ast_aes_decrypt_key * | dcx | |||
| ) | [static] |
Definition at line 6267 of file chan_iax2.c.
References ast_aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
06268 { 06269 #if 0 06270 /* Debug with "fake encryption" */ 06271 int x; 06272 if (len % 16) 06273 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06274 for (x=0;x<len;x++) 06275 dst[x] = src[x] ^ 0xff; 06276 #else 06277 unsigned char lastblock[16] = { 0 }; 06278 int x; 06279 while(len > 0) { 06280 ast_aes_decrypt(src, dst, dcx); 06281 for (x=0;x<16;x++) 06282 dst[x] ^= lastblock[x]; 06283 memcpy(lastblock, src, sizeof(lastblock)); 06284 dst += 16; 06285 src += 16; 06286 len -= 16; 06287 } 06288 #endif 06289 }
| static void memcpy_encrypt | ( | unsigned char * | dst, | |
| const unsigned char * | src, | |||
| int | len, | |||
| ast_aes_encrypt_key * | ecx | |||
| ) | [static] |
Definition at line 6291 of file chan_iax2.c.
References ast_aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
06292 { 06293 #if 0 06294 /* Debug with "fake encryption" */ 06295 int x; 06296 if (len % 16) 06297 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06298 for (x=0;x<len;x++) 06299 dst[x] = src[x] ^ 0xff; 06300 #else 06301 unsigned char curblock[16] = { 0 }; 06302 int x; 06303 while(len > 0) { 06304 for (x=0;x<16;x++) 06305 curblock[x] ^= src[x]; 06306 ast_aes_encrypt(curblock, dst, ecx); 06307 memcpy(curblock, dst, sizeof(curblock)); 06308 dst += 16; 06309 src += 16; 06310 len -= 16; 06311 } 06312 #endif 06313 }
| static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | enc | |||
| ) | [static] |
Definition at line 7854 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, IAX_ENCRYPT_AES128, IAX_ENCRYPT_KEYROTATE, and chan_iax2_pvt::keyrotateid.
Referenced by authenticate_reply(), and socket_process().
07855 { 07856 /* Select exactly one common encryption if there are any */ 07857 p->encmethods &= enc; 07858 if (p->encmethods) { 07859 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */ 07860 p->keyrotateid = -2; 07861 } 07862 if (p->encmethods & IAX_ENCRYPT_AES128) 07863 p->encmethods = IAX_ENCRYPT_AES128; 07864 else 07865 p->encmethods = 0; 07866 } 07867 }
| static void mwi_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 1275 of file chan_iax2.c.
01276 { 01277 /* The MWI subscriptions exist just so the core knows we care about those 01278 * mailboxes. However, we just grab the events out of the cache when it 01279 * is time to send MWI, since it is only sent with a REGACK. */ 01280 }
| static void network_change_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 1310 of file chan_iax2.c.
References ast_debug, iax2_sched_add(), and network_change_event_sched_cb().
Referenced by network_change_event_subscribe().
01311 { 01312 ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n"); 01313 if (network_change_event_sched_id == -1) { 01314 network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL); 01315 } 01316 01317 }
| static int network_change_event_sched_cb | ( | const void * | data | ) | [static] |
Definition at line 1297 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and iax2_do_register().
Referenced by network_change_event_cb().
01298 { 01299 struct iax2_registry *reg; 01300 network_change_event_sched_id = -1; 01301 AST_LIST_LOCK(®istrations); 01302 AST_LIST_TRAVERSE(®istrations, reg, entry) { 01303 iax2_do_register(reg); 01304 } 01305 AST_LIST_UNLOCK(®istrations); 01306 01307 return 0; 01308 }
| static void network_change_event_subscribe | ( | void | ) | [static] |
Definition at line 1282 of file chan_iax2.c.
References AST_EVENT_IE_END, AST_EVENT_NETWORK_CHANGE, ast_event_subscribe(), and network_change_event_cb().
Referenced by load_module(), reload_config(), and set_config().
01283 { 01284 if (!network_change_event_subscription) { 01285 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE, 01286 network_change_event_cb, "IAX2 Network Change", NULL, AST_EVENT_IE_END); 01287 } 01288 }
| static void network_change_event_unsubscribe | ( | void | ) | [static] |
Definition at line 1290 of file chan_iax2.c.
References ast_event_unsubscribe().
Referenced by __unload_module(), reload_config(), set_config(), and unload_module().
01291 { 01292 if (network_change_event_subscription) { 01293 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription); 01294 } 01295 }
| static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 12253 of file chan_iax2.c.
References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), ast_timer_fd(), and timing_read().
Referenced by start_network_thread().
12254 { 12255 if (timer) { 12256 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL); 12257 } 12258 12259 for (;;) { 12260 pthread_testcancel(); 12261 /* Wake up once a second just in case SIGURG was sent while 12262 * we weren't in poll(), to make sure we don't hang when trying 12263 * to unload. */ 12264 ast_io_wait(io, 1000); 12265 } 12266 12267 return NULL; 12268 }
| static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
| const char * | host | |||
| ) | [static, read] |
Definition at line 1989 of file chan_iax2.c.
References ao2_alloc, ao2_ref, AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, ast_string_field_set, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::dpentries, exten, chan_iax2_pvt::hold_signaling, chan_iax2_pvt::initid, chan_iax2_pvt::jb, jb_new(), jb_setconf(), chan_iax2_pvt::jbid, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::lagid, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, chan_iax2_pvt::pingid, prefs, chan_iax2_pvt::prefs, pvt_destructor(), jb_conf::resync_threshold, chan_iax2_pvt::signaling_queue, and jb_conf::target_extra.
Referenced by __find_callno().
01990 { 01991 struct chan_iax2_pvt *tmp; 01992 jb_conf jbconf; 01993 01994 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01995 return NULL; 01996 } 01997 01998 if (ast_string_field_init(tmp, 32)) { 01999 ao2_ref(tmp, -1); 02000 tmp = NULL; 02001 return NULL; 02002 } 02003 02004 tmp->prefs = prefs; 02005 tmp->pingid = -1; 02006 tmp->lagid = -1; 02007 tmp->autoid = -1; 02008 tmp->authid = -1; 02009 tmp->initid = -1; 02010 tmp->keyrotateid = -1; 02011 02012 ast_string_field_set(tmp,exten, "s"); 02013 ast_string_field_set(tmp,host, host); 02014 02015 tmp->jb = jb_new(); 02016 tmp->jbid = -1; 02017 jbconf.max_jitterbuf = maxjitterbuffer; 02018 jbconf.resync_threshold = resyncthreshold; 02019 jbconf.max_contig_interp = maxjitterinterps; 02020 jbconf.target_extra = jittertargetextra; 02021 jb_setconf(tmp->jb,&jbconf); 02022 02023 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries); 02024 02025 tmp->hold_signaling = 1; 02026 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue); 02027 02028 return tmp; 02029 }
| static void parse_dial_string | ( | char * | data, | |
| struct parsed_dial_string * | pds | |||
| ) | [static] |
Parses an IAX dial string into its component parts.
| data | the string to be parsed | |
| pds | pointer to a struct parsed_dial_string to be filled in |
The dial string format is: [username[:password]@]peer[:port][/exten[@context]][/options]
Definition at line 5037 of file chan_iax2.c.
References ast_strip_quoted(), ast_strlen_zero(), parsed_dial_string::context, parsed_dial_string::exten, parsed_dial_string::key, parsed_dial_string::options, parsed_dial_string::password, parsed_dial_string::peer, parsed_dial_string::port, strsep(), and parsed_dial_string::username.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_devicestate(), and iax2_request().
05038 { 05039 if (ast_strlen_zero(data)) 05040 return; 05041 05042 pds->peer = strsep(&data, "/"); 05043 pds->exten = strsep(&data, "/"); 05044 pds->options = data; 05045 05046 if (pds->exten) { 05047 data = pds->exten; 05048 pds->exten = strsep(&data, "@"); 05049 pds->context = data; 05050 } 05051 05052 if (strchr(pds->peer, '@')) { 05053 data = pds->peer; 05054 pds->username = strsep(&data, "@"); 05055 pds->peer = data; 05056 } 05057 05058 if (pds->username) { 05059 data = pds->username; 05060 pds->username = strsep(&data, ":"); 05061 pds->password = data; 05062 } 05063 05064 data = pds->peer; 05065 pds->peer = strsep(&data, ":"); 05066 pds->port = data; 05067 05068 /* check for a key name wrapped in [] in the secret position, if found, 05069 move it to the key field instead 05070 */ 05071 if (pds->password && (pds->password[0] == '[')) { 05072 pds->key = ast_strip_quoted(pds->password, "[", "]"); 05073 pds->password = NULL; 05074 } 05075 }
| static int peer_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1737 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, iax2_peer::name, name, and OBJ_KEY.
Referenced by load_module(), and load_objects().
01738 { 01739 struct iax2_peer *peer = obj, *peer2 = arg; 01740 const char *name = arg; 01741 01742 return !strcmp(peer->name, flags & OBJ_KEY ? name : peer2->name) ? 01743 CMP_MATCH | CMP_STOP : 0; 01744 }
| static int peer_delme_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 12996 of file chan_iax2.c.
References ast_set_flag64, and IAX_DELME.
Referenced by delete_users().
12997 { 12998 struct iax2_peer *peer = obj; 12999 13000 ast_set_flag64(peer, IAX_DELME); 13001 13002 return 0; 13003 }
| static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 12430 of file chan_iax2.c.
References ast_dnsmgr_release(), ast_event_unsubscribe(), ast_free_ha(), ast_mutex_lock, ast_mutex_unlock, ast_string_field_free_memory, iax2_peer::callno, iax2_peer::dnsmgr, iax2_peer::ha, iax2_destroy(), iax2_peer::mwi_event_sub, and register_peer_exten().
Referenced by build_peer().
12431 { 12432 struct iax2_peer *peer = obj; 12433 int callno = peer->callno; 12434 12435 ast_free_ha(peer->ha); 12436 12437 if (callno > 0) { 12438 ast_mutex_lock(&iaxsl[callno]); 12439 iax2_destroy(callno); 12440 ast_mutex_unlock(&iaxsl[callno]); 12441 } 12442 12443 register_peer_exten(peer, 0); 12444 12445 if (peer->dnsmgr) 12446 ast_dnsmgr_release(peer->dnsmgr); 12447 12448 if (peer->mwi_event_sub) 12449 ast_event_unsubscribe(peer->mwi_event_sub); 12450 12451 ast_string_field_free_memory(peer); 12452 }
| static int peer_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1726 of file chan_iax2.c.
References ast_str_hash(), iax2_peer::name, name, and OBJ_KEY.
Referenced by load_module(), and load_objects().
01727 { 01728 const struct iax2_peer *peer = obj; 01729 const char *name = obj; 01730 01731 return ast_str_hash(flags & OBJ_KEY ? name : peer->name); 01732 }
Definition at line 1786 of file chan_iax2.c.
References ao2_ref.
Referenced by __iax2_poke_noanswer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_unregister(), iax2_poke_peer(), realtime_peer(), reg_source_db(), socket_process(), and update_registry().
01787 { 01788 ao2_ref(peer, +1); 01789 return peer; 01790 }
| static int peer_set_sock_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 14475 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
14476 { 14477 struct iax2_peer *peer = obj; 14478 14479 if (peer->sockfd < 0) 14480 peer->sockfd = defaultsockfd; 14481 14482 return 0; 14483 }
| static int peer_set_srcaddr | ( | struct iax2_peer * | peer, | |
| const char * | srcaddr | |||
| ) | [static] |
Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found.
Definition at line 12355 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_debug, ast_get_ip(), ast_log(), ast_netsock_bind(), ast_netsock_find(), ast_netsock_sockfd(), ast_netsock_unref(), ast_sockaddr_to_sin, ast_strdupa, check_srcaddr(), IAX_DEFAULT_PORTNO, LOG_WARNING, iax2_peer::name, qos, socket_read(), iax2_peer::sockfd, iax2_trunk_peer::sockfd, ast_sockaddr::ss, and strsep().
Referenced by build_peer().
12356 { 12357 struct sockaddr_in sin; 12358 struct ast_sockaddr sin_tmp; 12359 int nonlocal = 1; 12360 int port = IAX_DEFAULT_PORTNO; 12361 int sockfd = defaultsockfd; 12362 char *tmp; 12363 char *addr; 12364 char *portstr; 12365 12366 if (!(tmp = ast_strdupa(srcaddr))) 12367 return -1; 12368 12369 addr = strsep(&tmp, ":"); 12370 portstr = tmp; 12371 12372 if (portstr) { 12373 port = atoi(portstr); 12374 if (port < 1) 12375 port = IAX_DEFAULT_PORTNO; 12376 } 12377 12378 sin_tmp.ss.ss_family = AF_INET; 12379 if (!ast_get_ip(&sin_tmp, addr)) { 12380 struct ast_netsock *sock; 12381 int res; 12382 12383 ast_sockaddr_to_sin(&sin_tmp, &sin); 12384 sin.sin_port = 0; 12385 sin.sin_family = AF_INET; 12386 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 12387 if (res == 0) { 12388 /* ip address valid. */ 12389 sin.sin_port = htons(port); 12390 if (!(sock = ast_netsock_find(netsock, &sin))) 12391 sock = ast_netsock_find(outsock, &sin); 12392 if (sock) { 12393 sockfd = ast_netsock_sockfd(sock); 12394 nonlocal = 0; 12395 } else { 12396 unsigned int orig_saddr = sin.sin_addr.s_addr; 12397 /* INADDR_ANY matches anyway! */ 12398 sin.sin_addr.s_addr = INADDR_ANY; 12399 if (ast_netsock_find(netsock, &sin)) { 12400 sin.sin_addr.s_addr = orig_saddr; 12401 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL); 12402 if (sock) { 12403 sockfd = ast_netsock_sockfd(sock); 12404 ast_netsock_unref(sock); 12405 nonlocal = 0; 12406 } else { 12407 nonlocal = 2; 12408 } 12409 } 12410 } 12411 } 12412 } 12413 12414 peer->sockfd = sockfd; 12415 12416 if (nonlocal == 1) { 12417 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 12418 srcaddr, peer->name); 12419 return -1; 12420 } else if (nonlocal == 2) { 12421 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 12422 srcaddr, peer->name); 12423 return -1; 12424 } else { 12425 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 12426 return 0; 12427 } 12428 }
| static int peer_status | ( | struct iax2_peer * | peer, | |
| char * | status, | |||
| int | statuslen | |||
| ) | [static] |
peer_status: Report Peer status in character string
Definition at line 3779 of file chan_iax2.c.
References ast_copy_string(), iax2_peer::lastms, and iax2_peer::maxms.
Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), function_iaxpeer(), function_sippeer(), handle_cli_iax2_show_peer(), manager_iax2_show_peer_list(), and peers_data_provider_get().
03780 { 03781 int res = 0; 03782 if (peer->maxms) { 03783 if (peer->lastms < 0) { 03784 ast_copy_string(status, "UNREACHABLE", statuslen); 03785 } else if (peer->lastms > peer->maxms) { 03786 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 03787 res = 1; 03788 } else if (peer->lastms) { 03789 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 03790 res = 1; 03791 } else { 03792 ast_copy_string(status, "UNKNOWN", statuslen); 03793 } 03794 } else { 03795 ast_copy_string(status, "Unmonitored", statuslen); 03796 res = -1; 03797 } 03798 return res; 03799 }
Definition at line 1792 of file chan_iax2.c.
References ao2_ref.
Referenced by __expire_registry(), __iax2_poke_noanswer(), __iax2_poke_peer_s(), __iax2_show_peers(), authenticate_reply(), build_peer(), calltoken_required(), complete_iax2_peers(), complete_iax2_unregister(), create_addr(), function_iaxpeer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_peer(), handle_cli_iax2_unregister(), iax2_devicestate(), iax2_getpeername(), iax2_getpeertrunk(), iax2_poke_noanswer(), iax2_poke_peer(), manager_iax2_show_peer_list(), peers_data_provider_get(), poke_all_peers(), prune_peers(), realtime_peer(), reg_source_db(), register_verify(), registry_authrequest(), requirecalltoken_mark_auto(), set_config(), socket_process(), unlink_peer(), and update_registry().
01793 { 01794 ao2_ref(peer, -1); 01795 return NULL; 01796 }
| static int peercnt_add | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2408 of file chan_iax2.c.
References peercnt::addr, iax2_trunk_peer::addr, ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_debug, ast_inet_ntoa(), ast_log(), peercnt::cur, peercnt::limit, LOG_ERROR, OBJ_POINTER, and set_peercnt_limit().
Referenced by __find_callno(), and complete_transfer().
02409 { 02410 struct peercnt *peercnt; 02411 unsigned long addr = sin->sin_addr.s_addr; 02412 int res = 0; 02413 struct peercnt tmp = { 02414 .addr = addr, 02415 }; 02416 02417 /* Reasoning for peercnts container lock: Two identical ip addresses 02418 * could be added by different threads at the "same time". Without the container 02419 * lock, both threads could alloc space for the same object and attempt 02420 * to link to table. With the lock, one would create the object and link 02421 * to table while the other would find the already created peercnt object 02422 * rather than creating a new one. */ 02423 ao2_lock(peercnts); 02424 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02425 ao2_lock(peercnt); 02426 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) { 02427 ao2_lock(peercnt); 02428 /* create and set defaults */ 02429 peercnt->addr = addr; 02430 set_peercnt_limit(peercnt); 02431 /* guarantees it does not go away after unlocking table 02432 * ao2_find automatically adds this */ 02433 ao2_link(peercnts, peercnt); 02434 } else { 02435 ao2_unlock(peercnts); 02436 return -1; 02437 } 02438 02439 /* check to see if the address has hit its callno limit. If not increment cur. */ 02440 if (peercnt->limit > peercnt->cur) { 02441 peercnt->cur++; 02442 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr)); 02443 } else { /* max num call numbers for this peer has been reached! */ 02444 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr)); 02445 res = -1; 02446 } 02447 02448 /* clean up locks and ref count */ 02449 ao2_unlock(peercnt); 02450 ao2_unlock(peercnts); 02451 ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */ 02452 02453 return res; 02454 }
| static int peercnt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2238 of file chan_iax2.c.
References peercnt::addr, CMP_MATCH, and CMP_STOP.
Referenced by load_objects().
02239 { 02240 struct peercnt *peercnt1 = obj, *peercnt2 = arg; 02241 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0; 02242 }
| static int peercnt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 2232 of file chan_iax2.c.
References peercnt::addr.
Referenced by load_objects().
| static void peercnt_modify | ( | unsigned char | reg, | |
| uint16_t | limit, | |||
| struct ast_sockaddr * | sockaddr | |||
| ) | [static] |
Definition at line 2375 of file chan_iax2.c.
References peercnt::addr, ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), ast_sockaddr_to_sin, peercnt::limit, OBJ_POINTER, peercnt::reg, and set_peercnt_limit().
Referenced by __expire_registry(), build_peer(), and update_registry().
02376 { 02377 /* this function turns off and on custom callno limits set by peer registration */ 02378 struct peercnt *peercnt; 02379 struct peercnt tmp = { 02380 .addr = 0, 02381 }; 02382 struct sockaddr_in sin; 02383 02384 ast_sockaddr_to_sin(sockaddr, &sin); 02385 02386 tmp.addr = sin.sin_addr.s_addr; 02387 02388 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02389 peercnt->reg = reg; 02390 if (limit) { 02391 peercnt->limit = limit; 02392 } else { 02393 set_peercnt_limit(peercnt); 02394 } 02395 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg); 02396 ao2_ref(peercnt, -1); /* decrement ref from find */ 02397 } 02398 }
| static void peercnt_remove | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2460 of file chan_iax2.c.
References peercnt::addr, ao2_lock, ao2_unlink, ao2_unlock, ast_debug, ast_inet_ntoa(), and peercnt::cur.
Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().
02461 { 02462 struct sockaddr_in sin = { 02463 .sin_addr.s_addr = peercnt->addr, 02464 }; 02465 02466 if (peercnt) { 02467 /* Container locked here since peercnt may be unlinked from list. If left unlocked, 02468 * peercnt_add could try and grab this entry from the table and modify it at the 02469 * "same time" this thread attemps to unlink it.*/ 02470 ao2_lock(peercnts); 02471 peercnt->cur--; 02472 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr)); 02473 /* if this was the last connection from the peer remove it from table */ 02474 if (peercnt->cur == 0) { 02475 ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */ 02476 } 02477 ao2_unlock(peercnts); 02478 } 02479 }
| static int peercnt_remove_by_addr | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2499 of file chan_iax2.c.
References peercnt::addr, ao2_find, ao2_ref, OBJ_POINTER, and peercnt_remove().
Referenced by __find_callno(), and complete_transfer().
02500 { 02501 struct peercnt *peercnt; 02502 struct peercnt tmp = { 02503 .addr = sin->sin_addr.s_addr, 02504 }; 02505 02506 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02507 peercnt_remove(peercnt); 02508 ao2_ref(peercnt, -1); /* decrement ref from find */ 02509 } 02510 return 0; 02511 }
| static int peercnt_remove_cb | ( | const void * | obj | ) | [static] |
Definition at line 2485 of file chan_iax2.c.
References ao2_ref, and peercnt_remove().
Referenced by sched_delay_remove().
02486 { 02487 struct peercnt *peercnt = (struct peercnt *) obj; 02488 02489 peercnt_remove(peercnt); 02490 ao2_ref(peercnt, -1); /* decrement ref from scheduler */ 02491 02492 return 0; 02493 }
| static int peers_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 14609 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_data_add_bool(), ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_inet_ntoa(), ast_sockaddr_port, ast_sockaddr_stringify_host(), ast_str_alloca, ast_str_buffer(), ast_test_flag64, iax2_peer::capability, iax2_peer::encmethods, encmethods_to_str(), iax2_data_add_codecs(), IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, peer_status(), peer_unref(), and status.
14611 { 14612 struct ast_data *data_peer; 14613 struct iax2_peer *peer; 14614 struct ao2_iterator i; 14615 char status[20]; 14616 struct ast_str *encmethods = ast_str_alloca(256); 14617 14618 i = ao2_iterator_init(peers, 0); 14619 while ((peer = ao2_iterator_next(&i))) { 14620 data_peer = ast_data_add_node(data_root, "peer"); 14621 if (!data_peer) { 14622 peer_unref(peer); 14623 continue; 14624 } 14625 14626 ast_data_add_structure(iax2_peer, data_peer, peer); 14627 14628 iax2_data_add_codecs(data_peer, "codecs", peer->capability); 14629 14630 peer_status(peer, status, sizeof(status)); 14631 ast_data_add_str(data_peer, "status", status); 14632 14633 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr)); 14634 14635 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask)); 14636 14637 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr)); 14638 14639 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK)); 14640 14641 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC)); 14642 14643 encmethods_to_str(peer->encmethods, encmethods); 14644 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no"); 14645 14646 peer_unref(peer); 14647 14648 if (!ast_data_search_match(search, data_peer)) { 14649 ast_data_remove_node(data_root, data_peer); 14650 } 14651 } 14652 ao2_iterator_destroy(&i); 14653 14654 return 0; 14655 }
| static void poke_all_peers | ( | void | ) | [static] |
Definition at line 13562 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, iax2_poke_peer(), and peer_unref().
Referenced by reload_config().
13563 { 13564 struct ao2_iterator i; 13565 struct iax2_peer *peer; 13566 13567 i = ao2_iterator_init(peers, 0); 13568 while ((peer = ao2_iterator_next(&i))) { 13569 iax2_poke_peer(peer, 0); 13570 peer_unref(peer); 13571 } 13572 ao2_iterator_destroy(&i); 13573 }
| static int prune_addr_range_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2364 of file chan_iax2.c.
References CMP_MATCH, and addr_range::delme.
Referenced by reload_config().
02365 { 02366 struct addr_range *addr_range = obj; 02367 02368 return addr_range->delme ? CMP_MATCH : 0; 02369 }
| static void prune_peers | ( | void | ) | [static] |
Definition at line 13059 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_test_flag64, IAX_DELME, IAX_RTCACHEFRIENDS, peer_unref(), and unlink_peer().
13060 { 13061 struct iax2_peer *peer; 13062 struct ao2_iterator i; 13063 13064 i = ao2_iterator_init(peers, 0); 13065 while ((peer = ao2_iterator_next(&i))) { 13066 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 13067 unlink_peer(peer); 13068 } 13069 peer_unref(peer); 13070 } 13071 ao2_iterator_destroy(&i); 13072 }
| static void prune_users | ( | void | ) | [static] |
Definition at line 13043 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_unlink, ast_test_flag64, IAX_DELME, IAX_RTCACHEFRIENDS, and user_unref().
Referenced by handle_cli_iax2_prune_realtime(), and reload_config().
13044 { 13045 struct iax2_user *user; 13046 struct ao2_iterator i; 13047 13048 i = ao2_iterator_init(users, 0); 13049 while ((user = ao2_iterator_next(&i))) { 13050 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 13051 ao2_unlink(users, user); 13052 } 13053 user_unref(user); 13054 } 13055 ao2_iterator_destroy(&i); 13056 }
| static int pvt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 14492 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().
14493 { 14494 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14495 14496 /* The frames_received field is used to hold whether we're matching 14497 * against a full frame or not ... */ 14498 14499 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 14500 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14501 }
| static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1942 of file chan_iax2.c.
References chan_iax2_pvt::addr, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, ast_mutex_lock, ast_mutex_unlock, ast_set_flag64, ast_string_field_free_memory, ast_variables_destroy(), iax2_registry::callno, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, jb_frame::data, frame_queue, free_signaling_queue_entry(), iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, sched_delay_remove(), chan_iax2_pvt::signaling_queue, and chan_iax2_pvt::vars.
01943 { 01944 struct chan_iax2_pvt *pvt = obj; 01945 struct iax_frame *cur = NULL; 01946 struct signaling_queue_entry *s = NULL; 01947 01948 ast_mutex_lock(&iaxsl[pvt->callno]); 01949 01950 iax2_destroy_helper(pvt); 01951 01952 sched_delay_remove(&pvt->addr, pvt->callno_entry); 01953 pvt->callno_entry = NULL; 01954 01955 /* Already gone */ 01956 ast_set_flag64(pvt, IAX_ALREADYGONE); 01957 01958 AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) { 01959 /* Cancel any pending transmissions */ 01960 cur->retries = -1; 01961 } 01962 01963 ast_mutex_unlock(&iaxsl[pvt->callno]); 01964 01965 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01966 free_signaling_queue_entry(s); 01967 } 01968 01969 if (pvt->reg) { 01970 pvt->reg->callno = 0; 01971 } 01972 01973 if (!pvt->owner) { 01974 jb_frame frame; 01975 if (pvt->vars) { 01976 ast_variables_destroy(pvt->vars); 01977 pvt->vars = NULL; 01978 } 01979 01980 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01981 iax2_frame_free(frame.data); 01982 } 01983 01984 jb_destroy(pvt->jb); 01985 ast_string_field_free_memory(pvt); 01986 } 01987 }
| static int pvt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 14485 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
14486 { 14487 const struct chan_iax2_pvt *pvt = obj; 14488 14489 return pvt->peercallno; 14490 }
| static int queue_signalling | ( | struct chan_iax2_pvt * | pvt, | |
| struct ast_frame * | f | |||
| ) | [static] |
All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number.
Definition at line 1918 of file chan_iax2.c.
References ast_calloc, AST_FRAME_IAX, AST_LIST_INSERT_TAIL, ast_frame::data, ast_frame::frametype, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, ast_frame::ptr, and chan_iax2_pvt::signaling_queue.
Referenced by __send_command().
01919 { 01920 struct signaling_queue_entry *new; 01921 01922 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) { 01923 return 1; /* do not queue this frame */ 01924 } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) { 01925 return -1; /* out of memory */ 01926 } 01927 01928 memcpy(&new->f, f, sizeof(new->f)); /* copy ast_frame into our queue entry */ 01929 01930 if (new->f.datalen) { /* if there is data in this frame copy it over as well */ 01931 if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) { 01932 free_signaling_queue_entry(new); 01933 return -1; 01934 } 01935 memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr)); 01936 } 01937 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next); 01938 01939 return 0; 01940 }
| static int raw_hangup | ( | struct sockaddr_in * | sin, | |
| unsigned short | src, | |||
| unsigned short | dst, | |||
| int | sockfd | |||
| ) | [static] |
Definition at line 7838 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_inet_ntoa(), compress_subclass(), ast_iax2_full_hdr::csub, ast_iax2_full_hdr::dcallno, IAX_COMMAND_INVAL, IAX_FLAG_FULL, iax_outputframe(), ast_iax2_full_hdr::iseqno, ast_iax2_full_hdr::oseqno, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type.
Referenced by socket_process().
07839 { 07840 struct ast_iax2_full_hdr fh; 07841 fh.scallno = htons(src | IAX_FLAG_FULL); 07842 fh.dcallno = htons(dst); 07843 fh.ts = 0; 07844 fh.oseqno = 0; 07845 fh.iseqno = 0; 07846 fh.type = AST_FRAME_IAX; 07847 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 07848 iax_outputframe(NULL, &fh, 0, sin, 0); 07849 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n", 07850 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 07851 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 07852 }
| static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
| struct sockaddr_in * | sin | |||
| ) | [static, read] |
Definition at line 4385 of file chan_iax2.c.
References iax2_peer::addr, ao2_link, ast_copy_flags64, ast_debug, ast_get_time_t(), ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), AST_SCHED_DEL, ast_set_flag64, ast_sockaddr_parse(), ast_sockaddr_set_port, ast_test_flag64, ast_variables_destroy(), build_peer(), iax2_peer::expire, expire_registry(), hp, iax2_sched_add(), IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_TEMPONLY, iax2_peer::name, ast_variable::name, ast_variable::next, PARSE_PORT_IGNORE, peer_ref(), peer_unref(), realtime_update_peer(), reg_source_db(), SENTINEL, ast_variable::value, and var.
04386 { 04387 struct ast_variable *var = NULL; 04388 struct ast_variable *tmp; 04389 struct iax2_peer *peer=NULL; 04390 time_t regseconds = 0, nowtime; 04391 int dynamic=0; 04392 04393 if (peername) { 04394 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL); 04395 if (!var && sin) 04396 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04397 } else if (sin) { 04398 char porta[25]; 04399 sprintf(porta, "%d", ntohs(sin->sin_port)); 04400 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04401 if (var) { 04402 /* We'll need the peer name in order to build the structure! */ 04403 for (tmp = var; tmp; tmp = tmp->next) { 04404 if (!strcasecmp(tmp->name, "name")) 04405 peername = tmp->value; 04406 } 04407 } 04408 } 04409 if (!var && peername) { /* Last ditch effort */ 04410 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL); 04411 /*!\note 04412 * If this one loaded something, then we need to ensure that the host 04413 * field matched. The only reason why we can't have this as a criteria 04414 * is because we only have the IP address and the host field might be 04415 * set as a name (and the reverse PTR might not match). 04416 */ 04417 if (var && sin) { 04418 for (tmp = var; tmp; tmp = tmp->next) { 04419 if (!strcasecmp(tmp->name, "host")) { 04420 struct ast_hostent ahp; 04421 struct hostent *hp; 04422 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 04423 /* No match */ 04424 ast_variables_destroy(var); 04425 var = NULL; 04426 } 04427 break; 04428 } 04429 } 04430 } 04431 } 04432 if (!var) 04433 return NULL; 04434 04435 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 04436 04437 if (!peer) { 04438 ast_variables_destroy(var); 04439 return NULL; 04440 } 04441 04442 for (tmp = var; tmp; tmp = tmp->next) { 04443 /* Make sure it's not a user only... */ 04444 if (!strcasecmp(tmp->name, "type")) { 04445 if (strcasecmp(tmp->value, "friend") && 04446 strcasecmp(tmp->value, "peer")) { 04447 /* Whoops, we weren't supposed to exist! */ 04448 peer = peer_unref(peer); 04449 break; 04450 } 04451 } else if (!strcasecmp(tmp->name, "regseconds")) { 04452 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 04453 } else if (!strcasecmp(tmp->name, "ipaddr")) { 04454 ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE); 04455 } else if (!strcasecmp(tmp->name, "port")) { 04456 ast_sockaddr_set_port(&peer->addr, atoi(tmp->value)); 04457 } else if (!strcasecmp(tmp->name, "host")) { 04458 if (!strcasecmp(tmp->value, "dynamic")) 04459 dynamic = 1; 04460 } 04461 } 04462 04463 ast_variables_destroy(var); 04464 04465 if (!peer) 04466 return NULL; 04467 04468 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04469 ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 04470 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) { 04471 if (peer->expire > -1) { 04472 if (!AST_SCHED_DEL(sched, peer->expire)) { 04473 peer->expire = -1; 04474 peer_unref(peer); 04475 } 04476 } 04477 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 04478 if (peer->expire == -1) 04479 peer_unref(peer); 04480 } 04481 ao2_link(peers, peer); 04482 if (ast_test_flag64(peer, IAX_DYNAMIC)) 04483 reg_source_db(peer); 04484 } else { 04485 ast_set_flag64(peer, IAX_TEMPONLY); 04486 } 04487 04488 if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 04489 time(&nowtime); 04490 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 04491 memset(&peer->addr, 0, sizeof(peer->addr)); 04492 realtime_update_peer(peer->name, &peer->addr, 0); 04493 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 04494 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04495 } 04496 else { 04497 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 04498 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04499 } 04500 } 04501 04502 return peer; 04503 }
| static void realtime_update_peer | ( | const char * | peername, | |
| struct ast_sockaddr * | sockaddr, | |||
| time_t | regtime | |||
| ) | [static] |
Definition at line 4576 of file chan_iax2.c.
References ast_config_AST_SYSTEM_NAME, ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_strlen_zero(), ast_test_flag64, ast_update_realtime(), IAX_RTSAVE_SYSNAME, and SENTINEL.
Referenced by __expire_registry(), realtime_peer(), update_peer(), and update_registry().
04577 { 04578 char port[10]; 04579 char regseconds[20]; 04580 const char *sysname = ast_config_AST_SYSTEM_NAME; 04581 char *syslabel = NULL; 04582 04583 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 04584 sysname = NULL; 04585 else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME)) 04586 syslabel = "regserver"; 04587 04588 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 04589 snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr)); 04590 ast_update_realtime("iaxpeers", "name", peername, 04591 "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port, 04592 "regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslable can be NULL */ 04593 }
| static struct iax2_user * realtime_user | ( | const char * | username, | |
| struct sockaddr_in * | sin | |||
| ) | [static, read] |
Definition at line 4505 of file chan_iax2.c.
References ao2_link, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_set_flag64, ast_test_flag64, ast_variables_destroy(), build_user(), hp, IAX_RTCACHEFRIENDS, IAX_TEMPONLY, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.
04506 { 04507 struct ast_variable *var; 04508 struct ast_variable *tmp; 04509 struct iax2_user *user=NULL; 04510 04511 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL); 04512 if (!var) 04513 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04514 if (!var && sin) { 04515 char porta[6]; 04516 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 04517 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04518 if (!var) 04519 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04520 } 04521 if (!var) { /* Last ditch effort */ 04522 var = ast_load_realtime("iaxusers", "name", username, SENTINEL); 04523 /*!\note 04524 * If this one loaded something, then we need to ensure that the host 04525 * field matched. The only reason why we can't have this as a criteria 04526 * is because we only have the IP address and the host field might be 04527 * set as a name (and the reverse PTR might not match). 04528 */ 04529 if (var) { 04530 for (tmp = var; tmp; tmp = tmp->next) { 04531 if (!strcasecmp(tmp->name, "host")) { 04532 struct ast_hostent ahp; 04533 struct hostent *hp; 04534 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 04535 /* No match */ 04536 ast_variables_destroy(var); 04537 var = NULL; 04538 } 04539 break; 04540 } 04541 } 04542 } 04543 } 04544 if (!var) 04545 return NULL; 04546 04547 tmp = var; 04548 while(tmp) { 04549 /* Make sure it's not a peer only... */ 04550 if (!strcasecmp(tmp->name, "type")) { 04551 if (strcasecmp(tmp->value, "friend") && 04552 strcasecmp(tmp->value, "user")) { 04553 return NULL; 04554 } 04555 } 04556 tmp = tmp->next; 04557 } 04558 04559 user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)); 04560 04561 ast_variables_destroy(var); 04562 04563 if (!user) 04564 return NULL; 04565 04566 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04567 ast_set_flag64(user, IAX_RTCACHEFRIENDS); 04568 ao2_link(users, user); 04569 } else { 04570 ast_set_flag64(user, IAX_TEMPONLY); 04571 } 04572 04573 return user; 04574 }
| static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 8720 of file chan_iax2.c.
References iax2_peer::addr, ast_db_get(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_log(), AST_SCHED_DEL, ast_sockaddr_parse(), ast_sockaddr_stringify(), ast_test_flag64, ast_verb, iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), IAX_TEMPONLY, LOG_NOTICE, iax2_peer::name, PARSE_PORT_REQUIRE, peer_ref(), peer_unref(), and register_peer_exten().
Referenced by build_peer(), realtime_peer(), set_config(), and temp_peer().
08721 { 08722 char data[80]; 08723 char *expiry; 08724 08725 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) { 08726 return; 08727 } 08728 08729 expiry = strrchr(data, ':'); 08730 if (!expiry) { 08731 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data); 08732 } 08733 *expiry++ = '\0'; 08734 08735 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) { 08736 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data); 08737 return; 08738 } 08739 08740 p->expiry = atoi(expiry); 08741 08742 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name, 08743 ast_sockaddr_stringify(&p->addr), p->expiry); 08744 08745 iax2_poke_peer(p, 0); 08746 if (p->expire > -1) { 08747 if (!AST_SCHED_DEL(sched, p->expire)) { 08748 p->expire = -1; 08749 peer_unref(p); 08750 } 08751 } 08752 08753 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08754 08755 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08756 if (p->expire == -1) { 08757 peer_unref(p); 08758 } 08759 08760 if (iax2_regfunk) { 08761 iax2_regfunk(p->name, 1); 08762 } 08763 08764 register_peer_exten(p, 1); 08765 }
| static void register_peer_exten | ( | struct iax2_peer * | peer, | |
| int | onoff | |||
| ) | [static] |
Definition at line 8635 of file chan_iax2.c.
References ast_add_extension(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr, ast_strdup, ast_strlen_zero(), ext, iax2_peer::name, iax2_peer::regexten, S_OR, and strsep().
Referenced by __expire_registry(), expire_register(), handle_response_peerpoke(), parse_register_contact(), peer_destructor(), reg_source_db(), sip_destroy_peer(), sip_poke_noanswer(), and update_registry().
08636 { 08637 char multi[256]; 08638 char *stringp, *ext; 08639 if (!ast_strlen_zero(regcontext)) { 08640 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 08641 stringp = multi; 08642 while((ext = strsep(&stringp, "&"))) { 08643 if (onoff) { 08644 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 08645 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 08646 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2"); 08647 } else 08648 ast_context_remove_extension(regcontext, ext, 1, NULL); 08649 } 08650 } 08651 }
| static int register_verify | ( | int | callno, | |
| struct sockaddr_in * | sin, | |||
| struct iax_ies * | ies | |||
| ) | [static] |
Verify inbound registration.
Definition at line 8005 of file chan_iax2.c.
References ast_apply_ha(), ast_check_signature(), ast_clear_flag, ast_copy_string(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_inet_ntoa(), ast_key_get(), AST_KEY_PUBLIC, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set_flag, ast_sockaddr_from_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, iax2_peer::authmethods, chan_iax2_pvt::expiry, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, iax2_peer::inkeys, LOG_NOTICE, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_peer::name, iax_ies::password, peer_unref(), iax_ies::refresh, iax_ies::rsa_result, iax2_peer::secret, secret, strsep(), and iax_ies::username.
Referenced by handle_request_register(), and socket_process().
08006 { 08007 char requeststr[256] = ""; 08008 char peer[256] = ""; 08009 char md5secret[256] = ""; 08010 char rsasecret[256] = ""; 08011 char secret[256] = ""; 08012 struct iax2_peer *p = NULL; 08013 struct ast_key *key; 08014 char *keyn; 08015 int x; 08016 int expire = 0; 08017 int res = -1; 08018 struct ast_sockaddr addr; 08019 08020 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08021 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 08022 if (ies->username) 08023 ast_copy_string(peer, ies->username, sizeof(peer)); 08024 if (ies->password) 08025 ast_copy_string(secret, ies->password, sizeof(secret)); 08026 if (ies->md5_result) 08027 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 08028 if (ies->rsa_result) 08029 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 08030 if (ies->refresh) 08031 expire = ies->refresh; 08032 08033 if (ast_strlen_zero(peer)) { 08034 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 08035 return -1; 08036 } 08037 08038 /* SLD: first call to lookup peer during registration */ 08039 ast_mutex_unlock(&iaxsl[callno]); 08040 p = find_peer(peer, 1); 08041 ast_mutex_lock(&iaxsl[callno]); 08042 if (!p || !iaxs[callno]) { 08043 if (iaxs[callno]) { 08044 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 08045 /* Anything, as long as it's non-blank */ 08046 ast_string_field_set(iaxs[callno], secret, "badsecret"); 08047 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 08048 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 08049 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 08050 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 08051 * to be plaintext, indicating it is an authmethod used by other peers on the system. 08052 * 08053 * If none of these cases exist, res will be returned as 0 without authentication indicating 08054 * an AUTHREQ needs to be sent out. */ 08055 08056 if (ast_strlen_zero(iaxs[callno]->challenge) && 08057 !(!ast_strlen_zero(secret) && plaintext)) { 08058 /* by setting res to 0, an REGAUTH will be sent */ 08059 res = 0; 08060 } 08061 } 08062 if (authdebug && !p) 08063 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 08064 goto return_unref; 08065 } 08066 08067 if (!ast_test_flag64(p, IAX_DYNAMIC)) { 08068 if (authdebug) 08069 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 08070 goto return_unref; 08071 } 08072 08073 ast_sockaddr_from_sin(&addr, sin); 08074 if (!ast_apply_ha(p->ha, &addr)) { 08075 if (authdebug) 08076 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 08077 goto return_unref; 08078 } 08079 ast_string_field_set(iaxs[callno], secret, p->secret); 08080 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 08081 /* Check secret against what we have on file */ 08082 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 08083 if (!ast_strlen_zero(p->inkeys)) { 08084 char tmpkeys[256]; 08085 char *stringp=NULL; 08086 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 08087 stringp=tmpkeys; 08088 keyn = strsep(&stringp, ":"); 08089 while(keyn) { 08090 key = ast_key_get(keyn, AST_KEY_PUBLIC); 08091 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 08092 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08093 break; 08094 } else if (!key) 08095 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 08096 keyn = strsep(&stringp, ":"); 08097 } 08098 if (!keyn) { 08099 if (authdebug) 08100 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 08101 goto return_unref; 08102 } 08103 } else { 08104 if (authdebug) 08105 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 08106 goto return_unref; 08107 } 08108 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 08109 struct MD5Context md5; 08110 unsigned char digest[16]; 08111 char *tmppw, *stringp; 08112 08113 tmppw = ast_strdupa(p->secret); 08114 stringp = tmppw; 08115 while((tmppw = strsep(&stringp, ";"))) { 08116 MD5Init(&md5); 08117 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 08118 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 08119 MD5Final(digest, &md5); 08120 for (x=0;x<16;x++) 08121 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 08122 if (!strcasecmp(requeststr, md5secret)) 08123 break; 08124 } 08125 if (tmppw) { 08126 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08127 } else { 08128 if (authdebug) 08129 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 08130 goto return_unref; 08131 } 08132 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 08133 /* They've provided a plain text password and we support that */ 08134 if (strcmp(secret, p->secret)) { 08135 if (authdebug) 08136 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 08137 goto return_unref; 08138 } else 08139 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08140 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 08141 /* if challenge has been sent, but no challenge response if given, reject. */ 08142 goto return_unref; 08143 } 08144 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08145 08146 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 08147 res = 0; 08148 08149 return_unref: 08150 if (iaxs[callno]) { 08151 ast_string_field_set(iaxs[callno], peer, peer); 08152 08153 /* Choose lowest expiry number */ 08154 if (expire && (expire < iaxs[callno]->expiry)) { 08155 iaxs[callno]->expiry = expire; 08156 } 08157 } 08158 08159 if (p) { 08160 peer_unref(p); 08161 } 08162 return res; 08163 }
| static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 8941 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_strdupa, ast_string_field_set, chan_iax2_pvt::authmethods, iax2_peer::authmethods, iax_ie_data::buf, find_peer(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_COMMAND_REGAUTH, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CHALLENGE, IAX_IE_USERNAME, peer_unref(), iax_ie_data::pos, and send_command().
Referenced by socket_process().
08942 { 08943 struct iax_ie_data ied; 08944 struct iax2_peer *p; 08945 char challenge[10]; 08946 const char *peer_name; 08947 int sentauthmethod; 08948 08949 peer_name = ast_strdupa(iaxs[callno]->peer); 08950 08951 /* SLD: third call to find_peer in registration */ 08952 ast_mutex_unlock(&iaxsl[callno]); 08953 if ((p = find_peer(peer_name, 1))) { 08954 last_authmethod = p->authmethods; 08955 } 08956 08957 ast_mutex_lock(&iaxsl[callno]); 08958 if (!iaxs[callno]) 08959 goto return_unref; 08960 08961 memset(&ied, 0, sizeof(ied)); 08962 /* The selection of which delayed reject is sent may leak information, 08963 * if it sets a static response. For example, if a host is known to only 08964 * use MD5 authentication, then an RSA response would indicate that the 08965 * peer does not exist, and vice-versa. 08966 * Therefore, we use whatever the last peer used (which may vary over the 08967 * course of a server, which should leak minimal information). */ 08968 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 08969 if (!p) { 08970 iaxs[callno]->authmethods = sentauthmethod; 08971 } 08972 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 08973 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 08974 /* Build the challenge */ 08975 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 08976 ast_string_field_set(iaxs[callno], challenge, challenge); 08977 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 08978 } 08979 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 08980 08981 return_unref: 08982 if (p) { 08983 peer_unref(p); 08984 } 08985 08986 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 08987 }
| static int registry_rerequest | ( | struct iax_ies * | ies, | |
| int | callno, | |||
| struct sockaddr_in * | sin | |||
| ) | [static] |
Definition at line 8989 of file chan_iax2.c.
References add_empty_calltoken_ie(), iax2_registry::addr, ast_copy_string(), AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_sockaddr_to_sin, ast_strlen_zero(), authenticate(), iax_ies::authmethods, iax_ie_data::buf, iax_ies::challenge, IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, REG_STATE_NOAUTH, iax2_registry::regstate, iax2_registry::secret, send_command(), iax2_registry::username, and iax_ies::username.
Referenced by socket_process().
08990 { 08991 struct iax2_registry *reg; 08992 /* Start pessimistic */ 08993 struct iax_ie_data ied; 08994 char peer[256] = ""; 08995 char challenge[256] = ""; 08996 int res; 08997 int authmethods = 0; 08998 if (ies->authmethods) 08999 authmethods = ies->authmethods; 09000 if (ies->username) 09001 ast_copy_string(peer, ies->username, sizeof(peer)); 09002 if (ies->challenge) 09003 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 09004 memset(&ied, 0, sizeof(ied)); 09005 reg = iaxs[callno]->reg; 09006 if (reg) { 09007 struct sockaddr_in reg_addr; 09008 09009 ast_sockaddr_to_sin(®->addr, ®_addr); 09010 09011 if (inaddrcmp(®_addr, sin)) { 09012 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 09013 return -1; 09014 } 09015 if (ast_strlen_zero(reg->secret)) { 09016 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 09017 reg->regstate = REG_STATE_NOAUTH; 09018 return -1; 09019 } 09020 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 09021 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 09022 if (reg->secret[0] == '[') { 09023 char tmpkey[256]; 09024 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 09025 tmpkey[strlen(tmpkey) - 1] = '\0'; 09026 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL); 09027 } else 09028 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL); 09029 if (!res) { 09030 reg->regstate = REG_STATE_AUTHSENT; 09031 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 09032 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 09033 } else 09034 return -1; 09035 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 09036 } else 09037 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 09038 return -1; 09039 }
| static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 7122 of file chan_iax2.c.
References REG_STATE_AUTHSENT, REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.
Referenced by handle_cli_iax2_show_registry(), handle_response_register(), manager_iax2_show_registry(), manager_show_registry(), sip_reg_timeout(), and sip_show_registry().
07123 { 07124 switch(regstate) { 07125 case REG_STATE_UNREGISTERED: 07126 return "Unregistered"; 07127 case REG_STATE_REGSENT: 07128 return "Request Sent"; 07129 case REG_STATE_AUTHSENT: 07130 return "Auth. Sent"; 07131 case REG_STATE_REGISTERED: 07132 return "Registered"; 07133 case REG_STATE_REJECTED: 07134 return "Rejected"; 07135 case REG_STATE_TIMEOUT: 07136 return "Timeout"; 07137 case REG_STATE_NOAUTH: 07138 return "No Authentication"; 07139 default: 07140 return "Unknown"; 07141 } 07142 }
| static int reload | ( | void | ) | [static] |
Definition at line 13623 of file chan_iax2.c.
References reload_config().
13624 { 13625 return reload_config(); 13626 }
| static int reload_config | ( | void | ) | [static] |
Definition at line 13574 of file chan_iax2.c.
References ao2_callback, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_unload_realtime(), config, debugaddr, iax2_do_register(), iax_provision_reload(), OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, poke_all_peers(), prune_addr_range_cb(), prune_peers(), prune_users(), reload_firmware(), set_config(), and set_peercnt_limit_all_cb().
13575 { 13576 static const char config[] = "iax.conf"; 13577 struct iax2_registry *reg; 13578 13579 if (set_config(config, 1) > 0) { 13580 prune_peers(); 13581 prune_users(); 13582 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13583 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13584 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL); 13585 trunk_timed = trunk_untimed = 0; 13586 trunk_nmaxmtu = trunk_maxmtu = 0; 13587 memset(&debugaddr, '\0', sizeof(debugaddr)); 13588 13589 AST_LIST_LOCK(®istrations); 13590 AST_LIST_TRAVERSE(®istrations, reg, entry) 13591 iax2_do_register(reg); 13592 AST_LIST_UNLOCK(®istrations); 13593 13594 /* Qualify hosts, too */ 13595 poke_all_peers(); 13596 } 13597 13598 reload_firmware(0); 13599 iax_provision_reload(1); 13600 ast_unload_realtime("iaxpeers"); 13601 13602 return 0; 13603 }
| static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 3277 of file chan_iax2.c.
References ast_config_AST_DATA_DIR, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verb, iax_firmware::dead, destroy_firmware(), errno, LOG_WARNING, and try_firmware().
Referenced by __unload_module(), load_module(), and reload_config().
03278 { 03279 struct iax_firmware *cur = NULL; 03280 DIR *fwd; 03281 struct dirent *de; 03282 char dir[256], fn[256]; 03283 03284 AST_LIST_LOCK(&firmwares); 03285 03286 /* Mark all as dead */ 03287 AST_LIST_TRAVERSE(&firmwares, cur, list) 03288 cur->dead = 1; 03289 03290 /* Now that we have marked them dead... load new ones */ 03291 if (!unload) { 03292 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR); 03293 fwd = opendir(dir); 03294 if (fwd) { 03295 while((de = readdir(fwd))) { 03296 if (de->d_name[0] != '.') { 03297 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 03298 if (!try_firmware(fn)) { 03299 ast_verb(2, "Loaded firmware '%s'\n", de->d_name); 03300 } 03301 } 03302 } 03303 closedir(fwd); 03304 } else 03305 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 03306 } 03307 03308 /* Clean up leftovers */ 03309 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) { 03310 if (!cur->dead) 03311 continue; 03312 AST_LIST_REMOVE_CURRENT(list); 03313 destroy_firmware(cur); 03314 } 03315 AST_LIST_TRAVERSE_SAFE_END; 03316 03317 AST_LIST_UNLOCK(&firmwares); 03318 }
| static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2199 of file chan_iax2.c.
References ao2_unlink, ast_log(), LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by complete_transfer(), iax2_destroy(), resend_with_token(), and socket_process().
02200 { 02201 if (!pvt->peercallno) { 02202 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 02203 return; 02204 } 02205 02206 ao2_unlink(iax_peercallno_pvts, pvt); 02207 }
| static void remove_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2180 of file chan_iax2.c.
References ao2_unlink, ast_log(), LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by complete_transfer(), and iax2_destroy().
02181 { 02182 if (!pvt->transfercallno) { 02183 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 02184 return; 02185 } 02186 02187 ao2_unlink(iax_transfercallno_pvts, pvt); 02188 }
| static int replace_callno | ( | const void * | obj | ) | [static] |
Definition at line 2709 of file chan_iax2.c.
References ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_log(), callno_entry::callno, LOG_ERROR, TRUNK_CALL_START, and callno_entry::validated.
Referenced by __find_callno(), make_trunk(), and sched_delay_remove().
02710 { 02711 struct callno_entry *callno_entry = (struct callno_entry *) obj; 02712 02713 /* the callno_pool container is locked here primarily to ensure thread 02714 * safety of the total_nonval_callno_used check and decrement */ 02715 ao2_lock(callno_pool); 02716 02717 if (!callno_entry->validated && (total_nonval_callno_used != 0)) { 02718 total_nonval_callno_used--; 02719 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) { 02720 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno); 02721 } 02722 02723 if (callno_entry->callno < TRUNK_CALL_START) { 02724 ao2_link(callno_pool, callno_entry); 02725 } else { 02726 ao2_link(callno_pool_trunk, callno_entry); 02727 } 02728 ao2_ref(callno_entry, -1); /* only container ref remains */ 02729 02730 ao2_unlock(callno_pool); 02731 return 0; 02732 }
| static void requirecalltoken_mark_auto | ( | const char * | name, | |
| int | subclass | |||
| ) | [static] |
Definition at line 4894 of file chan_iax2.c.
References ast_strlen_zero(), CALLTOKEN_AUTO, iax2_peer::calltoken_required, iax2_user::calltoken_required, CALLTOKEN_YES, find_peer(), find_user(), IAX_COMMAND_NEW, peer_unref(), and user_unref().
Referenced by handle_call_token().
04895 { 04896 struct iax2_user *user = NULL; 04897 struct iax2_peer *peer = NULL; 04898 04899 if (ast_strlen_zero(name)) { 04900 return; /* no username given */ 04901 } 04902 04903 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) { 04904 user->calltoken_required = CALLTOKEN_YES; 04905 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) { 04906 peer->calltoken_required = CALLTOKEN_YES; 04907 } 04908 04909 if (peer) { 04910 peer_unref(peer); 04911 } 04912 if (user) { 04913 user_unref(user); 04914 } 04915 }
| static void resend_with_token | ( | int | callno, | |
| struct iax_frame * | f, | |||
| const char * | newtoken | |||
| ) | [static] |
Definition at line 4812 of file chan_iax2.c.
References iax_frame::af, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_LIST_REMOVE, iax_ie_data::buf, chan_iax2_pvt::calltoken_ie_len, iax_frame::data, iax_frame::datalen, iax_frame::dcallno, iax_frame::encmethods, frame_queue, ast_frame::frametype, iax2_allow_new(), iax2_frame_free(), iax_ie_append_str(), IAX_IE_CALLTOKEN, ast_frame_subclass::integer, chan_iax2_pvt::iseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, remove_by_peercallno(), chan_iax2_pvt::rseqno, send_command(), and ast_frame::subclass.
Referenced by socket_process().
04813 { 04814 struct chan_iax2_pvt *pvt = iaxs[callno]; 04815 int frametype = f->af.frametype; 04816 int subclass = f->af.subclass.integer; 04817 struct { 04818 struct ast_iax2_full_hdr fh; 04819 struct iax_ie_data ied; 04820 } data = { 04821 .ied.buf = { 0 }, 04822 .ied.pos = 0, 04823 }; 04824 /* total len - header len gives us the frame's IE len */ 04825 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr); 04826 04827 if (!pvt) { 04828 return; /* this should not be possible if called from socket_process() */ 04829 } 04830 04831 /* 04832 * Check to make sure last frame sent is valid for call token resend 04833 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 04834 * 2. Frame should _NOT_ already have a destination callno 04835 * 3. Frame must be a valid iax_frame subclass capable of starting dialog 04836 * 4. Pvt must have a calltoken_ie_len which represents the number of 04837 * bytes at the end of the frame used for the previous calltoken ie. 04838 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length 04839 * 6. Total length of f->data must be _LESS_ than size of our data struct 04840 * because f->data must be able to fit within data. 04841 */ 04842 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0) 04843 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) || 04844 (f->datalen > sizeof(data))) { 04845 04846 return; /* ignore resend, token was not valid for the dialog */ 04847 } 04848 04849 /* token is valid 04850 * 1. Copy frame data over 04851 * 2. Redo calltoken IE, it will always be the last ie in the frame. 04852 * NOTE: Having the ie always be last is not protocol specified, 04853 * it is only an implementation choice. Since we only expect the ie to 04854 * be last for frames we have sent, this can no way be affected by 04855 * another end point. 04856 * 3. Remove frame from queue 04857 * 4. Free old frame 04858 * 5. Clear previous seqnos 04859 * 6. Resend with CALLTOKEN ie. 04860 */ 04861 04862 /* ---1.--- */ 04863 memcpy(&data, f->data, f->datalen); 04864 data.ied.pos = ie_data_pos; 04865 04866 /* ---2.--- */ 04867 /* move to the beginning of the calltoken ie so we can write over it */ 04868 data.ied.pos -= pvt->calltoken_ie_len; 04869 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken); 04870 04871 /* make sure to update token length incase it ever has to be stripped off again */ 04872 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */ 04873 04874 /* ---3.--- */ 04875 AST_LIST_REMOVE(&frame_queue[callno], f, list); 04876 04877 /* ---4.--- */ 04878 iax2_frame_free(f); 04879 04880 /* ---5.--- */ 04881 pvt->oseqno = 0; 04882 pvt->rseqno = 0; 04883 pvt->iseqno = 0; 04884 pvt->aseqno = 0; 04885 if (pvt->peercallno) { 04886 remove_by_peercallno(pvt); 04887 pvt->peercallno = 0; 04888 } 04889 04890 /* ---6.--- */ 04891 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1); 04892 }
Definition at line 9516 of file chan_iax2.c.
References ast_string_field_set, iax_frame::callno, IAX_MAX_OSPBLOCK_NUM, IAX_MAX_OSPBLOCK_SIZE, IAX_MAX_OSPBUFF_SIZE, iax_ies::ospblocklength, and iax_ies::osptokenblock.
Referenced by socket_process().
09517 { 09518 int i; 09519 unsigned int length, offset = 0; 09520 char full_osptoken[IAX_MAX_OSPBUFF_SIZE]; 09521 09522 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) { 09523 length = ies->ospblocklength[i]; 09524 if (length != 0) { 09525 if (length > IAX_MAX_OSPBLOCK_SIZE) { 09526 /* OSP token block length wrong, clear buffer */ 09527 offset = 0; 09528 break; 09529 } else { 09530 memcpy(full_osptoken + offset, ies->osptokenblock[i], length); 09531 offset += length; 09532 } 09533 } else { 09534 break; 09535 } 09536 } 09537 *(full_osptoken + offset) = '\0'; 09538 if (strlen(full_osptoken) != offset) { 09539 /* OSP token length wrong, clear buffer */ 09540 *full_osptoken = '\0'; 09541 } 09542 09543 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken); 09544 }
Definition at line 9505 of file chan_iax2.c.
References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iax_rr::jitter, iax_rr::losscnt, iax_rr::losspct, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::remote_rr, iax_ies::rr_delay, iax_ies::rr_dropped, iax_ies::rr_jitter, iax_ies::rr_loss, iax_ies::rr_ooo, and iax_ies::rr_pkts.
Referenced by socket_process().
09506 { 09507 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 09508 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 09509 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 09510 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 09511 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 09512 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 09513 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 09514 }
| static void sched_delay_remove | ( | struct sockaddr_in * | sin, | |
| struct callno_entry * | callno_entry | |||
| ) | [static] |
Definition at line 2781 of file chan_iax2.c.
References peercnt::addr, ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), iax2_sched_add(), MIN_REUSE_TIME, OBJ_POINTER, peercnt_remove_cb(), and replace_callno().
Referenced by pvt_destructor().
02782 { 02783 int i; 02784 struct peercnt *peercnt; 02785 struct peercnt tmp = { 02786 .addr = sin->sin_addr.s_addr, 02787 }; 02788 02789 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02790 /* refcount is incremented with ao2_find. keep that ref for the scheduler */ 02791 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME); 02792 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt); 02793 if (i == -1) { 02794 ao2_ref(peercnt, -1); 02795 } 02796 } 02797 02798 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry); 02799 }
| static int schedule_delivery | ( | struct iax_frame * | fr, | |
| int | updatehistory, | |||
| int | fromtrunk, | |||
| unsigned int * | tsout | |||
| ) | [static] |
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it.
Definition at line 4213 of file chan_iax2.c.
References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_channel_unlock, ast_codec_get_samples(), ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_samp2tv(), AST_SCHED_DEL, ast_test_flag64, ast_tv(), ast_tvadd(), ast_tvzero(), ast_channel::bridge, calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame_subclass::format, ast_frame::frametype, iax2_frame_free(), iax2_lock_owner(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, chan_iax2_pvt::jb, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, chan_iax2_pvt::jbid, chan_iax2_pvt::owner, ast_channel_tech::properties, chan_iax2_pvt::rxcore, ast_frame::subclass, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process(), and socket_process_meta().
04214 { 04215 int type, len; 04216 int ret; 04217 int needfree = 0; 04218 struct ast_channel *owner = NULL; 04219 struct ast_channel *bridge = NULL; 04220 04221 /* Attempt to recover wrapped timestamps */ 04222 unwrap_timestamp(fr); 04223 04224 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 04225 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 04226 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 04227 else { 04228 #if 0 04229 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 04230 #endif 04231 fr->af.delivery = ast_tv(0,0); 04232 } 04233 04234 type = JB_TYPE_CONTROL; 04235 len = 0; 04236 04237 if(fr->af.frametype == AST_FRAME_VOICE) { 04238 type = JB_TYPE_VOICE; 04239 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(&fr->af.subclass.format) / 1000); 04240 } else if(fr->af.frametype == AST_FRAME_CNG) { 04241 type = JB_TYPE_SILENCE; 04242 } 04243 04244 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 04245 if (tsout) 04246 *tsout = fr->ts; 04247 __do_deliver(fr); 04248 return -1; 04249 } 04250 04251 iax2_lock_owner(fr->callno); 04252 if (!iaxs[fr->callno]) { 04253 /* The call dissappeared so discard this frame that we could not send. */ 04254 iax2_frame_free(fr); 04255 return -1; 04256 } 04257 if ((owner = iaxs[fr->callno]->owner)) 04258 bridge = ast_bridged_channel(owner); 04259 04260 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 04261 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 04262 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 04263 jb_frame frame; 04264 04265 ast_channel_unlock(owner); 04266 04267 /* deliver any frames in the jb */ 04268 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 04269 __do_deliver(frame.data); 04270 /* __do_deliver() can make the call disappear */ 04271 if (!iaxs[fr->callno]) 04272 return -1; 04273 } 04274 04275 jb_reset(iaxs[fr->callno]->jb); 04276 04277 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid); 04278 04279 /* deliver this frame now */ 04280 if (tsout) 04281 *tsout = fr->ts; 04282 __do_deliver(fr); 04283 return -1; 04284 } 04285 if (owner) { 04286 ast_channel_unlock(owner); 04287 } 04288 04289 /* insert into jitterbuffer */ 04290 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 04291 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 04292 calc_rxstamp(iaxs[fr->callno],fr->ts)); 04293 if (ret == JB_DROP) { 04294 needfree++; 04295 } else if (ret == JB_SCHED) { 04296 update_jbsched(iaxs[fr->callno]); 04297 } 04298 if (tsout) 04299 *tsout = fr->ts; 04300 if (needfree) { 04301 /* Free our iax frame */ 04302 iax2_frame_free(fr); 04303 return -1; 04304 } 04305 return 0; 04306 }
| static int scheduled_destroy | ( | const void * | vid | ) | [static] |
Definition at line 1883 of file chan_iax2.c.
References ast_debug, ast_mutex_lock, ast_mutex_unlock, iax2_destroy(), and PTR_TO_CALLNO.
Referenced by iax2_hangup().
01884 { 01885 unsigned short callno = PTR_TO_CALLNO(vid); 01886 ast_mutex_lock(&iaxsl[callno]); 01887 if (iaxs[callno]) { 01888 ast_debug(1, "Really destroying %d now...\n", callno); 01889 iax2_destroy(callno); 01890 } 01891 ast_mutex_unlock(&iaxsl[callno]); 01892 return 0; 01893 }
| static int send_apathetic_reply | ( | unsigned short | callno, | |
| unsigned short | dcallno, | |||
| struct sockaddr_in * | sin, | |||
| int | command, | |||
| int | ts, | |||
| unsigned char | seqno, | |||
| int | sockfd, | |||
| struct iax_ie_data * | ied | |||
| ) | [static] |
Definition at line 4776 of file chan_iax2.c.
References AST_FRAME_IAX, iax_ie_data::buf, compress_subclass(), and iax_ie_data::pos.
Referenced by handle_call_token(), and socket_process().
04779 { 04780 struct { 04781 struct ast_iax2_full_hdr f; 04782 struct iax_ie_data ied; 04783 } data; 04784 size_t size = sizeof(struct ast_iax2_full_hdr); 04785 04786 if (ied) { 04787 size += ied->pos; 04788 memcpy(&data.ied, ied->buf, ied->pos); 04789 } 04790 04791 data.f.scallno = htons(0x8000 | callno); 04792 data.f.dcallno = htons(dcallno); 04793 data.f.ts = htonl(ts); 04794 data.f.iseqno = seqno; 04795 data.f.oseqno = 0; 04796 data.f.type = AST_FRAME_IAX; 04797 data.f.csub = compress_subclass(command); 04798 04799 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin)); 04800 }
| static int send_command | ( | struct chan_iax2_pvt * | i, | |
| char | type, | |||
| int | command, | |||
| unsigned int | ts, | |||
| const unsigned char * | data, | |||
| int | datalen, | |||
| int | seqno | |||
| ) | [static] |
Definition at line 7561 of file chan_iax2.c.
References __send_command().
Referenced by __attempt_transmit(), __send_lagrq(), __send_ping(), authenticate_reply(), authenticate_request(), cache_get_callno_locked(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_indicate(), iax2_key_rotate(), iax2_poke_peer(), iax2_provision(), iax2_start_transfer(), registry_authrequest(), registry_rerequest(), resend_with_token(), send_command_locked(), and socket_process().
07562 { 07563 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 07564 }
| static int send_command_final | ( | struct chan_iax2_pvt * | i, | |
| char | type, | |||
| int | command, | |||
| unsigned int | ts, | |||
| const unsigned char * | data, | |||
| int | datalen, | |||
| int | seqno | |||
| ) | [static] |
Definition at line 7580 of file chan_iax2.c.
References __send_command(), chan_iax2_pvt::callno, and iax2_predestroy().
Referenced by __auth_reject(), __auto_hangup(), authenticate_request(), iax2_hangup(), socket_process(), and update_registry().
07581 { 07582 int call_num = i->callno; 07583 /* It is assumed that the callno has already been locked */ 07584 iax2_predestroy(i->callno); 07585 if (!iaxs[call_num]) 07586 return -1; 07587 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 07588 }
| static int send_command_immediate | ( | struct chan_iax2_pvt * | i, | |
| char | type, | |||
| int | command, | |||
| unsigned int | ts, | |||
| const unsigned char * | data, | |||
| int | datalen, | |||
| int | seqno | |||
| ) | [static] |
Definition at line 7590 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
07591 { 07592 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 07593 }
| static int send_command_locked | ( | unsigned short | callno, | |
| char | type, | |||
| int | command, | |||
| unsigned int | ts, | |||
| const unsigned char * | data, | |||
| int | datalen, | |||
| int | seqno | |||
| ) | [static] |
Definition at line 7566 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_unlock, and send_command().
Referenced by iax2_answer(), iax2_digit_begin(), iax2_digit_end(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), and iax2_transfer().
07567 { 07568 int res; 07569 ast_mutex_lock(&iaxsl[callno]); 07570 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 07571 ast_mutex_unlock(&iaxsl[callno]); 07572 return res; 07573 }
| static int send_command_transfer | ( | struct chan_iax2_pvt * | i, | |
| char | type, | |||
| int | command, | |||
| unsigned int | ts, | |||
| const unsigned char * | data, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 7595 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
07596 { 07597 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 07598 }
| static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1589 of file chan_iax2.c.
References __send_lagrq(), ast_mutex_lock, ast_mutex_unlock, iax2_thread::callno, DONT_RESCHEDULE, chan_iax2_pvt::lagid, and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01590 { 01591 int callno = (long) data; 01592 ast_mutex_lock(&iaxsl[callno]); 01593 if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) { 01594 iaxs[callno]->lagid = -1; 01595 } 01596 ast_mutex_unlock(&iaxsl[callno]); 01597 01598 #ifdef SCHED_MULTITHREADED 01599 if (schedule_action(__send_lagrq, data)) 01600 #endif 01601 __send_lagrq(data); 01602 return 0; 01603 }
| static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3390 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax2_trunk_peer::addr, ast_debug, ast_inet_ntoa(), iax_frame::callno, iax_frame::data, iax_frame::datalen, errno, handle_error(), iax_showframe(), chan_iax2_pvt::peercallno, iax2_trunk_peer::sockfd, chan_iax2_pvt::transfer, transfer, iax_frame::transfer, and iax_frame::ts.
Referenced by __attempt_transmit(), iax2_send(), transmit_frame(), and vnak_retransmit().
03391 { 03392 int res; 03393 int callno = f->callno; 03394 03395 /* Don't send if there was an error, but return error instead */ 03396 if (!callno || !iaxs[callno] || iaxs[callno]->error) 03397 return -1; 03398 03399 /* Called with iaxsl held */ 03400 if (iaxdebug) 03401 ast_debug(3, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port)); 03402 03403 if (f->transfer) { 03404 if (iaxdebug) 03405 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03406 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer)); 03407 } else { 03408 if (iaxdebug) 03409 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03410 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr)); 03411 } 03412 if (res < 0) { 03413 if (iaxdebug) 03414 ast_debug(1, "Received error: %s\n", strerror(errno)); 03415 handle_error(); 03416 } else 03417 res = 0; 03418 03419 return res; 03420 }
| static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1522 of file chan_iax2.c.
References __send_ping(), ast_mutex_lock, ast_mutex_unlock, iax2_thread::callno, DONT_RESCHEDULE, chan_iax2_pvt::pingid, and schedule_action.
Referenced by __find_callno(), __send_ping(), do_monitor(), init_phone_step2(), and make_trunk().
01523 { 01524 int callno = (long) data; 01525 ast_mutex_lock(&iaxsl[callno]); 01526 if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) { 01527 iaxs[callno]->pingid = -1; 01528 } 01529 ast_mutex_unlock(&iaxsl[callno]); 01530 01531 #ifdef SCHED_MULTITHREADED 01532 if (schedule_action(__send_ping, data)) 01533 #endif 01534 __send_ping(data); 01535 01536 return 0; 01537 }
| static void send_signaling | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point.
Definition at line 1905 of file chan_iax2.c.
References AST_LIST_REMOVE_HEAD, signaling_queue_entry::f, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, iax2_send(), and chan_iax2_pvt::signaling_queue.
Referenced by socket_process().
01906 { 01907 struct signaling_queue_entry *s = NULL; 01908 01909 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01910 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0); 01911 free_signaling_queue_entry(s); 01912 } 01913 pvt->hold_signaling = 0; 01914 }
| static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
| struct timeval * | now | |||
| ) | [static] |
Definition at line 9173 of file chan_iax2.c.
References iax2_trunk_peer::addr, iax_frame::afdata, ast_debug, ast_inet_ntoa(), ast_test_flag64, calc_txpeerstamp(), iax2_trunk_peer::calls, ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, iax_frame::retrans, iax2_trunk_peer::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, ast_iax2_meta_trunk_hdr::ts, and ast_iax2_meta_hdr::zeros.
Referenced by iax2_trunk_queue(), and timing_read().
09174 { 09175 int res = 0; 09176 struct iax_frame *fr; 09177 struct ast_iax2_meta_hdr *meta; 09178 struct ast_iax2_meta_trunk_hdr *mth; 09179 int calls = 0; 09180 09181 /* Point to frame */ 09182 fr = (struct iax_frame *)tpeer->trunkdata; 09183 /* Point to meta data */ 09184 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 09185 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 09186 if (tpeer->trunkdatalen) { 09187 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 09188 meta->zeros = 0; 09189 meta->metacmd = IAX_META_TRUNK; 09190 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) 09191 meta->cmddata = IAX_META_TRUNK_MINI; 09192 else 09193 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 09194 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 09195 /* And the rest of the ast_iax2 header */ 09196 fr->direction = DIRECTION_OUTGRESS; 09197 fr->retrans = -1; 09198 fr->transfer = 0; 09199 /* Any appropriate call will do */ 09200 fr->data = fr->afdata; 09201 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 09202 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 09203 calls = tpeer->calls; 09204 #if 0 09205 ast_debug(1, "Trunking %d call chunks in %d bytes to %s:%d, ts=%d\n", calls, fr->datalen, ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), ntohl(mth->ts)); 09206 #endif 09207 /* Reset transmit trunk side data */ 09208 tpeer->trunkdatalen = 0; 09209 tpeer->calls = 0; 09210 } 09211 if (res < 0) 09212 return res; 09213 return calls; 09214 }
| static int set_config | ( | const char * | config_file, | |
| int | reload | |||
| ) | [static] |
Load configuration.
Definition at line 13091 of file chan_iax2.c.
References add_calltoken_ignore(), ao2_link, ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, ast_clear_flag64, ast_config_destroy(), ast_config_load, ast_context_find_or_create(), ast_copy_string(), ast_false(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_netsock_bind(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_str2cos(), ast_str2tos(), ast_strlen_zero(), ast_test_flag64, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, build_callno_limits(), build_peer(), build_user(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), iax2_parse_allow_disallow(), iax2_register(), IAX_ALLOWFWDOWNLOAD, IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTSAVE_SYSNAME, IAX_RTUPDATE, IAX_SENDCONNECTEDLINE, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxmaxthreadcount, iaxthreadcount, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_TRUNK_MTU, MAX_TRUNKDATA, ast_variable::name, network_change_event_subscribe(), network_change_event_unsubscribe(), ast_variable::next, peer_unref(), prefs, qos, reg_source_db(), secret, set_config_destroy(), socket_read(), user_unref(), and ast_variable::value.
Referenced by load_module(), reload(), reload_config(), and reload_module().
13092 { 13093 struct ast_config *cfg, *ucfg; 13094 iax2_format capability = iax2_capability; 13095 struct ast_variable *v; 13096 char *cat; 13097 const char *utype; 13098 const char *tosval; 13099 int format; 13100 int portno = IAX_DEFAULT_PORTNO; 13101 int x; 13102 int mtuv; 13103 int subscribe_network_change = 1; 13104 struct iax2_user *user; 13105 struct iax2_peer *peer; 13106 struct ast_netsock *ns; 13107 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 13108 #if 0 13109 static unsigned short int last_port=0; 13110 #endif 13111 13112 cfg = ast_config_load(config_file, config_flags); 13113 13114 if (!cfg) { 13115 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 13116 return -1; 13117 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 13118 ucfg = ast_config_load("users.conf", config_flags); 13119 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) 13120 return 0; 13121 /* Otherwise we need to reread both files */ 13122 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 13123 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) { 13124 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 13125 ast_config_destroy(ucfg); 13126 return 0; 13127 } 13128 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 13129 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 13130 return 0; 13131 } else { /* iax.conf changed, gotta reread users.conf, too */ 13132 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 13133 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 13134 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n"); 13135 ast_config_destroy(cfg); 13136 return 0; 13137 } 13138 } 13139 13140 if (reload) { 13141 set_config_destroy(); 13142 } 13143 13144 /* Reset global codec prefs */ 13145 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 13146 13147 /* Reset Global Flags */ 13148 memset(&globalflags, 0, sizeof(globalflags)); 13149 ast_set_flag64(&globalflags, IAX_RTUPDATE); 13150 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 13151 13152 #ifdef SO_NO_CHECK 13153 nochecksums = 0; 13154 #endif 13155 /* Reset default parking lot */ 13156 default_parkinglot[0] = '\0'; 13157 13158 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 13159 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 13160 global_max_trunk_mtu = MAX_TRUNK_MTU; 13161 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT; 13162 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL; 13163 13164 maxauthreq = 3; 13165 13166 srvlookup = 0; 13167 13168 v = ast_variable_browse(cfg, "general"); 13169 13170 /* Seed initial tos value */ 13171 tosval = ast_variable_retrieve(cfg, "general", "tos"); 13172 if (tosval) { 13173 if (ast_str2tos(tosval, &qos.tos)) 13174 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n"); 13175 } 13176 /* Seed initial cos value */ 13177 tosval = ast_variable_retrieve(cfg, "general", "cos"); 13178 if (tosval) { 13179 if (ast_str2cos(tosval, &qos.cos)) 13180 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n"); 13181 } 13182 while(v) { 13183 if (!strcasecmp(v->name, "bindport")){ 13184 if (reload) 13185 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 13186 else 13187 portno = atoi(v->value); 13188 } else if (!strcasecmp(v->name, "pingtime")) 13189 ping_time = atoi(v->value); 13190 else if (!strcasecmp(v->name, "iaxthreadcount")) { 13191 if (reload) { 13192 if (atoi(v->value) != iaxthreadcount) 13193 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 13194 } else { 13195 iaxthreadcount = atoi(v->value); 13196 if (iaxthreadcount < 1) { 13197 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 13198 iaxthreadcount = 1; 13199 } else if (iaxthreadcount > 256) { 13200 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 13201 iaxthreadcount = 256; 13202 } 13203 } 13204 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 13205 if (reload) { 13206 AST_LIST_LOCK(&dynamic_list); 13207 iaxmaxthreadcount = atoi(v->value); 13208 AST_LIST_UNLOCK(&dynamic_list); 13209 } else { 13210 iaxmaxthreadcount = atoi(v->value); 13211 if (iaxmaxthreadcount < 0) { 13212 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 13213 iaxmaxthreadcount = 0; 13214 } else if (iaxmaxthreadcount > 256) { 13215 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 13216 iaxmaxthreadcount = 256; 13217 } 13218 } 13219 } else if (!strcasecmp(v->name, "nochecksums")) { 13220 #ifdef SO_NO_CHECK 13221 if (ast_true(v->value)) 13222 nochecksums = 1; 13223 else 13224 nochecksums = 0; 13225 #else 13226 if (ast_true(v->value)) 13227 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 13228 #endif 13229 } 13230 else if (!strcasecmp(v->name, "maxjitterbuffer")) 13231 maxjitterbuffer = atoi(v->value); 13232 else if (!strcasecmp(v->name, "resyncthreshold")) 13233 resyncthreshold = atoi(v->value); 13234 else if (!strcasecmp(v->name, "maxjitterinterps")) 13235 maxjitterinterps = atoi(v->value); 13236 else if (!strcasecmp(v->name, "jittertargetextra")) 13237 jittertargetextra = atoi(v->value); 13238 else if (!strcasecmp(v->name, "lagrqtime")) 13239 lagrq_time = atoi(v->value); 13240 else if (!strcasecmp(v->name, "maxregexpire")) 13241 max_reg_expire = atoi(v->value); 13242 else if (!strcasecmp(v->name, "minregexpire")) 13243 min_reg_expire = atoi(v->value); 13244 else if (!strcasecmp(v->name, "bindaddr")) { 13245 if (reload) { 13246 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 13247 } else { 13248 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) { 13249 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 13250 } else { 13251 if (strchr(v->value, ':')) 13252 ast_verb(2, "Binding IAX2 to '%s'\n", v->value); 13253 else 13254 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno); 13255 if (defaultsockfd < 0) 13256 defaultsockfd = ast_netsock_sockfd(ns); 13257 ast_netsock_unref(ns); 13258 } 13259 } 13260 } else if (!strcasecmp(v->name, "authdebug")) { 13261 authdebug = ast_true(v->value); 13262 } else if (!strcasecmp(v->name, "encryption")) { 13263 iax2_encryption |= get_encrypt_methods(v->value); 13264 if (!iax2_encryption) { 13265 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13266 } 13267 } else if (!strcasecmp(v->name, "forceencryption")) { 13268 if (ast_false(v->value)) { 13269 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13270 } else { 13271 iax2_encryption |= get_encrypt_methods(v->value); 13272 if (iax2_encryption) { 13273 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13274 } 13275 } 13276 } else if (!strcasecmp(v->name, "transfer")) { 13277 if (!strcasecmp(v->value, "mediaonly")) { 13278 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 13279 } else if (ast_true(v->value)) { 13280 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 13281 } else 13282 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 13283 } else if (!strcasecmp(v->name, "codecpriority")) { 13284 if(!strcasecmp(v->value, "caller")) 13285 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST); 13286 else if(!strcasecmp(v->value, "disabled")) 13287 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13288 else if(!strcasecmp(v->value, "reqonly")) { 13289 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP); 13290 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13291 } 13292 } else if (!strcasecmp(v->name, "jitterbuffer")) 13293 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 13294 else if (!strcasecmp(v->name, "forcejitterbuffer")) 13295 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 13296 else if (!strcasecmp(v->name, "delayreject")) 13297 delayreject = ast_true(v->value); 13298 else if (!strcasecmp(v->name, "allowfwdownload")) 13299 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 13300 else if (!strcasecmp(v->name, "rtcachefriends")) 13301 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 13302 else if (!strcasecmp(v->name, "rtignoreregexpire")) 13303 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 13304 else if (!strcasecmp(v->name, "rtupdate")) 13305 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE); 13306 else if (!strcasecmp(v->name, "rtsavesysname")) 13307 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME); 13308 else if (!strcasecmp(v->name, "trunktimestamps")) 13309 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 13310 else if (!strcasecmp(v->name, "rtautoclear")) { 13311 int i = atoi(v->value); 13312 if(i > 0) 13313 global_rtautoclear = i; 13314 else 13315 i = 0; 13316 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 13317 } else if (!strcasecmp(v->name, "trunkfreq")) { 13318 trunkfreq = atoi(v->value); 13319 if (trunkfreq < 10) 13320 trunkfreq = 10; 13321 } else if (!strcasecmp(v->name, "trunkmtu")) { 13322 mtuv = atoi(v->value); 13323 if (mtuv == 0 ) 13324 global_max_trunk_mtu = 0; 13325 else if (mtuv >= 172 && mtuv < 4000) 13326 global_max_trunk_mtu = mtuv; 13327 else 13328 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n", 13329 mtuv, v->lineno); 13330 } else if (!strcasecmp(v->name, "trunkmaxsize")) { 13331 trunkmaxsize = atoi(v->value); 13332 if (trunkmaxsize == 0) 13333 trunkmaxsize = MAX_TRUNKDATA; 13334 } else if (!strcasecmp(v->name, "autokill")) { 13335 if (sscanf(v->value, "%30d", &x) == 1) { 13336 if (x >= 0) 13337 autokill = x; 13338 else 13339 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 13340 } else if (ast_true(v->value)) { 13341 autokill = DEFAULT_MAXMS; 13342 } else { 13343 autokill = 0; 13344 } 13345 } else if (!strcasecmp(v->name, "bandwidth")) { 13346 if (!strcasecmp(v->value, "low")) { 13347 capability = IAX_CAPABILITY_LOWBANDWIDTH; 13348 } else if (!strcasecmp(v->value, "medium")) { 13349 capability = IAX_CAPABILITY_MEDBANDWIDTH; 13350 } else if (!strcasecmp(v->value, "high")) { 13351 capability = IAX_CAPABILITY_FULLBANDWIDTH; 13352 } else 13353 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 13354 } else if (!strcasecmp(v->name, "allow")) { 13355 iax2_parse_allow_disallow(&prefs, &capability, v->value, 1); 13356 } else if (!strcasecmp(v->name, "disallow")) { 13357 iax2_parse_allow_disallow(&prefs, &capability, v->value, 0); 13358 } else if (!strcasecmp(v->name, "register")) { 13359 iax2_register(v->value, v->lineno); 13360 } else if (!strcasecmp(v->name, "iaxcompat")) { 13361 iaxcompat = ast_true(v->value); 13362 } else if (!strcasecmp(v->name, "regcontext")) { 13363 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 13364 /* Create context if it doesn't exist already */ 13365 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2"); 13366 } else if (!strcasecmp(v->name, "tos")) { 13367 if (ast_str2tos(v->value, &qos.tos)) 13368 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno); 13369 } else if (!strcasecmp(v->name, "cos")) { 13370 if (ast_str2cos(v->value, &qos.cos)) 13371 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno); 13372 } else if (!strcasecmp(v->name, "parkinglot")) { 13373 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot)); 13374 } else if (!strcasecmp(v->name, "accountcode")) { 13375 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 13376 } else if (!strcasecmp(v->name, "mohinterpret")) { 13377 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 13378 } else if (!strcasecmp(v->name, "mohsuggest")) { 13379 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 13380 } else if (!strcasecmp(v->name, "amaflags")) { 13381 format = ast_cdr_amaflags2int(v->value); 13382 if (format < 0) { 13383 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 13384 } else { 13385 amaflags = format; 13386 } 13387 } else if (!strcasecmp(v->name, "language")) { 13388 ast_copy_string(language, v->value, sizeof(language)); 13389 } else if (!strcasecmp(v->name, "maxauthreq")) { 13390 maxauthreq = atoi(v->value); 13391 if (maxauthreq < 0) 13392 maxauthreq = 0; 13393 } else if (!strcasecmp(v->name, "adsi")) { 13394 adsi = ast_true(v->value); 13395 } else if (!strcasecmp(v->name, "srvlookup")) { 13396 srvlookup = ast_true(v->value); 13397 } else if (!strcasecmp(v->name, "connectedline")) { 13398 if (ast_true(v->value)) { 13399 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13400 } else if (!strcasecmp(v->value, "send")) { 13401 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13402 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13403 } else if (!strcasecmp(v->value, "receive")) { 13404 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13405 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13406 } else { 13407 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13408 } 13409 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 13410 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) { 13411 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno); 13412 } 13413 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) { 13414 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) { 13415 ast_log(LOG_WARNING, "maxcallnumbers_nonvalidated must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 13416 } 13417 } else if (!strcasecmp(v->name, "calltokenoptional")) { 13418 if (add_calltoken_ignore(v->value)) { 13419 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno); 13420 } 13421 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) { 13422 if (ast_true(v->value)) { 13423 subscribe_network_change = 1; 13424 } else if (ast_false(v->value)) { 13425 subscribe_network_change = 0; 13426 } else { 13427 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno); 13428 } 13429 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 13430 if (ast_true(v->value)) { 13431 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 13432 } else if (ast_false(v->value)) { 13433 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID); 13434 } else { 13435 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 13436 } 13437 }/*else if (strcasecmp(v->name,"type")) */ 13438 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 13439 v = v->next; 13440 } 13441 13442 if (subscribe_network_change) { 13443 network_change_event_subscribe(); 13444 } else { 13445 network_change_event_unsubscribe(); 13446 } 13447 13448 if (defaultsockfd < 0) { 13449 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) { 13450 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 13451 } else { 13452 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 13453 defaultsockfd = ast_netsock_sockfd(ns); 13454 ast_netsock_unref(ns); 13455 } 13456 } 13457 if (reload) { 13458 ast_netsock_release(outsock); 13459 outsock = ast_netsock_list_alloc(); 13460 if (!outsock) { 13461 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 13462 return -1; 13463 } 13464 ast_netsock_init(outsock); 13465 } 13466 13467 if (min_reg_expire > max_reg_expire) { 13468 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 13469 min_reg_expire, max_reg_expire, max_reg_expire); 13470 min_reg_expire = max_reg_expire; 13471 } 13472 iax2_capability = capability; 13473 13474 if (ucfg) { 13475 struct ast_variable *gen; 13476 int genhasiax; 13477 int genregisteriax; 13478 const char *hasiax, *registeriax; 13479 13480 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 13481 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 13482 gen = ast_variable_browse(ucfg, "general"); 13483 cat = ast_category_browse(ucfg, NULL); 13484 while (cat) { 13485 if (strcasecmp(cat, "general")) { 13486 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 13487 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 13488 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 13489 /* Start with general parameters, then specific parameters, user and peer */ 13490 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 13491 if (user) { 13492 ao2_link(users, user); 13493 user = user_unref(user); 13494 } 13495 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 13496 if (peer) { 13497 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13498 reg_source_db(peer); 13499 ao2_link(peers, peer); 13500 peer = peer_unref(peer); 13501 } 13502 } 13503 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 13504 char tmp[256]; 13505 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 13506 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 13507 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 13508 if (!host) 13509 host = ast_variable_retrieve(ucfg, "general", "host"); 13510 if (!username) 13511 username = ast_variable_retrieve(ucfg, "general", "username"); 13512 if (!secret) 13513 secret = ast_variable_retrieve(ucfg, "general", "secret"); 13514 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 13515 if (!ast_strlen_zero(secret)) 13516 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 13517 else 13518 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 13519 iax2_register(tmp, 0); 13520 } 13521 } 13522 } 13523 cat = ast_category_browse(ucfg, cat); 13524 } 13525 ast_config_destroy(ucfg); 13526 } 13527 13528 cat = ast_category_browse(cfg, NULL); 13529 while(cat) { 13530 if (strcasecmp(cat, "general")) { 13531 utype = ast_variable_retrieve(cfg, cat, "type"); 13532 if (!strcasecmp(cat, "callnumberlimits")) { 13533 build_callno_limits(ast_variable_browse(cfg, cat)); 13534 } else if (utype) { 13535 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 13536 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 13537 if (user) { 13538 ao2_link(users, user); 13539 user = user_unref(user); 13540 } 13541 } 13542 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 13543 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 13544 if (peer) { 13545 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13546 reg_source_db(peer); 13547 ao2_link(peers, peer); 13548 peer = peer_unref(peer); 13549 } 13550 } else if (strcasecmp(utype, "user")) { 13551 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 13552 } 13553 } else 13554 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 13555 } 13556 cat = ast_category_browse(cfg, cat); 13557 } 13558 ast_config_destroy(cfg); 13559 return 1; 13560 }
| static void set_config_destroy | ( | void | ) | [static] |
Definition at line 13074 of file chan_iax2.c.
References addr_range_delme_cb(), ao2_callback, ast_clear_flag64, delete_users(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, MAX_TRUNKDATA, and OBJ_NODATA.
Referenced by set_config().
13075 { 13076 strcpy(accountcode, ""); 13077 strcpy(language, ""); 13078 strcpy(mohinterpret, "default"); 13079 strcpy(mohsuggest, ""); 13080 trunkmaxsize = MAX_TRUNKDATA; 13081 amaflags = 0; 13082 delayreject = 0; 13083 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | 13084 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13085 delete_users(); 13086 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL); 13087 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL); 13088 }
| static void set_hangup_source_and_cause | ( | int | callno, | |
| unsigned char | causecode | |||
| ) | [static] |
Definition at line 9941 of file chan_iax2.c.
References ast_channel_name(), ast_channel_unlock, ast_set_hangupsource(), ast_channel::hangupcause, iax2_lock_owner(), and chan_iax2_pvt::owner.
Referenced by socket_process().
09942 { 09943 iax2_lock_owner(callno); 09944 if (iaxs[callno] && iaxs[callno]->owner) { 09945 if (causecode) { 09946 iaxs[callno]->owner->hangupcause = causecode; 09947 } 09948 ast_set_hangupsource(iaxs[callno]->owner, ast_channel_name(iaxs[callno]->owner), 0); 09949 ast_channel_unlock(iaxs[callno]->owner); 09950 } 09951 }
| static void set_peercnt_limit | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2324 of file chan_iax2.c.
References peercnt::addr, addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_inet_ntoa(), addr_range::limit, peercnt::limit, and peercnt::reg.
Referenced by peercnt_add(), peercnt_modify(), and set_peercnt_limit_all_cb().
02325 { 02326 uint16_t limit = global_maxcallno; 02327 struct addr_range *addr_range; 02328 struct sockaddr_in sin = { 02329 .sin_addr.s_addr = peercnt->addr, 02330 }; 02331 02332 02333 if (peercnt->reg && peercnt->limit) { 02334 return; /* this peercnt has a custom limit set by a registration */ 02335 } 02336 02337 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) { 02338 limit = addr_range->limit; 02339 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr)); 02340 ao2_ref(addr_range, -1); 02341 } 02342 02343 peercnt->limit = limit; 02344 }
| static int set_peercnt_limit_all_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2350 of file chan_iax2.c.
References ast_debug, and set_peercnt_limit().
Referenced by reload_config().
02351 { 02352 struct peercnt *peercnt = obj; 02353 02354 set_peercnt_limit(peercnt); 02355 ast_debug(1, "Reset limits for peercnts table\n"); 02356 02357 return 0; 02358 }
| static void signal_condition | ( | ast_mutex_t * | lock, | |
| ast_cond_t * | cond | |||
| ) | [static] |
Definition at line 1049 of file chan_iax2.c.
References ast_cond_signal, ast_mutex_lock, and ast_mutex_unlock.
Referenced by __schedule_action(), cleanup_thread_list(), iax2_process_thread(), and socket_read().
01050 { 01051 ast_mutex_lock(lock); 01052 ast_cond_signal(cond); 01053 ast_mutex_unlock(lock); 01054 }
| static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 9953 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, ast_aes_set_decrypt_key(), ast_async_goto(), ast_bridged_channel(), ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_channel_datastore_add(), ast_channel_name(), ast_channel_ref, ast_channel_uniqueid(), ast_channel_unlock, ast_channel_unref, ast_clear_flag, ast_clear_flag64, ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), ast_connected_line_parse_data(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, ast_devstate_changed(), ast_exists_extension(), ast_format_cap_copy(), ast_format_cap_destroy(), ast_format_cap_dup(), ast_format_cap_from_old_bitfield(), ast_format_cap_set(), ast_format_cap_to_old_bitfield(), ast_format_from_old_bitfield(), ast_format_id_from_old_bitfield(), ast_format_set_video_mark(), AST_FORMAT_SLINEAR, ast_format_to_old_bitfield(), ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_free, ast_getformatname(), ast_getformatname_multiple(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_event, ast_mutex_lock, ast_mutex_unlock, ast_parking_ext_valid(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_party_id_presentation(), AST_SCHED_DEL, ast_set_callerid(), ast_set_flag, ast_set_flag64, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_var_assign(), ast_variables_destroy(), ast_verb, auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), chan_iax2_pvt::authmethods, iax_ie_data::buf, iax2_thread::buf, iax2_thread::buf_len, CACHE_FLAG_TRANSMITTED, iax_frame::cacheable, calc_timestamp(), iax_ies::called_number, ast_channel::caller, chan_iax2_pvt::calling_pres, iax2_peer::callno, chan_iax2_pvt::callno, iax_frame::callno, iax_ies::calltoken, iax_ies::calltokendata, chan_iax2_pvt::capability, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, check_access(), check_provisioning(), chan_iax2_pvt::chosenformat, cid_name, chan_iax2_pvt::cid_num, cid_num, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), context, chan_iax2_pvt::context, ast_iax2_full_hdr::csub, ast_datastore::data, ast_frame::data, ast_frame::datalen, DATASTORE_INHERIT_FOREVER, ast_iax2_full_hdr::dcallno, decrypt_frame(), iax_ies::devicetype, dp_lookup(), chan_iax2_pvt::encmethods, iax_ies::encmethods, ast_var_t::entries, chan_iax2_pvt::error, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, chan_iax2_pvt::exten, iax_frame::final, find_callno(), chan_iax2_pvt::first_iax_message, iax2_dpcache::flags, iax_ies::format, ast_frame_subclass::format, format, frame_queue, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, handle_call_token(), ast_channel::hangupcause, iax2_peer::historicms, chan_iax2_pvt::hold_signaling, iax2_ack_registry(), iax2_allow_new(), iax2_best_codec(), iax2_codec_choose(), iax2_destroy(), iax2_dprequest(), iax2_getformatname(), iax2_getformatname_multiple(), iax2_lock_owner(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), iax2_send(), iax2_vnak(), IAX_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CALLENCRYPTED, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_RTKEY, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DEBUGDIGEST, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, IAX_FORCE_ENCRYPT, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), iax_ie_append_versioned_uint64(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_FORMAT2, IAX_IE_IAX_UNKNOWN, IAX_IMMEDIATE, iax_outputframe(), iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, IAX_RECVCONNECTEDLINE, IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iax_ies::iax_unknown, iaxfrdup2(), chan_iax2_pvt::iaxvars, ast_party_caller::id, ast_party_connected_line::id, ast_format::id, inaddrcmp(), ast_datastore::inheritance, chan_iax2_pvt::initid, chan_iax2_pvt::inkeys, ast_frame_subclass::integer, iax2_thread::iofd, iax2_thread::iosin, chan_iax2_pvt::iseqno, iax_frame::iseqno, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, ast_frame::len, LOG_ERROR, log_jitterstats(), LOG_NOTICE, LOG_WARNING, make_trunk(), ast_frame::mallocd, manager_event, iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, chan_iax2_pvt::mohsuggest, iax_ies::musiconhold, ast_party_id::name, iax2_peer::name, ast_variable::name, ast_channel::nativeformats, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, ast_variable::next, ast_party_id::number, ast_frame::offset, chan_iax2_pvt::oseqno, iax_frame::oseqno, ast_iax2_full_hdr::oseqno, iax_frame::outoforder, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), peer_ref(), peer_unref(), chan_iax2_pvt::peercallno, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, chan_iax2_pvt::prefs, ast_party_name::presentation, ast_party_number::presentation, iax_ies::provver, iax_ies::provverpres, ast_frame::ptr, raw_hangup(), ast_channel::readformat, iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rprefs, chan_iax2_pvt::rseqno, S_COR, S_OR, ast_frame::samples, save_osptoken(), save_rr(), ast_iax2_full_hdr::scallno, schedule_delivery(), chan_iax2_pvt::secret, send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), send_signaling(), iax_ies::serviceident, set_hangup_source_and_cause(), iax2_peer::smoothing, socket_process_meta(), spawn_dp_lookup(), ast_frame::src, chan_iax2_pvt::state, stop_stuff(), store_by_peercallno(), ast_party_name::str, ast_party_number::str, ast_frame::subclass, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MEDIAPASS, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, try_transfer(), iax_frame::ts, ast_iax2_full_hdr::ts, ast_iax2_full_hdr::type, uncompress_subclass(), update_registry(), iax_ies::username, ast_party_name::valid, ast_party_number::valid, ast_variable::value, var, iax_ies::vars, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.
Referenced by handle_deferred_full_frames(), and iax2_process_thread().
09954 { 09955 struct sockaddr_in sin; 09956 int res; 09957 int updatehistory=1; 09958 int new = NEW_PREVENT; 09959 int dcallno = 0; 09960 char decrypted = 0; 09961 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 09962 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 09963 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 09964 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 09965 struct iax_frame *fr; 09966 struct iax_frame *cur; 09967 struct ast_frame f = { 0, }; 09968 struct ast_channel *c = NULL; 09969 struct iax2_dpcache *dp; 09970 struct iax2_peer *peer; 09971 struct iax_ies ies; 09972 struct iax_ie_data ied0, ied1; 09973 iax2_format format; 09974 int fd; 09975 int exists; 09976 int minivid = 0; 09977 char empty[32]=""; /* Safety measure */ 09978 struct iax_frame *duped_fr; 09979 char host_pref_buf[128]; 09980 char caller_pref_buf[128]; 09981 struct ast_codec_pref pref; 09982 char *using_prefs = "mine"; 09983 09984 /* allocate an iax_frame with 4096 bytes of data buffer */ 09985 fr = alloca(sizeof(*fr) + 4096); 09986 memset(fr, 0, sizeof(*fr)); 09987 fr->afdatalen = 4096; /* From alloca() above */ 09988 09989 /* Copy frequently used parameters to the stack */ 09990 res = thread->buf_len; 09991 fd = thread->iofd; 09992 memcpy(&sin, &thread->iosin, sizeof(sin)); 09993 09994 if (res < sizeof(*mh)) { 09995 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh)); 09996 return 1; 09997 } 09998 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 09999 if (res < sizeof(*vh)) { 10000 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a video frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 10001 return 1; 10002 } 10003 10004 /* This is a video frame, get call number */ 10005 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 10006 minivid = 1; 10007 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) 10008 return socket_process_meta(res, meta, &sin, fd, fr); 10009 10010 #ifdef DEBUG_SUPPORT 10011 if (res >= sizeof(*fh)) 10012 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 10013 #endif 10014 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10015 if (res < sizeof(*fh)) { 10016 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a full frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 10017 return 1; 10018 } 10019 10020 /* Get the destination call number */ 10021 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 10022 10023 10024 /* check to make sure this full frame isn't encrypted before we attempt 10025 * to look inside of it. If it is encrypted, decrypt it first. Its ok if the 10026 * callno is not found here, that just means one hasn't been allocated for 10027 * this connection yet. */ 10028 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) { 10029 ast_mutex_lock(&iaxsl[fr->callno]); 10030 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) { 10031 if (decrypt_frame(fr->callno, fh, &f, &res)) { 10032 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 10033 ast_mutex_unlock(&iaxsl[fr->callno]); 10034 return 1; 10035 } 10036 decrypted = 1; 10037 } 10038 ast_mutex_unlock(&iaxsl[fr->callno]); 10039 } 10040 10041 /* Retrieve the type and subclass */ 10042 f.frametype = fh->type; 10043 if (f.frametype == AST_FRAME_VIDEO) { 10044 ast_format_from_old_bitfield(&f.subclass.format, (uncompress_subclass(fh->csub & ~0x40))); 10045 if ((fh->csub >> 6) & 0x1) { 10046 ast_format_set_video_mark(&f.subclass.format); 10047 } 10048 } else if (f.frametype == AST_FRAME_VOICE) { 10049 ast_format_from_old_bitfield(&f.subclass.format, uncompress_subclass(fh->csub)); 10050 } else { 10051 f.subclass.integer = uncompress_subclass(fh->csub); 10052 } 10053 10054 /* Deal with POKE/PONG without allocating a callno */ 10055 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) { 10056 /* Reply back with a PONG, but don't care about the result. */ 10057 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10058 return 1; 10059 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) { 10060 /* Ignore */ 10061 return 1; 10062 } 10063 10064 f.datalen = res - sizeof(*fh); 10065 if (f.datalen) { 10066 if (f.frametype == AST_FRAME_IAX) { 10067 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) { 10068 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 10069 ast_variables_destroy(ies.vars); 10070 return 1; 10071 } 10072 f.data.ptr = NULL; 10073 f.datalen = 0; 10074 } else { 10075 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr); 10076 memset(&ies, 0, sizeof(ies)); 10077 } 10078 } else { 10079 if (f.frametype == AST_FRAME_IAX) 10080 f.data.ptr = NULL; 10081 else 10082 f.data.ptr = empty; 10083 memset(&ies, 0, sizeof(ies)); 10084 } 10085 10086 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) { 10087 /* only set NEW_ALLOW if calltoken checks out */ 10088 if (handle_call_token(fh, &ies, &sin, fd)) { 10089 ast_variables_destroy(ies.vars); 10090 return 1; 10091 } 10092 10093 if (ies.calltoken && ies.calltokendata) { 10094 /* if we've gotten this far, and the calltoken ie data exists, 10095 * then calltoken validation _MUST_ have taken place. If calltoken 10096 * data is provided, it is always validated reguardless of any 10097 * calltokenoptional or requirecalltoken options */ 10098 new = NEW_ALLOW_CALLTOKEN_VALIDATED; 10099 } else { 10100 new = NEW_ALLOW; 10101 } 10102 } 10103 } else { 10104 /* Don't know anything about it yet */ 10105 f.frametype = AST_FRAME_NULL; 10106 f.subclass.integer = 0; 10107 memset(&ies, 0, sizeof(ies)); 10108 } 10109 10110 if (!fr->callno) { 10111 int check_dcallno = 0; 10112 10113 /* 10114 * We enforce accurate destination call numbers for ACKs. This forces the other 10115 * end to know the destination call number before call setup can complete. 10116 * 10117 * Discussed in the following thread: 10118 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 10119 */ 10120 10121 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) { 10122 check_dcallno = 1; 10123 } 10124 10125 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) { 10126 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) { 10127 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10128 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) { 10129 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10130 } 10131 ast_variables_destroy(ies.vars); 10132 return 1; 10133 } 10134 } 10135 10136 if (fr->callno > 0) 10137 ast_mutex_lock(&iaxsl[fr->callno]); 10138 10139 if (!fr->callno || !iaxs[fr->callno]) { 10140 /* A call arrived for a nonexistent destination. Unless it's an "inval" 10141 frame, reply with an inval */ 10142 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10143 /* We can only raw hangup control frames */ 10144 if (((f.subclass.integer != IAX_COMMAND_INVAL) && 10145 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10146 (f.subclass.integer != IAX_COMMAND_TXACC) && 10147 (f.subclass.integer != IAX_COMMAND_FWDOWNL))|| 10148 (f.frametype != AST_FRAME_IAX)) 10149 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 10150 fd); 10151 } 10152 if (fr->callno > 0) 10153 ast_mutex_unlock(&iaxsl[fr->callno]); 10154 ast_variables_destroy(ies.vars); 10155 return 1; 10156 } 10157 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) { 10158 if (decrypt_frame(fr->callno, fh, &f, &res)) { 10159 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 10160 ast_variables_destroy(ies.vars); 10161 ast_mutex_unlock(&iaxsl[fr->callno]); 10162 return 1; 10163 } 10164 decrypted = 1; 10165 } 10166 10167 #ifdef DEBUG_SUPPORT 10168 if (decrypted) { 10169 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 10170 } 10171 #endif 10172 10173 10174 /* count this frame */ 10175 iaxs[fr->callno]->frames_received++; 10176 10177 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 10178 f.subclass.integer != IAX_COMMAND_TXCNT && /* for attended transfer */ 10179 f.subclass.integer != IAX_COMMAND_TXACC) { /* for attended transfer */ 10180 unsigned short new_peercallno; 10181 10182 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 10183 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 10184 if (iaxs[fr->callno]->peercallno) { 10185 remove_by_peercallno(iaxs[fr->callno]); 10186 } 10187 iaxs[fr->callno]->peercallno = new_peercallno; 10188 store_by_peercallno(iaxs[fr->callno]); 10189 } 10190 } 10191 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10192 if (iaxdebug) 10193 ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer); 10194 /* Check if it's out of order (and not an ACK or INVAL) */ 10195 fr->oseqno = fh->oseqno; 10196 fr->iseqno = fh->iseqno; 10197 fr->ts = ntohl(fh->ts); 10198 #ifdef IAXTESTS 10199 if (test_resync) { 10200 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 10201 fr->ts += test_resync; 10202 } 10203 #endif /* IAXTESTS */ 10204 #if 0 10205 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 10206 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 10207 (f.subclass == IAX_COMMAND_NEW || 10208 f.subclass == IAX_COMMAND_AUTHREQ || 10209 f.subclass == IAX_COMMAND_ACCEPT || 10210 f.subclass == IAX_COMMAND_REJECT)) ) ) 10211 #endif 10212 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 10213 updatehistory = 0; 10214 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 10215 (iaxs[fr->callno]->iseqno || 10216 ((f.subclass.integer != IAX_COMMAND_TXCNT) && 10217 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10218 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10219 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10220 (f.subclass.integer != IAX_COMMAND_TXACC)) || 10221 (f.frametype != AST_FRAME_IAX))) { 10222 if ( 10223 ((f.subclass.integer != IAX_COMMAND_ACK) && 10224 (f.subclass.integer != IAX_COMMAND_INVAL) && 10225 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10226 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10227 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10228 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10229 (f.subclass.integer != IAX_COMMAND_TXACC) && 10230 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10231 (f.frametype != AST_FRAME_IAX)) { 10232 /* If it's not an ACK packet, it's out of order. */ 10233 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 10234 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer); 10235 /* Check to see if we need to request retransmission, 10236 * and take sequence number wraparound into account */ 10237 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 10238 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 10239 if ((f.frametype != AST_FRAME_IAX) || 10240 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) { 10241 ast_debug(1, "Acking anyway\n"); 10242 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 10243 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 10244 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10245 } 10246 } else { 10247 /* Send a VNAK requesting retransmission */ 10248 iax2_vnak(fr->callno); 10249 } 10250 ast_variables_destroy(ies.vars); 10251 ast_mutex_unlock(&iaxsl[fr->callno]); 10252 return 1; 10253 } 10254 } else { 10255 /* Increment unless it's an ACK or VNAK */ 10256 if (((f.subclass.integer != IAX_COMMAND_ACK) && 10257 (f.subclass.integer != IAX_COMMAND_INVAL) && 10258 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10259 (f.subclass.integer != IAX_COMMAND_TXACC) && 10260 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10261 (f.frametype != AST_FRAME_IAX)) 10262 iaxs[fr->callno]->iseqno++; 10263 } 10264 /* Ensure text frames are NULL-terminated */ 10265 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 10266 if (res < thread->buf_size) 10267 thread->buf[res++] = '\0'; 10268 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 10269 thread->buf[res - 1] = '\0'; 10270 } 10271 10272 /* Handle implicit ACKing unless this is an INVAL, and only if this is 10273 from the real peer, not the transfer peer */ 10274 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10275 ((f.subclass.integer != IAX_COMMAND_INVAL) || 10276 (f.frametype != AST_FRAME_IAX))) { 10277 unsigned char x; 10278 int call_to_destroy; 10279 /* First we have to qualify that the ACKed value is within our window */ 10280 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno)) 10281 x = fr->iseqno; 10282 else 10283 x = iaxs[fr->callno]->oseqno; 10284 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 10285 /* The acknowledgement is within our window. Time to acknowledge everything 10286 that it says to */ 10287 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 10288 /* Ack the packet with the given timestamp */ 10289 if (iaxdebug) 10290 ast_debug(1, "Cancelling transmission of packet %d\n", x); 10291 call_to_destroy = 0; 10292 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10293 /* If it's our call, and our timestamp, mark -1 retries */ 10294 if (x == cur->oseqno) { 10295 cur->retries = -1; 10296 /* Destroy call if this is the end */ 10297 if (cur->final) 10298 call_to_destroy = fr->callno; 10299 } 10300 } 10301 if (call_to_destroy) { 10302 if (iaxdebug) 10303 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy); 10304 ast_mutex_lock(&iaxsl[call_to_destroy]); 10305 iax2_destroy(call_to_destroy); 10306 ast_mutex_unlock(&iaxsl[call_to_destroy]); 10307 } 10308 } 10309 /* Note how much we've received acknowledgement for */ 10310 if (iaxs[fr->callno]) 10311 iaxs[fr->callno]->rseqno = fr->iseqno; 10312 else { 10313 /* Stop processing now */ 10314 ast_variables_destroy(ies.vars); 10315 ast_mutex_unlock(&iaxsl[fr->callno]); 10316 return 1; 10317 } 10318 } else { 10319 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 10320 } 10321 } 10322 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10323 ((f.frametype != AST_FRAME_IAX) || 10324 ((f.subclass.integer != IAX_COMMAND_TXACC) && 10325 (f.subclass.integer != IAX_COMMAND_TXCNT)))) { 10326 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 10327 ast_variables_destroy(ies.vars); 10328 ast_mutex_unlock(&iaxsl[fr->callno]); 10329 return 1; 10330 } 10331 10332 /* when we receive the first full frame for a new incoming channel, 10333 it is safe to start the PBX on the channel because we have now 10334 completed a 3-way handshake with the peer */ 10335 if ((f.frametype == AST_FRAME_VOICE) || 10336 (f.frametype == AST_FRAME_VIDEO) || 10337 (f.frametype == AST_FRAME_IAX)) { 10338 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 10339 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10340 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) { 10341 ast_variables_destroy(ies.vars); 10342 ast_mutex_unlock(&iaxsl[fr->callno]); 10343 return 1; 10344 } 10345 } 10346 10347 if (ies.vars) { 10348 struct ast_datastore *variablestore = NULL; 10349 struct ast_variable *var, *prev = NULL; 10350 AST_LIST_HEAD(, ast_var_t) *varlist; 10351 10352 iax2_lock_owner(fr->callno); 10353 if (!iaxs[fr->callno]) { 10354 ast_variables_destroy(ies.vars); 10355 ast_mutex_unlock(&iaxsl[fr->callno]); 10356 return 1; 10357 } 10358 if ((c = iaxs[fr->callno]->owner)) { 10359 varlist = ast_calloc(1, sizeof(*varlist)); 10360 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 10361 10362 if (variablestore && varlist) { 10363 variablestore->data = varlist; 10364 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 10365 AST_LIST_HEAD_INIT(varlist); 10366 ast_debug(1, "I can haz IAX vars?\n"); 10367 for (var = ies.vars; var; var = var->next) { 10368 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 10369 if (prev) { 10370 ast_free(prev); 10371 } 10372 prev = var; 10373 if (!newvar) { 10374 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 10375 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10376 } else { 10377 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 10378 } 10379 } 10380 if (prev) { 10381 ast_free(prev); 10382 } 10383 ies.vars = NULL; 10384 ast_channel_datastore_add(c, variablestore); 10385 } else { 10386 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10387 if (variablestore) { 10388 ast_datastore_free(variablestore); 10389 } 10390 if (varlist) { 10391 ast_free(varlist); 10392 } 10393 } 10394 ast_channel_unlock(c); 10395 } else { 10396 /* No channel yet, so transfer the variables directly over to the pvt, 10397 * for later inheritance. */ 10398 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n"); 10399 for (var = ies.vars; var && var->next; var = var->next); 10400 if (var) { 10401 var->next = iaxs[fr->callno]->iaxvars; 10402 iaxs[fr->callno]->iaxvars = ies.vars; 10403 ies.vars = NULL; 10404 } 10405 } 10406 } 10407 10408 if (ies.vars) { 10409 ast_debug(1, "I have IAX variables, but they were not processed\n"); 10410 } 10411 } 10412 10413 /* once we receive our first IAX Full Frame that is not CallToken related, send all 10414 * queued signaling frames that were being held. */ 10415 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) { 10416 send_signaling(iaxs[fr->callno]); 10417 } 10418 10419 if (f.frametype == AST_FRAME_VOICE) { 10420 if (ast_format_to_old_bitfield(&f.subclass.format) != iaxs[fr->callno]->voiceformat) { 10421 iaxs[fr->callno]->voiceformat = ast_format_to_old_bitfield(&f.subclass.format); 10422 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(&f.subclass.format)); 10423 if (iaxs[fr->callno]->owner) { 10424 iax2_lock_owner(fr->callno); 10425 if (iaxs[fr->callno]) { 10426 if (iaxs[fr->callno]->owner) { 10427 struct ast_format_cap *orignative = ast_format_cap_dup(iaxs[fr->callno]->owner->nativeformats); 10428 struct ast_format_cap *native = iaxs[fr->callno]->owner->nativeformats; 10429 if (orignative) { 10430 ast_format_cap_set(native, &f.subclass.format); 10431 if (iaxs[fr->callno]->owner->readformat.id) { 10432 ast_set_read_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->readformat); 10433 } 10434 ast_format_cap_copy(native, orignative); 10435 ast_channel_unlock(iaxs[fr->callno]->owner); 10436 orignative = ast_format_cap_destroy(orignative); 10437 } 10438 } 10439 } else { 10440 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n"); 10441 /* Free remote variables (if any) */ 10442 if (ies.vars) { 10443 ast_variables_destroy(ies.vars); 10444 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n"); 10445 ies.vars = NULL; 10446 } 10447 ast_mutex_unlock(&iaxsl[fr->callno]); 10448 return 1; 10449 } 10450 } 10451 } 10452 } 10453 if (f.frametype == AST_FRAME_VIDEO) { 10454 if (f.subclass.format.id != ast_format_id_from_old_bitfield(iaxs[fr->callno]->videoformat)) { 10455 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(&f.subclass.format)); 10456 iaxs[fr->callno]->videoformat = ast_format_to_old_bitfield(&f.subclass.format); 10457 } 10458 } 10459 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) { 10460 if (f.subclass.integer == AST_CONTROL_BUSY) { 10461 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 10462 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) { 10463 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 10464 } 10465 } 10466 if (f.frametype == AST_FRAME_IAX) { 10467 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid); 10468 /* Handle the IAX pseudo frame itself */ 10469 if (iaxdebug) 10470 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer); 10471 10472 /* Update last ts unless the frame's timestamp originated with us. */ 10473 if (iaxs[fr->callno]->last < fr->ts && 10474 f.subclass.integer != IAX_COMMAND_ACK && 10475 f.subclass.integer != IAX_COMMAND_PONG && 10476 f.subclass.integer != IAX_COMMAND_LAGRP) { 10477 iaxs[fr->callno]->last = fr->ts; 10478 if (iaxdebug) 10479 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 10480 } 10481 iaxs[fr->callno]->last_iax_message = f.subclass.integer; 10482 if (!iaxs[fr->callno]->first_iax_message) { 10483 iaxs[fr->callno]->first_iax_message = f.subclass.integer; 10484 } 10485 switch(f.subclass.integer) { 10486 case IAX_COMMAND_ACK: 10487 /* Do nothing */ 10488 break; 10489 case IAX_COMMAND_QUELCH: 10490 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10491 /* Generate Manager Hold event, if necessary*/ 10492 if (iaxs[fr->callno]->owner) { 10493 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10494 "Status: On\r\n" 10495 "Channel: %s\r\n" 10496 "Uniqueid: %s\r\n", 10497 ast_channel_name(iaxs[fr->callno]->owner), 10498 ast_channel_uniqueid(iaxs[fr->callno]->owner)); 10499 } 10500 10501 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH); 10502 if (ies.musiconhold) { 10503 iax2_lock_owner(fr->callno); 10504 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) { 10505 break; 10506 } 10507 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10508 const char *moh_suggest = iaxs[fr->callno]->mohsuggest; 10509 10510 /* 10511 * We already hold the owner lock so we do not 10512 * need to check iaxs[fr->callno] after it returns. 10513 */ 10514 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 10515 S_OR(moh_suggest, NULL), 10516 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0); 10517 } 10518 ast_channel_unlock(iaxs[fr->callno]->owner); 10519 } 10520 } 10521 break; 10522 case IAX_COMMAND_UNQUELCH: 10523 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10524 iax2_lock_owner(fr->callno); 10525 if (!iaxs[fr->callno]) { 10526 break; 10527 } 10528 /* Generate Manager Unhold event, if necessary */ 10529 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) { 10530 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10531 "Status: Off\r\n" 10532 "Channel: %s\r\n" 10533 "Uniqueid: %s\r\n", 10534 ast_channel_name(iaxs[fr->callno]->owner), 10535 ast_channel_uniqueid(iaxs[fr->callno]->owner)); 10536 } 10537 10538 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH); 10539 if (!iaxs[fr->callno]->owner) { 10540 break; 10541 } 10542 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10543 /* 10544 * We already hold the owner lock so we do not 10545 * need to check iaxs[fr->callno] after it returns. 10546 */ 10547 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 10548 } 10549 ast_channel_unlock(iaxs[fr->callno]->owner); 10550 } 10551 break; 10552 case IAX_COMMAND_TXACC: 10553 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 10554 /* Ack the packet with the given timestamp */ 10555 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10556 /* Cancel any outstanding txcnt's */ 10557 if (cur->transfer) { 10558 cur->retries = -1; 10559 } 10560 } 10561 memset(&ied1, 0, sizeof(ied1)); 10562 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 10563 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 10564 iaxs[fr->callno]->transferring = TRANSFER_READY; 10565 } 10566 break; 10567 case IAX_COMMAND_NEW: 10568 /* Ignore if it's already up */ 10569 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 10570 break; 10571 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 10572 ast_mutex_unlock(&iaxsl[fr->callno]); 10573 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 10574 ast_mutex_lock(&iaxsl[fr->callno]); 10575 if (!iaxs[fr->callno]) { 10576 break; 10577 } 10578 } 10579 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 10580 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) { 10581 int new_callno; 10582 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 10583 fr->callno = new_callno; 10584 } 10585 /* For security, always ack immediately */ 10586 if (delayreject) 10587 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10588 if (check_access(fr->callno, &sin, &ies)) { 10589 /* They're not allowed on */ 10590 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10591 if (authdebug) 10592 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 10593 break; 10594 } 10595 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) { 10596 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10597 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n"); 10598 break; 10599 } 10600 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 10601 const char *context, *exten, *cid_num; 10602 10603 context = ast_strdupa(iaxs[fr->callno]->context); 10604 exten = ast_strdupa(iaxs[fr->callno]->exten); 10605 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 10606 10607 /* This might re-enter the IAX code and need the lock */ 10608 ast_mutex_unlock(&iaxsl[fr->callno]); 10609 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 10610 ast_mutex_lock(&iaxsl[fr->callno]); 10611 10612 if (!iaxs[fr->callno]) { 10613 break; 10614 } 10615 } else 10616 exists = 0; 10617 /* Get OSP token if it does exist */ 10618 save_osptoken(fr, &ies); 10619 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 10620 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 10621 memset(&ied0, 0, sizeof(ied0)); 10622 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10623 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10624 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10625 if (!iaxs[fr->callno]) { 10626 break; 10627 } 10628 if (authdebug) 10629 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 10630 } else { 10631 /* Select an appropriate format */ 10632 10633 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10634 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10635 using_prefs = "reqonly"; 10636 } else { 10637 using_prefs = "disabled"; 10638 } 10639 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 10640 memset(&pref, 0, sizeof(pref)); 10641 strcpy(caller_pref_buf, "disabled"); 10642 strcpy(host_pref_buf, "disabled"); 10643 } else { 10644 struct ast_format tmpfmt; 10645 using_prefs = "mine"; 10646 /* If the information elements are in here... use them */ 10647 if (ies.codec_prefs) 10648 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 10649 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) { 10650 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 10651 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10652 pref = iaxs[fr->callno]->rprefs; 10653 using_prefs = "caller"; 10654 } else { 10655 pref = iaxs[fr->callno]->prefs; 10656 } 10657 } else 10658 pref = iaxs[fr->callno]->prefs; 10659 10660 format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 10661 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 10662 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 10663 } 10664 if (!format) { 10665 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) 10666 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 10667 if (!format) { 10668 memset(&ied0, 0, sizeof(ied0)); 10669 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10670 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10671 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10672 if (!iaxs[fr->callno]) { 10673 break; 10674 } 10675 if (authdebug) { 10676 char tmp[256], tmp2[256], tmp3[256]; 10677 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10678 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", 10679 ast_inet_ntoa(sin.sin_addr), 10680 iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10681 iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10682 } else { 10683 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10684 ast_inet_ntoa(sin.sin_addr), 10685 iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10686 iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10687 iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10688 } 10689 } 10690 } else { 10691 /* Pick one... */ 10692 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10693 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 10694 format = 0; 10695 } else { 10696 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10697 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 10698 memset(&pref, 0, sizeof(pref)); 10699 format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10700 strcpy(caller_pref_buf,"disabled"); 10701 strcpy(host_pref_buf,"disabled"); 10702 } else { 10703 struct ast_format tmpfmt; 10704 using_prefs = "mine"; 10705 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) { 10706 /* Do the opposite of what we tried above. */ 10707 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10708 pref = iaxs[fr->callno]->prefs; 10709 } else { 10710 pref = iaxs[fr->callno]->rprefs; 10711 using_prefs = "caller"; 10712 } 10713 format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 10714 } else /* if no codec_prefs IE do it the old way */ 10715 format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10716 } 10717 } 10718 10719 if (!format) { 10720 char tmp[256], tmp2[256], tmp3[256]; 10721 memset(&ied0, 0, sizeof(ied0)); 10722 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10723 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10724 ast_log(LOG_ERROR, "No best format in '%s'???\n", iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 10725 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10726 if (!iaxs[fr->callno]) { 10727 break; 10728 } 10729 if (authdebug) { 10730 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10731 ast_inet_ntoa(sin.sin_addr), 10732 iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10733 iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10734 iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10735 } 10736 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10737 break; 10738 } 10739 } 10740 } 10741 if (format) { 10742 /* No authentication required, let them in */ 10743 memset(&ied1, 0, sizeof(ied1)); 10744 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 10745 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 10746 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 10747 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 10748 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10749 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n" 10750 "%srequested format = %s,\n" 10751 "%srequested prefs = %s,\n" 10752 "%sactual format = %s,\n" 10753 "%shost prefs = %s,\n" 10754 "%spriority = %s\n", 10755 ast_inet_ntoa(sin.sin_addr), 10756 VERBOSE_PREFIX_4, 10757 iax2_getformatname(iaxs[fr->callno]->peerformat), 10758 VERBOSE_PREFIX_4, 10759 caller_pref_buf, 10760 VERBOSE_PREFIX_4, 10761 iax2_getformatname(format), 10762 VERBOSE_PREFIX_4, 10763 host_pref_buf, 10764 VERBOSE_PREFIX_4, 10765 using_prefs); 10766 10767 iaxs[fr->callno]->chosenformat = format; 10768 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10769 } else { 10770 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10771 /* If this is a TBD call, we're ready but now what... */ 10772 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 10773 } 10774 } 10775 } 10776 break; 10777 } 10778 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 10779 merge_encryption(iaxs[fr->callno],ies.encmethods); 10780 else 10781 iaxs[fr->callno]->encmethods = 0; 10782 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 10783 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 10784 break; 10785 case IAX_COMMAND_DPREQ: 10786 /* Request status in the dialplan */ 10787 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 10788 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 10789 if (iaxcompat) { 10790 /* Spawn a thread for the lookup */ 10791 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 10792 } else { 10793 /* Just look it up */ 10794 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 10795 } 10796 } 10797 break; 10798 case IAX_COMMAND_HANGUP: 10799 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10800 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno); 10801 /* Set hangup cause according to remote and hangupsource */ 10802 if (iaxs[fr->callno]->owner) { 10803 set_hangup_source_and_cause(fr->callno, ies.causecode); 10804 if (!iaxs[fr->callno]) { 10805 break; 10806 } 10807 } 10808 10809 /* Send ack immediately, before we destroy */ 10810 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10811 iax2_destroy(fr->callno); 10812 break; 10813 case IAX_COMMAND_REJECT: 10814 /* Set hangup cause according to remote and hangup source */ 10815 if (iaxs[fr->callno]->owner) { 10816 set_hangup_source_and_cause(fr->callno, ies.causecode); 10817 if (!iaxs[fr->callno]) { 10818 break; 10819 } 10820 } 10821 10822 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10823 if (iaxs[fr->callno]->owner && authdebug) 10824 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 10825 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 10826 ies.cause ? ies.cause : "<Unknown>"); 10827 ast_debug(1, "Immediately destroying %d, having received reject\n", 10828 fr->callno); 10829 } 10830 /* Send ack immediately, before we destroy */ 10831 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 10832 fr->ts, NULL, 0, fr->iseqno); 10833 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) 10834 iaxs[fr->callno]->error = EPERM; 10835 iax2_destroy(fr->callno); 10836 break; 10837 case IAX_COMMAND_TRANSFER: 10838 { 10839 struct ast_channel *bridged_chan; 10840 struct ast_channel *owner; 10841 10842 iax2_lock_owner(fr->callno); 10843 if (!iaxs[fr->callno]) { 10844 /* Initiating call went away before we could transfer. */ 10845 break; 10846 } 10847 owner = iaxs[fr->callno]->owner; 10848 bridged_chan = owner ? ast_bridged_channel(owner) : NULL; 10849 if (bridged_chan && ies.called_number) { 10850 const char *context; 10851 10852 context = ast_strdupa(iaxs[fr->callno]->context); 10853 10854 ast_channel_ref(owner); 10855 ast_channel_ref(bridged_chan); 10856 ast_channel_unlock(owner); 10857 ast_mutex_unlock(&iaxsl[fr->callno]); 10858 10859 /* Set BLINDTRANSFER channel variables */ 10860 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", ast_channel_name(bridged_chan)); 10861 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", ast_channel_name(owner)); 10862 10863 /* DO NOT hold any locks while calling ast_parking_ext_valid() */ 10864 if (ast_parking_ext_valid(ies.called_number, owner, context)) { 10865 ast_debug(1, "Parking call '%s'\n", ast_channel_name(bridged_chan)); 10866 if (iax_park(bridged_chan, owner, ies.called_number, context)) { 10867 ast_log(LOG_WARNING, "Failed to park call '%s'\n", 10868 ast_channel_name(bridged_chan)); 10869 } 10870 } else { 10871 if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) { 10872 ast_log(LOG_WARNING, 10873 "Async goto of '%s' to '%s@%s' failed\n", 10874 ast_channel_name(bridged_chan), ies.called_number, context); 10875 } else { 10876 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", 10877 ast_channel_name(bridged_chan), ies.called_number, context); 10878 } 10879 } 10880 ast_channel_unref(owner); 10881 ast_channel_unref(bridged_chan); 10882 10883 ast_mutex_lock(&iaxsl[fr->callno]); 10884 } else { 10885 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno); 10886 if (owner) { 10887 ast_channel_unlock(owner); 10888 } 10889 } 10890 10891 break; 10892 } 10893 case IAX_COMMAND_ACCEPT: 10894 /* Ignore if call is already up or needs authentication or is a TBD */ 10895 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 10896 break; 10897 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10898 /* Send ack immediately, before we destroy */ 10899 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10900 iax2_destroy(fr->callno); 10901 break; 10902 } 10903 if (ies.format) { 10904 iaxs[fr->callno]->peerformat = ies.format; 10905 } else { 10906 if (iaxs[fr->callno]->owner) 10907 iaxs[fr->callno]->peerformat = ast_format_cap_to_old_bitfield(iaxs[fr->callno]->owner->nativeformats); 10908 else 10909 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 10910 } 10911 ast_verb(3, "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iax2_getformatname(iaxs[fr->callno]->peerformat)); 10912 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 10913 memset(&ied0, 0, sizeof(ied0)); 10914 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10915 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10916 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10917 if (!iaxs[fr->callno]) { 10918 break; 10919 } 10920 if (authdebug) { 10921 char tmp1[256], tmp2[256]; 10922 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n", 10923 ast_inet_ntoa(sin.sin_addr), 10924 iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 10925 iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10926 } 10927 } else { 10928 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10929 iax2_lock_owner(fr->callno); 10930 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 10931 char tmp[256]; 10932 /* Switch us to use a compatible format */ 10933 ast_format_cap_from_old_bitfield(iaxs[fr->callno]->owner->nativeformats, iaxs[fr->callno]->peerformat); 10934 ast_verb(3, "Format for call is %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->owner->nativeformats)); 10935 10936 /* Setup read/write formats properly. */ 10937 if (iaxs[fr->callno]->owner->writeformat.id) 10938 ast_set_write_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->writeformat); 10939 if (iaxs[fr->callno]->owner->readformat.id) 10940 ast_set_read_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->readformat); 10941 ast_channel_unlock(iaxs[fr->callno]->owner); 10942 } 10943 } 10944 if (iaxs[fr->callno]) { 10945 AST_LIST_LOCK(&dpcache); 10946 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list) 10947 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) 10948 iax2_dprequest(dp, fr->callno); 10949 AST_LIST_UNLOCK(&dpcache); 10950 } 10951 break; 10952 case IAX_COMMAND_POKE: 10953 /* Send back a pong packet with the original timestamp */ 10954 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 10955 break; 10956 case IAX_COMMAND_PING: 10957 { 10958 struct iax_ie_data pingied; 10959 construct_rr(iaxs[fr->callno], &pingied); 10960 /* Send back a pong packet with the original timestamp */ 10961 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 10962 } 10963 break; 10964 case IAX_COMMAND_PONG: 10965 /* Calculate ping time */ 10966 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 10967 /* save RR info */ 10968 save_rr(fr, &ies); 10969 10970 /* Good time to write jb stats for this call */ 10971 log_jitterstats(fr->callno); 10972 10973 if (iaxs[fr->callno]->peerpoke) { 10974 peer = iaxs[fr->callno]->peerpoke; 10975 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 10976 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 10977 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 10978 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 10979 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name); /* Activate notification */ 10980 } 10981 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 10982 if (iaxs[fr->callno]->pingtime > peer->maxms) { 10983 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 10984 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 10985 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 10986 } 10987 } 10988 peer->lastms = iaxs[fr->callno]->pingtime; 10989 if (peer->smoothing && (peer->lastms > -1)) 10990 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 10991 else if (peer->smoothing && peer->lastms < 0) 10992 peer->historicms = (0 + peer->historicms) / 2; 10993 else 10994 peer->historicms = iaxs[fr->callno]->pingtime; 10995 10996 /* Remove scheduled iax2_poke_noanswer */ 10997 if (peer->pokeexpire > -1) { 10998 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 10999 peer_unref(peer); 11000 peer->pokeexpire = -1; 11001 } 11002 } 11003 /* Schedule the next cycle */ 11004 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 11005 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 11006 else 11007 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 11008 if (peer->pokeexpire == -1) 11009 peer_unref(peer); 11010 /* and finally send the ack */ 11011 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11012 /* And wrap up the qualify call */ 11013 iax2_destroy(fr->callno); 11014 peer->callno = 0; 11015 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 11016 } 11017 break; 11018 case IAX_COMMAND_LAGRQ: 11019 case IAX_COMMAND_LAGRP: 11020 f.src = "LAGRQ"; 11021 f.mallocd = 0; 11022 f.offset = 0; 11023 f.samples = 0; 11024 iax_frame_wrap(fr, &f); 11025 if (f.subclass.integer == IAX_COMMAND_LAGRQ) { 11026 /* Received a LAGRQ - echo back a LAGRP */ 11027 fr->af.subclass.integer = IAX_COMMAND_LAGRP; 11028 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 11029 } else { 11030 /* Received LAGRP in response to our LAGRQ */ 11031 unsigned int ts; 11032 /* This is a reply we've been given, actually measure the difference */ 11033 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 11034 iaxs[fr->callno]->lag = ts - fr->ts; 11035 if (iaxdebug) 11036 ast_debug(1, "Peer %s lag measured as %dms\n", 11037 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 11038 } 11039 break; 11040 case IAX_COMMAND_AUTHREQ: 11041 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 11042 ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>"); 11043 break; 11044 } 11045 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 11046 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 11047 .subclass.integer = AST_CONTROL_HANGUP, 11048 }; 11049 ast_log(LOG_WARNING, 11050 "I don't know how to authenticate %s to %s\n", 11051 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 11052 iax2_queue_frame(fr->callno, &hangup_fr); 11053 } 11054 break; 11055 case IAX_COMMAND_AUTHREP: 11056 /* For security, always ack immediately */ 11057 if (delayreject) 11058 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11059 /* Ignore once we've started */ 11060 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 11061 ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>"); 11062 break; 11063 } 11064 if (authenticate_verify(iaxs[fr->callno], &ies)) { 11065 if (authdebug) 11066 ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->username); 11067 memset(&ied0, 0, sizeof(ied0)); 11068 auth_fail(fr->callno, IAX_COMMAND_REJECT); 11069 break; 11070 } 11071 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 11072 /* This might re-enter the IAX code and need the lock */ 11073 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 11074 } else 11075 exists = 0; 11076 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 11077 if (authdebug) 11078 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 11079 memset(&ied0, 0, sizeof(ied0)); 11080 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 11081 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 11082 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11083 if (!iaxs[fr->callno]) { 11084 break; 11085 } 11086 } else { 11087 /* Select an appropriate format */ 11088 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 11089 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11090 using_prefs = "reqonly"; 11091 } else { 11092 using_prefs = "disabled"; 11093 } 11094 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 11095 memset(&pref, 0, sizeof(pref)); 11096 strcpy(caller_pref_buf, "disabled"); 11097 strcpy(host_pref_buf, "disabled"); 11098 } else { 11099 struct ast_format tmpfmt; 11100 using_prefs = "mine"; 11101 if (ies.codec_prefs) 11102 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 11103 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) { 11104 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 11105 pref = iaxs[fr->callno]->rprefs; 11106 using_prefs = "caller"; 11107 } else { 11108 pref = iaxs[fr->callno]->prefs; 11109 } 11110 } else /* if no codec_prefs IE do it the old way */ 11111 pref = iaxs[fr->callno]->prefs; 11112 format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 11113 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 11114 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 11115 } 11116 if (!format) { 11117 char tmp1[256], tmp2[256], tmp3[256]; 11118 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11119 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n", 11120 iax2_getformatname(iaxs[fr->callno]->peerformat), 11121 iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability)); 11122 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 11123 } 11124 if (!format) { 11125 if (authdebug) { 11126 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11127 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr), 11128 iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11129 iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 11130 } else { 11131 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 11132 ast_inet_ntoa(sin.sin_addr), 11133 iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11134 iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 11135 iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 11136 } 11137 } 11138 memset(&ied0, 0, sizeof(ied0)); 11139 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 11140 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 11141 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11142 if (!iaxs[fr->callno]) { 11143 break; 11144 } 11145 } else { 11146 /* Pick one... */ 11147 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11148 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 11149 format = 0; 11150 } else { 11151 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 11152 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 11153 memset(&pref, 0, sizeof(pref)); 11154 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 11155 iaxs[fr->callno]->peerformat : iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 11156 strcpy(caller_pref_buf,"disabled"); 11157 strcpy(host_pref_buf,"disabled"); 11158 } else { 11159 struct ast_format tmpfmt; 11160 using_prefs = "mine"; 11161 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) { 11162 /* Do the opposite of what we tried above. */ 11163 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 11164 pref = iaxs[fr->callno]->prefs; 11165 } else { 11166 pref = iaxs[fr->callno]->rprefs; 11167 using_prefs = "caller"; 11168 } 11169 format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 11170 } else /* if no codec_prefs IE do it the old way */ 11171 format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 11172 } 11173 } 11174 if (!format) { 11175 char tmp1[256], tmp2[256], tmp3[256]; 11176 ast_log(LOG_ERROR, "No best format in %s???\n", 11177 iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 11178 if (authdebug) { 11179 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11180 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", 11181 ast_inet_ntoa(sin.sin_addr), 11182 iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11183 iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 11184 } else { 11185 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 11186 ast_inet_ntoa(sin.sin_addr), 11187 iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11188 iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 11189 iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 11190 } 11191 } 11192 memset(&ied0, 0, sizeof(ied0)); 11193 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 11194 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 11195 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11196 if (!iaxs[fr->callno]) { 11197 break; 11198 } 11199 } 11200 } 11201 } 11202 if (format) { 11203 /* Authentication received */ 11204 memset(&ied1, 0, sizeof(ied1)); 11205 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 11206 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 11207 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 11208 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 11209 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11210 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n" 11211 "%srequested format = %s,\n" 11212 "%srequested prefs = %s,\n" 11213 "%sactual format = %s,\n" 11214 "%shost prefs = %s,\n" 11215 "%spriority = %s\n", 11216 ast_inet_ntoa(sin.sin_addr), 11217 VERBOSE_PREFIX_4, 11218 iax2_getformatname(iaxs[fr->callno]->peerformat), 11219 VERBOSE_PREFIX_4, 11220 caller_pref_buf, 11221 VERBOSE_PREFIX_4, 11222 iax2_getformatname(format), 11223 VERBOSE_PREFIX_4, 11224 host_pref_buf, 11225 VERBOSE_PREFIX_4, 11226 using_prefs); 11227 11228 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11229 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL))) 11230 iax2_destroy(fr->callno); 11231 else if (ies.vars) { 11232 struct ast_datastore *variablestore; 11233 struct ast_variable *var, *prev = NULL; 11234 AST_LIST_HEAD(, ast_var_t) *varlist; 11235 varlist = ast_calloc(1, sizeof(*varlist)); 11236 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 11237 if (variablestore && varlist) { 11238 variablestore->data = varlist; 11239 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11240 AST_LIST_HEAD_INIT(varlist); 11241 ast_debug(1, "I can haz IAX vars? w00t\n"); 11242 for (var = ies.vars; var; var = var->next) { 11243 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 11244 if (prev) 11245 ast_free(prev); 11246 prev = var; 11247 if (!newvar) { 11248 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 11249 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11250 } else { 11251 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 11252 } 11253 } 11254 if (prev) 11255 ast_free(prev); 11256 ies.vars = NULL; 11257 ast_channel_datastore_add(c, variablestore); 11258 } else { 11259 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11260 if (variablestore) 11261 ast_datastore_free(variablestore); 11262 if (varlist) 11263 ast_free(varlist); 11264 } 11265 } 11266 } else { 11267 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11268 /* If this is a TBD call, we're ready but now what... */ 11269 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 11270 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) { 11271 goto immediatedial; 11272 } 11273 } 11274 } 11275 } 11276 break; 11277 case IAX_COMMAND_DIAL: 11278 immediatedial: 11279 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 11280 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11281 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 11282 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 11283 if (authdebug) 11284 ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 11285 memset(&ied0, 0, sizeof(ied0)); 11286 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 11287 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 11288 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11289 if (!iaxs[fr->callno]) { 11290 break; 11291 } 11292 } else { 11293 char tmp[256]; 11294 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11295 ast_verb(3, "Accepting DIAL from %s, formats = %s\n", 11296 ast_inet_ntoa(sin.sin_addr), 11297 iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat)); 11298 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11299 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 11300 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL))) 11301 iax2_destroy(fr->callno); 11302 else if (ies.vars) { 11303 struct ast_datastore *variablestore; 11304 struct ast_variable *var, *prev = NULL; 11305 AST_LIST_HEAD(, ast_var_t) *varlist; 11306 varlist = ast_calloc(1, sizeof(*varlist)); 11307 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 11308 ast_debug(1, "I can haz IAX vars? w00t\n"); 11309 if (variablestore && varlist) { 11310 variablestore->data = varlist; 11311 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11312 AST_LIST_HEAD_INIT(varlist); 11313 for (var = ies.vars; var; var = var->next) { 11314 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 11315 if (prev) 11316 ast_free(prev); 11317 prev = var; 11318 if (!newvar) { 11319 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 11320 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11321 } else { 11322 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 11323 } 11324 } 11325 if (prev) 11326 ast_free(prev); 11327 ies.vars = NULL; 11328 ast_channel_datastore_add(c, variablestore); 11329 } else { 11330 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11331 if (variablestore) 11332 ast_datastore_free(variablestore); 11333 if (varlist) 11334 ast_free(varlist); 11335 } 11336 } 11337 } 11338 } 11339 break; 11340 case IAX_COMMAND_INVAL: 11341 iaxs[fr->callno]->error = ENOTCONN; 11342 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno); 11343 iax2_destroy(fr->callno); 11344 ast_debug(1, "Destroying call %d\n", fr->callno); 11345 break; 11346 case IAX_COMMAND_VNAK: 11347 ast_debug(1, "Received VNAK: resending outstanding frames\n"); 11348 /* Force retransmission */ 11349 vnak_retransmit(fr->callno, fr->iseqno); 11350 break; 11351 case IAX_COMMAND_REGREQ: 11352 case IAX_COMMAND_REGREL: 11353 /* For security, always ack immediately */ 11354 if (delayreject) 11355 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11356 if (register_verify(fr->callno, &sin, &ies)) { 11357 if (!iaxs[fr->callno]) { 11358 break; 11359 } 11360 /* Send delayed failure */ 11361 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 11362 break; 11363 } 11364 if (!iaxs[fr->callno]) { 11365 break; 11366 } 11367 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 11368 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 11369 11370 if (f.subclass.integer == IAX_COMMAND_REGREL) { 11371 memset(&sin, 0, sizeof(sin)); 11372 sin.sin_family = AF_INET; 11373 } 11374 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) { 11375 ast_log(LOG_WARNING, "Registry error\n"); 11376 } 11377 if (!iaxs[fr->callno]) { 11378 break; 11379 } 11380 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 11381 ast_mutex_unlock(&iaxsl[fr->callno]); 11382 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 11383 ast_mutex_lock(&iaxsl[fr->callno]); 11384 } 11385 break; 11386 } 11387 registry_authrequest(fr->callno); 11388 break; 11389 case IAX_COMMAND_REGACK: 11390 if (iax2_ack_registry(&ies, &sin, fr->callno)) 11391 ast_log(LOG_WARNING, "Registration failure\n"); 11392 /* Send ack immediately, before we destroy */ 11393 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11394 iax2_destroy(fr->callno); 11395 break; 11396 case IAX_COMMAND_REGREJ: 11397 if (iaxs[fr->callno]->reg) { 11398 if (authdebug) { 11399 ast_log(LOG_NOTICE, "Registration of '%s' rejected: '%s' from: '%s'\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>", ast_inet_ntoa(sin.sin_addr)); 11400 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>"); 11401 } 11402 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 11403 } 11404 /* Send ack immediately, before we destroy */ 11405 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11406 iax2_destroy(fr->callno); 11407 break; 11408 case IAX_COMMAND_REGAUTH: 11409 /* Authentication request */ 11410 if (registry_rerequest(&ies, fr->callno, &sin)) { 11411 memset(&ied0, 0, sizeof(ied0)); 11412 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 11413 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 11414 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11415 } 11416 break; 11417 case IAX_COMMAND_TXREJ: 11418 iaxs[fr->callno]->transferring = 0; 11419 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>"); 11420 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 11421 if (iaxs[fr->callno]->bridgecallno) { 11422 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 11423 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 11424 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 11425 } 11426 } 11427 break; 11428 case IAX_COMMAND_TXREADY: 11429 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 11430 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 11431 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 11432 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 11433 else 11434 iaxs[fr->callno]->transferring = TRANSFER_READY; 11435 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>"); 11436 if (iaxs[fr->callno]->bridgecallno) { 11437 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 11438 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 11439 /* They're both ready, now release them. */ 11440 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 11441 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>", 11442 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->owner) : "<Unknown>"); 11443 11444 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 11445 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 11446 11447 memset(&ied0, 0, sizeof(ied0)); 11448 memset(&ied1, 0, sizeof(ied1)); 11449 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11450 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11451 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 11452 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 11453 } else { 11454 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>", 11455 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->owner) : "<Unknown>"); 11456 11457 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 11458 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 11459 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 11460 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 11461 11462 /* Stop doing lag & ping requests */ 11463 stop_stuff(fr->callno); 11464 stop_stuff(iaxs[fr->callno]->bridgecallno); 11465 11466 memset(&ied0, 0, sizeof(ied0)); 11467 memset(&ied1, 0, sizeof(ied1)); 11468 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11469 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11470 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 11471 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 11472 } 11473 11474 } 11475 } 11476 } 11477 break; 11478 case IAX_COMMAND_TXREQ: 11479 try_transfer(iaxs[fr->callno], &ies); 11480 break; 11481 case IAX_COMMAND_TXCNT: 11482 if (iaxs[fr->callno]->transferring) 11483 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 11484 break; 11485 case IAX_COMMAND_TXREL: 11486 /* Send ack immediately, rather than waiting until we've changed addresses */ 11487 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11488 complete_transfer(fr->callno, &ies); 11489 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 11490 break; 11491 case IAX_COMMAND_TXMEDIA: 11492 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 11493 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 11494 /* Cancel any outstanding frames and start anew */ 11495 if (cur->transfer) { 11496 cur->retries = -1; 11497 } 11498 } 11499 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 11500 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 11501 } 11502 break; 11503 case IAX_COMMAND_RTKEY: 11504 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) { 11505 ast_log(LOG_WARNING, 11506 "we've been told to rotate our encryption key, " 11507 "but this isn't an encrypted call. bad things will happen.\n" 11508 ); 11509 break; 11510 } 11511 11512 IAX_DEBUGDIGEST("Receiving", ies.challenge); 11513 11514 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx); 11515 break; 11516 case IAX_COMMAND_DPREP: 11517 complete_dpreply(iaxs[fr->callno], &ies); 11518 break; 11519 case IAX_COMMAND_UNSUPPORT: 11520 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 11521 break; 11522 case IAX_COMMAND_FWDOWNL: 11523 /* Firmware download */ 11524 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 11525 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 11526 break; 11527 } 11528 memset(&ied0, 0, sizeof(ied0)); 11529 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 11530 if (res < 0) 11531 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11532 else if (res > 0) 11533 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11534 else 11535 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11536 break; 11537 case IAX_COMMAND_CALLTOKEN: 11538 { 11539 struct iax_frame *cur; 11540 /* find last sent frame */ 11541 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) { 11542 resend_with_token(fr->callno, cur, (char *) ies.calltokendata); 11543 } 11544 break; 11545 } 11546 default: 11547 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno); 11548 memset(&ied0, 0, sizeof(ied0)); 11549 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer); 11550 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 11551 } 11552 /* Free remote variables (if any) */ 11553 if (ies.vars) { 11554 ast_variables_destroy(ies.vars); 11555 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n"); 11556 ies.vars = NULL; 11557 } 11558 11559 /* Don't actually pass these frames along */ 11560 if ((f.subclass.integer != IAX_COMMAND_ACK) && 11561 (f.subclass.integer != IAX_COMMAND_TXCNT) && 11562 (f.subclass.integer != IAX_COMMAND_TXACC) && 11563 (f.subclass.integer != IAX_COMMAND_INVAL) && 11564 (f.subclass.integer != IAX_COMMAND_VNAK)) { 11565 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 11566 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11567 } 11568 ast_mutex_unlock(&iaxsl[fr->callno]); 11569 return 1; 11570 } 11571 /* Unless this is an ACK or INVAL frame, ack it */ 11572 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 11573 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11574 } else if (minivid) { 11575 f.frametype = AST_FRAME_VIDEO; 11576 if (iaxs[fr->callno]->videoformat > 0) { 11577 if (ntohs(vh->ts) & 0x8000LL) { 11578 ast_format_set_video_mark(&f.subclass.format); 11579 } 11580 ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->videoformat); 11581 } else { 11582 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 11583 iax2_vnak(fr->callno); 11584 ast_variables_destroy(ies.vars); 11585 ast_mutex_unlock(&iaxsl[fr->callno]); 11586 return 1; 11587 } 11588 f.datalen = res - sizeof(*vh); 11589 if (f.datalen) 11590 f.data.ptr = thread->buf + sizeof(*vh); 11591 else 11592 f.data.ptr = NULL; 11593 #ifdef IAXTESTS 11594 if (test_resync) { 11595 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 11596 } else 11597 #endif /* IAXTESTS */ 11598 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 11599 } else { 11600 /* A mini frame */ 11601 f.frametype = AST_FRAME_VOICE; 11602 if (iaxs[fr->callno]->voiceformat > 0) 11603 ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->voiceformat); 11604 else { 11605 ast_debug(1, "Received mini frame before first full voice frame\n"); 11606 iax2_vnak(fr->callno); 11607 ast_variables_destroy(ies.vars); 11608 ast_mutex_unlock(&iaxsl[fr->callno]); 11609 return 1; 11610 } 11611 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 11612 if (f.datalen < 0) { 11613 ast_log(LOG_WARNING, "Datalen < 0?\n"); 11614 ast_variables_destroy(ies.vars); 11615 ast_mutex_unlock(&iaxsl[fr->callno]); 11616 return 1; 11617 } 11618 if (f.datalen) 11619 f.data.ptr = thread->buf + sizeof(*mh); 11620 else 11621 f.data.ptr = NULL; 11622 #ifdef IAXTESTS 11623 if (test_resync) { 11624 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 11625 } else 11626 #endif /* IAXTESTS */ 11627 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 11628 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 11629 } 11630 /* Don't pass any packets until we're started */ 11631 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 11632 ast_variables_destroy(ies.vars); 11633 ast_mutex_unlock(&iaxsl[fr->callno]); 11634 return 1; 11635 } 11636 /* Don't allow connected line updates unless we are configured to */ 11637 if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) { 11638 struct ast_party_connected_line connected; 11639 11640 if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) { 11641 ast_variables_destroy(ies.vars); 11642 ast_mutex_unlock(&iaxsl[fr->callno]); 11643 return 1; 11644 } 11645 11646 /* Initialize defaults */ 11647 ast_party_connected_line_init(&connected); 11648 connected.id.number.presentation = iaxs[fr->callno]->calling_pres; 11649 connected.id.name.presentation = iaxs[fr->callno]->calling_pres; 11650 11651 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) { 11652 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str); 11653 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str); 11654 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id); 11655 11656 if (iaxs[fr->callno]->owner) { 11657 ast_set_callerid(iaxs[fr->callno]->owner, 11658 S_COR(connected.id.number.valid, connected.id.number.str, ""), 11659 S_COR(connected.id.name.valid, connected.id.name.str, ""), 11660 NULL); 11661 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation; 11662 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation; 11663 } 11664 } 11665 ast_party_connected_line_free(&connected); 11666 } 11667 /* Common things */ 11668 f.src = "IAX2"; 11669 f.mallocd = 0; 11670 f.offset = 0; 11671 f.len = 0; 11672 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 11673 f.samples = ast_codec_get_samples(&f); 11674 /* We need to byteswap incoming slinear samples from network byte order */ 11675 if (f.subclass.format.id == AST_FORMAT_SLINEAR) 11676 ast_frame_byteswap_be(&f); 11677 } else 11678 f.samples = 0; 11679 iax_frame_wrap(fr, &f); 11680 11681 /* If this is our most recent packet, use it as our basis for timestamping */ 11682 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11683 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 11684 fr->outoforder = 0; 11685 } else { 11686 if (iaxdebug && iaxs[fr->callno]) 11687 ast_debug(1, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass.integer, fr->ts, iaxs[fr->callno]->last); 11688 fr->outoforder = -1; 11689 } 11690 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 11691 duped_fr = iaxfrdup2(fr); 11692 if (duped_fr) { 11693 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 11694 } 11695 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11696 iaxs[fr->callno]->last = fr->ts; 11697 #if 1 11698 if (iaxdebug) 11699 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 11700 #endif 11701 } 11702 11703 /* Always run again */ 11704 ast_variables_destroy(ies.vars); 11705 ast_mutex_unlock(&iaxsl[fr->callno]); 11706 return 1; 11707 }
| static int socket_process_meta | ( | int | packet_len, | |
| struct ast_iax2_meta_hdr * | meta, | |||
| struct sockaddr_in * | sin, | |||
| int | sockfd, | |||
| struct iax_frame * | fr | |||
| ) | [static] |
Definition at line 9743 of file chan_iax2.c.
References ast_codec_get_samples(), ast_format_from_old_bitfield(), AST_FRAME_VOICE, ast_inet_ntoa(), ast_log(), ast_mutex_unlock, ast_test_flag, ast_tvnow(), ast_tvzero(), iax_frame::callno, ast_iax2_meta_trunk_entry::callno, ast_iax2_mini_hdr::callno, ast_iax2_meta_hdr::cmddata, ast_frame::data, ast_iax2_meta_trunk_hdr::data, ast_iax2_meta_hdr::data, ast_frame::datalen, find_callno_locked(), find_tpeer(), fix_peerts(), ast_frame_subclass::format, ast_frame::frametype, iax2_vnak(), IAX_FLAG_FULL, iax_frame_wrap(), IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_STATE_STARTED, iaxfrdup2(), chan_iax2_pvt::last, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_frame::mallocd, ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, NEW_PREVENT, ast_frame::offset, iax_frame::outoforder, ast_frame::ptr, iax2_trunk_peer::rxtrunktime, ast_frame::samples, schedule_delivery(), ast_frame::src, chan_iax2_pvt::state, ast_frame::subclass, iax2_trunk_peer::trunkact, iax_frame::ts, ast_iax2_mini_hdr::ts, ast_iax2_meta_trunk_hdr::ts, and chan_iax2_pvt::voiceformat.
Referenced by socket_process().
09745 { 09746 unsigned char metatype; 09747 struct ast_iax2_meta_trunk_mini *mtm; 09748 struct ast_iax2_meta_trunk_hdr *mth; 09749 struct ast_iax2_meta_trunk_entry *mte; 09750 struct iax2_trunk_peer *tpeer; 09751 unsigned int ts; 09752 void *ptr; 09753 struct timeval rxtrunktime; 09754 struct ast_frame f = { 0, }; 09755 09756 if (packet_len < sizeof(*meta)) { 09757 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 09758 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09759 return 1; 09760 } 09761 09762 if (meta->metacmd != IAX_META_TRUNK) 09763 return 1; 09764 09765 if (packet_len < (sizeof(*meta) + sizeof(*mth))) { 09766 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len, 09767 (int) (sizeof(*meta) + sizeof(*mth))); 09768 return 1; 09769 } 09770 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 09771 ts = ntohl(mth->ts); 09772 metatype = meta->cmddata; 09773 packet_len -= (sizeof(*meta) + sizeof(*mth)); 09774 ptr = mth->data; 09775 tpeer = find_tpeer(sin, sockfd); 09776 if (!tpeer) { 09777 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 09778 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09779 return 1; 09780 } 09781 tpeer->trunkact = ast_tvnow(); 09782 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 09783 tpeer->rxtrunktime = tpeer->trunkact; 09784 rxtrunktime = tpeer->rxtrunktime; 09785 ast_mutex_unlock(&tpeer->lock); 09786 while (packet_len >= sizeof(*mte)) { 09787 /* Process channels */ 09788 unsigned short callno, trunked_ts, len; 09789 09790 if (metatype == IAX_META_TRUNK_MINI) { 09791 mtm = (struct ast_iax2_meta_trunk_mini *) ptr; 09792 ptr += sizeof(*mtm); 09793 packet_len -= sizeof(*mtm); 09794 len = ntohs(mtm->len); 09795 callno = ntohs(mtm->mini.callno); 09796 trunked_ts = ntohs(mtm->mini.ts); 09797 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 09798 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 09799 ptr += sizeof(*mte); 09800 packet_len -= sizeof(*mte); 09801 len = ntohs(mte->len); 09802 callno = ntohs(mte->callno); 09803 trunked_ts = 0; 09804 } else { 09805 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09806 break; 09807 } 09808 /* Stop if we don't have enough data */ 09809 if (len > packet_len) 09810 break; 09811 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0); 09812 if (!fr->callno) 09813 continue; 09814 09815 /* If it's a valid call, deliver the contents. If not, we 09816 drop it, since we don't have a scallno to use for an INVAL */ 09817 /* Process as a mini frame */ 09818 memset(&f, 0, sizeof(f)); 09819 f.frametype = AST_FRAME_VOICE; 09820 if (!iaxs[fr->callno]) { 09821 /* drop it */ 09822 } else if (iaxs[fr->callno]->voiceformat == 0) { 09823 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 09824 iax2_vnak(fr->callno); 09825 } else { 09826 ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->voiceformat); 09827 f.datalen = len; 09828 if (f.datalen >= 0) { 09829 if (f.datalen) 09830 f.data.ptr = ptr; 09831 else 09832 f.data.ptr = NULL; 09833 if (trunked_ts) 09834 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 09835 else 09836 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 09837 /* Don't pass any packets until we're started */ 09838 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09839 struct iax_frame *duped_fr; 09840 09841 /* Common things */ 09842 f.src = "IAX2"; 09843 f.mallocd = 0; 09844 f.offset = 0; 09845 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 09846 f.samples = ast_codec_get_samples(&f); 09847 else 09848 f.samples = 0; 09849 fr->outoforder = 0; 09850 iax_frame_wrap(fr, &f); 09851 duped_fr = iaxfrdup2(fr); 09852 if (duped_fr) 09853 schedule_delivery(duped_fr, 1, 1, &fr->ts); 09854 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) 09855 iaxs[fr->callno]->last = fr->ts; 09856 } 09857 } else { 09858 ast_log(LOG_WARNING, "Datalen < 0?\n"); 09859 } 09860 } 09861 ast_mutex_unlock(&iaxsl[fr->callno]); 09862 ptr += len; 09863 packet_len -= len; 09864 } 09865 09866 return 1; 09867 }
| static int socket_read | ( | int * | id, | |
| int | fd, | |||
| short | events, | |||
| void * | cbdata | |||
| ) | [static] |
Definition at line 9664 of file chan_iax2.c.
References ast_copy_string(), ast_debug, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), iax2_thread::buf, iax2_thread::buf_len, iax2_thread::buf_size, iax2_thread::callno, iax2_thread::cond, ast_iax2_full_hdr::csub, iax2_thread::csub, iax2_thread::curfunc, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), iax2_thread::iofd, iax2_thread::iosin, iax2_thread::iostate, iax2_thread::lock, LOG_WARNING, iax2_thread::readbuf, ast_iax2_full_hdr::scallno, signal_condition(), iax2_thread::sin, thread, ast_iax2_full_hdr::type, and iax2_thread::type.
Referenced by network_thread(), peer_set_srcaddr(), and set_config().
09665 { 09666 struct iax2_thread *thread; 09667 socklen_t len; 09668 time_t t; 09669 static time_t last_errtime = 0; 09670 struct ast_iax2_full_hdr *fh; 09671 09672 if (!(thread = find_idle_thread())) { 09673 time(&t); 09674 if (t != last_errtime) 09675 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n"); 09676 last_errtime = t; 09677 usleep(1); 09678 return 1; 09679 } 09680 09681 len = sizeof(thread->iosin); 09682 thread->iofd = fd; 09683 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 09684 thread->buf_size = sizeof(thread->readbuf); 09685 thread->buf = thread->readbuf; 09686 if (thread->buf_len < 0) { 09687 if (errno != ECONNREFUSED && errno != EAGAIN) 09688 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 09689 handle_error(); 09690 thread->iostate = IAX_IOSTATE_IDLE; 09691 signal_condition(&thread->lock, &thread->cond); 09692 return 1; 09693 } 09694 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 09695 thread->iostate = IAX_IOSTATE_IDLE; 09696 signal_condition(&thread->lock, &thread->cond); 09697 return 1; 09698 } 09699 09700 /* Determine if this frame is a full frame; if so, and any thread is currently 09701 processing a full frame for the same callno from this peer, then drop this 09702 frame (and the peer will retransmit it) */ 09703 fh = (struct ast_iax2_full_hdr *) thread->buf; 09704 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 09705 struct iax2_thread *cur = NULL; 09706 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 09707 09708 AST_LIST_LOCK(&active_list); 09709 AST_LIST_TRAVERSE(&active_list, cur, list) { 09710 if ((cur->ffinfo.callno == callno) && 09711 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 09712 break; 09713 } 09714 if (cur) { 09715 /* we found another thread processing a full frame for this call, 09716 so queue it up for processing later. */ 09717 defer_full_frame(thread, cur); 09718 AST_LIST_UNLOCK(&active_list); 09719 thread->iostate = IAX_IOSTATE_IDLE; 09720 signal_condition(&thread->lock, &thread->cond); 09721 return 1; 09722 } else { 09723 /* this thread is going to process this frame, so mark it */ 09724 thread->ffinfo.callno = callno; 09725 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 09726 thread->ffinfo.type = fh->type; 09727 thread->ffinfo.csub = fh->csub; 09728 AST_LIST_INSERT_HEAD(&active_list, thread, list); 09729 } 09730 AST_LIST_UNLOCK(&active_list); 09731 } 09732 09733 /* Mark as ready and send on its way */ 09734 thread->iostate = IAX_IOSTATE_READY; 09735 #ifdef DEBUG_SCHED_MULTITHREAD 09736 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 09737 #endif 09738 signal_condition(&thread->lock, &thread->cond); 09739 09740 return 1; 09741 }
| static void spawn_dp_lookup | ( | int | callno, | |
| const char * | context, | |||
| const char * | callednum, | |||
| const char * | callerid | |||
| ) | [static] |
Definition at line 9334 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), ast_log(), ast_pthread_create_detached, ast_strdup, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, dp_lookup_thread(), and LOG_WARNING.
Referenced by socket_process().
09335 { 09336 pthread_t newthread; 09337 struct dpreq_data *dpr; 09338 09339 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 09340 return; 09341 09342 dpr->callno = callno; 09343 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 09344 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 09345 if (callerid) 09346 dpr->callerid = ast_strdup(callerid); 09347 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) { 09348 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 09349 } 09350 }
| static int start_network_thread | ( | void | ) | [static] |
Definition at line 12270 of file chan_iax2.c.
References ast_calloc, ast_cond_destroy, ast_cond_init, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_destroy, ast_mutex_init, ast_pthread_create_background, ast_verb, iax2_thread::cond, iax2_process_thread(), IAX_THREAD_TYPE_POOL, iaxthreadcount, iax2_thread::init_cond, iax2_thread::init_lock, iax2_thread::lock, LOG_WARNING, network_thread(), thread, iax2_thread::threadid, iax2_thread::threadnum, and iax2_thread::type.
Referenced by load_module().
12271 { 12272 struct iax2_thread *thread; 12273 int threadcount = 0; 12274 int x; 12275 for (x = 0; x < iaxthreadcount; x++) { 12276 thread = ast_calloc(1, sizeof(*thread)); 12277 if (thread) { 12278 thread->type = IAX_THREAD_TYPE_POOL; 12279 thread->threadnum = ++threadcount; 12280 ast_mutex_init(&thread->lock); 12281 ast_cond_init(&thread->cond, NULL); 12282 ast_mutex_init(&thread->init_lock); 12283 ast_cond_init(&thread->init_cond, NULL); 12284 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 12285 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 12286 ast_mutex_destroy(&thread->lock); 12287 ast_cond_destroy(&thread->cond); 12288 ast_mutex_destroy(&thread->init_lock); 12289 ast_cond_destroy(&thread->init_cond); 12290 ast_free(thread); 12291 thread = NULL; 12292 continue; 12293 } 12294 AST_LIST_LOCK(&idle_list); 12295 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 12296 AST_LIST_UNLOCK(&idle_list); 12297 } 12298 } 12299 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 12300 ast_verb(2, "%d helper threads started\n", threadcount); 12301 return 0; 12302 }
| static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 9041 of file chan_iax2.c.
References iax2_destroy_helper().
Referenced by socket_process().
09042 { 09043 iax2_destroy_helper(iaxs[callno]); 09044 }
| static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2189 of file chan_iax2.c.
References ao2_link, ast_log(), LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by __find_callno(), complete_transfer(), and socket_process().
02190 { 02191 if (!pvt->peercallno) { 02192 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 02193 return; 02194 } 02195 02196 ao2_link(iax_peercallno_pvts, pvt); 02197 }
| static void store_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2170 of file chan_iax2.c.
References ao2_link, ast_log(), LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by try_transfer().
02171 { 02172 if (!pvt->transfercallno) { 02173 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 02174 return; 02175 } 02176 02177 ao2_link(iax_transfercallno_pvts, pvt); 02178 }
| static int timing_read | ( | int * | id, | |
| int | fd, | |||
| short | events, | |||
| void * | cbdata | |||
| ) | [static] |
Definition at line 9224 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_debug, ast_free, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_timer_ack(), ast_tvnow(), ast_verbose, iax2_trunk_expired(), iax2_trunk_peer::lock, send_trunk(), totalcalls, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.
Referenced by network_thread().
09225 { 09226 int res, processed = 0, totalcalls = 0; 09227 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL; 09228 struct timeval now = ast_tvnow(); 09229 09230 if (iaxtrunkdebug) 09231 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize); 09232 09233 if (timer) { 09234 ast_timer_ack(timer, 1); 09235 } 09236 09237 /* For each peer that supports trunking... */ 09238 AST_LIST_LOCK(&tpeers); 09239 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) { 09240 processed++; 09241 res = 0; 09242 ast_mutex_lock(&tpeer->lock); 09243 /* We can drop a single tpeer per pass. That makes all this logic 09244 substantially easier */ 09245 if (!drop && iax2_trunk_expired(tpeer, &now)) { 09246 /* Take it out of the list, but don't free it yet, because it 09247 could be in use */ 09248 AST_LIST_REMOVE_CURRENT(list); 09249 drop = tpeer; 09250 } else { 09251 res = send_trunk(tpeer, &now); 09252 trunk_timed++; 09253 if (iaxtrunkdebug) 09254 ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %d bytes backloged and has hit a high water mark of %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc); 09255 } 09256 totalcalls += res; 09257 res = 0; 09258 ast_mutex_unlock(&tpeer->lock); 09259 } 09260 AST_LIST_TRAVERSE_SAFE_END; 09261 AST_LIST_UNLOCK(&tpeers); 09262 09263 if (drop) { 09264 ast_mutex_lock(&drop->lock); 09265 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 09266 because by the time they could get tpeerlock, we've already grabbed it */ 09267 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 09268 if (drop->trunkdata) { 09269 ast_free(drop->trunkdata); 09270 drop->trunkdata = NULL; 09271 } 09272 ast_mutex_unlock(&drop->lock); 09273 ast_mutex_destroy(&drop->lock); 09274 ast_free(drop); 09275 } 09276 09277 if (iaxtrunkdebug) 09278 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 09279 iaxtrunkdebug = 0; 09280 09281 return 1; 09282 }
| static int transfercallno_pvt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 14510 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().
Referenced by load_objects().
14511 { 14512 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14513 14514 /* The frames_received field is used to hold whether we're matching 14515 * against a full frame or not ... */ 14516 14517 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 14518 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14519 }
| static int transfercallno_pvt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 14503 of file chan_iax2.c.
References chan_iax2_pvt::transfercallno.
Referenced by load_objects().
14504 { 14505 const struct chan_iax2_pvt *pvt = obj; 14506 14507 return pvt->transfercallno; 14508 }
| static int transmit_frame | ( | void * | data | ) | [static] |
Definition at line 4308 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, ast_mutex_lock, ast_mutex_unlock, attempt_transmit(), iax_frame::callno, frame_queue, iax2_sched_add(), iax_frame_free(), iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_packet(), and iax_frame::sentyet.
Referenced by iax2_transmit().
04309 { 04310 struct iax_frame *fr = data; 04311 04312 ast_mutex_lock(&iaxsl[fr->callno]); 04313 04314 fr->sentyet = 1; 04315 04316 if (iaxs[fr->callno]) { 04317 send_packet(fr); 04318 } 04319 04320 if (fr->retries < 0) { 04321 ast_mutex_unlock(&iaxsl[fr->callno]); 04322 /* No retransmit requested */ 04323 iax_frame_free(fr); 04324 } else { 04325 /* We need reliable delivery. Schedule a retransmission */ 04326 AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list); 04327 fr->retries++; 04328 fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr); 04329 ast_mutex_unlock(&iaxsl[fr->callno]); 04330 } 04331 04332 return 0; 04333 }
| static int transmit_trunk | ( | struct iax_frame * | f, | |
| struct sockaddr_in * | sin, | |||
| int | sockfd | |||
| ) | [static] |
Definition at line 3377 of file chan_iax2.c.
References ast_debug, iax_frame::data, iax_frame::datalen, errno, and handle_error().
Referenced by send_trunk().
03378 { 03379 int res; 03380 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 03381 sizeof(*sin)); 03382 if (res < 0) { 03383 ast_debug(1, "Received error: %s\n", strerror(errno)); 03384 handle_error(); 03385 } else 03386 res = 0; 03387 return res; 03388 }
| static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 3079 of file chan_iax2.c.
References ast_calloc, AST_FILE_MODE, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_strlen_zero(), ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, iax_firmware::dead, ast_iax2_firmware_header::devname, errno, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, LOG_WARNING, ast_iax2_firmware_header::magic, MD5Final(), MD5Init(), MD5Update(), iax_firmware::mmaplen, and ast_iax2_firmware_header::version.
Referenced by reload_firmware().
03080 { 03081 struct stat stbuf; 03082 struct iax_firmware *cur = NULL; 03083 int ifd, fd, res, len, chunk; 03084 struct ast_iax2_firmware_header *fwh, fwh2; 03085 struct MD5Context md5; 03086 unsigned char sum[16], buf[1024]; 03087 char *s2, *last; 03088 03089 if (!(s2 = alloca(strlen(s) + 100))) { 03090 ast_log(LOG_WARNING, "Alloca failed!\n"); 03091 return -1; 03092 } 03093 03094 last = strrchr(s, '/'); 03095 if (last) 03096 last++; 03097 else 03098 last = s; 03099 03100 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 03101 03102 if (stat(s, &stbuf) < 0) { 03103 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 03104 return -1; 03105 } 03106 03107 /* Make sure it's not a directory */ 03108 if (S_ISDIR(stbuf.st_mode)) 03109 return -1; 03110 ifd = open(s, O_RDONLY); 03111 if (ifd < 0) { 03112 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 03113 return -1; 03114 } 03115 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE); 03116 if (fd < 0) { 03117 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 03118 close(ifd); 03119 return -1; 03120 } 03121 /* Unlink our newly created file */ 03122 unlink(s2); 03123 03124 /* Now copy the firmware into it */ 03125 len = stbuf.st_size; 03126 while(len) { 03127 chunk = len; 03128 if (chunk > sizeof(buf)) 03129 chunk = sizeof(buf); 03130 res = read(ifd, buf, chunk); 03131 if (res != chunk) { 03132 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 03133 close(ifd); 03134 close(fd); 03135 return -1; 03136 } 03137 res = write(fd, buf, chunk); 03138 if (res != chunk) { 03139 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 03140 close(ifd); 03141 close(fd); 03142 return -1; 03143 } 03144 len -= chunk; 03145 } 03146 close(ifd); 03147 /* Return to the beginning */ 03148 lseek(fd, 0, SEEK_SET); 03149 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 03150 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 03151 close(fd); 03152 return -1; 03153 } 03154 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 03155 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 03156 close(fd); 03157 return -1; 03158 } 03159 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 03160 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 03161 close(fd); 03162 return -1; 03163 } 03164 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 03165 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 03166 close(fd); 03167 return -1; 03168 } 03169 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 03170 if (fwh == MAP_FAILED) { 03171 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 03172 close(fd); 03173 return -1; 03174 } 03175 MD5Init(&md5); 03176 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 03177 MD5Final(sum, &md5); 03178 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 03179 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 03180 munmap((void*)fwh, stbuf.st_size); 03181 close(fd); 03182 return -1; 03183 } 03184 03185 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03186 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 03187 /* Found a candidate */ 03188 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 03189 /* The version we have on loaded is older, load this one instead */ 03190 break; 03191 /* This version is no newer than what we have. Don't worry about it. 03192 We'll consider it a proper load anyhow though */ 03193 munmap((void*)fwh, stbuf.st_size); 03194 close(fd); 03195 return 0; 03196 } 03197 } 03198 03199 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) { 03200 cur->fd = -1; 03201 AST_LIST_INSERT_TAIL(&firmwares, cur, list); 03202 } 03203 03204 if (cur) { 03205 if (cur->fwh) 03206 munmap((void*)cur->fwh, cur->mmaplen); 03207 if (cur->fd > -1) 03208 close(cur->fd); 03209 cur->fwh = fwh; 03210 cur->fd = fd; 03211 cur->mmaplen = stbuf.st_size; 03212 cur->dead = 0; 03213 } 03214 03215 return 0; 03216 }
| static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 8359 of file chan_iax2.c.
References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log(), iax_ie_data::buf, iax_ies::callno, IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, inet_aton(), LOG_WARNING, iax_ie_data::pos, send_command_transfer(), store_by_transfercallno(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, TRANSFER_NONE, chan_iax2_pvt::transfercallno, iax_ies::transferid, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
08360 { 08361 int newcall = 0; 08362 char newip[256]; 08363 struct iax_ie_data ied; 08364 struct sockaddr_in new; 08365 08366 08367 memset(&ied, 0, sizeof(ied)); 08368 if (ies->apparent_addr) 08369 memmove(&new, ies->apparent_addr, sizeof(new)); 08370 if (ies->callno) 08371 newcall = ies->callno; 08372 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 08373 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08374 return -1; 08375 } 08376 pvt->transfercallno = newcall; 08377 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 08378 inet_aton(newip, &pvt->transfer.sin_addr); 08379 pvt->transfer.sin_family = AF_INET; 08380 pvt->transferid = ies->transferid; 08381 /* only store by transfercallno if this is a new transfer, 08382 * just in case we get a duplicate TXREQ */ 08383 if (pvt->transferring == TRANSFER_NONE) { 08384 store_by_transfercallno(pvt); 08385 } 08386 pvt->transferring = TRANSFER_BEGIN; 08387 08388 if (ies->transferid) 08389 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 08390 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 08391 return 0; 08392 }
| static iax2_format uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1625 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), handle_call_token(), and socket_process().
01626 { 01627 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01628 if (csub & IAX_FLAG_SC_LOG) { 01629 /* special case for 'compressed' -1 */ 01630 if (csub == 0xff) 01631 return -1; 01632 else 01633 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01634 } 01635 else 01636 return csub; 01637 }
| static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 8654 of file chan_iax2.c.
References ao2_unlink, AST_SCHED_DEL, iax2_peer::expire, peer_unref(), and iax2_peer::pokeexpire.
Referenced by __expire_registry(), build_peer(), and prune_peers().
08655 { 08656 if (peer->expire > -1) { 08657 if (!AST_SCHED_DEL(sched, peer->expire)) { 08658 peer->expire = -1; 08659 peer_unref(peer); 08660 } 08661 } 08662 08663 if (peer->pokeexpire > -1) { 08664 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 08665 peer->pokeexpire = -1; 08666 peer_unref(peer); 08667 } 08668 } 08669 08670 ao2_unlink(peers, peer); 08671 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 14468 of file chan_iax2.c.
References __unload_module(), and ast_custom_function_unregister().
14469 { 14470 ast_custom_function_unregister(&iaxpeer_function); 14471 ast_custom_function_unregister(&iaxvar_function); 14472 return __unload_module(); 14473 }
| static void unlock_both | ( | unsigned short | callno0, | |
| unsigned short | callno1 | |||
| ) | [static] |
Definition at line 5525 of file chan_iax2.c.
References ast_mutex_unlock.
Referenced by iax2_bridge().
05526 { 05527 ast_mutex_unlock(&iaxsl[callno1]); 05528 ast_mutex_unlock(&iaxsl[callno0]); 05529 }
| static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 4068 of file chan_iax2.c.
References iax_frame::af, ast_debug, AST_FRAME_VIDEO, iax_frame::callno, ast_frame::frametype, chan_iax2_pvt::last, and iax_frame::ts.
Referenced by schedule_delivery().
04069 { 04070 /* Video mini frames only encode the lower 15 bits of the session 04071 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 04072 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 04073 const int lower_mask = (1 << ts_shift) - 1; 04074 const int upper_mask = ~lower_mask; 04075 const int last_upper = iaxs[fr->callno]->last & upper_mask; 04076 04077 if ( (fr->ts & upper_mask) == last_upper ) { 04078 const int x = fr->ts - iaxs[fr->callno]->last; 04079 const int threshold = (ts_shift == 15) ? 25000 : 50000; 04080 04081 if (x < -threshold) { 04082 /* Sudden big jump backwards in timestamp: 04083 What likely happened here is that miniframe timestamp has circled but we haven't 04084 gotten the update from the main packet. We'll just pretend that we did, and 04085 update the timestamp appropriately. */ 04086 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 04087 if (iaxdebug) 04088 ast_debug(1, "schedule_delivery: pushed forward timestamp\n"); 04089 } else if (x > threshold) { 04090 /* Sudden apparent big jump forwards in timestamp: 04091 What's likely happened is this is an old miniframe belonging to the previous 04092 top 15 or 16-bit timestamp that has turned up out of order. 04093 Adjust the timestamp appropriately. */ 04094 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 04095 if (iaxdebug) 04096 ast_debug(1, "schedule_delivery: pushed back timestamp\n"); 04097 } 04098 } 04099 }
| static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 4103 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), iax2_sched_replace(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, and chan_iax2_pvt::rxcore.
Referenced by __get_from_jb(), and schedule_delivery().
04104 { 04105 int when; 04106 04107 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 04108 04109 when = jb_next(pvt->jb) - when; 04110 04111 if (when <= 0) { 04112 /* XXX should really just empty until when > 0.. */ 04113 when = 1; 04114 } 04115 04116 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 04117 CALLNO_TO_PTR(pvt->callno)); 04118 }
| static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 2097 of file chan_iax2.c.
References ast_debug, and TRUNK_CALL_START.
Referenced by __find_callno(), and make_trunk().
02098 { 02099 int max = 1; 02100 int x; 02101 /* XXX Prolly don't need locks here XXX */ 02102 for (x=1;x<TRUNK_CALL_START - 1; x++) { 02103 if (iaxs[x]) 02104 max = x + 1; 02105 } 02106 maxnontrunkcall = max; 02107 if (iaxdebug) 02108 ast_debug(1, "New max nontrunk callno is %d\n", max); 02109 }
| static void update_max_trunk | ( | void | ) | [static] |
Definition at line 2080 of file chan_iax2.c.
References ARRAY_LEN, ast_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy(), and make_trunk().
02081 { 02082 int max = TRUNK_CALL_START; 02083 int x; 02084 02085 /* XXX Prolly don't need locks here XXX */ 02086 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 02087 if (iaxs[x]) { 02088 max = x + 1; 02089 } 02090 } 02091 02092 maxtrunkcall = max; 02093 if (iaxdebug) 02094 ast_debug(1, "New max trunk callno is %d\n", max); 02095 }
| static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3515 of file chan_iax2.c.
References build_rand_pad(), iax_frame::callno, iax_frame::data, iax_frame::datalen, iax_frame::dcallno, ast_iax2_full_hdr::dcallno, decode_frame(), iax_frame::ecx, iax_frame::encmethods, encrypt_frame(), IAX_FLAG_RETRANS, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, iax_frame::mydcx, and iax_frame::semirand.
Referenced by __attempt_transmit().
03516 { 03517 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 03518 struct ast_iax2_full_hdr *fh = f->data; 03519 struct ast_frame af; 03520 03521 /* if frame is encrypted. decrypt before updating it. */ 03522 if (f->encmethods) { 03523 decode_frame(&f->mydcx, fh, &af, &f->datalen); 03524 } 03525 /* Mark this as a retransmission */ 03526 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 03527 /* Update iseqno */ 03528 f->iseqno = iaxs[f->callno]->iseqno; 03529 fh->iseqno = f->iseqno; 03530 03531 /* Now re-encrypt the frame */ 03532 if (f->encmethods) { 03533 /* since this is a retransmit frame, create a new random padding 03534 * before re-encrypting. */ 03535 build_rand_pad(f->semirand, sizeof(f->semirand)); 03536 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen); 03537 } 03538 return 0; 03539 }
| static int update_registry | ( | struct sockaddr_in * | sin, | |
| int | callno, | |||
| char * | devtype, | |||
| int | fd, | |||
| unsigned short | refresh | |||
| ) | [static] |
Definition at line 8773 of file chan_iax2.c.
References iax2_peer::addr, ast_app_inboxcount(), ast_db_del(), ast_db_put(), AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_SCHED_DEL, ast_sockaddr_cmp(), ast_sockaddr_from_sin, ast_sockaddr_to_sin, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_verb, iax_ie_data::buf, iax2_peer::cid_name, iax2_peer::cid_num, context, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, LOG_NOTICE, LOG_WARNING, mailbox, iax2_peer::mailbox, manager_event, iax2_peer::maxcallno, iax2_peer::name, peer_ref(), peer_unref(), peercnt_modify(), iax_ie_data::pos, realtime_update_peer(), register_peer_exten(), send_command_final(), iax2_peer::sockfd, strsep(), version, and iax2_peer::zonetag.
Referenced by socket_process().
08774 { 08775 /* Called from IAX thread only, with proper iaxsl lock */ 08776 struct iax_ie_data ied = { 08777 .pos = 0, 08778 }; 08779 struct iax2_peer *p; 08780 int msgcount; 08781 char data[80]; 08782 int version; 08783 const char *peer_name; 08784 int res = -1; 08785 struct ast_sockaddr sockaddr; 08786 08787 ast_sockaddr_from_sin(&sockaddr, sin); 08788 08789 peer_name = ast_strdupa(iaxs[callno]->peer); 08790 08791 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 08792 ast_mutex_unlock(&iaxsl[callno]); 08793 if (!(p = find_peer(peer_name, 1))) { 08794 ast_mutex_lock(&iaxsl[callno]); 08795 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 08796 return -1; 08797 } 08798 ast_mutex_lock(&iaxsl[callno]); 08799 if (!iaxs[callno]) 08800 goto return_unref; 08801 08802 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 08803 if (sin->sin_addr.s_addr) { 08804 time_t nowtime; 08805 time(&nowtime); 08806 realtime_update_peer(peer_name, &sockaddr, nowtime); 08807 } else { 08808 realtime_update_peer(peer_name, &sockaddr, 0); 08809 } 08810 } 08811 08812 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) { 08813 if (iax2_regfunk) { 08814 iax2_regfunk(p->name, 1); 08815 } 08816 08817 /* modify entry in peercnts table as _not_ registered */ 08818 peercnt_modify(0, 0, &p->addr); 08819 08820 /* Stash the IP address from which they registered */ 08821 ast_sockaddr_from_sin(&p->addr, sin); 08822 08823 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 08824 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 08825 ast_db_put("IAX/Registry", p->name, data); 08826 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 08827 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 08828 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\nPost: %d\r\n", p->name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 08829 register_peer_exten(p, 1); 08830 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08831 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) { 08832 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name, 08833 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 08834 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 08835 register_peer_exten(p, 0); 08836 ast_db_del("IAX/Registry", p->name); 08837 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */ 08838 } 08839 /* Update the host */ 08840 /* Verify that the host is really there */ 08841 iax2_poke_peer(p, callno); 08842 } 08843 08844 /* modify entry in peercnts table as registered */ 08845 if (p->maxcallno) { 08846 peercnt_modify(1, p->maxcallno, &p->addr); 08847 } 08848 08849 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 08850 if (!iaxs[callno]) { 08851 res = -1; 08852 goto return_unref; 08853 } 08854 08855 /* Store socket fd */ 08856 p->sockfd = fd; 08857 /* Setup the expiry */ 08858 if (p->expire > -1) { 08859 if (!AST_SCHED_DEL(sched, p->expire)) { 08860 p->expire = -1; 08861 peer_unref(p); 08862 } 08863 } 08864 /* treat an unspecified refresh interval as the minimum */ 08865 if (!refresh) 08866 refresh = min_reg_expire; 08867 if (refresh > max_reg_expire) { 08868 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08869 p->name, max_reg_expire, refresh); 08870 p->expiry = max_reg_expire; 08871 } else if (refresh < min_reg_expire) { 08872 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08873 p->name, min_reg_expire, refresh); 08874 p->expiry = min_reg_expire; 08875 } else { 08876 p->expiry = refresh; 08877 } 08878 if (p->expiry && sin->sin_addr.s_addr) { 08879 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08880 if (p->expire == -1) 08881 peer_unref(p); 08882 } 08883 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 08884 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 08885 if (sin->sin_addr.s_addr) { 08886 struct sockaddr_in peer_addr; 08887 08888 ast_sockaddr_to_sin(&p->addr, &peer_addr); 08889 08890 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 08891 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr); 08892 if (!ast_strlen_zero(p->mailbox)) { 08893 struct ast_event *event; 08894 int new, old; 08895 char *mailbox, *context; 08896 08897 context = mailbox = ast_strdupa(p->mailbox); 08898 strsep(&context, "@"); 08899 if (ast_strlen_zero(context)) 08900 context = "default"; 08901 08902 event = ast_event_get_cached(AST_EVENT_MWI, 08903 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 08904 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 08905 AST_EVENT_IE_END); 08906 if (event) { 08907 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 08908 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 08909 ast_event_destroy(event); 08910 } else { /* Fall back on checking the mailbox directly */ 08911 ast_app_inboxcount(p->mailbox, &new, &old); 08912 } 08913 08914 if (new > 255) { 08915 new = 255; 08916 } 08917 if (old > 255) { 08918 old = 255; 08919 } 08920 msgcount = (old << 8) | new; 08921 08922 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 08923 } 08924 if (ast_test_flag64(p, IAX_HASCALLERID)) { 08925 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 08926 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 08927 } 08928 } 08929 version = iax_check_version(devtype); 08930 if (version) 08931 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 08932 08933 res = 0; 08934 08935 return_unref: 08936 peer_unref(p); 08937 08938 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 08939 }
| static int user_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1760 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, iax2_user::name, name, and OBJ_KEY.
Referenced by load_objects().
01761 { 01762 struct iax2_user *user = obj, *user2 = arg; 01763 const char *name = arg; 01764 01765 return !strcmp(user->name, flags & OBJ_KEY ? name : user2->name) ? 01766 CMP_MATCH | CMP_STOP : 0; 01767 }
| static int user_delme_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 13005 of file chan_iax2.c.
References ast_set_flag64, and IAX_DELME.
Referenced by delete_users().
13006 { 13007 struct iax2_user *user = obj; 13008 13009 ast_set_flag64(user, IAX_DELME); 13010 13011 return 0; 13012 }
| static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 12733 of file chan_iax2.c.
References ast_free_ha(), ast_string_field_free_memory, ast_variables_destroy(), iax2_user::contexts, free_context(), iax2_user::ha, and iax2_user::vars.
Referenced by build_user().
12734 { 12735 struct iax2_user *user = obj; 12736 12737 ast_free_ha(user->ha); 12738 free_context(user->contexts); 12739 if(user->vars) { 12740 ast_variables_destroy(user->vars); 12741 user->vars = NULL; 12742 } 12743 ast_string_field_free_memory(user); 12744 }
| static int user_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1749 of file chan_iax2.c.
References ast_str_hash(), iax2_user::name, name, and OBJ_KEY.
Referenced by load_objects().
01750 { 01751 const struct iax2_user *user = obj; 01752 const char *name = obj; 01753 01754 return ast_str_hash(flags & OBJ_KEY ? name : user->name); 01755 }
Definition at line 1802 of file chan_iax2.c.
References ao2_ref.
01803 { 01804 ao2_ref(user, +1); 01805 return user; 01806 }
Definition at line 1808 of file chan_iax2.c.
References ao2_ref.
Referenced by authenticate_request(), authenticate_verify(), build_user(), calltoken_required(), check_access(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_users(), iax2_destroy_helper(), prune_users(), requirecalltoken_mark_auto(), set_config(), and users_data_provider_get().
01809 { 01810 ao2_ref(user, -1); 01811 return NULL; 01812 }
| static int users_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 14673 of file chan_iax2.c.
References iax2_user::amaflags, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cdr_flags2str(), ast_copy_string(), ast_data_add_bool(), ast_data_add_int(), ast_data_add_node(), ast_data_add_password(), ast_data_add_str(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_strlen_zero(), ast_test_flag64, iax2_user::authmethods, iax2_user::capability, iax2_context::context, iax2_user::contexts, DEFAULT_CONTEXT, iax2_user::ha, iax2_data_add_codecs(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, iax2_user::inkeys, iax2_user::secret, and user_unref().
14675 { 14676 struct ast_data *data_user, *data_authmethods, *data_enum_node; 14677 struct iax2_user *user; 14678 struct ao2_iterator i; 14679 char auth[90]; 14680 char *pstr = ""; 14681 14682 i = ao2_iterator_init(users, 0); 14683 for (; (user = ao2_iterator_next(&i)); user_unref(user)) { 14684 data_user = ast_data_add_node(data_root, "user"); 14685 if (!data_user) { 14686 continue; 14687 } 14688 14689 ast_data_add_structure(iax2_user, data_user, user); 14690 14691 iax2_data_add_codecs(data_user, "codecs", user->capability); 14692 14693 if (!ast_strlen_zero(user->secret)) { 14694 ast_copy_string(auth, user->secret, sizeof(auth)); 14695 } else if (!ast_strlen_zero(user->inkeys)) { 14696 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys); 14697 } else { 14698 ast_copy_string(auth, "no secret", sizeof(auth)); 14699 } 14700 ast_data_add_password(data_user, "secret", auth); 14701 14702 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT); 14703 14704 /* authmethods */ 14705 data_authmethods = ast_data_add_node(data_user, "authmethods"); 14706 if (!data_authmethods) { 14707 ast_data_remove_node(data_root, data_user); 14708 continue; 14709 } 14710 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA); 14711 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5); 14712 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT); 14713 14714 /* amaflags */ 14715 data_enum_node = ast_data_add_node(data_user, "amaflags"); 14716 if (!data_enum_node) { 14717 ast_data_remove_node(data_root, data_user); 14718 continue; 14719 } 14720 ast_data_add_int(data_enum_node, "value", user->amaflags); 14721 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags)); 14722 14723 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0); 14724 14725 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) { 14726 pstr = "REQ only"; 14727 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) { 14728 pstr = "disabled"; 14729 } else { 14730 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host"; 14731 } 14732 ast_data_add_str(data_user, "codec-preferences", pstr); 14733 14734 if (!ast_data_search_match(search, data_user)) { 14735 ast_data_remove_node(data_root, data_user); 14736 } 14737 } 14738 ao2_iterator_destroy(&i); 14739 14740 return 0; 14741 }
| static void vnak_retransmit | ( | int | callno, | |
| int | last | |||
| ) | [static] |
Definition at line 9142 of file chan_iax2.c.
References AST_LIST_TRAVERSE, f, frame_queue, iax_frame::oseqno, iax_frame::retries, and send_packet().
Referenced by socket_process().
09143 { 09144 struct iax_frame *f; 09145 09146 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) { 09147 /* Send a copy immediately */ 09148 if (((unsigned char) (f->oseqno - last) < 128) && 09149 (f->retries >= 0)) { 09150 send_packet(f); 09151 } 09152 } 09153 }
| static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 5336 of file chan_iax2.c.
References chan_iax2_pvt::callno, DEADLOCK_AVOIDANCE, and chan_iax2_pvt::peercallno.
Referenced by iax2_indicate(), and iax2_setoption().
05337 { 05338 unsigned short callno = pvt->callno; 05339 05340 if (!pvt->peercallno) { 05341 /* We don't know the remote side's call number, yet. :( */ 05342 int count = 10; 05343 while (count-- && pvt && !pvt->peercallno) { 05344 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 05345 pvt = iaxs[callno]; 05346 } 05347 if (!pvt->peercallno) { 05348 return -1; 05349 } 05350 } 05351 05352 return 0; 05353 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto", } [static] |
Definition at line 14896 of file chan_iax2.c.
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 379 of file chan_iax2.c.
Referenced by ast_async_goto(), build_peer(), check_peer_ok(), create_addr_from_peer(), func_channel_write_real(), and tds_log().
int adsi = 0 [static] |
Definition at line 383 of file chan_iax2.c.
int amaflags = 0 [static] |
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 14896 of file chan_iax2.c.
int authdebug = 0 [static] |
Definition at line 290 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 291 of file chan_iax2.c.
struct ao2_container* callno_limits [static] |
Table containing custom callno limit rules for a range of ip addresses.
Definition at line 891 of file chan_iax2.c.
struct ao2_container* callno_pool [static] |
table of available call numbers
Definition at line 846 of file chan_iax2.c.
const unsigned int CALLNO_POOL_BUCKETS = 2699 [static] |
Definition at line 851 of file chan_iax2.c.
struct ao2_container* callno_pool_trunk [static] |
table of available trunk call numbers
Definition at line 849 of file chan_iax2.c.
struct ao2_container* calltoken_ignores [static] |
Table containing ip addresses not requiring calltoken validation
Definition at line 894 of file chan_iax2.c.
struct ast_cli_entry cli_iax2[] [static] |
Definition at line 14211 of file chan_iax2.c.
| unsigned int cos |
Definition at line 301 of file chan_iax2.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1098 of file chan_iax2.c.
Referenced by handle_cli_iax2_set_debug(), iax_outputframe(), reload_config(), sip_debug_test_addr(), sip_do_debug(), sip_do_debug_ip(), and sip_do_debug_peer().
uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048 [static] |
Definition at line 896 of file chan_iax2.c.
uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static] |
Definition at line 898 of file chan_iax2.c.
char default_parkinglot[AST_MAX_CONTEXT] [static] |
Definition at line 268 of file chan_iax2.c.
Referenced by create_dynamic_parkinglot(), handle_parkedcalls(), load_config(), park_call_exec(), park_space_reserve(), parked_call_exec(), and xfer_park_call_helper().
int defaultsockfd = -1 [static] |
Definition at line 313 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 384 of file chan_iax2.c.
Definition at line 862 of file chan_iax2.c.
struct { ... } frame_queue[IAX_MAX_CALLS + 1] [static] |
a list of frames that may need to be retransmitted
Contents protected by the iaxsl[] locks
Referenced by __attempt_transmit(), complete_transfer(), handle_cli_iax2_show_stats(), pvt_destructor(), resend_with_token(), socket_process(), transmit_frame(), and vnak_retransmit().
int global_max_trunk_mtu [static] |
Maximum MTU, 0 if not used
Definition at line 263 of file chan_iax2.c.
uint16_t global_maxcallno [static] |
Definition at line 900 of file chan_iax2.c.
uint16_t global_maxcallno_nonval [static] |
Total num of call numbers allowed to be allocated without calltoken validation
Definition at line 903 of file chan_iax2.c.
int global_rtautoclear = 120 [static] |
Definition at line 435 of file chan_iax2.c.
struct ast_flags64 globalflags = { 0 } [static] |
Definition at line 387 of file chan_iax2.c.
iax2_format iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 365 of file chan_iax2.c.
struct ast_data_entry iax2_data_providers[] [static] |
Initial value:
{
AST_DATA_ENTRY("asterisk/channel/iax2/peers", &peers_data_provider),
AST_DATA_ENTRY("asterisk/channel/iax2/users", &users_data_provider),
}
Definition at line 14753 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 385 of file chan_iax2.c.
int(* iax2_regfunk)(const char *username, int onoff) = NULL [static] |
Referenced by __expire_registry(), reg_source_db(), and update_registry().
struct ast_switch iax2_switch [static] |
Definition at line 14097 of file chan_iax2.c.
struct ast_channel_tech iax2_tech [static] |
Definition at line 1216 of file chan_iax2.c.
struct ast_datastore_info iax2_variable_datastore_info [static] |
Initial value:
{
.type = "IAX2_VARIABLE",
.duplicate = iax2_dup_variable_datastore,
.destroy = iax2_free_variable_datastore,
}
Definition at line 1330 of file chan_iax2.c.
struct ao2_container* iax_peercallno_pvts [static] |
Another container of iax2_pvt structures.
Active IAX2 pvt structs are also stored in this container, if they are a part of an active call where we know the remote side's call number. The reason for this is that incoming media frames do not contain our call number. So, instead of having to iterate the entire iaxs array, we use this container to look up calls where the remote side is using a given call number.
Definition at line 1075 of file chan_iax2.c.
struct ao2_container* iax_transfercallno_pvts [static] |
Another container of iax2_pvt structures.
* Active IAX2 pvt stucts used during transfering a call are stored here.
Definition at line 1091 of file chan_iax2.c.
int iaxactivethreadcount = 0 [static] |
Definition at line 635 of file chan_iax2.c.
Referenced by iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 292 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 367 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 295 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 297 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 633 of file chan_iax2.c.
Referenced by find_idle_thread(), and iax2_process_thread().
int iaxdynamicthreadnum = 0 [static] |
int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static] |
struct ast_custom_function iaxpeer_function [static] |
Initial value:
{
.name = "IAXPEER",
.read = function_iaxpeer,
}
Definition at line 14017 of file chan_iax2.c.
struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS+1] [static] |
an array of iax2 pvt structures
The container for active chan_iax2_pvt structures is implemented as an array for extremely quick direct access to the correct pvt structure based on the local call number. The local call number is used as the index into the array where the associated pvt structure is stored.
Definition at line 1064 of file chan_iax2.c.
ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static] |
chan_iax2_pvt structure locks
These locks are used when accessing a pvt structure in the iaxs array. The index used here is the same as used in the iaxs array. It is the local call number for the associated pvt struct.
Definition at line 1084 of file chan_iax2.c.
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 631 of file chan_iax2.c.
Referenced by handle_cli_iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 369 of file chan_iax2.c.
struct ast_custom_function iaxvar_function [static] |
Initial value:
{
.name = "IAXVAR",
.read = acf_iaxvar_read,
.write = acf_iaxvar_write,
}
Definition at line 9935 of file chan_iax2.c.
struct io_context* io [static] |
Definition at line 360 of file chan_iax2.c.
int jittertargetextra = 40 [static] |
Definition at line 283 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 279 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 270 of file chan_iax2.c.
Definition at line 862 of file chan_iax2.c.
int last_authmethod = 0 [static] |
Definition at line 293 of file chan_iax2.c.
const time_t MAX_CALLTOKEN_DELAY = 10 [static] |
Definition at line 868 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 305 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 277 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 276 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 280 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 282 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 1165 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 1164 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 304 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 380 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 381 of file chan_iax2.c.
Referenced by build_peer(), check_peer_ok(), create_addr_from_peer(), set_peer_defaults(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 311 of file chan_iax2.c.
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
Definition at line 389 of file chan_iax2.c.
int network_change_event_sched_id = -1 [static] |
Definition at line 274 of file chan_iax2.c.
struct ast_event_sub* network_change_event_subscription [static] |
subscription id for network change events
Definition at line 273 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 312 of file chan_iax2.c.
char* papp = "IAX2Provision" [static] |
Definition at line 11974 of file chan_iax2.c.
struct ao2_container* peercnts [static] |
Table containing peercnt objects for every ip address consuming a callno
Definition at line 888 of file chan_iax2.c.
struct ao2_container* peers [static] |
Definition at line 882 of file chan_iax2.c.
struct ast_data_handler peers_data_provider [static] |
Initial value:
{
.version = AST_DATA_HANDLER_VERSION,
.get = peers_data_provider_get
}
Definition at line 14743 of file chan_iax2.c.
int ping_time = 21 [static] |
Definition at line 278 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 254 of file chan_iax2.c.
Referenced by ast_best_codec(), build_peer(), build_user(), check_access(), create_addr(), new_iax(), and set_config().
struct { ... } qos [static] |
Referenced by config_load(), config_parse_variables(), peer_set_srcaddr(), reload_config(), set_config(), and start_rtp().
int randomcalltokendata [static] |
Definition at line 866 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 271 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 281 of file chan_iax2.c.
struct ast_sched_context* sched [static] |
Definition at line 361 of file chan_iax2.c.
int srvlookup = 0 [static] |
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 256 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 371 of file chan_iax2.c.
Definition at line 309 of file chan_iax2.c.
Referenced by find_timer(), kqueue_timer_hash(), kqueue_timer_open(), process_dahdi(), pthread_timer_ack(), pthread_timer_close(), pthread_timer_destructor(), pthread_timer_disable_continuous(), pthread_timer_enable_continuous(), pthread_timer_get_event(), pthread_timer_hash(), pthread_timer_open(), pthread_timer_set_rate(), run_timer(), softmix_bridge_thread(), timer_destroy(), timerfd_timer_hash(), timerfd_timer_open(), and timing_test().
| unsigned int tos |
Definition at line 300 of file chan_iax2.c.
uint16_t total_nonval_callno_used = 0 [static] |
Definition at line 905 of file chan_iax2.c.
struct ast_taskprocessor* transmit_processor [static] |
Definition at line 864 of file chan_iax2.c.
int trunk_maxmtu [static] |
Definition at line 264 of file chan_iax2.c.
int trunk_nmaxmtu [static] |
Trunk MTU statistics
Definition at line 264 of file chan_iax2.c.
int trunk_timed [static] |
Definition at line 264 of file chan_iax2.c.
int trunk_untimed [static] |
Definition at line 264 of file chan_iax2.c.
int trunkfreq = 20 [static] |
Definition at line 287 of file chan_iax2.c.
int trunkmaxsize = MAX_TRUNKDATA [static] |
Definition at line 288 of file chan_iax2.c.
struct ao2_container* users [static] |
Definition at line 885 of file chan_iax2.c.
struct ast_data_handler users_data_provider [static] |
Initial value:
{
.version = AST_DATA_HANDLER_VERSION,
.get = users_data_provider_get
}
Definition at line 14748 of file chan_iax2.c.
1.5.6