Mon Aug 31 12:30:23 2015

Asterisk developer's documentation


chan_iax2.c File Reference

Implementation of Inter-Asterisk eXchange Version 2 as specified in RFC 5456. More...

#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  addr_range
struct  callno_entry
struct  chan_iax2_pvt
struct  create_addr_info
struct  dpreq_data
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  parsed_dial_string
struct  signaling_queue_entry

Defines

#define ACN_FORMAT1   "%-20.25s %4u %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
#define ACN_FORMAT2   "%s %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
#define CALLNO_TO_PTR(a)   ((void *)(unsigned long)(a))
#define CALLTOKEN_HASH_FORMAT   "%s%d%u%d"
#define CALLTOKEN_IE_FORMAT   "%u?%s"
#define DATA_EXPORT_IAX2_PEER(MEMBER)
#define DATA_EXPORT_IAX2_USER(MEMBER)
#define DEBUG_SCHED_MULTITHREAD
#define DEBUG_SUPPORT
#define DEFAULT_CONTEXT   "default"
#define DEFAULT_DROP   3
#define DEFAULT_FREQ_NOTOK   10 * 1000
#define DEFAULT_FREQ_OK   60 * 1000
#define DEFAULT_MAX_THREAD_COUNT   100
#define DEFAULT_MAXMS   2000
#define DEFAULT_RETRY_TIME   1000
#define DEFAULT_THREAD_COUNT   10
#define DEFAULT_TRUNKDATA   640 * 10
#define DONT_RESCHEDULE   -2
#define FORMAT   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n"
#define FORMAT   "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
#define FORMAT   "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n"
#define FORMAT   "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
#define FORMAT2   "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
#define FORMAT2   "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
#define FORMAT2   "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n"
#define FORMAT2   "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
#define FORMATB   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
#define GAMMA   (0.01)
#define IAX2_TRUNK_PREFACE   (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
#define IAX_ALLOWFWDOWNLOAD   (uint64_t)(1 << 26)
#define IAX_ALREADYGONE   (uint64_t)(1 << 9)
#define IAX_CALLENCRYPTED(pvt)   (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED))
#define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF
#define IAX_CAPABILITY_LOWBANDWIDTH
#define IAX_CAPABILITY_LOWFREE
#define IAX_CAPABILITY_MEDBANDWIDTH
#define IAX_CODEC_NOCAP   (uint64_t)(1 << 16)
#define IAX_CODEC_NOPREFS   (uint64_t)(1 << 15)
#define IAX_CODEC_USER_FIRST   (uint64_t)(1 << 14)
#define IAX_DEBUGDIGEST(msg, key)
#define IAX_DELAYPBXSTART   (uint64_t)(1 << 25)
#define IAX_DELME   (uint64_t)(1 << 1)
#define IAX_DYNAMIC   (uint64_t)(1 << 6)
#define IAX_ENCRYPTED   (uint64_t)(1 << 12)
#define IAX_FORCE_ENCRYPT   (uint64_t)(1 << 30)
#define IAX_FORCEJITTERBUF   (uint64_t)(1 << 20)
#define IAX_HASCALLERID   (uint64_t)(1 << 0)
#define IAX_IMMEDIATE   (uint64_t)(1 << 27)
#define IAX_KEYPOPULATED   (uint64_t)(1 << 13)
#define IAX_MAXAUTHREQ   (uint64_t)(1 << 24)
#define IAX_NOTRANSFER   (uint64_t)(1 << 4)
#define IAX_PROVISION   (uint64_t)(1 << 10)
#define IAX_QUELCH   (uint64_t)(1 << 11)
#define IAX_RECVCONNECTEDLINE   (uint64_t)(1 << 29)
#define IAX_RTAUTOCLEAR   (uint64_t)(1 << 19)
#define IAX_RTCACHEFRIENDS   (uint64_t)(1 << 17)
#define IAX_RTIGNOREREGEXPIRE   (uint64_t)(1 << 21)
#define IAX_RTSAVE_SYSNAME   (uint64_t)(1 << 8)
#define IAX_RTUPDATE   (uint64_t)(1 << 18)
#define IAX_SENDANI   (uint64_t)(1 << 7)
#define IAX_SENDCONNECTEDLINE   (uint64_t)(1 << 28)
#define IAX_SHRINKCALLERID   (uint64_t)(1 << 31)
#define IAX_TEMPONLY   (uint64_t)(1 << 2)
#define IAX_TRANSFERMEDIA   (uint64_t)(1 << 23)
#define IAX_TRUNK   (uint64_t)(1 << 3)
#define IAX_TRUNKTIMESTAMPS   (uint64_t)(1 << 22)
#define IAX_USEJITTERBUF   (uint64_t)(1 << 5)
#define MARK_IAX_SUBCLASS_TX   0x8000
#define MAX_JITTER_BUFFER   50
#define MAX_PEER_BUCKETS   563
#define MAX_RETRY_TIME   10000
#define MAX_TIMESTAMP_SKEW   160
#define MAX_TRUNK_MTU   1240
 Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240.
#define MAX_TRUNKDATA   640 * 200
#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS
#define MEMORY_SIZE   100
#define MIN_JITTER_BUFFER   10
#define MIN_RETRY_TIME   100
#define MIN_REUSE_TIME   60
#define PTR_TO_CALLNO(a)   ((unsigned short)(unsigned long)(a))
#define SCHED_MULTITHREADED
#define schedule_action(func, data)   __schedule_action(func, data, __PRETTY_FUNCTION__)
#define TRUNK_CALL_START   (IAX_MAX_CALLS / 2)
#define TS_GAP_FOR_JB_RESYNC   5000
#define update_max_nontrunk()   do { } while (0)
#define update_max_trunk()   do { } while (0)

Enumerations

enum  {
  CACHE_FLAG_EXISTS = (1 << 0), CACHE_FLAG_NONEXISTENT = (1 << 1), CACHE_FLAG_CANEXIST = (1 << 2), CACHE_FLAG_PENDING = (1 << 3),
  CACHE_FLAG_TIMEOUT = (1 << 4), CACHE_FLAG_TRANSMITTED = (1 << 5), CACHE_FLAG_UNKNOWN = (1 << 6), CACHE_FLAG_MATCHMORE = (1 << 7)
}
enum  { NEW_PREVENT = 0, NEW_ALLOW = 1, NEW_FORCE = 2, NEW_ALLOW_CALLTOKEN_VALIDATED = 3 }
enum  calltoken_peer_enum { CALLTOKEN_DEFAULT = 0, CALLTOKEN_YES = 1, CALLTOKEN_AUTO = 2, CALLTOKEN_NO = 3 }
 

Call token validation settings.

More...
enum  iax2_state { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2) }
enum  iax2_thread_iostate { IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_SCHEDREADY }
enum  iax2_thread_type { IAX_THREAD_TYPE_POOL, IAX_THREAD_TYPE_DYNAMIC }
enum  iax_reg_state {
  REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED,
  REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH
}
enum  iax_transfer_state {
  TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED,
  TRANSFER_PASSTHROUGH, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED,
  TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS
}

Functions

static void __attempt_transmit (const void *data)
static void __auth_reject (const void *nothing)
static void __auto_congest (const void *nothing)
static void __auto_hangup (const void *nothing)
static int __do_deliver (void *data)
static void __expire_registry (const void *data)
static int __find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
static void __get_from_jb (const void *p)
static void __iax2_do_register_s (const void *data)
static void __iax2_poke_noanswer (const void *data)
static void __iax2_poke_peer_s (const void *data)
static int __iax2_show_peers (int fd, int *total, struct mansession *s, const int argc, const char *const argv[])
static 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 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_channelast_iax2_new (int callno, int state, format_t capability, const char *linkedid, unsigned int cachable)
 Create new call, interface with the PBX core.
static AST_LIST_HEAD_NOLOCK (iax_frame)
 a list of frames that may need to be retransmitted
static AST_LIST_HEAD_STATIC (dynamic_list, iax2_thread)
static AST_LIST_HEAD_STATIC (active_list, iax2_thread)
static AST_LIST_HEAD_STATIC (idle_list, iax2_thread)
static AST_LIST_HEAD_STATIC (dpcache, iax2_dpcache)
static AST_LIST_HEAD_STATIC (firmwares, iax_firmware)
static AST_LIST_HEAD_STATIC (registrations, iax2_registry)
static AST_LIST_HEAD_STATIC (tpeers, iax2_trunk_peer)
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,"Inter Asterisk eXchange (Ver 2)",.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DRIVER,.nonoptreq="res_crypto",)
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_contextbuild_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_peerbuild_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_userbuild_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
 Create in-memory user structure from configuration.
static int cache_get_callno_locked (const char *data)
static unsigned int calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset)
static unsigned int calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
static unsigned int calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
static int callno_hash (const void *obj, const int flags)
static int calltoken_required (struct sockaddr_in *sin, const char *name, int subclass)
static int check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies)
static int check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
static int check_srcaddr (struct sockaddr *sa, socklen_t salen)
 Check if address can be used as packet source.
static void cleanup_thread_list (void *head)
static int complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies)
static char * complete_iax2_peers (const char *line, const char *word, int pos, int state, uint64_t flags)
static char * complete_iax2_unregister (const char *line, const char *word, int pos, int state)
static int complete_transfer (int callno, struct iax_ies *ies)
static unsigned char compress_subclass (format_t subclass)
static void construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
static int create_addr (const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
static int create_callno_pools (void)
static int decode_frame (ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
static int decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
static void defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here)
 Queue the last read full frame for processing by a certain thread.
static void delete_users (void)
static void destroy_firmware (struct iax_firmware *cur)
static void dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
static void * dp_lookup_thread (void *data)
static void encmethods_to_str (int e, struct ast_str **buf)
static int encrypt_frame (ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
static int expire_registry (const void *data)
static struct iax2_dpcachefind_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_threadfind_idle_thread (void)
static struct iax2_peerfind_peer (const char *name, int realtime)
static struct iax2_trunk_peerfind_tpeer (struct sockaddr_in *sin, int fd)
static struct iax2_userfind_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_entryget_unused_callno (int trunk, int validated)
static int handle_call_token (struct ast_iax2_full_hdr *fh, struct iax_ies *ies, struct sockaddr_in *sin, int fd)
static char * handle_cli_iax2_provision (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_prune_realtime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_set_debug_jb (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_set_debug_trunk (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_set_mtu (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Set trunk MTU from CLI.
static char * handle_cli_iax2_show_cache (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_callno_limits (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_firmware (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_netstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show one peer in detail.
static char * handle_cli_iax2_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_threads (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_test_losspct (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_iax2_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void handle_deferred_full_frames (struct iax2_thread *thread)
 Handle any deferred full frames for this thread.
static int handle_error (void)
static int iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno)
 Acknowledgment received for OUR registration.
static int attribute_pure iax2_allow_new (int frametype, int subclass, int inbound)
static void iax2_ami_channelupdate (struct chan_iax2_pvt *pvt)
 Send manager event at call setup to link between Asterisk channel name and IAX2 call identifiers.
static int iax2_answer (struct ast_channel *c)
static int iax2_append_register (const char *hostname, const char *username, const char *secret, const char *porta)
static enum ast_bridge_result iax2_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
static int iax2_call (struct ast_channel *c, char *dest, int timeout)
static int iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 part of the IAX2 dial plan switch interface
static unsigned int iax2_datetime (const char *tz)
static void iax2_destroy (int callno)
static void iax2_destroy_helper (struct chan_iax2_pvt *pvt)
static int iax2_devicestate (void *data)
 Part of the device state notification system ---.
static int iax2_digit_begin (struct ast_channel *c, char digit)
static int iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration)
static int iax2_do_register (struct iax2_registry *reg)
static int iax2_do_register_s (const void *data)
static void iax2_dprequest (struct iax2_dpcache *dp, int callno)
static void * iax2_dup_variable_datastore (void *)
static int iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Execute IAX2 dialplan switch.
static int iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Part of the IAX2 switch interface.
static int iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan)
static void iax2_frame_free (struct iax_frame *fr)
static void iax2_free_variable_datastore (void *)
static int iax2_getpeername (struct sockaddr_in sin, char *host, int len)
static int iax2_getpeertrunk (struct sockaddr_in sin)
static int iax2_hangup (struct ast_channel *c)
static int iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen)
static int iax2_is_control_frame_allowed (int subtype)
static int iax2_key_rotate (const void *vpvt)
static void iax2_lock_owner (int callno)
static int iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Part of the IAX2 Switch interface.
static int iax2_poke_noanswer (const void *data)
static int iax2_poke_peer (struct iax2_peer *peer, int heldcall)
static int iax2_poke_peer_cb (void *obj, void *arg, int flags)
static int iax2_poke_peer_s (const void *data)
static int iax2_predestroy (int callno)
static void * iax2_process_thread (void *data)
static void iax2_process_thread_cleanup (void *data)
static int iax2_prov_app (struct ast_channel *chan, const char *data)
static int iax2_provision (struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force)
static int iax2_queryoption (struct ast_channel *c, int option, void *data, int *datalen)
static int iax2_queue_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen)
 Queue a control frame on the ast_channel owner.
static int iax2_queue_frame (int callno, struct ast_frame *f)
 Queue a frame to a call's owning asterisk channel.
static int iax2_queue_hangup (int callno)
 Queue a hangup frame on the ast_channel owner.
static struct ast_frameiax2_read (struct ast_channel *c)
static int iax2_register (const char *value, int lineno)
static struct ast_channeliax2_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static int iax2_sched_add (struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data)
static int iax2_sched_replace (int id, struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data)
static int iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
static int iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen)
static int iax2_sendimage (struct ast_channel *c, struct ast_frame *img)
static int iax2_sendtext (struct ast_channel *c, const char *text)
static int iax2_setoption (struct ast_channel *c, int option, void *data, int datalen)
static int iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly)
static int iax2_transfer (struct ast_channel *c, const char *dest)
static int iax2_transmit (struct iax_frame *fr)
static int iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now)
static int iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr)
static int iax2_vnak (int callno)
static int iax2_write (struct ast_channel *c, struct ast_frame *f)
static int iax_check_version (char *dev)
static void iax_debug_output (const char *data)
static void iax_error_output (const char *data)
static int iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
static void iax_outputframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
static int iax_park (struct ast_channel *chan1, struct ast_channel *chan2, const char *park_exten, const char *park_context)
static void * iax_park_thread (void *stuff)
static struct iax_frameiaxfrdup2 (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_pvtnew_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_peerpeer_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_peerpeer_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_peerrealtime_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_userrealtime_user (const char *username, struct sockaddr_in *sin)
static void reg_source_db (struct iax2_peer *p)
static void register_peer_exten (struct iax2_peer *peer, int onoff)
static int register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies)
 Verify inbound registration.
static int registry_authrequest (int callno)
static int registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin)
static char * regstate2str (int regstate)
static int reload (void)
static int reload_config (void)
static void reload_firmware (int unload)
static void remove_by_peercallno (struct chan_iax2_pvt *pvt)
static void remove_by_transfercallno (struct chan_iax2_pvt *pvt)
static int replace_callno (const void *obj)
static void requirecalltoken_mark_auto (const char *name, int subclass)
static void resend_with_token (int callno, struct iax_frame *f, const char *newtoken)
static void save_osptoken (struct iax_frame *fr, struct iax_ies *ies)
static void save_rr (struct iax_frame *fr, struct iax_ies *ies)
static void sched_delay_remove (struct sockaddr_in *sin, struct callno_entry *callno_entry)
static int schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
static int scheduled_destroy (const void *vid)
static int send_apathetic_reply (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno, int sockfd, struct iax_ie_data *ied)
static int send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int)
static int send_lagrq (const void *data)
static int send_packet (struct iax_frame *f)
static int send_ping (const void *data)
static void send_signaling (struct chan_iax2_pvt *pvt)
 This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point.
static int send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now)
static int set_config (const char *config_file, int reload)
 Load configuration.
static void set_config_destroy (void)
static void set_hangup_source_and_cause (int callno, unsigned char causecode)
static void set_peercnt_limit (struct peercnt *peercnt)
static int set_peercnt_limit_all_cb (void *obj, void *arg, int flags)
static void signal_condition (ast_mutex_t *lock, ast_cond_t *cond)
static int socket_process (struct iax2_thread *thread)
static int socket_process_meta (int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd, struct iax_frame *fr)
static int socket_read (int *id, int fd, short events, void *cbdata)
static void spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid)
static int start_network_thread (void)
static void stop_stuff (int callno)
static void store_by_peercallno (struct chan_iax2_pvt *pvt)
static void store_by_transfercallno (struct chan_iax2_pvt *pvt)
static int timing_read (int *id, int fd, short events, void *cbdata)
static int transfercallno_pvt_cmp_cb (void *obj, void *arg, int flags)
static int transfercallno_pvt_hash_cb (const void *obj, const int flags)
static int transmit_frame (void *data)
static int transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
static int try_firmware (char *s)
static int try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies)
static format_t uncompress_subclass (unsigned char csub)
static void unlink_peer (struct iax2_peer *peer)
static int unload_module (void)
static void unlock_both (unsigned short callno0, unsigned short callno1)
static void unwrap_timestamp (struct iax_frame *fr)
static void update_jbsched (struct chan_iax2_pvt *pvt)
static int update_packet (struct iax_frame *f)
static int update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
static int user_cmp_cb (void *obj, void *arg, int flags)
static int user_delme_cb (void *obj, void *arg, int flags)
static void user_destructor (void *obj)
static int user_hash_cb (const void *obj, const int flags)
static struct iax2_useruser_ref (struct iax2_user *user)
static struct iax2_useruser_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 char accountcode [AST_MAX_ACCOUNT_CODE]
static int adsi = 0
static int amaflags = 0
static int authdebug = 1
static int autokill = 0
static struct ao2_containercallno_pool
static const unsigned int CALLNO_POOL_BUCKETS = 2699
static struct ao2_containercallno_pool_trunk
static struct ast_cli_entry cli_iax2 []
static struct sockaddr_in debugaddr
static char default_parkinglot [AST_MAX_CONTEXT]
static int defaultsockfd = -1
static int delayreject = 0
static int global_max_trunk_mtu
static int global_rtautoclear = 120
static struct ast_flags64 globalflags = { 0 }
static format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH
static struct ast_data_entry iax2_data_providers []
static int iax2_encryption = 0
static int(* iax2_regfunk )(const char *username, int onoff) = NULL
static struct ast_switch iax2_switch
static struct ast_channel_tech iax2_tech
static struct ast_datastore_info iax2_variable_datastore_info
static struct ao2_containeriax_peercallno_pvts
 Another container of iax2_pvt structures.
static struct ao2_containeriax_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_pvtiaxs [IAX_MAX_CALLS]
 an array of iax2 pvt structures
static ast_mutex_t iaxsl [ARRAY_LEN(iaxs)]
 chan_iax2_pvt structure locks
static int iaxthreadcount = DEFAULT_THREAD_COUNT
static int iaxtrunkdebug = 0
static struct ast_custom_function iaxvar_function
static struct io_contextio
static int jittertargetextra = 40
static int lagrq_time = 10
static char language [MAX_LANGUAGE] = ""
static int last_authmethod = 0
static int max_reg_expire
static int max_retries = 4
static int maxauthreq = 3
static int maxjitterbuffer = 1000
static int maxjitterinterps = 10
static int min_reg_expire
static char mohinterpret [MAX_MUSICCLASS]
static char mohsuggest [MAX_MUSICCLASS]
static struct ast_netsock_listnetsock
static pthread_t netthreadid = AST_PTHREADT_NULL
static int network_change_event_sched_id = -1
static struct ast_event_subnetwork_change_event_subscription
static struct ast_netsock_listoutsock
static char * papp = "IAX2Provision"
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 char regcontext [AST_MAX_CONTEXT] = ""
static int resyncthreshold = 1000
static struct ast_sched_threadsched
static int srvlookup = 0
static const char tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)"
static int test_losspct = 0
static struct ast_timertimer
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 ast_data_handler users_data_provider

Detailed Description

Implementation of Inter-Asterisk eXchange Version 2 as specified in RFC 5456.

Author:
Mark Spencer <markster@digium.com>
See also
Todo:
Implement musicclass settings for IAX2 devices

Definition in file chan_iax2.c.


Define Documentation

#define ACN_FORMAT1   "%-20.25s %4u %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 %u %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 (  )     ((void *)(unsigned long)(a))

Definition at line 243 of file chan_iax2.c.

Referenced by ast_iax2_new(), iax2_call(), iax2_hangup(), and update_jbsched().

#define CALLTOKEN_HASH_FORMAT   "%s%d%u%d"

Referenced by handle_call_token().

#define CALLTOKEN_IE_FORMAT   "%u?%s"

Referenced by handle_call_token().

#define DATA_EXPORT_IAX2_PEER ( MEMBER   ) 

Definition at line 14770 of file chan_iax2.c.

#define DATA_EXPORT_IAX2_USER ( MEMBER   ) 

Definition at line 14847 of file chan_iax2.c.

#define DEBUG_SCHED_MULTITHREAD

Definition at line 235 of file chan_iax2.c.

#define DEBUG_SUPPORT

Definition at line 251 of file chan_iax2.c.

#define DEFAULT_CONTEXT   "default"
#define DEFAULT_DROP   3

Definition at line 249 of file chan_iax2.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

Definition at line 345 of file chan_iax2.c.

Referenced by build_peer(), handle_response_peerpoke(), and sip_poke_noanswer().

#define DEFAULT_FREQ_OK   60 * 1000

Definition at line 344 of file chan_iax2.c.

Referenced by build_peer().

#define DEFAULT_MAX_THREAD_COUNT   100

Definition at line 246 of file chan_iax2.c.

#define DEFAULT_MAXMS   2000

Definition at line 343 of file chan_iax2.c.

Referenced by build_peer(), iax2_poke_peer(), reload_config(), and set_config().

#define DEFAULT_RETRY_TIME   1000

Definition at line 247 of file chan_iax2.c.

Referenced by __find_callno(), and complete_transfer().

#define DEFAULT_THREAD_COUNT   10

Definition at line 245 of file chan_iax2.c.

#define DEFAULT_TRUNKDATA   640 * 10

40ms, uncompressed linear * 10 channels

Definition at line 624 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

#define DONT_RESCHEDULE   -2

Definition at line 367 of file chan_iax2.c.

Referenced by __send_lagrq(), __send_ping(), iax2_destroy_helper(), send_lagrq(), and send_ping().

#define FORMAT   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n"
#define FORMAT   "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
#define FORMAT   "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n"
#define FORMAT   "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
#define FORMAT2   "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
#define FORMAT2   "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
#define FORMAT2   "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n"
#define FORMAT2   "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
#define FORMATB   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
#define GAMMA   (0.01)

Definition at line 256 of file chan_iax2.c.

#define IAX2_TRUNK_PREFACE   (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))

Definition at line 545 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

#define IAX_ALLOWFWDOWNLOAD   (uint64_t)(1 << 26)

Allow the FWDOWNL command?

Definition at line 433 of file chan_iax2.c.

Referenced by set_config(), and socket_process().

#define IAX_ALREADYGONE   (uint64_t)(1 << 9)

Already disconnected

Definition at line 416 of file chan_iax2.c.

Referenced by __do_deliver(), __get_from_jb(), iax2_hangup(), iax2_predestroy(), iax2_write(), pvt_destructor(), and socket_process().

#define IAX_CALLENCRYPTED ( pvt   )     (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED))

Definition at line 348 of file chan_iax2.c.

Referenced by acf_channel_read(), iax2_send(), iax2_start_transfer(), and socket_process().

#define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF

Definition at line 322 of file chan_iax2.c.

Referenced by cache_get_callno_locked(), and set_config().

#define IAX_CAPABILITY_LOWBANDWIDTH
Value:

Definition at line 334 of file chan_iax2.c.

Referenced by set_config().

#define IAX_CAPABILITY_LOWFREE
Value:

Definition at line 339 of file chan_iax2.c.

#define IAX_CAPABILITY_MEDBANDWIDTH

Definition at line 324 of file chan_iax2.c.

Referenced by set_config().

#define IAX_CODEC_NOCAP   (uint64_t)(1 << 16)

only consider requested format and ignore capabilities

Definition at line 423 of file chan_iax2.c.

Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), socket_process(), and users_data_provider_get().

#define IAX_CODEC_NOPREFS   (uint64_t)(1 << 15)

Force old behaviour by turning off prefs

Definition at line 422 of file chan_iax2.c.

Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), socket_process(), and users_data_provider_get().

#define IAX_CODEC_USER_FIRST   (uint64_t)(1 << 14)

are we willing to let the other guy choose the codec?

Definition at line 421 of file chan_iax2.c.

Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), socket_process(), and users_data_provider_get().

#define IAX_DEBUGDIGEST ( msg,
key   ) 

Definition at line 351 of file chan_iax2.c.

Referenced by iax2_key_rotate(), and socket_process().

#define IAX_DELAYPBXSTART   (uint64_t)(1 << 25)

Don't start a PBX on the channel until the peer sends us a response, so that we've achieved a three-way handshake with them before sending voice or anything else

Definition at line 432 of file chan_iax2.c.

Referenced by socket_process().

#define IAX_DELME   (uint64_t)(1 << 1)

Needs to be deleted

Definition at line 408 of file chan_iax2.c.

Referenced by build_peer(), build_user(), peer_delme_cb(), prune_peers(), prune_users(), and user_delme_cb().

#define IAX_DYNAMIC   (uint64_t)(1 << 6)
#define IAX_ENCRYPTED   (uint64_t)(1 << 12)

Whether we should assume encrypted tx/rx

Definition at line 419 of file chan_iax2.c.

Referenced by authenticate_reply(), authenticate_request(), iax2_send(), and socket_process().

#define IAX_FORCE_ENCRYPT   (uint64_t)(1 << 30)

Forces call encryption, if encryption not possible hangup

Definition at line 437 of file chan_iax2.c.

Referenced by __find_callno(), authenticate_reply(), authenticate_verify(), build_peer(), build_user(), check_access(), create_addr(), iax2_call(), iax2_queryoption(), iax2_setoption(), set_config(), and socket_process().

#define IAX_FORCEJITTERBUF   (uint64_t)(1 << 20)

Force jitterbuffer, even when bridged to a channel that can take jitter

Definition at line 427 of file chan_iax2.c.

Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_request(), schedule_delivery(), set_config(), and set_config_destroy().

#define IAX_HASCALLERID   (uint64_t)(1 << 0)

CallerID has been specified

Definition at line 407 of file chan_iax2.c.

Referenced by build_peer(), build_user(), check_access(), and update_registry().

#define IAX_IMMEDIATE   (uint64_t)(1 << 27)

Allow immediate off-hook to extension s

Definition at line 434 of file chan_iax2.c.

Referenced by build_user(), check_access(), and socket_process().

#define IAX_KEYPOPULATED   (uint64_t)(1 << 13)

Whether we have a key populated

Definition at line 420 of file chan_iax2.c.

Referenced by authenticate_reply(), decrypt_frame(), and iax2_send().

#define IAX_MAXAUTHREQ   (uint64_t)(1 << 24)

Maximum outstanding AUTHREQ restriction is in place

Definition at line 431 of file chan_iax2.c.

Referenced by authenticate_request(), authenticate_verify(), check_access(), and iax2_destroy_helper().

#define IAX_NOTRANSFER   (uint64_t)(1 << 4)
#define IAX_PROVISION   (uint64_t)(1 << 10)

This is a provisioning request

Definition at line 417 of file chan_iax2.c.

Referenced by iax2_provision(), and socket_process().

#define IAX_QUELCH   (uint64_t)(1 << 11)

Whether or not we quelch audio

Definition at line 418 of file chan_iax2.c.

Referenced by iax2_write(), and socket_process().

#define IAX_RECVCONNECTEDLINE   (uint64_t)(1 << 29)

Allow receiving of connected line updates

Definition at line 436 of file chan_iax2.c.

Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_request(), set_config(), set_config_destroy(), and socket_process().

#define IAX_RTAUTOCLEAR   (uint64_t)(1 << 19)

erase me on expire

Definition at line 426 of file chan_iax2.c.

Referenced by __expire_registry(), handle_cli_iax2_prune_realtime(), realtime_peer(), and set_config().

#define IAX_RTCACHEFRIENDS   (uint64_t)(1 << 17)

let realtime stay till your reload

Definition at line 424 of file chan_iax2.c.

Referenced by __expire_registry(), handle_cli_iax2_prune_realtime(), prune_peers(), prune_users(), 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 428 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 415 of file chan_iax2.c.

Referenced by realtime_update_peer(), and set_config().

#define IAX_RTUPDATE   (uint64_t)(1 << 18)

Send a realtime update

Definition at line 425 of file chan_iax2.c.

Referenced by __expire_registry(), set_config(), and update_registry().

#define IAX_SENDANI   (uint64_t)(1 << 7)

Send ANI along with CallerID

Definition at line 414 of file chan_iax2.c.

Referenced by build_peer(), create_addr(), iax2_call(), and iax2_request().

#define IAX_SENDCONNECTEDLINE   (uint64_t)(1 << 28)

Allow sending of connected line updates

Definition at line 435 of file chan_iax2.c.

Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_indicate(), iax2_request(), set_config(), and set_config_destroy().

#define IAX_SHRINKCALLERID   (uint64_t)(1 << 31)

Turn on and off caller id shrinking

Definition at line 438 of file chan_iax2.c.

Referenced by check_access(), and set_config().

#define IAX_TEMPONLY   (uint64_t)(1 << 2)

Temporary (realtime)

Definition at line 409 of file chan_iax2.c.

Referenced by __expire_registry(), 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 430 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)
#define IAX_TRUNKTIMESTAMPS   (uint64_t)(1 << 22)

Send trunk timestamps

Definition at line 429 of file chan_iax2.c.

Referenced by iax2_trunk_queue(), send_trunk(), and set_config().

#define IAX_USEJITTERBUF   (uint64_t)(1 << 5)
#define MARK_IAX_SUBCLASS_TX   0x8000

Definition at line 632 of file chan_iax2.c.

Referenced by ast_cli_netstats(), handle_cli_iax2_show_channels(), and iax2_send().

#define MAX_JITTER_BUFFER   50

Definition at line 621 of file chan_iax2.c.

#define MAX_PEER_BUCKETS   563

Referenced by load_objects().

#define MAX_RETRY_TIME   10000

Definition at line 619 of file chan_iax2.c.

Referenced by __attempt_transmit(), and iax2_send().

#define MAX_TIMESTAMP_SKEW   160

maximum difference between actual and predicted ts for sending

Definition at line 626 of file chan_iax2.c.

Referenced by ast_rtp_raw_write(), calc_timestamp(), and calc_txpeerstamp().

#define MAX_TRUNK_MTU   1240

Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240.

Definition at line 265 of file chan_iax2.c.

Referenced by handle_cli_iax2_set_mtu(), and set_config().

#define MAX_TRUNKDATA   640 * 200

40ms, uncompressed linear * 200 channels

Definition at line 289 of file chan_iax2.c.

Referenced by set_config(), and set_config_destroy().

#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS

Referenced by load_module(), and load_objects().

#define MEMORY_SIZE   100

Definition at line 248 of file chan_iax2.c.

#define MIN_JITTER_BUFFER   10

Definition at line 622 of file chan_iax2.c.

#define MIN_RETRY_TIME   100

Definition at line 618 of file chan_iax2.c.

Referenced by iax2_send().

#define MIN_REUSE_TIME   60

Definition at line 253 of file chan_iax2.c.

Referenced by make_trunk(), and sched_delay_remove().

#define PTR_TO_CALLNO (  )     ((unsigned short)(unsigned long)(a))
#define SCHED_MULTITHREADED

Definition at line 231 of file chan_iax2.c.

#define schedule_action ( func,
data   )     __schedule_action(func, data, __PRETTY_FUNCTION__)
#define TRUNK_CALL_START   (IAX_MAX_CALLS / 2)

Definition at line 1098 of file chan_iax2.c.

#define TS_GAP_FOR_JB_RESYNC   5000

Definition at line 629 of file chan_iax2.c.

 
#define update_max_nontrunk (  )     do { } while (0)

Definition at line 2131 of file chan_iax2.c.

Referenced by __find_callno(), and make_trunk().

 
#define update_max_trunk (  )     do { } while (0)

Definition at line 2130 of file chan_iax2.c.

Referenced by iax2_destroy(), and make_trunk().


Enumeration Type Documentation

anonymous enum
Enumerator:
CACHE_FLAG_EXISTS 

Extension exists

CACHE_FLAG_NONEXISTENT 

Extension is nonexistent

CACHE_FLAG_CANEXIST 

Extension can exist

CACHE_FLAG_PENDING 

Waiting to hear back response

CACHE_FLAG_TIMEOUT 

Timed out

CACHE_FLAG_TRANSMITTED 

Request transmitted

CACHE_FLAG_UNKNOWN 

Timeout

CACHE_FLAG_MATCHMORE 

Matchmore

Definition at line 943 of file chan_iax2.c.

00943      {
00944    /*! Extension exists */
00945    CACHE_FLAG_EXISTS      = (1 << 0),
00946    /*! Extension is nonexistent */
00947    CACHE_FLAG_NONEXISTENT = (1 << 1),
00948    /*! Extension can exist */
00949    CACHE_FLAG_CANEXIST    = (1 << 2),
00950    /*! Waiting to hear back response */
00951    CACHE_FLAG_PENDING     = (1 << 3),
00952    /*! Timed out */
00953    CACHE_FLAG_TIMEOUT     = (1 << 4),
00954    /*! Request transmitted */
00955    CACHE_FLAG_TRANSMITTED = (1 << 5),
00956    /*! Timeout */
00957    CACHE_FLAG_UNKNOWN     = (1 << 6),
00958    /*! Matchmore */
00959    CACHE_FLAG_MATCHMORE   = (1 << 7),
00960 };

anonymous enum
Enumerator:
NEW_PREVENT 
NEW_ALLOW 
NEW_FORCE 
NEW_ALLOW_CALLTOKEN_VALIDATED 

Definition at line 2057 of file chan_iax2.c.

02057      {
02058    /* do not allow a new call number, only search ones in use for match */
02059    NEW_PREVENT = 0,
02060    /* search for match first, then allow a new one to be allocated */
02061    NEW_ALLOW = 1,
02062    /* do not search for match, force a new call number */
02063    NEW_FORCE = 2,
02064    /* do not search for match, force a new call number.  Signifies call number
02065     * has been calltoken validated */
02066    NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
02067 };

Call token validation settings.

Enumerator:
CALLTOKEN_DEFAULT 

Default calltoken required unless the ip is in the ignorelist.

CALLTOKEN_YES 

Require call token validation.

CALLTOKEN_AUTO 

Require call token validation after a successful registration using call token validation occurs.

CALLTOKEN_NO 

Do not require call token validation.

Definition at line 446 of file chan_iax2.c.

00446                          {
00447    /*! \brief Default calltoken required unless the ip is in the ignorelist */
00448    CALLTOKEN_DEFAULT = 0,
00449    /*! \brief Require call token validation. */
00450    CALLTOKEN_YES = 1,
00451    /*! \brief Require call token validation after a successful registration
00452     *         using call token validation occurs. */
00453    CALLTOKEN_AUTO = 2,
00454    /*! \brief Do not require call token validation. */
00455    CALLTOKEN_NO = 3,
00456 };

enum iax2_state
Enumerator:
IAX_STATE_STARTED 
IAX_STATE_AUTHENTICATED 
IAX_STATE_TBD 

Definition at line 395 of file chan_iax2.c.

00395                 {
00396    IAX_STATE_STARTED =        (1 << 0),
00397    IAX_STATE_AUTHENTICATED =  (1 << 1),
00398    IAX_STATE_TBD =            (1 << 2),
00399 };

Enumerator:
IAX_IOSTATE_IDLE 
IAX_IOSTATE_READY 
IAX_IOSTATE_PROCESSING 
IAX_IOSTATE_SCHEDREADY 

Definition at line 984 of file chan_iax2.c.

Enumerator:
IAX_THREAD_TYPE_POOL 
IAX_THREAD_TYPE_DYNAMIC 

Definition at line 991 of file chan_iax2.c.

00991                       {
00992    IAX_THREAD_TYPE_POOL,
00993    IAX_THREAD_TYPE_DYNAMIC,
00994 };

Enumerator:
REG_STATE_UNREGISTERED 
REG_STATE_REGSENT 
REG_STATE_AUTHSENT 
REG_STATE_REGISTERED 
REG_STATE_REJECTED 
REG_STATE_TIMEOUT 
REG_STATE_NOAUTH 

Definition at line 577 of file chan_iax2.c.

Enumerator:
TRANSFER_NONE 
TRANSFER_BEGIN 
TRANSFER_READY 
TRANSFER_RELEASED 
TRANSFER_PASSTHROUGH 
TRANSFER_MBEGIN 
TRANSFER_MREADY 
TRANSFER_MRELEASED 
TRANSFER_MPASSTHROUGH 
TRANSFER_MEDIA 
TRANSFER_MEDIAPASS 

Definition at line 587 of file chan_iax2.c.


Function Documentation

static void __attempt_transmit ( const void *  data  )  [static]

Definition at line 3568 of file chan_iax2.c.

References chan_iax2_pvt::addr, iax_frame::af, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_REMOVE, ast_log(), ast_mutex_lock, ast_mutex_unlock, attempt_transmit(), iax_frame::callno, chan_iax2_pvt::error, f, iax_frame::final, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxs, iaxsl, 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().

03569 {
03570    /* Attempt to transmit the frame to the remote peer...
03571       Called without iaxsl held. */
03572    struct iax_frame *f = (struct iax_frame *)data;
03573    int freeme = 0;
03574    int callno = f->callno;
03575 
03576    /* Make sure this call is still active */
03577    if (callno) 
03578       ast_mutex_lock(&iaxsl[callno]);
03579    if (callno && iaxs[callno]) {
03580       if (f->retries < 0) {
03581          /* Already ACK'd */
03582          freeme = 1;
03583       } else if (f->retries >= max_retries) {
03584          /* Too many attempts.  Record an error. */
03585          if (f->transfer) {
03586             /* Transfer timeout */
03587             send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03588          } else if (f->final) {
03589             iax2_destroy(callno);
03590          } else {
03591             if (iaxs[callno]->owner) {
03592                ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %u, subclass = %d, ts=%u, seqno=%d)\n",
03593                   ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),
03594                   iaxs[f->callno]->owner->name,
03595                   f->af.frametype,
03596                   f->af.subclass.integer,
03597                   f->ts,
03598                   f->oseqno);
03599             }
03600             iaxs[callno]->error = ETIMEDOUT;
03601             if (iaxs[callno]->owner) {
03602                struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03603                /* Hangup the fd */
03604                iax2_queue_frame(callno, &fr); /* XXX */
03605                /* Remember, owner could disappear */
03606                if (iaxs[callno] && iaxs[callno]->owner)
03607                   iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03608             } else {
03609                if (iaxs[callno]->reg) {
03610                   memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03611                   iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03612                   iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03613                }
03614                iax2_destroy(callno);
03615             }
03616          }
03617          freeme = 1;
03618       } else {
03619          /* Update it if it needs it */
03620          update_packet(f);
03621          /* Attempt transmission */
03622          send_packet(f);
03623          f->retries++;
03624          /* Try again later after 10 times as long */
03625          f->retrytime *= 10;
03626          if (f->retrytime > MAX_RETRY_TIME)
03627             f->retrytime = MAX_RETRY_TIME;
03628          /* Transfer messages max out at one second */
03629          if (f->transfer && (f->retrytime > 1000))
03630             f->retrytime = 1000;
03631          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03632       }
03633    } else {
03634       /* Make sure it gets freed */
03635       f->retries = -1;
03636       freeme = 1;
03637    }
03638 
03639    if (freeme) {
03640       /* Don't attempt delivery, just remove it from the queue */
03641       AST_LIST_REMOVE(&frame_queue[callno], f, list);
03642       ast_mutex_unlock(&iaxsl[callno]);
03643       f->retrans = -1; /* this is safe because this is the scheduled function */
03644       /* Free the IAX frame */
03645       iax2_frame_free(f);
03646    } else if (callno) {
03647       ast_mutex_unlock(&iaxsl[callno]);
03648    }
03649 }

static void __auth_reject ( const void *  nothing  )  [static]

Definition at line 9112 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, iaxs, iaxsl, iax_ie_data::pos, and send_command_final().

Referenced by auth_reject().

09113 {
09114    /* Called from IAX thread only, without iaxs lock */
09115    int callno = (int)(long)(nothing);
09116    struct iax_ie_data ied;
09117    ast_mutex_lock(&iaxsl[callno]);
09118    if (iaxs[callno]) {
09119       memset(&ied, 0, sizeof(ied));
09120       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
09121          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
09122          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
09123       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
09124          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
09125          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
09126       }
09127       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
09128    }
09129    ast_mutex_unlock(&iaxsl[callno]);
09130 }

static void __auto_congest ( const void *  nothing  )  [static]

Definition at line 4758 of file chan_iax2.c.

References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_queue_frame(), iaxs, iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.

Referenced by auto_congest().

04759 {
04760    int callno = PTR_TO_CALLNO(nothing);
04761    struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } };
04762    ast_mutex_lock(&iaxsl[callno]);
04763    if (iaxs[callno]) {
04764       iaxs[callno]->initid = -1;
04765       iax2_queue_frame(callno, &f);
04766       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04767    }
04768    ast_mutex_unlock(&iaxsl[callno]);
04769 }

static void __auto_hangup ( const void *  nothing  )  [static]

Definition at line 9161 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, iaxs, iaxsl, iax_ie_data::pos, and send_command_final().

Referenced by auto_hangup().

09162 {
09163    /* Called from IAX thread only, without iaxs lock */
09164    int callno = (int)(long)(nothing);
09165    struct iax_ie_data ied;
09166    ast_mutex_lock(&iaxsl[callno]);
09167    if (iaxs[callno]) {
09168       memset(&ied, 0, sizeof(ied));
09169       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
09170       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
09171       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
09172    }
09173    ast_mutex_unlock(&iaxsl[callno]);
09174 }

static int __do_deliver ( void *  data  )  [static]
Note:
This function assumes that iaxsl[callno] is locked when called.
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 3356 of file chan_iax2.c.

References iax_frame::af, ast_clear_flag, AST_FRFLAG_HAS_TIMING_INFO, ast_test_flag64, iax_frame::callno, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, and iax_frame::retrans.

Referenced by __get_from_jb(), and schedule_delivery().

03357 {
03358    /* Just deliver the packet by using queueing.  This is called by
03359      the IAX thread with the iaxsl lock held. */
03360    struct iax_frame *fr = data;
03361    fr->retrans = -1;
03362    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03363    if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE))
03364       iax2_queue_frame(fr->callno, &fr->af);
03365    /* Free our iax frame */
03366    iax2_frame_free(fr);
03367    /* And don't run again */
03368    return 0;
03369 }

static void __expire_registry ( const void *  data  )  [static]

Definition at line 8737 of file chan_iax2.c.

References iax2_peer::addr, ast_db_del(), ast_debug, AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, 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, peer_unref(), peercnt_modify(), realtime_update_peer(), register_peer_exten(), and unlink_peer().

Referenced by expire_registry().

08738 {
08739    struct iax2_peer *peer = (struct iax2_peer *) data;
08740 
08741    if (!peer)
08742       return;
08743    if (peer->expire == -1) {
08744       /* Removed already (possibly through CLI), ignore */
08745       return;
08746    }
08747 
08748    peer->expire = -1;
08749 
08750    ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08751    if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08752       realtime_update_peer(peer->name, &peer->addr, 0);
08753    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08754    /* modify entry in peercnts table as _not_ registered */
08755    peercnt_modify((unsigned char) 0, 0, &peer->addr);
08756    /* Reset the address */
08757    memset(&peer->addr, 0, sizeof(peer->addr));
08758    /* Reset expiry value */
08759    peer->expiry = min_reg_expire;
08760    if (!ast_test_flag64(peer, IAX_TEMPONLY))
08761       ast_db_del("IAX/Registry", peer->name);
08762    register_peer_exten(peer, 0);
08763    ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
08764    if (iax2_regfunk)
08765       iax2_regfunk(peer->name, 0);
08766 
08767    if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08768       unlink_peer(peer);
08769 
08770    peer_unref(peer);
08771 }

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 2862 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_peercallno_pvts, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, iax_transfercallno_pvts, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, iaxs, iaxsl, chan_iax2_pvt::lagid, LOG_WARNING, match(), NEW_ALLOW, new_iax(), OBJ_POINTER, parkinglot, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, replace_callno(), send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, store_by_peercallno(), chan_iax2_pvt::transfer, and update_max_nontrunk.

Referenced by find_callno(), and find_callno_locked().

02863 {
02864    int res = 0;
02865    int x;
02866    /* this call is calltoken validated as long as it is either NEW_FORCE
02867     * or NEW_ALLOW_CALLTOKEN_VALIDATED */
02868    int validated = (new > NEW_ALLOW) ? 1 : 0;
02869    char host[80];
02870 
02871    if (new <= NEW_ALLOW) {
02872       if (callno) {
02873          struct chan_iax2_pvt *pvt;
02874          struct chan_iax2_pvt tmp_pvt = {
02875             .callno = dcallno,
02876             .peercallno = callno,
02877             .transfercallno = callno,
02878             /* hack!! */
02879             .frames_received = check_dcallno,
02880          };
02881 
02882          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02883          /* this works for finding normal call numbers not involving transfering */ 
02884          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02885             if (return_locked) {
02886                ast_mutex_lock(&iaxsl[pvt->callno]);
02887             }
02888             res = pvt->callno;
02889             ao2_ref(pvt, -1);
02890             pvt = NULL;
02891             return res;
02892          }
02893          /* this searches for transfer call numbers that might not get caught otherwise */
02894          memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02895          memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02896          if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02897             if (return_locked) {
02898                ast_mutex_lock(&iaxsl[pvt->callno]);
02899             }
02900             res = pvt->callno;
02901             ao2_ref(pvt, -1);
02902             pvt = NULL;
02903             return res;
02904          }
02905       }
02906          /* This will occur on the first response to a message that we initiated,
02907        * such as a PING. */
02908       if (dcallno) {
02909          ast_mutex_lock(&iaxsl[dcallno]);
02910       }
02911       if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02912          iaxs[dcallno]->peercallno = callno;
02913          res = dcallno;
02914          store_by_peercallno(iaxs[dcallno]);
02915          if (!res || !return_locked) {
02916             ast_mutex_unlock(&iaxsl[dcallno]);
02917          }
02918          return res;
02919       }
02920       if (dcallno) {
02921          ast_mutex_unlock(&iaxsl[dcallno]);
02922       }
02923 #ifdef IAX_OLD_FIND
02924       /* If we get here, we SHOULD NOT find a call structure for this
02925          callno; if we do, it means that there is a call structure that
02926          has a peer callno but did NOT get entered into the hash table,
02927          which is bad.
02928 
02929          If we find a call structure using this old, slow method, output a log
02930          message so we'll know about it. After a few months of leaving this in
02931          place, if we don't hear about people seeing these messages, we can
02932          remove this code for good.
02933       */
02934 
02935       for (x = 1; !res && x < maxnontrunkcall; x++) {
02936          ast_mutex_lock(&iaxsl[x]);
02937          if (iaxs[x]) {
02938             /* Look for an exact match */
02939             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02940                res = x;
02941             }
02942          }
02943          if (!res || !return_locked)
02944             ast_mutex_unlock(&iaxsl[x]);
02945       }
02946       for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02947          ast_mutex_lock(&iaxsl[x]);
02948          if (iaxs[x]) {
02949             /* Look for an exact match */
02950             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02951                res = x;
02952             }
02953          }
02954          if (!res || !return_locked)
02955             ast_mutex_unlock(&iaxsl[x]);
02956       }
02957 #endif
02958    }
02959    if (!res && (new >= NEW_ALLOW)) {
02960       struct callno_entry *callno_entry;
02961       /* It may seem odd that we look through the peer list for a name for
02962        * this *incoming* call.  Well, it is weird.  However, users don't
02963        * have an IP address/port number that we can match against.  So,
02964        * this is just checking for a peer that has that IP/port and
02965        * assuming that we have a user of the same name.  This isn't always
02966        * correct, but it will be changed if needed after authentication. */
02967       if (!iax2_getpeername(*sin, host, sizeof(host)))
02968          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02969 
02970       if (peercnt_add(sin)) {
02971          /* This address has hit its callnumber limit.  When the limit
02972           * is reached, the connection is not added to the peercnts table.*/
02973          return 0;
02974       }
02975 
02976       if (!(callno_entry = get_unused_callno(0, validated))) {
02977          /* since we ran out of space, remove the peercnt
02978           * entry we added earlier */
02979          peercnt_remove_by_addr(sin);
02980          ast_log(LOG_WARNING, "No more space\n");
02981          return 0;
02982       }
02983       x = callno_entry->callno;
02984       ast_mutex_lock(&iaxsl[x]);
02985 
02986       iaxs[x] = new_iax(sin, host);
02987       update_max_nontrunk();
02988       if (iaxs[x]) {
02989          if (iaxdebug)
02990             ast_debug(1, "Creating new call structure %d\n", x);
02991          iaxs[x]->callno_entry = callno_entry;
02992          iaxs[x]->sockfd = sockfd;
02993          iaxs[x]->addr.sin_port = sin->sin_port;
02994          iaxs[x]->addr.sin_family = sin->sin_family;
02995          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02996          iaxs[x]->peercallno = callno;
02997          iaxs[x]->callno = x;
02998          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02999          iaxs[x]->expiry = min_reg_expire;
03000          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
03001          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
03002          iaxs[x]->amaflags = amaflags;
03003          ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
03004          ast_string_field_set(iaxs[x], accountcode, accountcode);
03005          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
03006          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
03007          ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
03008 
03009          if (iaxs[x]->peercallno) {
03010             store_by_peercallno(iaxs[x]);
03011          }
03012       } else {
03013          ast_log(LOG_WARNING, "Out of resources\n");
03014          ast_mutex_unlock(&iaxsl[x]);
03015          replace_callno(callno_entry);
03016          return 0;
03017       }
03018       if (!return_locked)
03019          ast_mutex_unlock(&iaxsl[x]);
03020       res = x;
03021    }
03022    return res;
03023 }

static void __get_from_jb ( const void *  p  )  [static]

Definition at line 4152 of file chan_iax2.c.

References __do_deliver(), ast_codec_interp_len(), ast_format_rate(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_test_flag64, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_frame_subclass::codec, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, iaxsl, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, jb_frame::ms, 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().

04153 {
04154    int callno = PTR_TO_CALLNO(p);
04155    struct chan_iax2_pvt *pvt = NULL;
04156    struct iax_frame *fr;
04157    jb_frame frame;
04158    int ret;
04159    long ms;
04160    long next;
04161    struct timeval now = ast_tvnow();
04162    
04163    /* Make sure we have a valid private structure before going on */
04164    ast_mutex_lock(&iaxsl[callno]);
04165    pvt = iaxs[callno];
04166    if (!pvt) {
04167       /* No go! */
04168       ast_mutex_unlock(&iaxsl[callno]);
04169       return;
04170    }
04171 
04172    pvt->jbid = -1;
04173    
04174    /* round up a millisecond since ast_sched_runq does; */
04175    /* prevents us from spinning while waiting for our now */
04176    /* to catch up with runq's now */
04177    now.tv_usec += 1000;
04178    
04179    ms = ast_tvdiff_ms(now, pvt->rxcore);
04180    
04181    if(ms >= (next = jb_next(pvt->jb))) {
04182       ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
04183       switch(ret) {
04184       case JB_OK:
04185          fr = frame.data;
04186          __do_deliver(fr);
04187          /* __do_deliver() can cause the call to disappear */
04188          pvt = iaxs[callno];
04189          break;
04190       case JB_INTERP:
04191       {
04192          struct ast_frame af = { 0, };
04193          
04194          /* create an interpolation frame */
04195          af.frametype = AST_FRAME_VOICE;
04196          af.subclass.codec = pvt->voiceformat;
04197          af.samples  = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
04198          af.src  = "IAX2 JB interpolation";
04199          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
04200          af.offset = AST_FRIENDLY_OFFSET;
04201          
04202          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
04203           * which we'd need to malloc, and then it would free it.  That seems like a drag */
04204          if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) {
04205             iax2_queue_frame(callno, &af);
04206             /* iax2_queue_frame() could cause the call to disappear */
04207             pvt = iaxs[callno];
04208          }
04209       }
04210          break;
04211       case JB_DROP:
04212          iax2_frame_free(frame.data);
04213          break;
04214       case JB_NOFRAME:
04215       case JB_EMPTY:
04216          /* do nothing */
04217          break;
04218       default:
04219          /* shouldn't happen */
04220          break;
04221       }
04222    }
04223    if (pvt)
04224       update_jbsched(pvt);
04225    ast_mutex_unlock(&iaxsl[callno]);
04226 }

static void __iax2_do_register_s ( const void *  data  )  [static]

Definition at line 8408 of file chan_iax2.c.

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_do_register_s().

08409 {
08410    struct iax2_registry *reg = (struct iax2_registry *)data;
08411    reg->expire = -1;
08412    iax2_do_register(reg);
08413 }

static void __iax2_poke_noanswer ( const void *  data  )  [static]

Definition at line 12205 of file chan_iax2.c.

References AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_peer::callno, EVENT_FLAG_SYSTEM, iax2_destroy(), iax2_poke_peer_s(), iax2_sched_add(), iaxsl, iax2_peer::lastms, LOG_NOTICE, manager_event, peer_ref(), peer_unref(), iax2_peer::pokeexpire, and iax2_peer::pokefreqnotok.

Referenced by iax2_poke_noanswer().

12206 {
12207    struct iax2_peer *peer = (struct iax2_peer *)data;
12208    int callno;
12209 
12210    if (peer->lastms > -1) {
12211       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
12212       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
12213       ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
12214    }
12215    if ((callno = peer->callno) > 0) {
12216       ast_mutex_lock(&iaxsl[callno]);
12217       iax2_destroy(callno);
12218       ast_mutex_unlock(&iaxsl[callno]);
12219    }
12220    peer->callno = 0;
12221    peer->lastms = -1;
12222    /* Try again quickly */
12223    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
12224    if (peer->pokeexpire == -1)
12225       peer_unref(peer);
12226 }

static void __iax2_poke_peer_s ( const void *  data  )  [static]

Definition at line 9221 of file chan_iax2.c.

References iax2_poke_peer(), and peer_unref().

Referenced by iax2_poke_peer_s().

09222 {
09223    struct iax2_peer *peer = (struct iax2_peer *)data;
09224    iax2_poke_peer(peer, 0);
09225    peer_unref(peer);
09226 }

static int __iax2_show_peers ( int  fd,
int *  total,
struct mansession s,
const int  argc,
const char *const   argv[] 
) [static]

Definition at line 6760 of file chan_iax2.c.

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli(), ast_copy_string(), ast_inet_ntoa(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_sockaddr_to_sin, ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag64, astman_append(), iax2_peer::encmethods, encmethods_to_str(), FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, name, peer_status(), peer_unref(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and status.

Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().

06761 {
06762    regex_t regexbuf;
06763    int havepattern = 0;
06764    int total_peers = 0;
06765    int online_peers = 0;
06766    int offline_peers = 0;
06767    int unmonitored_peers = 0;
06768    struct ao2_iterator i;
06769 
06770 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s\n"
06771 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s\n"
06772 
06773    struct iax2_peer *peer = NULL;
06774    char name[256];
06775    struct ast_str *encmethods = ast_str_alloca(256);
06776    int registeredonly=0;
06777    char idtext[256] = "";
06778    switch (argc) {
06779    case 6:
06780       if (!strcasecmp(argv[3], "registered"))
06781          registeredonly = 1;
06782       else
06783          return RESULT_SHOWUSAGE;
06784       if (!strcasecmp(argv[4], "like")) {
06785          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06786             return RESULT_SHOWUSAGE;
06787          havepattern = 1;
06788       } else
06789          return RESULT_SHOWUSAGE;
06790       break;
06791    case 5:
06792       if (!strcasecmp(argv[3], "like")) {
06793          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06794             return RESULT_SHOWUSAGE;
06795          havepattern = 1;
06796       } else
06797          return RESULT_SHOWUSAGE;
06798       break;
06799    case 4:
06800       if (!strcasecmp(argv[3], "registered"))
06801          registeredonly = 1;
06802       else
06803          return RESULT_SHOWUSAGE;
06804       break;
06805    case 3:
06806       break;
06807    default:
06808       return RESULT_SHOWUSAGE;
06809    }
06810 
06811 
06812    if (!s)
06813       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status");
06814 
06815    i = ao2_iterator_init(peers, 0);
06816    for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
06817       char nm[20];
06818       char status[20];
06819       int retstatus;
06820       struct sockaddr_in peer_addr;
06821 
06822       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
06823 
06824       if (registeredonly && !peer_addr.sin_addr.s_addr) {
06825          continue;
06826       }
06827       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0)) {
06828          continue;
06829       }
06830 
06831       if (!ast_strlen_zero(peer->username))
06832          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06833       else
06834          ast_copy_string(name, peer->name, sizeof(name));
06835 
06836       encmethods_to_str(peer->encmethods, &encmethods);
06837       retstatus = peer_status(peer, status, sizeof(status));
06838       if (retstatus > 0)
06839          online_peers++;
06840       else if (!retstatus)
06841          offline_peers++;
06842       else
06843          unmonitored_peers++;
06844 
06845       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06846 
06847       if (s) {
06848          astman_append(s,
06849             "Event: PeerEntry\r\n%s"
06850             "Channeltype: IAX2\r\n"
06851             "ObjectName: %s\r\n"
06852             "ChanObjectType: peer\r\n"
06853             "IPaddress: %s\r\n"
06854             "IPport: %d\r\n"
06855             "Dynamic: %s\r\n"
06856             "Trunk: %s\r\n"
06857             "Encryption: %s\r\n"
06858             "Status: %s\r\n\r\n",
06859             idtext,
06860             name,
06861             ast_sockaddr_stringify_addr(&peer->addr),
06862             ast_sockaddr_port(&peer->addr),
06863             ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
06864             ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
06865             peer->encmethods ? ast_str_buffer(encmethods) : "no",
06866             status);
06867       } else {
06868          ast_cli(fd, FORMAT, name,
06869             ast_sockaddr_stringify_addr(&peer->addr),
06870             ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06871             nm,
06872             ast_sockaddr_port(&peer->addr),
06873             ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : "   ",
06874             peer->encmethods ? "(E)" : "   ",
06875             status);
06876       }
06877       total_peers++;
06878    }
06879    ao2_iterator_destroy(&i);
06880 
06881    if (!s)
06882       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
06883          total_peers, online_peers, offline_peers, unmonitored_peers);
06884 
06885    if (havepattern)
06886       regfree(&regexbuf);
06887 
06888    if (total)
06889       *total = total_peers;
06890 
06891    return RESULT_SUCCESS;
06892 #undef FORMAT
06893 #undef FORMAT2
06894 }

static int __schedule_action ( void(*)(const void *data)  func,
const void *  data,
const char *  funcname 
) [static]

Definition at line 1544 of file chan_iax2.c.

References ast_copy_string(), ast_debug, find_idle_thread(), IAX_IOSTATE_SCHEDREADY, signal_condition(), and thread.

01545 {
01546    struct iax2_thread *thread;
01547    static time_t lasterror;
01548    time_t t;
01549 
01550    thread = find_idle_thread();
01551    if (thread != NULL) {
01552       thread->schedfunc = func;
01553       thread->scheddata = data;
01554       thread->iostate = IAX_IOSTATE_SCHEDREADY;
01555 #ifdef DEBUG_SCHED_MULTITHREAD
01556       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01557 #endif
01558       signal_condition(&thread->lock, &thread->cond);
01559       return 0;
01560    }
01561    time(&t);
01562    if (t != lasterror) {
01563       lasterror = t;
01564       ast_debug(1, "Out of idle IAX2 threads for scheduling! (%s)\n", funcname);
01565    }
01566 
01567    return -1;
01568 }

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 7593 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().

07595 {
07596    struct ast_frame f = { 0, };
07597    int res = 0;
07598 
07599    f.frametype = type;
07600    f.subclass.integer = command;
07601    f.datalen = datalen;
07602    f.src = __FUNCTION__;
07603    f.data.ptr = (void *) data;
07604 
07605    if ((res = queue_signalling(i, &f)) <= 0) {
07606       return res;
07607    }
07608 
07609    return iax2_send(i, &f, ts, seqno, now, transfer, final);
07610 }

static void __send_lagrq ( const void *  data  )  [static]

Definition at line 1655 of file chan_iax2.c.

References ast_debug, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, DONT_RESCHEDULE, iax2_sched_add(), IAX_COMMAND_LAGRQ, iaxs, iaxsl, chan_iax2_pvt::lagid, send_command(), and send_lagrq().

Referenced by send_lagrq().

01656 {
01657    int callno = (long) data;
01658 
01659    ast_mutex_lock(&iaxsl[callno]);
01660 
01661    if (iaxs[callno]) {
01662       if (iaxs[callno]->peercallno) {
01663          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01664          if (iaxs[callno]->lagid != DONT_RESCHEDULE) {
01665             iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01666          }
01667       }
01668    } else {
01669       ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01670    }
01671 
01672    ast_mutex_unlock(&iaxsl[callno]);
01673 }

static void __send_ping ( const void *  data  )  [static]

Definition at line 1588 of file chan_iax2.c.

References ast_debug, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, DONT_RESCHEDULE, iax2_sched_add(), IAX_COMMAND_PING, iaxs, iaxsl, chan_iax2_pvt::pingid, send_command(), and send_ping().

Referenced by send_ping().

01589 {
01590    int callno = (long) data;
01591 
01592    ast_mutex_lock(&iaxsl[callno]);
01593 
01594    if (iaxs[callno]) {
01595       if (iaxs[callno]->peercallno) {
01596          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01597          if (iaxs[callno]->pingid != DONT_RESCHEDULE) {
01598             iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01599          }
01600       }
01601    } else {
01602       ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01603    }
01604 
01605    ast_mutex_unlock(&iaxsl[callno]);
01606 }

static int __unload_module ( void   )  [static]

Definition at line 14574 of file chan_iax2.c.

References ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_context_find(), ast_data_unregister, ast_manager_unregister(), ast_mutex_destroy, ast_netsock_release(), AST_PTHREADT_NULL, ast_sched_thread_destroy(), ast_taskprocessor_unreference(), AST_TEST_UNREGISTER, ast_timer_close(), ast_unload_realtime(), ast_unregister_application(), ast_unregister_switch(), cleanup_thread_list(), cli_iax2, delete_users(), iax2_destroy(), iax2_switch, iax2_tech, iax_peercallno_pvts, iax_provision_unload(), iax_transfercallno_pvts, iaxs, iaxsl, network_change_event_unsubscribe(), papp, and reload_firmware().

Referenced by load_module(), and unload_module().

14575 {
14576    struct ast_context *con;
14577    int x;
14578 
14579    network_change_event_unsubscribe();
14580 
14581    ast_manager_unregister("IAXpeers");
14582    ast_manager_unregister("IAXpeerlist");
14583    ast_manager_unregister("IAXnetstats");
14584    ast_manager_unregister("IAXregistry");
14585    ast_unregister_application(papp);
14586    ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14587    ast_unregister_switch(&iax2_switch);
14588    ast_channel_unregister(&iax2_tech);
14589 
14590    if (netthreadid != AST_PTHREADT_NULL) {
14591       pthread_cancel(netthreadid);
14592       pthread_kill(netthreadid, SIGURG);
14593       pthread_join(netthreadid, NULL);
14594    }
14595 
14596    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14597       if (iaxs[x]) {
14598          iax2_destroy(x);
14599       }
14600    }
14601 
14602    /* Call for all threads to halt */
14603    cleanup_thread_list(&active_list);
14604    cleanup_thread_list(&dynamic_list);
14605    cleanup_thread_list(&idle_list);
14606 
14607    ast_netsock_release(netsock);
14608    ast_netsock_release(outsock);
14609    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14610       if (iaxs[x]) {
14611          iax2_destroy(x);
14612       }
14613    }
14614    ast_manager_unregister( "IAXpeers" );
14615    ast_manager_unregister( "IAXpeerlist" );
14616    ast_manager_unregister( "IAXnetstats" );
14617    ast_manager_unregister( "IAXregistry" );
14618    ast_unregister_application(papp);
14619 #ifdef TEST_FRAMEWORK
14620    AST_TEST_UNREGISTER(test_iax2_peers_get);
14621    AST_TEST_UNREGISTER(test_iax2_users_get);
14622 #endif
14623    ast_data_unregister(NULL);
14624    ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14625    ast_unregister_switch(&iax2_switch);
14626    ast_channel_unregister(&iax2_tech);
14627    delete_users();
14628    iax_provision_unload();
14629    reload_firmware(1);
14630 
14631    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14632       ast_mutex_destroy(&iaxsl[x]);
14633    }
14634 
14635    ao2_ref(peers, -1);
14636    ao2_ref(users, -1);
14637    ao2_ref(iax_peercallno_pvts, -1);
14638    ao2_ref(iax_transfercallno_pvts, -1);
14639    ao2_ref(peercnts, -1);
14640    ao2_ref(callno_limits, -1);
14641    ao2_ref(calltoken_ignores, -1);
14642    ao2_ref(callno_pool, -1);
14643    ao2_ref(callno_pool_trunk, -1);
14644    if (timer) {
14645       ast_timer_close(timer);
14646       timer = NULL;
14647    }
14648    transmit_processor = ast_taskprocessor_unreference(transmit_processor);
14649    sched = ast_sched_thread_destroy(sched);
14650 
14651    con = ast_context_find(regcontext);
14652    if (con)
14653       ast_context_destroy(con, "IAX2");
14654    ast_unload_realtime("iaxpeers");
14655    return 0;
14656 }

static int acf_channel_read ( struct ast_channel chan,
const char *  funcname,
char *  preparse,
char *  buf,
size_t  buflen 
) [static]

Definition at line 14214 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, iax2_tech, IAX_CALLENCRYPTED, iaxs, iaxsl, LOG_ERROR, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.

14215 {
14216    struct chan_iax2_pvt *pvt;
14217    unsigned int callno;
14218    int res = 0;
14219 
14220    if (!chan || chan->tech != &iax2_tech) {
14221       ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
14222       return -1;
14223    }
14224 
14225    callno = PTR_TO_CALLNO(chan->tech_pvt);
14226    ast_mutex_lock(&iaxsl[callno]);
14227    if (!(pvt = iaxs[callno])) {
14228       ast_mutex_unlock(&iaxsl[callno]);
14229       return -1;
14230    }
14231 
14232    if (!strcasecmp(args, "osptoken")) {
14233       ast_copy_string(buf, pvt->osptoken, buflen);
14234    } else if (!strcasecmp(args, "peerip")) {
14235       ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
14236    } else if (!strcasecmp(args, "peername")) {
14237       ast_copy_string(buf, pvt->username, buflen);
14238    } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
14239       snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
14240    } else {
14241       res = -1;
14242    }
14243 
14244    ast_mutex_unlock(&iaxsl[callno]);
14245 
14246    return res;
14247 }

static int acf_iaxvar_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

Definition at line 9943 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_log(), ast_datastore::data, iax2_variable_datastore_info, LOG_WARNING, ast_var_t::name, ast_var_t::value, and var.

09944 {
09945    struct ast_datastore *variablestore;
09946    AST_LIST_HEAD(, ast_var_t) *varlist;
09947    struct ast_var_t *var;
09948 
09949    if (!chan) {
09950       ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
09951       return -1;
09952    }
09953 
09954    variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09955 
09956    if (!variablestore) {
09957       *buf = '\0';
09958       return 0;
09959    }
09960    varlist = variablestore->data;
09961 
09962    AST_LIST_LOCK(varlist);
09963    AST_LIST_TRAVERSE(varlist, var, entries) {
09964       if (strcmp(var->name, data) == 0) {
09965          ast_copy_string(buf, var->value, len);
09966          break;
09967       }
09968    }
09969    AST_LIST_UNLOCK(varlist);
09970    return 0;
09971 }

static int acf_iaxvar_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
) [static]

Definition at line 9973 of file chan_iax2.c.

References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc, ast_datastore_free(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_var_assign(), ast_var_delete(), ast_datastore::data, DATASTORE_INHERIT_FOREVER, iax2_variable_datastore_info, ast_datastore::inheritance, LOG_ERROR, LOG_WARNING, ast_var_t::name, and var.

09974 {
09975    struct ast_datastore *variablestore;
09976    AST_LIST_HEAD(, ast_var_t) *varlist;
09977    struct ast_var_t *var;
09978 
09979    if (!chan) {
09980       ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
09981       return -1;
09982    }
09983 
09984    variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09985 
09986    if (!variablestore) {
09987       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09988       if (!variablestore) {
09989          ast_log(LOG_ERROR, "Memory allocation error\n");
09990          return -1;
09991       }
09992       varlist = ast_calloc(1, sizeof(*varlist));
09993       if (!varlist) {
09994          ast_datastore_free(variablestore);
09995          ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09996          return -1;
09997       }
09998 
09999       AST_LIST_HEAD_INIT(varlist);
10000       variablestore->data = varlist;
10001       variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10002       ast_channel_datastore_add(chan, variablestore);
10003    } else
10004       varlist = variablestore->data;
10005 
10006    AST_LIST_LOCK(varlist);
10007    AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
10008       if (strcmp(var->name, data) == 0) {
10009          AST_LIST_REMOVE_CURRENT(entries);
10010          ast_var_delete(var);
10011          break;
10012       }
10013    }
10014    AST_LIST_TRAVERSE_SAFE_END;
10015    var = ast_var_assign(data, value);
10016    if (var)
10017       AST_LIST_INSERT_TAIL(varlist, var, entries);
10018    else
10019       ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
10020    AST_LIST_UNLOCK(varlist);
10021    return 0;
10022 }

static int add_calltoken_ignore ( const char *  addr  )  [static]

Definition at line 2597 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().

02598 {
02599    struct addr_range tmp;
02600    struct addr_range *addr_range = NULL;
02601    struct ast_ha *ha = NULL;
02602    int error = 0;
02603 
02604    if (ast_strlen_zero(addr)) {
02605       ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02606       return -1;
02607    }
02608 
02609    ha = ast_append_ha("permit", addr, NULL, &error);
02610 
02611    /* check for valid config information */
02612    if (error) {
02613       ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02614       return -1;
02615    }
02616 
02617    ast_copy_ha(ha, &tmp.ha);
02618    /* find or create the addr_range */
02619    if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02620       ao2_lock(addr_range);
02621       addr_range->delme = 0;
02622       ao2_unlock(addr_range);
02623    } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02624       /* copy over config data into addr_range object */
02625       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */
02626       ao2_link(calltoken_ignores, addr_range);
02627    } else {
02628       ast_free_ha(ha);
02629       return -1;
02630    }
02631 
02632    ast_free_ha(ha);
02633    ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02634 
02635    return 0;
02636 }

static void add_empty_calltoken_ie ( struct chan_iax2_pvt pvt,
struct iax_ie_data ied 
) [static]

Definition at line 4834 of file chan_iax2.c.

References iax_ie_data::buf, 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().

04835 {
04836    /* first make sure their are two empty bytes left in ied->buf */
04837    if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04838       ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;  /* type */
04839       ied->buf[ied->pos++] = 0;   /* data size,  ZERO in this case */
04840       pvt->calltoken_ie_len = 2;
04841    }
04842 }

static int addr_range_cmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 2248 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().

02249 {
02250    struct addr_range *lim1 = obj, *lim2 = arg;
02251    return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) &&
02252          !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ?
02253          CMP_MATCH | CMP_STOP : 0;
02254 }

static int addr_range_delme_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 2233 of file chan_iax2.c.

References addr_range::delme.

Referenced by set_config_destroy().

02234 {
02235    struct addr_range *lim = obj;
02236    lim->delme = 1;
02237    return 0;
02238 }

static int addr_range_hash_cb ( const void *  obj,
const int  flags 
) [static]

Definition at line 2240 of file chan_iax2.c.

References ast_ha::addr, ast_sockaddr_to_sin, and addr_range::ha.

Referenced by load_objects().

02241 {
02242    const struct addr_range *lim = obj;
02243    struct sockaddr_in sin;
02244    ast_sockaddr_to_sin(&lim->ha.addr, &sin);
02245    return abs((int) sin.sin_addr.s_addr);
02246 }

static int addr_range_match_address_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 2268 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().

02269 {
02270    struct addr_range *addr_range = obj;
02271    struct sockaddr_in *sin = arg;
02272    struct sockaddr_in ha_netmask_sin;
02273    struct sockaddr_in ha_addr_sin;
02274 
02275    ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin);
02276    ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin);
02277 
02278    if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) {
02279       return CMP_MATCH | CMP_STOP;
02280    }
02281    return 0;
02282 }

static int apply_context ( struct iax2_context con,
const char *  context 
) [static]

Definition at line 7657 of file chan_iax2.c.

References iax2_context::context, and iax2_context::next.

Referenced by check_access().

07658 {
07659    while(con) {
07660       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07661          return -1;
07662       con = con->next;
07663    }
07664    return 0;
07665 }

static int ast_cli_netstats ( struct mansession s,
int  fd,
int  limit_fmt 
) [static]

Definition at line 7352 of file chan_iax2.c.

References ACN_FORMAT1, ACN_FORMAT2, ARRAY_LEN, ast_cli(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, astman_append(), jb_info::current, chan_iax2_pvt::first_iax_message, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, chan_iax2_pvt::last_iax_message, jb_info::losspct, MARK_IAX_SUBCLASS_TX, jb_info::min, and chan_iax2_pvt::pingtime.

Referenced by handle_cli_iax2_show_netstats(), and manager_iax2_show_netstats().

07353 {
07354    int x;
07355    int numchans = 0;
07356    char first_message[10] = { 0, };
07357    char last_message[10] = { 0, };
07358 #define ACN_FORMAT1 "%-20.25s %4u %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
07359 #define ACN_FORMAT2 "%s %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
07360    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07361       ast_mutex_lock(&iaxsl[x]);
07362       if (iaxs[x]) {
07363          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
07364          jb_info jbinfo;
07365          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07366          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07367 
07368          if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07369             jb_getinfo(iaxs[x]->jb, &jbinfo);
07370             localjitter = jbinfo.jitter;
07371             localdelay = jbinfo.current - jbinfo.min;
07372             locallost = jbinfo.frames_lost;
07373             locallosspct = jbinfo.losspct/1000;
07374             localdropped = jbinfo.frames_dropped;
07375             localooo = jbinfo.frames_ooo;
07376          } else {
07377             localjitter = -1;
07378             localdelay = 0;
07379             locallost = -1;
07380             locallosspct = -1;
07381             localdropped = 0;
07382             localooo = -1;
07383          }
07384          if (s)
07385             astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07386                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07387                iaxs[x]->pingtime,
07388                localjitter,
07389                localdelay,
07390                locallost,
07391                locallosspct,
07392                localdropped,
07393                localooo,
07394                iaxs[x]->frames_received/1000,
07395                iaxs[x]->remote_rr.jitter,
07396                iaxs[x]->remote_rr.delay,
07397                iaxs[x]->remote_rr.losscnt,
07398                iaxs[x]->remote_rr.losspct,
07399                iaxs[x]->remote_rr.dropped,
07400                iaxs[x]->remote_rr.ooo,
07401                iaxs[x]->remote_rr.packets/1000,
07402                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07403                first_message,
07404                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07405                last_message);
07406          else
07407             ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07408                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07409                iaxs[x]->pingtime,
07410                localjitter,
07411                localdelay,
07412                locallost,
07413                locallosspct,
07414                localdropped,
07415                localooo,
07416                iaxs[x]->frames_received/1000,
07417                iaxs[x]->remote_rr.jitter,
07418                iaxs[x]->remote_rr.delay,
07419                iaxs[x]->remote_rr.losscnt,
07420                iaxs[x]->remote_rr.losspct,
07421                iaxs[x]->remote_rr.dropped,
07422                iaxs[x]->remote_rr.ooo,
07423                iaxs[x]->remote_rr.packets/1000,
07424                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07425                first_message,
07426                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07427                last_message);
07428          numchans++;
07429       }
07430       ast_mutex_unlock(&iaxsl[x]);
07431    }
07432 
07433    return numchans;
07434 }

AST_DATA_STRUCTURE ( iax2_user  ,
DATA_EXPORT_IAX2_USER   
)
AST_DATA_STRUCTURE ( iax2_peer  ,
DATA_EXPORT_IAX2_PEER   
)
static struct ast_channel* ast_iax2_new ( int  callno,
int  state,
format_t  capability,
const char *  linkedid,
unsigned int  cachable 
) [static, read]

Create new call, interface with the PBX core.

Definition at line 5838 of file chan_iax2.c.

References chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, ast_party_caller::ani, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_calloc, ast_channel_alloc, ast_channel_datastore_add(), ast_channel_release(), ast_copy_string(), ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_FLAG_DISABLE_DEVSTATE_CACHE, ast_free, ast_hangup(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, ast_log(), ast_module_ref(), ast_mutex_lock, ast_mutex_unlock, ast_pbx_start(), AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_var_assign(), ast_channel::caller, chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, chan_iax2_pvt::callno, CALLNO_TO_PTR, chan_iax2_pvt::capability, ast_channel::context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_channel::dialed, ast_channel::exten, ast_channel::flags, ast_party_redirecting::from, iax2_ami_channelupdate(), iax2_tech, iax2_variable_datastore_info, iaxs, iaxsl, ast_party_caller::id, ast_datastore::inheritance, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_party_id::name, ast_channel::nativeformats, ast_variable::next, ast_party_dialed::number, ast_party_id::number, chan_iax2_pvt::owner, parkinglot, 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, 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, and ast_channel::writeformat.

Referenced by iax2_request(), and socket_process().

05839 {
05840    struct ast_channel *tmp;
05841    struct chan_iax2_pvt *i;
05842    struct ast_variable *v = NULL;
05843 
05844    if (!(i = iaxs[callno])) {
05845       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05846       return NULL;
05847    }
05848 
05849    /* Don't hold call lock */
05850    ast_mutex_unlock(&iaxsl[callno]);
05851    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);
05852    ast_mutex_lock(&iaxsl[callno]);
05853    if (i != iaxs[callno]) {
05854       if (tmp) {
05855          /* unlock and relock iaxsl[callno] to preserve locking order */
05856          ast_mutex_unlock(&iaxsl[callno]);
05857          tmp = ast_channel_release(tmp);
05858          ast_mutex_lock(&iaxsl[callno]);
05859       }
05860       return NULL;
05861    }
05862    iax2_ami_channelupdate(i);
05863    if (!tmp)
05864       return NULL;
05865    tmp->tech = &iax2_tech;
05866    /* We can support any format by default, until we get restricted */
05867    tmp->nativeformats = capability;
05868    tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05869    tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05870    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05871 
05872    if (!ast_strlen_zero(i->parkinglot))
05873       ast_string_field_set(tmp, parkinglot, i->parkinglot);
05874    /* Don't use ast_set_callerid() here because it will
05875     * generate a NewCallerID event before the NewChannel event */
05876    if (!ast_strlen_zero(i->ani)) {
05877       tmp->caller.ani.number.valid = 1;
05878       tmp->caller.ani.number.str = ast_strdup(i->ani);
05879    } else if (!ast_strlen_zero(i->cid_num)) {
05880       tmp->caller.ani.number.valid = 1;
05881       tmp->caller.ani.number.str = ast_strdup(i->cid_num);
05882    }
05883    tmp->dialed.number.str = ast_strdup(i->dnid);
05884    if (!ast_strlen_zero(i->rdnis)) {
05885       tmp->redirecting.from.number.valid = 1;
05886       tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
05887    }
05888    tmp->caller.id.name.presentation = i->calling_pres;
05889    tmp->caller.id.number.presentation = i->calling_pres;
05890    tmp->caller.id.number.plan = i->calling_ton;
05891    tmp->dialed.transit_network_select = i->calling_tns;
05892    if (!ast_strlen_zero(i->language))
05893       ast_string_field_set(tmp, language, i->language);
05894    if (!ast_strlen_zero(i->accountcode))
05895       ast_string_field_set(tmp, accountcode, i->accountcode);
05896    if (i->amaflags)
05897       tmp->amaflags = i->amaflags;
05898    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05899    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05900    if (i->adsi)
05901       tmp->adsicpe = i->peeradsicpe;
05902    else
05903       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05904    i->owner = tmp;
05905    i->capability = capability;
05906 
05907    if (!cachable) {
05908       tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
05909    }
05910 
05911    /* Set inherited variables */
05912    if (i->vars) {
05913       for (v = i->vars ; v ; v = v->next)
05914          pbx_builtin_setvar_helper(tmp, v->name, v->value);
05915    }
05916    if (i->iaxvars) {
05917       struct ast_datastore *variablestore;
05918       struct ast_variable *var, *prev = NULL;
05919       AST_LIST_HEAD(, ast_var_t) *varlist;
05920       ast_debug(1, "Loading up the channel with IAXVARs\n");
05921       varlist = ast_calloc(1, sizeof(*varlist));
05922       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05923       if (variablestore && varlist) {
05924          variablestore->data = varlist;
05925          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05926          AST_LIST_HEAD_INIT(varlist);
05927          for (var = i->iaxvars; var; var = var->next) {
05928             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05929             if (prev)
05930                ast_free(prev);
05931             prev = var;
05932             if (!newvar) {
05933                /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */
05934                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05935             } else {
05936                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05937             }
05938          }
05939          if (prev)
05940             ast_free(prev);
05941          i->iaxvars = NULL;
05942          ast_channel_datastore_add(i->owner, variablestore);
05943       } else {
05944          if (variablestore) {
05945             ast_datastore_free(variablestore);
05946          }
05947          if (varlist) {
05948             ast_free(varlist);
05949          }
05950       }
05951    }
05952 
05953    if (state != AST_STATE_DOWN) {
05954       if (ast_pbx_start(tmp)) {
05955          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05956          ast_hangup(tmp);
05957          i->owner = NULL;
05958          return NULL;
05959       }
05960    }
05961 
05962    ast_module_ref(ast_module_info->self);
05963    return tmp;
05964 }

static AST_LIST_HEAD_NOLOCK ( iax_frame   )  [static]

a list of frames that may need to be retransmitted

Note:
The contents of this list do not need to be explicitly destroyed on module unload. This is because all active calls are destroyed, and all frames in this queue will get destroyed as a part of that process.
Contents protected by the iaxsl[] locks

peer connection private, keeps track of all the call numbers consumed by a single ip address

ip address consuming call numbers

Number of call numbers currently used by this ip address

Max call numbers allowed for this ip address

Specifies whether limit is set by a registration or not, if so normal limit setting rules do not apply to this address.

Definition at line 865 of file chan_iax2.c.

References iax2_trunk_peer::addr.

00912                {
00913    /*! ip address consuming call numbers */
00914    unsigned long addr;
00915    /*! Number of call numbers currently used by this ip address */
00916    uint16_t cur;
00917    /*! Max call numbers allowed for this ip address */
00918    uint16_t limit;
00919    /*! Specifies whether limit is set by a registration or not, if so normal
00920     *  limit setting rules do not apply to this address. */
00921    unsigned char reg;
00922 };

static AST_LIST_HEAD_STATIC ( dynamic_list  ,
iax2_thread   
) [static]
static AST_LIST_HEAD_STATIC ( active_list  ,
iax2_thread   
) [static]
static AST_LIST_HEAD_STATIC ( idle_list  ,
iax2_thread   
) [static]
static AST_LIST_HEAD_STATIC ( dpcache  ,
iax2_dpcache   
) [static]
static AST_LIST_HEAD_STATIC ( firmwares  ,
iax_firmware   
) [static]
static AST_LIST_HEAD_STATIC ( registrations  ,
iax2_registry   
) [static]
static AST_LIST_HEAD_STATIC ( tpeers  ,
iax2_trunk_peer   
) [static]
AST_MODULE_INFO ( ASTERISK_GPL_KEY  ,
AST_MODFLAG_LOAD_ORDER  ,
"Inter Asterisk eXchange (Ver 2)"  ,
load = load_module,
unload = unload_module,
reload = reload,
load_pri = AST_MODPRI_CHANNEL_DRIVER,
nonoptreq = "res_crypto" 
)
static int attempt_transmit ( const void *  data  )  [static]

Definition at line 3651 of file chan_iax2.c.

References __attempt_transmit(), and schedule_action.

Referenced by __attempt_transmit(), and transmit_frame().

03652 {
03653 #ifdef SCHED_MULTITHREADED
03654    if (schedule_action(__attempt_transmit, data))
03655 #endif      
03656       __attempt_transmit(data);
03657    return 0;
03658 }

static int auth_fail ( int  callno,
int  failcode 
) [static]

Definition at line 9146 of file chan_iax2.c.

References auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iax2_sched_replace(), and iaxs.

Referenced by socket_process().

09147 {
09148    /* Schedule sending the authentication failure in one second, to prevent
09149       guessing */
09150    if (iaxs[callno]) {
09151       iaxs[callno]->authfail = failcode;
09152       if (delayreject) {
09153          iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 
09154             sched, 1000, auth_reject, (void *)(long)callno);
09155       } else
09156          auth_reject((void *)(long)callno);
09157    }
09158    return 0;
09159 }

static int auth_reject ( const void *  data  )  [static]

Definition at line 9132 of file chan_iax2.c.

References __auth_reject(), ast_mutex_lock, ast_mutex_unlock, chan_iax2_pvt::authid, iaxs, iaxsl, and schedule_action.

Referenced by auth_fail().

09133 {
09134    int callno = (int)(long)(data);
09135    ast_mutex_lock(&iaxsl[callno]);
09136    if (iaxs[callno])
09137       iaxs[callno]->authid = -1;
09138    ast_mutex_unlock(&iaxsl[callno]);
09139 #ifdef SCHED_MULTITHREADED
09140    if (schedule_action(__auth_reject, data))
09141 #endif      
09142       __auth_reject(data);
09143    return 0;
09144 }

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 8230 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 authenticate_reply(), and registry_rerequest().

08231 {
08232    int res = -1;
08233    int x;
08234    if (!ast_strlen_zero(keyn)) {
08235       if (!(authmethods & IAX_AUTH_RSA)) {
08236          if (ast_strlen_zero(secret)) 
08237             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));
08238       } else if (ast_strlen_zero(challenge)) {
08239          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
08240       } else {
08241          char sig[256];
08242          struct ast_key *key;
08243          key = ast_key_get(keyn, AST_KEY_PRIVATE);
08244          if (!key) {
08245             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
08246          } else {
08247             if (ast_sign(key, (char*)challenge, sig)) {
08248                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
08249                res = -1;
08250             } else {
08251                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
08252                res = 0;
08253             }
08254          }
08255       }
08256    } 
08257    /* Fall back */
08258    if (res && !ast_strlen_zero(secret)) {
08259       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
08260          struct MD5Context md5;
08261          unsigned char digest[16];
08262          char digres[128];
08263          MD5Init(&md5);
08264          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
08265          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
08266          MD5Final(digest, &md5);
08267          /* If they support md5, authenticate with it.  */
08268          for (x=0;x<16;x++)
08269             sprintf(digres + (x << 1),  "%2.2x", (unsigned)digest[x]); /* safe */
08270          if (pvt) {
08271             build_encryption_keys(digest, pvt);
08272          }
08273          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
08274          res = 0;
08275       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
08276          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
08277          res = 0;
08278       } else
08279          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
08280    }
08281    return res;
08282 }

static int authenticate_reply ( struct chan_iax2_pvt p,
struct sockaddr_in *  sin,
struct iax_ies ies,
const char *  override,
const char *  okey 
) [static]
Note:
This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno, so do not call this function with a pvt lock held.

Definition at line 8288 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, iax_ies::challenge, ast_datastore::data, DATASTORE_INHERIT_FOREVER, chan_iax2_pvt::encmethods, iax_ies::encmethods, iax2_variable_datastore_info, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_FORCE_ENCRYPT, IAX_KEYPOPULATED, iaxs, iaxsl, ast_datastore::inheritance, LOG_ERROR, LOG_NOTICE, iax2_peer::mask, merge_encryption(), ast_variable::name, ast_variable::next, chan_iax2_pvt::owner, peer_unref(), iax_ie_data::pos, realtime_peer(), send_command(), iax_ies::username, ast_variable::value, var, and iax_ies::vars.

Referenced by socket_process().

08289 {
08290    struct iax2_peer *peer = NULL;
08291    /* Start pessimistic */
08292    int res = -1;
08293    int authmethods = 0;
08294    struct iax_ie_data ied;
08295    uint16_t callno = p->callno;
08296 
08297    memset(&ied, 0, sizeof(ied));
08298    
08299    if (ies->username)
08300       ast_string_field_set(p, username, ies->username);
08301    if (ies->challenge)
08302       ast_string_field_set(p, challenge, ies->challenge);
08303    if (ies->authmethods)
08304       authmethods = ies->authmethods;
08305    if (authmethods & IAX_AUTH_MD5)
08306       merge_encryption(p, ies->encmethods);
08307    else
08308       p->encmethods = 0;
08309 
08310    /* Check for override RSA authentication first */
08311    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
08312       /* Normal password authentication */
08313       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
08314    } else {
08315       struct ao2_iterator i = ao2_iterator_init(peers, 0);
08316       while ((peer = ao2_iterator_next(&i))) {
08317          struct sockaddr_in peer_addr;
08318 
08319          ast_sockaddr_to_sin(&peer->addr, &peer_addr);
08320 
08321          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
08322              /* No peer specified at our end, or this is the peer */
08323              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
08324              /* No username specified in peer rule, or this is the right username */
08325              && (!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)))
08326              /* No specified host, or this is our host */
08327             ) {
08328             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
08329             if (!res) {
08330                peer_unref(peer);
08331                break;
08332             }
08333          }
08334          peer_unref(peer);
08335       }
08336       ao2_iterator_destroy(&i);
08337       if (!peer) {
08338          /* We checked our list and didn't find one.  It's unlikely, but possible, 
08339             that we're trying to authenticate *to* a realtime peer */
08340          const char *peer_name = ast_strdupa(p->peer);
08341          ast_mutex_unlock(&iaxsl[callno]);
08342          if ((peer = realtime_peer(peer_name, NULL))) {
08343             ast_mutex_lock(&iaxsl[callno]);
08344             if (!(p = iaxs[callno])) {
08345                peer_unref(peer);
08346                return -1;
08347             }
08348             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
08349             peer_unref(peer);
08350          }
08351          if (!peer) {
08352             ast_mutex_lock(&iaxsl[callno]);
08353             if (!(p = iaxs[callno]))
08354                return -1;
08355          }
08356       }
08357    }
08358 
08359    if (ies->encmethods) {
08360       ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
08361    } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
08362       ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set\n");
08363       return -1;             /* if force encryption is yes, and no encryption methods, then return -1 to hangup */
08364    }
08365    if (!res) {
08366       struct ast_datastore *variablestore;
08367       struct ast_variable *var, *prev = NULL;
08368       AST_LIST_HEAD(, ast_var_t) *varlist;
08369       varlist = ast_calloc(1, sizeof(*varlist));
08370       variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08371       if (variablestore && varlist && p->owner) {
08372          variablestore->data = varlist;
08373          variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08374          AST_LIST_HEAD_INIT(varlist);
08375          for (var = ies->vars; var; var = var->next) {
08376             struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08377             if (prev)
08378                ast_free(prev);
08379             prev = var;
08380             if (!newvar) {
08381                /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */
08382                ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08383             } else {
08384                AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08385             }
08386          }
08387          if (prev)
08388             ast_free(prev);
08389          ies->vars = NULL;
08390          ast_channel_datastore_add(p->owner, variablestore);
08391       } else {
08392          if (p->owner)
08393             ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08394          if (variablestore)
08395             ast_datastore_free(variablestore);
08396          if (varlist)
08397             ast_free(varlist);
08398       }
08399    }
08400 
08401    if (!res)
08402       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
08403    return res;
08404 }

static int authenticate_request ( int  call_num  )  [static]
Precondition:
iaxsl[call_num] is locked
Note:
Since this function calls send_command_final(), the pvt struct for the given call number may disappear while executing this function.

Definition at line 7936 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, 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, iaxs, iax2_user::maxauthreq, OBJ_POINTER, iax_ie_data::pos, send_command(), send_command_final(), and user_unref().

Referenced by socket_process().

07937 {
07938    struct iax_ie_data ied;
07939    int res = -1, authreq_restrict = 0;
07940    char challenge[10];
07941    struct chan_iax2_pvt *p = iaxs[call_num];
07942 
07943    memset(&ied, 0, sizeof(ied));
07944 
07945    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
07946    if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07947       struct iax2_user *user, tmp_user = {
07948          .name = p->username, 
07949       };
07950 
07951       user = ao2_find(users, &tmp_user, OBJ_POINTER);
07952       if (user) {
07953          if (user->curauthreq == user->maxauthreq)
07954             authreq_restrict = 1;
07955          else
07956             user->curauthreq++;
07957          user = user_unref(user);
07958       }
07959    }
07960 
07961    /* If the AUTHREQ limit test failed, send back an error */
07962    if (authreq_restrict) {
07963       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07964       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07965       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07966       return 0;
07967    }
07968 
07969    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07970    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07971       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07972       ast_string_field_set(p, challenge, challenge);
07973       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
07974       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07975    }
07976    if (p->encmethods)
07977       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07978 
07979    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07980 
07981    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07982 
07983    if (p->encmethods)
07984       ast_set_flag64(p, IAX_ENCRYPTED);
07985 
07986    return res;
07987 }

static int authenticate_verify ( struct chan_iax2_pvt p,
struct iax_ies ies 
) [static]

Definition at line 7989 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, iax2_user::curauthreq, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_FORCE_ENCRYPT, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, LOG_NOTICE, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), OBJ_POINTER, iax_ies::password, iax_ies::rsa_result, secret, chan_iax2_pvt::state, and user_unref().

Referenced by socket_process().

07990 {
07991    char requeststr[256];
07992    char md5secret[256] = "";
07993    char secret[256] = "";
07994    char rsasecret[256] = "";
07995    int res = -1; 
07996    int x;
07997    struct iax2_user *user, tmp_user = {
07998       .name = p->username, 
07999    };
08000 
08001    if (p->authrej) {
08002       return res;
08003    }
08004    user = ao2_find(users, &tmp_user, OBJ_POINTER);
08005    if (user) {
08006       if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
08007          ast_atomic_fetchadd_int(&user->curauthreq, -1);
08008          ast_clear_flag64(p, IAX_MAXAUTHREQ);
08009       }
08010       ast_string_field_set(p, host, user->name);
08011       user = user_unref(user);
08012    }
08013    if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) { 
08014       ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.\n");
08015       return res;
08016    }
08017    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
08018       return res;
08019    if (ies->password)
08020       ast_copy_string(secret, ies->password, sizeof(secret));
08021    if (ies->md5_result)
08022       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
08023    if (ies->rsa_result)
08024       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
08025    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
08026       struct ast_key *key;
08027       char *keyn;
08028       char tmpkey[256];
08029       char *stringp=NULL;
08030       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
08031       stringp=tmpkey;
08032       keyn = strsep(&stringp, ":");
08033       while(keyn) {
08034          key = ast_key_get(keyn, AST_KEY_PUBLIC);
08035          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
08036             res = 0;
08037             break;
08038          } else if (!key)
08039             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
08040          keyn = strsep(&stringp, ":");
08041       }
08042    } else if (p->authmethods & IAX_AUTH_MD5) {
08043       struct MD5Context md5;
08044       unsigned char digest[16];
08045       char *tmppw, *stringp;
08046       
08047       tmppw = ast_strdupa(p->secret);
08048       stringp = tmppw;
08049       while((tmppw = strsep(&stringp, ";"))) {
08050          MD5Init(&md5);
08051          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
08052          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
08053          MD5Final(digest, &md5);
08054          /* If they support md5, authenticate with it.  */
08055          for (x=0;x<16;x++)
08056             sprintf(requeststr + (x << 1), "%2.2x", (unsigned)digest[x]); /* safe */
08057          if (!strcasecmp(requeststr, md5secret)) {
08058             res = 0;
08059             break;
08060          }
08061       }
08062    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
08063       if (!strcmp(secret, p->secret))
08064          res = 0;
08065    }
08066    return res;
08067 }

static int auto_congest ( const void *  data  )  [static]

Definition at line 4771 of file chan_iax2.c.

References __auto_congest(), and schedule_action.

Referenced by iax2_call().

04772 {
04773 #ifdef SCHED_MULTITHREADED
04774    if (schedule_action(__auto_congest, data))
04775 #endif      
04776       __auto_congest(data);
04777    return 0;
04778 }

static int auto_hangup ( const void *  data  )  [static]

Definition at line 9176 of file chan_iax2.c.

References __auto_hangup(), ast_mutex_lock, ast_mutex_unlock, chan_iax2_pvt::autoid, iaxs, iaxsl, and schedule_action.

Referenced by iax2_dprequest(), and iax2_provision().

09177 {
09178    int callno = (int)(long)(data);
09179    ast_mutex_lock(&iaxsl[callno]);
09180    if (iaxs[callno]) {
09181       iaxs[callno]->autoid = -1;
09182    }
09183    ast_mutex_unlock(&iaxsl[callno]);
09184 #ifdef SCHED_MULTITHREADED
09185    if (schedule_action(__auto_hangup, data))
09186 #endif      
09187       __auto_hangup(data);
09188    return 0;
09189 }

static void build_callno_limits ( struct ast_variable v  )  [static]

Definition at line 2542 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().

02543 {
02544    struct addr_range *addr_range = NULL;
02545    struct addr_range tmp;
02546    struct ast_ha *ha;
02547    int limit;
02548    int error;
02549    int found;
02550 
02551    for (; v; v = v->next) {
02552       limit = -1;
02553       error = 0;
02554       found = 0;
02555       ha = ast_append_ha("permit", v->name, NULL, &error);
02556 
02557       /* check for valid config information */
02558       if (error) {
02559          ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02560          continue;
02561       } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02562          ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02563          ast_free_ha(ha);
02564          continue;
02565       }
02566 
02567       ast_copy_ha(ha, &tmp.ha);
02568       /* find or create the addr_range */
02569       if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02570          ao2_lock(addr_range);
02571          found = 1;
02572       } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02573          ast_free_ha(ha);
02574          return; /* out of memory */
02575       }
02576 
02577       /* copy over config data into addr_range object */
02578       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */
02579       ast_free_ha(ha); /* cleanup the tmp ha */
02580       addr_range->limit = limit;
02581       addr_range->delme = 0;
02582 
02583       /* cleanup */
02584       if (found) {
02585          ao2_unlock(addr_range);
02586       } else {
02587          ao2_link(callno_limits, addr_range);
02588       }
02589       ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02590    }
02591 }

static struct iax2_context* build_context ( const char *  context  )  [static, read]

Definition at line 12474 of file chan_iax2.c.

References ast_calloc, ast_copy_string(), and iax2_context::context.

Referenced by build_user().

12475 {
12476    struct iax2_context *con;
12477 
12478    if ((con = ast_calloc(1, sizeof(*con))))
12479       ast_copy_string(con->context, context, sizeof(con->context));
12480    
12481    return con;
12482 }

static void build_ecx_key ( const unsigned char *  digest,
struct chan_iax2_pvt pvt 
) [static]

Definition at line 6305 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().

06306 {
06307    /* it is required to hold the corresponding decrypt key to our encrypt key
06308     * in the pvt struct because queued frames occasionally need to be decrypted and
06309     * re-encrypted when updated for a retransmission */
06310    build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
06311    ast_aes_set_encrypt_key(digest, &pvt->ecx);
06312    ast_aes_set_decrypt_key(digest, &pvt->mydcx);
06313 }

static void build_encryption_keys ( const unsigned char *  digest,
struct chan_iax2_pvt pvt 
) [static]

Definition at line 6299 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().

06300 {
06301    build_ecx_key(digest, pvt);
06302    ast_aes_set_decrypt_key(digest, &pvt->dcx);
06303 }

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 12623 of file chan_iax2.c.

References iax2_peer::addr, iax2_peer::adsi, ao2_alloc, ao2_find, ast_append_ha(), ast_callerid_split(), ast_clear_flag64, ast_copy_flags64, ast_dnsmgr_lookup(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_false(), ast_free_ha(), ast_get_ip(), ast_log(), ast_parse_allow_disallow(), ast_sched_thread_del, ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_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, 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, ast_sockaddr::len, ast_variable::lineno, LOG_WARNING, mailbox, iax2_peer::mask, iax2_peer::maxcallno, iax2_peer::maxms, mwi_event_cb(), iax2_peer::mwi_event_sub, ast_variable::name, ast_variable::next, OBJ_POINTER, 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, unlink_peer(), ast_variable::value, and zonetag.

Referenced by realtime_peer(), and set_config().

12624 {
12625    struct iax2_peer *peer = NULL;
12626    struct ast_ha *oldha = NULL;
12627    int maskfound = 0;
12628    int found = 0;
12629    int firstpass = 1;
12630    struct iax2_peer tmp_peer = {
12631       .name = name,
12632    };
12633 
12634    if (!temponly) {
12635       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
12636       if (peer && !ast_test_flag64(peer, IAX_DELME))
12637          firstpass = 0;
12638    }
12639 
12640    if (peer) {
12641       found++;
12642       if (firstpass) {
12643          oldha = peer->ha;
12644          peer->ha = NULL;
12645       }
12646       unlink_peer(peer);
12647    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
12648       peer->expire = -1;
12649       peer->pokeexpire = -1;
12650       peer->sockfd = defaultsockfd;
12651       peer->addr.ss.ss_family = AF_INET;
12652       peer->addr.len = sizeof(struct sockaddr_in);
12653       if (ast_string_field_init(peer, 32))
12654          peer = peer_unref(peer);
12655    }
12656 
12657    if (peer) {
12658       if (firstpass) {
12659          ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12660          peer->encmethods = iax2_encryption;
12661          peer->adsi = adsi;
12662          ast_string_field_set(peer,secret,"");
12663          if (!found) {
12664             ast_string_field_set(peer, name, name);
12665             ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12666             peer->expiry = min_reg_expire;
12667          }
12668          peer->prefs = prefs;
12669          peer->capability = iax2_capability;
12670          peer->smoothing = 0;
12671          peer->pokefreqok = DEFAULT_FREQ_OK;
12672          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
12673          peer->maxcallno = 0;
12674          peercnt_modify((unsigned char) 0, 0, &peer->addr);
12675          peer->calltoken_required = CALLTOKEN_DEFAULT;
12676          ast_string_field_set(peer,context,"");
12677          ast_string_field_set(peer,peercontext,"");
12678          ast_clear_flag64(peer, IAX_HASCALLERID);
12679          ast_string_field_set(peer, cid_name, "");
12680          ast_string_field_set(peer, cid_num, "");
12681          ast_string_field_set(peer, mohinterpret, mohinterpret);
12682          ast_string_field_set(peer, mohsuggest, mohsuggest);
12683       }
12684 
12685       if (!v) {
12686          v = alt;
12687          alt = NULL;
12688       }
12689       while(v) {
12690          if (!strcasecmp(v->name, "secret")) {
12691             ast_string_field_set(peer, secret, v->value);
12692          } else if (!strcasecmp(v->name, "mailbox")) {
12693             ast_string_field_set(peer, mailbox, v->value);
12694          } else if (!strcasecmp(v->name, "hasvoicemail")) {
12695             if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12696                ast_string_field_set(peer, mailbox, name);
12697             }
12698          } else if (!strcasecmp(v->name, "mohinterpret")) {
12699             ast_string_field_set(peer, mohinterpret, v->value);
12700          } else if (!strcasecmp(v->name, "mohsuggest")) {
12701             ast_string_field_set(peer, mohsuggest, v->value);
12702          } else if (!strcasecmp(v->name, "dbsecret")) {
12703             ast_string_field_set(peer, dbsecret, v->value);
12704          } else if (!strcasecmp(v->name, "trunk")) {
12705             ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK); 
12706             if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
12707                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12708                ast_clear_flag64(peer, IAX_TRUNK);
12709             }
12710          } else if (!strcasecmp(v->name, "auth")) {
12711             peer->authmethods = get_auth_methods(v->value);
12712          } else if (!strcasecmp(v->name, "encryption")) {
12713             peer->encmethods |= get_encrypt_methods(v->value);
12714             if (!peer->encmethods) {
12715                ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12716             }
12717          } else if (!strcasecmp(v->name, "forceencryption")) {
12718             if (ast_false(v->value)) {
12719                ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12720             } else {
12721                peer->encmethods |= get_encrypt_methods(v->value);
12722                if (peer->encmethods) {
12723                   ast_set_flag64(peer, IAX_FORCE_ENCRYPT);
12724                }
12725             }
12726          } else if (!strcasecmp(v->name, "transfer")) {
12727             if (!strcasecmp(v->value, "mediaonly")) {
12728                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12729             } else if (ast_true(v->value)) {
12730                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12731             } else
12732                ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12733          } else if (!strcasecmp(v->name, "jitterbuffer")) {
12734             ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF);
12735          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12736             ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12737          } else if (!strcasecmp(v->name, "host")) {
12738             if (!strcasecmp(v->value, "dynamic")) {
12739                /* They'll register with us */
12740                ast_set_flag64(peer, IAX_DYNAMIC);
12741                if (!found) {
12742                   /* Initialize stuff iff we're not found, otherwise
12743                      we keep going with what we had */
12744                   if (ast_sockaddr_port(&peer->addr)) {
12745                      peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr));
12746                   }
12747                   ast_sockaddr_setnull(&peer->addr);
12748                }
12749             } else {
12750                /* Non-dynamic.  Make sure we become that way if we're not */
12751                ast_sched_thread_del(sched, peer->expire);
12752                ast_clear_flag64(peer, IAX_DYNAMIC);
12753                if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12754                   return peer_unref(peer);
12755                if (!ast_sockaddr_port(&peer->addr)) {
12756                   ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12757                }
12758             }
12759             if (!maskfound)
12760                inet_aton("255.255.255.255", &peer->mask);
12761          } else if (!strcasecmp(v->name, "defaultip")) {
12762             struct ast_sockaddr peer_defaddr_tmp;
12763 
12764             peer_defaddr_tmp.ss.ss_family = AF_INET;
12765             if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
12766                return peer_unref(peer);
12767             }
12768             ast_sockaddr_to_sin(&peer_defaddr_tmp,
12769                       &peer->defaddr);
12770          } else if (!strcasecmp(v->name, "sourceaddress")) {
12771             peer_set_srcaddr(peer, v->value);
12772          } else if (!strcasecmp(v->name, "permit") ||
12773                   !strcasecmp(v->name, "deny")) {
12774             peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12775          } else if (!strcasecmp(v->name, "mask")) {
12776             maskfound++;
12777             inet_aton(v->value, &peer->mask);
12778          } else if (!strcasecmp(v->name, "context")) {
12779             ast_string_field_set(peer, context, v->value);
12780          } else if (!strcasecmp(v->name, "regexten")) {
12781             ast_string_field_set(peer, regexten, v->value);
12782          } else if (!strcasecmp(v->name, "peercontext")) {
12783             ast_string_field_set(peer, peercontext, v->value);
12784          } else if (!strcasecmp(v->name, "port")) {
12785             if (ast_test_flag64(peer, IAX_DYNAMIC)) {
12786                peer->defaddr.sin_port = htons(atoi(v->value));
12787             } else {
12788                ast_sockaddr_set_port(&peer->addr, atoi(v->value));
12789             }
12790          } else if (!strcasecmp(v->name, "username")) {
12791             ast_string_field_set(peer, username, v->value);
12792          } else if (!strcasecmp(v->name, "allow")) {
12793             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12794          } else if (!strcasecmp(v->name, "disallow")) {
12795             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12796          } else if (!strcasecmp(v->name, "callerid")) {
12797             if (!ast_strlen_zero(v->value)) {
12798                char name2[80];
12799                char num2[80];
12800                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12801                ast_string_field_set(peer, cid_name, name2);
12802                ast_string_field_set(peer, cid_num, num2);
12803             } else {
12804                ast_string_field_set(peer, cid_name, "");
12805                ast_string_field_set(peer, cid_num, "");
12806             }
12807             ast_set_flag64(peer, IAX_HASCALLERID);
12808          } else if (!strcasecmp(v->name, "fullname")) {
12809             ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12810             ast_set_flag64(peer, IAX_HASCALLERID);
12811          } else if (!strcasecmp(v->name, "cid_number")) {
12812             ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12813             ast_set_flag64(peer, IAX_HASCALLERID);
12814          } else if (!strcasecmp(v->name, "sendani")) {
12815             ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI);
12816          } else if (!strcasecmp(v->name, "inkeys")) {
12817             ast_string_field_set(peer, inkeys, v->value);
12818          } else if (!strcasecmp(v->name, "outkey")) {
12819             ast_string_field_set(peer, outkey, v->value);
12820          } else if (!strcasecmp(v->name, "qualify")) {
12821             if (!strcasecmp(v->value, "no")) {
12822                peer->maxms = 0;
12823             } else if (!strcasecmp(v->value, "yes")) {
12824                peer->maxms = DEFAULT_MAXMS;
12825             } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12826                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);
12827                peer->maxms = 0;
12828             }
12829          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12830             peer->smoothing = ast_true(v->value);
12831          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12832             if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12833                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);
12834             }
12835          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12836             if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12837                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);
12838             }
12839          } else if (!strcasecmp(v->name, "timezone")) {
12840             ast_string_field_set(peer, zonetag, v->value);
12841          } else if (!strcasecmp(v->name, "adsi")) {
12842             peer->adsi = ast_true(v->value);
12843          } else if (!strcasecmp(v->name, "connectedline")) {
12844             if (ast_true(v->value)) {
12845                ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12846             } else if (!strcasecmp(v->value, "send")) {
12847                ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE);
12848                ast_set_flag64(peer, IAX_SENDCONNECTEDLINE);
12849             } else if (!strcasecmp(v->value, "receive")) {
12850                ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE);
12851                ast_set_flag64(peer, IAX_RECVCONNECTEDLINE);
12852             } else {
12853                ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12854             }
12855          } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12856             if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12857                ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12858             } else {
12859                peercnt_modify((unsigned char) 1, peer->maxcallno, &peer->addr);
12860             }
12861          } else if (!strcasecmp(v->name, "requirecalltoken")) {
12862             /* default is required unless in optional ip list */
12863             if (ast_false(v->value)) {
12864                peer->calltoken_required = CALLTOKEN_NO;
12865             } else if (!strcasecmp(v->value, "auto")) {
12866                peer->calltoken_required = CALLTOKEN_AUTO;
12867             } else if (ast_true(v->value)) {
12868                peer->calltoken_required = CALLTOKEN_YES;
12869             } else {
12870                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12871             }
12872          } /* else if (strcasecmp(v->name,"type")) */
12873          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
12874          v = v->next;
12875          if (!v) {
12876             v = alt;
12877             alt = NULL;
12878          }
12879       }
12880       if (!peer->authmethods)
12881          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12882       ast_clear_flag64(peer, IAX_DELME);
12883    }
12884 
12885    if (oldha)
12886       ast_free_ha(oldha);
12887 
12888    if (!ast_strlen_zero(peer->mailbox)) {
12889       char *mailbox, *context;
12890       context = mailbox = ast_strdupa(peer->mailbox);
12891       strsep(&context, "@");
12892       if (ast_strlen_zero(context))
12893          context = "default";
12894       peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL,
12895          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12896          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12897          AST_EVENT_IE_END);
12898    }
12899 
12900    return peer;
12901 }

static void build_rand_pad ( unsigned char *  buf,
ssize_t  len 
) [static]

Definition at line 6289 of file chan_iax2.c.

References ast_random().

Referenced by build_ecx_key(), and update_packet().

06290 {
06291    long tmp;
06292    for (tmp = ast_random(); len > 0; tmp = ast_random()) {
06293       memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
06294       buf += sizeof(tmp);
06295       len -= sizeof(tmp);
06296    }
06297 }

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 12917 of file chan_iax2.c.

References iax2_user::adsi, iax2_user::amaflags, ao2_alloc, ao2_find, ao2_unlink, ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag64, ast_copy_flags64, ast_false(), ast_free_ha(), ast_log(), ast_parse_allow_disallow(), ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_strdupa, ast_string_field_build, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_true(), ast_variable_new(), iax2_user::authmethods, build_context(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_user::calltoken_required, CALLTOKEN_YES, iax2_user::capability, cid_name, cid_num, cleanup(), iax2_user::contexts, iax2_user::curauthreq, iax2_user::encmethods, format, free_context(), get_auth_methods(), get_encrypt_methods(), iax2_user::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_IMMEDIATE, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, ast_variable::lineno, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, ast_variable::next, iax2_context::next, OBJ_POINTER, parkinglot, prefs, iax2_user::prefs, secret, user_destructor(), user_unref(), ast_variable::value, and iax2_user::vars.

Referenced by realtime_user(), and set_config().

12918 {
12919    struct iax2_user *user = NULL;
12920    struct iax2_context *con, *conl = NULL;
12921    struct ast_ha *oldha = NULL;
12922    struct iax2_context *oldcon = NULL;
12923    int format;
12924    int firstpass=1;
12925    int oldcurauthreq = 0;
12926    char *varname = NULL, *varval = NULL;
12927    struct ast_variable *tmpvar = NULL;
12928    struct iax2_user tmp_user = {
12929       .name = name,
12930    };
12931 
12932    if (!temponly) {
12933       user = ao2_find(users, &tmp_user, OBJ_POINTER);
12934       if (user && !ast_test_flag64(user, IAX_DELME))
12935          firstpass = 0;
12936    }
12937 
12938    if (user) {
12939       if (firstpass) {
12940          oldcurauthreq = user->curauthreq;
12941          oldha = user->ha;
12942          oldcon = user->contexts;
12943          user->ha = NULL;
12944          user->contexts = NULL;
12945       }
12946       /* Already in the list, remove it and it will be added back (or FREE'd) */
12947       ao2_unlink(users, user);
12948    } else {
12949       user = ao2_alloc(sizeof(*user), user_destructor);
12950    }
12951    
12952    if (user) {
12953       if (firstpass) {
12954          ast_string_field_free_memory(user);
12955          memset(user, 0, sizeof(struct iax2_user));
12956          if (ast_string_field_init(user, 32)) {
12957             user = user_unref(user);
12958             goto cleanup;
12959          }
12960          user->maxauthreq = maxauthreq;
12961          user->curauthreq = oldcurauthreq;
12962          user->prefs = prefs;
12963          user->capability = iax2_capability;
12964          user->encmethods = iax2_encryption;
12965          user->adsi = adsi;
12966          user->calltoken_required = CALLTOKEN_DEFAULT;
12967          ast_string_field_set(user, name, name);
12968          ast_string_field_set(user, language, language);
12969          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);
12970          ast_clear_flag64(user, IAX_HASCALLERID);
12971          ast_string_field_set(user, cid_name, "");
12972          ast_string_field_set(user, cid_num, "");
12973          ast_string_field_set(user, accountcode, accountcode);
12974          ast_string_field_set(user, mohinterpret, mohinterpret);
12975          ast_string_field_set(user, mohsuggest, mohsuggest);
12976       }
12977       if (!v) {
12978          v = alt;
12979          alt = NULL;
12980       }
12981       while(v) {
12982          if (!strcasecmp(v->name, "context")) {
12983             con = build_context(v->value);
12984             if (con) {
12985                if (conl)
12986                   conl->next = con;
12987                else
12988                   user->contexts = con;
12989                conl = con;
12990             }
12991          } else if (!strcasecmp(v->name, "permit") ||
12992                   !strcasecmp(v->name, "deny")) {
12993             user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12994          } else if (!strcasecmp(v->name, "setvar")) {
12995             varname = ast_strdupa(v->value);
12996             if ((varval = strchr(varname, '='))) {
12997                *varval = '\0';
12998                varval++;
12999                if((tmpvar = ast_variable_new(varname, varval, ""))) {
13000                   tmpvar->next = user->vars; 
13001                   user->vars = tmpvar;
13002                }
13003             }
13004          } else if (!strcasecmp(v->name, "allow")) {
13005             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
13006          } else if (!strcasecmp(v->name, "disallow")) {
13007             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
13008          } else if (!strcasecmp(v->name, "trunk")) {
13009             ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK); 
13010             if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
13011                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
13012                ast_clear_flag64(user, IAX_TRUNK);
13013             }
13014          } else if (!strcasecmp(v->name, "auth")) {
13015             user->authmethods = get_auth_methods(v->value);
13016          } else if (!strcasecmp(v->name, "encryption")) {
13017             user->encmethods |= get_encrypt_methods(v->value);
13018             if (!user->encmethods) {
13019                ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
13020             }
13021          } else if (!strcasecmp(v->name, "forceencryption")) {
13022             if (ast_false(v->value)) {
13023                ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
13024             } else {
13025                user->encmethods |= get_encrypt_methods(v->value);
13026                if (user->encmethods) {
13027                   ast_set_flag64(user, IAX_FORCE_ENCRYPT);
13028                }
13029             }
13030          } else if (!strcasecmp(v->name, "transfer")) {
13031             if (!strcasecmp(v->value, "mediaonly")) {
13032                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13033             } else if (ast_true(v->value)) {
13034                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13035             } else
13036                ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13037          } else if (!strcasecmp(v->name, "codecpriority")) {
13038             if(!strcasecmp(v->value, "caller"))
13039                ast_set_flag64(user, IAX_CODEC_USER_FIRST);
13040             else if(!strcasecmp(v->value, "disabled"))
13041                ast_set_flag64(user, IAX_CODEC_NOPREFS);
13042             else if(!strcasecmp(v->value, "reqonly")) {
13043                ast_set_flag64(user, IAX_CODEC_NOCAP);
13044                ast_set_flag64(user, IAX_CODEC_NOPREFS);
13045             }
13046          } else if (!strcasecmp(v->name, "immediate")) {
13047             ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE);
13048          } else if (!strcasecmp(v->name, "jitterbuffer")) {
13049             ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF);
13050          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
13051             ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF);
13052          } else if (!strcasecmp(v->name, "dbsecret")) {
13053             ast_string_field_set(user, dbsecret, v->value);
13054          } else if (!strcasecmp(v->name, "secret")) {
13055             if (!ast_strlen_zero(user->secret)) {
13056                char *old = ast_strdupa(user->secret);
13057 
13058                ast_string_field_build(user, secret, "%s;%s", old, v->value);
13059             } else
13060                ast_string_field_set(user, secret, v->value);
13061          } else if (!strcasecmp(v->name, "callerid")) {
13062             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
13063                char name2[80];
13064                char num2[80];
13065                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
13066                ast_string_field_set(user, cid_name, name2);
13067                ast_string_field_set(user, cid_num, num2);
13068                ast_set_flag64(user, IAX_HASCALLERID);
13069             } else {
13070                ast_clear_flag64(user, IAX_HASCALLERID);
13071                ast_string_field_set(user, cid_name, "");
13072                ast_string_field_set(user, cid_num, "");
13073             }
13074          } else if (!strcasecmp(v->name, "fullname")) {
13075             if (!ast_strlen_zero(v->value)) {
13076                ast_string_field_set(user, cid_name, v->value);
13077                ast_set_flag64(user, IAX_HASCALLERID);
13078             } else {
13079                ast_string_field_set(user, cid_name, "");
13080                if (ast_strlen_zero(user->cid_num))
13081                   ast_clear_flag64(user, IAX_HASCALLERID);
13082             }
13083          } else if (!strcasecmp(v->name, "cid_number")) {
13084             if (!ast_strlen_zero(v->value)) {
13085                ast_string_field_set(user, cid_num, v->value);
13086                ast_set_flag64(user, IAX_HASCALLERID);
13087             } else {
13088                ast_string_field_set(user, cid_num, "");
13089                if (ast_strlen_zero(user->cid_name))
13090                   ast_clear_flag64(user, IAX_HASCALLERID);
13091             }
13092          } else if (!strcasecmp(v->name, "accountcode")) {
13093             ast_string_field_set(user, accountcode, v->value);
13094          } else if (!strcasecmp(v->name, "mohinterpret")) {
13095             ast_string_field_set(user, mohinterpret, v->value);
13096          } else if (!strcasecmp(v->name, "mohsuggest")) {
13097             ast_string_field_set(user, mohsuggest, v->value);
13098          } else if (!strcasecmp(v->name, "parkinglot")) {
13099             ast_string_field_set(user, parkinglot, v->value);
13100          } else if (!strcasecmp(v->name, "language")) {
13101             ast_string_field_set(user, language, v->value);
13102          } else if (!strcasecmp(v->name, "amaflags")) {
13103             format = ast_cdr_amaflags2int(v->value);
13104             if (format < 0) {
13105                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13106             } else {
13107                user->amaflags = format;
13108             }
13109          } else if (!strcasecmp(v->name, "inkeys")) {
13110             ast_string_field_set(user, inkeys, v->value);
13111          } else if (!strcasecmp(v->name, "maxauthreq")) {
13112             user->maxauthreq = atoi(v->value);
13113             if (user->maxauthreq < 0)
13114                user->maxauthreq = 0;
13115          } else if (!strcasecmp(v->name, "adsi")) {
13116             user->adsi = ast_true(v->value);
13117          } else if (!strcasecmp(v->name, "connectedline")) {
13118             if (ast_true(v->value)) {
13119                ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13120             } else if (!strcasecmp(v->value, "send")) {
13121                ast_clear_flag64(user, IAX_RECVCONNECTEDLINE);
13122                ast_set_flag64(user, IAX_SENDCONNECTEDLINE);
13123             } else if (!strcasecmp(v->value, "receive")) {
13124                ast_clear_flag64(user, IAX_SENDCONNECTEDLINE);
13125                ast_set_flag64(user, IAX_RECVCONNECTEDLINE);
13126             } else {
13127                ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13128             }
13129          } else if (!strcasecmp(v->name, "requirecalltoken")) {
13130             /* default is required unless in optional ip list */
13131             if (ast_false(v->value)) {
13132                user->calltoken_required = CALLTOKEN_NO;
13133             } else if (!strcasecmp(v->value, "auto")) {
13134                user->calltoken_required = CALLTOKEN_AUTO;
13135             } else if (ast_true(v->value)) {
13136                user->calltoken_required = CALLTOKEN_YES;
13137             } else {
13138                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
13139             }
13140          } /* else if (strcasecmp(v->name,"type")) */
13141          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
13142          v = v->next;
13143          if (!v) {
13144             v = alt;
13145             alt = NULL;
13146          }
13147       }
13148       if (!user->authmethods) {
13149          if (!ast_strlen_zero(user->secret)) {
13150             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
13151             if (!ast_strlen_zero(user->inkeys))
13152                user->authmethods |= IAX_AUTH_RSA;
13153          } else if (!ast_strlen_zero(user->inkeys)) {
13154             user->authmethods = IAX_AUTH_RSA;
13155          } else {
13156             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
13157          }
13158       }
13159       ast_clear_flag64(user, IAX_DELME);
13160    }
13161 cleanup:
13162    if (oldha)
13163       ast_free_ha(oldha);
13164    if (oldcon)
13165       free_context(oldcon);
13166    return user;
13167 }

static int cache_get_callno_locked ( const char *  data  )  [static]

Definition at line 13814 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, iaxs, iaxsl, 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().

13815 {
13816    struct sockaddr_in sin;
13817    int x;
13818    int callno;
13819    struct iax_ie_data ied;
13820    struct create_addr_info cai;
13821    struct parsed_dial_string pds;
13822    char *tmpstr;
13823 
13824    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13825       /* Look for an *exact match* call.  Once a call is negotiated, it can only
13826          look up entries for a single context */
13827       if (!ast_mutex_trylock(&iaxsl[x])) {
13828          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13829             return x;
13830          ast_mutex_unlock(&iaxsl[x]);
13831       }
13832    }
13833 
13834    /* No match found, we need to create a new one */
13835 
13836    memset(&cai, 0, sizeof(cai));
13837    memset(&ied, 0, sizeof(ied));
13838    memset(&pds, 0, sizeof(pds));
13839 
13840    tmpstr = ast_strdupa(data);
13841    parse_dial_string(tmpstr, &pds);
13842 
13843    if (ast_strlen_zero(pds.peer)) {
13844       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13845       return -1;
13846    }
13847 
13848    /* Populate our address from the given */
13849    if (create_addr(pds.peer, NULL, &sin, &cai))
13850       return -1;
13851 
13852    ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13853       pds.peer, pds.username, pds.password, pds.context);
13854 
13855    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13856    if (callno < 1) {
13857       ast_log(LOG_WARNING, "Unable to create call\n");
13858       return -1;
13859    }
13860 
13861    ast_string_field_set(iaxs[callno], dproot, data);
13862    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13863 
13864    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13865    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13866    /* the string format is slightly different from a standard dial string,
13867       because the context appears in the 'exten' position
13868    */
13869    if (pds.exten)
13870       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13871    if (pds.username)
13872       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13873    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13874    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13875    /* Keep password handy */
13876    if (pds.password)
13877       ast_string_field_set(iaxs[callno], secret, pds.password);
13878    if (pds.key)
13879       ast_string_field_set(iaxs[callno], outkey, pds.key);
13880    /* Start the call going */
13881    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
13882    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13883 
13884    return callno;
13885 }

static unsigned int calc_rxstamp ( struct chan_iax2_pvt p,
unsigned int  offset 
) [static]

Definition at line 6142 of file chan_iax2.c.

References ast_debug, ast_random(), ast_samp2tv(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, and chan_iax2_pvt::rxcore.

Referenced by schedule_delivery().

06143 {
06144    /* Returns where in "receive time" we are.  That is, how many ms
06145       since we received (or would have received) the frame with timestamp 0 */
06146    int ms;
06147 #ifdef IAXTESTS
06148    int jit;
06149 #endif /* IAXTESTS */
06150    /* Setup rxcore if necessary */
06151    if (ast_tvzero(p->rxcore)) {
06152       p->rxcore = ast_tvnow();
06153       if (iaxdebug)
06154          ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %ums\n",
06155                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
06156       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
06157 #if 1
06158       if (iaxdebug)
06159          ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
06160                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
06161 #endif
06162    }
06163 
06164    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
06165 #ifdef IAXTESTS
06166    if (test_jit) {
06167       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
06168          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
06169          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
06170             jit = -jit;
06171          ms += jit;
06172       }
06173    }
06174    if (test_late) {
06175       ms += test_late;
06176       test_late = 0;
06177    }
06178 #endif /* IAXTESTS */
06179    return ms;
06180 }

static unsigned int calc_timestamp ( struct chan_iax2_pvt p,
unsigned int  ts,
struct ast_frame f 
) [static]

Definition at line 6010 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_subclass::codec, ast_frame::delivery, ast_frame::frametype, iaxs, 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().

06011 {
06012    int ms;
06013    int voice = 0;
06014    int genuine = 0;
06015    int adjust;
06016    int rate = ast_format_rate(f->subclass.codec) / 1000;
06017    struct timeval *delivery = NULL;
06018 
06019 
06020    /* What sort of frame do we have?: voice is self-explanatory
06021       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
06022       non-genuine frames are CONTROL frames [ringing etc], DTMF
06023       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
06024       the others need a timestamp slaved to the voice frames so that they go in sequence
06025    */
06026    if (f->frametype == AST_FRAME_VOICE) {
06027       voice = 1;
06028       delivery = &f->delivery;
06029    } else if (f->frametype == AST_FRAME_IAX) {
06030       genuine = 1;
06031    } else if (f->frametype == AST_FRAME_CNG) {
06032       p->notsilenttx = 0;  
06033    }
06034 
06035    if (ast_tvzero(p->offset)) {
06036       p->offset = ast_tvnow();
06037       /* Round to nearest 20ms for nice looking traces */
06038       p->offset.tv_usec -= p->offset.tv_usec % 20000;
06039    }
06040    /* If the timestamp is specified, just send it as is */
06041    if (ts)
06042       return ts;
06043    /* If we have a time that the frame arrived, always use it to make our timestamp */
06044    if (delivery && !ast_tvzero(*delivery)) {
06045       ms = ast_tvdiff_ms(*delivery, p->offset);
06046       if (ms < 0) {
06047          ms = 0;
06048       }
06049       if (iaxdebug)
06050          ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
06051    } else {
06052       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
06053       if (ms < 0)
06054          ms = 0;
06055       if (voice) {
06056          /* On a voice frame, use predicted values if appropriate */
06057          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
06058             /* Adjust our txcore, keeping voice and non-voice synchronized */
06059             /* AN EXPLANATION:
06060                When we send voice, we usually send "calculated" timestamps worked out
06061                on the basis of the number of samples sent. When we send other frames,
06062                we usually send timestamps worked out from the real clock.
06063                The problem is that they can tend to drift out of step because the 
06064                   source channel's clock and our clock may not be exactly at the same rate.
06065                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
06066                for this call.  Moving it adjusts timestamps for non-voice frames.
06067                We make the adjustment in the style of a moving average.  Each time we
06068                adjust p->offset by 10% of the difference between our clock-derived
06069                timestamp and the predicted timestamp.  That's why you see "10000"
06070                below even though IAX2 timestamps are in milliseconds.
06071                The use of a moving average avoids offset moving too radically.
06072                Generally, "adjust" roams back and forth around 0, with offset hardly
06073                changing at all.  But if a consistent different starts to develop it
06074                will be eliminated over the course of 10 frames (200-300msecs) 
06075             */
06076             adjust = (ms - p->nextpred);
06077             if (adjust < 0)
06078                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
06079             else if (adjust > 0)
06080                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
06081 
06082             if (!p->nextpred) {
06083                p->nextpred = ms; /*f->samples / rate;*/
06084                if (p->nextpred <= p->lastsent)
06085                   p->nextpred = p->lastsent + 3;
06086             }
06087             ms = p->nextpred;
06088          } else {
06089                 /* in this case, just use the actual
06090             * time, since we're either way off
06091             * (shouldn't happen), or we're  ending a
06092             * silent period -- and seed the next
06093             * predicted time.  Also, round ms to the
06094             * next multiple of frame size (so our
06095             * silent periods are multiples of
06096             * frame size too) */
06097 
06098             if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
06099                ast_debug(1, "predicted timestamp skew (%d) > max (%d), using real ts instead.\n",
06100                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
06101 
06102             if (f->samples >= rate) /* check to make sure we don't core dump */
06103             {
06104                int diff = ms % (f->samples / rate);
06105                if (diff)
06106                    ms += f->samples/rate - diff;
06107             }
06108 
06109             p->nextpred = ms;
06110             p->notsilenttx = 1;
06111          }
06112       } else if ( f->frametype == AST_FRAME_VIDEO ) {
06113          /*
06114          * IAX2 draft 03 says that timestamps MUST be in order.
06115          * It does not say anything about several frames having the same timestamp
06116          * When transporting video, we can have a frame that spans multiple iax packets
06117          * (so called slices), so it would make sense to use the same timestamp for all of
06118          * them
06119          * We do want to make sure that frames don't go backwards though
06120          */
06121          if ( (unsigned int)ms < p->lastsent )
06122             ms = p->lastsent;
06123       } else {
06124          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
06125             it's a genuine frame */
06126          if (genuine) {
06127             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
06128             if (ms <= p->lastsent)
06129                ms = p->lastsent + 3;
06130          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
06131             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
06132             ms = p->lastsent + 3;
06133          }
06134       }
06135    }
06136    p->lastsent = ms;
06137    if (voice)
06138       p->nextpred = p->nextpred + f->samples / rate;
06139    return ms;
06140 }

static unsigned int calc_txpeerstamp ( struct iax2_trunk_peer tpeer,
int  sampms,
struct timeval *  now 
) [static]

Definition at line 5966 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().

05967 {
05968    unsigned long int mssincetx; /* unsigned to handle overflows */
05969    long int ms, pred;
05970 
05971    tpeer->trunkact = *now;
05972    mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05973    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05974       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
05975       tpeer->txtrunktime = *now;
05976       tpeer->lastsent = 999999;
05977    }
05978    /* Update last transmit time now */
05979    tpeer->lasttxtime = *now;
05980    
05981    /* Calculate ms offset */
05982    ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05983    /* Predict from last value */
05984    pred = tpeer->lastsent + sampms;
05985    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05986       ms = pred;
05987    
05988    /* We never send the same timestamp twice, so fudge a little if we must */
05989    if (ms == tpeer->lastsent)
05990       ms = tpeer->lastsent + 1;
05991    tpeer->lastsent = ms;
05992    return ms;
05993 }

static int callno_hash ( const void *  obj,
const int  flags 
) [static]

Definition at line 2765 of file chan_iax2.c.

References ast_random().

Referenced by create_callno_pools().

02766 {
02767    return abs(ast_random());
02768 }

static int calltoken_required ( struct sockaddr_in *  sin,
const char *  name,
int  subclass 
) [static]

Definition at line 2289 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().

02290 {
02291    struct addr_range *addr_range;
02292    struct iax2_peer *peer = NULL;
02293    struct iax2_user *user = NULL;
02294    /* if no username is given, check for guest accounts */
02295    const char *find = S_OR(name, "guest");
02296    int res = 1;  /* required by default */
02297    int optional = 0;
02298    enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
02299    /* There are only two cases in which calltoken validation is not required.
02300     * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and
02301     *         the peer definition has not set the requirecalltoken option.
02302     * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no.
02303     */
02304 
02305    /* ----- Case 1 ----- */
02306    if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
02307       ao2_ref(addr_range, -1);
02308       optional = 1;
02309    }
02310 
02311    /* ----- Case 2 ----- */
02312    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
02313       calltoken_required = user->calltoken_required;
02314    } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
02315       calltoken_required = user->calltoken_required;
02316    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
02317       calltoken_required = peer->calltoken_required;
02318    } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
02319       calltoken_required = peer->calltoken_required;
02320    }
02321 
02322    if (peer) {
02323       peer_unref(peer);
02324    }
02325    if (user) {
02326       user_unref(user);
02327    }
02328 
02329    ast_debug(1, "Determining if address %s with username %s requires calltoken validation.  Optional = %d  calltoken_required = %u\n", ast_inet_ntoa(sin->sin_addr), name, optional, calltoken_required);
02330    if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
02331       (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
02332       res = 0;
02333    }
02334 
02335    return res;
02336 }

static int check_access ( int  callno,
struct sockaddr_in *  sin,
struct iax_ies ies 
) [static]

Definition at line 7668 of file chan_iax2.c.

References 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_SENSE_ALLOW, AST_SENSE_DENY, ast_set2_flag64, ast_set_flag64, ast_shrink_phone_number(), ast_sockaddr_from_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_variable_new(), 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, cid_name, cid_num, iax_ies::codec_prefs, iax2_context::context, context, iax2_user::contexts, 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, iaxs, iax_ies::language, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, ast_variable::next, 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, user_unref(), iax_ies::username, ast_variable::value, iax2_user::vars, iax_ies::version, and version.

Referenced by socket_process().

07669 {
07670    /* Start pessimistic */
07671    int res = -1;
07672    int version = 2;
07673    struct iax2_user *user = NULL, *best = NULL;
07674    int bestscore = 0;
07675    int gotcapability = 0;
07676    struct ast_variable *v = NULL, *tmpvar = NULL;
07677    struct ao2_iterator i;
07678    struct ast_sockaddr addr;
07679 
07680    if (!iaxs[callno])
07681       return res;
07682    if (ies->called_number)
07683       ast_string_field_set(iaxs[callno], exten, ies->called_number);
07684    if (ies->calling_number) {
07685       if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) { 
07686          ast_shrink_phone_number(ies->calling_number);
07687       }
07688       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07689    }
07690    if (ies->calling_name)
07691       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07692    if (ies->calling_ani)
07693       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07694    if (ies->dnid)
07695       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07696    if (ies->rdnis)
07697       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07698    if (ies->called_context)
07699       ast_string_field_set(iaxs[callno], context, ies->called_context);
07700    if (ies->language)
07701       ast_string_field_set(iaxs[callno], language, ies->language);
07702    if (ies->username)
07703       ast_string_field_set(iaxs[callno], username, ies->username);
07704    if (ies->calling_ton > -1)
07705       iaxs[callno]->calling_ton = ies->calling_ton;
07706    if (ies->calling_tns > -1)
07707       iaxs[callno]->calling_tns = ies->calling_tns;
07708    if (ies->calling_pres > -1)
07709       iaxs[callno]->calling_pres = ies->calling_pres;
07710    if (ies->format)
07711       iaxs[callno]->peerformat = ies->format;
07712    if (ies->adsicpe)
07713       iaxs[callno]->peeradsicpe = ies->adsicpe;
07714    if (ies->capability) {
07715       gotcapability = 1;
07716       iaxs[callno]->peercapability = ies->capability;
07717    } 
07718    if (ies->version)
07719       version = ies->version;
07720 
07721    /* Use provided preferences until told otherwise for actual preferences */
07722    if (ies->codec_prefs) {
07723       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07724       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07725    }
07726 
07727    if (!gotcapability) 
07728       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07729    if (version > IAX_PROTO_VERSION) {
07730       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
07731          ast_inet_ntoa(sin->sin_addr), version);
07732       return res;
07733    }
07734    /* Search the userlist for a compatible entry, and fill in the rest */
07735    ast_sockaddr_from_sin(&addr, sin);
07736    i = ao2_iterator_init(users, 0);
07737    while ((user = ao2_iterator_next(&i))) {
07738       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
07739          !strcmp(iaxs[callno]->username, user->name))       /* Or this username specified */
07740          && ast_apply_ha(user->ha, &addr) == AST_SENSE_ALLOW      /* Access is permitted from this IP */
07741          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
07742             apply_context(user->contexts, iaxs[callno]->context))) {       /* Context is permitted */
07743          if (!ast_strlen_zero(iaxs[callno]->username)) {
07744             /* Exact match, stop right now. */
07745             if (best)
07746                user_unref(best);
07747             best = user;
07748             break;
07749          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07750             /* No required authentication */
07751             if (user->ha) {
07752                /* There was host authentication and we passed, bonus! */
07753                if (bestscore < 4) {
07754                   bestscore = 4;
07755                   if (best)
07756                      user_unref(best);
07757                   best = user;
07758                   continue;
07759                }
07760             } else {
07761                /* No host access, but no secret, either, not bad */
07762                if (bestscore < 3) {
07763                   bestscore = 3;
07764                   if (best)
07765                      user_unref(best);
07766                   best = user;
07767                   continue;
07768                }
07769             }
07770          } else {
07771             if (user->ha) {
07772                /* Authentication, but host access too, eh, it's something.. */
07773                if (bestscore < 2) {
07774                   bestscore = 2;
07775                   if (best)
07776                      user_unref(best);
07777                   best = user;
07778                   continue;
07779                }
07780             } else {
07781                /* Authentication and no host access...  This is our baseline */
07782                if (bestscore < 1) {
07783                   bestscore = 1;
07784                   if (best)
07785                      user_unref(best);
07786                   best = user;
07787                   continue;
07788                }
07789             }
07790          }
07791       }
07792       user_unref(user);
07793    }
07794    ao2_iterator_destroy(&i);
07795    user = best;
07796    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07797       user = realtime_user(iaxs[callno]->username, sin);
07798       if (user && (ast_apply_ha(user->ha, &addr) == AST_SENSE_DENY      /* Access is denied from this IP */
07799          || (!ast_strlen_zero(iaxs[callno]->context) &&              /* No context specified */
07800             !apply_context(user->contexts, iaxs[callno]->context)))) {  /* Context is permitted */
07801          user = user_unref(user);
07802       }
07803    }
07804    if (user) {
07805       /* We found our match (use the first) */
07806       /* copy vars */
07807       for (v = user->vars ; v ; v = v->next) {
07808          if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07809             tmpvar->next = iaxs[callno]->vars; 
07810             iaxs[callno]->vars = tmpvar;
07811          }
07812       }
07813       /* If a max AUTHREQ restriction is in place, activate it */
07814       if (user->maxauthreq > 0)
07815          ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ);
07816       iaxs[callno]->prefs = user->prefs;
07817       ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07818       iaxs[callno]->encmethods = user->encmethods;
07819       /* Store the requested username if not specified */
07820       if (ast_strlen_zero(iaxs[callno]->username))
07821          ast_string_field_set(iaxs[callno], username, user->name);
07822       /* Store whether this is a trunked call, too, of course, and move if appropriate */
07823       ast_copy_flags64(iaxs[callno], user, IAX_TRUNK);
07824       iaxs[callno]->capability = user->capability;
07825       /* And use the default context */
07826       if (ast_strlen_zero(iaxs[callno]->context)) {
07827          if (user->contexts)
07828             ast_string_field_set(iaxs[callno], context, user->contexts->context);
07829          else
07830             ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07831       }
07832       /* And any input keys */
07833       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07834       /* And the permitted authentication methods */
07835       iaxs[callno]->authmethods = user->authmethods;
07836       iaxs[callno]->adsi = user->adsi;
07837       /* If the user has callerid, override the remote caller id. */
07838       if (ast_test_flag64(user, IAX_HASCALLERID)) {
07839          iaxs[callno]->calling_tns = 0;
07840          iaxs[callno]->calling_ton = 0;
07841          ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07842          ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07843          ast_string_field_set(iaxs[callno], ani, user->cid_num);
07844          iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07845       } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07846          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07847       } /* else user is allowed to set their own CID settings */
07848       if (!ast_strlen_zero(user->accountcode))
07849          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07850       if (!ast_strlen_zero(user->mohinterpret))
07851          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07852       if (!ast_strlen_zero(user->mohsuggest))
07853          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07854       if (!ast_strlen_zero(user->parkinglot))
07855          ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07856       if (user->amaflags)
07857          iaxs[callno]->amaflags = user->amaflags;
07858       if (!ast_strlen_zero(user->language))
07859          ast_string_field_set(iaxs[callno], language, user->language);
07860       ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 
07861       /* Keep this check last */
07862       if (!ast_strlen_zero(user->dbsecret)) {
07863          char *family, *key=NULL;
07864          char buf[80];
07865          family = ast_strdupa(user->dbsecret);
07866          key = strchr(family, '/');
07867          if (key) {
07868             *key = '\0';
07869             key++;
07870          }
07871          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07872             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07873          else
07874             ast_string_field_set(iaxs[callno], secret, buf);
07875       } else
07876          ast_string_field_set(iaxs[callno], secret, user->secret);
07877       res = 0;
07878       user = user_unref(user);
07879    } else {
07880        /* user was not found, but we should still fake an AUTHREQ.
07881         * Set authmethods to the last known authmethod used by the system
07882         * Set a fake secret, it's not looked at, just required to attempt authentication.
07883         * Set authrej so the AUTHREP is rejected without even looking at its contents */
07884       iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07885       ast_string_field_set(iaxs[callno], secret, "badsecret");
07886       iaxs[callno]->authrej = 1;
07887       if (!ast_strlen_zero(iaxs[callno]->username)) {
07888          /* only send the AUTHREQ if a username was specified. */
07889          res = 0;
07890       }
07891    }
07892    ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07893    return res;
07894 }

static int check_provisioning ( struct sockaddr_in *  sin,
int  sockfd,
char *  si,
unsigned int  ver 
) [static]

Definition at line 9546 of file chan_iax2.c.

References ast_debug, iax2_provision(), and iax_provision_version().

Referenced by socket_process().

09547 {
09548    unsigned int ourver;
09549    char rsi[80];
09550    snprintf(rsi, sizeof(rsi), "si-%s", si);
09551    if (iax_provision_version(&ourver, rsi, 1))
09552       return 0;
09553    ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09554    if (ourver != ver) 
09555       iax2_provision(sin, sockfd, NULL, rsi, 1);
09556    return 0;
09557 }

static int check_srcaddr ( struct sockaddr *  sa,
socklen_t  salen 
) [static]

Check if address can be used as packet source.

Returns:
0 address available, 1 address unavailable, -1 error

Definition at line 12500 of file chan_iax2.c.

References ast_debug, ast_log(), errno, and LOG_ERROR.

Referenced by peer_set_srcaddr().

12501 {
12502    int sd;
12503    int res;
12504    
12505    sd = socket(AF_INET, SOCK_DGRAM, 0);
12506    if (sd < 0) {
12507       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12508       return -1;
12509    }
12510 
12511    res = bind(sd, sa, salen);
12512    if (res < 0) {
12513       ast_debug(1, "Can't bind: %s\n", strerror(errno));
12514       close(sd);
12515       return 1;
12516    }
12517 
12518    close(sd);
12519    return 0;
12520 }

static void cleanup_thread_list ( void *  head  )  [static]

Definition at line 14554 of file chan_iax2.c.

References AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, signal_condition(), and thread.

Referenced by __unload_module().

14555 {
14556    AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14557    struct iax2_thread_list *list_head = head;
14558    struct iax2_thread *thread;
14559 
14560    AST_LIST_LOCK(list_head);
14561    while ((thread = AST_LIST_REMOVE_HEAD(list_head, list))) {
14562       pthread_t thread_id = thread->threadid;
14563 
14564       thread->stop = 1;
14565       signal_condition(&thread->lock, &thread->cond);
14566 
14567       AST_LIST_UNLOCK(list_head);
14568       pthread_join(thread_id, NULL);
14569       AST_LIST_LOCK(list_head);
14570    }
14571    AST_LIST_UNLOCK(list_head);
14572 }

static int complete_dpreply ( struct chan_iax2_pvt pvt,
struct iax_ies ies 
) [static]

Definition at line 8458 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, iax_ies::refresh, status, and iax2_dpcache::waiters.

Referenced by socket_process().

08459 {
08460    char exten[256] = "";
08461    int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08462    struct iax2_dpcache *dp = NULL;
08463    
08464    if (ies->called_number)
08465       ast_copy_string(exten, ies->called_number, sizeof(exten));
08466    
08467    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08468       status = CACHE_FLAG_EXISTS;
08469    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08470       status = CACHE_FLAG_CANEXIST;
08471    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08472       status = CACHE_FLAG_NONEXISTENT;
08473 
08474    if (ies->refresh)
08475       expiry = ies->refresh;
08476    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08477       matchmore = CACHE_FLAG_MATCHMORE;
08478    
08479    AST_LIST_LOCK(&dpcache);
08480    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08481       if (strcmp(dp->exten, exten))
08482          continue;
08483       AST_LIST_REMOVE_CURRENT(peer_list);
08484       dp->callno = 0;
08485       dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08486       if (dp->flags & CACHE_FLAG_PENDING) {
08487          dp->flags &= ~CACHE_FLAG_PENDING;
08488          dp->flags |= status;
08489          dp->flags |= matchmore;
08490       }
08491       /* Wake up waiters */
08492       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08493          if (dp->waiters[x] > -1) {
08494             if (write(dp->waiters[x], "asdf", 4) < 0) {
08495             }
08496          }
08497       }
08498    }
08499    AST_LIST_TRAVERSE_SAFE_END;
08500    AST_LIST_UNLOCK(&dpcache);
08501 
08502    return 0;
08503 }

static char * complete_iax2_peers ( const char *  line,
const char *  word,
int  pos,
int  state,
uint64_t  flags 
) [static]

Definition at line 3918 of file chan_iax2.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, ast_test_flag64, and peer_unref().

Referenced by handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), and handle_cli_iax2_show_peer().

03919 {
03920    int which = 0;
03921    struct iax2_peer *peer;
03922    char *res = NULL;
03923    int wordlen = strlen(word);
03924    struct ao2_iterator i;
03925 
03926    i = ao2_iterator_init(peers, 0);
03927    while ((peer = ao2_iterator_next(&i))) {
03928       if (!strncasecmp(peer->name, word, wordlen) && ++which > state
03929          && (!flags || ast_test_flag64(peer, flags))) {
03930          res = ast_strdup(peer->name);
03931          peer_unref(peer);
03932          break;
03933       }
03934       peer_unref(peer);
03935    }
03936    ao2_iterator_destroy(&i);
03937 
03938    return res;
03939 }

static char * complete_iax2_unregister ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 7009 of file chan_iax2.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, iax2_peer::expire, and peer_unref().

Referenced by handle_cli_iax2_unregister().

07010 {
07011    int which = 0;
07012    struct iax2_peer *p = NULL;
07013    char *res = NULL;
07014    int wordlen = strlen(word);
07015 
07016    /* 0 - iax2; 1 - unregister; 2 - <peername> */
07017    if (pos == 2) {
07018       struct ao2_iterator i = ao2_iterator_init(peers, 0);
07019       while ((p = ao2_iterator_next(&i))) {
07020          if (!strncasecmp(p->name, word, wordlen) && 
07021             ++which > state && p->expire > 0) {
07022             res = ast_strdup(p->name);
07023             peer_unref(p);
07024             break;
07025          }
07026          peer_unref(p);
07027       }
07028       ao2_iterator_destroy(&i);
07029    }
07030 
07031    return res;
07032 }

static int complete_transfer ( int  callno,
struct iax_ies ies 
) [static]

Definition at line 8505 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, iax2_frame_free(), iaxs, chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), JB_OK, jb_reset(), chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::lastsent, 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().

08506 {
08507    int peercallno = 0;
08508    struct chan_iax2_pvt *pvt = iaxs[callno];
08509    struct iax_frame *cur;
08510    jb_frame frame;
08511 
08512    if (ies->callno)
08513       peercallno = ies->callno;
08514 
08515    if (peercallno < 1) {
08516       ast_log(LOG_WARNING, "Invalid transfer request\n");
08517       return -1;
08518    }
08519    remove_by_transfercallno(pvt);
08520    /* since a transfer has taken place, the address will change.
08521     * This must be accounted for in the peercnts table.  Remove
08522     * the old address and add the new one */
08523    peercnt_remove_by_addr(&pvt->addr);
08524    peercnt_add(&pvt->transfer);
08525    /* now copy over the new address */
08526    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08527    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08528    /* Reset sequence numbers */
08529    pvt->oseqno = 0;
08530    pvt->rseqno = 0;
08531    pvt->iseqno = 0;
08532    pvt->aseqno = 0;
08533 
08534    if (pvt->peercallno) {
08535       remove_by_peercallno(pvt);
08536    }
08537    pvt->peercallno = peercallno;
08538    /*this is where the transfering call swiches hash tables */
08539    store_by_peercallno(pvt);
08540    pvt->transferring = TRANSFER_NONE;
08541    pvt->svoiceformat = -1;
08542    pvt->voiceformat = 0;
08543    pvt->svideoformat = -1;
08544    pvt->videoformat = 0;
08545    pvt->transfercallno = 0;
08546    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08547    memset(&pvt->offset, 0, sizeof(pvt->offset));
08548    /* reset jitterbuffer */
08549    while(jb_getall(pvt->jb,&frame) == JB_OK)
08550       iax2_frame_free(frame.data);
08551    jb_reset(pvt->jb);
08552    pvt->lag = 0;
08553    pvt->last = 0;
08554    pvt->lastsent = 0;
08555    pvt->nextpred = 0;
08556    pvt->pingtime = DEFAULT_RETRY_TIME;
08557    AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) {
08558       /* We must cancel any packets that would have been transmitted
08559          because now we're talking to someone new.  It's okay, they
08560          were transmitted to someone that didn't care anyway. */
08561       cur->retries = -1;
08562    }
08563    return 0;
08564 }

static unsigned char compress_subclass ( format_t  subclass  )  [static]

Definition at line 1691 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().

01692 {
01693    int x;
01694    int power=-1;
01695    /* If it's 64 or smaller, just return it */
01696    if (subclass < IAX_FLAG_SC_LOG)
01697       return subclass;
01698    /* Otherwise find its power */
01699    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01700       if (subclass & (1LL << x)) {
01701          if (power > -1) {
01702             ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass);
01703             return 0;
01704          } else
01705             power = x;
01706       }
01707    }
01708    return power | IAX_FLAG_SC_LOG;
01709 }

static void construct_rr ( struct chan_iax2_pvt pvt,
struct iax_ie_data iep 
) [static]

Definition at line 9559 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().

09560 {
09561    jb_info stats;
09562    jb_getinfo(pvt->jb, &stats);
09563    
09564    memset(iep, 0, sizeof(*iep));
09565 
09566    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09567    if(stats.frames_in == 0) stats.frames_in = 1;
09568    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09569    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09570    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09571    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09572    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09573 }

static int create_addr ( const char *  peername,
struct ast_channel c,
struct sockaddr_in *  sin,
struct create_addr_info cai 
) [static]

Definition at line 4657 of file chan_iax2.c.

References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ast_clear_flag64, ast_codec_pref_convert(), ast_codec_pref_prepend(), ast_copy_flags64, ast_copy_string(), ast_db_get(), ast_debug, ast_get_ip_or_srv(), ast_log(), ast_sockaddr_to_sin, ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, create_addr_info::cid_name, create_addr_info::cid_num, create_addr_info::context, 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, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_channel::nativeformats, create_addr_info::outkey, peer_unref(), create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, ast_sockaddr::ss, create_addr_info::timezone, and create_addr_info::username.

Referenced by cache_get_callno_locked(), iax2_call(), iax2_provision(), and iax2_request().

04658 {
04659    struct iax2_peer *peer;
04660    int res = -1;
04661    struct ast_codec_pref ourprefs;
04662    struct sockaddr_in peer_addr;
04663 
04664    ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK);
04665    cai->sockfd = defaultsockfd;
04666    cai->maxtime = 0;
04667    sin->sin_family = AF_INET;
04668 
04669    if (!(peer = find_peer(peername, 1))) {
04670       struct ast_sockaddr sin_tmp;
04671 
04672       cai->found = 0;
04673       sin_tmp.ss.ss_family = AF_INET;
04674       if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) {
04675          ast_log(LOG_WARNING, "No such host: %s\n", peername);
04676          return -1;
04677       }
04678       ast_sockaddr_to_sin(&sin_tmp, sin);
04679       if (sin->sin_port == 0) {
04680          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04681       }
04682       /* use global iax prefs for unknown peer/user */
04683       /* But move the calling channel's native codec to the top of the preference list */
04684       memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04685       if (c)
04686          ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04687       ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04688       return 0;
04689    }
04690 
04691    cai->found = 1;
04692 
04693    ast_sockaddr_to_sin(&peer->addr, &peer_addr);
04694 
04695    /* if the peer has no address (current or default), return failure */
04696    if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
04697       goto return_unref;
04698    }
04699 
04700    /* if the peer is being monitored and is currently unreachable, return failure */
04701    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04702       goto return_unref;
04703 
04704    ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
04705    cai->maxtime = peer->maxms;
04706    cai->capability = peer->capability;
04707    cai->encmethods = peer->encmethods;
04708    cai->sockfd = peer->sockfd;
04709    cai->adsi = peer->adsi;
04710    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04711    /* Move the calling channel's native codec to the top of the preference list */
04712    if (c) {
04713       ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats);
04714       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04715    }
04716    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04717    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04718    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04719    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04720    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04721    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04722    ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num));
04723    ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name));
04724    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04725    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04726    if (ast_strlen_zero(peer->dbsecret)) {
04727       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04728    } else {
04729       char *family;
04730       char *key = NULL;
04731 
04732       family = ast_strdupa(peer->dbsecret);
04733       key = strchr(family, '/');
04734       if (key)
04735          *key++ = '\0';
04736       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04737          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04738          goto return_unref;
04739       }
04740    }
04741 
04742    if (peer_addr.sin_addr.s_addr) {
04743       sin->sin_addr = peer_addr.sin_addr;
04744       sin->sin_port = peer_addr.sin_port;
04745    } else {
04746       sin->sin_addr = peer->defaddr.sin_addr;
04747       sin->sin_port = peer->defaddr.sin_port;
04748    }
04749 
04750    res = 0;
04751 
04752 return_unref:
04753    peer_unref(peer);
04754 
04755    return res;
04756 }

static int create_callno_pools ( void   )  [static]

Definition at line 2770 of file chan_iax2.c.

References ao2_alloc, ao2_container_alloc, ao2_link, ao2_ref, callno_entry::callno, and callno_hash().

Referenced by load_objects().

02771 {
02772    uint16_t i;
02773 
02774    if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02775       return -1;
02776    }
02777 
02778    if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02779       return -1;
02780    }
02781 
02782    /* start at 2, 0 and 1 are reserved */
02783    for (i = 2; i < IAX_MAX_CALLS; i++) {
02784       struct callno_entry *callno_entry;
02785 
02786       if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02787          return -1;
02788       }
02789 
02790       callno_entry->callno = i;
02791 
02792       if (i < TRUNK_CALL_START) {
02793          ao2_link(callno_pool, callno_entry);
02794       } else {
02795          ao2_link(callno_pool_trunk, callno_entry);
02796       }
02797 
02798       ao2_ref(callno_entry, -1);
02799    }
02800 
02801    return 0;
02802 }

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 6363 of file chan_iax2.c.

References ast_alloca, ast_debug, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frame_subclass::codec, ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, 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().

06364 {
06365    int padding;
06366    unsigned char *workspace;
06367 
06368    workspace = ast_alloca(*datalen);
06369    memset(f, 0, sizeof(*f));
06370    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06371       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06372       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
06373          return -1;
06374       /* Decrypt */
06375       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
06376 
06377       padding = 16 + (workspace[15] & 0x0f);
06378       if (iaxdebug)
06379          ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, (unsigned)workspace[15]);
06380       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
06381          return -1;
06382 
06383       *datalen -= padding;
06384       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06385       f->frametype = fh->type;
06386       if (f->frametype == AST_FRAME_VIDEO) {
06387          f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06388       } else if (f->frametype == AST_FRAME_VOICE) {
06389          f->subclass.codec = uncompress_subclass(fh->csub);
06390       } else {
06391          f->subclass.integer = uncompress_subclass(fh->csub);
06392       }
06393    } else {
06394       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06395       if (iaxdebug)
06396          ast_debug(1, "Decoding mini with length %d\n", *datalen);
06397       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
06398          return -1;
06399       /* Decrypt */
06400       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06401       padding = 16 + (workspace[15] & 0x0f);
06402       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06403          return -1;
06404       *datalen -= padding;
06405       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06406    }
06407    return 0;
06408 }

static int decrypt_frame ( int  callno,
struct ast_iax2_full_hdr fh,
struct ast_frame f,
int *  datalen 
) [static]

Definition at line 6449 of file chan_iax2.c.

References ast_set_flag64, ast_strdupa, ast_test_flag64, build_encryption_keys(), decode_frame(), IAX_KEYPOPULATED, iaxs, MD5Final(), MD5Init(), MD5Update(), and secret.

Referenced by socket_process().

06450 {
06451    int res=-1;
06452    if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
06453       /* Search for possible keys, given secrets */
06454       struct MD5Context md5;
06455       unsigned char digest[16];
06456       char *tmppw, *stringp;
06457       
06458       tmppw = ast_strdupa(iaxs[callno]->secret);
06459       stringp = tmppw;
06460       while ((tmppw = strsep(&stringp, ";"))) {
06461          MD5Init(&md5);
06462          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06463          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06464          MD5Final(digest, &md5);
06465          build_encryption_keys(digest, iaxs[callno]);
06466          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06467          if (!res) {
06468             ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED);
06469             break;
06470          }
06471       }
06472    } else 
06473       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06474    return res;
06475 }

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 9706 of file chan_iax2.c.

References ast_calloc, ast_cond_signal, 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, IAX_IOSTATE_READY, and ast_iax2_full_hdr::oseqno.

Referenced by socket_read().

09707 {
09708    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09709    struct ast_iax2_full_hdr *fh, *cur_fh;
09710 
09711    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09712       return;
09713 
09714    pkt_buf->len = from_here->buf_len;
09715    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09716 
09717    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09718    ast_mutex_lock(&to_here->lock);
09719    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09720       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09721       if (fh->oseqno < cur_fh->oseqno) {
09722          AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09723          break;
09724       }
09725    }
09726    AST_LIST_TRAVERSE_SAFE_END
09727 
09728    if (!cur_pkt_buf)
09729       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09730 
09731    to_here->iostate = IAX_IOSTATE_READY;
09732    ast_cond_signal(&to_here->cond);
09733    
09734    ast_mutex_unlock(&to_here->lock);
09735 }

static void delete_users ( void   )  [static]

Definition at line 13187 of file chan_iax2.c.

References ao2_callback, ast_dnsmgr_release(), ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_del, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, iax2_destroy(), iaxs, iaxsl, peer_delme_cb(), chan_iax2_pvt::reg, and user_delme_cb().

Referenced by __unload_module(), and set_config_destroy().

13188 {
13189    struct iax2_registry *reg;
13190 
13191    ao2_callback(users, 0, user_delme_cb, NULL);
13192 
13193    AST_LIST_LOCK(&registrations);
13194    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
13195       if (sched) {
13196          ast_sched_thread_del(sched, reg->expire);
13197       }
13198       if (reg->callno) {
13199          int callno = reg->callno;
13200          ast_mutex_lock(&iaxsl[callno]);
13201          if (iaxs[callno]) {
13202             iaxs[callno]->reg = NULL;
13203             iax2_destroy(callno);
13204          }
13205          ast_mutex_unlock(&iaxsl[callno]);
13206       }
13207       if (reg->dnsmgr)
13208          ast_dnsmgr_release(reg->dnsmgr);
13209       ast_free(reg);
13210    }
13211    AST_LIST_UNLOCK(&registrations);
13212 
13213    ao2_callback(peers, 0, peer_delme_cb, NULL);
13214 }

static void destroy_firmware ( struct iax_firmware cur  )  [static]

Definition at line 3100 of file chan_iax2.c.

References ast_free.

Referenced by reload_firmware().

03101 {
03102    /* Close firmware */
03103    if (cur->fwh) {
03104       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
03105    }
03106    close(cur->fd);
03107    ast_free(cur);
03108 }

static void dp_lookup ( int  callno,
const char *  context,
const char *  callednum,
const char *  callerid,
int  skiplock 
) [static]

Definition at line 9361 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, iaxs, iaxsl, iax_ie_data::pos, and send_command().

Referenced by dp_lookup_thread(), and socket_process().

09362 {
09363    unsigned short dpstatus = 0;
09364    struct iax_ie_data ied1;
09365    int mm;
09366 
09367    memset(&ied1, 0, sizeof(ied1));
09368    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
09369    /* Must be started */
09370    if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
09371       dpstatus = IAX_DPSTATUS_EXISTS;
09372    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
09373       dpstatus = IAX_DPSTATUS_CANEXIST;
09374    } else {
09375       dpstatus = IAX_DPSTATUS_NONEXISTENT;
09376    }
09377    if (ast_ignore_pattern(context, callednum))
09378       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
09379    if (mm)
09380       dpstatus |= IAX_DPSTATUS_MATCHMORE;
09381    if (!skiplock)
09382       ast_mutex_lock(&iaxsl[callno]);
09383    if (iaxs[callno]) {
09384       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
09385       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
09386       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
09387       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
09388    }
09389    if (!skiplock)
09390       ast_mutex_unlock(&iaxsl[callno]);
09391 }

static void* dp_lookup_thread ( void *  data  )  [static]

Definition at line 9393 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().

09394 {
09395    /* Look up for dpreq */
09396    struct dpreq_data *dpr = data;
09397    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
09398    if (dpr->callerid)
09399       ast_free(dpr->callerid);
09400    ast_free(dpr);
09401    return NULL;
09402 }

static void encmethods_to_str ( int  e,
struct ast_str **  buf 
) [static]

Definition at line 1625 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().

01626 {
01627    ast_str_set(buf, 0, "(");
01628    if (e & IAX_ENCRYPT_AES128) {
01629       ast_str_append(buf, 0, "aes128");
01630    }
01631    if (e & IAX_ENCRYPT_KEYROTATE) {
01632       ast_str_append(buf, 0, ",keyrotate");
01633    }
01634    if (ast_str_strlen(*buf) > 1) {
01635       ast_str_append(buf, 0, ")");
01636    } else {
01637       ast_str_set(buf, 0, "No");
01638    }
01639 }

static int encrypt_frame ( ast_aes_encrypt_key ecx,
struct ast_iax2_full_hdr fh,
unsigned char *  poo,
int *  datalen 
) [static]

Definition at line 6410 of file chan_iax2.c.

References ast_alloca, 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().

06411 {
06412    int padding;
06413    unsigned char *workspace;
06414    workspace = ast_alloca(*datalen + 32);
06415    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06416       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06417       if (iaxdebug)
06418          ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06419       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06420       padding = 16 + (padding & 0xf);
06421       memcpy(workspace, poo, padding);
06422       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06423       workspace[15] &= 0xf0;
06424       workspace[15] |= (padding & 0xf);
06425       if (iaxdebug)
06426          ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, (unsigned)workspace[15]);
06427       *datalen += padding;
06428       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06429       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06430          memcpy(poo, workspace + *datalen - 32, 32);
06431    } else {
06432       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06433       if (iaxdebug)
06434          ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06435       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06436       padding = 16 + (padding & 0xf);
06437       memcpy(workspace, poo, padding);
06438       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06439       workspace[15] &= 0xf0;
06440       workspace[15] |= (padding & 0x0f);
06441       *datalen += padding;
06442       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06443       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06444          memcpy(poo, workspace + *datalen - 32, 32);
06445    }
06446    return 0;
06447 }

static int expire_registry ( const void *  data  )  [static]

Definition at line 8773 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().

08774 {
08775 #ifdef SCHED_MULTITHREADED
08776    if (schedule_action(__expire_registry, data))
08777 #endif      
08778       __expire_registry(data);
08779    return 0;
08780 }

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 13887 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_remaining_ms(), ast_test_flag, ast_tvcmp(), ast_tvnow(), ast_waitfor_nandfds(), CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, cache_get_callno_locked(), iax2_dpcache::callno, errno, iax2_dpcache::expiry, iax2_dpcache::exten, f, iax2_dpcache::flags, iax2_dprequest(), IAX_STATE_STARTED, iaxs, iaxsl, LOG_WARNING, iax2_dpcache::orig, iax2_dpcache::peercontext, and iax2_dpcache::waiters.

Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore().

13888 {
13889    struct iax2_dpcache *dp = NULL;
13890    struct timeval now = ast_tvnow();
13891    int x, com[2], timeout, old = 0, outfd, doabort, callno;
13892    struct ast_channel *c = NULL;
13893    struct ast_frame *f = NULL;
13894 
13895    AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13896       if (ast_tvcmp(now, dp->expiry) > 0) {
13897          AST_LIST_REMOVE_CURRENT(cache_list);
13898          if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13899             ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13900          else
13901             ast_free(dp);
13902          continue;
13903       }
13904       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13905          break;
13906    }
13907    AST_LIST_TRAVERSE_SAFE_END;
13908 
13909    if (!dp) {
13910       /* No matching entry.  Create a new one. */
13911       /* First, can we make a callno? */
13912       if ((callno = cache_get_callno_locked(data)) < 0) {
13913          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13914          return NULL;
13915       }
13916       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13917          ast_mutex_unlock(&iaxsl[callno]);
13918          return NULL;
13919       }
13920       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13921       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13922       dp->expiry = ast_tvnow();
13923       dp->orig = dp->expiry;
13924       /* Expires in 30 mins by default */
13925       dp->expiry.tv_sec += iaxdefaultdpcache;
13926       dp->flags = CACHE_FLAG_PENDING;
13927       for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13928          dp->waiters[x] = -1;
13929       /* Insert into the lists */
13930       AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13931       AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13932       /* Send the request if we're already up */
13933       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13934          iax2_dprequest(dp, callno);
13935       ast_mutex_unlock(&iaxsl[callno]);
13936    }
13937 
13938    /* By here we must have a dp */
13939    if (dp->flags & CACHE_FLAG_PENDING) {
13940       struct timeval start;
13941       int ms;
13942       /* Okay, here it starts to get nasty.  We need a pipe now to wait
13943          for a reply to come back so long as it's pending */
13944       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13945          /* Find an empty slot */
13946          if (dp->waiters[x] < 0)
13947             break;
13948       }
13949       if (x >= ARRAY_LEN(dp->waiters)) {
13950          ast_log(LOG_WARNING, "No more waiter positions available\n");
13951          return NULL;
13952       }
13953       if (pipe(com)) {
13954          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13955          return NULL;
13956       }
13957       dp->waiters[x] = com[1];
13958       /* Okay, now we wait */
13959       timeout = iaxdefaulttimeout * 1000;
13960       /* Temporarily unlock */
13961       AST_LIST_UNLOCK(&dpcache);
13962       /* Defer any dtmf */
13963       if (chan)
13964          old = ast_channel_defer_dtmf(chan);
13965       doabort = 0;
13966       start = ast_tvnow();
13967       while ((ms = ast_remaining_ms(start, timeout))) {
13968          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &ms);
13969          if (outfd > -1)
13970             break;
13971          if (!c)
13972             continue;
13973          if (!(f = ast_read(c))) {
13974             doabort = 1;
13975             break;
13976          }
13977          ast_frfree(f);
13978       }
13979       if (!ms) {
13980          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13981       }
13982       AST_LIST_LOCK(&dpcache);
13983       dp->waiters[x] = -1;
13984       close(com[1]);
13985       close(com[0]);
13986       if (doabort) {
13987          /* Don't interpret anything, just abort.  Not sure what th epoint
13988            of undeferring dtmf on a hung up channel is but hey whatever */
13989          if (!old && chan)
13990             ast_channel_undefer_dtmf(chan);
13991          return NULL;
13992       }
13993       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13994          /* Now to do non-independent analysis the results of our wait */
13995          if (dp->flags & CACHE_FLAG_PENDING) {
13996             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
13997                pending.  Don't let it take as long to timeout. */
13998             dp->flags &= ~CACHE_FLAG_PENDING;
13999             dp->flags |= CACHE_FLAG_TIMEOUT;
14000             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
14001                systems without leaving it unavailable once the server comes back online */
14002             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
14003             for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
14004                if (dp->waiters[x] > -1) {
14005                   if (write(dp->waiters[x], "asdf", 4) < 0) {
14006                      ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
14007                   }
14008                }
14009             }
14010          }
14011       }
14012       /* Our caller will obtain the rest */
14013       if (!old && chan)
14014          ast_channel_undefer_dtmf(chan);
14015    }
14016    return dp;  
14017 }

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 3025 of file chan_iax2.c.

References __find_callno().

Referenced by iax2_poke_peer(), and socket_process().

03025                                                                                                                                     { 
03026    return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
03027 }

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 3029 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().

03029                                                                                                                                            {
03030 
03031    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
03032 }

static struct iax2_thread* find_idle_thread ( void   )  [static, read]

Definition at line 1477 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::ffinfo, iax2_process_thread(), IAX_THREAD_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxdynamicthreadnum, iaxmaxthreadcount, and thread.

Referenced by __schedule_action(), and socket_read().

01478 {
01479    struct iax2_thread *thread = NULL;
01480 
01481    /* Pop the head of the idle list off */
01482    AST_LIST_LOCK(&idle_list);
01483    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01484    AST_LIST_UNLOCK(&idle_list);
01485 
01486    /* If we popped a thread off the idle list, just return it */
01487    if (thread) {
01488       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01489       return thread;
01490    }
01491 
01492    /* Pop the head of the dynamic list off */
01493    AST_LIST_LOCK(&dynamic_list);
01494    thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01495    AST_LIST_UNLOCK(&dynamic_list);
01496 
01497    /* If we popped a thread off the dynamic list, just return it */
01498    if (thread) {
01499       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01500       return thread;
01501    }
01502 
01503    /* If we can't create a new dynamic thread for any reason, return no thread at all */
01504    if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01505       return NULL;
01506 
01507    /* Set default values */
01508    ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01509    thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01510    thread->type = IAX_THREAD_TYPE_DYNAMIC;
01511 
01512    /* Initialize lock and condition */
01513    ast_mutex_init(&thread->lock);
01514    ast_cond_init(&thread->cond, NULL);
01515    ast_mutex_init(&thread->init_lock);
01516    ast_cond_init(&thread->init_cond, NULL);
01517    ast_mutex_lock(&thread->init_lock);
01518 
01519    /* Create thread and send it on it's way */
01520    if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01521       ast_cond_destroy(&thread->cond);
01522       ast_mutex_destroy(&thread->lock);
01523       ast_mutex_unlock(&thread->init_lock);
01524       ast_cond_destroy(&thread->init_cond);
01525       ast_mutex_destroy(&thread->init_lock);
01526       ast_free(thread);
01527       return NULL;
01528    }
01529 
01530    /* this thread is not processing a full frame (since it is idle),
01531       so ensure that the field for the full frame call number is empty */
01532    memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01533 
01534    /* Wait for the thread to be ready before returning it to the caller */
01535    ast_cond_wait(&thread->init_cond, &thread->init_lock);
01536 
01537    /* Done with init_lock */
01538    ast_mutex_unlock(&thread->init_lock);
01539 
01540    return thread;
01541 }

static struct iax2_peer* find_peer ( const char *  name,
int  realtime 
) [static, read]
Note:
This funtion calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno, so do not call it with a pvt lock held.

Definition at line 1769 of file chan_iax2.c.

References ao2_find, OBJ_POINTER, and realtime_peer().

Referenced by calltoken_required(), create_addr(), function_iaxpeer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), handle_cli_iax2_show_peer(), handle_cli_iax2_unregister(), iax2_devicestate(), register_verify(), registry_authrequest(), requirecalltoken_mark_auto(), and update_registry().

01770 {
01771    struct iax2_peer *peer = NULL;
01772    struct iax2_peer tmp_peer = {
01773       .name = name,
01774    };
01775 
01776    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01777 
01778    /* Now go for realtime if applicable */
01779    if(!peer && realtime)
01780       peer = realtime_peer(name, NULL);
01781 
01782    return peer;
01783 }

static struct iax2_trunk_peer* find_tpeer ( struct sockaddr_in *  sin,
int  fd 
) [static, read]

Definition at line 6182 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().

06183 {
06184    struct iax2_trunk_peer *tpeer = NULL;
06185    
06186    /* Finds and locks trunk peer */
06187    AST_LIST_LOCK(&tpeers);
06188 
06189    AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
06190       if (!inaddrcmp(&tpeer->addr, sin)) {
06191          ast_mutex_lock(&tpeer->lock);
06192          break;
06193       }
06194    }
06195 
06196    if (!tpeer) {
06197       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
06198          ast_mutex_init(&tpeer->lock);
06199          tpeer->lastsent = 9999;
06200          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
06201          tpeer->trunkact = ast_tvnow();
06202          ast_mutex_lock(&tpeer->lock);
06203          tpeer->sockfd = fd;
06204 #ifdef SO_NO_CHECK
06205          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
06206 #endif
06207          ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
06208          AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
06209       }
06210    }
06211 
06212    AST_LIST_UNLOCK(&tpeers);
06213 
06214    return tpeer;
06215 }

static struct iax2_user* find_user ( const char *  name  )  [static, read]

Definition at line 1797 of file chan_iax2.c.

References ao2_find, and OBJ_POINTER.

Referenced by calltoken_required(), handle_cli_iax2_prune_realtime(), and requirecalltoken_mark_auto().

01798 {
01799    struct iax2_user tmp_user = {
01800       .name = name,
01801    };
01802 
01803    return ao2_find(users, &tmp_user, OBJ_POINTER);
01804 }

static unsigned int fix_peerts ( struct timeval *  rxtrunktime,
int  callno,
unsigned int  ts 
) [static]

Definition at line 5995 of file chan_iax2.c.

References ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), iaxs, and chan_iax2_pvt::rxcore.

Referenced by socket_process_meta().

05996 {
05997    long ms; /* NOT unsigned */
05998    if (ast_tvzero(iaxs[callno]->rxcore)) {
05999       /* Initialize rxcore time if appropriate */
06000       iaxs[callno]->rxcore = ast_tvnow();
06001       /* Round to nearest 20ms so traces look pretty */
06002       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
06003    }
06004    /* Calculate difference between trunk and channel */
06005    ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
06006    /* Return as the sum of trunk time and the difference between trunk and real time */
06007    return ms + ts;
06008 }

static void free_context ( struct iax2_context con  )  [static]

Definition at line 12319 of file chan_iax2.c.

References ast_free, and iax2_context::next.

Referenced by build_user(), and user_destructor().

12320 {
12321    struct iax2_context *conl;
12322    while(con) {
12323       conl = con;
12324       con = con->next;
12325       ast_free(conl);
12326    }
12327 }

static void free_signaling_queue_entry ( struct signaling_queue_entry s  )  [static]

Definition at line 1903 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().

01904 {
01905    if (s->f.datalen) {
01906       ast_free(s->f.data.ptr);
01907    }
01908    ast_free(s);
01909 }

static int function_iaxpeer ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

Definition at line 14140 of file chan_iax2.c.

References iax2_peer::addr, iax2_trunk_peer::addr, ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_test_flag64, iax2_peer::callno, iax2_peer::capability, iax2_peer::expire, find_peer(), iax2_tech, IAX_DYNAMIC, iaxs, peer_status(), peer_unref(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.

14141 {
14142    struct iax2_peer *peer;
14143    char *peername, *colname;
14144 
14145    peername = ast_strdupa(data);
14146 
14147    /* if our channel, return the IP address of the endpoint of current channel */
14148    if (!strcmp(peername,"CURRENTCHANNEL")) {
14149            unsigned short callno;
14150       if (!chan || chan->tech != &iax2_tech) {
14151          return -1;
14152       }
14153       callno = PTR_TO_CALLNO(chan->tech_pvt);   
14154       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
14155       return 0;
14156    }
14157 
14158    if ((colname = strchr(peername, ',')))
14159       *colname++ = '\0';
14160    else
14161       colname = "ip";
14162 
14163    if (!(peer = find_peer(peername, 1)))
14164       return -1;
14165 
14166    if (!strcasecmp(colname, "ip")) {
14167       ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
14168    } else  if (!strcasecmp(colname, "status")) {
14169       peer_status(peer, buf, len); 
14170    } else  if (!strcasecmp(colname, "mailbox")) {
14171       ast_copy_string(buf, peer->mailbox, len);
14172    } else  if (!strcasecmp(colname, "context")) {
14173       ast_copy_string(buf, peer->context, len);
14174    } else  if (!strcasecmp(colname, "expire")) {
14175       snprintf(buf, len, "%d", peer->expire);
14176    } else  if (!strcasecmp(colname, "dynamic")) {
14177       ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
14178    } else  if (!strcasecmp(colname, "callerid_name")) {
14179       ast_copy_string(buf, peer->cid_name, len);
14180    } else  if (!strcasecmp(colname, "callerid_num")) {
14181       ast_copy_string(buf, peer->cid_num, len);
14182    } else  if (!strcasecmp(colname, "codecs")) {
14183       ast_getformatname_multiple(buf, len -1, peer->capability);
14184    } else  if (!strncasecmp(colname, "codec[", 6)) {
14185       char *codecnum, *ptr;
14186       int codec = 0;
14187 
14188       /* skip over "codec" to the '[' */
14189       codecnum = colname + 5;
14190       *codecnum = '\0';
14191       codecnum++;
14192       if ((ptr = strchr(codecnum, ']'))) {
14193          *ptr = '\0';
14194       }
14195       if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
14196          ast_copy_string(buf, ast_getformatname(codec), len);
14197       } else {
14198          buf[0] = '\0';
14199       }
14200    } else {
14201       buf[0] = '\0';
14202    }
14203 
14204    peer_unref(peer);
14205 
14206    return 0;
14207 }

static int get_auth_methods ( const char *  value  )  [static]

Definition at line 12484 of file chan_iax2.c.

References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.

Referenced by build_peer(), and build_user().

12485 {
12486    int methods = 0;
12487    if (strstr(value, "rsa"))
12488       methods |= IAX_AUTH_RSA;
12489    if (strstr(value, "md5"))
12490       methods |= IAX_AUTH_MD5;
12491    if (strstr(value, "plaintext"))
12492       methods |= IAX_AUTH_PLAINTEXT;
12493    return methods;
12494 }

static int get_encrypt_methods ( const char *  s  )  [static]

Definition at line 1641 of file chan_iax2.c.

References ast_true(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.

Referenced by build_peer(), build_user(), and set_config().

01642 {
01643    int e;
01644    if (!strcasecmp(s, "aes128"))
01645       e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01646    else if (ast_true(s))
01647       e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01648    else
01649       e = 0;
01650    return e;
01651 }

static int get_from_jb ( const void *  p  )  [static]

Definition at line 4228 of file chan_iax2.c.

References __get_from_jb(), and schedule_action.

Referenced by update_jbsched().

04229 {
04230 #ifdef SCHED_MULTITHREADED
04231    if (schedule_action(__get_from_jb, data))
04232 #endif      
04233       __get_from_jb(data);
04234    return 0;
04235 }

static struct callno_entry * get_unused_callno ( int  trunk,
int  validated 
) [static, read]

Definition at line 2703 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().

02704 {
02705    struct callno_entry *callno_entry = NULL;
02706    if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02707       ast_log(LOG_WARNING, "Out of CallNumbers\n");
02708       /* Minor optimization for the extreme case. */
02709       return NULL;
02710    }
02711 
02712    /* the callno_pool container is locked here primarily to ensure thread
02713     * safety of the total_nonval_callno_used check and increment */
02714    ao2_lock(callno_pool);
02715 
02716    /* only a certain number of nonvalidated call numbers should be allocated.
02717     * If there ever is an attack, this separates the calltoken validating
02718     * users from the non calltoken validating users. */
02719    if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02720       ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02721       ao2_unlock(callno_pool);
02722       return NULL;
02723    }
02724 
02725    /* unlink the object from the container, taking over ownership
02726     * of the reference the container had to the object */
02727    callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02728 
02729    if (callno_entry) {
02730       callno_entry->validated = validated;
02731       if (!validated) {
02732          total_nonval_callno_used++;
02733       }
02734    }
02735 
02736    ao2_unlock(callno_pool);
02737    return callno_entry;
02738 }

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 4966 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().

04968 {
04969 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"  /* address + port + ts + randomcalldata */
04970 #define CALLTOKEN_IE_FORMAT   "%u?%s"     /* time + ? + (40 char hash) */
04971    struct ast_str *buf = ast_str_alloca(256);
04972    time_t t = time(NULL);
04973    char hash[41]; /* 40 char sha1 hash */
04974    int subclass = uncompress_subclass(fh->csub);
04975 
04976    /* ----- Case 1 ----- */
04977    if (ies->calltoken && !ies->calltokendata) {  /* empty calltoken is provided, client supports calltokens */
04978       struct iax_ie_data ied = {
04979          .buf = { 0 },
04980          .pos = 0,
04981       };
04982 
04983       /* create the hash with their address data and our timestamp */
04984       ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04985       ast_sha1_hash(hash, ast_str_buffer(buf));
04986 
04987       ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04988       iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04989       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04990 
04991       return 1;
04992 
04993    /* ----- Case 2 ----- */
04994    } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */
04995       char *rec_hash = NULL;    /* the received hash, make sure it matches with ours. */
04996       char *rec_ts = NULL;      /* received timestamp */
04997       unsigned int rec_time;  /* received time_t */
04998 
04999       /* split the timestamp from the hash data */
05000       rec_hash = strchr((char *) ies->calltokendata, '?');
05001       if (rec_hash) {
05002          *rec_hash++ = '\0';
05003          rec_ts = (char *) ies->calltokendata;
05004       }
05005 
05006       /* check that we have valid data before we do any comparisons */
05007       if (!rec_hash || !rec_ts) {
05008          goto reject;
05009       } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
05010          goto reject;
05011       }
05012 
05013       /* create a hash with their address and the _TOKEN'S_ timestamp */
05014       ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
05015       ast_sha1_hash(hash, ast_str_buffer(buf));
05016 
05017       /* compare hashes and then check timestamp delay */
05018       if (strcmp(hash, rec_hash)) {
05019          ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
05020          goto reject; /* received hash does not match ours, reject */
05021       } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
05022          ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
05023          goto reject; /* too much delay, reject */
05024       }
05025 
05026       /* at this point the call token is valid, returning 0 
05027        * will allow socket_process to continue as usual */
05028       requirecalltoken_mark_auto(ies->username, subclass);
05029       return 0;
05030 
05031    /* ----- Case 3 ----- */
05032    } else { /* calltokens are not supported for this client, how do we respond? */
05033       if (calltoken_required(sin, ies->username, subclass)) {
05034          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"));
05035          goto reject;
05036       }
05037       return 0; /* calltoken is not required for this addr, so permit it. */
05038    }
05039 
05040 reject:
05041    /* received frame has failed calltoken inspection, send apathetic reject messages */
05042    if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
05043       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
05044    } else {
05045       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
05046    }
05047 
05048    return 1;
05049 }

static char* handle_cli_iax2_provision ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 12166 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.

12167 {
12168    int force = 0;
12169    int res;
12170 
12171    switch (cmd) {
12172    case CLI_INIT:
12173       e->command = "iax2 provision";
12174       e->usage = 
12175          "Usage: iax2 provision <host> <template> [forced]\n"
12176          "       Provisions the given peer or IP address using a template\n"
12177          "       matching either 'template' or '*' if the template is not\n"
12178          "       found.  If 'forced' is specified, even empty provisioning\n"
12179          "       fields will be provisioned as empty fields.\n";
12180       return NULL;
12181    case CLI_GENERATE:
12182       if (a->pos == 3)
12183          return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
12184       return NULL;
12185    }
12186 
12187    if (a->argc < 4)
12188       return CLI_SHOWUSAGE;
12189    if (a->argc > 4) {
12190       if (!strcasecmp(a->argv[4], "forced"))
12191          force = 1;
12192       else
12193          return CLI_SHOWUSAGE;
12194    }
12195    res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
12196    if (res < 0)
12197       ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
12198    else if (res < 1)
12199       ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
12200    else
12201       ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
12202    return CLI_SUCCESS;
12203 }

static char* handle_cli_iax2_prune_realtime ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3660 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.

03661 {
03662    struct iax2_peer *peer = NULL;
03663    struct iax2_user *user = NULL;
03664    static const char * const choices[] = { "all", NULL };
03665    char *cmplt;
03666 
03667    switch (cmd) {
03668    case CLI_INIT:
03669       e->command = "iax2 prune realtime";
03670       e->usage =
03671          "Usage: iax2 prune realtime [<peername>|all]\n"
03672          "       Prunes object(s) from the cache\n";
03673       return NULL;
03674    case CLI_GENERATE:
03675       if (a->pos == 3) {
03676          cmplt = ast_cli_complete(a->word, choices, a->n);
03677          if (!cmplt)
03678             cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
03679          return cmplt;
03680       }
03681       return NULL;
03682    }
03683    if (a->argc != 4)
03684       return CLI_SHOWUSAGE;
03685    if (!strcmp(a->argv[3], "all")) {
03686       prune_users();
03687       prune_peers();
03688       ast_cli(a->fd, "Cache flushed successfully.\n");
03689       return CLI_SUCCESS;
03690    }
03691    peer = find_peer(a->argv[3], 0);
03692    user = find_user(a->argv[3]);
03693    if (peer || user) {
03694       if (peer) {
03695          if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
03696             ast_set_flag64(peer, IAX_RTAUTOCLEAR);
03697             expire_registry(peer_ref(peer));
03698             ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03699          } else {
03700             ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03701          }
03702          peer_unref(peer);
03703       }
03704       if (user) {
03705          if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
03706             ast_set_flag64(user, IAX_RTAUTOCLEAR);
03707             ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03708          } else {
03709             ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03710          }
03711          ao2_unlink(users,user);
03712          user_unref(user);
03713       }
03714    } else {
03715       ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03716    }
03717 
03718    return CLI_SUCCESS;
03719 }

static char* handle_cli_iax2_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 13791 of file chan_iax2.c.

References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, reload_config(), and ast_cli_entry::usage.

13792 {
13793    switch (cmd) {
13794    case CLI_INIT:
13795       e->command = "iax2 reload";
13796       e->usage =
13797          "Usage: iax2 reload\n"
13798          "       Reloads IAX configuration from iax.conf\n";
13799       return NULL;
13800    case CLI_GENERATE:
13801       return NULL;
13802    }
13803 
13804    reload_config();
13805 
13806    return CLI_SUCCESS;
13807 }

static char* handle_cli_iax2_set_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 7459 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.

07460 {
07461    switch (cmd) {
07462    case CLI_INIT:
07463       e->command = "iax2 set debug {on|off|peer}";
07464       e->usage =
07465          "Usage: iax2 set debug {on|off|peer peername}\n"
07466          "       Enables/Disables dumping of IAX packets for debugging purposes.\n";
07467       return NULL;
07468    case CLI_GENERATE:
07469       if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07470          return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07471       return NULL;
07472    }
07473 
07474    if (a->argc < e->args  || a->argc > e->args + 1)
07475       return CLI_SHOWUSAGE;
07476 
07477    if (!strcasecmp(a->argv[3], "peer")) {
07478       struct iax2_peer *peer;
07479       struct sockaddr_in peer_addr;
07480 
07481 
07482       if (a->argc != e->args + 1)
07483          return CLI_SHOWUSAGE;
07484 
07485       peer = find_peer(a->argv[4], 1);
07486 
07487       if (!peer) {
07488          ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07489          return CLI_FAILURE;
07490       }
07491 
07492       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
07493 
07494       debugaddr.sin_addr = peer_addr.sin_addr;
07495       debugaddr.sin_port = peer_addr.sin_port;
07496 
07497       ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07498          ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07499 
07500       ao2_ref(peer, -1);
07501    } else if (!strncasecmp(a->argv[3], "on", 2)) {
07502       iaxdebug = 1;
07503       ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07504    } else {
07505       iaxdebug = 0;
07506       memset(&debugaddr, 0, sizeof(debugaddr));
07507       ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07508    }
07509    return CLI_SUCCESS;
07510 }

static char* handle_cli_iax2_set_debug_jb ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 7538 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.

07539 {
07540    switch (cmd) {
07541    case CLI_INIT:
07542       e->command = "iax2 set debug jb {on|off}";
07543       e->usage =
07544          "Usage: iax2 set debug jb {on|off}\n"
07545          "       Enables/Disables jitterbuffer debugging information\n";
07546       return NULL;
07547    case CLI_GENERATE:
07548       return NULL;
07549    }
07550 
07551    if (a->argc != e->args)
07552       return CLI_SHOWUSAGE;
07553    
07554    if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07555       jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07556       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07557    } else {
07558       jb_setoutput(jb_error_output, jb_warning_output, NULL);
07559       ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07560    }
07561    return CLI_SUCCESS;
07562 }

static char* handle_cli_iax2_set_debug_trunk ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 7512 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.

07513 {
07514    switch (cmd) {
07515    case CLI_INIT:
07516       e->command = "iax2 set debug trunk {on|off}";
07517       e->usage =
07518          "Usage: iax2 set debug trunk {on|off}\n"
07519          "       Enables/Disables debugging of IAX trunking\n";
07520       return NULL;
07521    case CLI_GENERATE:
07522       return NULL;
07523    }
07524 
07525    if (a->argc != e->args)
07526       return CLI_SHOWUSAGE;
07527 
07528    if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07529       iaxtrunkdebug = 1;
07530       ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07531    } else {
07532       iaxtrunkdebug = 0;
07533       ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07534    }
07535    return CLI_SUCCESS;
07536 }

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 3987 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.

03988 {
03989    int mtuv;
03990 
03991    switch (cmd) {
03992    case CLI_INIT:
03993       e->command = "iax2 set mtu";
03994       e->usage =
03995          "Usage: iax2 set mtu <value>\n"
03996          "       Set the system-wide IAX IP mtu to <value> bytes net or\n"
03997          "       zero to disable. Disabling means that the operating system\n"
03998          "       must handle fragmentation of UDP packets when the IAX2 trunk\n"
03999          "       packet exceeds the UDP payload size. This is substantially\n"
04000          "       below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
04001          "       greater for G.711 samples.\n";
04002       return NULL;
04003    case CLI_GENERATE:
04004       return NULL;
04005    }
04006 
04007    if (a->argc != 4)
04008       return CLI_SHOWUSAGE; 
04009    if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
04010       mtuv = MAX_TRUNK_MTU;
04011    else
04012       mtuv = atoi(a->argv[3]);
04013 
04014    if (mtuv == 0) {
04015       ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 
04016       global_max_trunk_mtu = 0; 
04017       return CLI_SUCCESS; 
04018    }
04019    if (mtuv < 172 || mtuv > 4000) {
04020       ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 
04021       return CLI_SHOWUSAGE; 
04022    }
04023    ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 
04024    global_max_trunk_mtu = mtuv; 
04025    return CLI_SUCCESS;
04026 }

static char* handle_cli_iax2_show_cache ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 4028 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.

04029 {
04030    struct iax2_dpcache *dp = NULL;
04031    char tmp[1024], *pc = NULL;
04032    int s, x, y;
04033    struct timeval now = ast_tvnow();
04034 
04035    switch (cmd) {
04036    case CLI_INIT:
04037       e->command = "iax2 show cache";
04038       e->usage =
04039          "Usage: iax2 show cache\n"
04040          "       Display currently cached IAX Dialplan results.\n";
04041       return NULL;
04042    case CLI_GENERATE:
04043       return NULL;
04044    }
04045 
04046    AST_LIST_LOCK(&dpcache);
04047 
04048    ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
04049 
04050    AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
04051       s = dp->expiry.tv_sec - now.tv_sec;
04052       tmp[0] = '\0';
04053       if (dp->flags & CACHE_FLAG_EXISTS)
04054          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
04055       if (dp->flags & CACHE_FLAG_NONEXISTENT)
04056          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
04057       if (dp->flags & CACHE_FLAG_CANEXIST)
04058          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
04059       if (dp->flags & CACHE_FLAG_PENDING)
04060          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
04061       if (dp->flags & CACHE_FLAG_TIMEOUT)
04062          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
04063       if (dp->flags & CACHE_FLAG_TRANSMITTED)
04064          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
04065       if (dp->flags & CACHE_FLAG_MATCHMORE)
04066          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
04067       if (dp->flags & CACHE_FLAG_UNKNOWN)
04068          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
04069       /* Trim trailing pipe */
04070       if (!ast_strlen_zero(tmp)) {
04071          tmp[strlen(tmp) - 1] = '\0';
04072       } else {
04073          ast_copy_string(tmp, "(none)", sizeof(tmp));
04074       }
04075       y = 0;
04076       pc = strchr(dp->peercontext, '@');
04077       if (!pc) {
04078          pc = dp->peercontext;
04079       } else {
04080          pc++;
04081       }
04082       for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
04083          if (dp->waiters[x] > -1)
04084             y++;
04085       }
04086       if (s > 0) {
04087          ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
04088       } else {
04089          ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
04090       }
04091    }
04092 
04093    AST_LIST_UNLOCK(&dpcache);
04094 
04095    return CLI_SUCCESS;
04096 }

static char* handle_cli_iax2_show_callno_limits ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 2638 of file chan_iax2.c.

References 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, ast_cli_args::fd, and ast_cli_entry::usage.

02639 {
02640    struct ao2_iterator i;
02641    struct peercnt *peercnt;
02642    struct sockaddr_in sin;
02643    int found = 0;
02644 
02645    switch (cmd) {
02646    case CLI_INIT:
02647       e->command = "iax2 show callnumber usage";
02648       e->usage =
02649          "Usage: iax2 show callnumber usage [IP address]\n"
02650          "       Shows current IP addresses which are consuming iax2 call numbers\n";
02651       return NULL;
02652    case CLI_GENERATE:
02653       return NULL;
02654    case CLI_HANDLER:
02655       if (a->argc < 4 || a->argc > 5)
02656          return CLI_SHOWUSAGE;
02657 
02658       if (a->argc == 4) {
02659          ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02660       }
02661 
02662       i = ao2_iterator_init(peercnts, 0);
02663       while ((peercnt = ao2_iterator_next(&i))) {
02664          sin.sin_addr.s_addr = peercnt->addr;
02665          if (a->argc == 5) {
02666             if (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr))) {
02667                ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02668                ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02669                ao2_ref(peercnt, -1);
02670                found = 1;
02671                break;
02672             }
02673          } else {
02674             ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02675          }
02676          ao2_ref(peercnt, -1);
02677       }
02678       ao2_iterator_destroy(&i);
02679 
02680       if (a->argc == 4) {
02681          ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n"
02682                           "Non-CallToken Validated Callno Used:   %d\n",
02683             global_maxcallno_nonval,
02684             total_nonval_callno_used);
02685 
02686          ast_cli(a->fd,   "Total Available Callno:                %d\n"
02687                           "Regular Callno Available:              %d\n"
02688                           "Trunk Callno Available:                %d\n",
02689             ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk),
02690             ao2_container_count(callno_pool),
02691             ao2_container_count(callno_pool_trunk));
02692       } else if (a->argc == 5 && !found) {
02693          ast_cli(a->fd, "No call number table entries for %s found\n", a->argv[4] );
02694       }
02695 
02696 
02697       return CLI_SUCCESS;
02698    default:
02699       return NULL;
02700    }
02701 }

static char* handle_cli_iax2_show_channels ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 7280 of file chan_iax2.c.

References iax2_trunk_peer::addr, ast_cli_args::argc, ARRAY_LEN, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, iax2_registry::callno, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, jb_info::current, ast_cli_args::fd, FORMAT, FORMAT2, iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, MARK_IAX_SUBCLASS_TX, jb_info::min, chan_iax2_pvt::owner, S_OR, and ast_cli_entry::usage.

07281 {
07282 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s  %s  %9s\n"
07283 #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"
07284 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
07285    int x;
07286    int numchans = 0;
07287    int usedchans = 0;
07288    char first_message[10] = { 0, };
07289    char last_message[10] = { 0, };
07290 
07291    switch (cmd) {
07292    case CLI_INIT:
07293       e->command = "iax2 show channels";
07294       e->usage =
07295          "Usage: iax2 show channels\n"
07296          "       Lists all currently active IAX channels.\n";
07297       return NULL;
07298    case CLI_GENERATE:
07299       return NULL;
07300    }
07301 
07302    if (a->argc != 3)
07303       return CLI_SHOWUSAGE;
07304    ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
07305    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07306       ast_mutex_lock(&iaxsl[x]);
07307       if (iaxs[x]) {
07308          int lag, jitter, localdelay;
07309          jb_info jbinfo;
07310          if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07311             jb_getinfo(iaxs[x]->jb, &jbinfo);
07312             jitter = jbinfo.jitter;
07313             localdelay = jbinfo.current - jbinfo.min;
07314          } else {
07315             jitter = -1;
07316             localdelay = 0;
07317          }
07318 
07319          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07320          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07321          lag = iaxs[x]->remote_rr.delay;
07322          ast_cli(a->fd, FORMAT,
07323             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07324             ast_inet_ntoa(iaxs[x]->addr.sin_addr),
07325             S_OR(iaxs[x]->username, "(None)"),
07326             iaxs[x]->callno, iaxs[x]->peercallno,
07327             iaxs[x]->oseqno, iaxs[x]->iseqno,
07328             lag,
07329             jitter,
07330             localdelay,
07331             ast_getformatname(iaxs[x]->voiceformat),
07332             (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07333             first_message,
07334             (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07335             last_message);
07336          numchans++;
07337          if (iaxs[x]->owner) { /* Count IAX dialog owned by a real channel */
07338             usedchans++;
07339          }  
07340       }
07341       ast_mutex_unlock(&iaxsl[x]);
07342    }
07343    ast_cli(a->fd, "%d active IAX dialog%s\n", numchans, (numchans != 1) ? "s" : "");
07344    ast_cli(a->fd, "%d used IAX channel%s\n", usedchans, (usedchans != 1) ? "s" : "");
07345 
07346    return CLI_SUCCESS;
07347 #undef FORMAT
07348 #undef FORMAT2
07349 #undef FORMATB
07350 }

static char* handle_cli_iax2_show_firmware ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 7066 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_cli_args::fd, and ast_cli_entry::usage.

07067 {
07068    struct iax_firmware *cur = NULL;
07069 
07070    switch (cmd) {
07071    case CLI_INIT:
07072       e->command = "iax2 show firmware";
07073       e->usage =
07074          "Usage: iax2 show firmware\n"
07075          "       Lists all known IAX firmware images.\n";
07076       return NULL;
07077    case CLI_GENERATE:
07078       return NULL;
07079    }
07080 
07081    if (a->argc != 3 && a->argc != 4)
07082       return CLI_SHOWUSAGE;
07083 
07084    ast_cli(a->fd, "%-15.15s  %-15.15s %-15.15s\n", "Device", "Version", "Size");
07085    AST_LIST_LOCK(&firmwares);
07086    AST_LIST_TRAVERSE(&firmwares, cur, list) {
07087       if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname)))  {
07088          ast_cli(a->fd, "%-15.15s  %-15d %-15d\n", cur->fwh->devname, 
07089             ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
07090       }
07091    }
07092    AST_LIST_UNLOCK(&firmwares);
07093 
07094    return CLI_SUCCESS;
07095 }

static char* handle_cli_iax2_show_netstats ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 7436 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.

07437 {
07438    int numchans = 0;
07439 
07440    switch (cmd) {
07441    case CLI_INIT:
07442       e->command = "iax2 show netstats";
07443       e->usage =
07444          "Usage: iax2 show netstats\n"
07445          "       Lists network status for all currently active IAX channels.\n";
07446       return NULL;
07447    case CLI_GENERATE:
07448       return NULL;
07449    }
07450    if (a->argc != 3)
07451       return CLI_SHOWUSAGE;
07452    ast_cli(a->fd, "                           -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
07453    ast_cli(a->fd, "Channel               RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts FirstMsg    LastMsg\n");
07454    numchans = ast_cli_netstats(NULL, a->fd, 1);
07455    ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07456    return CLI_SUCCESS;
07457 }

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 3835 of file chan_iax2.c.

References iax2_peer::addr, ast_cli_args::argc, ast_cli_args::argv, ast_callerid_merge(), ast_cli(), ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_sockaddr_to_sin, ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag64, CALLTOKEN_AUTO, iax2_peer::calltoken_required, CALLTOKEN_YES, iax2_peer::capability, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), iax2_peer::defaddr, iax2_peer::encmethods, encmethods_to_str(), iax2_peer::expire, ast_cli_args::fd, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_TRUNK, ast_cli_args::line, iax2_peer::maxcallno, ast_cli_args::n, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, ast_cli_args::pos, iax2_peer::prefs, iax2_peer::smoothing, status, ast_cli_entry::usage, and ast_cli_args::word.

03836 {
03837    char status[30];
03838    char cbuf[256];
03839    struct iax2_peer *peer;
03840    char codec_buf[512];
03841    struct ast_str *encmethods = ast_str_alloca(256);
03842    int x = 0, codec = 0, load_realtime = 0;
03843 
03844    switch (cmd) {
03845    case CLI_INIT:
03846       e->command = "iax2 show peer";
03847       e->usage =
03848          "Usage: iax2 show peer <name>\n"
03849          "       Display details on specific IAX peer\n";
03850       return NULL;
03851    case CLI_GENERATE:
03852       if (a->pos == 3)
03853          return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
03854       return NULL;
03855    }
03856 
03857    if (a->argc < 4)
03858       return CLI_SHOWUSAGE;
03859 
03860    load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03861 
03862    peer = find_peer(a->argv[3], load_realtime);
03863    if (peer) {
03864       struct sockaddr_in peer_addr;
03865 
03866       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
03867 
03868       encmethods_to_str(peer->encmethods, &encmethods);
03869       ast_cli(a->fd, "\n\n");
03870       ast_cli(a->fd, "  * Name       : %s\n", peer->name);
03871       ast_cli(a->fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03872       ast_cli(a->fd, "  Context      : %s\n", peer->context);
03873       ast_cli(a->fd, "  Parking lot  : %s\n", peer->parkinglot);
03874       ast_cli(a->fd, "  Mailbox      : %s\n", peer->mailbox);
03875       ast_cli(a->fd, "  Dynamic      : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
03876       ast_cli(a->fd, "  Callnum limit: %d\n", peer->maxcallno);
03877       ast_cli(a->fd, "  Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03878       ast_cli(a->fd, "  Trunk        : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
03879       ast_cli(a->fd, "  Encryption   : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
03880       ast_cli(a->fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03881       ast_cli(a->fd, "  Expire       : %d\n", peer->expire);
03882       ast_cli(a->fd, "  ACL          : %s\n", (peer->ha ? "Yes" : "No"));
03883       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));
03884       ast_cli(a->fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03885       ast_cli(a->fd, "  Username     : %s\n", peer->username);
03886       ast_cli(a->fd, "  Codecs       : ");
03887       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03888       ast_cli(a->fd, "%s\n", codec_buf);
03889 
03890       ast_cli(a->fd, "  Codec Order  : (");
03891       for(x = 0; x < 32 ; x++) {
03892          codec = ast_codec_pref_index(&peer->prefs,x);
03893          if(!codec)
03894             break;
03895          ast_cli(a->fd, "%s", ast_getformatname(codec));
03896          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03897             ast_cli(a->fd, "|");
03898       }
03899 
03900       if (!x)
03901          ast_cli(a->fd, "none");
03902       ast_cli(a->fd, ")\n");
03903 
03904       ast_cli(a->fd, "  Status       : ");
03905       peer_status(peer, status, sizeof(status));   
03906       ast_cli(a->fd, "%s\n",status);
03907       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");
03908       ast_cli(a->fd, "\n");
03909       peer_unref(peer);
03910    } else {
03911       ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03912       ast_cli(a->fd, "\n");
03913    }
03914 
03915    return CLI_SUCCESS;
03916 }

static char* handle_cli_iax2_show_peers ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 7034 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.

07035 {
07036    switch (cmd) {
07037    case CLI_INIT:
07038       e->command = "iax2 show peers";
07039       e->usage =
07040          "Usage: iax2 show peers [registered] [like <pattern>]\n"
07041          "       Lists all known IAX2 peers.\n"
07042          "       Optional 'registered' argument lists only peers with known addresses.\n"
07043          "       Optional regular expression pattern is used to filter the peer list.\n";
07044       return NULL;
07045    case CLI_GENERATE:
07046       return NULL;
07047    }
07048 
07049    switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
07050    case RESULT_SHOWUSAGE:
07051       return CLI_SHOWUSAGE;
07052    case RESULT_FAILURE:
07053       return CLI_FAILURE;
07054    default:
07055       return CLI_SUCCESS;
07056    }
07057 }

static char* handle_cli_iax2_show_registry ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 7189 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.

07190 {
07191 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
07192 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
07193    struct iax2_registry *reg = NULL;
07194    char host[80];
07195    char perceived[80];
07196    int counter = 0;
07197 
07198    switch (cmd) {
07199    case CLI_INIT:
07200       e->command = "iax2 show registry";
07201       e->usage =
07202          "Usage: iax2 show registry\n"
07203          "       Lists all registration requests and status.\n";
07204       return NULL;
07205    case CLI_GENERATE:
07206       return NULL;
07207    }
07208    if (a->argc != 3)
07209       return CLI_SHOWUSAGE;
07210    ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
07211    AST_LIST_LOCK(&registrations);
07212    AST_LIST_TRAVERSE(&registrations, reg, entry) {
07213       snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
07214       if (reg->us.sin_addr.s_addr) 
07215          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07216       else
07217          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07218       ast_cli(a->fd, FORMAT, host, 
07219                (reg->dnsmgr) ? "Y" : "N", 
07220                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
07221       counter++;
07222    }
07223    AST_LIST_UNLOCK(&registrations);
07224    ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
07225    return CLI_SUCCESS;
07226 #undef FORMAT
07227 #undef FORMAT2
07228 }

static char* handle_cli_iax2_show_stats ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3941 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, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iaxsl, iax_frame::retries, and ast_cli_entry::usage.

03942 {
03943    struct iax_frame *cur;
03944    int cnt = 0, dead = 0, final = 0, i = 0;
03945 
03946    switch (cmd) {
03947    case CLI_INIT:
03948       e->command = "iax2 show stats";
03949       e->usage =
03950          "Usage: iax2 show stats\n"
03951          "       Display statistics on IAX channel driver.\n";
03952       return NULL;
03953    case CLI_GENERATE:
03954       return NULL;
03955    }
03956 
03957    if (a->argc != 3)
03958       return CLI_SHOWUSAGE;
03959 
03960    for (i = 0; i < ARRAY_LEN(frame_queue); i++) {
03961       ast_mutex_lock(&iaxsl[i]);
03962       AST_LIST_TRAVERSE(&frame_queue[i], cur, list) {
03963          if (cur->retries < 0)
03964             dead++;
03965          if (cur->final)
03966             final++;
03967          cnt++;
03968       }
03969       ast_mutex_unlock(&iaxsl[i]);
03970    }
03971 
03972    ast_cli(a->fd, "    IAX Statistics\n");
03973    ast_cli(a->fd, "---------------------\n");
03974    ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03975    ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03976       trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03977    ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03978 
03979    trunk_timed = trunk_untimed = 0;
03980    if (trunk_maxmtu > trunk_nmaxmtu)
03981       trunk_nmaxmtu = trunk_maxmtu;
03982 
03983    return CLI_SUCCESS;
03984 }

static char* handle_cli_iax2_show_threads ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 6896 of file chan_iax2.c.

References ast_cli_args::argc, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, IAX_THREAD_TYPE_DYNAMIC, iaxthreadcount, thread, and ast_cli_entry::usage.

06897 {
06898    struct iax2_thread *thread = NULL;
06899    time_t t;
06900    int threadcount = 0, dynamiccount = 0;
06901    char type;
06902 
06903    switch (cmd) {
06904    case CLI_INIT:
06905       e->command = "iax2 show threads";
06906       e->usage =
06907          "Usage: iax2 show threads\n"
06908          "       Lists status of IAX helper threads\n";
06909       return NULL;
06910    case CLI_GENERATE:
06911       return NULL;
06912    }
06913    if (a->argc != 3)
06914       return CLI_SHOWUSAGE;
06915       
06916    ast_cli(a->fd, "IAX2 Thread Information\n");
06917    time(&t);
06918    ast_cli(a->fd, "Idle Threads:\n");
06919    AST_LIST_LOCK(&idle_list);
06920    AST_LIST_TRAVERSE(&idle_list, thread, list) {
06921 #ifdef DEBUG_SCHED_MULTITHREAD
06922       ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d, func='%s'\n", 
06923          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06924 #else
06925       ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d\n", 
06926          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06927 #endif
06928       threadcount++;
06929    }
06930    AST_LIST_UNLOCK(&idle_list);
06931    ast_cli(a->fd, "Active Threads:\n");
06932    AST_LIST_LOCK(&active_list);
06933    AST_LIST_TRAVERSE(&active_list, thread, list) {
06934       if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06935          type = 'D';
06936       else
06937          type = 'P';
06938 #ifdef DEBUG_SCHED_MULTITHREAD
06939       ast_cli(a->fd, "Thread %c%d: state=%u, update=%d, actions=%d, func='%s'\n", 
06940          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06941 #else
06942       ast_cli(a->fd, "Thread %c%d: state=%u, update=%d, actions=%d\n", 
06943          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06944 #endif
06945       threadcount++;
06946    }
06947    AST_LIST_UNLOCK(&active_list);
06948    ast_cli(a->fd, "Dynamic Threads:\n");
06949    AST_LIST_LOCK(&dynamic_list);
06950    AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06951 #ifdef DEBUG_SCHED_MULTITHREAD
06952       ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d, func='%s'\n",
06953          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06954 #else
06955       ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d\n",
06956          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06957 #endif
06958       dynamiccount++;
06959    }
06960    AST_LIST_UNLOCK(&dynamic_list);
06961    ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06962    return CLI_SUCCESS;
06963 }

static char* handle_cli_iax2_show_users ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 6687 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, ast_cli_entry::usage, and user_unref().

06688 {
06689    regex_t regexbuf;
06690    int havepattern = 0;
06691 
06692 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
06693 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
06694 
06695    struct iax2_user *user = NULL;
06696    char auth[90];
06697    char *pstr = "";
06698    struct ao2_iterator i;
06699 
06700    switch (cmd) {
06701    case CLI_INIT:
06702       e->command = "iax2 show users [like]";
06703       e->usage =
06704          "Usage: iax2 show users [like <pattern>]\n"
06705          "       Lists all known IAX2 users.\n"
06706          "       Optional regular expression pattern is used to filter the user list.\n";
06707       return NULL;
06708    case CLI_GENERATE:
06709       return NULL;
06710    }
06711 
06712    switch (a->argc) {
06713    case 5:
06714       if (!strcasecmp(a->argv[3], "like")) {
06715          if (regcomp(&regexbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06716             return CLI_SHOWUSAGE;
06717          havepattern = 1;
06718       } else
06719          return CLI_SHOWUSAGE;
06720    case 3:
06721       break;
06722    default:
06723       return CLI_SHOWUSAGE;
06724    }
06725 
06726    ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06727    i = ao2_iterator_init(users, 0);
06728    for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
06729       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
06730          continue;
06731 
06732       if (!ast_strlen_zero(user->secret)) {
06733          ast_copy_string(auth,user->secret, sizeof(auth));
06734       } else if (!ast_strlen_zero(user->inkeys)) {
06735          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06736       } else
06737          ast_copy_string(auth, "-no secret-", sizeof(auth));
06738 
06739       if(ast_test_flag64(user, IAX_CODEC_NOCAP))
06740          pstr = "REQ Only";
06741       else if(ast_test_flag64(user, IAX_CODEC_NOPREFS))
06742          pstr = "Disabled";
06743       else
06744          pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06745 
06746       ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 
06747          user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06748          user->ha ? "Yes" : "No", pstr);
06749    }
06750    ao2_iterator_destroy(&i);
06751 
06752    if (havepattern)
06753       regfree(&regexbuf);
06754 
06755    return CLI_SUCCESS;
06756 #undef FORMAT
06757 #undef FORMAT2
06758 }

static char* handle_cli_iax2_test_losspct ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3721 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.

03722 {
03723    switch (cmd) {
03724    case CLI_INIT:
03725       e->command = "iax2 test losspct";
03726       e->usage =
03727          "Usage: iax2 test losspct <percentage>\n"
03728          "       For testing, throws away <percentage> percent of incoming packets\n";
03729       return NULL;
03730    case CLI_GENERATE:
03731       return NULL;
03732    }
03733    if (a->argc != 4)
03734       return CLI_SHOWUSAGE;
03735 
03736    test_losspct = atoi(a->argv[3]);
03737 
03738    return CLI_SUCCESS;
03739 }

static char* handle_cli_iax2_unregister ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 6965 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_POINTER, peer_ref(), peer_unref(), ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

06966 {
06967    struct iax2_peer *p;
06968 
06969    switch (cmd) {
06970    case CLI_INIT:
06971       e->command = "iax2 unregister";
06972       e->usage =
06973          "Usage: iax2 unregister <peername>\n"
06974          "       Unregister (force expiration) an IAX2 peer from the registry.\n";
06975       return NULL;
06976    case CLI_GENERATE:
06977       return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06978    }
06979 
06980    if (a->argc != 3)
06981       return CLI_SHOWUSAGE;
06982 
06983    p = find_peer(a->argv[2], 1);
06984    if (p) {
06985       if (p->expire > 0) {
06986          struct iax2_peer tmp_peer = {
06987             .name = a->argv[2],
06988          };
06989          struct iax2_peer *peer;
06990 
06991          peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06992          if (peer) {
06993             expire_registry(peer_ref(peer)); /* will release its own reference when done */
06994             peer_unref(peer); /* ref from ao2_find() */
06995             ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06996          } else {
06997             ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06998          }
06999       } else {
07000          ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
07001       }
07002       peer_unref(p);
07003    } else {
07004       ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
07005    }
07006    return CLI_SUCCESS;
07007 }

static void handle_deferred_full_frames ( struct iax2_thread thread  )  [static]

Handle any deferred full frames for this thread.

Definition at line 9676 of file chan_iax2.c.

References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock, ast_mutex_unlock, and socket_process().

Referenced by iax2_process_thread().

09677 {
09678    struct iax2_pkt_buf *pkt_buf;
09679 
09680    ast_mutex_lock(&thread->lock);
09681 
09682    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09683       ast_mutex_unlock(&thread->lock);
09684 
09685       thread->buf = pkt_buf->buf;
09686       thread->buf_len = pkt_buf->len;
09687       thread->buf_size = pkt_buf->len + 1;
09688       
09689       socket_process(thread);
09690 
09691       thread->buf = NULL;
09692       ast_free(pkt_buf);
09693 
09694       ast_mutex_lock(&thread->lock);
09695    }
09696 
09697    ast_mutex_unlock(&thread->lock);
09698 }

static int handle_error ( void   )  [static]

Definition at line 3371 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().

03372 {
03373    /* XXX Ideally we should figure out why an error occurred and then abort those
03374       rather than continuing to try.  Unfortunately, the published interface does
03375       not seem to work XXX */
03376 #if 0
03377    struct sockaddr_in *sin;
03378    int res;
03379    struct msghdr m;
03380    struct sock_extended_err e;
03381    m.msg_name = NULL;
03382    m.msg_namelen = 0;
03383    m.msg_iov = NULL;
03384    m.msg_control = &e;
03385    m.msg_controllen = sizeof(e);
03386    m.msg_flags = 0;
03387    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03388    if (res < 0)
03389       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03390    else {
03391       if (m.msg_controllen) {
03392          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03393          if (sin) 
03394             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03395          else
03396             ast_log(LOG_WARNING, "No address detected??\n");
03397       } else {
03398          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03399       }
03400    }
03401 #endif
03402    return 0;
03403 }

static int iax2_ack_registry ( struct iax_ies ies,
struct sockaddr_in *  sin,
int  callno 
) [static]

Acknowledgment received for OUR registration.

Definition at line 8567 of file chan_iax2.c.

References iax2_registry::addr, iax_ies::apparent_addr, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_sockaddr_to_sin, ast_verb, iax_ies::calling_number, EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), iax2_sched_replace(), iaxs, inaddrcmp(), LOG_WARNING, manager_event, iax2_registry::messages, iax_ies::msgcount, iax2_registry::refresh, iax_ies::refresh, refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, iax2_registry::us, and iax_ies::username.

Referenced by socket_process().

08568 {
08569    struct iax2_registry *reg;
08570    /* Start pessimistic */
08571    char peer[256] = "";
08572    char msgstatus[60];
08573    int refresh = 60;
08574    char ourip[256] = "<Unspecified>";
08575    struct sockaddr_in oldus;
08576    struct sockaddr_in us;
08577    int oldmsgs;
08578    struct sockaddr_in reg_addr;
08579 
08580    memset(&us, 0, sizeof(us));
08581    if (ies->apparent_addr) {
08582       memmove(&us, ies->apparent_addr, sizeof(us));
08583    }
08584    if (ies->username) {
08585       ast_copy_string(peer, ies->username, sizeof(peer));
08586    }
08587    if (ies->refresh) {
08588       refresh = ies->refresh;
08589    }
08590    if (ies->calling_number) {
08591       /* We don't do anything with it really, but maybe we should */
08592    }
08593    reg = iaxs[callno]->reg;
08594    if (!reg) {
08595       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08596       return -1;
08597    }
08598    memcpy(&oldus, &reg->us, sizeof(oldus));
08599    oldmsgs = reg->messages;
08600    ast_sockaddr_to_sin(&reg->addr, &reg_addr);
08601    if (inaddrcmp(&reg_addr, sin)) {
08602       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08603       return -1;
08604    }
08605    memcpy(&reg->us, &us, sizeof(reg->us));
08606    if (ies->msgcount >= 0) {
08607       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
08608    }
08609    /* always refresh the registration at the interval requested by the server
08610       we are registering to
08611    */
08612    reg->refresh = refresh;
08613    reg->expire = iax2_sched_replace(reg->expire, sched,
08614       (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08615    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
08616       if (reg->messages > 255) {
08617          snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08618       } else if (reg->messages > 1) {
08619          snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages);
08620       } else if (reg->messages > 0) {
08621          ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus));
08622       } else {
08623          ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus));
08624       }
08625       snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08626       ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08627       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08628    }
08629    reg->regstate = REG_STATE_REGISTERED;
08630    return 0;
08631 }

static int attribute_pure iax2_allow_new ( int  frametype,
int  subclass,
int  inbound 
) [inline, static]

Definition at line 2839 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().

02840 {
02841    if (frametype != AST_FRAME_IAX) {
02842       return 0;
02843    }
02844    switch (subclass) {
02845    case IAX_COMMAND_NEW:
02846    case IAX_COMMAND_REGREQ:
02847    case IAX_COMMAND_FWDOWNL:
02848    case IAX_COMMAND_REGREL:
02849       return 1;
02850    case IAX_COMMAND_POKE:
02851       if (!inbound) {
02852          return 1;
02853       }
02854       break;
02855    }
02856    return 0;
02857 }

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 1406 of file chan_iax2.c.

References chan_iax2_pvt::callno, EVENT_FLAG_SYSTEM, manager_event, chan_iax2_pvt::owner, and chan_iax2_pvt::peercallno.

Referenced by ast_iax2_new(), and iax2_answer().

01407 {
01408    manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01409       "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01410       pvt->owner ? pvt->owner->name : "",
01411       pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01412 }

static int iax2_answer ( struct ast_channel c  )  [static]

Definition at line 5732 of file chan_iax2.c.

References AST_CONTROL_ANSWER, ast_debug, AST_FRAME_CONTROL, ast_mutex_lock, ast_mutex_unlock, iax2_ami_channelupdate(), iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.

05733 {
05734    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05735    ast_debug(1, "Answering IAX2 call\n");
05736    ast_mutex_lock(&iaxsl[callno]);
05737    if (iaxs[callno])
05738       iax2_ami_channelupdate(iaxs[callno]);
05739    ast_mutex_unlock(&iaxsl[callno]);
05740    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05741 }

static int iax2_append_register ( const char *  hostname,
const char *  username,
const char *  secret,
const char *  porta 
) [static]

Definition at line 8633 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().

08635 {
08636    struct iax2_registry *reg;
08637 
08638    if (!(reg = ast_calloc(1, sizeof(*reg))))
08639       return -1;
08640 
08641    reg->addr.ss.ss_family = AF_INET;
08642    if (ast_dnsmgr_lookup(hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08643       ast_free(reg);
08644       return -1;
08645    }
08646 
08647    ast_copy_string(reg->username, username, sizeof(reg->username));
08648 
08649    if (secret)
08650       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08651 
08652    reg->expire = -1;
08653    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08654    ast_sockaddr_set_port(&reg->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
08655 
08656    AST_LIST_LOCK(&registrations);
08657    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
08658    AST_LIST_UNLOCK(&registrations);
08659    
08660    return 0;
08661 }

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 5561 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_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_VIDUPDATE, 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, f, ast_frame::frametype, iax2_start_transfer(), iax2_tech, IAX_LINGER_TIMEOUT, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, iaxs, iaxsl, 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().

05562 {
05563    struct ast_channel *cs[3];
05564    struct ast_channel *who, *other;
05565    int to = -1;
05566    int res = -1;
05567    int transferstarted=0;
05568    struct ast_frame *f;
05569    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05570    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05571    struct timeval waittimer = {0, 0};
05572 
05573    /* We currently do not support native bridging if a timeoutms value has been provided */
05574    if (timeoutms > 0) {
05575       return AST_BRIDGE_FAILED;
05576    }
05577 
05578    timeoutms = -1;
05579 
05580    lock_both(callno0, callno1);
05581    if (!iaxs[callno0] || !iaxs[callno1]) {
05582       unlock_both(callno0, callno1);
05583       return AST_BRIDGE_FAILED;
05584    }
05585    /* Put them in native bridge mode */
05586    if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05587       iaxs[callno0]->bridgecallno = callno1;
05588       iaxs[callno1]->bridgecallno = callno0;
05589    }
05590    unlock_both(callno0, callno1);
05591 
05592    /* If not, try to bridge until we can execute a transfer, if we can */
05593    cs[0] = c0;
05594    cs[1] = c1;
05595    for (/* ever */;;) {
05596       /* Check in case we got masqueraded into */
05597       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05598          ast_verb(3, "Can't masquerade, we're different...\n");
05599          /* Remove from native mode */
05600          if (c0->tech == &iax2_tech) {
05601             ast_mutex_lock(&iaxsl[callno0]);
05602             iaxs[callno0]->bridgecallno = 0;
05603             ast_mutex_unlock(&iaxsl[callno0]);
05604          }
05605          if (c1->tech == &iax2_tech) {
05606             ast_mutex_lock(&iaxsl[callno1]);
05607             iaxs[callno1]->bridgecallno = 0;
05608             ast_mutex_unlock(&iaxsl[callno1]);
05609          }
05610          return AST_BRIDGE_FAILED_NOWARN;
05611       }
05612       if (c0->nativeformats != c1->nativeformats) {
05613          char buf0[256];
05614          char buf1[256];
05615          ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats);
05616          ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats);
05617          ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1);
05618          /* Remove from native mode */
05619          lock_both(callno0, callno1);
05620          if (iaxs[callno0])
05621             iaxs[callno0]->bridgecallno = 0;
05622          if (iaxs[callno1])
05623             iaxs[callno1]->bridgecallno = 0;
05624          unlock_both(callno0, callno1);
05625          return AST_BRIDGE_FAILED_NOWARN;
05626       }
05627       /* check if transferred and if we really want native bridging */
05628       if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) {
05629          /* Try the transfer */
05630          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05631                      ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA)))
05632             ast_log(LOG_WARNING, "Unable to start the transfer\n");
05633          transferstarted = 1;
05634       }
05635       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05636          /* Call has been transferred.  We're no longer involved */
05637          struct timeval now = ast_tvnow();
05638          if (ast_tvzero(waittimer)) {
05639             waittimer = now;
05640          } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05641             c0->_softhangup |= AST_SOFTHANGUP_DEV;
05642             c1->_softhangup |= AST_SOFTHANGUP_DEV;
05643             *fo = NULL;
05644             *rc = c0;
05645             res = AST_BRIDGE_COMPLETE;
05646             break;
05647          }
05648       }
05649       to = 1000;
05650       who = ast_waitfor_n(cs, 2, &to);
05651       /* XXX This will need to be updated to calculate
05652        * timeout correctly once timeoutms is allowed to be
05653        * > 0. Right now, this can go badly if the waitfor
05654        * times out in less than a millisecond
05655        */
05656       if (timeoutms > -1) {
05657          timeoutms -= (1000 - to);
05658          if (timeoutms < 0)
05659             timeoutms = 0;
05660       }
05661       if (!who) {
05662          if (!timeoutms) {
05663             res = AST_BRIDGE_RETRY;
05664             break;
05665          }
05666          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05667             res = AST_BRIDGE_FAILED;
05668             break;
05669          }
05670          continue;
05671       }
05672       f = ast_read(who);
05673       if (!f) {
05674          *fo = NULL;
05675          *rc = who;
05676          res = AST_BRIDGE_COMPLETE;
05677          break;
05678       }
05679       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
05680       if (f->frametype == AST_FRAME_CONTROL && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
05681          switch (f->subclass.integer) {
05682          case AST_CONTROL_VIDUPDATE:
05683          case AST_CONTROL_SRCUPDATE:
05684          case AST_CONTROL_SRCCHANGE:
05685          case AST_CONTROL_T38_PARAMETERS:
05686             ast_write(other, f);
05687             break;
05688          default:
05689             *fo = f;
05690             *rc = who;
05691             res = AST_BRIDGE_COMPLETE;
05692             break;
05693          }
05694          if (res == AST_BRIDGE_COMPLETE) {
05695             break;
05696          }
05697       } else if (f->frametype == AST_FRAME_VOICE
05698          || f->frametype == AST_FRAME_TEXT
05699          || f->frametype == AST_FRAME_VIDEO
05700          || f->frametype == AST_FRAME_IMAGE) {
05701          ast_write(other, f);
05702       } else if (f->frametype == AST_FRAME_DTMF) {
05703          /* monitored dtmf take out of the bridge.
05704           * check if we monitor the specific source.
05705           */
05706          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05707 
05708          if (flags & monitored_source) {
05709             *rc = who;
05710             *fo = f;
05711             res = AST_BRIDGE_COMPLETE;
05712             /* Remove from native mode */
05713             break;
05714          }
05715          ast_write(other, f);
05716       }
05717       ast_frfree(f);
05718       /* Swap who gets priority */
05719       cs[2] = cs[0];
05720       cs[0] = cs[1];
05721       cs[1] = cs[2];
05722    }
05723    lock_both(callno0, callno1);
05724    if(iaxs[callno0])
05725       iaxs[callno0]->bridgecallno = 0;
05726    if(iaxs[callno1])
05727       iaxs[callno1]->bridgecallno = 0;
05728    unlock_both(callno0, callno1);
05729    return res;
05730 }

static int iax2_call ( struct ast_channel c,
char *  dest,
int  timeout 
) [static]

Definition at line 5109 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_copy_string(), ast_debug, AST_FRAME_IAX, AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_party_id_presentation(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_var_name(), ast_var_value(), auto_congest(), iax_ie_data::buf, CALLNO_TO_PTR, capability, 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(), iax2_variable_datastore_info, IAX_COMMAND_NEW, IAX_FORCE_ENCRYPT, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_raw(), iax_ie_append_short(), iax_ie_append_str(), iax_ie_append_versioned_uint64(), IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CAPABILITY, IAX_IE_CAPABILITY2, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_FORMAT2, IAX_IE_LANGUAGE, IAX_IE_OSPTOKEN, IAX_IE_RDNIS, IAX_IE_USERNAME, IAX_IE_VARIABLE, IAX_IE_VERSION, IAX_MAX_OSPBLOCK_SIZE, IAX_MAX_OSPTOKEN_SIZE, IAX_PROTO_VERSION, IAX_SENDANI, iaxs, iaxsl, ast_party_connected_line::id, chan_iax2_pvt::initid, 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.

05110 {
05111    struct sockaddr_in sin;
05112    char *l=NULL, *n=NULL, *tmpstr;
05113    struct iax_ie_data ied;
05114    char *defaultrdest = "s";
05115    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05116    struct parsed_dial_string pds;
05117    struct create_addr_info cai;
05118    struct ast_var_t *var;
05119    struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
05120    const char* osp_token_ptr;
05121    unsigned int osp_token_length;
05122    unsigned char osp_block_index;
05123    unsigned int osp_block_length;
05124    unsigned char osp_buffer[256];
05125 
05126    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
05127       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
05128       return -1;
05129    }
05130 
05131    memset(&cai, 0, sizeof(cai));
05132    cai.encmethods = iax2_encryption;
05133 
05134    memset(&pds, 0, sizeof(pds));
05135    tmpstr = ast_strdupa(dest);
05136    parse_dial_string(tmpstr, &pds);
05137 
05138    if (ast_strlen_zero(pds.peer)) {
05139       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
05140       return -1;
05141    }
05142    if (!pds.exten) {
05143       pds.exten = defaultrdest;
05144    }
05145    if (create_addr(pds.peer, c, &sin, &cai)) {
05146       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
05147       return -1;
05148    }
05149    if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) {
05150       ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n");
05151       c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05152       return -1;
05153    }
05154    if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
05155       ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n");
05156       return -1;
05157    }
05158    if (!pds.username && !ast_strlen_zero(cai.username))
05159       pds.username = cai.username;
05160    if (!pds.password && !ast_strlen_zero(cai.secret))
05161       pds.password = cai.secret;
05162    if (!pds.key && !ast_strlen_zero(cai.outkey))
05163       pds.key = cai.outkey;
05164    if (!pds.context && !ast_strlen_zero(cai.peercontext))
05165       pds.context = cai.peercontext;
05166 
05167    /* Keep track of the context for outgoing calls too */
05168    ast_copy_string(c->context, cai.context, sizeof(c->context));
05169 
05170    if (pds.port)
05171       sin.sin_port = htons(atoi(pds.port));
05172 
05173    l = c->connected.id.number.valid ? c->connected.id.number.str : NULL;
05174    n = c->connected.id.name.valid ? c->connected.id.name.str : NULL;
05175 
05176    /* Now build request */ 
05177    memset(&ied, 0, sizeof(ied));
05178 
05179    /* On new call, first IE MUST be IAX version of caller */
05180    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
05181    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
05182    if (pds.options && strchr(pds.options, 'a')) {
05183       /* Request auto answer */
05184       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
05185    }
05186 
05187    /* WARNING: this breaks down at 190 bits! */
05188    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
05189 
05190    if (l) {
05191       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
05192       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05193          ast_party_id_presentation(&c->connected.id));
05194    } else if (n) {
05195       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05196          ast_party_id_presentation(&c->connected.id));
05197    } else {
05198       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
05199    }
05200 
05201    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan);
05202    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select);
05203 
05204    if (n)
05205       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
05206    if (ast_test_flag64(iaxs[callno], IAX_SENDANI)
05207       && c->connected.ani.number.valid
05208       && c->connected.ani.number.str) {
05209       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str);
05210    }
05211 
05212    if (!ast_strlen_zero(c->language))
05213       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
05214    if (!ast_strlen_zero(c->dialed.number.str)) {
05215       iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str);
05216    }
05217    if (c->redirecting.from.number.valid
05218       && !ast_strlen_zero(c->redirecting.from.number.str)) {
05219       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str);
05220    }
05221 
05222    if (pds.context)
05223       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
05224 
05225    if (pds.username)
05226       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
05227 
05228    if (cai.encmethods)
05229       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
05230 
05231    ast_mutex_lock(&iaxsl[callno]);
05232 
05233    if (!ast_strlen_zero(c->context))
05234       ast_string_field_set(iaxs[callno], context, c->context);
05235 
05236    if (pds.username)
05237       ast_string_field_set(iaxs[callno], username, pds.username);
05238 
05239    iaxs[callno]->encmethods = cai.encmethods;
05240 
05241    iaxs[callno]->adsi = cai.adsi;
05242    
05243    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
05244    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
05245 
05246    if (pds.key)
05247       ast_string_field_set(iaxs[callno], outkey, pds.key);
05248    if (pds.password)
05249       ast_string_field_set(iaxs[callno], secret, pds.password);
05250 
05251    iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats);
05252    iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats);
05253    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability);
05254    iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability);
05255    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
05256    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
05257 
05258    if (iaxs[callno]->maxtime) {
05259       /* Initialize pingtime and auto-congest time */
05260       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
05261       iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
05262    } else if (autokill) {
05263       iaxs[callno]->pingtime = autokill / 2;
05264       iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
05265    }
05266 
05267    /* Check if there is an OSP token */
05268    osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
05269    if (!ast_strlen_zero(osp_token_ptr)) {
05270       if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
05271          osp_block_index = 0;
05272          while (osp_token_length > 0) {
05273             osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
05274             osp_buffer[0] = osp_block_index;
05275             memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
05276             iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
05277             osp_block_index++;
05278             osp_token_ptr += osp_block_length;
05279             osp_token_length -= osp_block_length;
05280          } 
05281       } else
05282          ast_log(LOG_WARNING, "OSP token is too long\n");
05283    } else if (iaxdebug)
05284       ast_debug(1, "OSP token is undefined\n");
05285 
05286    /* send the command using the appropriate socket for this peer */
05287    iaxs[callno]->sockfd = cai.sockfd;
05288 
05289    /* Add remote vars */
05290    if (variablestore) {
05291       AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
05292       ast_debug(1, "Found an IAX variable store on this channel\n");
05293       AST_LIST_LOCK(variablelist);
05294       AST_LIST_TRAVERSE(variablelist, var, entries) {
05295          char tmp[256];
05296          int i;
05297          ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
05298          /* Automatically divide the value up into sized chunks */
05299          for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
05300             snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
05301             iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
05302          }
05303       }
05304       AST_LIST_UNLOCK(variablelist);
05305    }
05306 
05307    /* Transmit the string in a "NEW" request */
05308    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
05309    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
05310 
05311    ast_mutex_unlock(&iaxsl[callno]);
05312    ast_setstate(c, AST_STATE_RINGING);
05313 
05314    return 0;
05315 }

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 14043 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.

14044 {
14045    int res = 0;
14046    struct iax2_dpcache *dp = NULL;
14047 #if 0
14048    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14049 #endif
14050    if ((priority != 1) && (priority != 2))
14051       return 0;
14052 
14053    AST_LIST_LOCK(&dpcache);
14054    if ((dp = find_cache(chan, data, context, exten, priority))) {
14055       if (dp->flags & CACHE_FLAG_CANEXIST)
14056          res = 1;
14057    } else {
14058       ast_log(LOG_WARNING, "Unable to make DP cache\n");
14059    }
14060    AST_LIST_UNLOCK(&dpcache);
14061 
14062    return res;
14063 }

static unsigned int iax2_datetime ( const char *  tz  )  [static]

Definition at line 4780 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().

04781 {
04782    struct timeval t = ast_tvnow();
04783    struct ast_tm tm;
04784    unsigned int tmp;
04785    ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04786    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
04787    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
04788    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
04789    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
04790    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
04791    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
04792    return tmp;
04793 }

static void iax2_destroy ( int  callno  )  [static]

Definition at line 3475 of file chan_iax2.c.

References ao2_ref, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_queue_hangup(), DEADLOCK_AVOIDANCE, iax2_destroy_helper(), iaxs, iaxsl, chan_iax2_pvt::owner, chan_iax2_pvt::peercallno, remove_by_peercallno(), remove_by_transfercallno(), chan_iax2_pvt::transfercallno, and update_max_trunk.

Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __unload_module(), delete_users(), iax2_do_register(), iax2_hangup(), iax2_poke_peer(), peer_destructor(), scheduled_destroy(), and socket_process().

03476 {
03477    struct chan_iax2_pvt *pvt = NULL;
03478    struct ast_channel *owner = NULL;
03479 
03480 retry:
03481    if ((pvt = iaxs[callno])) {
03482 #if 0
03483       /* iax2_destroy_helper gets called from this function later on.  When
03484        * called twice, we get the (previously) familiar FRACK! errors in
03485        * devmode, from the scheduler.  An alternative to this approach is to
03486        * reset the scheduler entries to -1 when they're deleted in
03487        * iax2_destroy_helper().  That approach was previously decided to be
03488        * "wrong" because "the memory is going to be deallocated anyway.  Why
03489        * should we be resetting those values?" */
03490       iax2_destroy_helper(pvt);
03491 #endif
03492    }
03493 
03494    owner = pvt ? pvt->owner : NULL;
03495 
03496    if (owner) {
03497       if (ast_channel_trylock(owner)) {
03498          ast_debug(3, "Avoiding IAX destroy deadlock\n");
03499          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03500          goto retry;
03501       }
03502    }
03503 
03504    if (!owner) {
03505       iaxs[callno] = NULL;
03506    }
03507 
03508    if (pvt) {
03509       if (!owner) {
03510          pvt->owner = NULL;
03511       } else {
03512          /* If there's an owner, prod it to give up */
03513          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
03514           * because we already hold the owner channel lock. */
03515          ast_queue_hangup(owner);
03516       }
03517 
03518       if (pvt->peercallno) {
03519          remove_by_peercallno(pvt);
03520       }
03521 
03522       if (pvt->transfercallno) {
03523          remove_by_transfercallno(pvt);
03524       }
03525 
03526       if (!owner) {
03527          ao2_ref(pvt, -1);
03528          pvt = NULL;
03529       }
03530    }
03531 
03532    if (owner) {
03533       ast_channel_unlock(owner);
03534    }
03535 
03536    if (callno & TRUNK_CALL_START) {
03537       update_max_trunk();
03538    }
03539 }

static void iax2_destroy_helper ( struct chan_iax2_pvt pvt  )  [static]
Note:
Assumes the lock on the pvt is already held, when iax2_destroy_helper() is called.

Definition at line 1854 of file chan_iax2.c.

References ao2_find, ast_atomic_fetchadd_int(), ast_clear_flag64, AST_SCHED_DEL_SPINLOCK, ast_sched_thread_del, ast_sched_thread_get_context(), ast_test_flag64, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::callno, iax2_user::curauthreq, DONT_RESCHEDULE, IAX_MAXAUTHREQ, iaxsl, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::lagid, OBJ_POINTER, chan_iax2_pvt::pingid, and user_unref().

Referenced by iax2_destroy(), iax2_predestroy(), pvt_destructor(), and stop_stuff().

01855 {
01856    /* Decrement AUTHREQ count if needed */
01857    if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) {
01858       struct iax2_user *user;
01859       struct iax2_user tmp_user = {
01860          .name = pvt->username,
01861       };
01862 
01863       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01864       if (user) {
01865          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01866          user_unref(user);
01867       }
01868 
01869       ast_clear_flag64(pvt, IAX_MAXAUTHREQ);
01870    }
01871    /* No more pings or lagrq's */
01872    AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]);
01873    pvt->pingid = DONT_RESCHEDULE;
01874    AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]);
01875    pvt->lagid = DONT_RESCHEDULE;
01876    ast_sched_thread_del(sched, pvt->autoid);
01877    ast_sched_thread_del(sched, pvt->authid);
01878    ast_sched_thread_del(sched, pvt->initid);
01879    ast_sched_thread_del(sched, pvt->jbid);
01880    ast_sched_thread_del(sched, pvt->keyrotateid);
01881 }

static int iax2_devicestate ( void *  data  )  [static]

Part of the device state notification system ---.

Definition at line 14250 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().

14251 {
14252    struct parsed_dial_string pds;
14253    char *tmp = ast_strdupa(data);
14254    struct iax2_peer *p;
14255    int res = AST_DEVICE_INVALID;
14256 
14257    memset(&pds, 0, sizeof(pds));
14258    parse_dial_string(tmp, &pds);
14259 
14260    if (ast_strlen_zero(pds.peer)) {
14261       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
14262       return res;
14263    }
14264    
14265    ast_debug(3, "Checking device state for device %s\n", pds.peer);
14266 
14267    /* SLD: FIXME: second call to find_peer during registration */
14268    if (!(p = find_peer(pds.peer, 1)))
14269       return res;
14270 
14271    res = AST_DEVICE_UNAVAILABLE;
14272    ast_debug(3, "Found peer. What's device state of %s? addr=%u, defaddr=%u maxms=%d, lastms=%d\n",
14273       pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
14274    
14275    if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) &&
14276        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
14277       /* Peer is registered, or have default IP address
14278          and a valid registration */
14279       if (p->historicms == 0 || p->historicms <= p->maxms)
14280          /* let the core figure out whether it is in use or not */
14281          res = AST_DEVICE_UNKNOWN;  
14282    }
14283 
14284    peer_unref(p);
14285 
14286    return res;
14287 }

static int iax2_digit_begin ( struct ast_channel c,
char  digit 
) [static]

Definition at line 4381 of file chan_iax2.c.

References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.

04382 {
04383    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
04384 }

static int iax2_digit_end ( struct ast_channel c,
char  digit,
unsigned int  duration 
) [static]

Definition at line 4386 of file chan_iax2.c.

References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.

04387 {
04388    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
04389 }

static int iax2_do_register ( struct iax2_registry reg  )  [static]

Definition at line 12024 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, iaxs, iaxsl, 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().

12025 {
12026    struct iax_ie_data ied;
12027    if (iaxdebug)
12028       ast_debug(1, "Sending registration request for '%s'\n", reg->username);
12029 
12030    if (reg->dnsmgr && 
12031        ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(&reg->addr))) {
12032       /* Maybe the IP has changed, force DNS refresh */
12033       ast_dnsmgr_refresh(reg->dnsmgr);
12034    }
12035    
12036    /*
12037     * if IP has Changed, free allocated call to create a new one with new IP
12038     * call has the pointer to IP and must be updated to the new one
12039     */
12040    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
12041       int callno = reg->callno;
12042       ast_mutex_lock(&iaxsl[callno]);
12043       iax2_destroy(callno);
12044       ast_mutex_unlock(&iaxsl[callno]);
12045       reg->callno = 0;
12046    }
12047    if (!ast_sockaddr_ipv4(&reg->addr)) {
12048       if (iaxdebug)
12049          ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
12050       /* Setup the next registration attempt */
12051       reg->expire = iax2_sched_replace(reg->expire, sched, 
12052          (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
12053       return -1;
12054    }
12055 
12056    if (!reg->callno) {
12057       struct sockaddr_in reg_addr;
12058 
12059       ast_debug(3, "Allocate call number\n");
12060 
12061       ast_sockaddr_to_sin(&reg->addr, &reg_addr);
12062 
12063       reg->callno = find_callno_locked(0, 0, &reg_addr, NEW_FORCE, defaultsockfd, 0);
12064       if (reg->callno < 1) {
12065          ast_log(LOG_WARNING, "Unable to create call for registration\n");
12066          return -1;
12067       } else
12068          ast_debug(3, "Registration created on call %d\n", reg->callno);
12069       iaxs[reg->callno]->reg = reg;
12070       ast_mutex_unlock(&iaxsl[reg->callno]);
12071    }
12072    /* Setup the next registration a little early */
12073    reg->expire = iax2_sched_replace(reg->expire, sched, 
12074       (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
12075    /* Send the request */
12076    memset(&ied, 0, sizeof(ied));
12077    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
12078    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
12079    add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */
12080    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
12081    reg->regstate = REG_STATE_REGSENT;
12082    return 0;
12083 }

static int iax2_do_register_s ( const void *  data  )  [static]

Definition at line 8415 of file chan_iax2.c.

References __iax2_do_register_s(), and schedule_action.

Referenced by iax2_ack_registry(), and iax2_do_register().

08416 {
08417 #ifdef SCHED_MULTITHREADED
08418    if (schedule_action(__iax2_do_register_s, data))
08419 #endif      
08420       __iax2_do_register_s(data);
08421    return 0;
08422 }

static void iax2_dprequest ( struct iax2_dpcache dp,
int  callno 
) [static]

Definition at line 9191 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, iaxs, iax_ie_data::pos, and send_command().

Referenced by find_cache(), and socket_process().

09192 {
09193    struct iax_ie_data ied;
09194    /* Auto-hangup with 30 seconds of inactivity */
09195    iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
09196       sched, 30000, auto_hangup, (void *)(long)callno);
09197    memset(&ied, 0, sizeof(ied));
09198    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
09199    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
09200    dp->flags |= CACHE_FLAG_TRANSMITTED;
09201 }

static void * iax2_dup_variable_datastore ( void *  old  )  [static]

Definition at line 1420 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(), and LOG_ERROR.

01421 {
01422    AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01423    struct ast_var_t *oldvar, *newvar;
01424 
01425    newlist = ast_calloc(sizeof(*newlist), 1);
01426    if (!newlist) {
01427       ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01428       return NULL;
01429    }
01430 
01431    AST_LIST_HEAD_INIT(newlist);
01432    AST_LIST_LOCK(oldlist);
01433    AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01434       newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01435       if (newvar)
01436          AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01437       else
01438          ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01439    }
01440    AST_LIST_UNLOCK(oldlist);
01441    return newlist;
01442 }

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 14089 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().

14090 {
14091    char odata[256];
14092    char req[256];
14093    char *ncontext;
14094    struct iax2_dpcache *dp = NULL;
14095    struct ast_app *dial = NULL;
14096 #if 0
14097    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);
14098 #endif
14099    if (priority == 2) {
14100       /* Indicate status, can be overridden in dialplan */
14101       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
14102       if (dialstatus) {
14103          dial = pbx_findapp(dialstatus);
14104          if (dial) 
14105             pbx_exec(chan, dial, "");
14106       }
14107       return -1;
14108    } else if (priority != 1)
14109       return -1;
14110 
14111    AST_LIST_LOCK(&dpcache);
14112    if ((dp = find_cache(chan, data, context, exten, priority))) {
14113       if (dp->flags & CACHE_FLAG_EXISTS) {
14114          ast_copy_string(odata, data, sizeof(odata));
14115          ncontext = strchr(odata, '/');
14116          if (ncontext) {
14117             *ncontext = '\0';
14118             ncontext++;
14119             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
14120          } else {
14121             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
14122          }
14123          ast_verb(3, "Executing Dial('%s')\n", req);
14124       } else {
14125          AST_LIST_UNLOCK(&dpcache);
14126          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
14127          return -1;
14128       }
14129    }
14130    AST_LIST_UNLOCK(&dpcache);
14131 
14132    if ((dial = pbx_findapp("Dial")))
14133       return pbx_exec(chan, dial, req);
14134    else
14135       ast_log(LOG_WARNING, "No dial application registered\n");
14136 
14137    return -1;
14138 }

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 14020 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.

14021 {
14022    int res = 0;
14023    struct iax2_dpcache *dp = NULL;
14024 #if 0
14025    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14026 #endif
14027    if ((priority != 1) && (priority != 2))
14028       return 0;
14029 
14030    AST_LIST_LOCK(&dpcache);
14031    if ((dp = find_cache(chan, data, context, exten, priority))) {
14032       if (dp->flags & CACHE_FLAG_EXISTS)
14033          res = 1;
14034    } else {
14035       ast_log(LOG_WARNING, "Unable to make DP cache\n");
14036    }
14037    AST_LIST_UNLOCK(&dpcache);
14038 
14039    return res;
14040 }

static int iax2_fixup ( struct ast_channel oldchannel,
struct ast_channel newchan 
) [static]

Definition at line 4408 of file chan_iax2.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, iax_frame::callno, iaxs, iaxsl, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt.

04409 {
04410    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04411    ast_mutex_lock(&iaxsl[callno]);
04412    if (iaxs[callno])
04413       iaxs[callno]->owner = newchan;
04414    else
04415       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04416    ast_mutex_unlock(&iaxsl[callno]);
04417    return 0;
04418 }

static void iax2_frame_free ( struct iax_frame fr  )  [static]
static void iax2_free_variable_datastore ( void *  old  )  [static]

Definition at line 1444 of file chan_iax2.c.

References ast_free, AST_LIST_HEAD, AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.

01445 {
01446    AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01447    struct ast_var_t *oldvar;
01448 
01449    AST_LIST_LOCK(oldlist);
01450    while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01451       ast_free(oldvar);
01452    }
01453    AST_LIST_UNLOCK(oldlist);
01454    AST_LIST_HEAD_DESTROY(oldlist);
01455    ast_free(oldlist);
01456 }

static int iax2_getpeername ( struct sockaddr_in  sin,
char *  host,
int  len 
) [static]

Definition at line 1817 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, peer_unref(), and realtime_peer().

Referenced by __find_callno().

01818 {
01819    struct iax2_peer *peer = NULL;
01820    int res = 0;
01821    struct ao2_iterator i;
01822 
01823    i = ao2_iterator_init(peers, 0);
01824    while ((peer = ao2_iterator_next(&i))) {
01825       struct sockaddr_in peer_addr;
01826 
01827       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
01828 
01829       if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01830           (peer_addr.sin_port == sin.sin_port)) {
01831          ast_copy_string(host, peer->name, len);
01832          peer_unref(peer);
01833          res = 1;
01834          break;
01835       }
01836       peer_unref(peer);
01837    }
01838    ao2_iterator_destroy(&i);
01839 
01840    if (!peer) {
01841       peer = realtime_peer(NULL, &sin);
01842       if (peer) {
01843          ast_copy_string(host, peer->name, len);
01844          peer_unref(peer);
01845          res = 1;
01846       }
01847    }
01848 
01849    return res;
01850 }

static int iax2_getpeertrunk ( struct sockaddr_in  sin  )  [static]

Definition at line 5812 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().

05813 {
05814    struct iax2_peer *peer;
05815    int res = 0;
05816    struct ao2_iterator i;
05817 
05818    i = ao2_iterator_init(peers, 0);
05819    while ((peer = ao2_iterator_next(&i))) {
05820       struct sockaddr_in peer_addr;
05821 
05822       ast_sockaddr_to_sin(&peer->addr, &peer_addr);
05823 
05824       if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05825           (peer_addr.sin_port == sin.sin_port)) {
05826          res = ast_test_flag64(peer, IAX_TRUNK);
05827          peer_unref(peer);
05828          break;
05829       }
05830       peer_unref(peer);
05831    }
05832    ao2_iterator_destroy(&i);
05833 
05834    return res;
05835 }

static int iax2_hangup ( struct ast_channel c  )  [static]

Definition at line 5317 of file chan_iax2.c.

References ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_add(), ast_test_flag64, ast_verb, 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, iaxs, iaxsl, LOG_ERROR, LOG_WARNING, iax_ie_data::pos, PTR_TO_CALLNO, scheduled_destroy(), send_command_final(), and ast_channel::tech_pvt.

05318 {
05319    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05320    struct iax_ie_data ied;
05321    int alreadygone;
05322    memset(&ied, 0, sizeof(ied));
05323    ast_mutex_lock(&iaxsl[callno]);
05324    if (callno && iaxs[callno]) {
05325       ast_debug(1, "We're hanging up %s now...\n", c->name);
05326       alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE);
05327       /* Send the hangup unless we have had a transmission error or are already gone */
05328       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
05329       if (!iaxs[callno]->error && !alreadygone) {
05330          if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
05331             ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
05332          }
05333          if (!iaxs[callno]) {
05334             ast_mutex_unlock(&iaxsl[callno]);
05335             return 0;
05336          }
05337       }
05338       /* Explicitly predestroy it */
05339       iax2_predestroy(callno);
05340       /* If we were already gone to begin with, destroy us now */
05341       if (iaxs[callno] && alreadygone) {
05342          ast_debug(1, "Really destroying %s now...\n", c->name);
05343          iax2_destroy(callno);
05344       } else if (iaxs[callno]) {
05345          if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
05346             ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!!  Destroying immediately.\n", callno);
05347             iax2_destroy(callno);
05348          }
05349       }
05350    } else if (c->tech_pvt) {
05351       /* If this call no longer exists, but the channel still
05352        * references it we need to set the channel's tech_pvt to null
05353        * to avoid ast_channel_free() trying to free it.
05354        */
05355       c->tech_pvt = NULL;
05356    }
05357    ast_mutex_unlock(&iaxsl[callno]);
05358    ast_verb(3, "Hungup '%s'\n", c->name);
05359    return 0;
05360 }

static int iax2_indicate ( struct ast_channel c,
int  condition,
const void *  data,
size_t  datalen 
) [static]

Definition at line 5743 of file chan_iax2.c.

References AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_REDIRECTING, AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_CONTROL, ast_moh_start(), ast_moh_stop(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, IAX_SENDCONNECTEDLINE, iaxs, iaxsl, PTR_TO_CALLNO, send_command(), ast_channel::tech_pvt, and wait_for_peercallno().

05744 {
05745    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05746    struct chan_iax2_pvt *pvt;
05747    int res = 0;
05748 
05749    if (iaxdebug)
05750       ast_debug(1, "Indicating condition %d\n", condition);
05751 
05752    ast_mutex_lock(&iaxsl[callno]);
05753    pvt = iaxs[callno];
05754 
05755    if (wait_for_peercallno(pvt)) {
05756       res = -1;
05757       goto done;
05758    }
05759 
05760    switch (condition) {
05761    case AST_CONTROL_HOLD:
05762       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05763          ast_moh_start(c, data, pvt->mohinterpret);
05764          goto done;
05765       }
05766       break;
05767    case AST_CONTROL_UNHOLD:
05768       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05769          ast_moh_stop(c);
05770          goto done;
05771       }
05772       break;
05773    case AST_CONTROL_CONNECTED_LINE:
05774    case AST_CONTROL_REDIRECTING:
05775       if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE)) {
05776          /* We are not configured to allow sending these updates. */
05777          ast_debug(2, "Callno %d: Config blocked sending control frame %d.\n",
05778             callno, condition);
05779          goto done;
05780       }
05781       break;
05782    }
05783 
05784    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05785 
05786 done:
05787    ast_mutex_unlock(&iaxsl[callno]);
05788 
05789    return res;
05790 }

static int iax2_is_control_frame_allowed ( int  subtype  )  [static]

Definition at line 1284 of file chan_iax2.c.

References _XXX_AST_CONTROL_T38, AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_END_OF_Q, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_READ_ACTION, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_TRANSFER, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, and AST_CONTROL_WINK.

Referenced by send_command(), and socket_process().

01285 {
01286    enum ast_control_frame_type control = subtype;
01287    int is_allowed;
01288 
01289    /*
01290     * Note: If we compare the enumeration type, which does not have any
01291     * negative constants, the compiler may optimize this code away.
01292     * Therefore, we must perform an integer comparison here.
01293     */
01294    if (subtype == -1) {
01295       return -1;
01296    }
01297 
01298    /* Default to not allowing control frames to pass. */
01299    is_allowed = 0;
01300 
01301    /*
01302     * The switch default is not present in order to take advantage
01303     * of the compiler complaining of a missing enum case.
01304     */
01305    switch (control) {
01306    /*
01307     * These control frames make sense to send/receive across the link.
01308     */
01309    case AST_CONTROL_HANGUP:
01310    case AST_CONTROL_RING:
01311    case AST_CONTROL_RINGING:
01312    case AST_CONTROL_ANSWER:
01313    case AST_CONTROL_BUSY:
01314    case AST_CONTROL_TAKEOFFHOOK:
01315    case AST_CONTROL_OFFHOOK:
01316    case AST_CONTROL_CONGESTION:
01317    case AST_CONTROL_FLASH:
01318    case AST_CONTROL_WINK:
01319    case AST_CONTROL_OPTION:
01320    case AST_CONTROL_RADIO_KEY:
01321    case AST_CONTROL_RADIO_UNKEY:
01322    case AST_CONTROL_PROGRESS:
01323    case AST_CONTROL_PROCEEDING:
01324    case AST_CONTROL_HOLD:
01325    case AST_CONTROL_UNHOLD:
01326    case AST_CONTROL_VIDUPDATE:
01327    case AST_CONTROL_CONNECTED_LINE:
01328    case AST_CONTROL_REDIRECTING:
01329    case AST_CONTROL_T38_PARAMETERS:
01330    case AST_CONTROL_AOC:
01331    case AST_CONTROL_INCOMPLETE:
01332       is_allowed = -1;
01333       break;
01334 
01335    /*
01336     * These control frames do not make sense to send/receive across the link.
01337     */
01338    case _XXX_AST_CONTROL_T38:
01339       /* The control value is deprecated in favor of AST_CONTROL_T38_PARAMETERS. */
01340    case AST_CONTROL_SRCUPDATE:
01341       /* Across an IAX link the source is still the same. */
01342    case AST_CONTROL_TRANSFER:
01343       /* A success/fail status report from calling ast_transfer() on this machine. */
01344    case AST_CONTROL_CC:
01345       /* The payload contains pointers that are valid for the sending machine only. */
01346    case AST_CONTROL_SRCCHANGE:
01347       /* Across an IAX link the source is still the same. */
01348    case AST_CONTROL_READ_ACTION:
01349       /* The action can only be done by the sending machine. */
01350    case AST_CONTROL_END_OF_Q:
01351       /* This frame would cause the call to unexpectedly hangup. */
01352    case AST_CONTROL_UPDATE_RTP_PEER:
01353       /* Only meaningful across a bridge on this machine for direct-media exchange. */
01354       break;
01355    }
01356    return is_allowed;
01357 }

static int iax2_key_rotate ( const void *  vpvt  )  [static]

Definition at line 5479 of file chan_iax2.c.

References AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_sched_thread_add(), iax_ie_data::buf, build_ecx_key(), chan_iax2_pvt::callno, IAX_COMMAND_RTKEY, IAX_DEBUGDIGEST, iax_ie_append_raw(), IAX_IE_CHALLENGE, iaxsl, chan_iax2_pvt::keyrotateid, MD5Final(), MD5Init(), MD5Update(), iax_ie_data::pos, and send_command().

Referenced by iax2_send().

05480 {
05481    int res = 0;
05482    struct chan_iax2_pvt *pvt = (void *) vpvt;
05483    struct MD5Context md5;
05484    char key[17] = "";
05485    struct iax_ie_data ied = {
05486       .pos = 0,   
05487    };
05488    
05489    ast_mutex_lock(&iaxsl[pvt->callno]);
05490    pvt->keyrotateid = 
05491       ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
05492 
05493    snprintf(key, sizeof(key), "%lX", (unsigned long)ast_random());
05494 
05495    MD5Init(&md5);
05496    MD5Update(&md5, (unsigned char *) key, strlen(key));
05497    MD5Final((unsigned char *) key, &md5);
05498 
05499    IAX_DEBUGDIGEST("Sending", key);
05500 
05501    iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05502 
05503    res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05504 
05505    build_ecx_key((unsigned char *) key, pvt);
05506 
05507    ast_mutex_unlock(&iaxsl[pvt->callno]);
05508 
05509    return res;
05510 }

static void iax2_lock_owner ( int  callno  )  [static]

Definition at line 1260 of file chan_iax2.c.

References ast_channel_trylock, DEADLOCK_AVOIDANCE, iaxs, and iaxsl.

Referenced by iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), schedule_delivery(), set_hangup_source_and_cause(), and socket_process().

01261 {
01262    for (;;) {
01263       if (!iaxs[callno] || !iaxs[callno]->owner) {
01264          /* There is no owner lock to get. */
01265          break;
01266       }
01267       if (!ast_channel_trylock(iaxs[callno]->owner)) {
01268          /* We got the lock */
01269          break;
01270       }
01271       /* Avoid deadlock by pausing and trying again */
01272       DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01273    }
01274 }

static int iax2_matchmore ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid,
const char *  data 
) [static]

Part of the IAX2 Switch interface.

Definition at line 14066 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.

14067 {
14068    int res = 0;
14069    struct iax2_dpcache *dp = NULL;
14070 #if 0
14071    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14072 #endif
14073    if ((priority != 1) && (priority != 2))
14074       return 0;
14075 
14076    AST_LIST_LOCK(&dpcache);
14077    if ((dp = find_cache(chan, data, context, exten, priority))) {
14078       if (dp->flags & CACHE_FLAG_MATCHMORE)
14079          res = 1;
14080    } else {
14081       ast_log(LOG_WARNING, "Unable to make DP cache\n");
14082    }
14083    AST_LIST_UNLOCK(&dpcache);
14084 
14085    return res;
14086 }

static int iax2_poke_noanswer ( const void *  data  )  [static]

Definition at line 12228 of file chan_iax2.c.

References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.

Referenced by iax2_poke_peer().

12229 {
12230    struct iax2_peer *peer = (struct iax2_peer *)data;
12231    peer->pokeexpire = -1;
12232 #ifdef SCHED_MULTITHREADED
12233    if (schedule_action(__iax2_poke_noanswer, data))
12234 #endif      
12235       __iax2_poke_noanswer(data);
12236    peer_unref(peer);
12237    return 0;
12238 }

static int iax2_poke_peer ( struct iax2_peer peer,
int  heldcall 
) [static]

Definition at line 12249 of file chan_iax2.c.

References add_empty_calltoken_ie(), iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_del, ast_sockaddr_ipv4(), ast_sockaddr_to_sin, iax_ie_data::buf, iax2_peer::callno, DEFAULT_MAXMS, iax2_peer::dnsmgr, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), iax2_sched_add(), IAX_COMMAND_POKE, iaxs, iaxsl, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, 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().

12250 {
12251    int callno;
12252    struct sockaddr_in peer_addr;
12253 
12254    if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) {
12255       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
12256         immediately after clearing things out */
12257       peer->lastms = 0;
12258       peer->historicms = 0;
12259       peer->pokeexpire = -1;
12260       peer->callno = 0;
12261       return 0;
12262    }
12263 
12264    ast_sockaddr_to_sin(&peer->addr, &peer_addr);
12265 
12266    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
12267    if ((callno = peer->callno) > 0) {
12268       ast_log(LOG_NOTICE, "Still have a callno...\n");
12269       ast_mutex_lock(&iaxsl[callno]);
12270       iax2_destroy(callno);
12271       ast_mutex_unlock(&iaxsl[callno]);
12272    }
12273    if (heldcall)
12274       ast_mutex_unlock(&iaxsl[heldcall]);
12275    callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0);
12276    if (heldcall)
12277       ast_mutex_lock(&iaxsl[heldcall]);
12278    if (peer->callno < 1) {
12279       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
12280       return -1;
12281    }
12282 
12283    /* Speed up retransmission times for this qualify call */
12284    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
12285    iaxs[peer->callno]->peerpoke = peer;
12286 
12287    if (peer->pokeexpire > -1) {
12288       if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
12289          peer->pokeexpire = -1;
12290          peer_unref(peer);
12291       }
12292    }
12293  
12294    /* Queue up a new task to handle no reply */
12295    /* If the host is already unreachable then use the unreachable interval instead */
12296    if (peer->lastms < 0)
12297       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
12298    else
12299       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
12300 
12301    if (peer->pokeexpire == -1)
12302       peer_unref(peer);
12303 
12304    /* And send the poke */
12305    ast_mutex_lock(&iaxsl[callno]);
12306    if (iaxs[callno]) {
12307       struct iax_ie_data ied = {
12308          .buf = { 0 },
12309          .pos = 0,
12310       };
12311       add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
12312       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
12313    }
12314    ast_mutex_unlock(&iaxsl[callno]);
12315 
12316    return 0;
12317 }

static int iax2_poke_peer_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 12240 of file chan_iax2.c.

References iax2_poke_peer().

Referenced by load_module().

12241 {
12242    struct iax2_peer *peer = obj;
12243 
12244    iax2_poke_peer(peer, 0);
12245 
12246    return 0;
12247 }

static int iax2_poke_peer_s ( const void *  data  )  [static]

Definition at line 9228 of file chan_iax2.c.

References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.

Referenced by __iax2_poke_noanswer(), and socket_process().

09229 {
09230    struct iax2_peer *peer = (struct iax2_peer *)data;
09231    peer->pokeexpire = -1;
09232 #ifdef SCHED_MULTITHREADED
09233    if (schedule_action(__iax2_poke_peer_s, data))
09234 #endif      
09235       __iax2_poke_peer_s(data);
09236    return 0;
09237 }

static int iax2_predestroy ( int  callno  )  [static]
Note:
Since this function calls iax2_queue_hangup(), the pvt struct for the given call number may disappear during its execution.

Definition at line 3452 of file chan_iax2.c.

References ast_module_unref(), ast_set_flag64, ast_test_flag64, iax2_destroy_helper(), iax2_queue_hangup(), IAX_ALREADYGONE, iaxs, chan_iax2_pvt::owner, and ast_channel::tech_pvt.

Referenced by iax2_hangup(), and send_command_final().

03453 {
03454    struct ast_channel *c = NULL;
03455    struct chan_iax2_pvt *pvt = iaxs[callno];
03456 
03457    if (!pvt)
03458       return -1;
03459 
03460    if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) {
03461       iax2_destroy_helper(pvt);
03462       ast_set_flag64(pvt, IAX_ALREADYGONE);
03463    }
03464 
03465    if ((c = pvt->owner)) {
03466       c->tech_pvt = NULL;
03467       iax2_queue_hangup(callno);
03468       pvt->owner = NULL;
03469       ast_module_unref(ast_module_info->self);
03470    }
03471 
03472    return 0;
03473 }

static void * iax2_process_thread ( void *  data  )  [static]

Note:
For some reason, idle threads are exiting without being removed from an idle list, which is causing memory corruption. Forcibly remove it from the list, if it's there.

Definition at line 11878 of file chan_iax2.c.

References 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(), 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, insert_idle_thread(), signal_condition(), socket_process(), and thread.

Referenced by find_idle_thread(), and start_network_thread().

11879 {
11880    struct iax2_thread *thread = data;
11881    struct timeval wait;
11882    struct timespec ts;
11883    int put_into_idle = 0;
11884    int first_time = 1;
11885    int old_state;
11886 
11887    ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11888 
11889    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11890    pthread_cleanup_push(iax2_process_thread_cleanup, data);
11891 
11892    for (;;) {
11893       /* Wait for something to signal us to be awake */
11894       ast_mutex_lock(&thread->lock);
11895 
11896       if (thread->stop) {
11897          ast_mutex_unlock(&thread->lock);
11898          break;
11899       }
11900 
11901       /* Flag that we're ready to accept signals */
11902       if (first_time) {
11903          signal_condition(&thread->init_lock, &thread->init_cond);
11904          first_time = 0;
11905       }
11906 
11907       /* Put into idle list if applicable */
11908       if (put_into_idle) {
11909          insert_idle_thread(thread);
11910       }
11911 
11912       if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11913          struct iax2_thread *t = NULL;
11914          /* Wait to be signalled or time out */
11915          wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11916          ts.tv_sec = wait.tv_sec;
11917          ts.tv_nsec = wait.tv_usec * 1000;
11918          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11919             /* This thread was never put back into the available dynamic
11920              * thread list, so just go away. */
11921             if (!put_into_idle || thread->stop) {
11922                ast_mutex_unlock(&thread->lock);
11923                break;
11924             }
11925             AST_LIST_LOCK(&dynamic_list);
11926             /* Account for the case where this thread is acquired *right* after a timeout */
11927             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11928                ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11929             AST_LIST_UNLOCK(&dynamic_list);
11930             if (t) {
11931                /* This dynamic thread timed out waiting for a task and was
11932                 * not acquired immediately after the timeout, 
11933                 * so it's time to go away. */
11934                ast_mutex_unlock(&thread->lock);
11935                break;
11936             }
11937             /* Someone grabbed our thread *right* after we timed out.
11938              * Wait for them to set us up with something to do and signal
11939              * us to continue. */
11940             wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11941             ts.tv_sec = wait.tv_sec;
11942             ts.tv_nsec = wait.tv_usec * 1000;
11943             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11944                ast_mutex_unlock(&thread->lock);
11945                break;
11946             }
11947          }
11948       } else {
11949          ast_cond_wait(&thread->cond, &thread->lock);
11950       }
11951 
11952       /* Go back into our respective list */
11953       put_into_idle = 1;
11954 
11955       ast_mutex_unlock(&thread->lock);
11956 
11957       if (thread->stop) {
11958          break;
11959       }
11960 
11961       /* See what we need to do */
11962       switch (thread->iostate) {
11963       case IAX_IOSTATE_IDLE:
11964          continue;
11965       case IAX_IOSTATE_READY:
11966          thread->actions++;
11967          thread->iostate = IAX_IOSTATE_PROCESSING;
11968          socket_process(thread);
11969          handle_deferred_full_frames(thread);
11970          break;
11971       case IAX_IOSTATE_SCHEDREADY:
11972          thread->actions++;
11973          thread->iostate = IAX_IOSTATE_PROCESSING;
11974 #ifdef SCHED_MULTITHREADED
11975          thread->schedfunc(thread->scheddata);
11976 #endif      
11977          break;
11978       default:
11979          break;
11980       }
11981 
11982       /* The network thread added us to the active_thread list when we were given
11983        * frames to process, Now that we are done, we must remove ourselves from
11984        * the active list, and return to the idle list */
11985       AST_LIST_LOCK(&active_list);
11986       AST_LIST_REMOVE(&active_list, thread, list);
11987       AST_LIST_UNLOCK(&active_list);
11988 
11989       /* Make sure another frame didn't sneak in there after we thought we were done. */
11990       handle_deferred_full_frames(thread);
11991 
11992       time(&thread->checktime);
11993       thread->iostate = IAX_IOSTATE_IDLE;
11994 #ifdef DEBUG_SCHED_MULTITHREAD
11995       thread->curfunc[0]='\0';
11996 #endif
11997    }
11998 
11999    /*!
12000     * \note For some reason, idle threads are exiting without being
12001     * removed from an idle list, which is causing memory
12002     * corruption.  Forcibly remove it from the list, if it's there.
12003     */
12004    AST_LIST_LOCK(&idle_list);
12005    AST_LIST_REMOVE(&idle_list, thread, list);
12006    AST_LIST_UNLOCK(&idle_list);
12007 
12008    AST_LIST_LOCK(&dynamic_list);
12009    AST_LIST_REMOVE(&dynamic_list, thread, list);
12010    AST_LIST_UNLOCK(&dynamic_list);
12011 
12012    if (!thread->stop) {
12013       /* Nobody asked me to stop so nobody is waiting to join me. */
12014       pthread_detach(pthread_self());
12015    }
12016 
12017    /* I am exiting here on my own volition, I need to clean up my own data structures
12018    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
12019    */
12020    pthread_cleanup_pop(1);
12021    return NULL;
12022 }

static void iax2_process_thread_cleanup ( void *  data  )  [static]

Definition at line 11866 of file chan_iax2.c.

References ast_atomic_dec_and_test(), ast_cond_destroy, ast_free, ast_mutex_destroy, iaxactivethreadcount, and thread.

Referenced by iax2_process_thread().

11867 {
11868    struct iax2_thread *thread = data;
11869    ast_mutex_destroy(&thread->lock);
11870    ast_cond_destroy(&thread->cond);
11871    ast_mutex_destroy(&thread->init_lock);
11872    ast_cond_destroy(&thread->init_cond);
11873    ast_free(thread);
11874    /* Ignore check_return warning from Coverity for ast_atomic_dec_and_test below */
11875    ast_atomic_dec_and_test(&iaxactivethreadcount);
11876 }

static int iax2_provision ( struct sockaddr_in *  end,
int  sockfd,
const char *  dest,
const char *  template,
int  force 
) [static]

Definition at line 12085 of file chan_iax2.c.

References ast_debug, AST_FRAME_IAX, ast_mutex_unlock, ast_set_flag64, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, create_addr(), find_callno_locked(), iax2_sched_replace(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), iaxs, iaxsl, NEW_FORCE, iax_ie_data::pos, send_command(), and create_addr_info::sockfd.

Referenced by check_provisioning(), handle_cli_iax2_provision(), and iax2_prov_app().

12086 {
12087    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
12088       is found for template */
12089    struct iax_ie_data provdata;
12090    struct iax_ie_data ied;
12091    unsigned int sig;
12092    struct sockaddr_in sin;
12093    int callno;
12094    struct create_addr_info cai;
12095 
12096    memset(&cai, 0, sizeof(cai));
12097 
12098    ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
12099 
12100    if (iax_provision_build(&provdata, &sig, template, force)) {
12101       ast_debug(1, "No provisioning found for template '%s'\n", template);
12102       return 0;
12103    }
12104 
12105    if (end) {
12106       memcpy(&sin, end, sizeof(sin));
12107       cai.sockfd = sockfd;
12108    } else if (create_addr(dest, NULL, &sin, &cai))
12109       return -1;
12110 
12111    /* Build the rest of the message */
12112    memset(&ied, 0, sizeof(ied));
12113    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
12114 
12115    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12116    if (!callno)
12117       return -1;
12118 
12119    if (iaxs[callno]) {
12120       /* Schedule autodestruct in case they don't ever give us anything back */
12121       iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 
12122          sched, 15000, auto_hangup, (void *)(long)callno);
12123       ast_set_flag64(iaxs[callno], IAX_PROVISION);
12124       /* Got a call number now, so go ahead and send the provisioning information */
12125       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
12126    }
12127    ast_mutex_unlock(&iaxsl[callno]);
12128 
12129    return 1;
12130 }

static int iax2_queryoption ( struct ast_channel c,
int  option,
void *  data,
int *  datalen 
) [static]

Definition at line 5456 of file chan_iax2.c.

References ast_mutex_lock, ast_mutex_unlock, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, ast_test_flag64, chan_iax2_pvt::callno, IAX_FORCE_ENCRYPT, iaxs, iaxsl, PTR_TO_CALLNO, and ast_channel::tech_pvt.

05457 {
05458    switch (option) {
05459    case AST_OPTION_SECURE_SIGNALING:
05460    case AST_OPTION_SECURE_MEDIA:
05461    {
05462       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05463       ast_mutex_lock(&iaxsl[callno]);
05464       *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
05465       ast_mutex_unlock(&iaxsl[callno]);
05466       return 0;
05467    }
05468    default:
05469       return -1;
05470    }
05471 }

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.

Precondition:
Assumes lock for callno is already held.
Note:
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 may unlock and lock the mutex associated with this callno, meaning that another thread may grab it and destroy the call.

Definition at line 3090 of file chan_iax2.c.

References ast_channel_unlock, ast_queue_control_data(), iax2_lock_owner(), and iaxs.

Referenced by socket_process().

03092 {
03093    iax2_lock_owner(callno);
03094    if (iaxs[callno] && iaxs[callno]->owner) {
03095       ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
03096       ast_channel_unlock(iaxs[callno]->owner);
03097    }
03098    return 0;
03099 }

static int iax2_queue_frame ( int  callno,
struct ast_frame f 
) [static]

Queue a frame to a call's owning asterisk channel.

Precondition:
This function assumes that iaxsl[callno] is locked when called.
Note:
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 may unlock and lock the mutex associated with this callno, meaning that another thread may grab it and destroy the call.

Definition at line 3044 of file chan_iax2.c.

References ast_channel_unlock, ast_queue_frame(), iax2_lock_owner(), and iaxs.

Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), __get_from_jb(), and socket_process().

03045 {
03046    iax2_lock_owner(callno);
03047    if (iaxs[callno] && iaxs[callno]->owner) {
03048       ast_queue_frame(iaxs[callno]->owner, f);
03049       ast_channel_unlock(iaxs[callno]->owner);
03050    }
03051    return 0;
03052 }

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.

Precondition:
Assumes lock for callno is already held.
Note:
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 may unlock and lock the mutex associated with this callno, meaning that another thread may grab it and destroy the call.

Definition at line 3067 of file chan_iax2.c.

References ast_channel_unlock, ast_queue_hangup(), iax2_lock_owner(), and iaxs.

Referenced by iax2_predestroy().

03068 {
03069    iax2_lock_owner(callno);
03070    if (iaxs[callno] && iaxs[callno]->owner) {
03071       ast_queue_hangup(iaxs[callno]->owner);
03072       ast_channel_unlock(iaxs[callno]->owner);
03073    }
03074    return 0;
03075 }

static struct ast_frame * iax2_read ( struct ast_channel c  )  [static, read]

Definition at line 5473 of file chan_iax2.c.

References ast_debug, and ast_null_frame.

05474 {
05475    ast_debug(1, "I should never be called!\n");
05476    return &ast_null_frame;
05477 }

static int iax2_register ( const char *  value,
int  lineno 
) [static]

Definition at line 8663 of file chan_iax2.c.

References ast_copy_string(), ast_log(), copy(), hostname, iax2_append_register(), LOG_WARNING, and secret.

Referenced by set_config().

08664 {
08665    char copy[256];
08666    char *username, *hostname, *secret;
08667    char *porta;
08668    char *stringp=NULL;
08669    
08670    if (!value)
08671       return -1;
08672 
08673    ast_copy_string(copy, value, sizeof(copy));
08674    stringp = copy;
08675    username = strsep(&stringp, "@");
08676    hostname = strsep(&stringp, "@");
08677 
08678    if (!hostname) {
08679       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08680       return -1;
08681    }
08682 
08683    stringp = username;
08684    username = strsep(&stringp, ":");
08685    secret = strsep(&stringp, ":");
08686    stringp = hostname;
08687    hostname = strsep(&stringp, ":");
08688    porta = strsep(&stringp, ":");
08689    
08690    if (porta && !atoi(porta)) {
08691       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08692       return -1;
08693    }
08694 
08695    return iax2_append_register(hostname, username, secret, porta);
08696 }

static struct ast_channel * iax2_request ( const char *  type,
format_t  format,
const struct ast_channel requestor,
void *  data,
int *  cause 
) [static, read]

Definition at line 12329 of file chan_iax2.c.

References ast_best_codec(), AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_flags64, ast_getformatname(), ast_hangup(), ast_iax2_new(), ast_log(), ast_mutex_unlock, AST_STATE_DOWN, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_translator_best_choice(), create_addr_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, iaxs, iaxsl, 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.

12330 {
12331    int callno;
12332    int res;
12333    format_t fmt, native;
12334    struct sockaddr_in sin;
12335    struct ast_channel *c;
12336    struct parsed_dial_string pds;
12337    struct create_addr_info cai;
12338    char *tmpstr;
12339 
12340    memset(&pds, 0, sizeof(pds));
12341    tmpstr = ast_strdupa(data);
12342    parse_dial_string(tmpstr, &pds);
12343 
12344    if (ast_strlen_zero(pds.peer)) {
12345       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12346       return NULL;
12347    }
12348           
12349    memset(&cai, 0, sizeof(cai));
12350    cai.capability = iax2_capability;
12351 
12352    ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12353    
12354    /* Populate our address from the given */
12355    if (create_addr(pds.peer, NULL, &sin, &cai)) {
12356       *cause = AST_CAUSE_UNREGISTERED;
12357       return NULL;
12358    }
12359 
12360    if (pds.port)
12361       sin.sin_port = htons(atoi(pds.port));
12362 
12363    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12364    if (callno < 1) {
12365       ast_log(LOG_WARNING, "Unable to create call\n");
12366       *cause = AST_CAUSE_CONGESTION;
12367       return NULL;
12368    }
12369 
12370    /* If this is a trunk, update it now */
12371    ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12372    if (ast_test_flag64(&cai, IAX_TRUNK)) {
12373       int new_callno;
12374       if ((new_callno = make_trunk(callno, 1)) != -1)
12375          callno = new_callno;
12376    }
12377    iaxs[callno]->maxtime = cai.maxtime;
12378    if (cai.found)
12379       ast_string_field_set(iaxs[callno], host, pds.peer);
12380 
12381    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL, cai.found);
12382 
12383    ast_mutex_unlock(&iaxsl[callno]);
12384 
12385    if (c) {
12386       /* Choose a format we can live with */
12387       if (c->nativeformats & format) 
12388          c->nativeformats &= format;
12389       else {
12390          native = c->nativeformats;
12391          fmt = format;
12392          res = ast_translator_best_choice(&fmt, &native);
12393          if (res < 0) {
12394             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12395                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
12396             ast_hangup(c);
12397             return NULL;
12398          }
12399          c->nativeformats = native;
12400       }
12401       c->readformat = ast_best_codec(c->nativeformats);
12402       c->writeformat = c->readformat;
12403    }
12404 
12405    return c;
12406 }

static int iax2_sched_add ( struct ast_sched_thread st,
int  when,
ast_sched_cb  callback,
const void *  data 
) [static]
static int iax2_sched_replace ( int  id,
struct ast_sched_thread st,
int  when,
ast_sched_cb  callback,
const void *  data 
) [static]

Definition at line 1572 of file chan_iax2.c.

References ast_sched_thread_add(), and ast_sched_thread_del.

Referenced by auth_fail(), iax2_ack_registry(), iax2_do_register(), iax2_dprequest(), iax2_provision(), and update_jbsched().

01574 {
01575    ast_sched_thread_del(st, id);
01576 
01577    return ast_sched_thread_add(st, when, callback, data);
01578 }

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 6477 of file chan_iax2.c.

References chan_iax2_pvt::addr, iax_frame::af, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag64, calc_timestamp(), ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, chan_iax2_pvt::callno, iax_frame::callno, ast_frame_subclass::codec, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, 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::frametype, iax2_key_rotate(), iax2_transmit(), iax2_trunk_queue(), IAX_CALLENCRYPTED, IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_outputframe(), IAX_TRUNK, ast_frame_subclass::integer, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::last_iax_message, chan_iax2_pvt::lastsent, 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().

06478 {
06479    /* Queue a packet for delivery on a given private structure.  Use "ts" for
06480       timestamp, or calculate if ts is 0.  Send immediately without retransmission
06481       or delayed, with retransmission */
06482    struct ast_iax2_full_hdr *fh;
06483    struct ast_iax2_mini_hdr *mh;
06484    struct ast_iax2_video_hdr *vh;
06485    struct {
06486       struct iax_frame fr2;
06487       unsigned char buffer[4096];
06488    } frb;
06489    struct iax_frame *fr;
06490    int res;
06491    int sendmini=0;
06492    unsigned int lastsent;
06493    unsigned int fts;
06494 
06495    frb.fr2.afdatalen = sizeof(frb.buffer);
06496 
06497    if (!pvt) {
06498       ast_log(LOG_WARNING, "No private structure for packet?\n");
06499       return -1;
06500    }
06501    
06502    lastsent = pvt->lastsent;
06503 
06504    /* Calculate actual timestamp */
06505    fts = calc_timestamp(pvt, ts, f);
06506 
06507    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
06508     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
06509     * increment the "predicted timestamps" for voice, if we're predicting */
06510    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
06511       return 0;
06512 #if 0
06513    ast_log(LOG_NOTICE, 
06514       "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
06515       *("=!" + (f->frametype == AST_FRAME_VOICE)),
06516       IAX_CALLENCRYPTED(pvt) ? "" : "not ",
06517       pvt->keyrotateid != -1 ? "" : "no "
06518    );
06519 #endif
06520    if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
06521       iax2_key_rotate(pvt);
06522    }
06523 
06524    if ((ast_test_flag64(pvt, IAX_TRUNK) || 
06525          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
06526          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
06527       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
06528        (f->frametype == AST_FRAME_VOICE) 
06529       /* is a voice frame */ &&
06530       (f->subclass.codec == pvt->svoiceformat) 
06531       /* is the same type */ ) {
06532          /* Force immediate rather than delayed transmission */
06533          now = 1;
06534          /* Mark that mini-style frame is appropriate */
06535          sendmini = 1;
06536    }
06537    if ( f->frametype == AST_FRAME_VIDEO ) {
06538       /*
06539        * If the lower 15 bits of the timestamp roll over, or if
06540        * the video format changed then send a full frame.
06541        * Otherwise send a mini video frame
06542        */
06543       if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
06544           ((f->subclass.codec & ~0x1LL) == pvt->svideoformat)
06545          ) {
06546          now = 1;
06547          sendmini = 1;
06548       } else {
06549          now = 0;
06550          sendmini = 0;
06551       }
06552       pvt->lastvsent = fts;
06553    }
06554    if (f->frametype == AST_FRAME_IAX) {
06555       /* 0x8000 marks this message as TX:, this bit will be stripped later */
06556       pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX;
06557       if (!pvt->first_iax_message) {
06558          pvt->first_iax_message = pvt->last_iax_message;
06559       }
06560    }
06561    /* Allocate an iax_frame */
06562    if (now) {
06563       fr = &frb.fr2;
06564    } else
06565       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));
06566    if (!fr) {
06567       ast_log(LOG_WARNING, "Out of memory\n");
06568       return -1;
06569    }
06570    /* Copy our prospective frame into our immediate or retransmitted wrapper */
06571    iax_frame_wrap(fr, f);
06572 
06573    fr->ts = fts;
06574    fr->callno = pvt->callno;
06575    fr->transfer = transfer;
06576    fr->final = final;
06577    fr->encmethods = 0;
06578    if (!sendmini) {
06579       /* We need a full frame */
06580       if (seqno > -1)
06581          fr->oseqno = seqno;
06582       else
06583          fr->oseqno = pvt->oseqno++;
06584       fr->iseqno = pvt->iseqno;
06585       fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
06586       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
06587       fh->ts = htonl(fr->ts);
06588       fh->oseqno = fr->oseqno;
06589       if (transfer) {
06590          fh->iseqno = 0;
06591       } else
06592          fh->iseqno = fr->iseqno;
06593       /* Keep track of the last thing we've acknowledged */
06594       if (!transfer)
06595          pvt->aseqno = fr->iseqno;
06596       fh->type = fr->af.frametype & 0xFF;
06597 
06598       if (fr->af.frametype == AST_FRAME_VIDEO) {
06599          fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6);
06600       } else if (fr->af.frametype == AST_FRAME_VOICE) {
06601          fh->csub = compress_subclass(fr->af.subclass.codec);
06602       } else {
06603          fh->csub = compress_subclass(fr->af.subclass.integer);
06604       }
06605 
06606       if (transfer) {
06607          fr->dcallno = pvt->transfercallno;
06608       } else
06609          fr->dcallno = pvt->peercallno;
06610       fh->dcallno = htons(fr->dcallno);
06611       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
06612       fr->data = fh;
06613       fr->retries = 0;
06614       /* Retry after 2x the ping time has passed */
06615       fr->retrytime = pvt->pingtime * 2;
06616       if (fr->retrytime < MIN_RETRY_TIME)
06617          fr->retrytime = MIN_RETRY_TIME;
06618       if (fr->retrytime > MAX_RETRY_TIME)
06619          fr->retrytime = MAX_RETRY_TIME;
06620       /* Acks' don't get retried */
06621       if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK))
06622          fr->retries = -1;
06623       else if (f->frametype == AST_FRAME_VOICE)
06624          pvt->svoiceformat = f->subclass.codec;
06625       else if (f->frametype == AST_FRAME_VIDEO)
06626          pvt->svideoformat = f->subclass.codec & ~0x1LL;
06627       if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06628          if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06629             if (fr->transfer)
06630                iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06631             else
06632                iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06633             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06634             fr->encmethods = pvt->encmethods;
06635             fr->ecx = pvt->ecx;
06636             fr->mydcx = pvt->mydcx;
06637             memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06638          } else
06639             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06640       }
06641 
06642       if (now) {
06643          res = send_packet(fr);
06644       } else
06645          res = iax2_transmit(fr);
06646    } else {
06647       if (ast_test_flag64(pvt, IAX_TRUNK)) {
06648          iax2_trunk_queue(pvt, fr);
06649          res = 0;
06650       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06651          /* Video frame have no sequence number */
06652          fr->oseqno = -1;
06653          fr->iseqno = -1;
06654          vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06655          vh->zeros = 0;
06656          vh->callno = htons(0x8000 | fr->callno);
06657          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0));
06658          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06659          fr->data = vh;
06660          fr->retries = -1;
06661          res = send_packet(fr);
06662       } else {
06663          /* Mini-frames have no sequence number */
06664          fr->oseqno = -1;
06665          fr->iseqno = -1;
06666          /* Mini frame will do */
06667          mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06668          mh->callno = htons(fr->callno);
06669          mh->ts = htons(fr->ts & 0xFFFF);
06670          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06671          fr->data = mh;
06672          fr->retries = -1;
06673          if (pvt->transferring == TRANSFER_MEDIAPASS)
06674             fr->transfer = 1;
06675          if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06676             if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06677                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06678             } else
06679                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06680          }
06681          res = send_packet(fr);
06682       }
06683    }
06684    return res;
06685 }

static int iax2_sendhtml ( struct ast_channel c,
int  subclass,
const char *  data,
int  datalen 
) [static]

Definition at line 4403 of file chan_iax2.c.

References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.

04404 {
04405    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
04406 }

static int iax2_sendimage ( struct ast_channel c,
struct ast_frame img 
) [static]
static int iax2_sendtext ( struct ast_channel c,
const char *  text 
) [static]

Definition at line 4391 of file chan_iax2.c.

References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.

04392 {
04393    
04394    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
04395       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
04396 }

static int iax2_setoption ( struct ast_channel c,
int  option,
void *  data,
int  datalen 
) [static]

Definition at line 5384 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, iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().

05385 {
05386    struct ast_option_header *h;
05387    int res;
05388 
05389    switch (option) {
05390    case AST_OPTION_TXGAIN:
05391    case AST_OPTION_RXGAIN:
05392       /* these two cannot be sent, because they require a result */
05393       errno = ENOSYS;
05394       return -1;
05395    case AST_OPTION_OPRMODE:
05396       errno = EINVAL;
05397       return -1;
05398    case AST_OPTION_SECURE_SIGNALING:
05399    case AST_OPTION_SECURE_MEDIA:
05400    {
05401       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05402       ast_mutex_lock(&iaxsl[callno]);
05403       if ((*(int *) data)) {
05404          ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05405       } else {
05406          ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05407       }
05408       ast_mutex_unlock(&iaxsl[callno]);
05409       return 0;
05410    }
05411    /* These options are sent to the other side across the network where
05412     * they will be passed to whatever channel is bridged there. Don't
05413     * do anything silly like pass an option that transmits pointers to
05414     * memory on this machine to a remote machine to use */
05415    case AST_OPTION_TONE_VERIFY:
05416    case AST_OPTION_TDD:
05417    case AST_OPTION_RELAXDTMF:
05418    case AST_OPTION_AUDIO_MODE:
05419    case AST_OPTION_DIGIT_DETECT:
05420    case AST_OPTION_FAX_DETECT:
05421    {
05422       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05423       struct chan_iax2_pvt *pvt;
05424 
05425       ast_mutex_lock(&iaxsl[callno]);
05426       pvt = iaxs[callno];
05427 
05428       if (wait_for_peercallno(pvt)) {
05429          ast_mutex_unlock(&iaxsl[callno]);
05430          return -1;
05431       }
05432 
05433       ast_mutex_unlock(&iaxsl[callno]);
05434 
05435       if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05436          return -1;
05437       }
05438 
05439       h->flag = AST_OPTION_FLAG_REQUEST;
05440       h->option = htons(option);
05441       memcpy(h->data, data, datalen);
05442       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05443                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
05444                  datalen + sizeof(*h), -1);
05445       ast_free(h);
05446       return res;
05447    }
05448    default:
05449       return -1;
05450    }
05451 
05452    /* Just in case someone does a break instead of a return */
05453    return -1;
05454 }

static int iax2_start_transfer ( unsigned short  callno0,
unsigned short  callno1,
int  mediaonly 
) [static]

Definition at line 5512 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, iaxs, iax_ie_data::pos, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.

Referenced by iax2_bridge().

05513 {
05514    int res;
05515    struct iax_ie_data ied0;
05516    struct iax_ie_data ied1;
05517    unsigned int transferid = (unsigned int)ast_random();
05518 
05519    if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05520       ast_debug(1, "transfers are not supported for encrypted calls at this time\n");
05521       ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER);
05522       ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER);
05523       return 0;
05524    }
05525 
05526    memset(&ied0, 0, sizeof(ied0));
05527    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05528    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05529    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05530 
05531    memset(&ied1, 0, sizeof(ied1));
05532    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05533    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05534    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05535    
05536    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05537    if (res)
05538       return -1;
05539    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05540    if (res)
05541       return -1;
05542    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05543    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05544    return 0;
05545 }

static int iax2_transfer ( struct ast_channel c,
const char *  dest 
) [static]

Definition at line 5792 of file chan_iax2.c.

References 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.

05793 {
05794    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05795    struct iax_ie_data ied = { "", };
05796    char tmp[256], *context;
05797    enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
05798    ast_copy_string(tmp, dest, sizeof(tmp));
05799    context = strchr(tmp, '@');
05800    if (context) {
05801       *context = '\0';
05802       context++;
05803    }
05804    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05805    if (context)
05806       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05807    ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05808    ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message));
05809    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05810 }

static int iax2_transmit ( struct iax_frame fr  )  [static]

Definition at line 4374 of file chan_iax2.c.

References ast_taskprocessor_push(), iax_frame::sentyet, and transmit_frame().

Referenced by iax2_send().

04375 {
04376    fr->sentyet = 0;
04377 
04378    return ast_taskprocessor_push(transmit_processor, transmit_frame, fr);
04379 }

static int iax2_trunk_expired ( struct iax2_trunk_peer tpeer,
struct timeval *  now 
) [inline, static]

Definition at line 9282 of file chan_iax2.c.

References iax2_trunk_peer::trunkact.

Referenced by timing_read().

09283 {
09284    /* Drop when trunk is about 5 seconds idle */
09285    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
09286       return 1;
09287    return 0;
09288 }

static int iax2_trunk_queue ( struct chan_iax2_pvt pvt,
struct iax_frame fr 
) [static]

Definition at line 6217 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().

06218 {
06219    struct ast_frame *f;
06220    struct iax2_trunk_peer *tpeer;
06221    void *tmp, *ptr;
06222    struct timeval now;
06223    struct ast_iax2_meta_trunk_entry *met;
06224    struct ast_iax2_meta_trunk_mini *mtm;
06225 
06226    f = &fr->af;
06227    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
06228    if (tpeer) {
06229       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
06230          /* Need to reallocate space */
06231          if (tpeer->trunkdataalloc < trunkmaxsize) {
06232             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
06233                ast_mutex_unlock(&tpeer->lock);
06234                return -1;
06235             }
06236             
06237             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
06238             tpeer->trunkdata = tmp;
06239             ast_debug(1, "Expanded trunk '%s:%d' to %u bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc);
06240          } else {
06241             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));
06242             ast_mutex_unlock(&tpeer->lock);
06243             return -1;
06244          }
06245       }
06246 
06247       /* Append to meta frame */
06248       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
06249       if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) {
06250          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06251          mtm->len = htons(f->datalen);
06252          mtm->mini.callno = htons(pvt->callno);
06253          mtm->mini.ts = htons(0xffff & fr->ts);
06254          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
06255          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
06256       } else {
06257          met = (struct ast_iax2_meta_trunk_entry *)ptr;
06258          /* Store call number and length in meta header */
06259          met->callno = htons(pvt->callno);
06260          met->len = htons(f->datalen);
06261          /* Advance pointers/decrease length past trunk entry header */
06262          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
06263          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
06264       }
06265       /* Copy actual trunk data */
06266       memcpy(ptr, f->data.ptr, f->datalen);
06267       tpeer->trunkdatalen += f->datalen;
06268 
06269       tpeer->calls++;
06270 
06271       /* track the largest mtu we actually have sent */
06272       if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 
06273          trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 
06274 
06275       /* if we have enough for a full MTU, ship it now without waiting */
06276       if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
06277          now = ast_tvnow();
06278          send_trunk(tpeer, &now); 
06279          trunk_untimed ++; 
06280       }
06281 
06282       ast_mutex_unlock(&tpeer->lock);
06283    }
06284    return 0;
06285 }

static int iax2_vnak ( int  callno  )  [static]

Definition at line 9203 of file chan_iax2.c.

References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().

Referenced by socket_process(), and socket_process_meta().

09204 {
09205    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
09206 }

static int iax2_write ( struct ast_channel c,
struct ast_frame f 
) [static]

Definition at line 7564 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, iaxs, iaxsl, PTR_TO_CALLNO, and ast_channel::tech_pvt.

07565 {
07566    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07567    int res = -1;
07568    ast_mutex_lock(&iaxsl[callno]);
07569    if (iaxs[callno]) {
07570    /* If there's an outstanding error, return failure now */
07571       if (!iaxs[callno]->error) {
07572          if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
07573             res = 0;
07574             /* Don't waste bandwidth sending null frames */
07575          else if (f->frametype == AST_FRAME_NULL)
07576             res = 0;
07577          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
07578             res = 0;
07579          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07580             res = 0;
07581          else
07582          /* Simple, just queue for transmission */
07583             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07584       } else {
07585          ast_debug(1, "Write error: %s\n", strerror(errno));
07586       }
07587    }
07588    /* If it's already gone, just return */
07589    ast_mutex_unlock(&iaxsl[callno]);
07590    return res;
07591 }

static int iax_check_version ( char *  dev  )  [static]

Definition at line 3246 of file chan_iax2.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strlen_zero().

Referenced by update_registry().

03247 {
03248    int res = 0;
03249    struct iax_firmware *cur = NULL;
03250 
03251    if (ast_strlen_zero(dev))
03252       return 0;
03253 
03254    AST_LIST_LOCK(&firmwares);
03255    AST_LIST_TRAVERSE(&firmwares, cur, list) {
03256       if (!strcmp(dev, (char *)cur->fwh->devname)) {
03257          res = ntohs(cur->fwh->version);
03258          break;
03259       }
03260    }
03261    AST_LIST_UNLOCK(&firmwares);
03262 
03263    return res;
03264 }

static void iax_debug_output ( const char *  data  )  [static]

Definition at line 1120 of file chan_iax2.c.

References ast_verbose.

Referenced by load_module().

01121 {
01122    if (iaxdebug)
01123       ast_verbose("%s", data);
01124 }

static void iax_error_output ( const char *  data  )  [static]

Definition at line 1126 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by load_module().

01127 {
01128    ast_log(LOG_WARNING, "%s", data);
01129 }

static int iax_firmware_append ( struct iax_ie_data ied,
const unsigned char *  dev,
unsigned int  desc 
) [static]

Definition at line 3266 of file chan_iax2.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), iax_ie_append(), iax_ie_append_int(), iax_ie_append_raw(), IAX_IE_FWBLOCKDATA, and IAX_IE_FWBLOCKDESC.

Referenced by socket_process().

03267 {
03268    int res = -1;
03269    unsigned int bs = desc & 0xff;
03270    unsigned int start = (desc >> 8) & 0xffffff;
03271    unsigned int bytes;
03272    struct iax_firmware *cur;
03273 
03274    if (ast_strlen_zero((char *)dev) || !bs)
03275       return -1;
03276 
03277    start *= bs;
03278    
03279    AST_LIST_LOCK(&firmwares);
03280    AST_LIST_TRAVERSE(&firmwares, cur, list) {
03281       if (strcmp((char *)dev, (char *)cur->fwh->devname))
03282          continue;
03283       iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
03284       if (start < ntohl(cur->fwh->datalen)) {
03285          bytes = ntohl(cur->fwh->datalen) - start;
03286          if (bytes > bs)
03287             bytes = bs;
03288          iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
03289       } else {
03290          bytes = 0;
03291          iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
03292       }
03293       if (bytes == bs)
03294          res = 0;
03295       else
03296          res = 1;
03297       break;
03298    }
03299    AST_LIST_UNLOCK(&firmwares);
03300 
03301    return res;
03302 }

static void iax_outputframe ( struct iax_frame f,
struct ast_iax2_full_hdr fhi,
int  rx,
struct sockaddr_in *  sin,
int  datalen 
) [static]

Definition at line 1103 of file chan_iax2.c.

References debugaddr, and iax_showframe().

Referenced by iax2_send(), raw_hangup(), send_apathetic_reply(), send_packet(), and socket_process().

01104 {
01105    if (iaxdebug ||
01106        (sin && debugaddr.sin_addr.s_addr && 
01107         (!ntohs(debugaddr.sin_port) ||
01108          debugaddr.sin_port == sin->sin_port) &&
01109         debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
01110       if (iaxdebug) {
01111          iax_showframe(f, fhi, rx, sin, datalen);
01112       } else {
01113          iaxdebug = 1;
01114          iax_showframe(f, fhi, rx, sin, datalen);
01115          iaxdebug = 0;
01116       }
01117    }
01118 }

static int iax_park ( struct ast_channel chan1,
struct ast_channel chan2,
const char *  park_exten,
const char *  park_context 
) [static]

DO NOT hold any locks while calling iax_park

Definition at line 9456 of file chan_iax2.c.

References ast_channel::amaflags, ast_calloc, ast_channel_alloc, ast_channel_masquerade(), ast_copy_string(), ast_do_masquerade(), ast_free, ast_hangup(), ast_pthread_create_detached_background, AST_STATE_DOWN, ast_strdup, ast_string_field_set, iax_dual::chan1, iax_dual::chan2, ast_channel::context, ast_channel::exten, iax_park_thread(), iax_dual::park_context, iax_dual::park_exten, parkinglot, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.

Referenced by socket_process().

09457 {
09458    struct iax_dual *d;
09459    struct ast_channel *chan1m, *chan2m;/* Chan2m: The transferer, chan1m: The transferee */
09460    pthread_t th;
09461 
09462    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
09463    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name);
09464    d = ast_calloc(1, sizeof(*d));
09465    if (!chan1m || !chan2m || !d) {
09466       if (chan1m) {
09467          ast_hangup(chan1m);
09468       }
09469       if (chan2m) {
09470          ast_hangup(chan2m);
09471       }
09472       ast_free(d);
09473       return -1;
09474    }
09475    d->park_exten = ast_strdup(park_exten);
09476    d->park_context = ast_strdup(park_context);
09477    if (!d->park_exten || !d->park_context) {
09478       ast_hangup(chan1m);
09479       ast_hangup(chan2m);
09480       ast_free(d->park_exten);
09481       ast_free(d->park_context);
09482       ast_free(d);
09483       return -1;
09484    }
09485 
09486    /* Make formats okay */
09487    chan1m->readformat = chan1->readformat;
09488    chan1m->writeformat = chan1->writeformat;
09489 
09490    /* Prepare for taking over the channel */
09491    if (ast_channel_masquerade(chan1m, chan1)) {
09492       ast_hangup(chan1m);
09493       ast_hangup(chan2m);
09494       ast_free(d->park_exten);
09495       ast_free(d->park_context);
09496       ast_free(d);
09497       return -1;
09498    }
09499 
09500    /* Setup the extensions and such */
09501    ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
09502    ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
09503    chan1m->priority = chan1->priority;
09504 
09505    ast_do_masquerade(chan1m);
09506 
09507    /* We make a clone of the peer channel too, so we can play
09508       back the announcement */
09509 
09510    /* Make formats okay */
09511    chan2m->readformat = chan2->readformat;
09512    chan2m->writeformat = chan2->writeformat;
09513    ast_string_field_set(chan2m, parkinglot, chan2->parkinglot);
09514 
09515    /* Prepare for taking over the channel */
09516    if (ast_channel_masquerade(chan2m, chan2)) {
09517       ast_hangup(chan1m);
09518       ast_hangup(chan2m);
09519       ast_free(d->park_exten);
09520       ast_free(d->park_context);
09521       ast_free(d);
09522       return -1;
09523    }
09524 
09525    /* Setup the extensions and such */
09526    ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09527    ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09528    chan2m->priority = chan2->priority;
09529 
09530    ast_do_masquerade(chan2m);
09531 
09532    d->chan1 = chan1m;   /* Transferee */
09533    d->chan2 = chan2m;   /* Transferer */
09534    if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) {
09535       /* Could not start thread */
09536       ast_hangup(chan1m);
09537       ast_hangup(chan2m);
09538       ast_free(d->park_exten);
09539       ast_free(d->park_context);
09540       ast_free(d);
09541       return -1;
09542    }
09543    return 0;
09544 }

static void* iax_park_thread ( void *  stuff  )  [static]

Definition at line 9429 of file chan_iax2.c.

References ast_debug, ast_free, ast_hangup(), ast_log(), ast_park_call_exten(), iax_dual::chan1, iax_dual::chan2, ext, LOG_NOTICE, iax_dual::park_context, and iax_dual::park_exten.

Referenced by iax_park().

09430 {
09431    struct iax_dual *d;
09432    int res;
09433    int ext = 0;
09434 
09435    d = stuff;
09436 
09437    ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n",
09438       d->chan2->name, d->chan1->name);
09439 
09440    res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext);
09441    if (res) {
09442       /* Parking failed. */
09443       ast_hangup(d->chan1);
09444    } else {
09445       ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
09446    }
09447    ast_hangup(d->chan2);
09448 
09449    ast_free(d->park_exten);
09450    ast_free(d->park_context);
09451    ast_free(d);
09452    return NULL;
09453 }

static struct iax_frame* iaxfrdup2 ( struct iax_frame fr  )  [static, read]

Definition at line 2040 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().

02041 {
02042    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
02043    if (new) {
02044       size_t afdatalen = new->afdatalen;
02045       memcpy(new, fr, sizeof(*new));
02046       iax_frame_wrap(new, &fr->af);
02047       new->afdatalen = afdatalen;
02048       new->data = NULL;
02049       new->datalen = 0;
02050       new->direction = DIRECTION_INGRESS;
02051       new->retrans = -1;
02052    }
02053    return new;
02054 }

static void insert_idle_thread ( struct iax2_thread thread  )  [static]

Definition at line 1462 of file chan_iax2.c.

References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, and IAX_THREAD_TYPE_DYNAMIC.

Referenced by iax2_process_thread().

01463 {
01464    if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01465       AST_LIST_LOCK(&dynamic_list);
01466       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01467       AST_LIST_UNLOCK(&dynamic_list);
01468    } else {
01469       AST_LIST_LOCK(&idle_list);
01470       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01471       AST_LIST_UNLOCK(&idle_list);
01472    }
01473 
01474    return;
01475 }

static void jb_debug_output ( const char *  fmt,
  ... 
) [static]

Definition at line 1155 of file chan_iax2.c.

References args, and ast_verbose.

Referenced by handle_cli_iax2_set_debug_jb().

01156 {
01157    va_list args;
01158    char buf[1024];
01159 
01160    va_start(args, fmt);
01161    vsnprintf(buf, sizeof(buf), fmt, args);
01162    va_end(args);
01163 
01164    ast_verbose("%s", buf);
01165 }

static void jb_error_output ( const char *  fmt,
  ... 
) [static]

Definition at line 1131 of file chan_iax2.c.

References args, ast_log(), and LOG_ERROR.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

01132 {
01133    va_list args;
01134    char buf[1024];
01135 
01136    va_start(args, fmt);
01137    vsnprintf(buf, sizeof(buf), fmt, args);
01138    va_end(args);
01139 
01140    ast_log(LOG_ERROR, "%s", buf);
01141 }

static void jb_warning_output ( const char *  fmt,
  ... 
) [static]

Definition at line 1143 of file chan_iax2.c.

References args, ast_log(), and LOG_WARNING.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

01144 {
01145    va_list args;
01146    char buf[1024];
01147 
01148    va_start(args, fmt);
01149    vsnprintf(buf, sizeof(buf), fmt, args);
01150    va_end(args);
01151 
01152    ast_log(LOG_WARNING, "%s", buf);
01153 }

static int load_module ( void   )  [static]

Load IAX2 module, load configuraiton ---.

Definition at line 14949 of file chan_iax2.c.

References __unload_module(), ao2_callback, ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register, ast_data_register_multiple, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_mutex_init, ast_netsock_init(), ast_netsock_list_alloc(), ast_random(), ast_realtime_require_field(), ast_register_application_xml, ast_register_switch(), ast_sched_thread_create(), ast_sched_thread_destroy(), AST_TEST_REGISTER, ast_timer_close(), ast_timer_open(), ast_timer_set_rate(), ast_verb, cli_iax2, config, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, iax2_data_providers, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), iax_error_output(), iax_provision_reload(), iax_set_error(), iax_set_output(), iaxpeer_function, iaxs, iaxsl, iaxvar_function, io_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(), papp, peer_set_sock_cb(), reload_firmware(), RQ_CHAR, RQ_UINTEGER2, SENTINEL, set_config(), and start_network_thread().

14950 {
14951    static const char config[] = "iax.conf";
14952    int x = 0;
14953    struct iax2_registry *reg = NULL;
14954 
14955    if (load_objects()) {
14956       return AST_MODULE_LOAD_FAILURE;
14957    }
14958 
14959    memset(iaxs, 0, sizeof(iaxs));
14960 
14961    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14962       ast_mutex_init(&iaxsl[x]);
14963    }
14964 
14965    if (!(sched = ast_sched_thread_create())) {
14966       ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14967       return AST_MODULE_LOAD_FAILURE;
14968    }
14969 
14970    if (!(io = io_context_create())) {
14971       ast_log(LOG_ERROR, "Failed to create I/O context\n");
14972       sched = ast_sched_thread_destroy(sched);
14973       return AST_MODULE_LOAD_FAILURE;
14974    }
14975 
14976    if (!(netsock = ast_netsock_list_alloc())) {
14977       ast_log(LOG_ERROR, "Failed to create netsock list\n");
14978       io_context_destroy(io);
14979       sched = ast_sched_thread_destroy(sched);
14980       return AST_MODULE_LOAD_FAILURE;
14981    }
14982    ast_netsock_init(netsock);
14983    
14984    outsock = ast_netsock_list_alloc();
14985    if (!outsock) {
14986       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14987       io_context_destroy(io);
14988       sched = ast_sched_thread_destroy(sched);
14989       return AST_MODULE_LOAD_FAILURE;
14990    }
14991    ast_netsock_init(outsock);
14992 
14993    randomcalltokendata = ast_random();
14994 
14995    iax_set_output(iax_debug_output);
14996    iax_set_error(iax_error_output);
14997    jb_setoutput(jb_error_output, jb_warning_output, NULL);
14998    
14999    if ((timer = ast_timer_open())) {
15000       ast_timer_set_rate(timer, 1000 / trunkfreq);
15001    }
15002 
15003    if (set_config(config, 0) == -1) {
15004       if (timer) {
15005          ast_timer_close(timer);
15006          timer = NULL;
15007       }
15008       return AST_MODULE_LOAD_DECLINE;
15009    }
15010 
15011 #ifdef TEST_FRAMEWORK
15012    AST_TEST_REGISTER(test_iax2_peers_get);
15013    AST_TEST_REGISTER(test_iax2_users_get);
15014 #endif
15015 
15016    /* Register AstData providers */
15017    ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers));
15018    ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
15019 
15020    ast_register_application_xml(papp, iax2_prov_app);
15021 
15022    ast_custom_function_register(&iaxpeer_function);
15023    ast_custom_function_register(&iaxvar_function);
15024 
15025    ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers);
15026    ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list);
15027    ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats);
15028    ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry);
15029 
15030    if (ast_channel_register(&iax2_tech)) {
15031       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
15032       __unload_module();
15033       return AST_MODULE_LOAD_FAILURE;
15034    }
15035 
15036    if (ast_register_switch(&iax2_switch)) {
15037       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
15038    }
15039 
15040    if (start_network_thread()) {
15041       ast_log(LOG_ERROR, "Unable to start network thread\n");
15042       __unload_module();
15043       return AST_MODULE_LOAD_FAILURE;
15044    } else {
15045       ast_verb(2, "IAX Ready and Listening\n");
15046    }
15047 
15048    AST_LIST_LOCK(&registrations);
15049    AST_LIST_TRAVERSE(&registrations, reg, entry)
15050       iax2_do_register(reg);
15051    AST_LIST_UNLOCK(&registrations); 
15052    
15053    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
15054    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
15055 
15056 
15057    reload_firmware(0);
15058    iax_provision_reload(0);
15059 
15060    ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
15061 
15062    network_change_event_subscribe();
15063 
15064    return AST_MODULE_LOAD_SUCCESS;
15065 }

static int load_objects ( void   )  [static]

Definition at line 14711 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(), iax_peercallno_pvts, iax_transfercallno_pvts, 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().

14712 {
14713    peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
14714    peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
14715 
14716    if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
14717       goto container_fail;
14718    } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
14719       goto container_fail;
14720    } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
14721       goto container_fail;
14722    } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
14723       goto container_fail;
14724    } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
14725       goto container_fail;
14726    } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14727       goto container_fail;
14728    } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14729       goto container_fail;
14730    } else if (create_callno_pools()) {
14731       goto container_fail;
14732    } else if  (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) {
14733       goto container_fail;
14734    }
14735 
14736    return 0;
14737 
14738 container_fail:
14739    if (peers) {
14740       ao2_ref(peers, -1);
14741    }
14742    if (users) {
14743       ao2_ref(users, -1);
14744    }
14745    if (iax_peercallno_pvts) {
14746       ao2_ref(iax_peercallno_pvts, -1);
14747    }
14748    if (iax_transfercallno_pvts) {
14749       ao2_ref(iax_transfercallno_pvts, -1);
14750    }
14751    if (peercnts) {
14752       ao2_ref(peercnts, -1);
14753    }
14754    if (callno_limits) {
14755       ao2_ref(callno_limits, -1);
14756    }
14757    if (calltoken_ignores) {
14758       ao2_ref(calltoken_ignores, -1);
14759    }
14760    if (callno_pool) {
14761       ao2_ref(callno_pool, -1);
14762    }
14763    if (callno_pool_trunk) {
14764       ao2_ref(callno_pool_trunk, -1);
14765    }
14766    return AST_MODULE_LOAD_FAILURE;
14767 }

static void lock_both ( unsigned short  callno0,
unsigned short  callno1 
) [static]

Definition at line 5547 of file chan_iax2.c.

References ast_mutex_lock, ast_mutex_trylock, DEADLOCK_AVOIDANCE, and iaxsl.

Referenced by iax2_bridge().

05548 {
05549    ast_mutex_lock(&iaxsl[callno0]);
05550    while (ast_mutex_trylock(&iaxsl[callno1])) {
05551       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05552    }
05553 }

static void log_jitterstats ( unsigned short  callno  )  [static]

Definition at line 9616 of file chan_iax2.c.

References ast_debug, ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, jb_info::current, EVENT_FLAG_REPORTING, jb_info::frames_dropped, jb_info::frames_in, jb_info::frames_lost, jb_info::frames_ooo, IAX_USEJITTERBUF, iaxs, iaxsl, ast_channel::jb, jb_getinfo(), jb_info::jitter, jb_info::losspct, manager_event, jb_info::min, and chan_iax2_pvt::pingtime.

Referenced by socket_process().

09617 {
09618    int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09619    jb_info jbinfo;
09620 
09621    ast_mutex_lock(&iaxsl[callno]);
09622    if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09623       if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
09624          jb_getinfo(iaxs[callno]->jb, &jbinfo);
09625          localjitter = jbinfo.jitter;
09626          localdelay = jbinfo.current - jbinfo.min;
09627          locallost = jbinfo.frames_lost;
09628          locallosspct = jbinfo.losspct/1000;
09629          localdropped = jbinfo.frames_dropped;
09630          localooo = jbinfo.frames_ooo;
09631          localpackets = jbinfo.frames_in;
09632       }
09633       ast_debug(3, "JB STATS:%s ping=%u 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",
09634          iaxs[callno]->owner->name,
09635          iaxs[callno]->pingtime,
09636          localjitter,
09637          localdelay,
09638          locallost,
09639          locallosspct,
09640          localdropped,
09641          localooo,
09642          localpackets,
09643          iaxs[callno]->remote_rr.jitter,
09644          iaxs[callno]->remote_rr.delay,
09645          iaxs[callno]->remote_rr.losscnt,
09646          iaxs[callno]->remote_rr.losspct/1000,
09647          iaxs[callno]->remote_rr.dropped,
09648          iaxs[callno]->remote_rr.ooo,
09649          iaxs[callno]->remote_rr.packets);
09650       manager_event(EVENT_FLAG_REPORTING, "JitterBufStats", "Owner: %s\r\nPing: %u\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",
09651          iaxs[callno]->owner->name,
09652          iaxs[callno]->pingtime,
09653          localjitter,
09654          localdelay,
09655          locallost,
09656          locallosspct,
09657          localdropped,
09658          localooo,
09659          localpackets,
09660          iaxs[callno]->remote_rr.jitter,
09661          iaxs[callno]->remote_rr.delay,
09662          iaxs[callno]->remote_rr.losscnt,
09663          iaxs[callno]->remote_rr.losspct/1000,
09664          iaxs[callno]->remote_rr.dropped,
09665          iaxs[callno]->remote_rr.ooo,
09666          iaxs[callno]->remote_rr.packets);
09667    }
09668    ast_mutex_unlock(&iaxsl[callno]);
09669 }

static int make_trunk ( unsigned short  callno,
int  locked 
) [static]

Note:
We delete these before switching the slot, because if they fire in the meantime, they will generate a warning.

Definition at line 2135 of file chan_iax2.c.

References ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_del, chan_iax2_pvt::callno, callno_entry::callno, chan_iax2_pvt::callno_entry, get_unused_callno(), iax2_sched_add(), iaxs, iaxsl, chan_iax2_pvt::lagid, LOG_WARNING, MIN_REUSE_TIME, chan_iax2_pvt::pingid, replace_callno(), send_lagrq(), send_ping(), update_max_nontrunk, update_max_trunk, and callno_entry::validated.

Referenced by iax2_request(), and socket_process().

02136 {
02137    int x;
02138    int res= 0;
02139    struct callno_entry *callno_entry;
02140    if (iaxs[callno]->oseqno) {
02141       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
02142       return -1;
02143    }
02144    if (callno >= TRUNK_CALL_START) {
02145       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
02146       return -1;
02147    }
02148 
02149    if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
02150       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
02151       return -1;
02152    }
02153 
02154    x = callno_entry->callno;
02155    ast_mutex_lock(&iaxsl[x]);
02156 
02157    /*!
02158     * \note We delete these before switching the slot, because if
02159     * they fire in the meantime, they will generate a warning.
02160     */
02161    ast_sched_thread_del(sched, iaxs[callno]->pingid);
02162    ast_sched_thread_del(sched, iaxs[callno]->lagid);
02163    iaxs[callno]->lagid = iaxs[callno]->pingid = -1;
02164    iaxs[x] = iaxs[callno];
02165    iaxs[x]->callno = x;
02166 
02167    /* since we copied over the pvt from a different callno, make sure the old entry is replaced
02168     * before assigning the new one */
02169    if (iaxs[x]->callno_entry) {
02170       iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
02171    }
02172    iaxs[x]->callno_entry = callno_entry;
02173 
02174    iaxs[callno] = NULL;
02175    /* Update the two timers that should have been started */
02176    iaxs[x]->pingid = iax2_sched_add(sched, 
02177       ping_time * 1000, send_ping, (void *)(long)x);
02178    iaxs[x]->lagid = iax2_sched_add(sched, 
02179       lagrq_time * 1000, send_lagrq, (void *)(long)x);
02180 
02181    if (locked)
02182       ast_mutex_unlock(&iaxsl[callno]);
02183    res = x;
02184    if (!locked)
02185       ast_mutex_unlock(&iaxsl[x]);
02186 
02187    ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
02188    /* We move this call from a non-trunked to a trunked call */
02189    update_max_trunk();
02190    update_max_nontrunk();
02191    return res;
02192 }

static int manager_iax2_show_netstats ( struct mansession s,
const struct message m 
) [static]

Definition at line 7059 of file chan_iax2.c.

References ast_cli_netstats(), astman_append(), and RESULT_SUCCESS.

Referenced by load_module().

07060 {
07061    ast_cli_netstats(s, -1, 0);
07062    astman_append(s, "\r\n");
07063    return RESULT_SUCCESS;
07064 }

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 7122 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, peer_status(), peer_unref(), RESULT_SUCCESS, and status.

Referenced by load_module().

07123 {
07124    struct iax2_peer *peer = NULL;
07125    int peer_count = 0;
07126    char nm[20];
07127    char status[20];
07128    const char *id = astman_get_header(m,"ActionID");
07129    char idtext[256] = "";
07130    struct ast_str *encmethods = ast_str_alloca(256);
07131    struct ao2_iterator i;
07132 
07133    if (!ast_strlen_zero(id))
07134       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07135 
07136    astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
07137 
07138 
07139    i = ao2_iterator_init(peers, 0);
07140    for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
07141       encmethods_to_str(peer->encmethods, &encmethods);
07142       astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
07143       if (!ast_strlen_zero(peer->username)) {
07144          astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
07145       } else {
07146          astman_append(s, "ObjectName: %s\r\n", peer->name);
07147       }
07148       astman_append(s, "ChanObjectType: peer\r\n");
07149       astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr));
07150       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
07151       astman_append(s, "Mask: %s\r\n", nm);
07152       astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr));
07153       astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
07154       astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
07155       astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
07156       peer_status(peer, status, sizeof(status));
07157       astman_append(s, "Status: %s\r\n\r\n", status);
07158       peer_count++;
07159    }
07160    ao2_iterator_destroy(&i);
07161 
07162    astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
07163    return RESULT_SUCCESS;
07164 }

static int manager_iax2_show_peers ( struct mansession s,
const struct message m 
) [static]

callback to display iax peers in manager

Definition at line 7098 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().

07099 {
07100    static const char * const a[] = { "iax2", "show", "peers" };
07101    const char *id = astman_get_header(m,"ActionID");
07102    char idtext[256] = "";
07103    int total = 0;
07104 
07105    if (!ast_strlen_zero(id))
07106       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07107 
07108    astman_send_listack(s, m, "Peer status list will follow", "start");
07109         /* List the peers in separate manager events */
07110    __iax2_show_peers(-1, &total, s, 3, a);
07111         /* Send final confirmation */
07112         astman_append(s,
07113         "Event: PeerlistComplete\r\n"
07114         "EventList: Complete\r\n"
07115         "ListItems: %d\r\n"
07116         "%s"
07117         "\r\n", total, idtext);
07118         return 0;
07119 }

static int manager_iax2_show_registry ( struct mansession s,
const struct message m 
) [static]

Definition at line 7230 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().

07231 {
07232    const char *id = astman_get_header(m, "ActionID");
07233    struct iax2_registry *reg = NULL;
07234    char idtext[256] = "";
07235    char host[80] = "";
07236    char perceived[80] = "";
07237    int total = 0;
07238 
07239    if (!ast_strlen_zero(id))
07240       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07241 
07242    astman_send_listack(s, m, "Registrations will follow", "start");
07243 
07244    AST_LIST_LOCK(&registrations);
07245    AST_LIST_TRAVERSE(&registrations, reg, entry) {
07246       snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(&reg->addr));
07247       
07248       if (reg->us.sin_addr.s_addr) {
07249          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07250       } else {
07251          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07252       }
07253       
07254       astman_append(s,
07255          "Event: RegistryEntry\r\n"
07256          "%s"
07257          "Host: %s\r\n"
07258          "DNSmanager: %s\r\n"
07259          "Username: %s\r\n"
07260          "Perceived: %s\r\n"
07261          "Refresh: %d\r\n"
07262          "State: %s\r\n"
07263          "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, 
07264          reg->refresh, regstate2str(reg->regstate));
07265 
07266       total++;
07267    }
07268    AST_LIST_UNLOCK(&registrations);
07269 
07270    astman_append(s,
07271       "Event: RegistrationsComplete\r\n"
07272       "EventList: Complete\r\n"
07273       "ListItems: %d\r\n"
07274       "%s"
07275       "\r\n", total, idtext);
07276    
07277    return 0;
07278 }

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 2069 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(), transfercallno_pvt_cmp_cb(), and xmldoc_attribute_match().

02070 {
02071    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
02072       (cur->addr.sin_port == sin->sin_port)) {
02073       /* This is the main host */
02074       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
02075           (check_dcallno ? dcallno == cur->callno : 1) ) {
02076          /* That's us.  Be sure we keep track of the peer call number */
02077          return 1;
02078       }
02079    }
02080    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
02081        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
02082       /* We're transferring */
02083       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
02084          return 1;
02085    }
02086    return 0;
02087 }

static void memcpy_decrypt ( unsigned char *  dst,
const unsigned char *  src,
int  len,
ast_aes_decrypt_key dcx 
) [static]

Definition at line 6315 of file chan_iax2.c.

References ast_aes_decrypt(), ast_log(), and LOG_WARNING.

Referenced by decode_frame().

06316 {
06317 #if 0
06318    /* Debug with "fake encryption" */
06319    int x;
06320    if (len % 16)
06321       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06322    for (x=0;x<len;x++)
06323       dst[x] = src[x] ^ 0xff;
06324 #else 
06325    unsigned char lastblock[16] = { 0 };
06326    int x;
06327    while(len > 0) {
06328       ast_aes_decrypt(src, dst, dcx);
06329       for (x=0;x<16;x++)
06330          dst[x] ^= lastblock[x];
06331       memcpy(lastblock, src, sizeof(lastblock));
06332       dst += 16;
06333       src += 16;
06334       len -= 16;
06335    }
06336 #endif
06337 }

static void memcpy_encrypt ( unsigned char *  dst,
const unsigned char *  src,
int  len,
ast_aes_encrypt_key ecx 
) [static]

Definition at line 6339 of file chan_iax2.c.

References ast_aes_encrypt(), ast_log(), and LOG_WARNING.

Referenced by encrypt_frame().

06340 {
06341 #if 0
06342    /* Debug with "fake encryption" */
06343    int x;
06344    if (len % 16)
06345       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06346    for (x=0;x<len;x++)
06347       dst[x] = src[x] ^ 0xff;
06348 #else
06349    unsigned char curblock[16] = { 0 };
06350    int x;
06351    while(len > 0) {
06352       for (x=0;x<16;x++)
06353          curblock[x] ^= src[x];
06354       ast_aes_encrypt(curblock, dst, ecx);
06355       memcpy(curblock, dst, sizeof(curblock)); 
06356       dst += 16;
06357       src += 16;
06358       len -= 16;
06359    }
06360 #endif
06361 }

static void merge_encryption ( struct chan_iax2_pvt p,
unsigned int  enc 
) [static]

Definition at line 7915 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().

07916 {
07917    /* Select exactly one common encryption if there are any */
07918    p->encmethods &= enc;
07919    if (p->encmethods) {
07920       if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */
07921          p->keyrotateid = -2;
07922       }
07923       if (p->encmethods & IAX_ENCRYPT_AES128)
07924          p->encmethods = IAX_ENCRYPT_AES128;
07925       else
07926          p->encmethods = 0;
07927    }
07928 }

static void mwi_event_cb ( const struct ast_event event,
void *  userdata 
) [static]

Definition at line 1359 of file chan_iax2.c.

Referenced by build_peer().

01360 {
01361    /* The MWI subscriptions exist just so the core knows we care about those
01362     * mailboxes.  However, we just grab the events out of the cache when it
01363     * is time to send MWI, since it is only sent with a REGACK. */
01364 }

static void network_change_event_cb ( const struct ast_event event,
void *  userdata 
) [static]

Definition at line 1394 of file chan_iax2.c.

References ast_debug, iax2_sched_add(), and network_change_event_sched_cb().

Referenced by network_change_event_subscribe().

01395 {
01396    ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n");
01397    if (network_change_event_sched_id == -1) {
01398       network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL);
01399    }
01400 
01401 }

static int network_change_event_sched_cb ( const void *  data  )  [static]

Definition at line 1381 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().

01382 {
01383    struct iax2_registry *reg;
01384    network_change_event_sched_id = -1;
01385    AST_LIST_LOCK(&registrations);
01386    AST_LIST_TRAVERSE(&registrations, reg, entry) {
01387       iax2_do_register(reg);
01388    }
01389    AST_LIST_UNLOCK(&registrations);
01390 
01391    return 0;
01392 }

static void network_change_event_subscribe ( void   )  [static]
static void network_change_event_unsubscribe ( void   )  [static]
static void* network_thread ( void *  ignore  )  [static]

Definition at line 12408 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().

12409 {
12410    if (timer) {
12411       ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12412    }
12413 
12414    for (;;) {
12415       pthread_testcancel();
12416       /* Wake up once a second just in case SIGURG was sent while
12417        * we weren't in poll(), to make sure we don't hang when trying
12418        * to unload. */
12419       if (ast_io_wait(io, 1000) <= 0) {
12420          break;
12421       }
12422    }
12423 
12424    return NULL;
12425 }

static struct chan_iax2_pvt* new_iax ( struct sockaddr_in *  sin,
const char *  host 
) [static, read]

Definition at line 1998 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, exten, 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, and jb_conf::target_extra.

Referenced by __find_callno().

01999 {
02000    struct chan_iax2_pvt *tmp;
02001    jb_conf jbconf;
02002 
02003    if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
02004       return NULL;
02005    }
02006 
02007    if (ast_string_field_init(tmp, 32)) {
02008       ao2_ref(tmp, -1);
02009       tmp = NULL;
02010       return NULL;
02011    }
02012       
02013    tmp->prefs = prefs;
02014    tmp->pingid = -1;
02015    tmp->lagid = -1;
02016    tmp->autoid = -1;
02017    tmp->authid = -1;
02018    tmp->initid = -1;
02019    tmp->keyrotateid = -1;
02020 
02021    ast_string_field_set(tmp,exten, "s");
02022    ast_string_field_set(tmp,host, host);
02023 
02024    tmp->jb = jb_new();
02025    tmp->jbid = -1;
02026    jbconf.max_jitterbuf = maxjitterbuffer;
02027    jbconf.resync_threshold = resyncthreshold;
02028    jbconf.max_contig_interp = maxjitterinterps;
02029    jbconf.target_extra = jittertargetextra;
02030    jb_setconf(tmp->jb,&jbconf);
02031 
02032    AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
02033 
02034    tmp->hold_signaling = 1;
02035    AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
02036 
02037    return tmp;
02038 }

static void parse_dial_string ( char *  data,
struct parsed_dial_string pds 
) [static]

Parses an IAX dial string into its component parts.

Parameters:
data the string to be parsed
pds pointer to a struct parsed_dial_string to be filled in
Returns:
nothing

This function parses the string and fills the structure with pointers to its component parts. The input string will be modified.

Note:
This function supports both plaintext passwords and RSA key names; if the password string is formatted as '[keyname]', then the keyname will be placed into the key field, and the password field will be set to NULL.
The dial string format is: [username[:password]@]peer[:port][/exten[@context]][/options]

Definition at line 5069 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, and parsed_dial_string::username.

Referenced by cache_get_callno_locked(), iax2_call(), iax2_devicestate(), and iax2_request().

05070 {
05071    if (ast_strlen_zero(data))
05072       return;
05073 
05074    pds->peer = strsep(&data, "/");
05075    pds->exten = strsep(&data, "/");
05076    pds->options = data;
05077 
05078    if (pds->exten) {
05079       data = pds->exten;
05080       pds->exten = strsep(&data, "@");
05081       pds->context = data;
05082    }
05083 
05084    if (strchr(pds->peer, '@')) {
05085       data = pds->peer;
05086       pds->username = strsep(&data, "@");
05087       pds->peer = data;
05088    }
05089 
05090    if (pds->username) {
05091       data = pds->username;
05092       pds->username = strsep(&data, ":");
05093       pds->password = data;
05094    }
05095 
05096    data = pds->peer;
05097    pds->peer = strsep(&data, ":");
05098    pds->port = data;
05099 
05100    /* check for a key name wrapped in [] in the secret position, if found,
05101       move it to the key field instead
05102    */
05103    if (pds->password && (pds->password[0] == '[')) {
05104       pds->key = ast_strip_quoted(pds->password, "[", "]");
05105       pds->password = NULL;
05106    }
05107 }

static int peer_cmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]
Note:
The only member of the peer passed here guaranteed to be set is the name field

Definition at line 1738 of file chan_iax2.c.

References CMP_MATCH, and CMP_STOP.

Referenced by load_objects().

01739 {
01740    struct iax2_peer *peer = obj, *peer2 = arg;
01741 
01742    return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01743 }

static int peer_delme_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 13169 of file chan_iax2.c.

References ast_set_flag64, and IAX_DELME.

Referenced by delete_users().

13170 {
13171    struct iax2_peer *peer = obj;
13172 
13173    ast_set_flag64(peer, IAX_DELME);
13174 
13175    return 0;
13176 }

static void peer_destructor ( void *  obj  )  [static]

Definition at line 12598 of file chan_iax2.c.

References ast_dnsmgr_release(), ast_event_unsubscribe(), ast_free_ha(), ast_mutex_lock, ast_mutex_unlock, ast_string_field_free_memory, iax2_peer::callno, iax2_peer::dnsmgr, iax2_peer::ha, iax2_destroy(), iaxsl, iax2_peer::mwi_event_sub, and register_peer_exten().

Referenced by build_peer().

12599 {
12600    struct iax2_peer *peer = obj;
12601    int callno = peer->callno;
12602 
12603    ast_free_ha(peer->ha);
12604 
12605    if (callno > 0) {
12606       ast_mutex_lock(&iaxsl[callno]);
12607       iax2_destroy(callno);
12608       ast_mutex_unlock(&iaxsl[callno]);
12609    }
12610 
12611    register_peer_exten(peer, 0);
12612 
12613    if (peer->dnsmgr)
12614       ast_dnsmgr_release(peer->dnsmgr);
12615 
12616    if (peer->mwi_event_sub)
12617       ast_event_unsubscribe(peer->mwi_event_sub);
12618 
12619    ast_string_field_free_memory(peer);
12620 }

static int peer_hash_cb ( const void *  obj,
const int  flags 
) [static]
Note:
The only member of the peer passed here guaranteed to be set is the name field

Definition at line 1728 of file chan_iax2.c.

References ast_str_hash().

Referenced by load_objects().

01729 {
01730    const struct iax2_peer *peer = obj;
01731 
01732    return ast_str_hash(peer->name);
01733 }

static struct iax2_peer* peer_ref ( struct iax2_peer peer  )  [static, read]

Definition at line 1785 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().

01786 {
01787    ao2_ref(peer, +1);
01788    return peer;
01789 }

static int peer_set_sock_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 14665 of file chan_iax2.c.

References iax2_peer::sockfd.

Referenced by load_module().

14666 {
14667    struct iax2_peer *peer = obj;
14668 
14669    if (peer->sockfd < 0)
14670       peer->sockfd = defaultsockfd;
14671 
14672    return 0;
14673 }

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 12525 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, qos, socket_read(), iax2_peer::sockfd, iax2_trunk_peer::sockfd, and ast_sockaddr::ss.

Referenced by build_peer().

12526 {
12527    struct sockaddr_in sin;
12528    struct ast_sockaddr sin_tmp;
12529    int nonlocal = 1;
12530    int port = IAX_DEFAULT_PORTNO;
12531    int sockfd = defaultsockfd;
12532    char *tmp;
12533    char *addr;
12534    char *portstr;
12535 
12536    tmp = ast_strdupa(srcaddr);
12537    addr = strsep(&tmp, ":");
12538    portstr = tmp;
12539 
12540    if (portstr) {
12541       port = atoi(portstr);
12542       if (port < 1)
12543          port = IAX_DEFAULT_PORTNO;
12544    }
12545 
12546    sin_tmp.ss.ss_family = AF_INET;
12547    if (!ast_get_ip(&sin_tmp, addr)) {
12548       struct ast_netsock *sock;
12549       int res;
12550 
12551       ast_sockaddr_to_sin(&sin_tmp, &sin);
12552       sin.sin_port = 0;
12553       sin.sin_family = AF_INET;
12554       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
12555       if (res == 0) {
12556          /* ip address valid. */
12557          sin.sin_port = htons(port);
12558          if (!(sock = ast_netsock_find(netsock, &sin)))
12559             sock = ast_netsock_find(outsock, &sin);
12560          if (sock) {
12561             sockfd = ast_netsock_sockfd(sock);
12562             nonlocal = 0;
12563          } else {
12564             unsigned int orig_saddr = sin.sin_addr.s_addr;
12565             /* INADDR_ANY matches anyway! */
12566             sin.sin_addr.s_addr = INADDR_ANY;
12567             if (ast_netsock_find(netsock, &sin)) {
12568                sin.sin_addr.s_addr = orig_saddr;
12569                sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12570                if (sock) {
12571                   sockfd = ast_netsock_sockfd(sock);
12572                   ast_netsock_unref(sock);
12573                   nonlocal = 0;
12574                } else {
12575                   nonlocal = 2;
12576                }
12577             }
12578          }
12579       }
12580    }
12581       
12582    peer->sockfd = sockfd;
12583 
12584    if (nonlocal == 1) {
12585       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12586          srcaddr, peer->name);
12587       return -1;
12588         } else if (nonlocal == 2) {
12589       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12590          srcaddr, peer->name);
12591          return -1;
12592    } else {
12593       ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12594       return 0;
12595    }
12596 }

static int peer_status ( struct iax2_peer peer,
char *  status,
int  statuslen 
) [static]

peer_status: Report Peer status in character string

Definition at line 3812 of file chan_iax2.c.

References ast_copy_string(), iax2_peer::lastms, and iax2_peer::maxms.

Referenced by __iax2_show_peers(), function_iaxpeer(), handle_cli_iax2_show_peer(), manager_iax2_show_peer_list(), and peers_data_provider_get().

03813 {
03814    int res = 0;
03815    if (peer->maxms) {
03816       if (peer->lastms < 0) {
03817          ast_copy_string(status, "UNREACHABLE", statuslen);
03818       } else if (peer->lastms > peer->maxms) {
03819          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03820          res = 1;
03821       } else if (peer->lastms) {
03822          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03823          res = 1;
03824       } else {
03825          ast_copy_string(status, "UNKNOWN", statuslen);
03826       }
03827    } else { 
03828       ast_copy_string(status, "Unmonitored", statuslen);
03829       res = -1;
03830    }
03831    return res;
03832 }

static struct iax2_peer* peer_unref ( struct iax2_peer peer  )  [static, read]
static int peercnt_add ( struct sockaddr_in *  sin  )  [static]

Definition at line 2432 of file chan_iax2.c.

References iax2_trunk_peer::addr, ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_debug, ast_inet_ntoa(), ast_log(), LOG_ERROR, OBJ_POINTER, and set_peercnt_limit().

Referenced by __find_callno(), and complete_transfer().

02433 {
02434    struct peercnt *peercnt;
02435    unsigned long addr = sin->sin_addr.s_addr;
02436    int res = 0;
02437    struct peercnt tmp = {
02438       .addr = addr,
02439    };
02440 
02441    /* Reasoning for peercnts container lock:  Two identical ip addresses
02442     * could be added by different threads at the "same time". Without the container
02443     * lock, both threads could alloc space for the same object and attempt
02444     * to link to table.  With the lock, one would create the object and link
02445     * to table while the other would find the already created peercnt object
02446     * rather than creating a new one. */
02447    ao2_lock(peercnts);
02448    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02449       ao2_lock(peercnt);
02450    } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
02451       ao2_lock(peercnt);
02452       /* create and set defaults */
02453       peercnt->addr = addr;
02454       set_peercnt_limit(peercnt);
02455       /* guarantees it does not go away after unlocking table
02456        * ao2_find automatically adds this */
02457       ao2_link(peercnts, peercnt);
02458    } else {
02459       ao2_unlock(peercnts);
02460       return -1;
02461    }
02462 
02463    /* check to see if the address has hit its callno limit.  If not increment cur. */
02464    if (peercnt->limit > peercnt->cur) {
02465       peercnt->cur++;
02466       ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02467    } else { /* max num call numbers for this peer has been reached! */
02468       ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02469       res = -1;
02470    }
02471 
02472    /* clean up locks and ref count */
02473    ao2_unlock(peercnt);
02474    ao2_unlock(peercnts);
02475    ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */
02476 
02477    return res;
02478 }

static int peercnt_cmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 2262 of file chan_iax2.c.

References CMP_MATCH, and CMP_STOP.

Referenced by load_objects().

02263 {
02264    struct peercnt *peercnt1 = obj, *peercnt2 = arg;
02265    return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
02266 }

static int peercnt_hash_cb ( const void *  obj,
const int  flags 
) [static]

Definition at line 2256 of file chan_iax2.c.

Referenced by load_objects().

02257 {
02258    const struct peercnt *peercnt = obj;
02259    return abs((int) peercnt->addr);
02260 }

static void peercnt_modify ( unsigned char  reg,
uint16_t  limit,
struct ast_sockaddr sockaddr 
) [static]

Definition at line 2399 of file chan_iax2.c.

References ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), ast_sockaddr_to_sin, OBJ_POINTER, and set_peercnt_limit().

Referenced by __expire_registry(), build_peer(), and update_registry().

02400 {
02401    /* this function turns off and on custom callno limits set by peer registration */
02402    struct peercnt *peercnt;
02403    struct peercnt tmp = {
02404       .addr = 0,
02405    };
02406    struct sockaddr_in sin;
02407 
02408    ast_sockaddr_to_sin(sockaddr, &sin);
02409 
02410    tmp.addr = sin.sin_addr.s_addr;
02411 
02412    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02413       peercnt->reg = reg;
02414       if (limit) {
02415          peercnt->limit = limit;
02416       } else {
02417          set_peercnt_limit(peercnt);
02418       }
02419       ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg);
02420       ao2_ref(peercnt, -1); /* decrement ref from find */
02421    }
02422 }

static void peercnt_remove ( struct peercnt *  peercnt  )  [static]

Definition at line 2484 of file chan_iax2.c.

References ao2_lock, ao2_unlink, ao2_unlock, ast_debug, and ast_inet_ntoa().

Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().

02485 {
02486    struct sockaddr_in sin = {
02487       .sin_addr.s_addr = peercnt->addr,
02488    };
02489 
02490    /*
02491     * Container locked here since peercnt may be unlinked from
02492     * list.  If left unlocked, peercnt_add could try and grab this
02493     * entry from the table and modify it at the "same time" this
02494     * thread attemps to unlink it.
02495     */
02496    ao2_lock(peercnts);
02497    peercnt->cur--;
02498    ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02499    /* if this was the last connection from the peer remove it from table */
02500    if (peercnt->cur == 0) {
02501       ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */
02502    }
02503    ao2_unlock(peercnts);
02504 }

static int peercnt_remove_by_addr ( struct sockaddr_in *  sin  )  [static]

Definition at line 2524 of file chan_iax2.c.

References ao2_find, ao2_ref, OBJ_POINTER, and peercnt_remove().

Referenced by __find_callno(), and complete_transfer().

02525 {
02526    struct peercnt *peercnt;
02527    struct peercnt tmp = {
02528       .addr = sin->sin_addr.s_addr,
02529    };
02530 
02531    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02532       peercnt_remove(peercnt);
02533       ao2_ref(peercnt, -1); /* decrement ref from find */
02534    }
02535    return 0;
02536 }

static int peercnt_remove_cb ( const void *  obj  )  [static]

Definition at line 2510 of file chan_iax2.c.

References ao2_ref, and peercnt_remove().

Referenced by sched_delay_remove().

02511 {
02512    struct peercnt *peercnt = (struct peercnt *) obj;
02513 
02514    peercnt_remove(peercnt);
02515    ao2_ref(peercnt, -1); /* decrement ref from scheduler */
02516 
02517    return 0;
02518 }

static int peers_data_provider_get ( const struct ast_data_search search,
struct ast_data data_root 
) [static]

Definition at line 14799 of file chan_iax2.c.

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_inet_ntoa(), ast_sockaddr_port, ast_sockaddr_stringify_host(), ast_str_alloca, ast_str_buffer(), ast_test_flag64, iax2_peer::capability, iax2_peer::encmethods, encmethods_to_str(), IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, peer_status(), peer_unref(), and status.

14801 {
14802    struct ast_data *data_peer;
14803    struct iax2_peer *peer;
14804    struct ao2_iterator i;
14805    char status[20];
14806    struct ast_str *encmethods = ast_str_alloca(256);
14807 
14808    i = ao2_iterator_init(peers, 0);
14809    while ((peer = ao2_iterator_next(&i))) {
14810       data_peer = ast_data_add_node(data_root, "peer");
14811       if (!data_peer) {
14812          peer_unref(peer);
14813          continue;
14814       }
14815 
14816       ast_data_add_structure(iax2_peer, data_peer, peer);
14817 
14818       ast_data_add_codecs(data_peer, "codecs", peer->capability);
14819 
14820       peer_status(peer, status, sizeof(status));
14821       ast_data_add_str(data_peer, "status", status);
14822 
14823       ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr));
14824 
14825       ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask));
14826 
14827       ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr));
14828 
14829       ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK));
14830 
14831       ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC));
14832 
14833       encmethods_to_str(peer->encmethods, &encmethods);
14834       ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no");
14835 
14836       peer_unref(peer);
14837 
14838       if (!ast_data_search_match(search, data_peer)) {
14839          ast_data_remove_node(data_root, data_peer);
14840       }
14841    }
14842    ao2_iterator_destroy(&i);
14843 
14844    return 0;
14845 }

static void poke_all_peers ( void   )  [static]

Definition at line 13748 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().

13749 {
13750    struct ao2_iterator i;
13751    struct iax2_peer *peer;
13752 
13753    i = ao2_iterator_init(peers, 0);
13754    while ((peer = ao2_iterator_next(&i))) {
13755       iax2_poke_peer(peer, 0);
13756       peer_unref(peer);
13757    }
13758    ao2_iterator_destroy(&i);
13759 }

static int prune_addr_range_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 2388 of file chan_iax2.c.

References CMP_MATCH, and addr_range::delme.

Referenced by reload_config().

02389 {
02390    struct addr_range *addr_range = obj;
02391 
02392    return addr_range->delme ? CMP_MATCH : 0;
02393 }

static void prune_peers ( void   )  [static]

Definition at line 13232 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().

Referenced by handle_cli_iax2_prune_realtime(), and reload_config().

13233 {
13234    struct iax2_peer *peer;
13235    struct ao2_iterator i;
13236 
13237    i = ao2_iterator_init(peers, 0);
13238    while ((peer = ao2_iterator_next(&i))) {
13239       if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
13240          unlink_peer(peer);
13241       }
13242       peer_unref(peer);
13243    }
13244    ao2_iterator_destroy(&i);
13245 }

static void prune_users ( void   )  [static]

Definition at line 13216 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().

13217 {
13218    struct iax2_user *user;
13219    struct ao2_iterator i;
13220 
13221    i = ao2_iterator_init(users, 0);
13222    while ((user = ao2_iterator_next(&i))) {
13223       if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
13224          ao2_unlink(users, user);
13225       }
13226       user_unref(user);
13227    }
13228    ao2_iterator_destroy(&i);
13229 }

static int pvt_cmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 14682 of file chan_iax2.c.

References CMP_MATCH, CMP_STOP, and match().

Referenced by load_objects().

14683 {
14684    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14685 
14686    /* The frames_received field is used to hold whether we're matching
14687     * against a full frame or not ... */
14688 
14689    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
14690       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14691 }

static void pvt_destructor ( void *  obj  )  [static]

Definition at line 1951 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, free_signaling_queue_entry(), iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxsl, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, and sched_delay_remove().

Referenced by new_iax().

01952 {
01953    struct chan_iax2_pvt *pvt = obj;
01954    struct iax_frame *cur = NULL;
01955    struct signaling_queue_entry *s = NULL;
01956 
01957    ast_mutex_lock(&iaxsl[pvt->callno]);
01958 
01959    iax2_destroy_helper(pvt);
01960 
01961    sched_delay_remove(&pvt->addr, pvt->callno_entry);
01962    pvt->callno_entry = NULL;
01963 
01964    /* Already gone */
01965    ast_set_flag64(pvt, IAX_ALREADYGONE);
01966 
01967    AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) {
01968       /* Cancel any pending transmissions */
01969       cur->retries = -1;
01970    }
01971 
01972    ast_mutex_unlock(&iaxsl[pvt->callno]);
01973 
01974    while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01975       free_signaling_queue_entry(s);
01976    }
01977 
01978    if (pvt->reg) {
01979       pvt->reg->callno = 0;
01980    }
01981 
01982    if (!pvt->owner) {
01983       jb_frame frame;
01984       if (pvt->vars) {
01985           ast_variables_destroy(pvt->vars);
01986           pvt->vars = NULL;
01987       }
01988 
01989       while (jb_getall(pvt->jb, &frame) == JB_OK) {
01990          iax2_frame_free(frame.data);
01991       }
01992 
01993       jb_destroy(pvt->jb);
01994       ast_string_field_free_memory(pvt);
01995    }
01996 }

static int pvt_hash_cb ( const void *  obj,
const int  flags 
) [static]

Definition at line 14675 of file chan_iax2.c.

References chan_iax2_pvt::peercallno.

Referenced by load_objects().

14676 {
14677    const struct chan_iax2_pvt *pvt = obj;
14678 
14679    return pvt->peercallno;
14680 }

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 1926 of file chan_iax2.c.

References ast_calloc, AST_FRAME_IAX, AST_LIST_INSERT_TAIL, ast_malloc, ast_frame::data, ast_frame::datalen, signaling_queue_entry::f, ast_frame::frametype, free_signaling_queue_entry(), and ast_frame::ptr.

Referenced by __send_command().

01927 {
01928    struct signaling_queue_entry *qe;
01929 
01930    if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
01931       return 1; /* do not queue this frame */
01932    } else if (!(qe = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
01933       return -1;  /* out of memory */
01934    }
01935 
01936    /* copy ast_frame into our queue entry */
01937    qe->f = *f;
01938    if (qe->f.datalen) {
01939       /* if there is data in this frame copy it over as well */
01940       if (!(qe->f.data.ptr = ast_malloc(qe->f.datalen))) {
01941          free_signaling_queue_entry(qe);
01942          return -1;
01943       }
01944       memcpy(qe->f.data.ptr, f->data.ptr, qe->f.datalen);
01945    }
01946    AST_LIST_INSERT_TAIL(&pvt->signaling_queue, qe, next);
01947 
01948    return 0;
01949 }

static int raw_hangup ( struct sockaddr_in *  sin,
unsigned short  src,
unsigned short  dst,
int  sockfd 
) [static]

Definition at line 7896 of file chan_iax2.c.

References ast_debug, AST_FRAME_IAX, ast_inet_ntoa(), compress_subclass(), ast_iax2_full_hdr::csub, ast_iax2_full_hdr::dcallno, IAX_COMMAND_INVAL, IAX_FLAG_FULL, iax_outputframe(), ast_iax2_full_hdr::iseqno, option_debug, ast_iax2_full_hdr::oseqno, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type.

Referenced by socket_process().

07897 {
07898    struct ast_iax2_full_hdr fh;
07899    fh.scallno = htons(src | IAX_FLAG_FULL);
07900    fh.dcallno = htons(dst);
07901    fh.ts = 0;
07902    fh.oseqno = 0;
07903    fh.iseqno = 0;
07904    fh.type = AST_FRAME_IAX;
07905    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07906    iax_outputframe(NULL, &fh, 0, sin, 0);
07907 #if 0
07908    if (option_debug)
07909 #endif   
07910       ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07911          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07912    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07913 }

static struct iax2_peer * realtime_peer ( const char *  peername,
struct sockaddr_in *  sin 
) [static, read]
Note:
This function calls reg_source_db -> iax2_poke_peer -> find_callno, so do not call this with a pvt lock held.

Note:
If this one loaded something, then we need to ensure that the host field matched. The only reason why we can't have this as a criteria is because we only have the IP address and the host field might be set as a name (and the reverse PTR might not match).

Definition at line 4424 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_log(), ast_sched_thread_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, LOG_WARNING, 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.

Referenced by authenticate_reply(), calltoken_required(), find_peer(), and iax2_getpeername().

04425 {
04426    struct ast_variable *var = NULL;
04427    struct ast_variable *tmp;
04428    struct iax2_peer *peer=NULL;
04429    time_t regseconds = 0, nowtime;
04430    int dynamic=0;
04431 
04432    if (peername) {
04433       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04434       if (!var && sin)
04435          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04436    } else if (sin) {
04437       char porta[25];
04438       sprintf(porta, "%d", ntohs(sin->sin_port));
04439       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04440       if (var) {
04441          /* We'll need the peer name in order to build the structure! */
04442          for (tmp = var; tmp; tmp = tmp->next) {
04443             if (!strcasecmp(tmp->name, "name"))
04444                peername = tmp->value;
04445          }
04446       }
04447    }
04448    if (!var && peername) { /* Last ditch effort */
04449       var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04450       /*!\note
04451        * If this one loaded something, then we need to ensure that the host
04452        * field matched.  The only reason why we can't have this as a criteria
04453        * is because we only have the IP address and the host field might be
04454        * set as a name (and the reverse PTR might not match).
04455        */
04456       if (var && sin) {
04457          for (tmp = var; tmp; tmp = tmp->next) {
04458             if (!strcasecmp(tmp->name, "host")) {
04459                struct ast_hostent ahp;
04460                struct hostent *hp;
04461                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) {
04462                   /* No match */
04463                   ast_variables_destroy(var);
04464                   var = NULL;
04465                }
04466                break;
04467             }
04468          }
04469       }
04470    }
04471    if (!var)
04472       return NULL;
04473 
04474    peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04475 
04476    if (!peer) {
04477       ast_variables_destroy(var);
04478       return NULL;
04479    }
04480 
04481    for (tmp = var; tmp; tmp = tmp->next) {
04482       /* Make sure it's not a user only... */
04483       if (!strcasecmp(tmp->name, "type")) {
04484          if (strcasecmp(tmp->value, "friend") &&
04485              strcasecmp(tmp->value, "peer")) {
04486             /* Whoops, we weren't supposed to exist! */
04487             peer = peer_unref(peer);
04488             break;
04489          }
04490       } else if (!strcasecmp(tmp->name, "regseconds")) {
04491          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
04492       } else if (!strcasecmp(tmp->name, "ipaddr")) {
04493          if (!ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE)) {
04494             ast_log(LOG_WARNING, "Failed to parse sockaddr '%s' for ipaddr of realtime peer '%s'\n", tmp->value, tmp->name);
04495          }
04496       } else if (!strcasecmp(tmp->name, "port")) {
04497          ast_sockaddr_set_port(&peer->addr, atoi(tmp->value));
04498       } else if (!strcasecmp(tmp->name, "host")) {
04499          if (!strcasecmp(tmp->value, "dynamic"))
04500             dynamic = 1;
04501       }
04502    }
04503 
04504    ast_variables_destroy(var);
04505 
04506    if (!peer)
04507       return NULL;
04508 
04509    if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04510       ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04511       if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) {
04512          if (peer->expire > -1) {
04513             if (!ast_sched_thread_del(sched, peer->expire)) {
04514                peer->expire = -1;
04515                peer_unref(peer);
04516             }
04517          }
04518          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04519          if (peer->expire == -1)
04520             peer_unref(peer);
04521       }
04522       ao2_link(peers, peer);
04523       if (ast_test_flag64(peer, IAX_DYNAMIC))
04524          reg_source_db(peer);
04525    } else {
04526       ast_set_flag64(peer, IAX_TEMPONLY);
04527    }
04528 
04529    if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04530       time(&nowtime);
04531       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04532          memset(&peer->addr, 0, sizeof(peer->addr));
04533          realtime_update_peer(peer->name, &peer->addr, 0);
04534          ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04535             peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04536       }
04537       else {
04538          ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04539             peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04540       }
04541    }
04542 
04543    return peer;
04544 }

static void realtime_update_peer ( const char *  peername,
struct ast_sockaddr sockaddr,
time_t  regtime 
) [static]

Definition at line 4617 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(), and update_registry().

04618 {
04619    char port[10];
04620    char regseconds[20];
04621    const char *sysname = ast_config_AST_SYSTEM_NAME;
04622    char *syslabel = NULL;
04623 
04624    if (ast_strlen_zero(sysname)) /* No system name, disable this */
04625       sysname = NULL;
04626    else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME))
04627       syslabel = "regserver";
04628 
04629    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04630    snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr));
04631    ast_update_realtime("iaxpeers", "name", peername, 
04632       "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port, 
04633       "regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslable can be NULL */
04634 }

static struct iax2_user * realtime_user ( const char *  username,
struct sockaddr_in *  sin 
) [static, read]

Note:
If this one loaded something, then we need to ensure that the host field matched. The only reason why we can't have this as a criteria is because we only have the IP address and the host field might be set as a name (and the reverse PTR might not match).

Definition at line 4546 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.

Referenced by calltoken_required(), and check_access().

04547 {
04548    struct ast_variable *var;
04549    struct ast_variable *tmp;
04550    struct iax2_user *user=NULL;
04551 
04552    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04553    if (!var)
04554       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04555    if (!var && sin) {
04556       char porta[6];
04557       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04558       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04559       if (!var)
04560          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04561    }
04562    if (!var) { /* Last ditch effort */
04563       var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04564       /*!\note
04565        * If this one loaded something, then we need to ensure that the host
04566        * field matched.  The only reason why we can't have this as a criteria
04567        * is because we only have the IP address and the host field might be
04568        * set as a name (and the reverse PTR might not match).
04569        */
04570       if (var) {
04571          for (tmp = var; tmp; tmp = tmp->next) {
04572             if (!strcasecmp(tmp->name, "host")) {
04573                struct ast_hostent ahp;
04574                struct hostent *hp;
04575                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) {
04576                   /* No match */
04577                   ast_variables_destroy(var);
04578                   var = NULL;
04579                }
04580                break;
04581             }
04582          }
04583       }
04584    }
04585    if (!var)
04586       return NULL;
04587 
04588    tmp = var;
04589    while(tmp) {
04590       /* Make sure it's not a peer only... */
04591       if (!strcasecmp(tmp->name, "type")) {
04592          if (strcasecmp(tmp->value, "friend") &&
04593              strcasecmp(tmp->value, "user")) {
04594             return NULL;
04595          } 
04596       }
04597       tmp = tmp->next;
04598    }
04599 
04600    user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS));
04601 
04602    ast_variables_destroy(var);
04603 
04604    if (!user)
04605       return NULL;
04606 
04607    if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04608       ast_set_flag64(user, IAX_RTCACHEFRIENDS);
04609       ao2_link(users, user);
04610    } else {
04611       ast_set_flag64(user, IAX_TEMPONLY);
04612    }
04613 
04614    return user;
04615 }

static void reg_source_db ( struct iax2_peer p  )  [static]

Definition at line 8782 of file chan_iax2.c.

References iax2_peer::addr, ast_db_get(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_log(), ast_sched_thread_del, ast_sockaddr_parse(), ast_sockaddr_stringify(), ast_test_flag64, ast_verb, iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), IAX_TEMPONLY, LOG_NOTICE, PARSE_PORT_REQUIRE, peer_ref(), peer_unref(), and register_peer_exten().

Referenced by realtime_peer(), and set_config().

08783 {
08784    char data[80];
08785    char *expiry;
08786 
08787    if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
08788       return;
08789    }
08790 
08791    expiry = strrchr(data, ':');
08792    if (!expiry) {
08793       ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
08794       return;
08795    }
08796    *expiry++ = '\0';
08797 
08798    if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
08799       ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
08800       return;
08801    }
08802 
08803    p->expiry = atoi(expiry);
08804 
08805    ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
08806       ast_sockaddr_stringify(&p->addr), p->expiry);
08807 
08808    iax2_poke_peer(p, 0);
08809    if (p->expire > -1) {
08810       if (!ast_sched_thread_del(sched, p->expire)) {
08811          p->expire = -1;
08812          peer_unref(p);
08813       }
08814    }
08815 
08816    ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
08817 
08818    p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08819    if (p->expire == -1) {
08820       peer_unref(p);
08821    }
08822 
08823    if (iax2_regfunk) {
08824       iax2_regfunk(p->name, 1);
08825    }
08826 
08827    register_peer_exten(p, 1);
08828 }

static void register_peer_exten ( struct iax2_peer peer,
int  onoff 
) [static]

Definition at line 8699 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, and S_OR.

Referenced by __expire_registry(), peer_destructor(), reg_source_db(), and update_registry().

08700 {
08701    char multi[256];
08702    char *stringp, *ext;
08703    if (!ast_strlen_zero(regcontext)) {
08704       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08705       stringp = multi;
08706       while((ext = strsep(&stringp, "&"))) {
08707          if (onoff) {
08708             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08709                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08710                        "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08711          } else
08712             ast_context_remove_extension(regcontext, ext, 1, NULL);
08713       }
08714    }
08715 }

static int register_verify ( int  callno,
struct sockaddr_in *  sin,
struct iax_ies ies 
) [static]

Verify inbound registration.

Definition at line 8070 of file chan_iax2.c.

References ast_apply_ha(), ast_check_signature(), ast_clear_flag, ast_copy_string(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, 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, iaxs, iaxsl, LOG_NOTICE, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax_ies::password, peer_unref(), iax_ies::refresh, iax_ies::rsa_result, secret, and iax_ies::username.

Referenced by socket_process().

08071 {
08072    char requeststr[256] = "";
08073    char peer[256] = "";
08074    char md5secret[256] = "";
08075    char rsasecret[256] = "";
08076    char secret[256] = "";
08077    struct iax2_peer *p = NULL;
08078    struct ast_key *key;
08079    char *keyn;
08080    int x;
08081    int expire = 0;
08082    int res = -1;
08083    struct ast_sockaddr addr;
08084 
08085    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08086    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
08087    if (ies->username)
08088       ast_copy_string(peer, ies->username, sizeof(peer));
08089    if (ies->password)
08090       ast_copy_string(secret, ies->password, sizeof(secret));
08091    if (ies->md5_result)
08092       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
08093    if (ies->rsa_result)
08094       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
08095    if (ies->refresh)
08096       expire = ies->refresh;
08097 
08098    if (ast_strlen_zero(peer)) {
08099       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
08100       return -1;
08101    }
08102 
08103    /* SLD: first call to lookup peer during registration */
08104    ast_mutex_unlock(&iaxsl[callno]);
08105    p = find_peer(peer, 1);
08106    ast_mutex_lock(&iaxsl[callno]);
08107    if (!p || !iaxs[callno]) {
08108       if (iaxs[callno]) {
08109          int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
08110          /* Anything, as long as it's non-blank */
08111          ast_string_field_set(iaxs[callno], secret, "badsecret");
08112          /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless
08113           * 1. A challenge already exists indicating a AUTHREQ was already sent out.
08114           * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it.
08115           * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened
08116           *    to be plaintext, indicating it is an authmethod used by other peers on the system. 
08117           *
08118           * If none of these cases exist, res will be returned as 0 without authentication indicating
08119           * an AUTHREQ needs to be sent out. */
08120 
08121          if (ast_strlen_zero(iaxs[callno]->challenge) &&
08122             !(!ast_strlen_zero(secret) && plaintext)) {
08123             /* by setting res to 0, an REGAUTH will be sent */
08124             res = 0;
08125          }
08126       }
08127       if (authdebug && !p)
08128          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
08129       goto return_unref;
08130    }
08131 
08132    if (!ast_test_flag64(p, IAX_DYNAMIC)) {
08133       if (authdebug)
08134          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
08135       goto return_unref;
08136    }
08137 
08138    ast_sockaddr_from_sin(&addr, sin);
08139    if (!ast_apply_ha(p->ha, &addr)) {
08140       if (authdebug)
08141          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08142       goto return_unref;
08143    }
08144    ast_string_field_set(iaxs[callno], secret, p->secret);
08145    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
08146    /* Check secret against what we have on file */
08147    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08148       if (!ast_strlen_zero(p->inkeys)) {
08149          char tmpkeys[256];
08150          char *stringp=NULL;
08151          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
08152          stringp=tmpkeys;
08153          keyn = strsep(&stringp, ":");
08154          while(keyn) {
08155             key = ast_key_get(keyn, AST_KEY_PUBLIC);
08156             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
08157                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08158                break;
08159             } else if (!key)
08160                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
08161             keyn = strsep(&stringp, ":");
08162          }
08163          if (!keyn) {
08164             if (authdebug)
08165                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
08166             goto return_unref;
08167          }
08168       } else {
08169          if (authdebug)
08170             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
08171          goto return_unref;
08172       }
08173    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08174       struct MD5Context md5;
08175       unsigned char digest[16];
08176       char *tmppw, *stringp;
08177 
08178       tmppw = ast_strdupa(p->secret);
08179       stringp = tmppw;
08180       while((tmppw = strsep(&stringp, ";"))) {
08181          MD5Init(&md5);
08182          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
08183          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
08184          MD5Final(digest, &md5);
08185          for (x=0;x<16;x++)
08186             sprintf(requeststr + (x << 1), "%2.2x", (unsigned)digest[x]); /* safe */
08187          if (!strcasecmp(requeststr, md5secret))
08188             break;
08189       }
08190       if (tmppw) {
08191          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08192       } else {
08193          if (authdebug)
08194             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
08195          goto return_unref;
08196       }
08197    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
08198       /* They've provided a plain text password and we support that */
08199       if (strcmp(secret, p->secret)) {
08200          if (authdebug)
08201             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08202          goto return_unref;
08203       } else
08204          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08205    } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
08206       /* if challenge has been sent, but no challenge response if given, reject. */
08207       goto return_unref;
08208    }
08209    ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
08210 
08211    /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
08212    res = 0;
08213 
08214 return_unref:
08215    if (iaxs[callno]) {
08216       ast_string_field_set(iaxs[callno], peer, peer);
08217 
08218       /* Choose lowest expiry number */
08219       if (expire && (expire < iaxs[callno]->expiry)) {
08220          iaxs[callno]->expiry = expire;
08221       }
08222    }
08223 
08224    if (p) {
08225       peer_unref(p);
08226    }
08227    return res;
08228 }

static int registry_authrequest ( int  callno  )  [static]

Definition at line 9007 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, iaxs, iaxsl, peer_unref(), iax_ie_data::pos, and send_command().

Referenced by socket_process().

09008 {
09009    struct iax_ie_data ied;
09010    struct iax2_peer *p;
09011    char challenge[10];
09012    const char *peer_name;
09013    int sentauthmethod;
09014 
09015    peer_name = ast_strdupa(iaxs[callno]->peer);
09016 
09017    /* SLD: third call to find_peer in registration */
09018    ast_mutex_unlock(&iaxsl[callno]);
09019    if ((p = find_peer(peer_name, 1))) {
09020       last_authmethod = p->authmethods;
09021    }
09022 
09023    ast_mutex_lock(&iaxsl[callno]);
09024    if (!iaxs[callno])
09025       goto return_unref;
09026 
09027    memset(&ied, 0, sizeof(ied));
09028    /* The selection of which delayed reject is sent may leak information,
09029     * if it sets a static response.  For example, if a host is known to only
09030     * use MD5 authentication, then an RSA response would indicate that the
09031     * peer does not exist, and vice-versa.
09032     * Therefore, we use whatever the last peer used (which may vary over the
09033     * course of a server, which should leak minimal information). */
09034    sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
09035    if (!p) {
09036       iaxs[callno]->authmethods = sentauthmethod;
09037    }
09038    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
09039    if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
09040       /* Build the challenge */
09041       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
09042       ast_string_field_set(iaxs[callno], challenge, challenge);
09043       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
09044    }
09045    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
09046 
09047 return_unref:
09048    if (p) {
09049       peer_unref(p);
09050    }
09051 
09052    return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
09053 }

static int registry_rerequest ( struct iax_ies ies,
int  callno,
struct sockaddr_in *  sin 
) [static]

Definition at line 9055 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, iaxs, 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().

09056 {
09057    struct iax2_registry *reg;
09058    /* Start pessimistic */
09059    struct iax_ie_data ied;
09060    char peer[256] = "";
09061    char challenge[256] = "";
09062    int res;
09063    int authmethods = 0;
09064    if (ies->authmethods)
09065       authmethods = ies->authmethods;
09066    if (ies->username)
09067       ast_copy_string(peer, ies->username, sizeof(peer));
09068    if (ies->challenge)
09069       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
09070    memset(&ied, 0, sizeof(ied));
09071    reg = iaxs[callno]->reg;
09072    if (reg) {
09073       struct sockaddr_in reg_addr;
09074 
09075       ast_sockaddr_to_sin(&reg->addr, &reg_addr);
09076 
09077       if (inaddrcmp(&reg_addr, sin)) {
09078          ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
09079          return -1;
09080       }
09081       if (ast_strlen_zero(reg->secret)) {
09082          ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
09083          reg->regstate = REG_STATE_NOAUTH;
09084          return -1;
09085       }
09086       iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
09087       iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
09088       if (reg->secret[0] == '[') {
09089          char tmpkey[256];
09090          ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
09091          tmpkey[strlen(tmpkey) - 1] = '\0';
09092          res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
09093       } else
09094          res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
09095       if (!res) {
09096          reg->regstate = REG_STATE_AUTHSENT;
09097          add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
09098          return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
09099       } else
09100          return -1;
09101       ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
09102    } else   
09103       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
09104    return -1;
09105 }

static char* regstate2str ( int  regstate  )  [static]

Definition at line 7167 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(), and manager_iax2_show_registry().

07168 {
07169    switch(regstate) {
07170    case REG_STATE_UNREGISTERED:
07171       return "Unregistered";
07172    case REG_STATE_REGSENT:
07173       return "Request Sent";
07174    case REG_STATE_AUTHSENT:
07175       return "Auth. Sent";
07176    case REG_STATE_REGISTERED:
07177       return "Registered";
07178    case REG_STATE_REJECTED:
07179       return "Rejected";
07180    case REG_STATE_TIMEOUT:
07181       return "Timeout";
07182    case REG_STATE_NOAUTH:
07183       return "No Authentication";
07184    default:
07185       return "Unknown";
07186    }
07187 }

static int reload ( void   )  [static]

Definition at line 13809 of file chan_iax2.c.

References reload_config().

13810 {
13811    return reload_config();
13812 }

static int reload_config ( void   )  [static]

Definition at line 13760 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().

Referenced by handle_cli_iax2_reload(), and reload().

13761 {
13762    static const char config[] = "iax.conf";
13763    struct iax2_registry *reg;
13764 
13765    if (set_config(config, 1) > 0) {
13766       prune_peers();
13767       prune_users();
13768       ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13769       ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13770       ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13771       trunk_timed = trunk_untimed = 0; 
13772       trunk_nmaxmtu = trunk_maxmtu = 0;
13773       memset(&debugaddr, '\0', sizeof(debugaddr));
13774 
13775       AST_LIST_LOCK(&registrations);
13776       AST_LIST_TRAVERSE(&registrations, reg, entry)
13777          iax2_do_register(reg);
13778       AST_LIST_UNLOCK(&registrations);
13779 
13780       /* Qualify hosts, too */
13781       poke_all_peers();
13782    }
13783    
13784    reload_firmware(0);
13785    iax_provision_reload(1);
13786    ast_unload_realtime("iaxpeers");
13787 
13788    return 0;
13789 }

static void reload_firmware ( int  unload  )  [static]

Definition at line 3305 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, destroy_firmware(), errno, LOG_WARNING, and try_firmware().

Referenced by __unload_module(), load_module(), and reload_config().

03306 {
03307    struct iax_firmware *cur = NULL;
03308    DIR *fwd;
03309    struct dirent *de;
03310    char dir[256], fn[256];
03311 
03312    AST_LIST_LOCK(&firmwares);
03313 
03314    /* Mark all as dead */
03315    AST_LIST_TRAVERSE(&firmwares, cur, list)
03316       cur->dead = 1;
03317 
03318    /* Now that we have marked them dead... load new ones */
03319    if (!unload) {
03320       snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
03321       fwd = opendir(dir);
03322       if (fwd) {
03323          while((de = readdir(fwd))) {
03324             if (de->d_name[0] != '.') {
03325                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
03326                if (!try_firmware(fn)) {
03327                   ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
03328                }
03329             }
03330          }
03331          closedir(fwd);
03332       } else 
03333          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
03334    }
03335 
03336    /* Clean up leftovers */
03337    AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
03338       if (!cur->dead)
03339          continue;
03340       AST_LIST_REMOVE_CURRENT(list);
03341       destroy_firmware(cur);
03342    }
03343    AST_LIST_TRAVERSE_SAFE_END;
03344 
03345    AST_LIST_UNLOCK(&firmwares);
03346 }

static void remove_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2223 of file chan_iax2.c.

References ao2_unlink, ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.

Referenced by complete_transfer(), iax2_destroy(), resend_with_token(), and socket_process().

02224 {
02225    if (!pvt->peercallno) {
02226       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02227       return;
02228    }
02229 
02230    ao2_unlink(iax_peercallno_pvts, pvt);
02231 }

static void remove_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2204 of file chan_iax2.c.

References ao2_unlink, ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.

Referenced by complete_transfer(), and iax2_destroy().

02205 {
02206    if (!pvt->transfercallno) {
02207       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02208       return;
02209    }
02210 
02211    ao2_unlink(iax_transfercallno_pvts, pvt);
02212 }

static int replace_callno ( const void *  obj  )  [static]

Definition at line 2740 of file chan_iax2.c.

References ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_log(), callno_entry::callno, LOG_ERROR, and callno_entry::validated.

Referenced by __find_callno(), make_trunk(), and sched_delay_remove().

02741 {
02742    struct callno_entry *callno_entry = (struct callno_entry *) obj;
02743 
02744    /* the callno_pool container is locked here primarily to ensure thread
02745     * safety of the total_nonval_callno_used check and decrement */
02746    ao2_lock(callno_pool);
02747 
02748    if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02749       total_nonval_callno_used--;
02750    } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02751       ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02752    }
02753 
02754    if (callno_entry->callno < TRUNK_CALL_START) {
02755       ao2_link(callno_pool, callno_entry);
02756    } else {
02757       ao2_link(callno_pool_trunk, callno_entry);
02758    }
02759    ao2_ref(callno_entry, -1); /* only container ref remains */
02760 
02761    ao2_unlock(callno_pool);
02762    return 0;
02763 }

static void requirecalltoken_mark_auto ( const char *  name,
int  subclass 
) [static]

Definition at line 4926 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().

04927 {
04928    struct iax2_user *user = NULL;
04929    struct iax2_peer *peer = NULL;
04930 
04931    if (ast_strlen_zero(name)) {
04932       return; /* no username given */
04933    }
04934 
04935    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04936       user->calltoken_required = CALLTOKEN_YES;
04937    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04938       peer->calltoken_required = CALLTOKEN_YES;
04939    }
04940 
04941    if (peer) {
04942       peer_unref(peer);
04943    }
04944    if (user) {
04945       user_unref(user);
04946    }
04947 }

static void resend_with_token ( int  callno,
struct iax_frame f,
const char *  newtoken 
) [static]

Definition at line 4844 of file chan_iax2.c.

References iax_frame::af, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_LIST_REMOVE, iax_ie_data::buf, iax_frame::data, iax_frame::datalen, iax_frame::dcallno, iax_frame::encmethods, ast_frame::frametype, iax2_allow_new(), iax2_frame_free(), iax_ie_append_str(), IAX_IE_CALLTOKEN, iaxs, 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().

04845 {
04846    struct chan_iax2_pvt *pvt = iaxs[callno];
04847    int frametype = f->af.frametype;
04848    int subclass = f->af.subclass.integer;
04849    struct {
04850       struct ast_iax2_full_hdr fh;
04851       struct iax_ie_data ied;
04852    } data = {
04853       .ied.buf = { 0 },
04854       .ied.pos = 0,
04855    };
04856    /* total len - header len gives us the frame's IE len */
04857    int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04858 
04859    if (!pvt) {
04860       return;  /* this should not be possible if called from socket_process() */
04861    }
04862 
04863    /* 
04864     * Check to make sure last frame sent is valid for call token resend
04865     * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 
04866     * 2. Frame should _NOT_ already have a destination callno
04867     * 3. Frame must be a valid iax_frame subclass capable of starting dialog
04868     * 4. Pvt must have a calltoken_ie_len which represents the number of
04869     *    bytes at the end of the frame used for the previous calltoken ie.
04870     * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length
04871     * 6. Total length of f->data must be _LESS_ than size of our data struct
04872     *    because f->data must be able to fit within data. 
04873     */
04874    if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04875       || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04876       (f->datalen > sizeof(data))) {
04877 
04878       return;  /* ignore resend, token was not valid for the dialog */
04879    }
04880 
04881    /* token is valid
04882     * 1. Copy frame data over
04883     * 2. Redo calltoken IE, it will always be the last ie in the frame.
04884     *    NOTE: Having the ie always be last is not protocol specified,
04885     *    it is only an implementation choice.  Since we only expect the ie to
04886     *    be last for frames we have sent, this can no way be affected by
04887     *    another end point.
04888     * 3. Remove frame from queue
04889     * 4. Free old frame
04890     * 5. Clear previous seqnos
04891     * 6. Resend with CALLTOKEN ie.
04892     */
04893 
04894    /* ---1.--- */
04895    memcpy(&data, f->data, f->datalen);
04896    data.ied.pos = ie_data_pos;
04897 
04898    /* ---2.--- */
04899    /* move to the beginning of the calltoken ie so we can write over it */
04900    data.ied.pos -= pvt->calltoken_ie_len;
04901    iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04902 
04903    /* make sure to update token length incase it ever has to be stripped off again */
04904    pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */
04905 
04906    /* ---3.--- */
04907    AST_LIST_REMOVE(&frame_queue[callno], f, list);
04908 
04909    /* ---4.--- */
04910    iax2_frame_free(f);
04911 
04912    /* ---5.--- */
04913    pvt->oseqno = 0;
04914    pvt->rseqno = 0;
04915    pvt->iseqno = 0;
04916    pvt->aseqno = 0;
04917    if (pvt->peercallno) {
04918       remove_by_peercallno(pvt);
04919       pvt->peercallno = 0;
04920    }
04921 
04922    /* ---6.--- */
04923    send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04924 }

static void save_osptoken ( struct iax_frame fr,
struct iax_ies ies 
) [static]

Definition at line 9586 of file chan_iax2.c.

References ast_string_field_set, iax_frame::callno, IAX_MAX_OSPBLOCK_NUM, IAX_MAX_OSPBLOCK_SIZE, IAX_MAX_OSPBUFF_SIZE, iaxs, iax_ies::ospblocklength, and iax_ies::osptokenblock.

Referenced by socket_process().

09587 {
09588    int i;
09589    unsigned int length, offset = 0;
09590    char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09591 
09592    for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09593       length = ies->ospblocklength[i];
09594       if (length != 0) {
09595          if (length > IAX_MAX_OSPBLOCK_SIZE) {
09596             /* OSP token block length wrong, clear buffer */
09597             offset = 0;
09598             break;
09599          } else {
09600             memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09601             offset += length;
09602          }
09603       } else {
09604          break;
09605       }
09606    }
09607    *(full_osptoken + offset) = '\0';
09608    if (strlen(full_osptoken) != offset) {
09609       /* OSP token length wrong, clear buffer */
09610       *full_osptoken = '\0';
09611    }
09612 
09613    ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09614 }

static void save_rr ( struct iax_frame fr,
struct iax_ies ies 
) [static]

Definition at line 9575 of file chan_iax2.c.

References iax_frame::callno, iaxs, 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().

09576 {
09577    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09578    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09579    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09580    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09581    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09582    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09583    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09584 }

static void sched_delay_remove ( struct sockaddr_in *  sin,
struct callno_entry callno_entry 
) [static]

Definition at line 2812 of file chan_iax2.c.

References 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().

02813 {
02814    int i;
02815    struct peercnt *peercnt;
02816    struct peercnt tmp = {
02817       .addr = sin->sin_addr.s_addr,
02818    };
02819 
02820    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02821       /* refcount is incremented with ao2_find.  keep that ref for the scheduler */
02822       ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02823       i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02824       if (i == -1) {
02825          ao2_ref(peercnt, -1);
02826       }
02827    }
02828 
02829    iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02830 }

static int schedule_delivery ( struct iax_frame fr,
int  updatehistory,
int  fromtrunk,
unsigned int *  tsout 
) [static]
Note:
This function assumes fr->callno is locked
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 4243 of file chan_iax2.c.

References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_channel_unlock, ast_codec_get_samples(), ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_samp2tv(), ast_sched_thread_del, ast_test_flag64, ast_tv(), ast_tvadd(), ast_tvzero(), ast_channel::bridge, calc_rxstamp(), iax_frame::callno, ast_frame_subclass::codec, jb_frame::data, ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_lock_owner(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, 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, len(), 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().

04244 {
04245    int type, len;
04246    int ret;
04247    int needfree = 0;
04248    struct ast_channel *owner = NULL;
04249    struct ast_channel *bridge = NULL;
04250 
04251    /*
04252     * Clear fr->af.data if there is no data in the buffer.  Things
04253     * like AST_CONTROL_HOLD without a suggested music class must
04254     * have a NULL pointer.
04255     */
04256    if (!fr->af.datalen) {
04257       memset(&fr->af.data, 0, sizeof(fr->af.data));
04258    }
04259 
04260    /* Attempt to recover wrapped timestamps */
04261    unwrap_timestamp(fr);
04262 
04263    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
04264    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
04265       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
04266    else {
04267 #if 0
04268       ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
04269 #endif
04270       fr->af.delivery = ast_tv(0,0);
04271    }
04272 
04273    type = JB_TYPE_CONTROL;
04274    len = 0;
04275 
04276    if(fr->af.frametype == AST_FRAME_VOICE) {
04277       type = JB_TYPE_VOICE;
04278       len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000);
04279    } else if(fr->af.frametype == AST_FRAME_CNG) {
04280       type = JB_TYPE_SILENCE;
04281    }
04282 
04283    if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
04284       if (tsout)
04285          *tsout = fr->ts;
04286       __do_deliver(fr);
04287       return -1;
04288    }
04289 
04290    iax2_lock_owner(fr->callno);
04291    if (!iaxs[fr->callno]) {
04292       /* The call dissappeared so discard this frame that we could not send. */
04293       iax2_frame_free(fr);
04294       return -1;
04295    }
04296    if ((owner = iaxs[fr->callno]->owner))
04297       bridge = ast_bridged_channel(owner);
04298 
04299    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
04300     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
04301    if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
04302       jb_frame frame;
04303 
04304       ast_channel_unlock(owner);
04305 
04306       /* deliver any frames in the jb */
04307       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
04308          __do_deliver(frame.data);
04309          /* __do_deliver() can make the call disappear */
04310          if (!iaxs[fr->callno])
04311             return -1;
04312       }
04313 
04314       jb_reset(iaxs[fr->callno]->jb);
04315 
04316       ast_sched_thread_del(sched, iaxs[fr->callno]->jbid);
04317 
04318       /* deliver this frame now */
04319       if (tsout)
04320          *tsout = fr->ts;
04321       __do_deliver(fr);
04322       return -1;
04323    }
04324    if (owner) {
04325       ast_channel_unlock(owner);
04326    }
04327 
04328    /* insert into jitterbuffer */
04329    /* TODO: Perhaps we could act immediately if it's not droppable and late */
04330    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
04331          calc_rxstamp(iaxs[fr->callno],fr->ts));
04332    if (ret == JB_DROP) {
04333       needfree++;
04334    } else if (ret == JB_SCHED) {
04335       update_jbsched(iaxs[fr->callno]);
04336    }
04337    if (tsout)
04338       *tsout = fr->ts;
04339    if (needfree) {
04340       /* Free our iax frame */
04341       iax2_frame_free(fr);
04342       return -1;
04343    }
04344    return 0;
04345 }

static int scheduled_destroy ( const void *  vid  )  [static]

Definition at line 1889 of file chan_iax2.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_destroy(), iaxs, iaxsl, LOG_DEBUG, option_debug, and PTR_TO_CALLNO.

Referenced by iax2_hangup().

01890 {
01891    unsigned short callno = PTR_TO_CALLNO(vid);
01892    ast_mutex_lock(&iaxsl[callno]);
01893    if (iaxs[callno]) {
01894       if (option_debug) {
01895          ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01896       }
01897       iax2_destroy(callno);
01898    }
01899    ast_mutex_unlock(&iaxsl[callno]);
01900    return 0;
01901 }

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 4806 of file chan_iax2.c.

References AST_FRAME_IAX, iax_ie_data::buf, compress_subclass(), IAX_FLAG_RETRANS, iax_outputframe(), and iax_ie_data::pos.

Referenced by handle_call_token(), and socket_process().

04809 {
04810    struct {
04811       struct ast_iax2_full_hdr f;
04812       struct iax_ie_data ied;
04813    } data;
04814    size_t size = sizeof(struct ast_iax2_full_hdr);
04815 
04816    if (ied) {
04817       size += ied->pos;
04818       memcpy(&data.ied, ied->buf, ied->pos);
04819    }
04820 
04821    data.f.scallno = htons(0x8000 | callno);
04822    data.f.dcallno = htons(dcallno & ~IAX_FLAG_RETRANS);
04823    data.f.ts = htonl(ts);
04824    data.f.iseqno = seqno;
04825    data.f.oseqno = 0;
04826    data.f.type = AST_FRAME_IAX;
04827    data.f.csub = compress_subclass(command);
04828 
04829    iax_outputframe(NULL, &data.f, 0, sin, size - sizeof(struct ast_iax2_full_hdr));
04830 
04831    return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04832 }

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 7612 of file chan_iax2.c.

References __send_command(), ast_debug, AST_FRAME_CONTROL, chan_iax2_pvt::callno, and iax2_is_control_frame_allowed().

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().

07613 {
07614    if (type == AST_FRAME_CONTROL && !iax2_is_control_frame_allowed(command)) {
07615       /* Control frame should not go out on the wire. */
07616       ast_debug(2, "Callno %d: Blocked sending control frame %d.\n",
07617          i->callno, command);
07618       return 0;
07619    }
07620    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07621 }

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]
Note:
Since this function calls iax2_predestroy() -> iax2_queue_hangup(), the pvt struct for the given call number may disappear during its execution.

Definition at line 7637 of file chan_iax2.c.

References __send_command(), chan_iax2_pvt::callno, iax2_predestroy(), and iaxs.

Referenced by __auth_reject(), __auto_hangup(), authenticate_request(), iax2_hangup(), socket_process(), and update_registry().

07638 {
07639    int call_num = i->callno;
07640    /* It is assumed that the callno has already been locked */
07641    iax2_predestroy(i->callno);
07642    if (!iaxs[call_num])
07643       return -1;
07644    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07645 }

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 7647 of file chan_iax2.c.

References __send_command().

Referenced by iax2_vnak(), and socket_process().

07648 {
07649    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07650 }

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 7623 of file chan_iax2.c.

References ast_mutex_lock, ast_mutex_unlock, iaxs, iaxsl, and send_command().

Referenced by iax2_answer(), iax2_digit_begin(), iax2_digit_end(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), and iax2_transfer().

07624 {
07625    int res;
07626    ast_mutex_lock(&iaxsl[callno]);
07627    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07628    ast_mutex_unlock(&iaxsl[callno]);
07629    return res;
07630 }

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 7652 of file chan_iax2.c.

References __send_command().

Referenced by socket_process(), and try_transfer().

07653 {
07654    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07655 }

static int send_lagrq ( const void *  data  )  [static]

Definition at line 1675 of file chan_iax2.c.

References __send_lagrq(), ast_mutex_lock, ast_mutex_unlock, DONT_RESCHEDULE, iaxs, iaxsl, chan_iax2_pvt::lagid, and schedule_action.

Referenced by __find_callno(), __send_lagrq(), and make_trunk().

01676 {
01677    int callno = (long) data;
01678    ast_mutex_lock(&iaxsl[callno]);
01679    if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) {
01680       iaxs[callno]->lagid = -1;
01681    }
01682    ast_mutex_unlock(&iaxsl[callno]);
01683 
01684 #ifdef SCHED_MULTITHREADED
01685    if (schedule_action(__send_lagrq, data))
01686 #endif
01687       __send_lagrq(data);
01688    return 0;
01689 }

static int send_packet ( struct iax_frame f  )  [static]

Definition at line 3418 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_outputframe(), iaxs, 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().

03419 {
03420    int res;
03421    int callno = f->callno;
03422 
03423    /* Don't send if there was an error, but return error instead */
03424    if (!callno || !iaxs[callno] || iaxs[callno]->error)
03425        return -1;
03426    
03427    /* Called with iaxsl held */
03428    if (iaxdebug)
03429       ast_debug(3, "Sending %u 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));
03430    
03431    if (f->transfer) {
03432       iax_outputframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03433       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03434    } else {
03435       iax_outputframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03436       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03437    }
03438    if (res < 0) {
03439       if (iaxdebug)
03440          ast_debug(1, "Received error: %s\n", strerror(errno));
03441       handle_error();
03442    } else
03443       res = 0;
03444 
03445    return res;
03446 }

static int send_ping ( const void *  data  )  [static]

Definition at line 1608 of file chan_iax2.c.

References __send_ping(), ast_mutex_lock, ast_mutex_unlock, DONT_RESCHEDULE, iaxs, iaxsl, chan_iax2_pvt::pingid, and schedule_action.

Referenced by __find_callno(), __send_ping(), and make_trunk().

01609 {
01610    int callno = (long) data;
01611    ast_mutex_lock(&iaxsl[callno]);
01612    if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) {
01613       iaxs[callno]->pingid = -1;
01614    }
01615    ast_mutex_unlock(&iaxsl[callno]);
01616 
01617 #ifdef SCHED_MULTITHREADED
01618    if (schedule_action(__send_ping, data))
01619 #endif
01620       __send_ping(data);
01621 
01622    return 0;
01623 }

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 1913 of file chan_iax2.c.

References AST_LIST_REMOVE_HEAD, signaling_queue_entry::f, free_signaling_queue_entry(), and iax2_send().

Referenced by socket_process().

01914 {
01915    struct signaling_queue_entry *s = NULL;
01916 
01917    while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01918       iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
01919       free_signaling_queue_entry(s);
01920    }
01921    pvt->hold_signaling = 0;
01922 }

static int send_trunk ( struct iax2_trunk_peer tpeer,
struct timeval *  now 
) [static]

Definition at line 9239 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().

09240 {
09241    int res = 0;
09242    struct iax_frame *fr;
09243    struct ast_iax2_meta_hdr *meta;
09244    struct ast_iax2_meta_trunk_hdr *mth;
09245    int calls = 0;
09246    
09247    /* Point to frame */
09248    fr = (struct iax_frame *)tpeer->trunkdata;
09249    /* Point to meta data */
09250    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
09251    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
09252    if (tpeer->trunkdatalen) {
09253       /* We're actually sending a frame, so fill the meta trunk header and meta header */
09254       meta->zeros = 0;
09255       meta->metacmd = IAX_META_TRUNK;
09256       if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS))
09257          meta->cmddata = IAX_META_TRUNK_MINI;
09258       else
09259          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
09260       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
09261       /* And the rest of the ast_iax2 header */
09262       fr->direction = DIRECTION_OUTGRESS;
09263       fr->retrans = -1;
09264       fr->transfer = 0;
09265       /* Any appropriate call will do */
09266       fr->data = fr->afdata;
09267       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
09268       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
09269       calls = tpeer->calls;
09270 #if 0
09271       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));
09272 #endif      
09273       /* Reset transmit trunk side data */
09274       tpeer->trunkdatalen = 0;
09275       tpeer->calls = 0;
09276    }
09277    if (res < 0)
09278       return res;
09279    return calls;
09280 }

static int set_config ( const char *  config_file,
int  reload 
) [static]

Load configuration.

Definition at line 13264 of file chan_iax2.c.

References add_calltoken_ignore(), ao2_link, ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, ast_clear_flag64, ast_config_destroy(), ast_config_load, ast_context_find_or_create(), ast_copy_string(), ast_false(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_netsock_bind(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_allow_disallow(), ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_str2cos(), ast_str2tos(), ast_strlen_zero(), ast_test_flag64, ast_timer_set_rate(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, build_callno_limits(), build_peer(), build_user(), capability, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), 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(), and reload_config().

13265 {
13266    struct ast_config *cfg, *ucfg;
13267    format_t capability = iax2_capability;
13268    struct ast_variable *v;
13269    char *cat;
13270    const char *utype;
13271    const char *tosval;
13272    int format;
13273    int portno = IAX_DEFAULT_PORTNO;
13274    int  x;
13275    int mtuv;
13276    int subscribe_network_change = 1;
13277    struct iax2_user *user;
13278    struct iax2_peer *peer;
13279    struct ast_netsock *ns;
13280    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
13281 #if 0
13282    static unsigned short int last_port=0;
13283 #endif
13284 
13285    cfg = ast_config_load(config_file, config_flags);
13286 
13287    if (!cfg) {
13288       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
13289       return -1;
13290    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
13291       ucfg = ast_config_load("users.conf", config_flags);
13292       if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
13293          return 0;
13294       /* Otherwise we need to reread both files */
13295       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13296       if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
13297          ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", config_file);
13298          ast_config_destroy(ucfg);
13299          return 0;
13300       }
13301       if (!cfg) {
13302          /* should have been able to load the config here */
13303          ast_log(LOG_ERROR, "Unable to load config %s again\n", config_file);
13304          return -1;
13305       }
13306    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
13307       ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", config_file);
13308       return 0;
13309    } else { /* iax.conf changed, gotta reread users.conf, too */
13310       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13311       if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
13312          ast_log(LOG_ERROR, "Config file users.conf is in an invalid format.  Aborting.\n");
13313          ast_config_destroy(cfg);
13314          return 0;
13315       }
13316    }
13317 
13318    if (reload) {
13319       set_config_destroy();
13320    }
13321 
13322    /* Reset global codec prefs */
13323    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
13324 
13325    /* Reset Global Flags */
13326    memset(&globalflags, 0, sizeof(globalflags));
13327    ast_set_flag64(&globalflags, IAX_RTUPDATE);
13328    ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13329 
13330 #ifdef SO_NO_CHECK
13331    nochecksums = 0;
13332 #endif
13333    /* Reset default parking lot */
13334    default_parkinglot[0] = '\0';
13335 
13336    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13337    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13338    global_max_trunk_mtu = MAX_TRUNK_MTU;
13339    global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
13340    global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
13341 
13342    maxauthreq = 3;
13343 
13344    srvlookup = 0;
13345 
13346    v = ast_variable_browse(cfg, "general");
13347 
13348    /* Seed initial tos value */
13349    tosval = ast_variable_retrieve(cfg, "general", "tos");
13350    if (tosval) {
13351       if (ast_str2tos(tosval, &qos.tos))
13352          ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13353    }
13354    /* Seed initial cos value */
13355    tosval = ast_variable_retrieve(cfg, "general", "cos");
13356    if (tosval) {
13357       if (ast_str2cos(tosval, &qos.cos))
13358          ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13359    }
13360    while(v) {
13361       if (!strcasecmp(v->name, "bindport")){ 
13362          if (reload)
13363             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13364          else
13365             portno = atoi(v->value);
13366       } else if (!strcasecmp(v->name, "pingtime")) 
13367          ping_time = atoi(v->value);
13368       else if (!strcasecmp(v->name, "iaxthreadcount")) {
13369          if (reload) {
13370             if (atoi(v->value) != iaxthreadcount)
13371                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13372          } else {
13373             iaxthreadcount = atoi(v->value);
13374             if (iaxthreadcount < 1) {
13375                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13376                iaxthreadcount = 1;
13377             } else if (iaxthreadcount > 256) {
13378                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13379                iaxthreadcount = 256;
13380             }
13381          }
13382       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13383          if (reload) {
13384             AST_LIST_LOCK(&dynamic_list);
13385             iaxmaxthreadcount = atoi(v->value);
13386             AST_LIST_UNLOCK(&dynamic_list);
13387          } else {
13388             iaxmaxthreadcount = atoi(v->value);
13389             if (iaxmaxthreadcount < 0) {
13390                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13391                iaxmaxthreadcount = 0;
13392             } else if (iaxmaxthreadcount > 256) {
13393                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13394                iaxmaxthreadcount = 256;
13395             }
13396          }
13397       } else if (!strcasecmp(v->name, "nochecksums")) {
13398 #ifdef SO_NO_CHECK
13399          if (ast_true(v->value))
13400             nochecksums = 1;
13401          else
13402             nochecksums = 0;
13403 #else
13404          if (ast_true(v->value))
13405             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13406 #endif
13407       }
13408       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
13409          maxjitterbuffer = atoi(v->value);
13410       else if (!strcasecmp(v->name, "resyncthreshold")) 
13411          resyncthreshold = atoi(v->value);
13412       else if (!strcasecmp(v->name, "maxjitterinterps")) 
13413          maxjitterinterps = atoi(v->value);
13414       else if (!strcasecmp(v->name, "jittertargetextra"))
13415          jittertargetextra = atoi(v->value);
13416       else if (!strcasecmp(v->name, "lagrqtime")) 
13417          lagrq_time = atoi(v->value);
13418       else if (!strcasecmp(v->name, "maxregexpire")) 
13419          max_reg_expire = atoi(v->value);
13420       else if (!strcasecmp(v->name, "minregexpire")) 
13421          min_reg_expire = atoi(v->value);
13422       else if (!strcasecmp(v->name, "bindaddr")) {
13423          if (reload) {
13424             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13425          } else {
13426             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
13427                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
13428             } else {
13429                   if (strchr(v->value, ':'))
13430                   ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
13431                   else
13432                   ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
13433                if (defaultsockfd < 0) 
13434                   defaultsockfd = ast_netsock_sockfd(ns);
13435                ast_netsock_unref(ns);
13436             }
13437          }
13438       } else if (!strcasecmp(v->name, "authdebug")) {
13439          authdebug = ast_true(v->value);
13440       } else if (!strcasecmp(v->name, "encryption")) {
13441             iax2_encryption |= get_encrypt_methods(v->value);
13442             if (!iax2_encryption) {
13443                ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13444             }
13445       } else if (!strcasecmp(v->name, "forceencryption")) {
13446          if (ast_false(v->value)) {
13447             ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13448          } else {
13449             iax2_encryption |= get_encrypt_methods(v->value);
13450             if (iax2_encryption) {
13451                ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13452             }
13453          }
13454       } else if (!strcasecmp(v->name, "transfer")) {
13455          if (!strcasecmp(v->value, "mediaonly")) {
13456             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13457          } else if (ast_true(v->value)) {
13458             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13459          } else
13460             ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13461       } else if (!strcasecmp(v->name, "codecpriority")) {
13462          if(!strcasecmp(v->value, "caller"))
13463             ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST);
13464          else if(!strcasecmp(v->value, "disabled"))
13465             ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13466          else if(!strcasecmp(v->value, "reqonly")) {
13467             ast_set_flag64((&globalflags), IAX_CODEC_NOCAP);
13468             ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13469          }
13470       } else if (!strcasecmp(v->name, "jitterbuffer"))
13471          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
13472       else if (!strcasecmp(v->name, "forcejitterbuffer"))
13473          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
13474       else if (!strcasecmp(v->name, "delayreject"))
13475          delayreject = ast_true(v->value);
13476       else if (!strcasecmp(v->name, "allowfwdownload"))
13477          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
13478       else if (!strcasecmp(v->name, "rtcachefriends"))
13479          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
13480       else if (!strcasecmp(v->name, "rtignoreregexpire"))
13481          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
13482       else if (!strcasecmp(v->name, "rtupdate"))
13483          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE);
13484       else if (!strcasecmp(v->name, "rtsavesysname"))
13485          ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME);
13486       else if (!strcasecmp(v->name, "trunktimestamps"))
13487          ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
13488       else if (!strcasecmp(v->name, "rtautoclear")) {
13489          int i = atoi(v->value);
13490          if(i > 0)
13491             global_rtautoclear = i;
13492          else
13493             i = 0;
13494          ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
13495       } else if (!strcasecmp(v->name, "trunkfreq")) {
13496          trunkfreq = atoi(v->value);
13497          if (trunkfreq < 10) {
13498             ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 10ms instead.\n");
13499             trunkfreq = 10;
13500          } else if (trunkfreq > 1000) {
13501             ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 1000ms instead.\n");
13502             trunkfreq = 1000;
13503          }
13504          if (timer) {
13505             ast_timer_set_rate(timer, 1000 / trunkfreq);
13506          }
13507       } else if (!strcasecmp(v->name, "trunkmtu")) {
13508          mtuv = atoi(v->value);
13509          if (mtuv  == 0 )
13510             global_max_trunk_mtu = 0;
13511          else if (mtuv >= 172 && mtuv < 4000)
13512             global_max_trunk_mtu = mtuv;
13513          else
13514             ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13515                mtuv, v->lineno);
13516       } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13517          trunkmaxsize = atoi(v->value);
13518          if (trunkmaxsize == 0)
13519             trunkmaxsize = MAX_TRUNKDATA;
13520       } else if (!strcasecmp(v->name, "autokill")) {
13521          if (sscanf(v->value, "%30d", &x) == 1) {
13522             if (x >= 0)
13523                autokill = x;
13524             else
13525                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13526          } else if (ast_true(v->value)) {
13527             autokill = DEFAULT_MAXMS;
13528          } else {
13529             autokill = 0;
13530          }
13531       } else if (!strcasecmp(v->name, "bandwidth")) {
13532          if (!strcasecmp(v->value, "low")) {
13533             capability = IAX_CAPABILITY_LOWBANDWIDTH;
13534          } else if (!strcasecmp(v->value, "medium")) {
13535             capability = IAX_CAPABILITY_MEDBANDWIDTH;
13536          } else if (!strcasecmp(v->value, "high")) {
13537             capability = IAX_CAPABILITY_FULLBANDWIDTH;
13538          } else
13539             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13540       } else if (!strcasecmp(v->name, "allow")) {
13541          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
13542       } else if (!strcasecmp(v->name, "disallow")) {
13543          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
13544       } else if (!strcasecmp(v->name, "register")) {
13545          iax2_register(v->value, v->lineno);
13546       } else if (!strcasecmp(v->name, "iaxcompat")) {
13547          iaxcompat = ast_true(v->value);
13548       } else if (!strcasecmp(v->name, "regcontext")) {
13549          ast_copy_string(regcontext, v->value, sizeof(regcontext));
13550          /* Create context if it doesn't exist already */
13551          ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
13552       } else if (!strcasecmp(v->name, "tos")) {
13553          if (ast_str2tos(v->value, &qos.tos))
13554             ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13555       } else if (!strcasecmp(v->name, "cos")) {
13556          if (ast_str2cos(v->value, &qos.cos))
13557             ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13558       } else if (!strcasecmp(v->name, "parkinglot")) {
13559          ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
13560       } else if (!strcasecmp(v->name, "accountcode")) {
13561          ast_copy_string(accountcode, v->value, sizeof(accountcode));
13562       } else if (!strcasecmp(v->name, "mohinterpret")) {
13563          ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
13564       } else if (!strcasecmp(v->name, "mohsuggest")) {
13565          ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
13566       } else if (!strcasecmp(v->name, "amaflags")) {
13567          format = ast_cdr_amaflags2int(v->value);
13568          if (format < 0) {
13569             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13570          } else {
13571             amaflags = format;
13572          }
13573       } else if (!strcasecmp(v->name, "language")) {
13574          ast_copy_string(language, v->value, sizeof(language));
13575       } else if (!strcasecmp(v->name, "maxauthreq")) {
13576          maxauthreq = atoi(v->value);
13577          if (maxauthreq < 0)
13578             maxauthreq = 0;
13579       } else if (!strcasecmp(v->name, "adsi")) {
13580          adsi = ast_true(v->value);
13581       } else if (!strcasecmp(v->name, "srvlookup")) {
13582          srvlookup = ast_true(v->value);
13583       } else if (!strcasecmp(v->name, "connectedline")) {
13584          if (ast_true(v->value)) {
13585             ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13586          } else if (!strcasecmp(v->value, "send")) {
13587             ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13588             ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13589          } else if (!strcasecmp(v->value, "receive")) {
13590             ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13591             ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13592          } else {
13593             ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13594          }
13595       } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13596          if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
13597             ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number.  %s is not valid at line %d\n", v->value, v->lineno);
13598          }
13599       } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
13600          if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
13601             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);
13602          }
13603       } else if (!strcasecmp(v->name, "calltokenoptional")) {
13604          if (add_calltoken_ignore(v->value)) {
13605             ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
13606          }
13607       } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
13608          if (ast_true(v->value)) {
13609             subscribe_network_change = 1;
13610          } else if (ast_false(v->value)) {
13611             subscribe_network_change = 0;
13612          } else {
13613             ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
13614          }
13615       } else if (!strcasecmp(v->name, "shrinkcallerid")) {
13616          if (ast_true(v->value)) {
13617             ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13618          } else if (ast_false(v->value)) {
13619             ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID);
13620          } else {
13621             ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
13622          }
13623       }/*else if (strcasecmp(v->name,"type")) */
13624       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
13625       v = v->next;
13626    }
13627 
13628    if (subscribe_network_change) {
13629       network_change_event_subscribe();
13630    } else {
13631       network_change_event_unsubscribe();
13632    }
13633 
13634    if (defaultsockfd < 0) {
13635       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
13636          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
13637       } else {
13638          ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
13639          defaultsockfd = ast_netsock_sockfd(ns);
13640          ast_netsock_unref(ns);
13641       }
13642    }
13643    if (reload) {
13644       ast_netsock_release(outsock);
13645       outsock = ast_netsock_list_alloc();
13646       if (!outsock) {
13647          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13648          return -1;
13649       }
13650       ast_netsock_init(outsock);
13651    }
13652 
13653    if (min_reg_expire > max_reg_expire) {
13654       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
13655          min_reg_expire, max_reg_expire, max_reg_expire);
13656       min_reg_expire = max_reg_expire;
13657    }
13658    iax2_capability = capability;
13659    
13660    if (ucfg) {
13661       struct ast_variable *gen;
13662       int genhasiax;
13663       int genregisteriax;
13664       const char *hasiax, *registeriax;
13665       
13666       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
13667       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
13668       gen = ast_variable_browse(ucfg, "general");
13669       cat = ast_category_browse(ucfg, NULL);
13670       while (cat) {
13671          if (strcasecmp(cat, "general")) {
13672             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
13673             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
13674             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
13675                /* Start with general parameters, then specific parameters, user and peer */
13676                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
13677                if (user) {
13678                   ao2_link(users, user);
13679                   user = user_unref(user);
13680                }
13681                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
13682                if (peer) {
13683                   if (ast_test_flag64(peer, IAX_DYNAMIC))
13684                      reg_source_db(peer);
13685                   ao2_link(peers, peer);
13686                   peer = peer_unref(peer);
13687                }
13688             }
13689             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
13690                char tmp[256];
13691                const char *host = ast_variable_retrieve(ucfg, cat, "host");
13692                const char *username = ast_variable_retrieve(ucfg, cat, "username");
13693                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
13694                if (!host)
13695                   host = ast_variable_retrieve(ucfg, "general", "host");
13696                if (!username)
13697                   username = ast_variable_retrieve(ucfg, "general", "username");
13698                if (!secret)
13699                   secret = ast_variable_retrieve(ucfg, "general", "secret");
13700                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
13701                   if (!ast_strlen_zero(secret))
13702                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
13703                   else
13704                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
13705                   iax2_register(tmp, 0);
13706                }
13707             }
13708          }
13709          cat = ast_category_browse(ucfg, cat);
13710       }
13711       ast_config_destroy(ucfg);
13712    }
13713    
13714    cat = ast_category_browse(cfg, NULL);
13715    while(cat) {
13716       if (strcasecmp(cat, "general")) {
13717          utype = ast_variable_retrieve(cfg, cat, "type");
13718          if (!strcasecmp(cat, "callnumberlimits")) {
13719             build_callno_limits(ast_variable_browse(cfg, cat));
13720          } else if (utype) {
13721             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
13722                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
13723                if (user) {
13724                   ao2_link(users, user);
13725                   user = user_unref(user);
13726                }
13727             }
13728             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
13729                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
13730                if (peer) {
13731                   if (ast_test_flag64(peer, IAX_DYNAMIC))
13732                      reg_source_db(peer);
13733                   ao2_link(peers, peer);
13734                   peer = peer_unref(peer);
13735                }
13736             } else if (strcasecmp(utype, "user")) {
13737                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
13738             }
13739          } else
13740             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
13741       }
13742       cat = ast_category_browse(cfg, cat);
13743    }
13744    ast_config_destroy(cfg);
13745    return 1;
13746 }

static void set_config_destroy ( void   )  [static]
static void set_hangup_source_and_cause ( int  callno,
unsigned char  causecode 
) [static]

Definition at line 10030 of file chan_iax2.c.

References ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_mutex_lock, ast_mutex_unlock, ast_set_hangupsource(), ast_strdupa, ast_channel::hangupcause, iax2_lock_owner(), iaxs, iaxsl, name, and chan_iax2_pvt::owner.

Referenced by socket_process().

10031 {
10032    iax2_lock_owner(callno);
10033    if (iaxs[callno] && iaxs[callno]->owner) {
10034       struct ast_channel *owner;
10035       const char *name;
10036 
10037       owner = iaxs[callno]->owner;
10038       if (causecode) {
10039          owner->hangupcause = causecode;
10040       }
10041       name = ast_strdupa(owner->name);
10042       ast_channel_ref(owner);
10043       ast_channel_unlock(owner);
10044       ast_mutex_unlock(&iaxsl[callno]);
10045       ast_set_hangupsource(owner, name, 0);
10046       ast_channel_unref(owner);
10047       ast_mutex_lock(&iaxsl[callno]);
10048    }
10049 }

static void set_peercnt_limit ( struct peercnt *  peercnt  )  [static]

Definition at line 2348 of file chan_iax2.c.

References addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_inet_ntoa(), and addr_range::limit.

Referenced by peercnt_add(), peercnt_modify(), and set_peercnt_limit_all_cb().

02349 {
02350    uint16_t limit = global_maxcallno;
02351    struct addr_range *addr_range;
02352    struct sockaddr_in sin = {
02353       .sin_addr.s_addr = peercnt->addr,
02354    };
02355 
02356 
02357    if (peercnt->reg && peercnt->limit) {
02358       return; /* this peercnt has a custom limit set by a registration */
02359    }
02360 
02361    if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02362       limit = addr_range->limit;
02363       ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02364       ao2_ref(addr_range, -1);
02365    }
02366 
02367    peercnt->limit = limit;
02368 }

static int set_peercnt_limit_all_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 2374 of file chan_iax2.c.

References ast_debug, and set_peercnt_limit().

Referenced by reload_config().

02375 {
02376    struct peercnt *peercnt = obj;
02377 
02378    set_peercnt_limit(peercnt);
02379    ast_debug(1, "Reset limits for peercnts table\n");
02380 
02381    return 0;
02382 }

static void signal_condition ( ast_mutex_t lock,
ast_cond_t cond 
) [static]

Definition at line 1052 of file chan_iax2.c.

References ast_cond_signal, ast_mutex_lock, and ast_mutex_unlock.

Referenced by __schedule_action(), cleanup_thread_list(), iax2_process_thread(), and socket_read().

01053 {
01054    ast_mutex_lock(lock);
01055    ast_cond_signal(cond);
01056    ast_mutex_unlock(lock);
01057 }

static int socket_process ( struct iax2_thread thread  )  [static]

Definition at line 10051 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_alloca, ast_async_goto(), ast_best_codec(), ast_bridged_channel(), ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_channel_datastore_add(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_clear_flag, ast_clear_flag64, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), ast_connected_line_parse_data(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_UNHOLD, ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_free, ast_getformatname(), ast_getformatname_multiple(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_event, ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, ast_parking_ext_valid(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_party_id_presentation(), ast_sched_thread_del, ast_set_callerid(), ast_set_flag, ast_set_flag64, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_var_assign(), ast_variables_destroy(), ast_verb, auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), chan_iax2_pvt::authmethods, iax_ie_data::buf, 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, cid_num, ast_frame_subclass::codec, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), context, ast_iax2_full_hdr::csub, ast_datastore::data, ast_frame::data, ast_frame::datalen, DATASTORE_INHERIT_FOREVER, ast_iax2_full_hdr::dcallno, DEADLOCK_AVOIDANCE, decrypt_frame(), iax_ies::devicetype, dp_lookup(), chan_iax2_pvt::encmethods, iax_ies::encmethods, chan_iax2_pvt::error, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, iax_frame::final, find_callno(), chan_iax2_pvt::first_iax_message, iax2_dpcache::flags, iax_ies::format, format, ast_frame::frametype, iax_ies::fwdesc, handle_call_token(), ast_channel::hangupcause, iax2_peer::historicms, iax2_ack_registry(), iax2_allow_new(), iax2_destroy(), iax2_dprequest(), iax2_is_control_frame_allowed(), iax2_lock_owner(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), iax2_send(), iax2_variable_datastore_info, iax2_vnak(), IAX_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CALLENCRYPTED, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_RTKEY, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DEBUGDIGEST, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, IAX_FORCE_ENCRYPT, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), iax_ie_append_versioned_uint64(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_FORMAT2, IAX_IE_IAX_UNKNOWN, IAX_IMMEDIATE, iax_outputframe(), iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, IAX_RECVCONNECTEDLINE, IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iax_ies::iax_unknown, iaxfrdup2(), iaxs, iaxsl, ast_party_caller::id, ast_party_connected_line::id, inaddrcmp(), ast_datastore::inheritance, chan_iax2_pvt::initid, ast_frame_subclass::integer, 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, iax_ies::musiconhold, ast_party_id::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(), 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_NONE, 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().

10052 {
10053    struct sockaddr_in sin;
10054    int res;
10055    int updatehistory=1;
10056    int new = NEW_PREVENT;
10057    int dcallno = 0;
10058    char decrypted = 0;
10059    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
10060    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
10061    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
10062    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
10063    struct iax_frame *fr;
10064    struct iax_frame *cur;
10065    struct ast_frame f = { 0, };
10066    struct ast_channel *c = NULL;
10067    struct iax2_dpcache *dp;
10068    struct iax2_peer *peer;
10069    struct iax_ies ies;
10070    struct iax_ie_data ied0, ied1;
10071    format_t format;
10072    int fd;
10073    int exists;
10074    int minivid = 0;
10075    char empty[32]="";      /* Safety measure */
10076    struct iax_frame *duped_fr;
10077    char host_pref_buf[128];
10078    char caller_pref_buf[128];
10079    struct ast_codec_pref pref;
10080    char *using_prefs = "mine";
10081 
10082    /* allocate an iax_frame with 4096 bytes of data buffer */
10083    fr = ast_alloca(sizeof(*fr) + 4096);
10084    memset(fr, 0, sizeof(*fr));
10085    fr->afdatalen = 4096; /* From ast_alloca() above */
10086 
10087    /* Copy frequently used parameters to the stack */
10088    res = thread->buf_len;
10089    fd = thread->iofd;
10090    memcpy(&sin, &thread->iosin, sizeof(sin));
10091 
10092    if (res < sizeof(*mh)) {
10093       ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
10094       return 1;
10095    }
10096    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
10097       if (res < sizeof(*vh)) {
10098          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));
10099          return 1;
10100       }
10101 
10102       /* This is a video frame, get call number */
10103       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
10104       minivid = 1;
10105    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
10106       return socket_process_meta(res, meta, &sin, fd, fr);
10107 
10108 #ifdef DEBUG_SUPPORT
10109    if (res >= sizeof(*fh))
10110       iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
10111 #endif
10112    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10113       if (res < sizeof(*fh)) {
10114          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));
10115          return 1;
10116       }
10117 
10118       /* Get the destination call number */
10119       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
10120 
10121 
10122       /* check to make sure this full frame isn't encrypted before we attempt
10123        * to look inside of it. If it is encrypted, decrypt it first. Its ok if the
10124        * callno is not found here, that just means one hasn't been allocated for
10125        * this connection yet. */
10126       if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
10127          ast_mutex_lock(&iaxsl[fr->callno]);
10128          if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
10129             if (decrypt_frame(fr->callno, fh, &f, &res)) {
10130                ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10131                ast_mutex_unlock(&iaxsl[fr->callno]);
10132                return 1;
10133             }
10134             decrypted = 1;
10135          }
10136          ast_mutex_unlock(&iaxsl[fr->callno]);
10137       }
10138 
10139       /* Retrieve the type and subclass */
10140       f.frametype = fh->type;
10141       if (f.frametype == AST_FRAME_VIDEO) {
10142          f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
10143       } else if (f.frametype == AST_FRAME_VOICE) {
10144          f.subclass.codec = uncompress_subclass(fh->csub);
10145       } else {
10146          f.subclass.integer = uncompress_subclass(fh->csub);
10147       }
10148 
10149       /* Deal with POKE/PONG without allocating a callno */
10150       if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) {
10151          /* Reply back with a PONG, but don't care about the result. */
10152          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10153          return 1;
10154       } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
10155          /* Ignore */
10156          return 1;
10157       }
10158 
10159       f.datalen = res - sizeof(*fh);
10160       if (f.datalen) {
10161          if (f.frametype == AST_FRAME_IAX) {
10162             if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
10163                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
10164                ast_variables_destroy(ies.vars);
10165                return 1;
10166             }
10167             f.data.ptr = NULL;
10168             f.datalen = 0;
10169          } else {
10170             f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
10171             memset(&ies, 0, sizeof(ies));
10172          }
10173       } else {
10174          if (f.frametype == AST_FRAME_IAX)
10175             f.data.ptr = NULL;
10176          else
10177             f.data.ptr = empty;
10178          memset(&ies, 0, sizeof(ies));
10179       }
10180 
10181       if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
10182          /* only set NEW_ALLOW if calltoken checks out */
10183          if (handle_call_token(fh, &ies, &sin, fd)) {
10184             ast_variables_destroy(ies.vars);
10185             return 1;
10186          }
10187 
10188          if (ies.calltoken && ies.calltokendata) {
10189             /* if we've gotten this far, and the calltoken ie data exists,
10190              * then calltoken validation _MUST_ have taken place.  If calltoken
10191              * data is provided, it is always validated reguardless of any
10192              * calltokenoptional or requirecalltoken options */
10193             new = NEW_ALLOW_CALLTOKEN_VALIDATED;
10194          } else {
10195             new = NEW_ALLOW;
10196          }
10197       }
10198    } else {
10199       /* Don't know anything about it yet */
10200       f.frametype = AST_FRAME_NULL;
10201       f.subclass.integer = 0;
10202       memset(&ies, 0, sizeof(ies));
10203    }
10204 
10205    if (!fr->callno) {
10206       int check_dcallno = 0;
10207 
10208       /*
10209        * We enforce accurate destination call numbers for ACKs.  This forces the other
10210        * end to know the destination call number before call setup can complete.
10211        *
10212        * Discussed in the following thread:
10213        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
10214        */
10215 
10216       if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
10217          check_dcallno = 1;
10218       }
10219 
10220       if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
10221          if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) {
10222             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10223          } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) {
10224             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10225          }
10226          ast_variables_destroy(ies.vars);
10227          return 1;
10228       }
10229    }
10230 
10231    if (fr->callno > 0)
10232       ast_mutex_lock(&iaxsl[fr->callno]);
10233 
10234    if (!fr->callno || !iaxs[fr->callno]) {
10235       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
10236          frame, reply with an inval */
10237       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10238          /* We can only raw hangup control frames */
10239          if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
10240              (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10241              (f.subclass.integer != IAX_COMMAND_TXACC) &&
10242              (f.subclass.integer != IAX_COMMAND_FWDOWNL))||
10243              (f.frametype != AST_FRAME_IAX))
10244             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
10245             fd);
10246       }
10247       if (fr->callno > 0) 
10248          ast_mutex_unlock(&iaxsl[fr->callno]);
10249       ast_variables_destroy(ies.vars);
10250       return 1;
10251    }
10252    if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
10253       if (decrypt_frame(fr->callno, fh, &f, &res)) {
10254          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10255          ast_variables_destroy(ies.vars);
10256          ast_mutex_unlock(&iaxsl[fr->callno]);
10257          return 1;
10258       }
10259       decrypted = 1;
10260    }
10261 
10262 #ifdef DEBUG_SUPPORT
10263    if (decrypted) {
10264       iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
10265    }
10266 #endif
10267 
10268 
10269    /* count this frame */
10270    iaxs[fr->callno]->frames_received++;
10271 
10272    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
10273       f.subclass.integer != IAX_COMMAND_TXCNT &&      /* for attended transfer */
10274       f.subclass.integer != IAX_COMMAND_TXACC) {      /* for attended transfer */
10275       unsigned short new_peercallno;
10276       
10277       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10278       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10279          if (iaxs[fr->callno]->peercallno) {
10280             remove_by_peercallno(iaxs[fr->callno]);
10281          }
10282          iaxs[fr->callno]->peercallno = new_peercallno;
10283          store_by_peercallno(iaxs[fr->callno]);
10284       }
10285    }
10286    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10287       if (iaxdebug)
10288          ast_debug(1, "Received packet %d, (%u, %d)\n", fh->oseqno, f.frametype, f.subclass.integer);
10289       /* Check if it's out of order (and not an ACK or INVAL) */
10290       fr->oseqno = fh->oseqno;
10291       fr->iseqno = fh->iseqno;
10292       fr->ts = ntohl(fh->ts);
10293 #ifdef IAXTESTS
10294       if (test_resync) {
10295          ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10296          fr->ts += test_resync;
10297       }
10298 #endif /* IAXTESTS */
10299 #if 0
10300       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10301            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10302                         (f.subclass == IAX_COMMAND_NEW ||
10303                          f.subclass == IAX_COMMAND_AUTHREQ ||
10304                          f.subclass == IAX_COMMAND_ACCEPT ||
10305                          f.subclass == IAX_COMMAND_REJECT))      ) )
10306 #endif
10307       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10308          updatehistory = 0;
10309       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10310          (iaxs[fr->callno]->iseqno ||
10311             ((f.subclass.integer != IAX_COMMAND_TXCNT) &&
10312             (f.subclass.integer != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
10313             (f.subclass.integer != IAX_COMMAND_TXREL) &&    /* for attended transfer */
10314             (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
10315             (f.subclass.integer != IAX_COMMAND_TXACC)) ||
10316             (f.frametype != AST_FRAME_IAX))) {
10317          if (
10318           ((f.subclass.integer != IAX_COMMAND_ACK) &&
10319            (f.subclass.integer != IAX_COMMAND_INVAL) &&
10320            (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10321            (f.subclass.integer != IAX_COMMAND_TXREADY) &&      /* for attended transfer */
10322            (f.subclass.integer != IAX_COMMAND_TXREL) &&     /* for attended transfer */
10323            (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
10324            (f.subclass.integer != IAX_COMMAND_TXACC) &&
10325            (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10326            (f.frametype != AST_FRAME_IAX)) {
10327             /* If it's not an ACK packet, it's out of order. */
10328             ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %u, subclass = %d)\n", 
10329                iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10330             /* Check to see if we need to request retransmission,
10331              * and take sequence number wraparound into account */
10332             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10333                /* If we've already seen it, ack it XXX There's a border condition here XXX */
10334                if ((f.frametype != AST_FRAME_IAX) || 
10335                      ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) {
10336                   ast_debug(1, "Acking anyway\n");
10337                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
10338                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
10339                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10340                }
10341             } else {
10342                /* Send a VNAK requesting retransmission */
10343                iax2_vnak(fr->callno);
10344             }
10345             ast_variables_destroy(ies.vars);
10346             ast_mutex_unlock(&iaxsl[fr->callno]);
10347             return 1;
10348          }
10349       } else {
10350          /* Increment unless it's an ACK or VNAK */
10351          if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10352              (f.subclass.integer != IAX_COMMAND_INVAL) &&
10353              (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10354              (f.subclass.integer != IAX_COMMAND_TXACC) &&
10355             (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10356              (f.frametype != AST_FRAME_IAX))
10357             iaxs[fr->callno]->iseqno++;
10358       }
10359       /* Ensure text frames are NULL-terminated */
10360       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10361          if (res < thread->buf_size)
10362             thread->buf[res++] = '\0';
10363          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
10364             thread->buf[res - 1] = '\0';
10365       }
10366 
10367       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
10368          from the real peer, not the transfer peer */
10369       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
10370           ((f.subclass.integer != IAX_COMMAND_INVAL) ||
10371            (f.frametype != AST_FRAME_IAX))) {
10372          unsigned char x;
10373          int call_to_destroy;
10374          /* First we have to qualify that the ACKed value is within our window */
10375          if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10376             x = fr->iseqno;
10377          else 
10378             x = iaxs[fr->callno]->oseqno;
10379          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10380             /* The acknowledgement is within our window.  Time to acknowledge everything
10381                that it says to */
10382             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10383                /* Ack the packet with the given timestamp */
10384                if (iaxdebug)
10385                   ast_debug(1, "Cancelling transmission of packet %d\n", x);
10386                call_to_destroy = 0;
10387                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10388                   /* If it's our call, and our timestamp, mark -1 retries */
10389                   if (x == cur->oseqno) {
10390                      cur->retries = -1;
10391                      /* Destroy call if this is the end */
10392                      if (cur->final)
10393                         call_to_destroy = fr->callno;
10394                   }
10395                }
10396                if (call_to_destroy) {
10397                   if (iaxdebug)
10398                      ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10399                   ast_mutex_lock(&iaxsl[call_to_destroy]);
10400                   iax2_destroy(call_to_destroy);
10401                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
10402                }
10403             }
10404             /* Note how much we've received acknowledgement for */
10405             if (iaxs[fr->callno])
10406                iaxs[fr->callno]->rseqno = fr->iseqno;
10407             else {
10408                /* Stop processing now */
10409                ast_variables_destroy(ies.vars);
10410                ast_mutex_unlock(&iaxsl[fr->callno]);
10411                return 1;
10412             }
10413          } else {
10414             ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10415          }
10416       }
10417       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
10418          ((f.frametype != AST_FRAME_IAX) || 
10419           ((f.subclass.integer != IAX_COMMAND_TXACC) &&
10420            (f.subclass.integer != IAX_COMMAND_TXCNT)))) {
10421          /* Only messages we accept from a transfer host are TXACC and TXCNT */
10422          ast_variables_destroy(ies.vars);
10423          ast_mutex_unlock(&iaxsl[fr->callno]);
10424          return 1;
10425       }
10426 
10427       /* when we receive the first full frame for a new incoming channel,
10428          it is safe to start the PBX on the channel because we have now
10429          completed a 3-way handshake with the peer */
10430       if ((f.frametype == AST_FRAME_VOICE) ||
10431           (f.frametype == AST_FRAME_VIDEO) ||
10432           (f.frametype == AST_FRAME_IAX)) {
10433          if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
10434             ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10435             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL,
10436                     ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED))) {
10437                ast_variables_destroy(ies.vars);
10438                ast_mutex_unlock(&iaxsl[fr->callno]);
10439                return 1;
10440             }
10441          }
10442 
10443          if (ies.vars) {
10444             struct ast_datastore *variablestore = NULL;
10445             struct ast_variable *var, *prev = NULL;
10446             AST_LIST_HEAD(, ast_var_t) *varlist;
10447 
10448             iax2_lock_owner(fr->callno);
10449             if (!iaxs[fr->callno]) {
10450                ast_variables_destroy(ies.vars);
10451                ast_mutex_unlock(&iaxsl[fr->callno]);
10452                return 1;
10453             }
10454             if ((c = iaxs[fr->callno]->owner)) {
10455                varlist = ast_calloc(1, sizeof(*varlist));
10456                variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10457 
10458                if (variablestore && varlist) {
10459                   variablestore->data = varlist;
10460                   variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10461                   AST_LIST_HEAD_INIT(varlist);
10462                   ast_debug(1, "I can haz IAX vars?\n");
10463                   for (var = ies.vars; var; var = var->next) {
10464                      struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10465                      if (prev) {
10466                         ast_free(prev);
10467                      }
10468                      prev = var;
10469                      if (!newvar) {
10470                         /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
10471                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10472                      } else {
10473                         AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10474                      }
10475                   }
10476                   if (prev) {
10477                      ast_free(prev);
10478                   }
10479                   ies.vars = NULL;
10480                   ast_channel_datastore_add(c, variablestore);
10481                } else {
10482                   ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10483                   if (variablestore) {
10484                      ast_datastore_free(variablestore);
10485                   }
10486                   if (varlist) {
10487                      ast_free(varlist);
10488                   }
10489                }
10490                ast_channel_unlock(c);
10491             } else {
10492                /* No channel yet, so transfer the variables directly over to the pvt,
10493                 * for later inheritance. */
10494                ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10495                for (var = ies.vars; var && var->next; var = var->next);
10496                if (var) {
10497                   var->next = iaxs[fr->callno]->iaxvars;
10498                   iaxs[fr->callno]->iaxvars = ies.vars;
10499                   ies.vars = NULL;
10500                }
10501             }
10502          }
10503 
10504          if (ies.vars) {
10505             ast_debug(1, "I have IAX variables, but they were not processed\n");
10506          }
10507       }
10508 
10509       /* once we receive our first IAX Full Frame that is not CallToken related, send all
10510        * queued signaling frames that were being held. */
10511       if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
10512          send_signaling(iaxs[fr->callno]);
10513       }
10514 
10515       if (f.frametype == AST_FRAME_VOICE) {
10516          if (f.subclass.codec != iaxs[fr->callno]->voiceformat) {
10517                iaxs[fr->callno]->voiceformat = f.subclass.codec;
10518                ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec));
10519                if (iaxs[fr->callno]->owner) {
10520                   iax2_lock_owner(fr->callno);
10521                   if (iaxs[fr->callno]) {
10522                      if (iaxs[fr->callno]->owner) {
10523                         format_t orignative;
10524 
10525                         orignative = iaxs[fr->callno]->owner->nativeformats;
10526                         iaxs[fr->callno]->owner->nativeformats = f.subclass.codec;
10527                         if (iaxs[fr->callno]->owner->readformat)
10528                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10529                         iaxs[fr->callno]->owner->nativeformats = orignative;
10530                         ast_channel_unlock(iaxs[fr->callno]->owner);
10531                      }
10532                   } else {
10533                      ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10534                      /* Free remote variables (if any) */
10535                      if (ies.vars) {
10536                         ast_variables_destroy(ies.vars);
10537                         ast_debug(1, "I can haz iaxvars, but they is no good.  :-(\n");
10538                         ies.vars = NULL;
10539                      }
10540                      ast_mutex_unlock(&iaxsl[fr->callno]);
10541                      return 1;
10542                   }
10543                }
10544          }
10545       }
10546       if (f.frametype == AST_FRAME_VIDEO) {
10547          if (f.subclass.codec != iaxs[fr->callno]->videoformat) {
10548             ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL));
10549             iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL;
10550          }
10551       }
10552       if (f.frametype == AST_FRAME_IAX) {
10553          ast_sched_thread_del(sched, iaxs[fr->callno]->initid);
10554          /* Handle the IAX pseudo frame itself */
10555          if (iaxdebug)
10556             ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10557 
10558                         /* Update last ts unless the frame's timestamp originated with us. */
10559          if (iaxs[fr->callno]->last < fr->ts &&
10560                             f.subclass.integer != IAX_COMMAND_ACK &&
10561                             f.subclass.integer != IAX_COMMAND_PONG &&
10562                             f.subclass.integer != IAX_COMMAND_LAGRP) {
10563             iaxs[fr->callno]->last = fr->ts;
10564             if (iaxdebug)
10565                ast_debug(1, "For call=%d, set last=%u\n", fr->callno, fr->ts);
10566          }
10567          iaxs[fr->callno]->last_iax_message = f.subclass.integer;
10568          if (!iaxs[fr->callno]->first_iax_message) {
10569             iaxs[fr->callno]->first_iax_message = f.subclass.integer;
10570          }
10571          switch(f.subclass.integer) {
10572          case IAX_COMMAND_ACK:
10573             /* Do nothing */
10574             break;
10575          case IAX_COMMAND_QUELCH:
10576             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10577                     /* Generate Manager Hold event, if necessary*/
10578                if (iaxs[fr->callno]->owner) {
10579                   ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10580                      "Status: On\r\n"
10581                      "Channel: %s\r\n"
10582                      "Uniqueid: %s\r\n",
10583                      iaxs[fr->callno]->owner->name,
10584                      iaxs[fr->callno]->owner->uniqueid);
10585                }
10586 
10587                ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
10588                if (ies.musiconhold) {
10589                   iax2_lock_owner(fr->callno);
10590                   if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10591                      break;
10592                   }
10593                   if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10594                      const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10595 
10596                      /*
10597                       * We already hold the owner lock so we do not
10598                       * need to check iaxs[fr->callno] after it returns.
10599                       */
10600                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
10601                         S_OR(moh_suggest, NULL),
10602                         !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10603                   }
10604                   ast_channel_unlock(iaxs[fr->callno]->owner);
10605                }
10606             }
10607             break;
10608          case IAX_COMMAND_UNQUELCH:
10609             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10610                iax2_lock_owner(fr->callno);
10611                if (!iaxs[fr->callno]) {
10612                   break;
10613                }
10614                /* Generate Manager Unhold event, if necessary */
10615                if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
10616                   ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10617                      "Status: Off\r\n"
10618                      "Channel: %s\r\n"
10619                      "Uniqueid: %s\r\n",
10620                      iaxs[fr->callno]->owner->name,
10621                      iaxs[fr->callno]->owner->uniqueid);
10622                }
10623 
10624                ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH);
10625                if (!iaxs[fr->callno]->owner) {
10626                   break;
10627                }
10628                if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10629                   /*
10630                    * We already hold the owner lock so we do not
10631                    * need to check iaxs[fr->callno] after it returns.
10632                    */
10633                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10634                }
10635                ast_channel_unlock(iaxs[fr->callno]->owner);
10636             }
10637             break;
10638          case IAX_COMMAND_TXACC:
10639             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10640                /* Ack the packet with the given timestamp */
10641                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10642                   /* Cancel any outstanding txcnt's */
10643                   if (cur->transfer) {
10644                      cur->retries = -1;
10645                   }
10646                }
10647                memset(&ied1, 0, sizeof(ied1));
10648                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10649                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10650                iaxs[fr->callno]->transferring = TRANSFER_READY;
10651             }
10652             break;
10653          case IAX_COMMAND_NEW:
10654             /* Ignore if it's already up */
10655             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10656                break;
10657             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10658                ast_mutex_unlock(&iaxsl[fr->callno]);
10659                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10660                ast_mutex_lock(&iaxsl[fr->callno]);
10661                if (!iaxs[fr->callno]) {
10662                   break;
10663                }
10664             }
10665             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
10666             if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10667                int new_callno;
10668                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10669                   fr->callno = new_callno;
10670             }
10671             /* For security, always ack immediately */
10672             if (delayreject)
10673                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10674             if (check_access(fr->callno, &sin, &ies)) {
10675                /* They're not allowed on */
10676                auth_fail(fr->callno, IAX_COMMAND_REJECT);
10677                if (authdebug)
10678                   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);
10679                break;
10680             }
10681             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10682                auth_fail(fr->callno, IAX_COMMAND_REJECT);
10683                ast_log(LOG_WARNING, "Rejected connect attempt.  No secret present while force encrypt enabled.\n");
10684                break;
10685             }
10686             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10687                const char *context, *exten, *cid_num;
10688 
10689                context = ast_strdupa(iaxs[fr->callno]->context);
10690                exten = ast_strdupa(iaxs[fr->callno]->exten);
10691                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10692 
10693                /* This might re-enter the IAX code and need the lock */
10694                ast_mutex_unlock(&iaxsl[fr->callno]);
10695                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10696                ast_mutex_lock(&iaxsl[fr->callno]);
10697 
10698                if (!iaxs[fr->callno]) {
10699                   break;
10700                }
10701             } else
10702                exists = 0;
10703             /* Get OSP token if it does exist */
10704             save_osptoken(fr, &ies);
10705             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10706                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10707                   memset(&ied0, 0, sizeof(ied0));
10708                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10709                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10710                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10711                   if (!iaxs[fr->callno]) {
10712                      break;
10713                   }
10714                   if (authdebug)
10715                      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);
10716                } else {
10717                   /* Select an appropriate format */
10718 
10719                   if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10720                      if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10721                         using_prefs = "reqonly";
10722                      } else {
10723                         using_prefs = "disabled";
10724                      }
10725                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10726                      memset(&pref, 0, sizeof(pref));
10727                      strcpy(caller_pref_buf, "disabled");
10728                      strcpy(host_pref_buf, "disabled");
10729                   } else {
10730                      using_prefs = "mine";
10731                      /* If the information elements are in here... use them */
10732                      if (ies.codec_prefs)
10733                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10734                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10735                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
10736                         if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10737                            pref = iaxs[fr->callno]->rprefs;
10738                            using_prefs = "caller";
10739                         } else {
10740                            pref = iaxs[fr->callno]->prefs;
10741                         }
10742                      } else
10743                         pref = iaxs[fr->callno]->prefs;
10744 
10745                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10746                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10747                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10748                   }
10749                   if (!format) {
10750                      if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP))
10751                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10752                      if (!format) {
10753                         memset(&ied0, 0, sizeof(ied0));
10754                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10755                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10756                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10757                         if (!iaxs[fr->callno]) {
10758                            break;
10759                         }
10760                         if (authdebug) {
10761                            char tmp[256], tmp2[256], tmp3[256];
10762                            if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10763                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10764                                  ast_inet_ntoa(sin.sin_addr),
10765                                  ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10766                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10767                            } else {
10768                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10769                                  ast_inet_ntoa(sin.sin_addr),
10770                                  ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10771                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10772                                  ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10773                            }
10774                         }
10775                      } else {
10776                         /* Pick one... */
10777                         if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10778                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10779                               format = 0;
10780                         } else {
10781                            if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10782                               using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10783                               memset(&pref, 0, sizeof(pref));
10784                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10785                               strcpy(caller_pref_buf,"disabled");
10786                               strcpy(host_pref_buf,"disabled");
10787                            } else {
10788                               using_prefs = "mine";
10789                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10790                                  /* Do the opposite of what we tried above. */
10791                                  if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10792                                     pref = iaxs[fr->callno]->prefs;
10793                                  } else {
10794                                     pref = iaxs[fr->callno]->rprefs;
10795                                     using_prefs = "caller";
10796                                  }
10797                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10798                               } else /* if no codec_prefs IE do it the old way */
10799                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10800                            }
10801                         }
10802 
10803                         if (!format) {
10804                            char tmp[256], tmp2[256], tmp3[256];
10805                            memset(&ied0, 0, sizeof(ied0));
10806                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10807                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10808                            ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
10809                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10810                            if (!iaxs[fr->callno]) {
10811                               break;
10812                            }
10813                            if (authdebug) {
10814                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10815                                  ast_inet_ntoa(sin.sin_addr),
10816                                  ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10817                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10818                                  ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10819                            }
10820                            ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10821                            break;
10822                         }
10823                      }
10824                   }
10825                   if (format) {
10826                      /* No authentication required, let them in */
10827                      memset(&ied1, 0, sizeof(ied1));
10828                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10829                      iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
10830                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10831                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10832                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10833                         ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10834                                     "%srequested format = %s,\n"
10835                                     "%srequested prefs = %s,\n"
10836                                     "%sactual format = %s,\n"
10837                                     "%shost prefs = %s,\n"
10838                                     "%spriority = %s\n",
10839                                     ast_inet_ntoa(sin.sin_addr), 
10840                                     VERBOSE_PREFIX_4,
10841                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
10842                                     VERBOSE_PREFIX_4,
10843                                     caller_pref_buf,
10844                                     VERBOSE_PREFIX_4,
10845                                     ast_getformatname(format), 
10846                                     VERBOSE_PREFIX_4,
10847                                     host_pref_buf, 
10848                                     VERBOSE_PREFIX_4,
10849                                     using_prefs);
10850 
10851                         iaxs[fr->callno]->chosenformat = format;
10852                         ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10853                      } else {
10854                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10855                         /* If this is a TBD call, we're ready but now what...  */
10856                         ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10857                      }
10858                   }
10859                }
10860                break;
10861             }
10862             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10863                merge_encryption(iaxs[fr->callno],ies.encmethods);
10864             else
10865                iaxs[fr->callno]->encmethods = 0;
10866             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10867                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10868             break;
10869          case IAX_COMMAND_DPREQ:
10870             /* Request status in the dialplan */
10871             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10872                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10873                if (iaxcompat) {
10874                   /* Spawn a thread for the lookup */
10875                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10876                } else {
10877                   /* Just look it up */
10878                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10879                }
10880             }
10881             break;
10882          case IAX_COMMAND_HANGUP:
10883             ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10884             ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10885             /* Set hangup cause according to remote and hangupsource */
10886             if (iaxs[fr->callno]->owner) {
10887                set_hangup_source_and_cause(fr->callno, ies.causecode);
10888                if (!iaxs[fr->callno]) {
10889                   break;
10890                }
10891             }
10892 
10893             /* Send ack immediately, before we destroy */
10894             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10895             iax2_destroy(fr->callno);
10896             break;
10897          case IAX_COMMAND_REJECT:
10898             /* Set hangup cause according to remote and hangup source */
10899             if (iaxs[fr->callno]->owner) {
10900                set_hangup_source_and_cause(fr->callno, ies.causecode);
10901                if (!iaxs[fr->callno]) {
10902                   break;
10903                }
10904             }
10905 
10906             if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10907                if (iaxs[fr->callno]->owner && authdebug)
10908                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10909                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10910                      ies.cause ? ies.cause : "<Unknown>");
10911                ast_debug(1, "Immediately destroying %d, having received reject\n",
10912                   fr->callno);
10913             }
10914             /* Send ack immediately, before we destroy */
10915             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10916                          fr->ts, NULL, 0, fr->iseqno);
10917             if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION))
10918                iaxs[fr->callno]->error = EPERM;
10919             iax2_destroy(fr->callno);
10920             break;
10921          case IAX_COMMAND_TRANSFER:
10922          {
10923             struct ast_channel *bridged_chan;
10924             struct ast_channel *owner;
10925 
10926             iax2_lock_owner(fr->callno);
10927             if (!iaxs[fr->callno]) {
10928                /* Initiating call went away before we could transfer. */
10929                break;
10930             }
10931             owner = iaxs[fr->callno]->owner;
10932             bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10933             if (bridged_chan && ies.called_number) {
10934                const char *context;
10935 
10936                context = ast_strdupa(iaxs[fr->callno]->context);
10937 
10938                ast_channel_ref(owner);
10939                ast_channel_ref(bridged_chan);
10940                ast_channel_unlock(owner);
10941                ast_mutex_unlock(&iaxsl[fr->callno]);
10942 
10943                /* Set BLINDTRANSFER channel variables */
10944                pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name);
10945                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name);
10946 
10947                /* DO NOT hold any locks while calling ast_parking_ext_valid() */
10948                if (ast_parking_ext_valid(ies.called_number, owner, context)) {
10949                   ast_debug(1, "Parking call '%s'\n", bridged_chan->name);
10950                   if (iax_park(bridged_chan, owner, ies.called_number, context)) {
10951                      ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10952                         bridged_chan->name);
10953                   }
10954                } else {
10955                   if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) {
10956                      ast_log(LOG_WARNING,
10957                         "Async goto of '%s' to '%s@%s' failed\n",
10958                         bridged_chan->name, ies.called_number, context);
10959                   } else {
10960                      ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10961                         bridged_chan->name, ies.called_number, context);
10962                   }
10963                }
10964                ast_channel_unref(owner);
10965                ast_channel_unref(bridged_chan);
10966 
10967                ast_mutex_lock(&iaxsl[fr->callno]);
10968             } else {
10969                ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10970                if (owner) {
10971                   ast_channel_unlock(owner);
10972                }
10973             }
10974 
10975             break;
10976          }
10977          case IAX_COMMAND_ACCEPT:
10978             /* Ignore if call is already up or needs authentication or is a TBD */
10979             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10980                break;
10981             if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10982                /* Send ack immediately, before we destroy */
10983                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10984                iax2_destroy(fr->callno);
10985                break;
10986             }
10987             if (ies.format) {
10988                iaxs[fr->callno]->peerformat = ies.format;
10989             } else {
10990                if (iaxs[fr->callno]->owner)
10991                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10992                else
10993                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10994             }
10995             ast_verb(3, "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
10996             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10997                memset(&ied0, 0, sizeof(ied0));
10998                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10999                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11000                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11001                if (!iaxs[fr->callno]) {
11002                   break;
11003                }
11004                if (authdebug) {
11005                   char tmp1[256], tmp2[256];
11006                   ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
11007                      ast_inet_ntoa(sin.sin_addr),
11008                      ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11009                      ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11010                }
11011             } else {
11012                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11013                iax2_lock_owner(fr->callno);
11014                if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
11015                   /* Switch us to use a compatible format */
11016                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
11017                   ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
11018 
11019                   /* Setup read/write formats properly. */
11020                   if (iaxs[fr->callno]->owner->writeformat)
11021                      ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
11022                   if (iaxs[fr->callno]->owner->readformat)
11023                      ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
11024                   ast_channel_unlock(iaxs[fr->callno]->owner);
11025                }
11026             }
11027             if (iaxs[fr->callno]) {
11028                AST_LIST_LOCK(&dpcache);
11029                AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
11030                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
11031                      iax2_dprequest(dp, fr->callno);
11032                AST_LIST_UNLOCK(&dpcache);
11033             }
11034             break;
11035          case IAX_COMMAND_POKE:
11036             /* Send back a pong packet with the original timestamp */
11037             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
11038             break;
11039          case IAX_COMMAND_PING:
11040          {
11041             struct iax_ie_data pingied;
11042             construct_rr(iaxs[fr->callno], &pingied);
11043             /* Send back a pong packet with the original timestamp */
11044             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
11045          }
11046             break;
11047          case IAX_COMMAND_PONG:
11048             /* Calculate ping time */
11049             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
11050             /* save RR info */
11051             save_rr(fr, &ies);
11052 
11053             /* Good time to write jb stats for this call */
11054             log_jitterstats(fr->callno);
11055 
11056             if (iaxs[fr->callno]->peerpoke) {
11057                peer = iaxs[fr->callno]->peerpoke;
11058                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
11059                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
11060                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %u\n", peer->name, iaxs[fr->callno]->pingtime);
11061                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %u\r\n", peer->name, iaxs[fr->callno]->pingtime); 
11062                      ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
11063                   }
11064                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
11065                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
11066                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%u ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
11067                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %u\r\n", peer->name, iaxs[fr->callno]->pingtime); 
11068                      ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
11069                   }
11070                }
11071                peer->lastms = iaxs[fr->callno]->pingtime;
11072                if (peer->smoothing && (peer->lastms > -1))
11073                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
11074                else if (peer->smoothing && peer->lastms < 0)
11075                   peer->historicms = (0 + peer->historicms) / 2;
11076                else              
11077                   peer->historicms = iaxs[fr->callno]->pingtime;
11078 
11079                /* Remove scheduled iax2_poke_noanswer */
11080                if (peer->pokeexpire > -1) {
11081                   if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
11082                      peer_unref(peer);
11083                      peer->pokeexpire = -1;
11084                   }
11085                }
11086                /* Schedule the next cycle */
11087                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
11088                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11089                else
11090                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
11091                if (peer->pokeexpire == -1)
11092                   peer_unref(peer);
11093                /* and finally send the ack */
11094                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11095                /* And wrap up the qualify call */
11096                iax2_destroy(fr->callno);
11097                peer->callno = 0;
11098                ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
11099             }
11100             break;
11101          case IAX_COMMAND_LAGRQ:
11102          case IAX_COMMAND_LAGRP:
11103             f.src = "LAGRQ";
11104             f.mallocd = 0;
11105             f.offset = 0;
11106             f.samples = 0;
11107             iax_frame_wrap(fr, &f);
11108             if (f.subclass.integer == IAX_COMMAND_LAGRQ) {
11109                /* Received a LAGRQ - echo back a LAGRP */
11110                fr->af.subclass.integer = IAX_COMMAND_LAGRP;
11111                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
11112             } else {
11113                /* Received LAGRP in response to our LAGRQ */
11114                unsigned int ts;
11115                /* This is a reply we've been given, actually measure the difference */
11116                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
11117                iaxs[fr->callno]->lag = ts - fr->ts;
11118                if (iaxdebug)
11119                   ast_debug(1, "Peer %s lag measured as %dms\n",
11120                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
11121             }
11122             break;
11123          case IAX_COMMAND_AUTHREQ:
11124             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
11125                ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11126                break;
11127             }
11128             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
11129                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
11130                         .subclass.integer = AST_CONTROL_HANGUP,
11131                };
11132                ast_log(LOG_WARNING, 
11133                   "I don't know how to authenticate %s to %s\n", 
11134                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
11135                iax2_queue_frame(fr->callno, &hangup_fr);
11136             }
11137             break;
11138          case IAX_COMMAND_AUTHREP:
11139             /* For security, always ack immediately */
11140             if (delayreject)
11141                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11142             /* Ignore once we've started */
11143             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
11144                ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11145                break;
11146             }
11147             if (authenticate_verify(iaxs[fr->callno], &ies)) {
11148                if (authdebug)
11149                   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);
11150                memset(&ied0, 0, sizeof(ied0));
11151                auth_fail(fr->callno, IAX_COMMAND_REJECT);
11152                break;
11153             }
11154             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
11155                /* This might re-enter the IAX code and need the lock */
11156                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
11157             } else
11158                exists = 0;
11159             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
11160                if (authdebug)
11161                   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);
11162                memset(&ied0, 0, sizeof(ied0));
11163                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11164                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11165                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11166                if (!iaxs[fr->callno]) {
11167                   break;
11168                }
11169             } else {
11170                /* Select an appropriate format */
11171                if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11172                   if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11173                      using_prefs = "reqonly";
11174                   } else {
11175                      using_prefs = "disabled";
11176                   }
11177                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
11178                   memset(&pref, 0, sizeof(pref));
11179                   strcpy(caller_pref_buf, "disabled");
11180                   strcpy(host_pref_buf, "disabled");
11181                } else {
11182                   using_prefs = "mine";
11183                   if (ies.codec_prefs)
11184                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
11185                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11186                      if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11187                         pref = iaxs[fr->callno]->rprefs;
11188                         using_prefs = "caller";
11189                      } else {
11190                         pref = iaxs[fr->callno]->prefs;
11191                      }
11192                   } else /* if no codec_prefs IE do it the old way */
11193                      pref = iaxs[fr->callno]->prefs;
11194                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
11195                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
11196                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
11197                }
11198                if (!format) {
11199                   char tmp1[256], tmp2[256], tmp3[256];
11200                   if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11201                      ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
11202                         ast_getformatname(iaxs[fr->callno]->peerformat),
11203                         ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
11204                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
11205                   }
11206                   if (!format) {
11207                      if (authdebug) {
11208                         if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11209                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
11210                               ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11211                               ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11212                         } else {
11213                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11214                               ast_inet_ntoa(sin.sin_addr),
11215                               ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11216                               ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11217                               ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11218                         }
11219                      }
11220                      memset(&ied0, 0, sizeof(ied0));
11221                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11222                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11223                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11224                      if (!iaxs[fr->callno]) {
11225                         break;
11226                      }
11227                   } else {
11228                      /* Pick one... */
11229                      if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11230                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
11231                            format = 0;
11232                      } else {
11233                         if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11234                            using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
11235                            memset(&pref, 0, sizeof(pref));
11236                            format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
11237                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11238                            strcpy(caller_pref_buf,"disabled");
11239                            strcpy(host_pref_buf,"disabled");
11240                         } else {
11241                            using_prefs = "mine";
11242                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11243                               /* Do the opposite of what we tried above. */
11244                               if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11245                                  pref = iaxs[fr->callno]->prefs;
11246                               } else {
11247                                  pref = iaxs[fr->callno]->rprefs;
11248                                  using_prefs = "caller";
11249                               }
11250                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
11251                            } else /* if no codec_prefs IE do it the old way */
11252                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
11253                         }
11254                      }
11255                      if (!format) {
11256                         char tmp1[256], tmp2[256], tmp3[256];
11257                         ast_log(LOG_ERROR, "No best format in %s???\n",
11258                            ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
11259                         if (authdebug) {
11260                            if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11261                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11262                                  ast_inet_ntoa(sin.sin_addr),
11263                                  ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11264                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11265                            } else {
11266                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11267                                  ast_inet_ntoa(sin.sin_addr),
11268                                  ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11269                                  ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11270                                  ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11271                            }
11272                         }
11273                         memset(&ied0, 0, sizeof(ied0));
11274                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11275                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11276                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11277                         if (!iaxs[fr->callno]) {
11278                            break;
11279                         }
11280                      }
11281                   }
11282                }
11283                if (format) {
11284                   /* Authentication received */
11285                   memset(&ied1, 0, sizeof(ied1));
11286                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11287                   iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
11288                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11289                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11290                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11291                      ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11292                                  "%srequested format = %s,\n"
11293                                  "%srequested prefs = %s,\n"
11294                                  "%sactual format = %s,\n"
11295                                  "%shost prefs = %s,\n"
11296                                  "%spriority = %s\n", 
11297                                  ast_inet_ntoa(sin.sin_addr), 
11298                                  VERBOSE_PREFIX_4,
11299                                  ast_getformatname(iaxs[fr->callno]->peerformat),
11300                                  VERBOSE_PREFIX_4,
11301                                  caller_pref_buf,
11302                                  VERBOSE_PREFIX_4,
11303                                  ast_getformatname(format),
11304                                  VERBOSE_PREFIX_4,
11305                                  host_pref_buf,
11306                                  VERBOSE_PREFIX_4,
11307                                  using_prefs);
11308 
11309                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11310                      if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL, 1)))
11311                         iax2_destroy(fr->callno);
11312                      else if (ies.vars) {
11313                         struct ast_datastore *variablestore;
11314                         struct ast_variable *var, *prev = NULL;
11315                         AST_LIST_HEAD(, ast_var_t) *varlist;
11316                         varlist = ast_calloc(1, sizeof(*varlist));
11317                         variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11318                         if (variablestore && varlist) {
11319                            variablestore->data = varlist;
11320                            variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11321                            AST_LIST_HEAD_INIT(varlist);
11322                            ast_debug(1, "I can haz IAX vars? w00t\n");
11323                            for (var = ies.vars; var; var = var->next) {
11324                               struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11325                               if (prev)
11326                                  ast_free(prev);
11327                               prev = var;
11328                               if (!newvar) {
11329                                  /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11330                                  ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11331                               } else {
11332                                  AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11333                               }
11334                            }
11335                            if (prev)
11336                               ast_free(prev);
11337                            ies.vars = NULL;
11338                            ast_channel_datastore_add(c, variablestore);
11339                         } else {
11340                            ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11341                            if (variablestore)
11342                               ast_datastore_free(variablestore);
11343                            if (varlist)
11344                               ast_free(varlist);
11345                         }
11346                      }
11347                   } else {
11348                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11349                      /* If this is a TBD call, we're ready but now what...  */
11350                      ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
11351                      if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) {
11352                         goto immediatedial;
11353                      }
11354                   }
11355                }
11356             }
11357             break;
11358          case IAX_COMMAND_DIAL:
11359 immediatedial:
11360             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
11361                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11362                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11363                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11364                   if (authdebug)
11365                      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);
11366                   memset(&ied0, 0, sizeof(ied0));
11367                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11368                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11369                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11370                   if (!iaxs[fr->callno]) {
11371                      break;
11372                   }
11373                } else {
11374                   char tmp[256];
11375                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11376                   ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11377                      ast_inet_ntoa(sin.sin_addr),
11378                      ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
11379                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11380                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
11381                   if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, 1)))
11382                      iax2_destroy(fr->callno);
11383                   else if (ies.vars) {
11384                      struct ast_datastore *variablestore;
11385                      struct ast_variable *var, *prev = NULL;
11386                      AST_LIST_HEAD(, ast_var_t) *varlist;
11387                      varlist = ast_calloc(1, sizeof(*varlist));
11388                      variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11389                      ast_debug(1, "I can haz IAX vars? w00t\n");
11390                      if (variablestore && varlist) {
11391                         variablestore->data = varlist;
11392                         variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11393                         AST_LIST_HEAD_INIT(varlist);
11394                         for (var = ies.vars; var; var = var->next) {
11395                            struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11396                            if (prev)
11397                               ast_free(prev);
11398                            prev = var;
11399                            if (!newvar) {
11400                               /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
11401                               ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11402                            } else {
11403                               AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11404                            }
11405                         }
11406                         if (prev)
11407                            ast_free(prev);
11408                         ies.vars = NULL;
11409                         ast_channel_datastore_add(c, variablestore);
11410                      } else {
11411                         ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11412                         if (variablestore)
11413                            ast_datastore_free(variablestore);
11414                         if (varlist)
11415                            ast_free(varlist);
11416                      }
11417                   }
11418                }
11419             }
11420             break;
11421          case IAX_COMMAND_INVAL:
11422             iaxs[fr->callno]->error = ENOTCONN;
11423             ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11424             iax2_destroy(fr->callno);
11425             ast_debug(1, "Destroying call %d\n", fr->callno);
11426             break;
11427          case IAX_COMMAND_VNAK:
11428             ast_debug(1, "Received VNAK: resending outstanding frames\n");
11429             /* Force retransmission */
11430             vnak_retransmit(fr->callno, fr->iseqno);
11431             break;
11432          case IAX_COMMAND_REGREQ:
11433          case IAX_COMMAND_REGREL:
11434             /* For security, always ack immediately */
11435             if (delayreject)
11436                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11437             if (register_verify(fr->callno, &sin, &ies)) {
11438                if (!iaxs[fr->callno]) {
11439                   break;
11440                }
11441                /* Send delayed failure */
11442                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
11443                break;
11444             }
11445             if (!iaxs[fr->callno]) {
11446                break;
11447             }
11448             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
11449                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
11450 
11451                if (f.subclass.integer == IAX_COMMAND_REGREL) {
11452                   memset(&sin, 0, sizeof(sin));
11453                   sin.sin_family = AF_INET;
11454                }
11455                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) {
11456                   ast_log(LOG_WARNING, "Registry error\n");
11457                }
11458                if (!iaxs[fr->callno]) {
11459                   break;
11460                }
11461                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
11462                   ast_mutex_unlock(&iaxsl[fr->callno]);
11463                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
11464                   ast_mutex_lock(&iaxsl[fr->callno]);
11465                }
11466                break;
11467             }
11468             registry_authrequest(fr->callno);
11469             break;
11470          case IAX_COMMAND_REGACK:
11471             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
11472                ast_log(LOG_WARNING, "Registration failure\n");
11473             /* Send ack immediately, before we destroy */
11474             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11475             iax2_destroy(fr->callno);
11476             break;
11477          case IAX_COMMAND_REGREJ:
11478             if (iaxs[fr->callno]->reg) {
11479                if (authdebug) {
11480                   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));
11481                   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>");
11482                }
11483                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
11484             }
11485             /* Send ack immediately, before we destroy */
11486             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11487             iax2_destroy(fr->callno);
11488             break;
11489          case IAX_COMMAND_REGAUTH:
11490             /* Authentication request */
11491             if (registry_rerequest(&ies, fr->callno, &sin)) {
11492                memset(&ied0, 0, sizeof(ied0));
11493                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11494                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
11495                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11496             }
11497             break;
11498          case IAX_COMMAND_TXREJ:
11499             while (iaxs[fr->callno]
11500                && iaxs[fr->callno]->bridgecallno
11501                && ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
11502                DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
11503             }
11504             if (!iaxs[fr->callno]) {
11505                break;
11506             }
11507 
11508             iaxs[fr->callno]->transferring = TRANSFER_NONE;
11509             ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11510             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11511 
11512             if (!iaxs[fr->callno]->bridgecallno) {
11513                break;
11514             }
11515 
11516             if (iaxs[iaxs[fr->callno]->bridgecallno]
11517                && iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
11518                iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_NONE;
11519                send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
11520             }
11521             ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11522             break;
11523          case IAX_COMMAND_TXREADY:
11524             while (iaxs[fr->callno]
11525                && iaxs[fr->callno]->bridgecallno
11526                && ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
11527                DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
11528             }
11529             if (!iaxs[fr->callno]) {
11530                break;
11531             }
11532 
11533             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
11534                iaxs[fr->callno]->transferring = TRANSFER_READY;
11535             } else if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) {
11536                iaxs[fr->callno]->transferring = TRANSFER_MREADY;
11537             } else {
11538                if (iaxs[fr->callno]->bridgecallno) {
11539                   ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11540                }
11541                break;
11542             }
11543             ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11544 
11545             if (!iaxs[fr->callno]->bridgecallno) {
11546                break;
11547             }
11548 
11549             if (!iaxs[iaxs[fr->callno]->bridgecallno]
11550                || (iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_READY
11551                   && iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_MREADY)) {
11552                ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11553                break;
11554             }
11555 
11556             /* Both sides are ready */
11557 
11558             /* XXX what isn't checked here is that both sides match transfer types. */
11559 
11560             if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11561                ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11562                      iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11563 
11564                iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
11565                iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
11566 
11567                memset(&ied0, 0, sizeof(ied0));
11568                memset(&ied1, 0, sizeof(ied1));
11569                iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11570                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11571                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11572                send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11573             } else {
11574                ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11575                      iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11576 
11577                iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
11578                iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
11579                ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
11580                ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
11581 
11582                /* Stop doing lag & ping requests */
11583                stop_stuff(fr->callno);
11584                stop_stuff(iaxs[fr->callno]->bridgecallno);
11585 
11586                memset(&ied0, 0, sizeof(ied0));
11587                memset(&ied1, 0, sizeof(ied1));
11588                iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11589                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11590                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11591                send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11592             }
11593             ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11594             break;
11595          case IAX_COMMAND_TXREQ:
11596             try_transfer(iaxs[fr->callno], &ies);
11597             break;
11598          case IAX_COMMAND_TXCNT:
11599             if (iaxs[fr->callno]->transferring)
11600                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
11601             break;
11602          case IAX_COMMAND_TXREL:
11603             /* Send ack immediately, rather than waiting until we've changed addresses */
11604             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11605             complete_transfer(fr->callno, &ies);
11606             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
11607             break;   
11608          case IAX_COMMAND_TXMEDIA:
11609             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11610                AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11611                   /* Cancel any outstanding frames and start anew */
11612                   if (cur->transfer) {
11613                      cur->retries = -1;
11614                   }
11615                }
11616                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
11617                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
11618             }
11619             break;
11620          case IAX_COMMAND_RTKEY:
11621             if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11622                ast_log(LOG_WARNING, 
11623                   "we've been told to rotate our encryption key, "
11624                   "but this isn't an encrypted call. bad things will happen.\n"
11625                );
11626                break;
11627             }
11628 
11629             IAX_DEBUGDIGEST("Receiving", ies.challenge);
11630 
11631             ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11632             break;
11633          case IAX_COMMAND_DPREP:
11634             complete_dpreply(iaxs[fr->callno], &ies);
11635             break;
11636          case IAX_COMMAND_UNSUPPORT:
11637             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11638             break;
11639          case IAX_COMMAND_FWDOWNL:
11640             /* Firmware download */
11641             if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
11642                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
11643                break;
11644             }
11645             memset(&ied0, 0, sizeof(ied0));
11646             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11647             if (res < 0)
11648                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11649             else if (res > 0)
11650                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11651             else
11652                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11653             break;
11654          case IAX_COMMAND_CALLTOKEN:
11655          {
11656             struct iax_frame *cur;
11657             /* find last sent frame */
11658             if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11659                resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11660             }
11661             break;
11662          }
11663          default:
11664             ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11665             memset(&ied0, 0, sizeof(ied0));
11666             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer);
11667             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11668          }
11669          /* Free remote variables (if any) */
11670          if (ies.vars) {
11671             ast_variables_destroy(ies.vars);
11672             ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11673             ies.vars = NULL;
11674          }
11675 
11676          /* Don't actually pass these frames along */
11677          if ((f.subclass.integer != IAX_COMMAND_ACK) &&
11678             (f.subclass.integer != IAX_COMMAND_TXCNT) &&
11679             (f.subclass.integer != IAX_COMMAND_TXACC) &&
11680             (f.subclass.integer != IAX_COMMAND_INVAL) &&
11681             (f.subclass.integer != IAX_COMMAND_VNAK)) {
11682             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) {
11683                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11684             }
11685          }
11686          ast_mutex_unlock(&iaxsl[fr->callno]);
11687          return 1;
11688       }
11689       /* Unless this is an ACK or INVAL frame, ack it */
11690       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11691          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11692    } else if (minivid) {
11693       f.frametype = AST_FRAME_VIDEO;
11694       if (iaxs[fr->callno]->videoformat > 0) 
11695          f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0);
11696       else {
11697          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11698          iax2_vnak(fr->callno);
11699          ast_variables_destroy(ies.vars);
11700          ast_mutex_unlock(&iaxsl[fr->callno]);
11701          return 1;
11702       }
11703       f.datalen = res - sizeof(*vh);
11704       if (f.datalen)
11705          f.data.ptr = thread->buf + sizeof(*vh);
11706       else
11707          f.data.ptr = NULL;
11708 #ifdef IAXTESTS
11709       if (test_resync) {
11710          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11711       } else
11712 #endif /* IAXTESTS */
11713          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11714    } else {
11715       /* A mini frame */
11716       f.frametype = AST_FRAME_VOICE;
11717       if (iaxs[fr->callno]->voiceformat > 0)
11718          f.subclass.codec = iaxs[fr->callno]->voiceformat;
11719       else {
11720          ast_debug(1, "Received mini frame before first full voice frame\n");
11721          iax2_vnak(fr->callno);
11722          ast_variables_destroy(ies.vars);
11723          ast_mutex_unlock(&iaxsl[fr->callno]);
11724          return 1;
11725       }
11726       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11727       if (f.datalen < 0) {
11728          ast_log(LOG_WARNING, "Datalen < 0?\n");
11729          ast_variables_destroy(ies.vars);
11730          ast_mutex_unlock(&iaxsl[fr->callno]);
11731          return 1;
11732       }
11733       if (f.datalen)
11734          f.data.ptr = thread->buf + sizeof(*mh);
11735       else
11736          f.data.ptr = NULL;
11737 #ifdef IAXTESTS
11738       if (test_resync) {
11739          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11740       } else
11741 #endif /* IAXTESTS */
11742       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11743       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
11744    }
11745 
11746    /* Don't pass any packets until we're started */
11747    if (!iaxs[fr->callno]
11748       || !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11749       ast_variables_destroy(ies.vars);
11750       ast_mutex_unlock(&iaxsl[fr->callno]);
11751       return 1;
11752    }
11753 
11754    if (f.frametype == AST_FRAME_CONTROL) {
11755       if (!iax2_is_control_frame_allowed(f.subclass.integer)) {
11756          /* Control frame not allowed to come from the wire. */
11757          ast_debug(2, "Callno %d: Blocked receiving control frame %d.\n",
11758             fr->callno, f.subclass.integer);
11759          ast_variables_destroy(ies.vars);
11760          ast_mutex_unlock(&iaxsl[fr->callno]);
11761          return 1;
11762       }
11763       if (f.subclass.integer == AST_CONTROL_CONNECTED_LINE
11764          || f.subclass.integer == AST_CONTROL_REDIRECTING) {
11765          if (iaxs[fr->callno]
11766             && !ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) {
11767             /* We are not configured to allow receiving these updates. */
11768             ast_debug(2, "Callno %d: Config blocked receiving control frame %d.\n",
11769                fr->callno, f.subclass.integer);
11770             ast_variables_destroy(ies.vars);
11771             ast_mutex_unlock(&iaxsl[fr->callno]);
11772             return 1;
11773          }
11774       }
11775 
11776       iax2_lock_owner(fr->callno);
11777       if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
11778          if (f.subclass.integer == AST_CONTROL_BUSY) {
11779             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
11780          } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
11781             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
11782          }
11783          ast_channel_unlock(iaxs[fr->callno]->owner);
11784       }
11785    }
11786 
11787    if (f.frametype == AST_FRAME_CONTROL
11788       && f.subclass.integer == AST_CONTROL_CONNECTED_LINE
11789       && iaxs[fr->callno]) {
11790       struct ast_party_connected_line connected;
11791 
11792       /*
11793        * Process a received connected line update.
11794        *
11795        * Initialize defaults.
11796        */
11797       ast_party_connected_line_init(&connected);
11798       connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
11799       connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
11800 
11801       if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) {
11802          ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
11803          ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
11804          iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id);
11805 
11806          iax2_lock_owner(fr->callno);
11807          if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
11808             ast_set_callerid(iaxs[fr->callno]->owner,
11809                S_COR(connected.id.number.valid, connected.id.number.str, ""),
11810                S_COR(connected.id.name.valid, connected.id.name.str, ""),
11811                NULL);
11812             iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation;
11813             iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation;
11814             ast_channel_unlock(iaxs[fr->callno]->owner);
11815          }
11816       }
11817       ast_party_connected_line_free(&connected);
11818    }
11819 
11820    /* Common things */
11821    f.src = "IAX2";
11822    f.mallocd = 0;
11823    f.offset = 0;
11824    f.len = 0;
11825    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11826       f.samples = ast_codec_get_samples(&f);
11827       /* We need to byteswap incoming slinear samples from network byte order */
11828       if (f.subclass.codec == AST_FORMAT_SLINEAR)
11829          ast_frame_byteswap_be(&f);
11830    } else
11831       f.samples = 0;
11832    iax_frame_wrap(fr, &f);
11833 
11834    /* If this is our most recent packet, use it as our basis for timestamping */
11835    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11836       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
11837       fr->outoforder = 0;
11838    } else {
11839       if (iaxdebug && iaxs[fr->callno]) {
11840          ast_debug(1, "Received out of order packet... (type=%u, subclass %d, ts = %u, last = %u)\n", f.frametype, f.subclass.integer, fr->ts, iaxs[fr->callno]->last);
11841       }
11842       fr->outoforder = -1;
11843    }
11844    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11845    if (iaxs[fr->callno]) {
11846       duped_fr = iaxfrdup2(fr);
11847       if (duped_fr) {
11848          schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11849       }
11850    }
11851    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11852       iaxs[fr->callno]->last = fr->ts;
11853 #if 1
11854       if (iaxdebug)
11855          ast_debug(1, "For call=%d, set last=%u\n", fr->callno, fr->ts);
11856 #endif
11857    }
11858 
11859    /* Always run again */
11860    ast_variables_destroy(ies.vars);
11861    ast_mutex_unlock(&iaxsl[fr->callno]);
11862    return 1;
11863 }

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 9817 of file chan_iax2.c.

References ast_codec_get_samples(), AST_FRAME_VOICE, ast_inet_ntoa(), ast_log(), ast_mutex_unlock, ast_test_flag, ast_tvnow(), ast_tvzero(), iax_frame::callno, ast_iax2_meta_trunk_entry::callno, ast_iax2_mini_hdr::callno, ast_iax2_meta_hdr::cmddata, ast_frame_subclass::codec, 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::frametype, iax2_vnak(), IAX_FLAG_FULL, iax_frame_wrap(), IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_STATE_STARTED, iaxfrdup2(), iaxs, iaxsl, chan_iax2_pvt::last, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, 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().

09819 {
09820    unsigned char metatype;
09821    struct ast_iax2_meta_trunk_mini *mtm;
09822    struct ast_iax2_meta_trunk_hdr *mth;
09823    struct ast_iax2_meta_trunk_entry *mte;
09824    struct iax2_trunk_peer *tpeer;
09825    unsigned int ts;
09826    void *ptr;
09827    struct timeval rxtrunktime;
09828    struct ast_frame f = { 0, };
09829 
09830    if (packet_len < sizeof(*meta)) {
09831       ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 
09832          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09833       return 1;
09834    }
09835 
09836    if (meta->metacmd != IAX_META_TRUNK)
09837       return 1;
09838 
09839    if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09840       ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09841          (int) (sizeof(*meta) + sizeof(*mth)));
09842       return 1;
09843    }
09844    mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09845    ts = ntohl(mth->ts);
09846    metatype = meta->cmddata;
09847    packet_len -= (sizeof(*meta) + sizeof(*mth));
09848    ptr = mth->data;
09849    tpeer = find_tpeer(sin, sockfd);
09850    if (!tpeer) {
09851       ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 
09852          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09853       return 1;
09854    }
09855    tpeer->trunkact = ast_tvnow();
09856    if (!ts || ast_tvzero(tpeer->rxtrunktime))
09857       tpeer->rxtrunktime = tpeer->trunkact;
09858    rxtrunktime = tpeer->rxtrunktime;
09859    ast_mutex_unlock(&tpeer->lock);
09860    while (packet_len >= sizeof(*mte)) {
09861       /* Process channels */
09862       unsigned short callno, trunked_ts, len;
09863 
09864       if (metatype == IAX_META_TRUNK_MINI) {
09865          mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09866          ptr += sizeof(*mtm);
09867          packet_len -= sizeof(*mtm);
09868          len = ntohs(mtm->len);
09869          callno = ntohs(mtm->mini.callno);
09870          trunked_ts = ntohs(mtm->mini.ts);
09871       } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09872          mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09873          ptr += sizeof(*mte);
09874          packet_len -= sizeof(*mte);
09875          len = ntohs(mte->len);
09876          callno = ntohs(mte->callno);
09877          trunked_ts = 0;
09878       } else {
09879          ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09880          break;
09881       }
09882       /* Stop if we don't have enough data */
09883       if (len > packet_len)
09884          break;
09885       fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09886       if (!fr->callno)
09887          continue;
09888 
09889       /* If it's a valid call, deliver the contents.  If not, we
09890          drop it, since we don't have a scallno to use for an INVAL */
09891       /* Process as a mini frame */
09892       memset(&f, 0, sizeof(f));
09893       f.frametype = AST_FRAME_VOICE;
09894       if (!iaxs[fr->callno]) {
09895          /* drop it */
09896       } else if (iaxs[fr->callno]->voiceformat == 0) {
09897          ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09898          iax2_vnak(fr->callno);
09899       } else {
09900          f.subclass.codec = iaxs[fr->callno]->voiceformat;
09901          f.datalen = len;
09902          if (f.datalen >= 0) {
09903             if (f.datalen)
09904                f.data.ptr = ptr;
09905             else
09906                f.data.ptr = NULL;
09907             if (trunked_ts)
09908                fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09909             else
09910                fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09911             /* Don't pass any packets until we're started */
09912             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09913                struct iax_frame *duped_fr;
09914 
09915                /* Common things */
09916                f.src = "IAX2";
09917                f.mallocd = 0;
09918                f.offset = 0;
09919                if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
09920                   f.samples = ast_codec_get_samples(&f);
09921                else
09922                   f.samples = 0;
09923                fr->outoforder = 0;
09924                iax_frame_wrap(fr, &f);
09925                duped_fr = iaxfrdup2(fr);
09926                if (duped_fr)
09927                   schedule_delivery(duped_fr, 1, 1, &fr->ts);
09928                if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09929                   iaxs[fr->callno]->last = fr->ts;
09930             }
09931          } else {
09932             ast_log(LOG_WARNING, "Datalen < 0?\n");
09933          }
09934       }
09935       ast_mutex_unlock(&iaxsl[fr->callno]);
09936       ptr += len;
09937       packet_len -= len;
09938    }
09939 
09940    return 1;
09941 }

static int socket_read ( int *  id,
int  fd,
short  events,
void *  cbdata 
) [static]

Definition at line 9737 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(), ast_iax2_full_hdr::csub, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), len(), LOG_WARNING, ast_iax2_full_hdr::scallno, signal_condition(), thread, and ast_iax2_full_hdr::type.

Referenced by peer_set_srcaddr(), and set_config().

09738 {
09739    struct iax2_thread *thread;
09740    socklen_t len;
09741    time_t t;
09742    static time_t last_errtime = 0;
09743    struct ast_iax2_full_hdr *fh;
09744 
09745    if (!(thread = find_idle_thread())) {
09746       time(&t);
09747       if (t != last_errtime) {
09748          last_errtime = t;
09749          ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09750       }
09751       usleep(1);
09752       return 1;
09753    }
09754 
09755    len = sizeof(thread->iosin);
09756    thread->iofd = fd;
09757    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09758    thread->buf_size = sizeof(thread->readbuf);
09759    thread->buf = thread->readbuf;
09760    if (thread->buf_len < 0) {
09761       if (errno != ECONNREFUSED && errno != EAGAIN)
09762          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09763       handle_error();
09764       thread->iostate = IAX_IOSTATE_IDLE;
09765       signal_condition(&thread->lock, &thread->cond);
09766       return 1;
09767    }
09768    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
09769       thread->iostate = IAX_IOSTATE_IDLE;
09770       signal_condition(&thread->lock, &thread->cond);
09771       return 1;
09772    }
09773    
09774    /* Determine if this frame is a full frame; if so, and any thread is currently
09775       processing a full frame for the same callno from this peer, then drop this
09776       frame (and the peer will retransmit it) */
09777    fh = (struct ast_iax2_full_hdr *) thread->buf;
09778    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09779       struct iax2_thread *cur = NULL;
09780       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09781       
09782       AST_LIST_LOCK(&active_list);
09783       AST_LIST_TRAVERSE(&active_list, cur, list) {
09784          if ((cur->ffinfo.callno == callno) &&
09785              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09786             break;
09787       }
09788       if (cur) {
09789          /* we found another thread processing a full frame for this call,
09790             so queue it up for processing later. */
09791          defer_full_frame(thread, cur);
09792          AST_LIST_UNLOCK(&active_list);
09793          thread->iostate = IAX_IOSTATE_IDLE;
09794          signal_condition(&thread->lock, &thread->cond);
09795          return 1;
09796       } else {
09797          /* this thread is going to process this frame, so mark it */
09798          thread->ffinfo.callno = callno;
09799          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09800          thread->ffinfo.type = fh->type;
09801          thread->ffinfo.csub = fh->csub;
09802          AST_LIST_INSERT_HEAD(&active_list, thread, list);
09803       }
09804       AST_LIST_UNLOCK(&active_list);
09805    }
09806    
09807    /* Mark as ready and send on its way */
09808    thread->iostate = IAX_IOSTATE_READY;
09809 #ifdef DEBUG_SCHED_MULTITHREAD
09810    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09811 #endif
09812    signal_condition(&thread->lock, &thread->cond);
09813 
09814    return 1;
09815 }

static void spawn_dp_lookup ( int  callno,
const char *  context,
const char *  callednum,
const char *  callerid 
) [static]

Definition at line 9404 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().

09405 {
09406    pthread_t newthread;
09407    struct dpreq_data *dpr;
09408    
09409    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
09410       return;
09411 
09412    dpr->callno = callno;
09413    ast_copy_string(dpr->context, context, sizeof(dpr->context));
09414    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
09415    if (callerid)
09416       dpr->callerid = ast_strdup(callerid);
09417    if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
09418       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
09419    }
09420 }

static int start_network_thread ( void   )  [static]

Definition at line 12427 of file chan_iax2.c.

References ast_calloc, ast_cond_destroy, ast_cond_init, ast_cond_wait, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, ast_verb, iax2_process_thread(), IAX_THREAD_TYPE_POOL, iaxthreadcount, LOG_ERROR, LOG_WARNING, network_thread(), and thread.

Referenced by load_module().

12428 {
12429    struct iax2_thread *thread;
12430    int threadcount = 0;
12431    int x;
12432    for (x = 0; x < iaxthreadcount; x++) {
12433       thread = ast_calloc(1, sizeof(*thread));
12434       if (thread) {
12435          thread->type = IAX_THREAD_TYPE_POOL;
12436          thread->threadnum = ++threadcount;
12437          ast_mutex_init(&thread->lock);
12438          ast_cond_init(&thread->cond, NULL);
12439          ast_mutex_init(&thread->init_lock);
12440          ast_cond_init(&thread->init_cond, NULL);
12441 
12442          ast_mutex_lock(&thread->init_lock);
12443 
12444          if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
12445             ast_log(LOG_WARNING, "Failed to create new thread!\n");
12446             ast_mutex_destroy(&thread->lock);
12447             ast_cond_destroy(&thread->cond);
12448             ast_mutex_unlock(&thread->init_lock);
12449             ast_mutex_destroy(&thread->init_lock);
12450             ast_cond_destroy(&thread->init_cond);
12451             ast_free(thread);
12452             thread = NULL;
12453             continue;
12454          }
12455          /* Wait for the thread to be ready */
12456          ast_cond_wait(&thread->init_cond, &thread->init_lock);
12457 
12458          /* Done with init_lock */
12459          ast_mutex_unlock(&thread->init_lock);
12460 
12461          AST_LIST_LOCK(&idle_list);
12462          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
12463          AST_LIST_UNLOCK(&idle_list);
12464       }
12465    }
12466    if (ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL)) {
12467       ast_log(LOG_ERROR, "Failed to create new thread!\n");
12468       return -1;
12469    }
12470    ast_verb(2, "%d helper threads started\n", threadcount);
12471    return 0;
12472 }

static void stop_stuff ( int  callno  )  [static]

Definition at line 9107 of file chan_iax2.c.

References iax2_destroy_helper(), and iaxs.

Referenced by socket_process().

09108 {
09109    iax2_destroy_helper(iaxs[callno]);
09110 }

static void store_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2213 of file chan_iax2.c.

References ao2_link, ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.

Referenced by __find_callno(), complete_transfer(), and socket_process().

02214 {
02215    if (!pvt->peercallno) {
02216       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02217       return;
02218    }
02219 
02220    ao2_link(iax_peercallno_pvts, pvt);
02221 }

static void store_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 2194 of file chan_iax2.c.

References ao2_link, ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.

Referenced by try_transfer().

02195 {
02196    if (!pvt->transfercallno) {
02197       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02198       return;
02199    }
02200 
02201    ao2_link(iax_transfercallno_pvts, pvt);
02202 }

static int timing_read ( int *  id,
int  fd,
short  events,
void *  cbdata 
) [static]

Definition at line 9290 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_log(), ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_timer_ack(), ast_tvnow(), ast_verbose, iax2_trunk_expired(), iax2_trunk_peer::lock, LOG_ERROR, send_trunk(), totalcalls, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.

Referenced by network_thread().

09291 {
09292    int res, processed = 0, totalcalls = 0;
09293    struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
09294    struct timeval now = ast_tvnow();
09295 
09296    if (iaxtrunkdebug)
09297       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
09298 
09299    if (timer) {
09300       if (ast_timer_ack(timer, 1) < 0) {
09301          ast_log(LOG_ERROR, "Timer failed acknowledge\n");
09302          return 0;
09303       }
09304    }
09305 
09306    /* For each peer that supports trunking... */
09307    AST_LIST_LOCK(&tpeers);
09308    AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
09309       processed++;
09310       res = 0;
09311       ast_mutex_lock(&tpeer->lock);
09312       /* We can drop a single tpeer per pass.  That makes all this logic
09313          substantially easier */
09314       if (!drop && iax2_trunk_expired(tpeer, &now)) {
09315          /* Take it out of the list, but don't free it yet, because it
09316             could be in use */
09317          AST_LIST_REMOVE_CURRENT(list);
09318          drop = tpeer;
09319       } else {
09320          res = send_trunk(tpeer, &now);
09321          trunk_timed++; 
09322          if (iaxtrunkdebug)
09323             ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %u bytes backloged and has hit a high water mark of %u bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc);
09324       }     
09325       totalcalls += res;   
09326       res = 0;
09327       ast_mutex_unlock(&tpeer->lock);
09328    }
09329    AST_LIST_TRAVERSE_SAFE_END;
09330    AST_LIST_UNLOCK(&tpeers);
09331 
09332    if (drop) {
09333       ast_mutex_lock(&drop->lock);
09334       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
09335          because by the time they could get tpeerlock, we've already grabbed it */
09336       ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
09337       if (drop->trunkdata) {
09338          ast_free(drop->trunkdata);
09339          drop->trunkdata = NULL;
09340       }
09341       ast_mutex_unlock(&drop->lock);
09342       ast_mutex_destroy(&drop->lock);
09343       ast_free(drop);
09344       
09345    }
09346 
09347    if (iaxtrunkdebug)
09348       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
09349    iaxtrunkdebug = 0;
09350 
09351    return 1;
09352 }

static int transfercallno_pvt_cmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 14700 of file chan_iax2.c.

References CMP_MATCH, CMP_STOP, and match().

Referenced by load_objects().

14701 {
14702    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14703 
14704    /* The frames_received field is used to hold whether we're matching
14705     * against a full frame or not ... */
14706 
14707    return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14708       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14709 }

static int transfercallno_pvt_hash_cb ( const void *  obj,
const int  flags 
) [static]

Definition at line 14693 of file chan_iax2.c.

References chan_iax2_pvt::transfercallno.

Referenced by load_objects().

14694 {
14695    const struct chan_iax2_pvt *pvt = obj;
14696 
14697    return pvt->transfercallno;
14698 }

static int transmit_frame ( void *  data  )  [static]

Definition at line 4347 of file chan_iax2.c.

References AST_LIST_INSERT_TAIL, ast_mutex_lock, ast_mutex_unlock, attempt_transmit(), iax_frame::callno, iax2_sched_add(), iax_frame_free(), iaxs, iaxsl, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_packet(), and iax_frame::sentyet.

Referenced by iax2_transmit().

04348 {
04349    struct iax_frame *fr = data;
04350 
04351    ast_mutex_lock(&iaxsl[fr->callno]);
04352 
04353    fr->sentyet = 1;
04354 
04355    if (iaxs[fr->callno]) {
04356       send_packet(fr);
04357    }
04358 
04359    if (fr->retries < 0) {
04360       ast_mutex_unlock(&iaxsl[fr->callno]);
04361       /* No retransmit requested */
04362       iax_frame_free(fr);
04363    } else {
04364       /* We need reliable delivery.  Schedule a retransmission */
04365       AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list);
04366       fr->retries++;
04367       fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr);
04368       ast_mutex_unlock(&iaxsl[fr->callno]);
04369    }
04370 
04371    return 0;
04372 }

static int transmit_trunk ( struct iax_frame f,
struct sockaddr_in *  sin,
int  sockfd 
) [static]

Definition at line 3405 of file chan_iax2.c.

References ast_debug, iax_frame::data, iax_frame::datalen, errno, and handle_error().

Referenced by send_trunk().

03406 {
03407    int res;
03408    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03409                sizeof(*sin));
03410    if (res < 0) {
03411       ast_debug(1, "Received error: %s\n", strerror(errno));
03412       handle_error();
03413    } else
03414       res = 0;
03415    return res;
03416 }

static int try_firmware ( char *  s  )  [static]

Definition at line 3110 of file chan_iax2.c.

References ast_alloca, ast_calloc, AST_FILE_MODE, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_strlen_zero(), MD5Context::buf, ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, errno, IAX_FIRMWARE_MAGIC, last, len(), LOG_WARNING, ast_iax2_firmware_header::magic, MD5Final(), MD5Init(), MD5Update(), and ast_iax2_firmware_header::version.

Referenced by reload_firmware().

03111 {
03112    struct stat stbuf;
03113    struct iax_firmware *cur = NULL;
03114    int ifd, fd, res, len, chunk;
03115    struct ast_iax2_firmware_header *fwh, fwh2;
03116    struct MD5Context md5;
03117    unsigned char sum[16], buf[1024];
03118    char *s2, *last;
03119 
03120    s2 = ast_alloca(strlen(s) + 100);
03121 
03122    last = strrchr(s, '/');
03123    if (last)
03124       last++;
03125    else
03126       last = s;
03127 
03128    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, ast_random());
03129 
03130    if ((res = stat(s, &stbuf) < 0)) {
03131       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
03132       return -1;
03133    }
03134 
03135    /* Make sure it's not a directory */
03136    if (S_ISDIR(stbuf.st_mode))
03137       return -1;
03138    ifd = open(s, O_RDONLY);
03139    if (ifd < 0) {
03140       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
03141       return -1;
03142    }
03143    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
03144    if (fd < 0) {
03145       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
03146       close(ifd);
03147       return -1;
03148    }
03149    /* Unlink our newly created file */
03150    unlink(s2);
03151    
03152    /* Now copy the firmware into it */
03153    len = stbuf.st_size;
03154    while(len) {
03155       chunk = len;
03156       if (chunk > sizeof(buf))
03157          chunk = sizeof(buf);
03158       res = read(ifd, buf, chunk);
03159       if (res != chunk) {
03160          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03161          close(ifd);
03162          close(fd);
03163          return -1;
03164       }
03165       res = write(fd, buf, chunk);
03166       if (res != chunk) {
03167          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03168          close(ifd);
03169          close(fd);
03170          return -1;
03171       }
03172       len -= chunk;
03173    }
03174    close(ifd);
03175    /* Return to the beginning */
03176    lseek(fd, 0, SEEK_SET);
03177    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
03178       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
03179       close(fd);
03180       return -1;
03181    }
03182    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
03183       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
03184       close(fd);
03185       return -1;
03186    }
03187    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
03188       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
03189       close(fd);
03190       return -1;
03191    }
03192    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
03193       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
03194       close(fd);
03195       return -1;
03196    }
03197    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
03198    if (fwh == MAP_FAILED) {
03199       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
03200       close(fd);
03201       return -1;
03202    }
03203    MD5Init(&md5);
03204    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
03205    MD5Final(sum, &md5);
03206    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
03207       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
03208       munmap((void*)fwh, stbuf.st_size);
03209       close(fd);
03210       return -1;
03211    }
03212 
03213    AST_LIST_TRAVERSE(&firmwares, cur, list) {
03214       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
03215          /* Found a candidate */
03216          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
03217             /* The version we have on loaded is older, load this one instead */
03218             break;
03219          /* This version is no newer than what we have.  Don't worry about it.
03220             We'll consider it a proper load anyhow though */
03221          munmap((void*)fwh, stbuf.st_size);
03222          close(fd);
03223          return 0;
03224       }
03225    }
03226    
03227    if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
03228       cur->fd = -1;
03229       AST_LIST_INSERT_TAIL(&firmwares, cur, list);
03230    }
03231    
03232    if (cur) {
03233       if (cur->fwh)
03234          munmap((void*)cur->fwh, cur->mmaplen);
03235       if (cur->fd > -1)
03236          close(cur->fd);
03237       cur->fwh = fwh;
03238       cur->fd = fd;
03239       cur->mmaplen = stbuf.st_size;
03240       cur->dead = 0;
03241    }
03242    
03243    return 0;
03244 }

static int try_transfer ( struct chan_iax2_pvt pvt,
struct iax_ies ies 
) [static]

Definition at line 8424 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, 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().

08425 {
08426    int newcall = 0;
08427    char newip[256];
08428    struct iax_ie_data ied;
08429    struct sockaddr_in new = { 0, };
08430 
08431    memset(&ied, 0, sizeof(ied));
08432    if (ies->apparent_addr)
08433       memmove(&new, ies->apparent_addr, sizeof(new));
08434    if (ies->callno)
08435       newcall = ies->callno;
08436    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08437       ast_log(LOG_WARNING, "Invalid transfer request\n");
08438       return -1;
08439    }
08440    pvt->transfercallno = newcall;
08441    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08442    inet_aton(newip, &pvt->transfer.sin_addr);
08443    pvt->transfer.sin_family = AF_INET;
08444    pvt->transferid = ies->transferid;
08445    /* only store by transfercallno if this is a new transfer,
08446     * just in case we get a duplicate TXREQ */
08447    if (pvt->transferring == TRANSFER_NONE) {
08448       store_by_transfercallno(pvt);
08449    }
08450    pvt->transferring = TRANSFER_BEGIN;
08451 
08452    if (ies->transferid)
08453       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08454    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08455    return 0;
08456 }

static format_t uncompress_subclass ( unsigned char  csub  )  [static]

Definition at line 1711 of file chan_iax2.c.

References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.

Referenced by decode_frame(), handle_call_token(), and socket_process().

01712 {
01713    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01714    if (csub & IAX_FLAG_SC_LOG) {
01715       /* special case for 'compressed' -1 */
01716       if (csub == 0xff)
01717          return -1;
01718       else
01719          return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01720    }
01721    else
01722       return csub;
01723 }

static void unlink_peer ( struct iax2_peer peer  )  [static]

Definition at line 8718 of file chan_iax2.c.

References ao2_unlink, ast_sched_thread_del, iax2_peer::expire, peer_unref(), and iax2_peer::pokeexpire.

Referenced by __expire_registry(), build_peer(), and prune_peers().

08719 {
08720    if (peer->expire > -1) {
08721       if (!ast_sched_thread_del(sched, peer->expire)) {
08722          peer->expire = -1;
08723          peer_unref(peer);
08724       }
08725    }
08726 
08727    if (peer->pokeexpire > -1) {
08728       if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08729          peer->pokeexpire = -1;
08730          peer_unref(peer);
08731       }
08732    }
08733 
08734    ao2_unlink(peers, peer);
08735 }

static int unload_module ( void   )  [static]
static void unlock_both ( unsigned short  callno0,
unsigned short  callno1 
) [static]

Definition at line 5555 of file chan_iax2.c.

References ast_mutex_unlock, and iaxsl.

Referenced by iax2_bridge().

05556 {
05557    ast_mutex_unlock(&iaxsl[callno1]);
05558    ast_mutex_unlock(&iaxsl[callno0]);
05559 }

static void unwrap_timestamp ( struct iax_frame fr  )  [static]

Definition at line 4100 of file chan_iax2.c.

References iax_frame::af, ast_debug, AST_FRAME_VIDEO, iax_frame::callno, ast_frame::frametype, iaxs, chan_iax2_pvt::last, and iax_frame::ts.

Referenced by schedule_delivery().

04101 {
04102    /* Video mini frames only encode the lower 15 bits of the session
04103     * timestamp, but other frame types (e.g. audio) encode 16 bits. */
04104    const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
04105    const int lower_mask = (1 << ts_shift) - 1;
04106    const int upper_mask = ~lower_mask;
04107    const int last_upper = iaxs[fr->callno]->last & upper_mask;
04108 
04109    if ( (fr->ts & upper_mask) == last_upper ) {
04110       const int x = fr->ts - iaxs[fr->callno]->last;
04111       const int threshold = (ts_shift == 15) ? 25000 : 50000;
04112 
04113       if (x < -threshold) {
04114          /* Sudden big jump backwards in timestamp:
04115             What likely happened here is that miniframe timestamp has circled but we haven't
04116             gotten the update from the main packet.  We'll just pretend that we did, and
04117             update the timestamp appropriately. */
04118          fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
04119          if (iaxdebug)
04120             ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
04121       } else if (x > threshold) {
04122          /* Sudden apparent big jump forwards in timestamp:
04123             What's likely happened is this is an old miniframe belonging to the previous
04124             top 15 or 16-bit timestamp that has turned up out of order.
04125             Adjust the timestamp appropriately. */
04126          fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
04127          if (iaxdebug)
04128             ast_debug(1, "schedule_delivery: pushed back timestamp\n");
04129       }
04130    }
04131 }

static void update_jbsched ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 4135 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().

04136 {
04137    int when;
04138    
04139    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
04140    
04141    when = jb_next(pvt->jb) - when;
04142 
04143    if (when <= 0) {
04144       /* XXX should really just empty until when > 0.. */
04145       when = 1;
04146    }
04147    
04148    pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 
04149       CALLNO_TO_PTR(pvt->callno));
04150 }

static int update_packet ( struct iax_frame f  )  [static]

Definition at line 3541 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, iaxs, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, iax_frame::mydcx, and iax_frame::semirand.

Referenced by __attempt_transmit().

03542 {
03543    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
03544    struct ast_iax2_full_hdr *fh = f->data;
03545    struct ast_frame af;
03546 
03547    /* if frame is encrypted. decrypt before updating it. */
03548    if (f->encmethods) {
03549       decode_frame(&f->mydcx, fh, &af, &f->datalen);
03550    }
03551    /* Mark this as a retransmission */
03552    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03553    /* Update iseqno */
03554    f->iseqno = iaxs[f->callno]->iseqno;
03555    fh->iseqno = f->iseqno;
03556 
03557    /* Now re-encrypt the frame */
03558    if (f->encmethods) {
03559    /* since this is a retransmit frame, create a new random padding
03560     * before re-encrypting. */
03561       build_rand_pad(f->semirand, sizeof(f->semirand));
03562       encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03563    }
03564    return 0;
03565 }

static int update_registry ( struct sockaddr_in *  sin,
int  callno,
char *  devtype,
int  fd,
unsigned short  refresh 
) [static]
Precondition:
iaxsl[callno] is locked
Note:
Since this function calls send_command_final(), the pvt struct for the given call number may disappear while executing this function.

Definition at line 8836 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_CACHABLE, ast_devstate_changed(), ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_del, ast_sockaddr_cmp(), ast_sockaddr_from_sin, ast_sockaddr_to_sin, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_verb, iax_ie_data::buf, 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, iaxs, iaxsl, LOG_NOTICE, LOG_WARNING, mailbox, manager_event, iax2_peer::maxcallno, peer_ref(), peer_unref(), peercnt_modify(), iax_ie_data::pos, realtime_update_peer(), register_peer_exten(), send_command_final(), iax2_peer::sockfd, and version.

Referenced by socket_process().

08837 {
08838    /* Called from IAX thread only, with proper iaxsl lock */
08839    struct iax_ie_data ied = {
08840       .pos = 0,
08841    };
08842    struct iax2_peer *p;
08843    int msgcount;
08844    char data[80];
08845    int version;
08846    const char *peer_name;
08847    int res = -1;
08848    struct ast_sockaddr sockaddr;
08849 
08850    ast_sockaddr_from_sin(&sockaddr, sin);
08851 
08852    peer_name = ast_strdupa(iaxs[callno]->peer);
08853 
08854    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
08855    ast_mutex_unlock(&iaxsl[callno]);
08856    if (!(p = find_peer(peer_name, 1))) {
08857       ast_mutex_lock(&iaxsl[callno]);
08858       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08859       return -1;
08860    }
08861    ast_mutex_lock(&iaxsl[callno]);
08862    if (!iaxs[callno])
08863       goto return_unref;
08864 
08865    if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08866       if (sin->sin_addr.s_addr) {
08867          time_t nowtime;
08868          time(&nowtime);
08869          realtime_update_peer(peer_name, &sockaddr, nowtime);
08870       } else {
08871          realtime_update_peer(peer_name, &sockaddr, 0);
08872       }
08873    }
08874 
08875    /* treat an unspecified refresh interval as the minimum */
08876    if (!refresh) {
08877       refresh = min_reg_expire;
08878    }
08879    if (refresh > max_reg_expire) {
08880       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08881          p->name, max_reg_expire, refresh);
08882       p->expiry = max_reg_expire;
08883    } else if (refresh < min_reg_expire) {
08884       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08885          p->name, min_reg_expire, refresh);
08886       p->expiry = min_reg_expire;
08887    } else {
08888       p->expiry = refresh;
08889    }
08890 
08891    if (ast_sockaddr_cmp(&p->addr, &sockaddr)) {
08892       if (iax2_regfunk) {
08893          iax2_regfunk(p->name, 1);
08894       }
08895 
08896       /* modify entry in peercnts table as _not_ registered */
08897       peercnt_modify((unsigned char) 0, 0, &p->addr);
08898 
08899       /* Stash the IP address from which they registered */
08900       ast_sockaddr_from_sin(&p->addr, sin);
08901 
08902       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08903       if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08904          ast_db_put("IAX/Registry", p->name, data);
08905          ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08906                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08907          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08908          register_peer_exten(p, 1);
08909          ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
08910       } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
08911          ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08912                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08913          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08914          register_peer_exten(p, 0);
08915          ast_db_del("IAX/Registry", p->name);
08916          ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
08917       }
08918       /* Update the host */
08919       /* Verify that the host is really there */
08920       iax2_poke_peer(p, callno);
08921    }
08922 
08923    /* modify entry in peercnts table as registered */
08924    if (p->maxcallno) {
08925       peercnt_modify((unsigned char) 1, p->maxcallno, &p->addr);
08926    }
08927 
08928    /* Make sure our call still exists, an INVAL at the right point may make it go away */
08929    if (!iaxs[callno]) {
08930       res = -1;
08931       goto return_unref;
08932    }
08933 
08934    /* Store socket fd */
08935    p->sockfd = fd;
08936    /* Setup the expiry */
08937    if (p->expire > -1) {
08938       if (!ast_sched_thread_del(sched, p->expire)) {
08939          p->expire = -1;
08940          peer_unref(p);
08941       }
08942    }
08943 
08944    if (p->expiry && sin->sin_addr.s_addr) {
08945       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08946       if (p->expire == -1)
08947          peer_unref(p);
08948    }
08949    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08950    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08951    if (sin->sin_addr.s_addr) {
08952       struct sockaddr_in peer_addr;
08953 
08954       ast_sockaddr_to_sin(&p->addr, &peer_addr);
08955 
08956       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08957       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
08958       if (!ast_strlen_zero(p->mailbox)) {
08959          struct ast_event *event;
08960          int new, old;
08961          char *mailbox, *context;
08962 
08963          context = mailbox = ast_strdupa(p->mailbox);
08964          strsep(&context, "@");
08965          if (ast_strlen_zero(context))
08966             context = "default";
08967 
08968          event = ast_event_get_cached(AST_EVENT_MWI,
08969             AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08970             AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08971             AST_EVENT_IE_END);
08972          if (event) {
08973             new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08974             old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08975             ast_event_destroy(event);
08976          } else { /* Fall back on checking the mailbox directly */
08977             ast_app_inboxcount(p->mailbox, &new, &old);
08978          }
08979 
08980          if (new > 255) {
08981             new = 255;
08982          }
08983          if (old > 255) {
08984             old = 255;
08985          }
08986          msgcount = (old << 8) | new;
08987 
08988          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08989       }
08990       if (ast_test_flag64(p, IAX_HASCALLERID)) {
08991          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08992          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08993       }
08994    }
08995    version = iax_check_version(devtype);
08996    if (version) 
08997       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08998 
08999    res = 0;
09000 
09001 return_unref:
09002    peer_unref(p);
09003 
09004    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
09005 }

static int user_cmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]
Note:
The only member of the user passed here guaranteed to be set is the name field

Definition at line 1758 of file chan_iax2.c.

References CMP_MATCH, and CMP_STOP.

Referenced by load_objects().

01759 {
01760    struct iax2_user *user = obj, *user2 = arg;
01761 
01762    return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01763 }

static int user_delme_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 13178 of file chan_iax2.c.

References ast_set_flag64, and IAX_DELME.

Referenced by delete_users().

13179 {
13180    struct iax2_user *user = obj;
13181 
13182    ast_set_flag64(user, IAX_DELME);
13183 
13184    return 0;
13185 }

static void user_destructor ( void *  obj  )  [static]

Definition at line 12903 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().

12904 {
12905    struct iax2_user *user = obj;
12906 
12907    ast_free_ha(user->ha);
12908    free_context(user->contexts);
12909    if(user->vars) {
12910       ast_variables_destroy(user->vars);
12911       user->vars = NULL;
12912    }
12913    ast_string_field_free_memory(user);
12914 }

static int user_hash_cb ( const void *  obj,
const int  flags 
) [static]
Note:
The only member of the user passed here guaranteed to be set is the name field

Definition at line 1748 of file chan_iax2.c.

References ast_str_hash().

Referenced by load_objects().

01749 {
01750    const struct iax2_user *user = obj;
01751 
01752    return ast_str_hash(user->name);
01753 }

static struct iax2_user* user_ref ( struct iax2_user user  )  [static, read]

Definition at line 1805 of file chan_iax2.c.

References ao2_ref.

01806 {
01807    ao2_ref(user, +1);
01808    return user;
01809 }

static struct iax2_user* user_unref ( struct iax2_user user  )  [static, read]
static int users_data_provider_get ( const struct ast_data_search search,
struct ast_data data_root 
) [static]

Definition at line 14863 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_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_password(), ast_data_add_str(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_strlen_zero(), ast_test_flag64, iax2_user::authmethods, iax2_user::capability, iax2_context::context, iax2_user::contexts, DEFAULT_CONTEXT, iax2_user::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, and user_unref().

14865 {
14866    struct ast_data *data_user, *data_authmethods, *data_enum_node;
14867    struct iax2_user *user;
14868    struct ao2_iterator i;
14869    char auth[90];
14870    char *pstr = "";
14871 
14872    i = ao2_iterator_init(users, 0);
14873    for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
14874       data_user = ast_data_add_node(data_root, "user");
14875       if (!data_user) {
14876          continue;
14877       }
14878 
14879       ast_data_add_structure(iax2_user, data_user, user);
14880 
14881       ast_data_add_codecs(data_user, "codecs", user->capability);
14882 
14883       if (!ast_strlen_zero(user->secret)) {
14884          ast_copy_string(auth, user->secret, sizeof(auth));
14885       } else if (!ast_strlen_zero(user->inkeys)) {
14886          snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
14887       } else {
14888          ast_copy_string(auth, "no secret", sizeof(auth));
14889       }
14890       ast_data_add_password(data_user, "secret", auth);
14891 
14892       ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
14893 
14894       /* authmethods */
14895       data_authmethods = ast_data_add_node(data_user, "authmethods");
14896       if (!data_authmethods) {
14897          ast_data_remove_node(data_root, data_user);
14898          continue;
14899       }
14900       ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA);
14901       ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5);
14902       ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT);
14903 
14904       /* amaflags */
14905       data_enum_node = ast_data_add_node(data_user, "amaflags");
14906       if (!data_enum_node) {
14907          ast_data_remove_node(data_root, data_user);
14908          continue;
14909       }
14910       ast_data_add_int(data_enum_node, "value", user->amaflags);
14911       ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags));
14912 
14913       ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0);
14914 
14915       if (ast_test_flag64(user, IAX_CODEC_NOCAP)) {
14916          pstr = "REQ only";
14917       } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) {
14918          pstr = "disabled";
14919       } else {
14920          pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host";
14921       }
14922       ast_data_add_str(data_user, "codec-preferences", pstr);
14923 
14924       if (!ast_data_search_match(search, data_user)) {
14925          ast_data_remove_node(data_root, data_user);
14926       }
14927    }
14928    ao2_iterator_destroy(&i);
14929 
14930    return 0;
14931 }

static void vnak_retransmit ( int  callno,
int  last 
) [static]

Definition at line 9208 of file chan_iax2.c.

References AST_LIST_TRAVERSE, f, iax_frame::oseqno, iax_frame::retries, and send_packet().

Referenced by socket_process().

09209 {
09210    struct iax_frame *f;
09211 
09212    AST_LIST_TRAVERSE(&frame_queue[callno], f, list) {
09213       /* Send a copy immediately */
09214       if (((unsigned char) (f->oseqno - last) < 128) &&
09215             (f->retries >= 0)) {
09216          send_packet(f);
09217       }
09218    }
09219 }

static int wait_for_peercallno ( struct chan_iax2_pvt pvt  )  [static]
Note:
expects the pvt to be locked

Definition at line 5365 of file chan_iax2.c.

References chan_iax2_pvt::callno, DEADLOCK_AVOIDANCE, iaxs, iaxsl, and chan_iax2_pvt::peercallno.

Referenced by iax2_indicate(), and iax2_setoption().

05366 {
05367    unsigned short callno = pvt->callno;
05368 
05369    if (!pvt->peercallno) {
05370       /* We don't know the remote side's call number, yet.  :( */
05371       int count = 10;
05372       while (count-- && pvt && !pvt->peercallno) {
05373          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
05374          pvt = iaxs[callno];
05375       }
05376       if (!pvt || !pvt->peercallno) {
05377          return -1;
05378       }
05379    }
05380 
05381    return 0;
05382 }


Variable Documentation

char accountcode[AST_MAX_ACCOUNT_CODE] [static]
int adsi = 0 [static]

Definition at line 387 of file chan_iax2.c.

int amaflags = 0 [static]

Definition at line 386 of file chan_iax2.c.

Referenced by ast_async_goto().

int authdebug = 1 [static]

Definition at line 294 of file chan_iax2.c.

int autokill = 0 [static]

Definition at line 295 of file chan_iax2.c.

struct ao2_container* callno_pool [static]

table of available call numbers

Definition at line 849 of file chan_iax2.c.

const unsigned int CALLNO_POOL_BUCKETS = 2699 [static]

Definition at line 854 of file chan_iax2.c.

struct ao2_container* callno_pool_trunk [static]

table of available trunk call numbers

Definition at line 852 of file chan_iax2.c.

struct ast_cli_entry cli_iax2[] [static]

Definition at line 14403 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

unsigned int cos

Definition at line 305 of file chan_iax2.c.

struct sockaddr_in debugaddr [static]

Definition at line 1101 of file chan_iax2.c.

Referenced by handle_cli_iax2_set_debug(), iax_outputframe(), and reload_config().

char default_parkinglot[AST_MAX_CONTEXT] [static]

Definition at line 272 of file chan_iax2.c.

int defaultsockfd = -1 [static]

Definition at line 317 of file chan_iax2.c.

int delayreject = 0 [static]

Definition at line 388 of file chan_iax2.c.

int global_max_trunk_mtu [static]

Maximum MTU, 0 if not used

Definition at line 267 of file chan_iax2.c.

int global_rtautoclear = 120 [static]

Definition at line 439 of file chan_iax2.c.

struct ast_flags64 globalflags = { 0 } [static]

Definition at line 391 of file chan_iax2.c.

format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static]

Definition at line 369 of file chan_iax2.c.

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 14943 of file chan_iax2.c.

Referenced by load_module().

int iax2_encryption = 0 [static]

Definition at line 389 of file chan_iax2.c.

int(* iax2_regfunk)(const char *username, int onoff) = NULL [static]
struct ast_switch iax2_switch [static]

Definition at line 14289 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

struct ast_channel_tech iax2_tech [static]
Initial value:
 {
   .type = "IAX2_VARIABLE",
   .duplicate = iax2_dup_variable_datastore,
   .destroy = iax2_free_variable_datastore,
}

Definition at line 1414 of file chan_iax2.c.

Referenced by acf_iaxvar_read(), acf_iaxvar_write(), ast_iax2_new(), authenticate_reply(), iax2_call(), and socket_process().

Another container of iax2_pvt structures.

Active IAX2 pvt structs are also stored in this container, if they are a part of an active call where we know the remote side's call number. The reason for this is that incoming media frames do not contain our call number. So, instead of having to iterate the entire iaxs array, we use this container to look up calls where the remote side is using a given call number.

Definition at line 1078 of file chan_iax2.c.

Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_peercallno(), and store_by_peercallno().

Another container of iax2_pvt structures.

* Active IAX2 pvt stucts used during transfering a call are stored here.

Definition at line 1094 of file chan_iax2.c.

Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_transfercallno(), and store_by_transfercallno().

int iaxactivethreadcount = 0 [static]

Definition at line 638 of file chan_iax2.c.

Referenced by iax2_process_thread(), and iax2_process_thread_cleanup().

int iaxcompat = 0 [static]

Definition at line 296 of file chan_iax2.c.

int iaxdebug = 0 [static]

Definition at line 371 of file chan_iax2.c.

int iaxdefaultdpcache = 10 * 60 [static]

Definition at line 299 of file chan_iax2.c.

int iaxdefaulttimeout = 5 [static]

Definition at line 301 of file chan_iax2.c.

int iaxdynamicthreadcount = 0 [static]

Definition at line 636 of file chan_iax2.c.

Referenced by find_idle_thread(), and iax2_process_thread().

int iaxdynamicthreadnum = 0 [static]

Definition at line 637 of file chan_iax2.c.

Referenced by find_idle_thread().

int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static]

Definition at line 635 of file chan_iax2.c.

Referenced by find_idle_thread(), and set_config().

Initial value:
 {
   .name = "IAXPEER",
   .read = function_iaxpeer,
}

Definition at line 14209 of file chan_iax2.c.

Referenced by load_module(), and unload_module().

struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS] [static]

an array of iax2 pvt structures

The container for active chan_iax2_pvt structures is implemented as an array for extremely quick direct access to the correct pvt structure based on the local call number. The local call number is used as the index into the array where the associated pvt structure is stored.

Definition at line 1067 of file chan_iax2.c.

Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __find_callno(), __get_from_jb(), __send_lagrq(), __send_ping(), __unload_module(), acf_channel_read(), ast_cli_netstats(), ast_iax2_new(), auth_fail(), auth_reject(), authenticate_reply(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), dp_lookup(), find_cache(), fix_peerts(), function_iaxpeer(), handle_cli_iax2_show_channels(), iax2_ack_registry(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_lock_owner(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_queryoption(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_setoption(), iax2_start_transfer(), iax2_vnak(), iax2_write(), load_module(), log_jitterstats(), make_trunk(), register_verify(), registry_authrequest(), registry_rerequest(), resend_with_token(), save_osptoken(), save_rr(), schedule_delivery(), scheduled_destroy(), send_command_final(), send_command_locked(), send_lagrq(), send_packet(), send_ping(), set_hangup_source_and_cause(), socket_process(), socket_process_meta(), stop_stuff(), transmit_frame(), unwrap_timestamp(), update_packet(), update_registry(), and wait_for_peercallno().

ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static]
int iaxthreadcount = DEFAULT_THREAD_COUNT [static]

Definition at line 634 of file chan_iax2.c.

Referenced by handle_cli_iax2_show_threads(), set_config(), and start_network_thread().

int iaxtrunkdebug = 0 [static]

Definition at line 373 of file chan_iax2.c.

Initial value:
 {
   .name = "IAXVAR",
   .read = acf_iaxvar_read,
   .write = acf_iaxvar_write,
}

Definition at line 10024 of file chan_iax2.c.

Referenced by load_module(), and unload_module().

struct io_context* io [static]

Definition at line 364 of file chan_iax2.c.

int jittertargetextra = 40 [static]

Definition at line 287 of file chan_iax2.c.

int lagrq_time = 10 [static]

Definition at line 283 of file chan_iax2.c.

char language[MAX_LANGUAGE] = "" [static]

Definition at line 274 of file chan_iax2.c.

int last_authmethod = 0 [static]

Definition at line 297 of file chan_iax2.c.

int max_reg_expire [static]

Definition at line 309 of file chan_iax2.c.

int max_retries = 4 [static]

Definition at line 281 of file chan_iax2.c.

int maxauthreq = 3 [static]

Definition at line 280 of file chan_iax2.c.

int maxjitterbuffer = 1000 [static]

Definition at line 284 of file chan_iax2.c.

int maxjitterinterps = 10 [static]

Definition at line 286 of file chan_iax2.c.

int min_reg_expire [static]

Definition at line 308 of file chan_iax2.c.

char mohinterpret[MAX_MUSICCLASS] [static]

Definition at line 384 of file chan_iax2.c.

char mohsuggest[MAX_MUSICCLASS] [static]
struct ast_netsock_list* netsock [static]

Definition at line 315 of file chan_iax2.c.

pthread_t netthreadid = AST_PTHREADT_NULL [static]

Definition at line 393 of file chan_iax2.c.

int network_change_event_sched_id = -1 [static]

Definition at line 278 of file chan_iax2.c.

subscription id for network change events

Definition at line 277 of file chan_iax2.c.

struct ast_netsock_list* outsock [static]

used if sourceaddress specified and bindaddr == INADDR_ANY

Definition at line 316 of file chan_iax2.c.

char* papp = "IAX2Provision" [static]

Definition at line 12132 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

Initial value:

Definition at line 14933 of file chan_iax2.c.

int ping_time = 21 [static]

Definition at line 282 of file chan_iax2.c.

struct ast_codec_pref prefs [static]
struct { ... } qos [static]

Referenced by peer_set_srcaddr(), and set_config().

char regcontext[AST_MAX_CONTEXT] = "" [static]

Definition at line 275 of file chan_iax2.c.

int resyncthreshold = 1000 [static]

Definition at line 285 of file chan_iax2.c.

struct ast_sched_thread* sched [static]

Definition at line 365 of file chan_iax2.c.

int srvlookup = 0 [static]

Definition at line 311 of file chan_iax2.c.

Referenced by build_peer().

const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static]

Definition at line 260 of file chan_iax2.c.

int test_losspct = 0 [static]

Definition at line 375 of file chan_iax2.c.

struct ast_timer* timer [static]
unsigned int tos

Definition at line 304 of file chan_iax2.c.

int trunk_maxmtu [static]

Definition at line 268 of file chan_iax2.c.

int trunk_nmaxmtu [static]

Trunk MTU statistics

Definition at line 268 of file chan_iax2.c.

int trunk_timed [static]

Definition at line 268 of file chan_iax2.c.

int trunk_untimed [static]

Definition at line 268 of file chan_iax2.c.

int trunkfreq = 20 [static]

Definition at line 291 of file chan_iax2.c.

int trunkmaxsize = MAX_TRUNKDATA [static]

Definition at line 292 of file chan_iax2.c.

Initial value:

Definition at line 14938 of file chan_iax2.c.


Generated on 31 Aug 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1